Question: Can anyone make this procedure threadsafe to enable parallel computing?

Dear All,
My group recently published a DAEsolver in Maple, https://mapletransactions.org/index.php/maple/article/view/16701
This solver is very competive compared to existing large scale DAE solvers (even in other languages) by performing symbolic calculation for analytical Jacobian (including sparsity pattern), and by using parallel sparse direct solver (PARDISO).

The code and paper use ListTools. If the attached procedure can be made threadsafe and parallelized, then the resulting DAEsolver is publishable and will be better than most solvers (from any language) today. We welcome collaborations and suggestions. The code works for N = 40, but kernel connection is lost for higher values of N and it is not stable.

thanks

Dr. Venkat Subramanian
PS, for the specific problem, it is trivial to write the Jacobian and residue in a for loop that can be run in parallel (and it helps us to solve > 1 Million or more DAEs), but the attached code (makeproc) helps in solving DAEs resulting from sophisticated discretization approaches for PDEs without user input.

 

NULL

restart:

Digits:=15;

15

makeproc:=proc(n0,nf,Nt,Eqode::Array,Vars::list,Vars1::list,Equation::Array,j11::Matrix(storage=sparse))
local i,j,LL,LL2,L,i1,varsdir,varsdir1,node,eqs;

for i from n0 to nf do
eqs:=rhs(Eqode[i]):
L:=indets(eqs)minus{t};#print(L);
if nops(L)>0 then
LL := [seq(ListTools:-Search(L[j], Vars),
             j = 1 .. nops(L))];
 LL2 := ListTools:-MakeUnique(LL);
if LL2[nops(LL2)] = 0 then
             LL := [seq(LL2[i1], i1 = 1 .. nops(LL2) - 1)];
         end if;
         if LL2[1]= 0 then LL:=[seq(LL2[i1],i1=2..nops(LL2))]: end:#print(1,LL);
varsdir:=[seq(Vars[LL[i1]]=0.5*uu[LL[i1]]+uu_old[LL[i1]],i1=1..nops(LL))];
else varsdir:=[1=1]:end:

Equation[i]:=uu[i]-deltA*subs(varsdir,t=tnew,eqs):#print(i,Equation[i]);
        L := indets(Equation[i]);
        LL := [seq(ListTools:-Search(L[j], Vars1),j = 1 .. nops(L))];
        LL2 := ListTools:-MakeUnique(LL);
        if LL2[nops(LL2)] = 0 then
            LL := [seq(LL2[i1], i1 = 1 .. nops(LL2) - 1)];
        end if;
        if LL2[1]= 0 then LL:=[seq(LL2[i1],i1=2..nops(LL2))]: end:
        
        for j to nops(LL) do
            j11[i, LL[j]] := diff(Equation[i], uu[LL[j]]);
        end do;
 
od:
end proc:

CodeTools[ThreadSafetyCheck](makeproc);

0, 1

#infolevel[all]:=10;

 

N:=40;h:=1.0/N:

40

with(Threads[Task]):

Eqs:=Array(1..N,1..N):

for i from 1 to N do for j from 1 to N do
if i = 1 then left:=0: else left:=(c[i,j](t)-c[i-1,j](t))/h:end:
if i = N then right:=-0.1: else right:=(c[i+1,j](t)-c[i,j](t))/h:end:
if j = 1 then bot:=0: else bot:=(c[i,j](t)-c[i,j-1](t))/h:end:
if j = N then top:=-0.1: else top:=(c[i,j+1](t)-c[i,j](t))/h:end:
Eqs[i,j]:=diff(c[i,j](t),t)=(right-left)/h+(top-bot)/h-c[i,j](t)^2:
od:od:

 

eqs1:=Array([seq(seq(Eqs[i,j],i=1..N),j=1..N)]):

ics:=[seq(seq(c[i,j](t)=1.0,i=1..N),j=1..N)]:

Vars:=[seq(seq(c[i,j](t),i=1..N),j=1..N)]:

Vars1:=[seq(uu[i],i=1..N^2)]:

Equation:=Array(1..N^2):j11:=Matrix(1..N^2,1..N^2,storage=sparse):eqs:=copy(Equation):

CodeTools:-Usage(makeproc(1,N^2,N^2,eqs1,Vars,Vars1,Equation,j11));

memory used=21.47MiB, alloc change=24.99MiB, cpu time=235.00ms, real time=231.00ms, gc time=62.50ms

1-deltA*(-1600.00000000000-.50*uu[1600]-1.0*uu_old[1600])

j11[5,5];

1-deltA*(-2400.00000000000-.50*uu[5]-1.0*uu_old[5])

#Equation[1];

makeprocDistribute := proc(i_low, i_high,Nt,Eqode::Array,Vars::list,Vars1::list,Equation::Array,j11::Matrix(storage=sparse))
local i_mid;
if 200 < i_high - i_low then
#if i_low > 250 then
#i_mid := floor(1/2*i_high - 1/2*i_low) + i_low;
i_mid:=iquo(i_low+i_high,2):
Continue(null,
Task = [makeprocDistribute, i_low, i_mid,Nt,Eqode,Vars,Vars1,Equation,j11],
Task = [makeprocDistribute,i_mid + 1, i_high,Nt,Eqode,Vars,Vars1,Equation,j11]);
else
makeproc(i_low, i_high,Nt,Eqode,Vars,Vars1,Equation,j11); end if;
end proc:

j11[5,5];

1-deltA*(-2400.00000000000-.50*uu[5]-1.0*uu_old[5])

N^2;

1600

NN:=N^2;

1600

Equation:=Array(1..N^2):j11:=Matrix(1..N^2,1..N^2,storage=sparse):

CodeTools:-Usage(Start(makeprocDistribute,1,NN,NN,eqs1,Vars,Vars1,Equation,j11)):

memory used=22.01MiB, alloc change=239.31MiB, cpu time=985.00ms, real time=241.00ms, gc time=1.61s

j11[5,5];

1-deltA*(-2400.00000000000-.50*uu[5]-1.0*uu_old[5])

 

NULL


 

Download makeproctest.mw
 

NULL

 

Please Wait...