From a34c9714ab5e4f83deb7a72efe78b807229ca52c Mon Sep 17 00:00:00 2001 From: Michael Krayer Date: Tue, 19 Jan 2021 13:13:42 +0100 Subject: [PATCH] initial commit --- README.md | 8 ++++ build | 2 + src/mkparallel.cc | 93 +++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 README.md create mode 100755 build create mode 100644 src/mkparallel.cc diff --git a/README.md b/README.md new file mode 100644 index 0000000..b4e4865 --- /dev/null +++ b/README.md @@ -0,0 +1,8 @@ +mkparallel +--- +Execute a serial command embarassingly parallel. +Usage: +mpirun -n mkparallel + + is the command to be executed where every occurence of {} will be replaced by the rank of the processor. +The rank can be padded with leading zeros by specifying with a value greater than zero. diff --git a/build b/build new file mode 100755 index 0000000..26ca250 --- /dev/null +++ b/build @@ -0,0 +1,2 @@ +#!/bin/bash +mpicxx -o mkparallel src/mkparallel.cc diff --git a/src/mkparallel.cc b/src/mkparallel.cc new file mode 100644 index 0000000..a31a5e5 --- /dev/null +++ b/src/mkparallel.cc @@ -0,0 +1,93 @@ +#include +#include +#include +#include +#include + +using namespace std; + +string toStringZeroPadded(int,int); +void replaceAll(string&r,const string&,const string&); + +int main(int argc,char *argv[]) +{ + int ierr; + int nproc; + int rank; + MPI_Status status; + + ierr = MPI_Init(&argc,&argv); + ierr = MPI_Comm_rank(MPI_COMM_WORLD,&rank); + ierr = MPI_Comm_size(MPI_COMM_WORLD,&nproc); + + // Check positional arguments + if(argc!=3){ + cerr << "Usage: mpirun -n " << nproc << " " << argv[0] << " \n" + << " command to be executed embarassingly parallel. {} is replaced by rank\n" + << " number of leading zeros for rank replacement\n"; + MPI_Finalize(); + return 1; + } + + // Parse command line arguments + string arg_cmd = argv[1]; + string arg_digits = argv[2]; + int digits; + try{ + digits = stoi(arg_digits); + } + catch(const invalid_argument& ia){ + cerr << "Invalid argument to " << ia.what() << ": " << arg_digits << endl; + return 2; + } + + // Construct command to be executed + string str_cmd = arg_cmd; + string str_rank; + if(digits>0) + str_rank = toStringZeroPadded(rank,digits); + else + str_rank = to_string(rank); + replaceAll(str_cmd,"{}",str_rank); + cerr << "Rank " << rank << " is executing: " << str_cmd << endl; + + // Run command and return exit code + int exitcode = system(str_cmd.c_str()); + cerr << "Rank " << rank << " finished with exitcode " << exitcode << endl; + + // Finalize + MPI_Finalize(); + return 0; +} + +string toStringZeroPadded(int val,int pad){ + char tmp[pad]; + string str; + sprintf(tmp,"%0*d",pad,val); + str = tmp; + return str; +} + +void replaceAll(string& str,const string& from,const string& to){ + if(from.empty()) + return; + size_t start_pos = 0; + while((start_pos=str.find(from,start_pos))!=string::npos){ + str.replace(start_pos,from.length(),to); + start_pos+=to.length(); // In case 'to' contains 'from', like replacing 'x' with 'yx' + } +} + +/* +int checkMpiError(int ierr){ + char msg[MPI_MAX_ERROR_STRING]; + int msglen, ierr2; + if(ierr!=0){ + ierr2 = MPI_Error_string(ierr,msg,&msglen); + cout << msg << endl; + return ierr2; + } + else + return 0; +} +*/