source: pcp/src/opt.c@ f70c2a

Last change on this file since f70c2a was e08f45, checked in by Frederik Heber <heber@…>, 17 years ago

Merge branch 'ConcaveHull' of ../espack2 into ConcaveHull

Conflicts:

molecuilder/src/boundary.cpp
molecuilder/src/boundary.hpp
molecuilder/src/builder.cpp
molecuilder/src/linkedcell.cpp
molecuilder/src/linkedcell.hpp
molecuilder/src/vector.cpp
molecuilder/src/vector.hpp
util/src/NanoCreator.c

Basically, this resulted from a lot of conversions two from spaces to one tab, which is my standard indentation. The mess was caused by eclipse auto-indenting. And in espack2:ConcaveHull was the new stuff, so all from ConcaveHull was replaced in case of doubt.
Additionally, vector had ofstream << operator instead ostream << ...

  • Property mode set to 100755
File size: 14.9 KB
Line 
1/** \file opt.c
2 * Option Retrieving and debugger.
3 * This file contains routines that read options from command line GetOptions(),
4 * set the verbosity level SetOutGroup1() and individually for each process
5 * SetOutGroup2() and starting the various debuggers Start_cvd(), Start_dbx(),
6 * Start_ddd(), Start_gdb(), Start_totalview(), Start_ups(), StartDebugger().
7 * And deallocating the debug string FreeDebugStr().
8 *
9 * \date 1998-2000
10 *
11 * $Id: opt.c,v 1.15 2007-02-12 09:44:56 foo Exp $
12 */
13
14#ifdef HAVE_CONFIG_H
15#include <config.h>
16#endif
17
18#include<stdio.h>
19#include<stdlib.h>
20#include<string.h>
21#include<unistd.h>
22#include<sys/utsname.h>
23#include"data.h"
24#include"helpers.h"
25#include"opt.h"
26
27static char *DebugString = NULL; //!< command line option
28static char *program_name = NULL;//<! copy of argv[0]
29static int debugger_started = 0; //!< "debugger been started?"-flag (0 - no, 1 - yes)
30
31/** Free debug string memory .
32 * Frees memory for DebugString and program_name
33 */
34static void FreeDebugStr(void) {
35 if (DebugString) Free(DebugString, "FreeDebugStr: DebugString");
36 if (program_name) Free(program_name, "FreeDebugStr: program_name");
37}
38
39/*extern char *optarg;
40 extern int optind;*/
41
42/** Reads options from commandline and fills \ref CallOptions.
43 * uses getopt in order to retrieve options from command line, including
44 * most importantly the main paramter file. The rest is just verbosity,
45 * debugging, alarm timer and source file for restarting calculations.\n
46 * Also usage is printed on request
47 *
48 * \param *Call \ref CallOptions structure to be filled
49 * \param argc argument count and ...
50 * \param argv[] .. argument const char array right from command line
51 */
52void GetOptions(struct CallOptions *Call, int argc, char *const argv[]) {
53 /* parsen der Kommandozeile */
54 int c, errflg = 0;
55
56 /* defaults setzen */
57 Call->MainParameterFile = NULL;
58 Call->ForcesFile = NULL;
59 Call->debug = 0;
60 Call->nicelevel = 0;
61 Call->Out = 0;
62 Call->alarm = 0;
63 Call->proc[PEPsi] = 0;
64 Call->proc[PEGamma] = 0;
65 Call->ReadSrcFiles = DoNotParse;
66 Call->WriteSrcFiles = 0;
67 Call->AddNFactor = 1;
68
69 while ((c = getopt(argc, argv, "a:d:D:hn:o:p:m:rvwxF:")) != -1) {
70 switch (c) {
71 case 'a':
72 Call->alarm = abs(atoi(optarg));
73 break;
74 case 'd':
75 if (DebugString) Free(DebugString, "GetOptions: DebugString");
76 Call->debug = 1;
77 DebugString = (char *)Malloc(strlen(optarg)+1, "GetOptions");
78 strcpy(DebugString, optarg);
79 break;
80 case 'D':
81 if (DebugString) Free(DebugString, "GetOptions: DebugString");
82 DebugString = (char *)Malloc(strlen(optarg)+1, "GetOptions");
83 strcpy(DebugString, optarg);
84 Call->debug = 2;
85 break;
86 case 'h':
87 printf("Usage: %s [-hvxrw ] [-a alarmtime] [-d debugstr|-D debugstr] [-n nicelevel] [-m addNfactor]\n","pcp");
88 printf(" [-o verbosity] mainparameterfile\n");
89 printf(" -a alarmtime Sets alarm to alarmtime seconds. Code will finish after\n");
90 printf(" next timestep, writing out the current state.\n");
91 printf(" -d debugstr Starts debugger right away.\n");
92 printf(" -D debugstr Starts debugger when encountering an error.\n");
93 printf(" Valid syntax for debugstr:\n");
94 printf(" 0 sleep for a minute, no debugger\n");
95 printf(" [host[:display][,debugger]] start debugger xterm on host:display\n");
96 printf(" (if DISPLAY is set or for local connection set host to local).\n");
97 printf(" Valid values for debugger are: gdb, dbx, ddd, cvd, totalview, ups.\n");
98 printf(" -h Displays this help page and exits successfully.\n");
99 printf(" -n nicelevel Decreases priority of process.\n");
100 printf(" -o verbosity Sets verbosity level. Deprecated, use -v instead.\n");
101 printf(" Possible values include: 0-5.\n");
102 printf(" -v Increases verbosity level by one. Default value: 0.\n");
103 printf(" -p n,m procs per Gamma-point, procs per psi\n");
104 printf(" No.of PE = n * m\n");
105 printf(" -r Read old src files.\n");
106 printf(" -w Write src files.\n");
107 printf(" -m f Additional NFactor - to fix read srcpsi\n");
108 printf(" -F file Do not calculate Hellmann-Feyman forces but read from file\n");
109 printf("For parallel codes it is necessary to specify the main parameter file\n");
110 printf("with an absolute path.\n");
111 exit(EXIT_SUCCESS);
112 case 'n':
113 Call->nicelevel = abs(atoi(optarg));
114 break;
115 case 'o':
116 Call->Out = abs(atoi(optarg));
117 break;
118 case 'p':
119 if (sscanf(optarg, "%d,%d", &Call->proc[PEPsi], &Call->proc[PEGamma]) < 2)
120 errflg++;
121 if (Call->proc[PEPsi] < 1 || Call->proc[PEGamma] < 1) {
122 fprintf(stderr, "proc[i] must be > 0\n");
123 errflg++;
124 }
125 break;
126 case 'r':
127 Call->ReadSrcFiles++;
128 break;
129 case 'v':
130 Call->Out++;
131 break;
132 case 'w':
133 Call->WriteSrcFiles++;
134 break;
135 case 'm':
136 if (sscanf(optarg, "%d", &Call->AddNFactor) < 1)
137 errflg++;
138 if (Call->AddNFactor <= 1) {
139 fprintf(stderr, "AddNFactor must be > 0\n");
140 errflg++;
141 }
142 break;
143 case '?':
144 errflg++;
145 break;
146 case 'F':
147 fprintf(stderr, "Recognized forces file '%s' with length %ld.\n", optarg, strlen(optarg));
148 Call->ForcesFile = (char *) Malloc((strlen(optarg)+2)*sizeof(char), "GetOptions: CallOptions::*ForcesFile");
149 strcpy(Call->ForcesFile, optarg);
150 fprintf(stderr, "Stored CallOptions->ForcesFile: %s\n", Call->ForcesFile);
151 break;
152 default:
153 fprintf(stderr, "GetOptions: getopt() returned character code O%o !?\n", c);
154 errflg++;
155 }
156 }
157 if (errflg) {
158 fprintf(stderr,"Usage: %s [ OPTIONS ] mainparameterfile\nTry '%s -h' for more information.\n", argv[0], argv[0]);
159 exit(EXIT_FAILURE);
160 }
161 if ( optind < argc - 1)
162 fprintf(stderr, "Warning: more than one file specified\n");
163 for ( ; optind < argc ; optind++) {
164 Call->MainParameterFile = (char *)Malloc(strlen(argv[optind])+1, "GetOptions: MainParameterFile");
165 strcpy(Call->MainParameterFile, argv[optind]);
166 }
167
168 /* nun auswerten */
169 program_name = (char *)Malloc(strlen(argv[0]) + 1, "GetOptions");
170 strcpy(program_name, argv[0]);
171 if (Call->alarm) alarm(Call->alarm);
172 if (Call->nicelevel) nice(Call->nicelevel);
173 if (!Call->MainParameterFile) {
174 fprintf(stderr, "Did not specify a main parameter file.\n");
175 exit(EXIT_FAILURE);
176 }
177 atexit(FreeDebugStr); /* nachher aufraeumen */
178}
179
180/** Starts DDD Debugger.
181 * Via a system call the debugger is started with certain paramaters
182 * \param *Host hostname (if not specified, then launched via \a pid)
183 * \param *program program name
184 * \param pid Process ID of te program
185 * \return return value of launched debugger
186 */
187static int Start_ddd(char *Host, char *program, pid_t pid) {
188 char s[MAXSTRINGSIZE];
189 if (Host) sprintf(s, "ddd -display %s %s %ld &", Host, program, (long int)pid);
190 else sprintf(s, "ddd %s %ld &", program, (long int)pid);
191 return system(s);
192}
193
194/** Starts GDB Debugger.
195 * Via a system call the debugger is started with certain paramaters
196 * \param *Host hostname (if not specified, then launched via \a pid)
197 * \param *program program name
198 * \param pid Process ID of te program
199 * \return return value of launched debugger
200 */
201static int Start_gdb(char *Host, char *program, pid_t pid) {
202 char s[MAXSTRINGSIZE];
203 if (Host) sprintf(s, "xterm -display %s -e gdb %s %ld &", Host, program, (long int)pid);
204 else sprintf(s, "xterm -e gdb %s %ld &", program, (long int)pid);
205 return system(s);
206}
207
208/** Starts DBX Debugger.
209 * Via a system call the debugger is started with certain paramaters
210 * \param *Host hostname (if not specified, then launched via \a pid)
211 * \param *program program name
212 * \param pid Process ID of te program
213 * \return return value of launched debugger
214 */
215static int Start_dbx(char *Host, char *program, pid_t pid) {
216 char s[MAXSTRINGSIZE];
217 program = program;
218 if (Host) sprintf(s, "xterm -display %s -e dbx -p %ld &", Host, (long int)pid);
219 else sprintf(s, "xterm -e dbx -p %ld &", (long int)pid);
220 return system(s);
221}
222
223/** Starts CVD Debugger.
224 * Via a system call the debugger is started with certain paramaters
225 * \param *Host hostname (if not specified, then launched via \a pid)
226 * \param *program program name
227 * \param pid Process ID of te program
228 * \return return value of launched debugger
229 */
230static int Start_cvd(char *Host, char *program, pid_t pid) {
231 char s[MAXSTRINGSIZE];
232 program = program;
233 if (Host) sprintf(s, "cvd -pid %ld -display %s &", (long int)pid, Host);
234 else sprintf(s, "cvd -pid %ld &", (long int)pid);
235 return system(s);
236}
237
238/** Starts Totalview Debugger.
239 * Via a system call the debugger is started with certain paramaters
240 * \param *Host hostname (if not specified, then launched via \a pid)
241 * \param *program program name
242 * \param pid Process ID of te program
243 * \return return value of launched debugger
244 */
245static int Start_totalview(char *Host, char *program, pid_t pid) {
246 char s[MAXSTRINGSIZE];
247 int myrank = 0;
248 MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
249 if (myrank) return 0; /* nur einmal totalview aufrufen */
250 if (Host) sprintf(s, "totalview -display %s -p %ld %s &", Host, (long int)pid, program);
251 else sprintf(s, "totalview -p %ld %s &", (long int)pid, program);
252 return system(s);
253}
254
255/** Starts UPS Debugger.
256 * Via a system call the debugger is started with certain paramaters
257 * \param *Host hostname (if not specified, then launched via \a pid)
258 * \param *program program name
259 * \param pid Process ID of te program
260 * \return return value of launched debugger
261 */
262static int Start_ups(char *Host, char *program, pid_t pid) {
263 char s[MAXSTRINGSIZE];
264 if (Host) sprintf(s, "ups -display %s %s %ld &", Host, program, (long int)pid);
265 else sprintf(s, "ups %s %ld &", program, (long int)pid);
266 return system(s);
267}
268
269/** Starts debugger.
270 * Tries to start a certain debugger, specified either via command line
271 * or educatedly guessed (having a list of typical ones), waits a minute
272 * in order to let the debugger have time for its pre-activities
273 *
274 * \warning no mallocs in this routine, no \ref Error
275 */
276void StartDebugger(void) {
277 char Host[MAXSTRINGSIZE] = "", Debugger[MAXSTRINGSIZE] = "";
278 char *host_ptr = Host;
279 int (*Debugger_call) (char *, char *, pid_t);
280 struct utsname op;
281
282 if (debugger_started || !DebugString)
283 return; /* nicht starten, falls kein -d oder -D, nicht zweimal starten */
284 debugger_started = 1;
285
286 if (strcmp(DebugString, "0")) {
287 /* debugger soll aus Programm heraus gestartet werden */
288 if (!system(NULL)) {
289 fprintf(stderr,"StartDebugger: No shell available\n");
290 exit(EXIT_FAILURE);
291 }
292 switch (sscanf(DebugString, " %197[a-zA-Z0-9._:-],%199s", Host, Debugger)) {
293 case 2:
294 if (!strcmp(Debugger, "ddd")) Debugger_call = Start_ddd;
295 else if (!strcmp(Debugger, "gdb")) Debugger_call = Start_gdb;
296 else if (!strcmp(Debugger, "dbx")) Debugger_call = Start_dbx;
297 else if (!strcmp(Debugger, "cvd")) Debugger_call = Start_cvd;
298 else if (!strcmp(Debugger, "totalview")) Debugger_call = Start_totalview;
299 else if (!strcmp(Debugger, "ups")) Debugger_call = Start_ups;
300 else {
301 fprintf(stderr, "StartDebugger: debugger %s not supported.\n", Debugger);
302 exit(EXIT_FAILURE);
303 }
304 break;
305 case 0:
306 host_ptr = NULL; /* no -display */
307 case 1:
308 /* try to set debugger smart ;-) */
309 if (uname(&op) == -1) {
310 perror("StartDebugger: uname failed");
311 exit(EXIT_FAILURE);
312 }
313 if (!strncmp(op.sysname, "Linux", 5) || !strncmp(op.sysname, "linux", 5)) Debugger_call = Start_gdb;
314 else if (!strncmp(op.sysname, "IRIX", 4)) Debugger_call = Start_cvd;
315 else if (!strncmp(op.sysname, "sn", 2)) Debugger_call = Start_totalview;
316 else Debugger_call = Start_gdb;
317 break;
318 default:
319 fprintf(stderr, "StartDebugger: could not read debugstring.\n");
320 exit(EXIT_FAILURE);
321 }
322 if (!strcmp(Host, "local")) host_ptr = NULL; /* no -display */
323 else if (!strchr(Host, ':')) strcat(Host, ":0"); /* kein :0 gesetzt */
324 if (Debugger_call(host_ptr, program_name, getpid())) {
325 fprintf(stderr, "StartDebugger: could not start %s on %s\n", Debugger, Host);
326 exit(EXIT_FAILURE);
327 }
328 }
329 sleep(60); /* danach sollte der Debugger gestartet sein */
330}
331
332/** Sets verbosity individually for each group.
333 * Depending on the specified general verbosity \ref CallOptions#Out the array \ref CallOptions#out
334 * is set accordingly
335 *
336 * \sa SetOutGroup2()
337 * \param *Call \ref CallOptions structure containing \ref CallOptions#Out and \ref CallOptions#out
338 */
339void SetOutGroup1(struct CallOptions *Call) {
340 int i, me;
341 MPI_Comm_rank(MPI_COMM_WORLD, &me); // me is the process number of this one
342 for (i=0; i < MaxOutGroup; i++) Call->out[i] = 0; // resetting all levels
343 if (me == 0) Call->out[MinOut] = 1; // generally (0) does some output
344 switch (Call->Out) {
345 case OutNone:
346 break;
347 case OutNormal:
348 if (me == 0) Call->out[MinOut] = 1;
349 if (me == 0) Call->out[NormalOut] = 1;
350 if (me == 0) Call->out[ValueOut] = 1;
351 break;
352 case OutNormalP:
353 Call->out[MinOut] = 1;
354 Call->out[NormalOut] = 1;
355 if (me == 0) Call->out[ValueOut] = 1;
356 break;
357 case OutMore:
358 if (me == 0) Call->out[MinOut] = 1;
359 if (me == 0) Call->out[NormalOut] = 1;
360 if (me == 0) Call->out[ReadOut] = 1;
361 if (me == 0) Call->out[ValueOut] = 1;
362 break;
363 case OutMoreP:
364 Call->out[MinOut] = 1;
365 Call->out[NormalOut] = 1;
366 Call->out[ReadOut] = 1;
367 Call->out[ValueOut] = 1;
368 break;
369 case OutAll:
370 break;
371 case OutAllP:
372 default:
373 ;
374 }
375}
376
377/** Set the output of various MPI communicating groups.
378 * Groups such as SpinDouble and for fft receive equal output levels
379 * regarding their calculations. Pattern is: "Me being part of the
380 * group? (..==0) Then set level to blabla"
381 *
382 * \sa SetOutGroup1()
383 * \param *P \ref Problem contains the communicators (aka groups)
384 * \param *Call \ref CallOptions contains verbosity level
385 */
386void SetOutGroup2(struct Problem *P, struct CallOptions *Call) {
387 int i;
388 switch (Call->Out) {
389 case OutNone:
390 break;
391 case OutNormal:
392 if (P->Par.me_comm_ST_Psi == 0) Call->out[LeaderOut] = 1;
393 break;
394 case OutNormalP:
395 if (P->Par.me_comm_ST_Psi == 0) Call->out[LeaderOut] = 1;
396 if (P->Par.me_comm_ST == 0) Call->out[StepLeaderOut] = 1;
397 break;
398 case OutMore:
399 if (P->Par.me_comm_ST_Psi == 0) Call->out[LeaderOut] = 1;
400 if (P->Par.me_comm_ST == 0) Call->out[PsiOut] = 1;
401 if (P->Par.me_comm_ST_Psi == 0) Call->out[StepLeaderOut] = 1;
402 break;
403 case OutMoreP:
404 if (P->Par.my_color_comm_ST_Psi == 0) Call->out[LeaderOut] = 1;
405 if (P->Par.my_color_comm_ST_Psi == 0) Call->out[PsiOut] = 1;
406 if (P->Par.my_color_comm_ST_Psi == 0) Call->out[StepLeaderOut] = 1;
407 break;
408 case OutAll:
409 for (i=0; i < MaxOutGroup; i++) Call->out[i] = 1;
410 break;
411 case OutAllP:
412 default:
413 for (i=0; i < MaxOutGroup; i++) Call->out[i] = 1;
414 }
415}
Note: See TracBrowser for help on using the repository browser.