Passing a parameter into a slurm script (matlab) - matlab

I am using slurm to submit jobs to the university supercomputer. My matlab function has one parameter:
function test(variable_1)
and my slurm file is (I am not sure if it is correct. I know how to define the value of the parameter in the slurm file, but I would like to pass the value to the slurm file as I need to run the matlab function many times with different values for the parameter):
#!/bin/bash -l
#SBATCH --time=2-00:00:00
#SBATCH --job-name="test"
#SBATCH --nodes=1
#SBATCH --ntasks=1
#SBATCH --mem=4gb
#SBATCH -p small
module load matlab/R2021a
matlab -nodisplay -nodesktop -nosplash -r "test variable_1"
I tried to use the following codes (for example, I would like to set variable_1=12) to submit the job but it did not work.
sbatch test.slurm 12
Can anyone help me with this issue? Thanks!

The first argument of the Bash script is stored in an environment variable named $1. So the last line of the script should be
matlab -nodisplay -nodesktop -nosplash -r "test $1"
Beware that if the argument is a number, you might need to first cast it to integer from string with str2num in your Matlab script.

Related

How to use LSB_JOBINDEX in bsub array job arguments in Platform LSF?

I would like to pass LSB_JOBINDEX to as an argument to my script instead of using an environment variable.
This makes my script more LSF agnostic and avoids creating a helper script that uses the environment variable.
However, I was not able to use LSB_JOBINDEX in arguments: it only works as part of the initial command string.
For example, from a bash shell, I use the test command:
bsub -J 'myjobname[1-4]' -o bsub%I.log \
'echo $LSB_JOBINDEX' \
'$LSB_JOBINDEX' \
\$LSB_JOBINDEX \
'$LSB_JOBINDEX' \
"\$LSB_JOBINDEX"
and the output of say bsub2.log is:
2 $LSB_JOBINDEX $LSB_JOBINDEX $LSB_JOBINDEX $LSB_JOBINDEX
So in this case, only the first $LSB_JOBINDEX got expanded, but not any of the following ones.
But I would rather not pass the entire command as a single huge string as the 'echo $LSB_JOBINDEX' in this example. I would prefer to just use separate arguments as in a regular bash command.
I've also tried to play around with %I but it only works for -o and related bsub options, not for the command itself.
Related: Referencing job index in LSF job array
Tested in LSF 10.1.0. Related documentation: https://www.ibm.com/support/knowledgecenter/en/SSWRJV_10.1.0/lsf_admin/job_array_cl_args.html
bsub will add single quotes around the arguments if the argument starts with $. For example. If the bsub command line is
bsub command -a $ARG1 -b $ARG2
Then bsub will add quotes to the arguments to the 2nd and 4th parameters. The command is stored like this
command -a '$ARG1' -b '$ARG2'
One way to prevent this is to put the commands in a script. Like this:
$ cat cmd
echo $LSB_JOBINDEX
echo "line 2"
echo $LSB_JOBINDEX
Then run your job like this:
$ bsub -I < cmd
Job <2669> is submitted to default queue <normal>.
<<Waiting for dispatch ...>>
<<Starting on hostA>>
0
line 2
0
Note that the -I is not needed. Its just so you can see the job output on the bsub's stdout.
EDIT
OK. Looks like this works. But its not really a serious answer since it's so ugly. The thing is that bsub will surround the argument with single quotes if the argument starts with $. So the strategy is to find some way to make sure that the first character in the argument isn't a $. One way is to put any character other than $ as the first character of the argument. Follow it by a backspace literal, followed by the $. Note that it needs to be the actual backspace character, not ^ followed by H. Use ctrl-v followed by a ctrl-h to get the literal appended to the command line.
$ bsub -I echo "x^H\$LSB_JOBINDEX" "x^H\$LSB_JOBINDEX"
Job <2686> is submitted to default queue <normal>.
<<Waiting for dispatch ...>>
<<Starting on hostA>>
0 0
EDIT2
A tab literal also works. Not that its much better.
$ bsub -I echo " \$LSB_JOBINDEX" " \$LSB_JOBINDEX"
Job <2687> is submitted to default queue <normal>.
<<Waiting for dispatch ...>>
<<Starting on hostA>>
0 0

