Yesterday i ran Guile with OpenMP support. It is an idea that i had for a while to use OpenMP available in C with some Guile procedures. OpenMP is a standart to // code in many language C,Fortran,etc on multiple cores on the same hardware (as opposite to MPI that require multiples hosts,a fast network such as Infiniband ,etc...) : https://www.openmp.org/wp-content/uploads/openmp-examples-4.5.0.pdf
My goal was to be able to use a FOR loop in C parallelised with OpenMP to run a Scheme function that work on an array indexed by the FOR loop. Like that all the data are keep in Scheme and processing too. Only the // for in C is done in OpenMP. Running Guile with some support of OpenMP requires to call an OpenMP C function that in return call one or many Scheme functions int it // region. I was afraid it would be source of problem and many segmentation fault later i get the good code that i present below, it is quite simple at the end: file:guile-openMP.c : // openMP for Guile #include <libguile.h> #include <omp.h> #include <stdio.h> int openmp(int start,int stop,char * func_name) { SCM func; func = scm_variable_ref(scm_c_lookup(func_name)); int i; #pragma omp parallel for for (i=start; i<=stop; i++) { /* i is private by default */ scm_init_guile(); // needed here because we are in a new thread? scm_call_1( func , scm_from_int(i) ); } return 1; } https://github.com/damien-mattei/library-FunctProg/blob/master/guile-openMP.c and that's all for the C part. A few words before looking at the Scheme code: I only had access those last days to a Mac OS M1 box which is harder to developp than Linux. Under Mac os or Linux you need the source code of Guile to have the libguile.h . Xcode disable by default OpenMP support ! you have to activate it passing good args to clang compiler (gcc seems to be hidden behind clang): https://mac.r-project.org/openmp/ you have to install OpenMP with brew and i forget all the install i had to done aside. Under Linux this would have been more easy. The C code must be compiled under Mac OS like that: gcc `pkg-config --cflags guile-3.0` -I/opt/homebrew/opt/libomp/include -L/opt/homebrew/opt/libomp/lib -Xclang -fopenmp -shared -o libguile-openMP.so -fPIC -lguile-3.0 -lomp guile-openMP.c or: clang `pkg-config --cflags guile-3.0` -I/opt/homebrew/opt/libomp/include -L/opt/homebrew/opt/libomp/lib -Xclang -fopenmp -shared -o libguile-openMP.so -fPIC -lguile-3.0 -lomp guile-openMP.c Now the Scheme code, again it is quite simple and transparent (thanks to the Guile developpers!): you need to : (use-modules (system foreign) (system foreign-library) ) https://github.com/damien-mattei/library-FunctProg/blob/master/start-%CE%BB%CE%BF%CE%B3%CE%B9%CE%BA%CE%B9-guile%2B.scm#L70 added in your code to be able to call external function from Guile. or written like that: (define-module (openmp for) #:use-module (system foreign) #:use-module (system foreign-library) #:export (openmp)) you need to declare to Guile the external function openmp used in the C code: (define openmp (foreign-library-function "libguile-openMP" "openmp" #:return-type int #:arg-types (list int int '*))) https://github.com/damien-mattei/library-FunctProg/blob/master/guile/logiki%2B.scm#L3557 and you call the code like that: (openmp start stop (string->pointer "function-unify-minterms-vectors")) ;; call openMP C functions https://github.com/damien-mattei/library-FunctProg/blob/master/guile/logiki%2B.scm#L3608 notice i had to pass the scheme name function, this is the way Guile works and retrieve the function in the C code with scm_c_lookup(func_name) do not forget to declare the number of cores you want you code to run on in the terminal: export OMP_NUM_THREADS=8 before running Guile and perheaps also when compiling the C code . On my logic code i experienced a speed up of 33% but only the critical parts are // . Also the scheme calls and environment scm_init_guile(); should take some time but it is faster than before with OpenMP support. Cheers, Damien