[Julia] function내에서 동적 Module 로딩 및 분산처리

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

댓글 달기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다