function 내에서 using ModuleXX 등으로 동적으로 모듈을 로딩하는 것은 쉽지 않다.
function내에서 using ModuleXX로 모듈을 로딩하는 경우
“syntax: “using” expression not at top level “
에러가 발생한다.
이런 경우 에러없이 동적으로 모듈을 로딩하기 위해서 eval 사용등으로 메타프로그램을 해야 된다.
아래 예제에서는 분산처리(Parallel Processing)예를 들어 설명한다.
특정 폴더 예를 들어 “/home/shpark/julia_test/exproptimizatoin/examples” 에 TestM01.jl을 생성한다.
파일명과 모듈명을 같이 해야 한다. using ModuleXX 시 모듈경로로 등록된 곳에서 ModuleXX.jl 파일을 읽어 오기 때문임
참고로 julia 기본 모듈 폴더외 추가적으로 모듈 폴더를 등록시 “push!(LOAD_PATH, $module_dir)” 를 사용하여 등록한다.
이렇게 등록된 폴더 아래 있는 모듈들은 using을 통해 사용 할 수 있다.
TestM01.jl 모듈이 /home/shpark/julia_test/exproptimizatoin/examples 폴더에 생성되었다고 가정한다.
module TestM01
using Distributed
function f(x)
println("MyID=$(myid())")
x
end
end # module TestM01
TestM01 모듈에 있는 f(x)를 병렬처리 하기위해 jupyter notebook이나 atom에서 아래 코드를 작성한다.
using Distributed
#=
일반적으로 Module은 function내에서 using을 사용하여 선언 될 수 없기 때문에
function에서 동적으로 Module을 worker들이 로드 할 수 있게 한다.
addprocs 이 후에 생성된 worker 프로세스가 알 수 있도록 @everywhere를 사용해서 알려 준다.
=#
function parallel_procs()
# worker 프로세스 생성
pids = addprocs(10)
# TestM01.jl 모듈이 있는 위치
module_dir = "/home/shpark/julia_test/exproptimizatoin/examples"
# worker 프로세스에 TestM01 모듈이 있는 위치를 알려 준다
@everywhere push!(LOAD_PATH, $module_dir)
#= @everywhere를 사용하기 위해 Distributed를 사용하고
worker들에게 TestM01 모듈을 사용할 수 있게 한다
=#
eval(macroexpand(Distributed,quote @everywhere using TestM01 end))
# 생성된 worker들에게 작업을 배정한다.
p = [@spawn TestM01.f(i) for i in 1:length(pids)]
# fetch는 worker들이 작업을 끝내고 결과를 돌려 줄 때 까지 기다린다
r = map(x->fetch(p[x]), 1:length(pids))
# 생성한 worker들을 종료 한다.
rmprocs(pids)
return r
end
r = parallel_procs()
parallel_procs() 를 실행하면 worker process가 10개 생기고 병렬처리 되었음을 아래에서 알 수 있다.
From worker 18: MyID=18
From worker 17: MyID=17
From worker 14: MyID=14
From worker 12: MyID=12
From worker 19: MyID=19
From worker 20: MyID=20
From worker 15: MyID=15
From worker 16: MyID=16
From worker 21: MyID=21
From worker 13: MyID=13
10-element Array{Int64,1}:
1
2
3
4
5
6
7
8
9
10