2016-08-22 44 views
2

我有以下测试模块(MyMod.jl)在Julia中存储一些函数。一些核心功能是以串行方式编写的。其他功能并行调用核心功能。Julia:如何让多个工作人员访问“包含(...)”功能到模块中?

module MyMod 

export Dummy,distribute_data,recombine_data,regular_test,parallel_test 

function Dummy(icol,model,data,A,B) 
    nz,nx,nh = size(model) # = size(A) = size(B) 
    for ih = 1:nh 
     for ix = 1:nx 
      for iz = 1:nz 
       data[iz,icol] += A[iz,ix,ih]*B[iz,ix,ih]*model[iz,ix,ih] 
      end 
     end 
    end 
end 

function distribute_data(X, obj_name_on_worker::Symbol;mod=Main) 
    dim = length(size(X)) 
    size_per_worker = floor(Int,size(X,1)/nworkers()) 
    StartIdx = 1 
    EndIdx = size_per_worker 
    for (idx, pid) in enumerate(workers()) 
     if idx == nworkers() 
      EndIdx = size(X,1) 
     end 
     println(StartIdx:EndIdx) 
     if dim == 3 
      @spawnat(pid, eval(mod, Expr(:(=), obj_name_on_worker, X[StartIdx:EndIdx,:,:]))) 
     elseif dim == 2 
      @spawnat(pid, eval(mod, Expr(:(=), obj_name_on_worker, X[StartIdx:EndIdx,:]))) 
     end 
     StartIdx = EndIdx + 1 
     EndIdx = EndIdx + size_per_worker - 1 
    end 
end 

function recombine_data(Data::Symbol;mod=Main) 
    Results = cell(nworkers()) 
    for (idx, pid) in enumerate(workers()) 
     Results[idx] = fetch(@spawnat(pid, getfield(mod, Data))) 
    end 
    return vcat(Results...) 
end 

function regular_test(model,data,A,B) 
    ncol=size(data,2) 
    map((arg)->Dummy(arg,model,data,A,B),[icol for icol = 1:ncol]) 
end 

function parallel_test(model,data,A,B) 
    distribute_data(model, :model) 
    distribute_data(A, :A) 
    distribute_data(B, :B) 
    distribute_data(data, :data) 
    @everywhere ncol=size(data,2) 
    @everywhere begin 
     if myid() != 1 
      map((arg)->Dummy(arg,model,data,A,B),[icol for icol = 1:ncol]) 
     end 
    end 
    P_Data = recombine_data(:data) 
    return P_Data 
end 

end 

该模块按预期工作。当我打开一个Julia会话并运行以下命令时,我发现regular_testparallel_test给出了相同的结果,没有任何错误。

addprocs(3) 

@everywhere using MyMod 

nx = 250; 
nz = 350; 
nh = 150; 
ncol = 125; 

model = rand(nz,nx,nh); 
data = SharedArray(Float64,nz,ncol); 
A = rand(nz,nx,nh); 
B = rand(nz,nx,nh); 

@time P_Data = parallel_test(model,data,A,B); 
@time regular_test(model,data,A,B); 

P_Data == data 

对于较大/复杂的功能,以这种方式存储模块变得相当混乱。以前我已经通过将每个功能存储为单独的文件来清理,然后使用include(..)将它们放入模块中。以下模块是我试图做到这一点:

module MyMod_2 

export Dummy,distribute_data,recombine_data,regular_test,parallel_test 

@everywhere include("Dummy.jl") 
@everywhere include("distribute_data.jl") 
@everywhere include("recombine_data.jl") 
@everywhere include("regular_test.jl") 
@everywhere include("parallel_test.jl") 

end 

其中每个功能都存储在同一目录中MyMod2一个单独的文件。然而,当我打开朱莉娅会话,并尝试运行相同的一组是之前,我下面的冗长的错误命令的执行@everywhere using MyMod_2

WARNING: Module MyMod_2 not defined on process 4 
fatal error on WARNING: Module MyMod_2 not defined on process 3 
4: fatal error on WARNING: Module MyMod_2 not defined on process 2 
3: fatal error on 2: ERROR: UndefVarError: MyMod_2 not defined 
in deserialize at serialize.jl:504 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:560 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:538 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:696 
in deserialize_datatype at serialize.jl:651 
in handle_deserialize at serialize.jl:465 
in message_handler_loop at multi.jl:862 
in process_tcp_streams at multi.jl:851 
in anonymous at task.jl:63 
ERROR: UndefVarError: MyMod_2 not defined 
in deserialize at serialize.jl:504 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:560 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:538 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:696 
in deserialize_datatype at serialize.jl:651 
in handle_deserialize at serialize.jl:465 
in message_handler_loop at multi.jl:862 
in process_tcp_streams at multi.jl:851 
in anonymous at task.jl:63 
ERROR: UndefVarError: MyMod_2 not defined 
in deserialize at serialize.jl:504 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:560 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:538 
in handle_deserialize at serialize.jl:465 
in deserialize at serialize.jl:696 
in deserialize_datatype at serialize.jl:651 
in handle_deserialize at serialize.jl:465 
in message_handler_loop at multi.jl:862 
in process_tcp_streams at multi.jl:851 
in anonymous at task.jl:63 
Worker 2 terminated. 
ERROR: ProcessExitedException() 
in yieldto at ./task.jl:71 
in wait at ./task.jl:371 
in wait at ./task.jl:286 
in wait at ./channels.jl:63 
in take! at ./channels.jl:53 
in take! at ./multi.jl:803 
in remotecall_fetch at multi.jl:729 
in remotecall_fetch at multi.jl:734 
in anonymous at multi.jl:1380 

...and 3 other exceptions. 

in sync_end at ./task.jl:413 
in anonymous at multi.jl:1389 
Worker 3 terminated.ERROR (unhandled task failure): EOFError: read end of file 


julia> Worker 4 terminated.ERROR (unhandled task failure): EOFError: read end of file 
julia> 
fatal error on ERROR (unhandled task failure): EOFError: read end of file 
1: ERROR: attempt to send to unknown socket 
fatal error on 1: ERROR: attempt to send to unknown socket 

时有什么我可以MyMod_2更改为修复此错误,并得到它正确加载到Julia会话?

回答

2

小调整 - 在您的模块中,省略了宏@everywhere。加载你的模块时,只需使用单个的@everywhere就可以了。否则,你会进入一个奇怪的递归类型的情况,其中工作人员都在执行你的模块中的代码(从@everywhere using MyMod_2,然后每个这些工作人员调用@everywhere include()

相关问题