Slurm task id as Matlab's function argument

I want to create a job array in slurm in a way such that it is called a Matlab function that depends on the array task id. I tried
#!/bin/bash
#SBATCH -J TEST
#SBATCH -p slims
#SBATCH -o o
#SBATCH -e e
matlab -r "test(${SLURM_ARRAY_TASK_ID})"
where test.m is the matlab function that I want to run. This throw the error "Not enough arguments in line 7 test.m ..."
How should I do it?
It looks like $SLURM_ARRAY_TASK_ID was not defined, and there is no --array parameter in your submission file. So unless you provided that argument on the command line
sbatch --array ... <yourscript.sh>
you did not tell Slurm to create an array.
Either add #SBATCH --array ... to your submission script or specify it on the command line.

Call sequential m-files batch file?

I want to write a batch file that calls sequentially 2 m-files. I want the second m-file (f.m) not to start before the end of the first m-file (main.m). The second m-file is repeated 4 times (4 tasks).
I have tried to use the wait option as below but it does not work.
#$ -S /bin/bash
#$ -l h_vmem=2G
#$ -l tmem=2G
#$ -cwd
#$ -j y
#$ -N example
#$ -t 1-4
echo "Task ID is $SGE_TASK_ID"
matlab -wait -nodisplay -nodesktop -nojvm -nosplash < main.m
matlab -nodisplay -nodesktop -nojvm -nosplash < f.m
What am I doing wrong?
You can either concatenate the contents of main.m and f.m together prior to piping them to MATLAB
cat main.m f.m | matlab -nodisplay -nodesktop -nojvm -nosplash
Or you can call the scripts by passing a command to MATLAB using the -r flag
matlab -nodisplay -nodesktop -nojvm -nosplash -r 'main; f; exit'
These are both going to be more performant than your approach since here we're only launching one instance of MATLAB.

assign parameters for cluster job with slurm sbatch

I am using slurm sbatch to parralel launch a matlab function on a cluster.
What is the proper syntax in my sbatch file in order to assign numeric parameters to the matlab function?
I have tried the following (and alike s):
#!/bin/bash
#SBATCH --partition=debug
#SBATCH --time=0-00:15:00
#SBATCH --cpus-per-task=12
#SBATCH -n1
VAR1=50
VAR2=40
BASE_MFILE_NAME=RUNAGT
MATLAB_MFILE=.m
srun --exclusive --cpus-per-task=12 matlab2013b/bin/matlab -nodesktop -nosplash -nodisplay -r "RUNAGT(${SLURM_ARRAY_TASK_ID},VAR1,VAR2);exit" -logfile testV${SLURM_ARRAY_TASK_ID}.log &
wait
${SLURM_ARRAY_TASK_ID} is working but matlab does not recognize VAR1 and VAR2.
error: Undefined function or variable 'VAR1'.
I believe it is not reading your variables because you are not putting a $ in front of them. You srun line should be:
srun --exclusive --cpus-per-task=12 matlab2013b/bin/matlab -nodesktop -nosplash -nodisplay -r "RUNAGT(${SLURM_ARRAY_TASK_ID},${VAR1},${VAR2});exit" -logfile testV${SLURM_ARRAY_TASK_ID}.log &

bsub and Matlab

I'm running matlab jobs on a remote server. The documentation says to run 'script.m', use the following command:
bsub -o script.out -R "rusage[matlab=1:duration=1]" matlab -nodisplay script
This doesn't seem to do much (or anything).
However,
bsub -o script.out -R "rusage[matlab=1:duration=1]" matlab -nodisplay -r "script"
works though. Any idea why the -r and quotation marks were omitted in the documentation? Was this simply a mistake, or am I misunderstanding something.
That looks just plain wrong to me, MATLAB has always needed the -r option to run a script.