source: trunk/oar/mpilauncher.cpp @ 24

Last change on this file since 24 was 24, checked in by g7moreau, 12 years ago
  • Update man
  • Property svn:eol-style set to native
File size: 5.8 KB
Line 
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
13using namespace std;
14
15/*
16 * These two variables sets the command to launch in each sub-directory
17 * and the arguments required. The name of the root directory of the
18 * datasets is given as an argument when starting the MPIlauncher. const
19 * string
20 * commandToLaunch("$HOME/SOURCES/MES-PROJETS/MPILAUNCHER/appli.exe");
21 * const string("-l -info");
22 */
23
24/*
25 * getListOfDir(string rep, vector<string> &files)
26 *
27 * Gets the list of tjhe subdirectories in the directory rep and returns
28 * them in a vector array of strings. Directories ";" and ".." are removed
29 * from the vector array.
30 */
31int getListOfDir(string rep, vector < string > &files) {
32   DIR *dir;
33   struct dirent *ent;
34   int count;
35
36   count = 0;
37   dir = opendir(rep.c_str());
38   if (dir != NULL) {
39      /*
40       * search for the files within directory
41       */
42      while ((ent = readdir(dir)) != NULL)
43         if (ent->d_type == DT_DIR) {
44            if (strcmp(ent->d_name, ".") *
45                  strcmp(ent->d_name, "..")) {
46               count++;
47               files.push_back(string(ent->d_name));
48               }
49            }
50      closedir(dir);
51      }
52   else {
53      cerr << "Directory " << rep.c_str() << " not found" << endl;
54      }
55   return count;
56   }
57
58/*
59 * getListOfCommand(string rep, vector<string> &files) Gets the list of
60 * commands in the ascii file fich. One command per line (no wrap) in this
61 * first version.
62 */
63int getListOfCommand(const string & fich, vector < string > &commands) {
64   int count;
65   string line;
66
67   count = 0;
68   commands.clear();
69
70   std::ifstream infile(fich.c_str(), std::ios_base::in);
71   while (getline(infile, line, '\n')) {
72      // remove all trailing blanks
73      while (line.size() > 0 && isspace(line[line.size() - 1]))
74         line.erase(line.size() - 1);
75
76      // no empty line
77      if (line.size() > 0) {
78         commands.push_back(line);
79         count++;
80         }
81      }
82   return count;
83   }
84
85/*
86 * Main program
87 */
88int main(int argc, char **argv) {
89   vector < string > files = vector < string > ();
90   string rep;          // root directory where to find
91   // subdirectories
92   int rank, size, nbdir, stride;
93   int nbcmd;
94   /*
95    * These two variables sets the command to launch in each
96    * sub-directory and the arguments required. The name of the root
97    * directory of the datasets is given as an argument when starting the
98    * MPIlauncher.
99    */
100   string commandToLaunch;
101   string arguments;
102   string commandfile;
103
104   string finalCommand; // command to execute
105
106   MPI_Init(&argc, &argv);      /* starts MPI */
107   MPI_Comm_rank(MPI_COMM_WORLD, &rank);        /* get current process id */
108   MPI_Comm_size(MPI_COMM_WORLD, &size);        /* get number of processes
109                                                 */
110
111   if (argc < 3) {
112      cout << "USAGE:" << endl;
113      cout << argv[0] << " root_directory  command [arguments]" <<
114           endl;
115      cout << argv[0] << " -f  command_file" << endl;
116      }
117   else {
118      if (strcmp(argv[1], "-f") == 0) {
119         /*
120          * processing a command file now.
121          */
122         commandfile = argv[2];
123         nbcmd = getListOfCommand(commandfile, files);
124         // if (rank==0){
125         // cout<<"Command file is "<<commandfile<<endl;
126         // for (unsigned int i = 0;i < nbcmd;i++)
127         // cout<<"["<<files[i]<<"]"<<endl;
128         // }
129
130         // Number of commands should divide by number of cpus
131         // if (nbcmd%size != 0) {
132         // if(rank ==0)
133         // cerr <<nbcmd<<" command(s) to process in "<<commandfile
134         // <<" cannot fit on "<<size<<" processe(s)"
135         // <<endl<<"FAILED"<<endl;
136         // }
137         // else {
138         // execute the command
139         int reste;
140         stride = nbcmd / size;
141         for (unsigned int i = 0; i < stride; i++) {
142            cerr << "Process " << rank << " execute " <<
143                 files[stride * rank + i] << endl;
144            system(files[stride * rank + i].c_str());
145            }
146         // remaining command lines
147         reste = nbcmd - stride * size;
148         if (rank > 0 && rank <= reste) {
149            cerr << "Process " << rank << " execute " <<
150                 files[nbcmd - rank] << endl;
151            system(files[nbcmd - rank].c_str());
152            }
153         // }
154         }
155      else {
156         /*
157          * processing a list of dir now
158          */
159         rep = string(argv[1]);
160         commandToLaunch = string(argv[2]);
161         for (int i = 3; i < argc; i++)
162            (arguments += argv[i]) += " ";
163
164         nbdir = getListOfDir(rep, files);
165
166         // Number of dir should divide by number of cpus
167         if (nbdir % size != 0) {
168            if (rank == 0)
169               cerr << nbdir <<
170                    " dataset(s) to process cannot fit on "
171                    << size << " processes" << endl <<
172                    "FAILED" << endl;
173            }
174         else {
175            // execute the command
176            stride = nbdir / size;
177            for (unsigned int i = 0; i < stride; i++) {
178               string finalCommand("cd ");
179               finalCommand += rep;
180               finalCommand += "/";
181               finalCommand +=
182                  files[stride * rank + i];
183               finalCommand += ";";
184               finalCommand += commandToLaunch;
185               finalCommand += " ";
186               finalCommand += arguments;
187               // cout<<"On "<<rank<<" execute "<<finalCommand<<endl;
188               system(finalCommand.c_str());
189               }
190            }
191         }
192      }
193   MPI_Finalize();
194
195   return 0;
196   }
197
198/*
199 * documentation POD format
200 *
201 * =head1 NAME
202 *
203 *  mpilauncher - parallel execute lot of small job via mpi
204 *
205 * =head1 SYNOPSIS
206 *
207 *  mpilauncher root_folder command [args]
208 *  mpilauncher -f command_file
209 *
210 * =cut
211 *
212 */
Note: See TracBrowser for help on using the repository browser.