1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
4 * (C) 2014 by Argonne National Laboratory.
5 * See COPYRIGHT in top-level directory.
7 #include "mtest_datatype.h"
8 #if defined(HAVE_STDIO_H) || defined(STDC_HEADERS)
11 #if defined(HAVE_STDLIB_H) || defined(STDC_HEADERS)
14 #if defined(HAVE_STRING_H) || defined(STDC_HEADERS)
20 /* The following two includes permit the collection of resource usage
23 #ifdef HAVE_SYS_TIME_H
26 #ifdef HAVE_SYS_RESOURCE_H
27 #include <sys/resource.h>
31 SMPI_VARINIT_GLOBAL_AND_SET(dbgflag2, int, 0); /* Flag used for debugging */
32 SMPI_VARINIT_GLOBAL_AND_SET(wrank2, int, -1); /* World rank */
33 SMPI_VARINIT_GLOBAL_AND_SET(verbose2,int, 0); /* Message level (0 is none) */
36 * Utility routines for writing MPI datatype communication tests.
38 * Both basic and derived datatype are included.
39 * For basic datatypes, every type has a test case that both the send and
40 * receive buffer use the same datatype and count.
42 * For derived datatypes:
43 * All the test cases are defined in this file, and the datatype definitions
44 * are in file mtest_datatype.c. Each test case will be automatically called
47 * Test case generation:
48 * Every datatype tests derived datatype send buffer and
49 * derived datatype receive buffer separately. Each test contains various sub
50 * tests for different structures (i.e., different value of count or block
51 * length). The following four structures are defined:
52 * L count & S block length & S stride
53 * S count & L block length & S stride
54 * L count & S block length & L stride
55 * S count & L block length & L stride
56 * S count & L block length & S stride & S lower-bound
57 * contiguous (stride = block length)
58 * contiguous (stride = block length) & S lower-bound
60 * How to add a new structure for each datatype:
61 * 1. Add structure definition in function MTestDdtStructDefine.
62 * 2. Increase MTEST_DDT_NUM_SUBTESTS
64 * Datatype definition:
65 * Every type is initialized by the creation function stored in
66 * mtestDdtCreators variable, all of their create/init/check functions are
67 * defined in file mtest_datatype.c.
69 * How to add a new derived datatype:
70 * 1. Add the new datatype in enum MTEST_DERIVED_DT.
71 * 2. Add its create/init/check functions in file mtest_datatype.c
72 * 3. Add its creator function to mtestDdtCreators variable
74 * Following three test levels of datatype are defined.
78 * All basic datatypes | Vector | Indexed
80 * All basic datatypes | Vector | Hvector | Indexed | Hindexed |
81 * Indexed-block | Hindexed-block | Subarray with order-C | Subarray with order-Fortran
83 * There are two ways to specify the test level of datatype. The second way has
84 * higher priority (means the value specified by the first way will be overwritten
85 * by that in the second way).
86 * 1. Specify global test level by setting the MPITEST_DATATYPE_TEST_LEVEL
87 * environment variable before execution (basic,min,full|full by default).
88 * 2. Initialize a special level for a datatype loop by calling the corresponding
89 * initialization function before that loop, otherwise the default value specified
90 * in the first way is used.
91 * Basic : MTestInitBasicDatatypes
92 * Minimum : MTestInitMinDatatypes
93 * Full : MTestInitFullDatatypes
96 SMPI_VARINIT_GLOBAL_AND_SET(datatype_index,int,0);
98 /* ------------------------------------------------------------------------ */
99 /* Routine and internal parameters to define the range of datatype tests */
100 /* ------------------------------------------------------------------------ */
102 #define MTEST_DDT_NUM_SUBTESTS 7 /* 7 kinds of derived datatype structure */
103 SMPI_VARINIT_GLOBAL_AND_SET( mtestDdtCreators, MTestDdtCreator*,NULL);
105 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_BDT_START_IDX, int, -1);
106 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_BDT_NUM_TESTS, int, 0);
107 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_BDT_RANGE, int, 0);
109 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_DDT_NUM_TYPES, int, 0);
110 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_SEND_DDT_START_IDX, int, 0);
111 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_SEND_DDT_NUM_TESTS, int, 0);
112 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_SEND_DDT_RANGE, int, 0);
114 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_RECV_DDT_START_IDX, int, 0);
115 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_RECV_DDT_NUM_TESTS, int, 0);
116 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_RECV_DDT_RANGE, int, 0);
119 MTEST_DATATYPE_TEST_LEVEL_FULL,
120 MTEST_DATATYPE_TEST_LEVEL_MIN,
121 MTEST_DATATYPE_TEST_LEVEL_BASIC
124 /* current datatype test level */
125 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_DATATYPE_TEST_LEVEL,int, MTEST_DATATYPE_TEST_LEVEL_FULL);
126 /* default datatype test level specified by environment variable */
127 SMPI_VARINIT_GLOBAL_AND_SET(MTEST_DATATYPE_TEST_LEVEL_ENV, int, -1);
128 /* default datatype initialization function */
129 static void (*MTestInitDefaultTestFunc) (void) = NULL;
131 static void MTestInitDatatypeGen(int basic_dt_num, int derived_dt_num)
133 SMPI_VARGET_GLOBAL(MTEST_BDT_START_IDX) = 0;
134 SMPI_VARGET_GLOBAL(MTEST_BDT_NUM_TESTS) = basic_dt_num;
135 SMPI_VARGET_GLOBAL(MTEST_BDT_RANGE) = SMPI_VARGET_GLOBAL(MTEST_BDT_START_IDX) + SMPI_VARGET_GLOBAL(MTEST_BDT_NUM_TESTS);
136 SMPI_VARGET_GLOBAL(MTEST_DDT_NUM_TYPES) = derived_dt_num;
137 SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_START_IDX) = SMPI_VARGET_GLOBAL(MTEST_BDT_NUM_TESTS);
138 SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_NUM_TESTS) = SMPI_VARGET_GLOBAL(MTEST_DDT_NUM_TYPES) * MTEST_DDT_NUM_SUBTESTS;
139 SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_RANGE) = SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_START_IDX) + SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_NUM_TESTS);
140 SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_START_IDX) = SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_START_IDX) + SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_NUM_TESTS);
141 SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_NUM_TESTS) = SMPI_VARGET_GLOBAL(MTEST_DDT_NUM_TYPES) * MTEST_DDT_NUM_SUBTESTS;
142 SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_RANGE) = SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_START_IDX) + SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_NUM_TESTS);
145 static int MTestIsDatatypeGenInited()
147 return (SMPI_VARGET_GLOBAL(MTEST_BDT_START_IDX) < 0) ? 0 : 1;
150 static void MTestPrintDatatypeGen()
152 MTestPrintfMsg(1, "MTest datatype test level : %s. %d basic datatype tests, "
153 "%d derived datatype tests will be generated\n",
154 (SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL) == MTEST_DATATYPE_TEST_LEVEL_FULL) ? "FULL" : "MIN",
155 SMPI_VARGET_GLOBAL(MTEST_BDT_NUM_TESTS), SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_NUM_TESTS) + SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_NUM_TESTS));
158 static void MTestResetDatatypeGen()
160 SMPI_VARGET_GLOBAL(MTEST_BDT_START_IDX) = -1;
163 void MTestInitFullDatatypes(void)
165 if(SMPI_VARGET_GLOBAL(mtestDdtCreators)==NULL)
166 SMPI_VARGET_GLOBAL(mtestDdtCreators)= (MTestDdtCreator*)malloc(sizeof(MTestDdtCreator)*MTEST_DDT_MAX);
167 /* Do not allow to change datatype test level during loop.
168 * Otherwise indexes will be wrong.
169 * Test must explicitly call reset or wait for current datatype loop being
170 * done before changing to another test level. */
171 if (!MTestIsDatatypeGenInited()) {
172 SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL) = MTEST_DATATYPE_TEST_LEVEL_FULL;
173 MTestTypeCreatorInit((MTestDdtCreator *) SMPI_VARGET_GLOBAL(mtestDdtCreators));
174 MTestInitDatatypeGen(MTEST_BDT_MAX, MTEST_DDT_MAX);
177 printf("Warning: trying to reinitialize mtest datatype during " "datatype iteration!");
181 void MTestInitMinDatatypes(void)
183 if(SMPI_VARGET_GLOBAL(mtestDdtCreators)==NULL)
184 SMPI_VARGET_GLOBAL(mtestDdtCreators)= (MTestDdtCreator*)malloc(sizeof(MTestDdtCreator)*MTEST_DDT_MAX);
185 /* Do not allow to change datatype test level during loop.
186 * Otherwise indexes will be wrong.
187 * Test must explicitly call reset or wait for current datatype loop being
188 * done before changing to another test level. */
189 if (!MTestIsDatatypeGenInited()) {
190 SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL) = MTEST_DATATYPE_TEST_LEVEL_MIN;
191 MTestTypeMinCreatorInit((MTestDdtCreator *) SMPI_VARGET_GLOBAL(mtestDdtCreators));
192 MTestInitDatatypeGen(MTEST_BDT_MAX, MTEST_MIN_DDT_MAX);
195 printf("Warning: trying to reinitialize mtest datatype during " "datatype iteration!");
199 void MTestInitBasicDatatypes(void)
201 if(SMPI_VARGET_GLOBAL(mtestDdtCreators)==NULL)
202 SMPI_VARGET_GLOBAL(mtestDdtCreators)= (MTestDdtCreator*)malloc(sizeof(MTestDdtCreator)*MTEST_DDT_MAX);
203 /* Do not allow to change datatype test level during loop.
204 * Otherwise indexes will be wrong.
205 * Test must explicitly call reset or wait for current datatype loop being
206 * done before changing to another test level. */
207 if (!MTestIsDatatypeGenInited()) {
208 SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL) = MTEST_DATATYPE_TEST_LEVEL_BASIC;
209 MTestInitDatatypeGen(MTEST_BDT_MAX, 0);
212 printf("Warning: trying to reinitialize mtest datatype during " "datatype iteration!");
216 static inline void MTestInitDatatypeEnv()
220 /* Read global test level specified by user environment variable.
221 * Only initialize once at the first time that test calls datatype routine. */
222 if (SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL_ENV) > -1)
226 SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL_ENV) = MTEST_DATATYPE_TEST_LEVEL_FULL;
227 MTestInitDefaultTestFunc = MTestInitFullDatatypes;
229 envval = getenv("MPITEST_DATATYPE_TEST_LEVEL");
230 if (envval && strlen(envval)) {
231 if (!strncmp(envval, "min", strlen("min"))) {
232 SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL_ENV) = MTEST_DATATYPE_TEST_LEVEL_MIN;
233 MTestInitDefaultTestFunc = MTestInitMinDatatypes;
235 else if (!strncmp(envval, "basic", strlen("basic"))) {
236 SMPI_VARGET_GLOBAL(MTEST_DATATYPE_TEST_LEVEL_ENV) = MTEST_DATATYPE_TEST_LEVEL_BASIC;
237 MTestInitDefaultTestFunc = MTestInitBasicDatatypes;
239 else if (strncmp(envval, "full", strlen("full"))) {
240 fprintf(stderr, "Unknown MPITEST_DATATYPE_TEST_LEVEL %s\n", envval);
245 /* -------------------------------------------------------------------------------*/
246 /* Routine to define various sets of blocklen/count/stride for derived datatypes. */
247 /* ------------------------------------------------------------------------------ */
249 static inline int MTestDdtStructDefine(int ddt_index, MPI_Aint tot_count, MPI_Aint * count,
250 MPI_Aint * blen, MPI_Aint * stride,
251 MPI_Aint * align_tot_count, MPI_Aint * lb)
255 MPI_Aint _short = 0, _align_tot_count = 0, _count = 0, _blen = 0, _stride = 0;
258 ddt_c_st = ddt_index % MTEST_DDT_NUM_SUBTESTS;
260 /* Get short value according to user specified tot_count.
261 * It is used as count for large-block-length structure, or block length
262 * for large-count structure. */
266 else if (tot_count < 64) {
272 _align_tot_count = (tot_count + _short - 1) & ~(_short - 1);
276 /* Large block length. */
278 _blen = _align_tot_count / _short;
283 _count = _align_tot_count / _short;
288 /* Large block length and large stride */
290 _blen = _align_tot_count / _short;
291 _stride = _blen * 10;
294 /* Large count and large stride */
295 _count = _align_tot_count / _short;
297 _stride = _blen * 10;
300 /* Large block length with lb */
302 _blen = _align_tot_count / _short;
304 _lb = _short / 2; /* make sure lb < blen */
307 /* Contig ddt (stride = block length) without lb */
308 _count = _align_tot_count / _short;
313 /* Contig ddt (stride = block length) with lb */
315 _blen = _align_tot_count / _short;
317 _lb = _short / 2; /* make sure lb < blen */
320 /* Undefined index */
325 *align_tot_count = _align_tot_count;
334 /* ------------------------------------------------------------------------ */
335 /* Routine to generate basic datatypes */
336 /* ------------------------------------------------------------------------ */
338 static inline int MTestGetBasicDatatypes(MTestDatatype * sendtype,
339 MTestDatatype * recvtype, MPI_Aint tot_count)
342 int bdt_index = SMPI_VARGET_GLOBAL(datatype_index) - SMPI_VARGET_GLOBAL(MTEST_BDT_START_IDX);
343 if (bdt_index >= MTEST_BDT_MAX) {
344 printf("Wrong index: global %d, bst %d in %s\n", SMPI_VARGET_GLOBAL(datatype_index), bdt_index, __func__);
351 merr = MTestTypeBasicCreate(MPI_INT, sendtype);
352 merr = MTestTypeBasicCreate(MPI_INT, recvtype);
354 case MTEST_BDT_DOUBLE:
355 merr = MTestTypeBasicCreate(MPI_DOUBLE, sendtype);
356 merr = MTestTypeBasicCreate(MPI_DOUBLE, recvtype);
358 case MTEST_BDT_FLOAT_INT:
359 merr = MTestTypeBasicCreate(MPI_FLOAT_INT, sendtype);
360 merr = MTestTypeBasicCreate(MPI_FLOAT_INT, recvtype);
362 case MTEST_BDT_SHORT:
363 merr = MTestTypeBasicCreate(MPI_SHORT, sendtype);
364 merr = MTestTypeBasicCreate(MPI_SHORT, recvtype);
367 merr = MTestTypeBasicCreate(MPI_LONG, sendtype);
368 merr = MTestTypeBasicCreate(MPI_LONG, recvtype);
371 merr = MTestTypeBasicCreate(MPI_CHAR, sendtype);
372 merr = MTestTypeBasicCreate(MPI_CHAR, recvtype);
374 case MTEST_BDT_UINT64_T:
375 merr = MTestTypeBasicCreate(MPI_UINT64_T, sendtype);
376 merr = MTestTypeBasicCreate(MPI_UINT64_T, recvtype);
378 case MTEST_BDT_FLOAT:
379 merr = MTestTypeBasicCreate(MPI_FLOAT, sendtype);
380 merr = MTestTypeBasicCreate(MPI_FLOAT, recvtype);
383 merr = MTestTypeBasicCreate(MPI_BYTE, sendtype);
384 merr = MTestTypeBasicCreate(MPI_BYTE, recvtype);
387 sendtype->count = tot_count;
388 recvtype->count = tot_count;
393 /* ------------------------------------------------------------------------ */
394 /* Routine to generate send/receive derived datatypes */
395 /* ------------------------------------------------------------------------ */
397 static inline int MTestGetSendDerivedDatatypes(MTestDatatype * sendtype,
398 MTestDatatype * recvtype, MPI_Aint tot_count)
401 int ddt_datatype_index, ddt_c_dt;
402 MPI_Aint blen, stride, count, align_tot_count, lb;
403 MPI_Datatype old_type = MPI_DOUBLE;
406 ddt_datatype_index = SMPI_VARGET_GLOBAL(datatype_index) - SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_START_IDX);
407 ddt_c_dt = ddt_datatype_index / MTEST_DDT_NUM_SUBTESTS;
408 if (ddt_c_dt >= MTEST_DDT_MAX || !SMPI_VARGET_GLOBAL(mtestDdtCreators)[ddt_c_dt]) {
409 printf("Wrong index: global %d, send %d send-ddt %d, or undefined creator in %s\n",
410 SMPI_VARGET_GLOBAL(datatype_index), ddt_datatype_index, ddt_c_dt, __func__);
415 /* Set datatype structure */
416 merr = MTestDdtStructDefine(ddt_datatype_index, tot_count, &count, &blen,
417 &stride, &align_tot_count, &lb);
419 printf("Wrong index: global %d, send %d send-ddt %d, or undefined ddt structure in %s\n",
420 SMPI_VARGET_GLOBAL(datatype_index), ddt_datatype_index, ddt_c_dt, __func__);
425 /* Create send datatype */
426 merr = SMPI_VARGET_GLOBAL(mtestDdtCreators)[ddt_c_dt] (count, blen, stride, lb, old_type, "send", sendtype);
432 /* Create receive datatype */
433 merr = MTestTypeBasicCreate(old_type, recvtype);
437 recvtype->count = sendtype->count * align_tot_count;
442 static inline int MTestGetRecvDerivedDatatypes(MTestDatatype * sendtype,
443 MTestDatatype * recvtype, MPI_Aint tot_count)
446 int ddt_datatype_index, ddt_c_dt;
447 MPI_Aint blen, stride, count, align_tot_count, lb;
448 MPI_Datatype old_type = MPI_DOUBLE;
451 ddt_datatype_index = SMPI_VARGET_GLOBAL(datatype_index) - SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_START_IDX);
452 ddt_c_dt = ddt_datatype_index / MTEST_DDT_NUM_SUBTESTS;
453 if (ddt_c_dt >= MTEST_DDT_MAX || !SMPI_VARGET_GLOBAL(mtestDdtCreators)[ddt_c_dt]) {
454 printf("Wrong index: global %d, recv %d recv-ddt %d, or undefined creator in %s\n",
455 SMPI_VARGET_GLOBAL(datatype_index), ddt_datatype_index, ddt_c_dt, __func__);
460 /* Set datatype structure */
461 merr = MTestDdtStructDefine(ddt_datatype_index, tot_count, &count, &blen,
462 &stride, &align_tot_count, &lb);
464 printf("Wrong index: global %d, recv %d recv-ddt %d, or undefined ddt structure in %s\n",
465 SMPI_VARGET_GLOBAL(datatype_index), ddt_datatype_index, ddt_c_dt, __func__);
469 /* Create receive datatype */
470 merr = SMPI_VARGET_GLOBAL(mtestDdtCreators)[ddt_c_dt] (count, blen, stride, lb, old_type, "recv", recvtype);
476 /* Create send datatype */
477 merr = MTestTypeBasicCreate(old_type, sendtype);
481 sendtype->count = recvtype->count * align_tot_count;
486 /* ------------------------------------------------------------------------ */
487 /* Exposed routine to external tests */
488 /* ------------------------------------------------------------------------ */
489 int MTestGetDatatypes(MTestDatatype * sendtype, MTestDatatype * recvtype, MPI_Aint tot_count)
493 MTestGetDbgInfo(&SMPI_VARGET_GLOBAL(dbgflag2), &SMPI_VARGET_GLOBAL(verbose2));
494 MTestInitDatatypeEnv();
495 MPI_Comm_rank(MPI_COMM_WORLD, &SMPI_VARGET_GLOBAL(wrank2));
497 /* Initialize the default test level if test does not specify. */
498 if (!MTestIsDatatypeGenInited()) {
499 MTestInitDefaultTestFunc();
502 if (SMPI_VARGET_GLOBAL(datatype_index) == 0) {
503 MTestPrintDatatypeGen();
506 /* Start generating tests */
507 if (SMPI_VARGET_GLOBAL(datatype_index) < SMPI_VARGET_GLOBAL(MTEST_BDT_RANGE)) {
508 merr = MTestGetBasicDatatypes(sendtype, recvtype, tot_count);
511 else if (SMPI_VARGET_GLOBAL(datatype_index) < SMPI_VARGET_GLOBAL(MTEST_SEND_DDT_RANGE)) {
512 merr = MTestGetSendDerivedDatatypes(sendtype, recvtype, tot_count);
515 else if (SMPI_VARGET_GLOBAL(datatype_index) < SMPI_VARGET_GLOBAL(MTEST_RECV_DDT_RANGE)) {
516 merr = MTestGetRecvDerivedDatatypes(sendtype, recvtype, tot_count);
521 SMPI_VARGET_GLOBAL(datatype_index) = -1;
522 MTestResetDatatypeGen();
525 /* stop if error reported */
527 SMPI_VARGET_GLOBAL(datatype_index) = -1;
530 if (SMPI_VARGET_GLOBAL(datatype_index) > 0) {
531 /* general initialization for receive buffer. */
532 recvtype->InitBuf = MTestTypeInitRecv;
535 SMPI_VARGET_GLOBAL(datatype_index)++;
537 if (SMPI_VARGET_GLOBAL(verbose2) >= 2 && SMPI_VARGET_GLOBAL(datatype_index) > 0) {
538 MPI_Count ssize, rsize;
539 MPI_Aint slb, rlb, sextent, rextent;
540 const char *sendtype_nm = MTestGetDatatypeName(sendtype);
541 const char *recvtype_nm = MTestGetDatatypeName(recvtype);
542 MPI_Type_size_x(sendtype->datatype, &ssize);
543 MPI_Type_size_x(recvtype->datatype, &rsize);
545 MPI_Type_get_extent(sendtype->datatype, &slb, &sextent);
546 MPI_Type_get_extent(recvtype->datatype, &rlb, &rextent);
548 MTestPrintfMsg(2, "Get datatypes: send = %s(size %d ext %ld lb %ld count %d basesize %d), "
549 "recv = %s(size %d ext %ld lb %ld count %d basesize %d), tot_count=%d\n",
550 sendtype_nm, ssize, sextent, slb, sendtype->count, sendtype->basesize,
551 recvtype_nm, rsize, rextent, rlb, recvtype->count, recvtype->basesize,
556 return SMPI_VARGET_GLOBAL(datatype_index);
559 /* Reset the datatype index (start from the initial data type.
560 Note: This routine is rarely needed; MTestGetDatatypes automatically
561 starts over after the last available datatype is used.
563 void MTestResetDatatypes(void)
565 SMPI_VARGET_GLOBAL(datatype_index) = 0;
566 MTestResetDatatypeGen();
569 /* Return the index of the current datatype. This is rarely needed and
570 is provided mostly to enable debugging of the MTest package itself */
571 int MTestGetDatatypeIndex(void)
573 return SMPI_VARGET_GLOBAL(datatype_index);
576 /* Free the storage associated with a datatype */
577 void MTestFreeDatatype(MTestDatatype * mtype)
580 /* Invoke a datatype-specific free function to handle
581 * both the datatype and the send/receive buffers */
582 if (mtype->FreeBuf) {
583 (mtype->FreeBuf) (mtype);
585 /* Free the datatype itself if it was created */
586 if (!mtype->isBasic) {
587 merr = MPI_Type_free(&mtype->datatype);
589 MTestPrintError(merr);
593 /* Check that a message was received correctly. Returns the number of
594 errors detected. Status may be NULL or MPI_STATUS_IGNORE */
595 int MTestCheckRecv(MPI_Status * status, MTestDatatype * recvtype)
600 if (status && status != MPI_STATUS_IGNORE) {
601 merr = MPI_Get_count(status, recvtype->datatype, &count);
603 MTestPrintError(merr);
605 /* Check count against expected count */
606 if (count != recvtype->count) {
611 /* Check received data */
612 if (!errs && recvtype->CheckBuf(recvtype)) {
618 SMPI_VARINIT_GLOBAL_AND_SET(name , char*,NULL);
619 SMPI_VARINIT_GLOBAL_AND_SET(sp,int,0);
621 /* This next routine uses a circular buffer of static name arrays just to
622 simplify the use of the routine */
623 const char *MTestGetDatatypeName(MTestDatatype * dtype)
625 if(SMPI_VARGET_GLOBAL(name)==NULL) SMPI_VARGET_GLOBAL(name)=(char*)malloc(4*MPI_MAX_OBJECT_NAME*sizeof(char));
628 if (SMPI_VARGET_GLOBAL(sp) >= 4)
629 SMPI_VARGET_GLOBAL(sp) = 0;
630 merr = MPI_Type_get_name(dtype->datatype, &SMPI_VARGET_GLOBAL(name)[SMPI_VARGET_GLOBAL(sp)*MPI_MAX_OBJECT_NAME], &rlen);
632 MTestPrintError(merr);
633 return (const char *) &SMPI_VARGET_GLOBAL(name)[(SMPI_VARGET_GLOBAL(sp)++) *MPI_MAX_OBJECT_NAME];