Batch Remote Execution

Runit.jl scripts that call the function EarthBox.run_earthbox to run Model.jl and Plot.jl scripts in the background via command line can be run on remote machines using the function remote_model_loop. See execute_remote_script_in_background for details how passwordless ssh accessed is used for remote execution.

Linux/Unix Only

Remote model execution functions are compatible with Linux/Unix operating systems only.

module RunitRemote

using EarthBox

function run_remote_models()
    model_dir_path = "/mnt/extradrive1/nfs/apps/julia/EarthBox/models/extension_to_sfs/extension_strong_zones"
    models = Dict(
        "hostname1" => ["case0", "case1"],
        "hostname2" => ["case0", "case1", "case2"],
    )
    remote_model_loop(
        models,
        model_dir_path,
        run_model = true,
        plot_markers = false,
        plot_scalars = false,
        istart = 1,
        iend = 100
    )
end

end # module

if abspath(PROGRAM_FILE) == @__FILE__
    RunitRemote.run_remote_models()
end

Remote Model Loop

EarthBox.RunTools.remote_model_loopFunction
remote_model_loop(;
    models::Dict{String, Vector{String}},
    model_dir_path::String,
    run_model::Union{Bool, Nothing} = nothing,
    plot_markers::Union{Bool, Nothing} = nothing,
    plot_scalars::Union{Bool, Nothing} = nothing,
    istart::Union{Int64, Nothing} = nothing,
    iend::Union{Int64, Nothing} = nothing
)

Execute a script on a remote machine in the background by looping over the function execute_remote_script_in_background for each model case.

!!! WARNING !!! This function is for Linux/Unix systems only.

Arguments

  • models::Dict{String, Vector{String}}
    • A dictionary of host names and model case names like:
      • "hostname1" => ["case0", "case1", "case2"]
      • "hostname2" => ["case3", "case4", "case5"]
  • model_dir_path::String
    • The path to the directory that contains the model directories
  • run_model::Union{Bool, Nothing}
    • Run the model (default: nothing)
  • plot_markers::Union{Bool, Nothing}
    • Plot markers (default: nothing)
  • plot_scalars::Union{Bool, Nothing}
    • Plot scalars (default: nothing)
  • istart::Union{Int64, Nothing}
    • Start index for plotting (default: nothing)
  • iend::Union{Int64, Nothing}
    • End index for plotting (default: nothing)
source

Executing Remote Scripts in the Background

EarthBox.RunTools.execute_remote_script_in_backgroundFunction
execute_remote_script_in_background(;
    hostname::String,
    model_dir_path::String,
    model_case_name::String,
    run_model::Union{Bool, Nothing} = nothing,
    plot_markers::Union{Bool, Nothing} = nothing,
    plot_scalars::Union{Bool, Nothing} = nothing,
    istart::Union{Int64, Nothing} = nothing,
    iend::Union{Int64, Nothing} = nothing
)

This function runs the Runit.jl script on a remote machine in the background as follows:

ssh <hostname> 'cd <model_dir_path> && nohup julia --startup=no <model_dir_path>/Runit.jl case_name=<case_name> <runit_actions> <istart_iend> > /dev/null 2>&1 &'

where:

  • <hostname> is the name of the remote machine.
  • <model_dir_path> is the path to the directory that contains the model input files and the Runit.jl script.
  • <model_case_name> is the name of the model case like "case0", "case1", "case2", etc.
  • <runit_actions> are the actions to be taken by the Runit.jl script like "runmodel", "plotmarkers", "plot_scalars" or a combination of these separated by spaces.
  • <istart_iend> are the starting and ending time steps. For example, "istart=1 iend=10".

The Runit.jl script should be in a model directory that contains Model.jl and Plot.jl scripts that are properly configured and setup for command-line execution of the run_earthbox() function. For example, the Runit.jl script should contain the following code or similar code that achieves the same result:

module Runit

using EarthBox
include("Model.jl")
import .Model: EB_PROJECT_PATH, ROOT_PATH_OUTPUT
run_earthbox(
    model_dir = PATH_TO_MODEL_DIRECTORY,
    eb_project_path_from_script = EB_PROJECT_PATH,
    root_path_output_from_script = ROOT_PATH_OUTPUT
    )

end

if abspath(PROGRAM_FILE) == @__FILE__
    Runit.main()
end

Arguments

  • hostname::String
    • The name of the remote machine.
  • model_dir_path::String
    • The path to the directory that contains the model input files and the Runit.jl script.
  • model_case_name::String
    • The name of the model case. This is the name of the case that will be executed as defined in the model script like "case0", "case1", "case2", etc.
  • run_model::Union{Bool, Nothing}
    • Run the model (default: nothing)
  • plot_markers::Union{Bool, Nothing}
    • Plot markers (default: nothing)
  • plot_scalars::Union{Bool, Nothing}
    • Plot scalars (default: nothing)
  • istart::Union{Int64, Nothing}
    • Starting time step. Default is 1.
  • iend::Union{Int64, Nothing}
    • Ending time step. Default is nothing.

It is assumed that passwordless SSH access is configured for the remote machine and hostnames are resolved to IP addresses.

Setting up passwordless SSH access

On Ubuntu/PopOS/Debian-based systems you can map IP addresses to hostnames in the /etc/hosts file by editing the file with the following command:

sudo vi /etc/hosts

and adding an IP-address and hostname pair on each line for each remote machine.

Passwordless SSH access can be configured on Ubuntu/PopOS/Debian-based systems by following the instructions:

[1] Generate SSH key files:

ssh-keygen -t rsa

Use id_rsa for the private key that will be located at /home/username/.ssh and follow the prompts to enter a passphrase or use an empty passphrase. A public key file will also be created that will be shared with the remote machine (see step [2] below).

[2] Copy the public SSH key to the remote machine:

ssh-copy-id <username>@<hostname>
source