запись в разделяемые массивы внутри распределенного цикла for в JULIA - PullRequest
2 голосов
/ 08 июня 2019

У меня есть ODE, который мне нужно решить в широком диапазоне параметров.Ранее я использовал парфор MATLAB для разделения диапазонов параметров между несколькими потоками.Я новичок в Джулии, и теперь мне нужно сделать то же самое в Джулии.Вот код, который я использую

using DifferentialEquations, SharedArrays, Distributed, Plots


function SingleBubble(du,u,p,t)
    du[1]=@. u[2]
    du[2]=@. ((-0.5*u[2]^2)*(3-u[2]/(p[4]))+(1+(1-3*p[7])*u[2]/p[4])*((p[6]-p[5])/p[2]+2*p[1]/(p[2]*p[8]))*(p[8]/u[1])^(3*p[7])-2*p[1]/(p[2]*u[1])-4*p[3]*u[2]/(p[2]*u[1])-(1+u[2]/p[4])*(p[6]-p[5]+p[10]*sin(2*pi*p[9]*t))/p[2]-p[10]*u[1]*cos(2*pi*p[9]*t)*2*pi*p[9]/(p[2]*p[4]))/((1-u[2]/p[4])*u[1]+4*p[3]/(p[2]*p[4]))
end

R0=2e-6
f=2e6
u0=[R0,0]
LN=1000

RS = SharedArray(zeros(LN))
P = SharedArray(zeros(LN))
bif = SharedArray(zeros(LN,6))

 @distributed     for i= 1:LN
    ps=1e3+i*1e3
    tspan=(0,60/f)
    p=[0.0725,998,1e-3,1481,0,1.01e5,7/5,R0,f,ps]
    prob = ODEProblem(SingleBubble,u0,tspan,p)
    sol=solve(prob,Tsit5(),alg_hints=:stiff,saveat=0.01/f,reltol=1e-8,abstol=1e-8)
    RS[i]=maximum((sol[1,5000:6000])/R0)
    P[i]=ps
    for j=1:6
          nn=5500+(j-1)*100;
          bif[i,j]=(sol[1,nn]/R0);
     end
end


plotly()
scatter(P/1e3,bif,shape=:circle,ms=0.5,label="")#,ma=0.6,mc=:black,mz=1,label="")

При использовании одного рабочего цикла цикл в основном выполняется как обычный однопоточный цикл и работает нормально.Тем не менее, когда я использую addprocs (n) для добавления n дополнительных рабочих, ничего не записывается в SharedArrays RS, P и bif.Я ценю любые рекомендации, которые кто-либо может дать.

1 Ответ

2 голосов
/ 10 июня 2019

Эти изменения необходимы, чтобы ваша программа работала с несколькими работниками и отображала нужные вам результаты:

  1. Какие бы пакеты и функции ни использовались в цикле @distributed, они должны быть доступны во всех процессах.используя @everywhere как объяснено здесь .Итак, в вашем случае это будут пакеты DifferentialEquations и SharedArrays, а также функция SingleBubble().
  2. Вы должны нарисовать график только после того, как все рабочие закончат свои задачи.Для этого вам нужно будет использовать @sync вместе с @distributed.

С этими изменениями ваш код будет выглядеть так:

using Distributed, Plots

@everywhere using DifferentialEquations, SharedArrays

@everywhere function SingleBubble(du,u,p,t)
    du[1]=@. u[2]
    du[2]=@. ((-0.5*u[2]^2)*(3-u[2]/(p[4]))+(1+(1-3*p[7])*u[2]/p[4])*((p[6]-p[5])/p[2]+2*p[1]/(p[2]*p[8]))*(p[8]/u[1])^(3*p[7])-2*p[1]/(p[2]*u[1])-4*p[3]*u[2]/(p[2]*u[1])-(1+u[2]/p[4])*(p[6]-p[5]+p[10]*sin(2*pi*p[9]*t))/p[2]-p[10]*u[1]*cos(2*pi*p[9]*t)*2*pi*p[9]/(p[2]*p[4]))/((1-u[2]/p[4])*u[1]+4*p[3]/(p[2]*p[4]))
end

R0=2e-6
f=2e6
u0=[R0,0]
LN=1000

RS = SharedArray(zeros(LN))
P = SharedArray(zeros(LN))
bif = SharedArray(zeros(LN,6))

@sync @distributed     for i= 1:LN
    ps=1e3+i*1e3
    tspan=(0,60/f)
    p=[0.0725,998,1e-3,1481,0,1.01e5,7/5,R0,f,ps]
    prob = ODEProblem(SingleBubble,u0,tspan,p)
    sol=solve(prob,Tsit5(),alg_hints=:stiff,saveat=0.01/f,reltol=1e-8,abstol=1e-8)
    RS[i]=maximum((sol[1,5000:6000])/R0)
    P[i]=ps
    for j=1:6
          nn=5500+(j-1)*100;
          bif[i,j]=(sol[1,nn]/R0);
     end
end


plotly()
scatter(P/1e3,bif,shape=:circle,ms=0.5,label="")#,ma=0.6,mc=:black,mz=1,label="")

Вывод с использованием нескольких рабочих: enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...