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 }
189 
193 void print_executeinfo(int log_level) {
194  int rank=0;
195  int proc, i, len, mpi_ver, mpi_subver;
196  char *p;
197  char date[32];
198  time_t t;
199  int d;
200 #ifndef HECMW_SERIAL
201  char hostname[MPI_MAX_PROCESSOR_NAME];
202  char mpilibver[MPI_MAX_LIBRARY_VERSION_STRING];
203  MPI_Status status;
204  MPI_Comm_size(MPI_COMM_WORLD, &proc);
205  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
206  MPI_Get_version(&mpi_ver, &mpi_subver);
207  MPI_Get_library_version(mpilibver,&len);
208  /* mpich returns too long string, clip 1st line. */
209  while ((p = strchr(mpilibver, '\n')) != NULL) *p = '\0';
210  MPI_Get_processor_name(hostname, &len);
211 #else
212  char hostname[128];
213 #endif
214 
215  if (rank==0){
216  printf("execute: \n");
217  t=time(NULL);
218  /* for windows compatibility */
219  d=(int)difftime(t,mktime(gmtime(&t)));
220  strftime(date, sizeof(date), "%Y-%m-%dT%H:%M:%S", localtime(&t));
221  printf(" date: %s", date);
222  if (abs(d)<86400) printf("%+05d", (int)(d/3600)*100+(int)(d/60)%60);
223  printf("\n");
224  printf(" processes: %d\n", get_procs_num());
225  printf(" threads: %d\n", get_threads_num());
226  printf(" cores: %d\n", get_threads_num()*get_procs_num());
227 #ifndef HECMW_SERIAL
228  printf(" MPI: \"%d.%d, %.128s\"\n", mpi_ver, mpi_subver, mpilibver);
229 #endif
230  printf(" host:\n");
231  }
232 #ifndef HECMW_SERIAL
233 
234  if (rank == 0){
235  printf(" %d: %s\n",0,hostname);
236  for (i=1;i<proc;i++){
237  MPI_Recv(&hostname, sizeof(hostname), MPI_CHAR, i, 0, MPI_COMM_WORLD, &status);
238  printf(" %d: %s\n",i,hostname);
239  }
240  }else{
241  MPI_Send(&hostname, len, MPI_CHAR, 0, 0, MPI_COMM_WORLD);
242  }
243 #else
244  gethostname(hostname, sizeof(hostname));
245  printf(" %d: %s\n",0,hostname);
246 #endif
247  if (rank==0) printf("---\n");
248 }
249 
253 void version(char *arg) {
254  int rank=0;
255 #ifndef HECMW_SERIAL
256  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
257 #endif
258  print_buildinfo(9);
259  if (rank==0) printf("---\n");
260  exit(0);
261 }
262 
266 void load_hecmw_ctrl(char *arg) {
267  fprintf(stderr, "Sorry this option cannot work yet. (-c)\n");
268  fprintf(stderr, "%s\n", arg);
269  exit(1);
270 }
271 
275 void set_loglevel_debug(char *arg) {
277 }
278 
283 struct option_rec options[] = {
284  {"-h", help},
285  {"-H", help},
286  {"-v", version},
287  {"-V", version},
288 #ifdef _OPENMP
289  {"-t", set_num_threads},
290  {"-T", set_num_threads},
291 #endif /* _OPENMP */
292  {"-c", load_hecmw_ctrl},
293  {"-C", load_hecmw_ctrl},
294  {"--debug", set_loglevel_debug},
295  {NULL, NULL}
296 };
297 
301 int main(int argc, char *argv[])
302 {
303  struct option_rec *p;
304  unsigned int i;
305 
306 #ifndef HECMW_SERIAL
307  MPI_Init(&argc, &argv);
308 #ifdef _OPENACC
309  int rank = 0;
310  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
311  const int ngpus = acc_get_num_devices(acc_device_nvidia);
312  if (ngpus == 0 && rank == 0) {
313  fprintf(stdout, "No GPU devices found.\n");
314  }
315  const int gpuid = ngpus > 0 ? rank % ngpus : -1;
316  if (gpuid >= 0) {
317  acc_set_device_num(gpuid, acc_device_nvidia);
318  }
319 #endif
320 #endif
321  for (i = 0; i < argc; i++) {
322  for (p = options; p->option_name != NULL; p++) {
323  if (strncmp(p->option_name, argv[i], strlen(p->option_name)) == 0) {
324  p->func(argv[i + 1]);
325  }
326  }
327  }
328  print_buildinfo(1);
330 #ifndef HECMW_SERIAL
331  MPI_Barrier( MPI_COMM_WORLD );
332 #endif
333  fstr_main();
334  return 0;
335 }
#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:301
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:193
void set_loglevel_debug(char *arg)
set log level to HECMW_LOG_DEBUG
Definition: main.c:275
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:253
struct option_rec options[]
specify command line option name and executing function name.
Definition: main.c:283
void load_hecmw_ctrl(char *arg)
load hecmw_ctrl.dat from specified place
Definition: main.c:266
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