Julia

Julia is a high-level, high-performance dynamic programming language for technical computing, with syntax that is familiar to users of other technical computing environments.


Usage

Tradition mandates we start with a 'hello world' example. Create a file called hi.jl with your favorite text editor and add this code to it:

#!/usr/bin/env julia

# save a variable as a string
this_is_a_string = "Hello, world.\n"

# print a string
println(this_is_a_string)

Now we will need to load the Julia module and execute the script.

Command:

module load julia/julia-0.5.0
module list
srun julia hi.jl

Output:

[jgotberg@lewis4-r710-login-node223 training]$ module load julia/julia-0.5.0
[jgotberg@lewis4-r710-login-node223 training]$ module list
Currently Loaded Modulefiles:
  1) julia/julia-0.5.0
[jgotberg@lewis4-r710-login-node223 julia_fib]$ srun julia hi.jl
Hello, world.

[jgotberg@lewis4-r710-login-node223 julia_fib]$

Now let's find Fibonacci numbers in various ways using Julia. Copy the example below and copy it into a new file called fib.jl. We can execute this new script with the command:

Command:

srun julia fib.jl

Output:

[jgotberg@lewis4-r710-login-node223 julia_fib]$ srun julia fib.jl
** Start **
rfib(33) = 3524578
rfib_1line(33) = 3524578
sfib(33) = 3524578
** End **

Before we can run non-trivial algorithms we need to wrap our scripts with sbatch so they run on the correct worker nodes. Copy the text from the julia_sbatch.sh example below into a file of the same name. Now submit the script to the cluster:

Command:

sbatch julia_sbatch.sh

Output:

[jgotberg@lewis4-r710-login-node223 julia_fib]$ sbatch julia_sbatch.sh
Submitted batch job 551104

NOTE

Your job id# will be different from this example

Once the job is complete our results will appear in the results_julia-###.out file, where ### is your job id. In this example it was results_julia-551104.out.

Command:

ls
cat results_julia-551104.out

Output:

[jgotberg@lewis4-r710-login-node223 julia_fib]$ ls
fib.jl  hi.jl  julia_sbatch.sh  results_julia-551104.out
[jgotberg@lewis4-r710-login-node223 julia_fib]$ cat results_julia-551104.out
### Starting at: Fri Feb 17 02:42:20 CST 2017 ###
Currently Loaded Modulefiles:
  1) julia/julia-0.5.0
First core reporting from node:
lewis4-lenovo-hpc2-node282
Currently working in directory:
/home/jgotberg/training/julia_fib
Files in this folder:
total 102
-rw-rw-r--. 1 jgotberg jgotberg 1089 Feb 17 02:36 fib.jl
-rw-rw-r--. 1 jgotberg jgotberg  182 Feb 17 01:17 hi.jl
-rw-rw-r--. 1 jgotberg jgotberg 1271 Feb 17 01:10 julia_sbatch.sh
-rw-rw-r--. 1 jgotberg jgotberg  246 Feb 17 02:42 results_julia-551104.out
** Start **
rfib(33) = 3524578
rfib_1line(33) = 3524578
sfib(33) = 3524578
** End **
### Ending at: Fri Feb 17 02:42:42 CST 2017 ###

Now you are ready to use Julia.


Contents of Example Files

fib.jl:

#!/usr/bin/env julia
# header goes here
# JLG 2017-02
##

# recursive fibonacci algorithm
function rfib(n)
  if n == 0
    return 0
  elseif n == 1
    return 1
  elseif n < 0 || !isa(n, Number)
    println("Input must be a positive integer")
    return -1
  else
    return rfib(n-2) + rfib(n-1)
  end
end

# recursive fibonacci algorithm (one line, no input checking)
rfib_1line(n) = n < 2 ? n : rfib_1line(n-1) + rfib_1line(n-2)

## stored result fib onacci algorithm
function sfib(n)
  # initalize the results array
  results = zeros(Int, n)
  results[1] = 1
  results[2] = 1
  results[3] = 2

  # scrub input
  if n < 0 || !isa(n, Number)
    println("Input must be a positive integer")
    return -1
  elseif n < 3
    return results[n]
  else
    # only calculate each fib# once then add
    for i = 3:n
      results[i] = results[i-2] + results[i-1]
    end
    return results[n]
  end
end

# execute
println("** Start **")
n = 33
@printf("rfib(%d) = %d\n", n, rfib(n))
@printf("rfib_1line(%d) = %d\n", n, rfib_1line(n))
@printf("sfib(%d) = %d\n", n, sfib(n))
println("** End **")

julia_sbatch.sh:

#!/bin/bash
#-------------------------------------------------------------------------------
#  SBATCH CONFIG
#-------------------------------------------------------------------------------
## resources
#SBATCH -p General  # partition (which set of nodes to run on)
#SBATCH -N1  # nodes
#SBATCH -n1  # tasks (cores)
#SBATCH --mem=8G  # total RAM
#SBATCH -t 0-01:00  # time (days-hours:minutes)
#SBATCH --qos=normal  # qos level
#
## labels and outputs
#SBATCH -J julia_fib  # job name - shows up in sacct and squeue
#SBATCH -o results_julia-%j.out  # filename for the output from this job (%j = job#)
#SBATCH -A general  # investor account
#
## notifications
#SBATCH --mail-user=username@missouri.edu  # email address for notifications
#SBATCH --mail-type=END,FAIL  # which type of notifications to send
#
#-------------------------------------------------------------------------------

echo "### Starting at: $(date) ###"

# load modules then display what we have
module load julia/julia-0.5.0
module list

# Serial operations - only runs on the first core
echo "First core reporting from node:"
hostname

echo "Currently working in directory:"
pwd

echo "Files in this folder:"
ls -l

# Execute the julia fib script:
julia fib.jl

echo "### Ending at: $(date) ###"