1 /*****************************************************************************
2 * Copyright (c) 2019 FrontISTR Commons
3 * This software is released under the MIT License, see LICENSE.txt
4 *****************************************************************************/
5 /**
6 * \brief Startup routine for FrontISTR
7 */
8
9 #include <stdio.h>
10 #include <time.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <FrontISTRConfig.h>
14 #include "hecmw_log.h"
15 #ifndef HECMW_SERIAL
16 #include "mpi.h"
17 #else
18 #include <unistd.h>
19 #endif
20 #ifdef _OPENMP
21 #include <omp.h>
22 #endif /* _OPENMP */
23
24 extern void fstr_main();
25
26 /**
27 * \brief struct of command-line option
28 */
29 struct option_rec {
30 char *option_name;
31 void (*func)(char *);
32 };
33
get_procs_num()34 int get_procs_num(){
35 #ifndef HECMW_SERIAL
36 int proc;
37 MPI_Comm_size(MPI_COMM_WORLD, &proc);
38 return proc;
39 #else
40 return 1;
41 #endif
42 }
print_hostname()43 void print_hostname(){
44 int rank,proc;
45 int name_length = 256;
46 char name[name_length];
47 int ret,i;
48 #ifndef HECMW_SERIAL
49 MPI_Status status;
50 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
51 MPI_Comm_size(MPI_COMM_WORLD, &proc);
52 MPI_Get_processor_name(name, &name_length);
53 if (rank == 0){
54 printf(" %d: %s\n",0,name);
55 for (i=1;i<proc;i++){
56 ret = MPI_Recv(&name, name_length, MPI_CHAR, i, 0, MPI_COMM_WORLD, &status);
57 printf(" %d: %s\n",i,name);
58 }
59 }else{
60 ret = MPI_Send(&name, name_length, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
61 }
62 #else
63 gethostname(name, name_length);
64 printf(" %d: %s\n",0,name);
65 #endif
66 }
get_threads_num()67 int get_threads_num(){
68 #ifdef _OPENMP
69 return omp_get_max_threads();
70 #else
71 return 1;
72 #endif /* _OPENMP */
73 }
74
75 #ifdef _OPENMP
76 /**
77 * \brief Set number of OpenMP threads
78 */
set_num_threads(char * arg)79 void set_num_threads(char *arg) {
80 int exec_threads;
81
82 if (arg == NULL) {
83 fprintf(stderr, "Error : specify number of OpenMP threads.\n");
84 fprintf(stderr, "Format: -t <n>\n");
85 exit(1);
86 }
87
88 exec_threads = atoi(arg);
89
90 if (exec_threads == 0) {
91 fprintf(stderr, "Error : specify 1 or more OpenMP threads.\n");
92 exit(1);
93 }
94 omp_set_num_threads(exec_threads);
95 }
96 #endif /* _OPENMP */
97
98 /**
99 * \brief show available command line option
100 */
help(char * arg)101 void help(char *arg) {
102 printf("usage: [ mpirun -np <mpiprocs> ] fistr1 [options] \n");
103 printf(" -h: Show this help message.\n");
104 printf(" -v: Show version.\n");
105 #ifdef _OPENMP
106 printf(" -t <n>: Set number of OpenMP threads\n");
107 #endif
108 printf(" -c <Path of control file>: Use this control file. Default "
109 "./hecmw_ctrl.dat\n");
110 printf("--debug: Show debug messages.\n");
111 exit(0);
112 }
113
114 /**
115 * \brief show version and revision of FrontISTR
116 */
version(char * arg)117 void version(char *arg) {
118 #ifdef WITH_MPI
119 printf("MPI: Enabled\n");
120 #else
121 printf("MPI: Disabled\n");
122 #endif
123 #ifndef OPENMP_UNKNOWN
124 #ifdef WITH_OPENMP
125 printf("OpenMP: Enabled\n");
126 #else
127 printf("OpenMP: Disabled\n");
128 #endif
129 #else
130 printf("OpenMP: Unknown\n");
131 #endif
132 #ifdef HECMW_METIS_VER
133 printf("HECMW_METIS_VER: %d\n", HECMW_METIS_VER);
134 #endif
135 printf("CompileOption: ");
136 #ifdef WITH_MPI
137 printf("-p ");
138 #endif
139 #ifdef WITH_TOOLS
140 printf("--with-tools ");
141 #endif
142 #ifdef WITH_REFINER
143 printf("--with-refiner ");
144 #endif
145 #ifdef WITH_METIS
146 printf("--with-metis ");
147 #endif
148 #ifdef WITH_MUMPS
149 printf("--with-mumps ");
150 #endif
151 #ifdef WITH_LAPACK
152 printf("--with-lapack ");
153 #endif
154 #ifdef WITH_ML
155 printf("--with-ml ");
156 #endif
157 #ifdef WITH_PARMETIS
158 printf("--with-parmetis ");
159 #endif
160 #ifdef WITH_MKL
161 printf("--with-mkl ");
162 #endif
163 printf("\n");
164 exit(0);
165 }
166
167 /**
168 * \brief load hecmw_ctrl.dat from specified place
169 */
load_hecmw_ctrl(char * arg)170 void load_hecmw_ctrl(char *arg) {
171 fprintf(stderr, "Sorry this option cannot work yet. (-c)\n");
172 fprintf(stderr, "%s\n", arg);
173 exit(0);
174 }
175
176 /**
177 * \brief set log level to HECMW_LOG_DEBUG
178 */
set_loglevel_debug(char * arg)179 void set_loglevel_debug(char *arg) {
180 HECMW_setloglv(HECMW_LOG_DEBUG);
181 }
182
183 /**
184 * \brief specify command line option name and executing function name.
185 * \attension list must be terminated with NULL value.
186 */
187 struct option_rec options[] = {
188 {"-h", help},
189 {"-H", help},
190 {"-v", version},
191 {"-V", version},
192 #ifdef _OPENMP
193 {"-t", set_num_threads},
194 {"-T", set_num_threads},
195 #endif /* _OPENMP */
196 {"-c", load_hecmw_ctrl},
197 {"-C", load_hecmw_ctrl},
198 {"--debug", set_loglevel_debug},
199 {NULL, NULL}
200 };
201
202 /**
203 * \brief main function
204 */
main(int argc,char * argv[])205 int main(int argc, char *argv[])
206 {
207 char date[64];
208 struct option_rec *p;
209 unsigned int i;
210 int rank=0;
211 time_t t = time(NULL);
212
213 #ifndef HECMW_SERIAL
214 MPI_Init(&argc, &argv);
215 MPI_Comm_rank(MPI_COMM_WORLD, &rank);
216 #endif
217 if ( rank==0 ){
218 printf("##################################################################\n");
219 printf("# FrontISTR #\n");
220 printf("##################################################################\n");
221 printf("---\n");
222 if (VERSION_PATCH == 0){
223 printf("version: %d.%d\n", VERSION_MAJOR,VERSION_MINOR);
224 }else{
225 printf("version: %d.%d.%d\n", VERSION_MAJOR,VERSION_MINOR, VERSION_PATCH);
226 }
227 printf("git_hash: %s\n", GIT_HASH );
228 printf("build:\n");
229 printf(" date: %s\n", BUILD_DATE );
230 printf(" MPI: ");
231 #ifdef WITH_MPI
232 printf("enabled\n");
233 #else
234 printf("disabled\n");
235 #endif
236 printf(" OpenMP: ");
237 #ifndef OPENMP_UNKNOWN
238 #ifdef WITH_OPENMP
239 printf("enabled\n");
240 #else
241 printf("disabled\n");
242 #endif
243 #else
244 printf("unknown\n");
245 #endif
246 printf(" option: ");
247 printf("\"");
248 #ifdef WITH_MPI
249 printf("-p ");
250 #endif
251 #ifdef WITH_TOOLS
252 printf("--with-tools ");
253 #endif
254 #ifdef WITH_REFINER
255 printf("--with-refiner ");
256 #endif
257 #ifdef WITH_METIS
258 printf("--with-metis ");
259 #endif
260 #ifdef WITH_MUMPS
261 printf("--with-mumps ");
262 #endif
263 #ifdef WITH_LAPACK
264 printf("--with-lapack ");
265 #endif
266 #ifdef WITH_ML
267 printf("--with-ml ");
268 #endif
269 #ifdef WITH_PARMETIS
270 printf("--with-parmetis ");
271 #endif
272 #ifdef WITH_MKL
273 printf("--with-mkl ");
274 #endif
275 printf("\"");
276 printf("\n");
277 #ifdef HECMW_METIS_VER
278 printf(" HECMW_METIS_VER: %d\n", HECMW_METIS_VER);
279 #endif
280 }
281
282 for (i = 0; i < argc; i++) {
283 for (p = options; p->option_name != NULL; p++) {
284 if (strncmp(p->option_name, argv[i], strlen(p->option_name)) == 0) {
285 p->func(argv[i + 1]);
286 }
287 }
288 }
289 if ( rank==0 ){
290 printf("execute: \n");
291 strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S%z", localtime(&t));
292 printf(" date: %s\n", date);
293 printf(" processes: %d\n", get_procs_num());
294 printf(" threads: %d\n", get_threads_num());
295 printf(" cores: %d\n", get_threads_num()*get_procs_num());
296 printf(" host:\n");
297 }
298 print_hostname();
299 if ( rank==0 ){
300 printf("---\n");
301 printf("...\n");
302 }
303 #ifndef HECMW_SERIAL
304 MPI_Barrier( MPI_COMM_WORLD );
305 #endif
306 fstr_main();
307 return 0;
308 }
309