Julia cluster install with MPI packages

Julia is a high-level, high-performance dynamic language for technical computing. With a "just in time" compiler, it is very fast, especially compared to languages like MATLAB, Octave, R etc. However it is relatively new and a cluster installation and package deployment has a few quirks.

Download the source from github. By default you will be building the latest unstable version of Julia from the git checkout. However, we want to run 0.4.0 (or rather, 0.4rc4) which is the last stable release.


# cd /usr/local/src/JULIA
# git clone git://github.com/JuliaLang/julia.git
# mv julia 0.4.0
# cd 0.4.0
# git checkout release-0.4

GCC version 4.7 or later is required to build Julia. Using 4.8.2 as it was used for benchmarks.


# module load gcc/4.8.2

For scientific computing with environment modules, you will want a specific path.


# mkdir -p /usr/local/julia/0.4.0

Write `prefix=/path/to/install/folder` into `Make.user` (indented by a tab, obviously, to satisfy Makefile syntax).

Load environment modules for dependencies.


# module load perl/5.16.2
# moodule load git/2.6.1
# module load m4/1.4.17
# module load curl/7.33.0


# module list
Currently Loaded Modulefiles:
1) gmp/4.3.2 3) mpc/0.8.1 5) m4/1.4.17 7) cmake/2.8.10.1 9) git/2.6.1
2) mpfr/2.4.2 4) libelf/0.8.9 6) gcc/4.8.2 8) curl/7.33.0 10) perl/5.16.2


# make

Don't do make -j x, it loses it's head c.f., https://github.com/JuliaLang/julia/issues/12582

Not there is a sometimes processor-specific requirements.


make[2]: *** [libs] Error 1
\033[33;1m*** Clean the OpenBLAS build with 'make -C deps clean-openblas'. Rebuild with 'make OPENBLAS_USE_THREAD=0' if OpenBLAS had trouble linking libpthread.so, and with 'make OPENBLAS_TARGET_ARCH=NEHALEM' if there were errors building SandyBridge support. Both these options can also be used simultaneously. ***\033[0m
make[1]: *** [openblas/libopenblas64_.so] Error 1

Applies these and run make install.


# make OPENBLAS_USE_THREAD=0 OPENBLAS_TARGET_ARCH=NEHALEM
# make install

Create a base environment modules and link to it.


# mkdir -p /usr/local/Modules/modulefiles/julia
# cd /usr/local/Modules/modulefiles/julia
# ln -s .base 0.4.0

The .base file looks like the following. Note the check for GCC and the package directory path. The last line is very important if you want system-wide packages. Julia will create subdirectories within that for its own versions.


#%Module1.0#####################################################################
##
## $name modulefile
##
set ver [lrange [split [ module-info name ] / ] 1 1 ]
set name [lrange [split [ module-info name ] / ] 0 0 ]
set loading [module-info mode load]
set desc [join [read [ open "/usr/local/Modules/modulefiles/$name/.desc" ] ] ]
proc ModulesHelp { } {
puts stderr "\tThis module sets the envinronment for $name v$ver"
}
module-whatis "$desc (v$ver)"
if { $loading } {
module load gcc/4.8.2
}
prepend-path --delim " " CPPFLAGS -I/usr/local/$name/$ver/include
prepend-path --delim " " LDFLAGS -L/usr/local/$name/$ver/lib
prepend-path LD_LIBRARY_PATH /usr/local/$name/$ver/lib
prepend-path PKG_CONFIG_PATH /usr/local/$name/$ver/lib/pkgconfig
prepend-path PATH /usr/local/$name/$ver/bin
prepend-path MANPATH /usr/local/$name/$ver/share/man
prepend-path JULIA_PKGDIR /usr/local/$name/packages

A list of packages are available at the following URL: http://pkg.julialang.org/

Install packages and environment modules. You'll want to load the paths for OpenMPI for the MPI package!


# cd /usr/local/julia/0.4.0
# module load cmake
# module load openmpic-gcc/1.7.0
# julia
julia> Pkg.status()
No packages installed
julia> Pkg.add("MPI")
julia> Pkg.add("JuMP")
julia> Pkg.add("MatlabCompat")
julia> Pkg.add("Plots")
julia> Pkg.add("RDatasets")

Test as user, with parallel with an interactive PBS job.


[~]$ qsub -l nodes=1:ppn=2,walltime=0:30:0 -I
[179 ~]$ module load julia
[179 ~]$ module load openmpi-gcc
[179 ~]$ julia -p 2
julia> r = remotecall(2, rand, 2, 2)
RemoteRef{Channel{Any}}(2,1,3)
julia> fetch(r)
2x2 Array{Float64,2}:
0.271799 0.930905
0.761982 0.703684

Compare these results with single core


julia> r = remotecall(2, rand, 2, 2)
RemoteRef{Channel{Any}}(2,1,3)
julia> fetch(r)
2x2 Array{Float64,2}:
0.927498 0.902214
0.472731 0.917804