FrontISTR  5.9.0
Large-scale structural analysis program with finit element method
main.c
Go to the documentation of this file.
1 /*****************************************************************************
2  * Copyright (c) 2019 FrontISTR Commons
3  * This software is released under the MIT License, see LICENSE.txt
4  *****************************************************************************/
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 #ifdef _OPENACC
18 #include <openacc.h>
19 #endif
20 #else
21 #include <unistd.h>
22 #endif
23 #ifdef _OPENMP
24 #include <omp.h>
25 #endif /* _OPENMP */
26 #ifdef WITH_MKL
27 #include <mkl.h>
28 #endif
29 #ifdef WITH_NETCDF
30 #include <netcdf.h>
31 #endif
32 
33 extern void fstr_main();
34 
38 struct option_rec {
39  char *option_name;
40  void (*func)(char *);
41 };
42 
44 #ifndef HECMW_SERIAL
45  int proc;
46  MPI_Comm_size(MPI_COMM_WORLD, &proc);
47  return proc;
48 #else
49  return 1;
50 #endif
51 }
52 
54 #ifdef _OPENMP
55  return omp_get_max_threads();
56 #else
57  return 1;
58 #endif /* _OPENMP */
59 }
60 
61 #ifdef _OPENMP
65 void set_num_threads(char *arg) {
66  int exec_threads;
67 
68  if (arg == NULL) {
69  fprintf(stderr, "Error : specify number of OpenMP threads.\n");
70  fprintf(stderr, "Format: -t <n>\n");
71  exit(1);
72  }
73 
74  exec_threads = atoi(arg);
75 
76  if (exec_threads == 0) {
77  fprintf(stderr, "Error : specify 1 or more OpenMP threads.\n");
78  exit(1);
79  }
80  omp_set_num_threads(exec_threads);
81 #ifdef WITH_MKL
82  mkl_set_num_threads(exec_threads);
83 #endif
84 
85 }
86 #endif /* _OPENMP */
87 
91 void help(char *arg) {
92  printf("usage: [ mpirun -np <mpiprocs> ] fistr1 [options] \n");
93  printf(" -h: Show this help message.\n");
94  printf(" -v: Show version.\n");
95 #ifdef _OPENMP
96  printf(" -t <n>: Set number of OpenMP threads\n");
97 #endif
98  printf(" -c <Path of control file>: Use this control file. Default "
99  "./hecmw_ctrl.dat\n");
100  printf("--debug: Show debug messages.\n");
101  exit(0);
102 }
103 
107 void print_buildinfo(int log_level) {
108  int rank;
109 #ifndef HECMW_SERIAL
110  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
111  if (rank!=0) return;
112 #endif
113  printf("##################################################################\n");
114  printf("# FrontISTR #\n");
115  printf("##################################################################\n");
116  printf("---\n");
117  if (VERSION_PATCH == 0){
118  printf("version: %d.%d\n", VERSION_MAJOR, VERSION_MINOR);
119  }else{
120  printf("version: %d.%d.%d\n", VERSION_MAJOR, VERSION_MINOR, VERSION_PATCH);
121  }
122  printf("git_hash: %s\n", GIT_HASH );
123  printf("build:\n");
124  printf(" date: %s\n", BUILD_DATE );
125 #ifdef WITH_MPI
126  printf(" MPI: \"%d.%d", MPI_VERSION, MPI_SUBVERSION);
127 #if defined(MVAPITCH2_VERSION)
128  printf(", MVAPITCH %s", MVAPITCH2_VERSION);
129 #elif defined(I_MPI_VERSION)
130  printf(", Intel MPI %s", I_MPI_VERSION);
131 #elif defined(MSMPI_VER)
132  printf(", Microsoft MPI");
133 #elif defined(MPI_NEC_MODE_GETPUTALIGNED)
134  printf(", NEC MPI");
135 #elif defined(MPICH_VERSION)
136  printf(", MPICH %s", MPICH_VERSION);
137 #elif defined(OMPI_MAJOR_VERSION)
138  printf(", Open MPI %d.%d.%d", OMPI_MAJOR_VERSION, OMPI_MINOR_VERSION, OMPI_RELEASE_VERSION);
139 #endif
140  printf("\"\n");
141 #else
142  printf(" MPI: disabled\n");
143 #endif
144 #ifdef _OPENMP
145  printf(" OpenMP: %d\n", _OPENMP);
146 #else
147  printf(" OpenMP: disabled\n");
148 #endif
149 #ifdef _OPENACC
150  printf(" OpenACC: %d\n", _OPENACC);
151 #else
152  printf(" OpenACC: disabled\n");
153 #endif
154  printf(" option: ");
155  printf("\"");
156 #ifdef WITH_MPI
157  printf("-p ");
158 #endif
159 #ifdef WITH_TOOLS
160  printf("--with-tools ");
161 #endif
162 #ifdef WITH_REFINER
163  printf("--with-refiner ");
164 #endif
165 #ifdef WITH_METIS
166  printf("--with-metis ");
167 #endif
168 #ifdef WITH_MUMPS
169  printf("--with-mumps ");
170 #endif
171 #ifdef WITH_LAPACK
172  printf("--with-lapack ");
173 #endif
174 #ifdef WITH_ML
175  printf("--with-ml ");
176 #endif
177 #ifdef WITH_PARMETIS
178  printf("--with-parmetis ");
179 #endif
180 #ifdef WITH_MKL
181  printf("--with-mkl ");
182 #endif
183 #ifdef WITH_NETCDF
184  printf("--with-netcdf ");
185 #endif
186  printf("\"");
187  printf("\n");
188 #ifdef HECMW_METIS_VER
189  printf(" HECMW_METIS_VER: %d\n", HECMW_METIS_VER);
190 #endif
191 }
192 
196 void print_executeinfo(int log_level) {
197  int rank=0;
198  int proc, i, len, mpi_ver, mpi_subver;
199  char *p;
200  char date[32];
201  time_t t;
202  int d;
203 #ifndef HECMW_SERIAL
204  char hostname[MPI_MAX_PROCESSOR_NAME];
205  char mpilibver[MPI_MAX_LIBRARY_VERSION_STRING];
206  MPI_Status status;
207  MPI_Comm_size(MPI_COMM_WORLD, &proc);
208  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
209  MPI_Get_version(&mpi_ver, &mpi_subver);
210  MPI_Get_library_version(mpilibver,&len);
211  /* mpich returns too long string, clip 1st line. */
212  while ((p = strchr(mpilibver, '\n')) != NULL) *p = '\0';
213  MPI_Get_processor_name(hostname, &len);
214 #else
215  char hostname[128];
216 #endif
217 
218  if (rank==0){
219  printf("execute: \n");
220  t=time(NULL);
221  /* for windows compatibility */
222  d=(int)difftime(t,mktime(gmtime(&t)));
223  strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", localtime(&t));
224  printf(" date: %s", date);
225  if (abs(d)<86400) printf("%+05d", (int)(d/3600)*100+(int)(d/60)%60);
226  printf("\n");
227  printf(" processes: %d\n", get_procs_num());
228  printf(" threads: %d\n", get_threads_num());
229  printf(" cores: %d\n", get_threads_num()*get_procs_num());
230 #ifndef HECMW_SERIAL
231  printf(" MPI: \"%d.%d, %.128s\"\n", mpi_ver, mpi_subver, mpilibver);
232 #endif
233  printf(" host:\n");
234  }
235 #ifndef HECMW_SERIAL
236 
237  if (rank == 0){
238  printf(" %d: %s\n",0,hostname);
239  for (i=1;i<proc;i++){
240  MPI_Recv(&hostname, sizeof(hostname), MPI_CHAR, i, 0, MPI_COMM_WORLD, &status);
241  printf(" %d: %s\n",i,hostname);
242  }
243  }else{
244  MPI_Send(&hostname, len, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
245  }
246 #else
247  gethostname(hostname, sizeof(hostname));
248  printf(" %d: %s\n",0,hostname);
249 #endif
250  if (rank==0) printf("---\n");
251 }
252 
256 void version(char *arg) {
257  int rank=0;
258 #ifndef HECMW_SERIAL
259  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
260 #endif
261  print_buildinfo(9);
262  if (rank==0) printf("---\n");
263  exit(0);
264 }
265 
269 void load_hecmw_ctrl(char *arg) {
270  fprintf(stderr, "Sorry this option cannot work yet. (-c)\n");
271  fprintf(stderr, "%s\n", arg);
272  exit(0);
273 }
274 
278 void set_loglevel_debug(char *arg) {
280 }
281 
286 struct option_rec options[] = {
287  {"-h", help},
288  {"-H", help},
289  {"-v", version},
290  {"-V", version},
291 #ifdef _OPENMP
292  {"-t", set_num_threads},
293  {"-T", set_num_threads},
294 #endif /* _OPENMP */
295  {"-c", load_hecmw_ctrl},
296  {"-C", load_hecmw_ctrl},
297  {"--debug", set_loglevel_debug},
298  {NULL, NULL}
299 };
300 
304 int main(int argc, char *argv[])
305 {
306  struct option_rec *p;
307  unsigned int i;
308 
309 #ifndef HECMW_SERIAL
310  MPI_Init(&argc, &argv);
311 #ifdef _OPENACC
312  int rank = 0;
313  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
314  const int ngpus = acc_get_num_devices(acc_device_nvidia);
315  if (ngpus == 0 && rank == 0) {
316  fprintf(stdout, "No GPU devices found.\n");
317  }
318  const int gpuid = ngpus > 0 ? rank % ngpus : -1;
319  if (gpuid >= 0) {
320  acc_set_device_num(gpuid, acc_device_nvidia);
321  }
322 #endif
323 #endif
324  for (i = 0; i < argc; i++) {
325  for (p = options; p->option_name != NULL; p++) {
326  if (strncmp(p->option_name, argv[i], strlen(p->option_name)) == 0) {
327  p->func(argv[i + 1]);
328  }
329  }
330  }
331  print_buildinfo(1);
333 #ifndef HECMW_SERIAL
334  MPI_Barrier( MPI_COMM_WORLD );
335 #endif
336  fstr_main();
337  return 0;
338 }
#define NULL
void HECMW_setloglv(int loglv)
Definition: hecmw_log.c:57
#define HECMW_LOG_DEBUG
Definition: hecmw_log.h:21
int main(int argc, char *argv[])
main function
Definition: main.c:304
void help(char *arg)
show available command line option
Definition: main.c:91
void print_executeinfo(int log_level)
show execute environment information
Definition: main.c:196
void set_loglevel_debug(char *arg)
set log level to HECMW_LOG_DEBUG
Definition: main.c:278
int get_threads_num()
Definition: main.c:53
void fstr_main()
Startup routine for FrontISTR.
int get_procs_num()
Definition: main.c:43
void version(char *arg)
show version and revision of FrontISTR
Definition: main.c:256
struct option_rec options[]
specify command line option name and executing function name.
Definition: main.c:286
void load_hecmw_ctrl(char *arg)
load hecmw_ctrl.dat from specified place
Definition: main.c:269
void print_buildinfo(int log_level)
show build information
Definition: main.c:107
struct of command-line option
Definition: main.c:38
char * option_name
Definition: main.c:39
void(* func)(char *)
Definition: main.c:40