Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
391 views
in Technique[技术] by (71.8m points)

cluster computing - Using a loop variable in a Bash script to pass different command-line arguments

I have a C++ program to which I pass two doubles as inputs from the command line using

int main(int argc, char *argv[]){
    double a,b;
    a = atof(argv[1]);
    b = atof(argv[2]);
    further code.....

I run the code on a cluster using the qsub utility and I have a Bash script named 'jobsub.sh` to submit the jobs which looks like this:

#!/bin/csh -f
hostname
cd /home/roy/codes/3D             # Change directory first -- replace Mysubdir
set startdir = `pwd`               # Remember the directory we're in
if( ! -d /scratch/$USER ) then
    mkdir /scratch/$USER       # Create scratch directory
endif                              # If it does not exist
#cp infile12 /scratch/$USER     # Copy input file to scratch directory
cd /scratch/$USER                  # Change to scratch directory
#rm *.*
$HOME/codes/3D/autoA100.out 2.1 2.2          # Run a program
cp * $startdir         # Copy outputfiles back to where we started

At the terminal I do qsub jobsub.sh.

However, I want to run the same executable for different values of a and b in parallel on different cores. Is it possible to write a for loop in the Bash script so that I can do something like,

for i=1;i<=10;i++ {
   $HOME/codes/3D/autoA100.out 2+i*0.1 2+i*0.2
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

If you are submitting the execution script to a batch loader, then there is no way to have a simple loop do the execution like you want because the entire script is run on each node. However, most batch loaders provide environment variables to the user.

PBS, for example, has $PBS_ARRAYID, which specifies the unique ID for the job as it is running. So instead of using a loop, your script can have:

a=$(echo "2+($PBS_ARRAYID+1)*0.1" | bc -l)
b=$(echo "2+($PBS_ARRAYID+1)*0.2" | bc -l)
$HOME/codes/3D/autoA100.out $a $b

Notice I've added 1 to $PBS_ARRAYID above because the ID begins from 0 while your loop begins from 1. It's also worth mentioning that while bash can do some arithmetic natively, it cannot handle real numbers; that's why I had to invoke bc.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...