Bill Allombert on Sun, 13 Oct 2013 14:28:37 +0200 |
[Date Prev] [Date Next] [Thread Prev] [Thread Next] [Date Index] [Thread Index]
Branch bill-mt for parallel pari updated |
Dear PARI developers, I have updated the GIT branch bill-mt for parallel pari. This branch support three kind of parallelism: - POSIX threads: do ./Configure --mt=pthread - MPI (for clusters) ./Configure --mt=mpi - No parallelism: ./Configure --mt=single The following parallel GP functions are available: parapply, pareval, parsum, parvector Code evaluated in parallel must not access global variables and local variables declared with local(), and must be free of side effect. The following new defaults are available: nbthreads: number of threads to use threadsize: the stack of the PARI size used by each threads An example file is provided: examples/pari-mt.gp An new declaration is available: inline(var) This declares that var should be inlined in each functions, with the value of var at the time the function is created. This allows to create functions that are not stored in global variables, which is necessar for parallel code. I will give an example: You want to compute this in parallel: -- sinc(x)=if(x,sin(x)/x,1) fun(a)=intnum(x=0,a,sinc(x)) apply(fun,[1..100]) -- If you do -- sinc(x)=if(x,sin(x)/x,1) fun(a)=intnum(x=0,a,sinc(x)) parapply(fun,[1..100]) -- it fails with *** parapply: mt: global variable not supported :sinc. since parallel code cannot use global variables. What you can do is -- inline(sinc); sinc(x)=if(x,sin(x)/x,1); fun(a)=intnum(x=0,a,sinc(x)); parapply(fun,[1..100]) -- which works since now sinc is inlined inside fun. NB: if you use parvector instead of parapply as in parvector(100,i,fun(i)) you will have to declare fun as inline, too. Sometime it is convenient to interrupt a parallel computation when one of the thread has found the result we sought. This can be done using the error/iferr mechanism. For example, let says we want to find an elliptic curve of prime order over F_p for some p: -- inline(test); test(p)=a->my(E=ellinit([1,a],p));if(isprime(ellcard(E)),error(a)) getcurve(p)= { iferr(parapply(test(p),[1..1000]),err ,component(err,1) ,errname(err)=="e_USER"); } -- ? getcurve(nextprime(2^120)) %4 = [200] ? E=ellinit([1,200],nextprime(2^120)); ? ellcard(E) %5 = 1329227995784915874132467290876997467 ? isprime(%) %6 = 1 The mechanism of throwing an error to interrupt the parallel computation is a bit ugly but works really well. Maybe I could add a dedicated function. Cheers, Bill.