[17] | 1 | #include <sys/types.h> |
---|
| 2 | #include <dirent.h> |
---|
| 3 | #include <errno.h> |
---|
| 4 | #include <string.h> |
---|
| 5 | #include <stdlib.h> |
---|
| 6 | #include <vector> |
---|
| 7 | #include <string> |
---|
| 8 | #include <iostream> |
---|
| 9 | #include <fstream> |
---|
| 10 | |
---|
| 11 | #include <mpi.h> |
---|
| 12 | |
---|
| 13 | using namespace std; |
---|
| 14 | |
---|
| 15 | /* |
---|
| 16 | These two variables sets the command to launch in each sub-directory and the arguments required. The name of the root directory of the datasets is given as an argument when starting the MPIlauncher. |
---|
| 17 | const string commandToLaunch("/HA/sources/begou/SOURCES/MES-PROJETS/MPILAUNCHER/appli.exe"); |
---|
| 18 | const string("-l -info"); |
---|
| 19 | */ |
---|
| 20 | |
---|
| 21 | /* |
---|
| 22 | getListOfDir(string rep, vector<string> &files) |
---|
| 23 | |
---|
| 24 | Gets the list of tjhe subdirectories in the directory rep and returns them |
---|
| 25 | in a vector array of strings. Directories ";" and ".." are removed from the |
---|
| 26 | vector array. |
---|
| 27 | */ |
---|
| 28 | int getListOfDir(string rep, vector<string> &files) |
---|
| 29 | { |
---|
| 30 | DIR *dir; |
---|
| 31 | struct dirent *ent; |
---|
| 32 | int count; |
---|
| 33 | |
---|
| 34 | count=0; |
---|
| 35 | dir = opendir (rep.c_str()); |
---|
| 36 | if (dir != NULL) { |
---|
| 37 | /* search for the files within directory */ |
---|
| 38 | while ((ent = readdir (dir)) != NULL) |
---|
| 39 | if (ent->d_type == DT_DIR) { |
---|
| 40 | if (strcmp(ent->d_name,".") * strcmp(ent->d_name,"..")) { |
---|
| 41 | count++; |
---|
| 42 | files.push_back(string(ent->d_name)); |
---|
| 43 | } |
---|
| 44 | } |
---|
| 45 | closedir (dir); |
---|
| 46 | } |
---|
| 47 | else { |
---|
| 48 | cerr<<"Directory "<<rep.c_str()<<" not found"<<endl; |
---|
| 49 | } |
---|
| 50 | return count; |
---|
| 51 | } |
---|
| 52 | /* getListOfCommand(string rep, vector<string> &files) |
---|
| 53 | Gets the list of commands in the ascii file fich. One command per line (no wrap) |
---|
| 54 | in this first version. |
---|
| 55 | */ |
---|
| 56 | int getListOfCommand(const string & fich, vector<string> &commands) |
---|
| 57 | { |
---|
| 58 | int count; |
---|
| 59 | string line; |
---|
| 60 | |
---|
| 61 | count=0; |
---|
| 62 | commands.clear(); |
---|
| 63 | |
---|
| 64 | std::ifstream infile (fich.c_str(), std::ios_base::in); |
---|
| 65 | while (getline(infile, line, '\n')) |
---|
| 66 | { |
---|
| 67 | // remove all trailing blanks |
---|
| 68 | while(line.size() >0 && isspace(line[line.size() -1])) line.erase(line.size() -1); |
---|
| 69 | |
---|
| 70 | // no empty line |
---|
| 71 | if (line.size() > 0) { |
---|
| 72 | commands.push_back (line); |
---|
| 73 | count++; |
---|
| 74 | } |
---|
| 75 | } |
---|
| 76 | return count; |
---|
| 77 | } |
---|
| 78 | |
---|
| 79 | |
---|
| 80 | |
---|
| 81 | /* |
---|
| 82 | Main program |
---|
| 83 | */ |
---|
| 84 | int main(int argc, char **argv) |
---|
| 85 | { |
---|
| 86 | vector<string> files = vector<string>(); |
---|
| 87 | string rep; //root directory where to find subdirectories |
---|
| 88 | int rank, size, nbdir, stride; |
---|
| 89 | int nbcmd; |
---|
| 90 | /* |
---|
| 91 | These two variables sets the command to launch in each sub-directory and the arguments required. The name of the root directory of the datasets is given as an argument when starting the MPIlauncher. |
---|
| 92 | */ |
---|
| 93 | string commandToLaunch; |
---|
| 94 | string arguments; |
---|
| 95 | string commandfile; |
---|
| 96 | |
---|
| 97 | string finalCommand; //command to execute |
---|
| 98 | |
---|
| 99 | MPI_Init (&argc, &argv); /* starts MPI */ |
---|
| 100 | MPI_Comm_rank (MPI_COMM_WORLD, &rank); /* get current process id */ |
---|
| 101 | MPI_Comm_size (MPI_COMM_WORLD, &size); /* get number of processes */ |
---|
| 102 | |
---|
| 103 | if (argc<3){ |
---|
| 104 | cout<<"USAGE:"<<endl; |
---|
| 105 | cout<<argv[0]<<" root_directory command [arguments]"<<endl; |
---|
| 106 | cout<<argv[0]<<" -f command_file"<<endl; |
---|
| 107 | } |
---|
| 108 | else { |
---|
| 109 | if (strcmp(argv[1],"-f")==0) { |
---|
| 110 | /* processing a command file now. */ |
---|
| 111 | commandfile=argv[2]; |
---|
| 112 | nbcmd=getListOfCommand(commandfile, files); |
---|
| 113 | // if (rank==0){ |
---|
| 114 | // cout<<"Command file is "<<commandfile<<endl; |
---|
| 115 | // for (unsigned int i = 0;i < nbcmd;i++) |
---|
| 116 | // cout<<"["<<files[i]<<"]"<<endl; |
---|
| 117 | // } |
---|
| 118 | |
---|
| 119 | |
---|
| 120 | //Number of commands should divide by number of cpus |
---|
| 121 | // if (nbcmd%size != 0) { |
---|
| 122 | // if(rank ==0) |
---|
| 123 | // cerr <<nbcmd<<" command(s) to process in "<<commandfile |
---|
| 124 | // <<" cannot fit on "<<size<<" processe(s)" |
---|
| 125 | // <<endl<<"FAILED"<<endl; |
---|
| 126 | // } |
---|
| 127 | // else { |
---|
| 128 | // execute the command |
---|
| 129 | int reste; |
---|
| 130 | stride=nbcmd/size; |
---|
| 131 | for (unsigned int i = 0;i < stride;i++) { |
---|
| 132 | cerr<<"Process "<<rank<<" execute "<<files[stride*rank+i] <<endl; |
---|
| 133 | system(files[stride*rank+i].c_str() ); |
---|
| 134 | } |
---|
| 135 | //remaining command lines |
---|
| 136 | reste=nbcmd-stride*size; |
---|
| 137 | if(rank>0 && rank<=reste){ |
---|
| 138 | cerr<<"Process "<<rank<<" execute "<<files[nbcmd-rank] <<endl; |
---|
| 139 | system(files[nbcmd-rank].c_str() ); |
---|
| 140 | } |
---|
| 141 | // } |
---|
| 142 | } |
---|
| 143 | else { |
---|
| 144 | /* processing a list of dir now */ |
---|
| 145 | rep=string(argv[1]); |
---|
| 146 | commandToLaunch=string(argv[2]); |
---|
| 147 | for (int i=3; i<argc; i++) (arguments+=argv[i])+=" "; |
---|
| 148 | |
---|
| 149 | nbdir=getListOfDir(rep, files); |
---|
| 150 | |
---|
| 151 | //Number of dir should divide by number of cpus |
---|
| 152 | if (nbdir%size != 0) { |
---|
| 153 | if(rank ==0) |
---|
| 154 | cerr <<nbdir<<" dataset(s) to process cannot fit on "<<size<<" processes"<<endl<<"FAILED"<<endl; |
---|
| 155 | } |
---|
| 156 | else { |
---|
| 157 | // execute the command |
---|
| 158 | stride=nbdir/size; |
---|
| 159 | for (unsigned int i = 0;i < stride;i++) { |
---|
| 160 | string finalCommand("cd "); |
---|
| 161 | finalCommand +=rep; |
---|
| 162 | finalCommand +="/"; |
---|
| 163 | finalCommand += files[stride*rank+i]; |
---|
| 164 | finalCommand +=";"; |
---|
| 165 | finalCommand +=commandToLaunch; |
---|
| 166 | finalCommand +=" "; |
---|
| 167 | finalCommand +=arguments; |
---|
| 168 | //cout<<"On "<<rank<<" execute "<<finalCommand<<endl; |
---|
| 169 | system(finalCommand.c_str() ); |
---|
| 170 | } |
---|
| 171 | } |
---|
| 172 | } |
---|
| 173 | } |
---|
| 174 | MPI_Finalize(); |
---|
| 175 | |
---|
| 176 | return 0; |
---|
| 177 | } |
---|