From: Damien Mattei <damien.mattei@gmail.com>
To: guile-user <guile-user@gnu.org>
Subject: OpenMP example to run Scheme procedure in parallel
Date: Sat, 31 Dec 2022 10:45:03 +0100 [thread overview]
Message-ID: <CADEOaddyVcTVXWYCZ5WLAGEM8GLe_qZ-inLyT06W7Y4guB7CAQ@mail.gmail.com> (raw)
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
reply other threads:[~2022-12-31 9:45 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=CADEOaddyVcTVXWYCZ5WLAGEM8GLe_qZ-inLyT06W7Y4guB7CAQ@mail.gmail.com \
--to=damien.mattei@gmail.com \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).