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 | } |
---|