1
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
3
* (C) 2013 by Argonne National Laboratory.
4
* See COPYRIGHT in top-level directory.
7
/* To print out all MPI_T control variables, performance variables and their
8
categories in the MPI implementation. But whether they function well as
9
expected, is not tested.
14
#include <string.h> /* For strncpy */
18
char *mpit_scopeToStr(int scope);
19
char *mpit_bindingToStr(int binding);
20
char *mpit_validDtypeStr(MPI_Datatype datatype);
21
char *mpit_varclassToStr(int varClass);
22
char *mpit_verbosityToStr(int verbosity);
23
int perfvarReadInt(int pvarIndex, int isContinuous, int *found);
24
unsigned int perfvarReadUint(int pvarIndex, int isContinuous, int *found);
25
double perfvarReadDouble(int pvarIndex, int isContinuous, int *found);
26
int PrintControlVars(FILE * fp);
27
int PrintPerfVars(FILE * fp);
28
int PrintCategories(FILE * fp);
30
static int verbose = 0;
32
int main(int argc, char *argv[])
34
int required, provided;
35
required = MPI_THREAD_SINGLE;
37
MPI_T_init_thread(required, &provided);
38
MPI_Init_thread(&argc, &argv, required, &provided);
40
if (getenv("MPITEST_VERBOSE"))
43
PrintControlVars(stdout);
45
fprintf(stdout, "\n");
47
PrintPerfVars(stdout);
49
fprintf(stdout, "\n");
51
PrintCategories(stdout);
53
/* Put MPI_T_finalize() after MPI_Finalize() will cause mpich memory
54
* tracing facility falsely reports memory leaks, though these memories
55
* are freed in MPI_T_finalize().
60
fprintf(stdout, " No Errors\n");
65
int PrintControlVars(FILE * fp)
67
int i, num_cvar, nameLen, verbosity, descLen, binding, scope;
69
char name[128], desc[1024];
70
MPI_T_enum enumtype = MPI_T_ENUM_NULL;
71
MPI_Datatype datatype;
73
MPI_T_cvar_get_num(&num_cvar);
75
fprintf(fp, "%d MPI Control Variables\n", num_cvar);
76
for (i = 0; i < num_cvar; i++) {
78
nameLen = sizeof(name);
79
descLen = sizeof(desc);
80
MPI_T_cvar_get_info(i, name, &nameLen, &verbosity, &datatype,
81
&enumtype, desc, &descLen, &binding, &scope);
82
if (datatype == MPI_INT && enumtype != MPI_T_ENUM_NULL) {
83
int enameLen, enumber;
85
enameLen = sizeof(ename);
86
/* TODO: Extract a useful string to show for an enum */
87
MPI_T_enum_get_info(enumtype, &enumber, ename, &enameLen);
89
if (datatype == MPI_INT && binding == MPI_T_BIND_NO_OBJECT) {
91
MPI_T_cvar_handle chandle;
92
MPI_T_cvar_handle_alloc(i, NULL, &chandle, &count);
94
MPI_T_cvar_read(chandle, &ival);
97
MPI_T_cvar_handle_free(&chandle);
100
if (hasValue && verbose) {
101
fprintf(fp, "\t%s=%d\t%s\t%s\t%s\t%s\t%s\n",
104
mpit_scopeToStr(scope),
105
mpit_bindingToStr(binding),
106
mpit_validDtypeStr(datatype), mpit_verbosityToStr(verbosity), desc);
109
fprintf(fp, "\t%s\t%s\t%s\t%s\t%s\t%s\n",
111
mpit_scopeToStr(scope),
112
mpit_bindingToStr(binding),
113
mpit_validDtypeStr(datatype), mpit_verbosityToStr(verbosity), desc);
120
int PrintPerfVars(FILE * fp)
122
int i, numPvar, nameLen, descLen, verbosity, varClass;
123
int binding, isReadonly, isContinuous, isAtomic;
124
char name[128], desc[1024];
126
MPI_Datatype datatype;
128
MPI_T_pvar_get_num(&numPvar);
130
fprintf(fp, "%d MPI Performance Variables\n", numPvar);
132
for (i = 0; i < numPvar; i++) {
133
nameLen = sizeof(name);
134
descLen = sizeof(desc);
135
MPI_T_pvar_get_info(i, name, &nameLen, &verbosity, &varClass,
136
&datatype, &enumtype, desc, &descLen, &binding,
137
&isReadonly, &isContinuous, &isAtomic);
140
fprintf(fp, "\t%s\t%s\t%s\t%s\t%s\tReadonly=%s\tContinuous=%s\tAtomic=%s\t%s\n",
142
mpit_varclassToStr(varClass),
143
mpit_bindingToStr(binding),
144
mpit_validDtypeStr(datatype),
145
mpit_verbosityToStr(verbosity),
146
isReadonly ? "T" : "F", isContinuous ? "T" : "F", isAtomic ? "T" : "F", desc);
148
if (datatype == MPI_INT) {
150
val = perfvarReadInt(i, isContinuous, &isFound);
151
if (isFound && verbose)
152
fprintf(fp, "\tValue = %d\n", val);
154
else if (datatype == MPI_UNSIGNED) {
157
val = perfvarReadUint(i, isContinuous, &isFound);
158
if (isFound && verbose)
159
fprintf(fp, "\tValue = %u\n", val);
161
else if (datatype == MPI_DOUBLE) {
164
val = perfvarReadDouble(i, isContinuous, &isFound);
165
if (isFound && verbose)
166
fprintf(fp, "\tValue = %e\n", val);
172
int PrintCategories(FILE * fp)
174
int i, j, numCat, nameLen, descLen, numCvars, numPvars, numSubcat;
175
char name[128], desc[1024];
177
MPI_T_category_get_num(&numCat);
180
fprintf(fp, "%d MPI_T categories\n", numCat);
182
fprintf(fp, "No categories defined\n");
185
for (i = 0; i < numCat; i++) {
186
nameLen = sizeof(name);
187
descLen = sizeof(desc);
188
MPI_T_category_get_info(i, name, &nameLen, desc, &descLen, &numCvars,
189
&numPvars, &numSubcat);
191
fprintf(fp, "Category %s has %d control variables, %d performance variables, %d subcategories\n",
192
name, numCvars, numPvars, numSubcat);
193
fprintf(fp, "\tDescription: %s\n", desc);
198
fprintf(fp, "\tControl variables include: ");
199
int *cvarIndex = (int *) malloc(numCvars * sizeof(int));
200
MPI_T_category_get_cvars(i, numCvars, cvarIndex);
201
for (j = 0; j < numCvars; j++) {
202
/* Get just the variable name */
203
int varnameLen, verb, binding, scope;
204
MPI_Datatype datatype;
206
varnameLen = sizeof(varname);
207
MPI_T_cvar_get_info(cvarIndex[j], varname, &varnameLen,
208
&verb, &datatype, NULL, NULL, NULL, &binding, &scope);
210
fprintf(fp, "%s, ", varname);
219
fprintf(fp, "\tPerformance variables include: ");
221
int *pvarIndex = (int *) malloc(numPvars * sizeof(int));
222
MPI_T_category_get_pvars(i, numPvars, pvarIndex);
223
for (j = 0; j < numPvars; j++) {
224
int varnameLen, verb, varclass, binding;
225
int isReadonly, isContinuous, isAtomic;
226
MPI_Datatype datatype;
228
varnameLen = sizeof(varname);
229
MPI_T_pvar_get_info(pvarIndex[j], varname, &varnameLen, &verb,
230
&varclass, &datatype, NULL, NULL, NULL, &binding,
231
&isReadonly, &isContinuous, &isAtomic);
233
fprintf(fp, "%s, ", varname);
241
/* TODO: Make it possible to recursively print category information */
244
fprintf(fp, "\tSubcategories include: ");
246
int *subcatIndex = (int *) malloc(numSubcat * sizeof(int));
247
MPI_T_category_get_categories(i, numSubcat, subcatIndex);
248
for (j = 0; j < numSubcat; j++) {
249
int catnameLen, ncvars, npvars, nsubcats;
251
catnameLen = sizeof(catname);
252
MPI_T_category_get_info(subcatIndex[j], catname, &catnameLen, NULL, NULL,
253
&ncvars, &npvars, &nsubcats);
255
fprintf(fp, "%s, ", catname);
268
/* --- Support routines --- */
270
char *mpit_validDtypeStr(MPI_Datatype datatype)
273
if (datatype == MPI_INT)
275
else if (datatype == MPI_UNSIGNED)
277
else if (datatype == MPI_UNSIGNED_LONG)
278
p = "MPI_UNSIGNED_LONG";
279
else if (datatype == MPI_UNSIGNED_LONG_LONG)
280
p = "MPI_UNSIGNED_LONG_LONG";
281
else if (datatype == MPI_COUNT)
283
else if (datatype == MPI_CHAR)
285
else if (datatype == MPI_DOUBLE)
288
if (datatype == MPI_DATATYPE_NULL) {
289
p = "Invalid MPI datatype:NULL";
292
static char typename[MPI_MAX_OBJECT_NAME + 9];
294
strncpy(typename, "Invalid:", MPI_MAX_OBJECT_NAME);
295
MPI_Type_get_name(datatype, typename + 8, &tlen);
296
/* We must check location typename[8] to see if
297
MPI_Type_get_name returned a name (not all datatypes
298
have names). If it did not, then we indicate that
299
with a different message */
303
p = "Invalid: Unknown datatype name";
310
char *mpit_scopeToStr(int scope)
314
case MPI_T_SCOPE_CONSTANT:
315
p = "SCOPE_CONSTANT";
317
case MPI_T_SCOPE_READONLY:
318
p = "SCOPE_READONLY";
320
case MPI_T_SCOPE_LOCAL:
323
case MPI_T_SCOPE_GROUP:
326
case MPI_T_SCOPE_GROUP_EQ:
327
p = "SCOPE_GROUP_EQ";
329
case MPI_T_SCOPE_ALL:
332
case MPI_T_SCOPE_ALL_EQ:
336
p = "Unrecoginized scope";
342
char *mpit_bindingToStr(int binding)
346
case MPI_T_BIND_NO_OBJECT:
349
case MPI_T_BIND_MPI_COMM:
352
case MPI_T_BIND_MPI_DATATYPE:
355
case MPI_T_BIND_MPI_ERRHANDLER:
356
p = "MPI_ERRHANDLER";
358
case MPI_T_BIND_MPI_FILE:
361
case MPI_T_BIND_MPI_GROUP:
364
case MPI_T_BIND_MPI_OP:
367
case MPI_T_BIND_MPI_REQUEST:
370
case MPI_T_BIND_MPI_WIN:
373
case MPI_T_BIND_MPI_MESSAGE:
376
case MPI_T_BIND_MPI_INFO:
380
p = "Unknown object binding";
385
char *mpit_varclassToStr(int varClass)
389
case MPI_T_PVAR_CLASS_STATE:
392
case MPI_T_PVAR_CLASS_LEVEL:
395
case MPI_T_PVAR_CLASS_SIZE:
398
case MPI_T_PVAR_CLASS_PERCENTAGE:
399
p = "CLASS_PERCENTAGE";
401
case MPI_T_PVAR_CLASS_HIGHWATERMARK:
402
p = "CLASS_HIGHWATERMARK";
404
case MPI_T_PVAR_CLASS_LOWWATERMARK:
405
p = "CLASS_LOWWATERMARK";
407
case MPI_T_PVAR_CLASS_COUNTER:
410
case MPI_T_PVAR_CLASS_AGGREGATE:
411
p = "CLASS_AGGREGATE";
413
case MPI_T_PVAR_CLASS_TIMER:
416
case MPI_T_PVAR_CLASS_GENERIC:
420
p = "Unrecognized pvar class";
426
char *mpit_verbosityToStr(int verbosity)
430
case MPI_T_VERBOSITY_USER_BASIC:
431
p = "VERBOSITY_USER_BASIC";
433
case MPI_T_VERBOSITY_USER_DETAIL:
434
p = "VERBOSITY_USER_DETAIL";
436
case MPI_T_VERBOSITY_USER_ALL:
437
p = "VERBOSITY_USER_ALL";
439
case MPI_T_VERBOSITY_TUNER_BASIC:
440
p = "VERBOSITY_TUNER_BASIC";
442
case MPI_T_VERBOSITY_TUNER_DETAIL:
443
p = "VERBOSITY_TUNER_DETAIL";
445
case MPI_T_VERBOSITY_TUNER_ALL:
446
p = "VERBOSITY_TUNER_ALL";
448
case MPI_T_VERBOSITY_MPIDEV_BASIC:
449
p = "VERBOSITY_MPIDEV_BASIC";
451
case MPI_T_VERBOSITY_MPIDEV_DETAIL:
452
p = "VERBOSITY_MPIDEV_DETAIL";
454
case MPI_T_VERBOSITY_MPIDEV_ALL:
455
p = "VERBOSITY_MPIDEV_ALL";
458
p = "Invalid verbosity";
464
char *mpit_errclassToStr(int err)
468
case MPI_T_ERR_MEMORY:
471
case MPI_T_ERR_NOT_INITIALIZED:
472
p = "ERR_NOT_INITIALIZED";
474
case MPI_T_ERR_CANNOT_INIT:
475
p = "ERR_CANNOT_INIT";
477
case MPI_T_ERR_INVALID_INDEX:
478
p = "ERR_INVALID_INDEX";
480
case MPI_T_ERR_INVALID_ITEM:
481
p = "ERR_INVALID_ITEM";
483
case MPI_T_ERR_INVALID_HANDLE:
484
p = "ERR_INVALID_HANDLE";
486
case MPI_T_ERR_OUT_OF_HANDLES:
487
p = "ERR_OUT_OF_HANDLES";
489
case MPI_T_ERR_OUT_OF_SESSIONS:
490
p = "ERR_OUT_OF_SESSIONS";
492
case MPI_T_ERR_INVALID_SESSION:
493
p = "ERR_INVALID_SESSION";
495
case MPI_T_ERR_CVAR_SET_NOT_NOW:
496
p = "ERR_CVAR_SET_NOT_NOW";
498
case MPI_T_ERR_CVAR_SET_NEVER:
499
p = "ERR_CVAR_SET_NEVER";
501
case MPI_T_ERR_PVAR_NO_STARTSTOP:
502
p = "ERR_PVAR_NO_STARTSTOP";
504
case MPI_T_ERR_PVAR_NO_WRITE:
505
p = "ERR_PVAR_NO_WRITE";
507
case MPI_T_ERR_PVAR_NO_ATOMIC:
508
p = "ERR_PVAR_NO_ATOMIC";
511
p = "Unknown MPI_T_ERR class";
517
/* Return the value of the performance variable as the value */
518
int perfvarReadInt(int pvarIndex, int isContinuous, int *found)
521
int err1 = MPI_SUCCESS;
522
int err2 = MPI_SUCCESS;
523
MPI_T_pvar_session session;
524
MPI_T_pvar_handle pvarHandle;
525
MPI_T_pvar_session_create(&session);
526
MPI_T_pvar_handle_alloc(session, pvarIndex, NULL, &pvarHandle, &count);
527
MPI_T_pvar_start(session, MPI_T_PVAR_ALL_HANDLES);
528
MPI_T_pvar_stop(session, MPI_T_PVAR_ALL_HANDLES);
532
/* start and stop the variable (just because we can) */
533
err1 = MPI_T_pvar_start(session, pvarHandle);
534
err2 = MPI_T_pvar_stop(session, pvarHandle);
536
MPI_T_pvar_read(session, pvarHandle, &val);
538
MPI_T_pvar_handle_free(session, &pvarHandle);
539
MPI_T_pvar_session_free(&session);
541
/* Above codes imply that err1 and err2 should be MPI_SUCCESS.
542
* If not, catch errors here, e.g., when MPI_ERR_INTERN is returned.
544
if (err1 != MPI_SUCCESS || err2 != MPI_SUCCESS) {
545
fprintf(stderr, "Unexpected MPI_T_pvar_start/stop return code\n");
552
/* Return the value of the performance variable as the value */
553
unsigned int perfvarReadUint(int pvarIndex, int isContinuous, int *found)
556
unsigned int val = 0;
557
int err1 = MPI_SUCCESS;
558
int err2 = MPI_SUCCESS;
559
MPI_T_pvar_session session;
560
MPI_T_pvar_handle pvarHandle;
563
MPI_T_pvar_session_create(&session);
564
MPI_T_pvar_handle_alloc(session, pvarIndex, NULL, &pvarHandle, &count);
565
MPI_T_pvar_start(session, MPI_T_PVAR_ALL_HANDLES);
566
MPI_T_pvar_stop(session, MPI_T_PVAR_ALL_HANDLES);
570
/* start and stop the variable (just because we can) */
571
err1 = MPI_T_pvar_start(session, pvarHandle);
572
err2 = MPI_T_pvar_stop(session, pvarHandle);
574
MPI_T_pvar_read(session, pvarHandle, &val);
576
MPI_T_pvar_handle_free(session, &pvarHandle);
577
MPI_T_pvar_session_free(&session);
579
/* Above codes imply that err1 and err2 should be MPI_SUCCESS.
580
* If not, catch errors here, e.g., when MPI_ERR_INTERN is returned.
582
if (err1 != MPI_SUCCESS || err2 != MPI_SUCCESS) {
583
fprintf(stderr, "Unexpected MPI_T_pvar_start/stop return code\n");
590
double perfvarReadDouble(int pvarIndex, int isContinuous, int *found)
594
int err1 = MPI_SUCCESS;
595
int err2 = MPI_SUCCESS;
596
MPI_T_pvar_session session;
597
MPI_T_pvar_handle pvarHandle;
600
MPI_T_pvar_session_create(&session);
601
MPI_T_pvar_handle_alloc(session, pvarIndex, NULL, &pvarHandle, &count);
602
MPI_T_pvar_start(session, MPI_T_PVAR_ALL_HANDLES);
603
MPI_T_pvar_stop(session, MPI_T_PVAR_ALL_HANDLES);
607
/* start and stop the variable (just because we can) */
608
err1 = MPI_T_pvar_start(session, pvarHandle);
609
err2 = MPI_T_pvar_stop(session, pvarHandle);
611
MPI_T_pvar_read(session, pvarHandle, &val);
613
MPI_T_pvar_handle_free(session, &pvarHandle);
614
MPI_T_pvar_session_free(&session);
616
/* Catch errors if MPI_T_pvar_start/stop are not properly implemented */
617
if (err1 != MPI_SUCCESS || err2 != MPI_SUCCESS) {
618
fprintf(stderr, "Unknown MPI_T return code when starting/stopping double pvar\n");