⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtest.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 3 页
字号:
	    MTestError( "Out of memory in type buffer init\n" );	}	for (i=0; i<totsize; i++) {	    p[i] = 0xff;	}    }    else {	/* count == 0 */	if (mtype->buf) {	    free( mtype->buf );	}	mtype->buf = 0;    }    return mtype->buf;}static void *MTestTypeIndexedFree( MTestDatatype *mtype ){    if (mtype->buf) {	free( mtype->buf );	free( mtype->displs );	free( mtype->index );	mtype->buf    = 0;	mtype->displs = 0;	mtype->index  = 0;    }    return 0;}static int MTestTypeIndexedCheckbuf( MTestDatatype *mtype ){    unsigned char *p;    unsigned char expected;    int  i, err = 0, merr;    MPI_Aint totsize;    p = (unsigned char *)mtype->buf;    if (p) {	int j, k, offset;	merr = MPI_Type_extent( mtype->datatype, &totsize );	if (merr) MTestPrintError( merr );		k = 0;	for (i=0; i<mtype->nelm; i++) {	    int b;	    /* Compute the offset: */	    offset = mtype->displs[i] * mtype->basesize;	    for (b=0; b<mtype->index[i]; b++) {		for (j=0; j<mtype->basesize; j++) {		    expected = (0xff ^ (k & 0xff));		    if (p[offset+j] != expected) {			err++;			if (mtype->printErrors && err < 10) {			    printf( "Data expected = %x but got %x for %dth entry\n",				    expected, p[offset+j], k );			    fflush( stdout );			}		    }		    k++;		}		offset += mtype->basesize;	    }	}    }    return err;}/* ------------------------------------------------------------------------ *//* Routines to select a datatype and associated buffer create/fill/check    *//* routines                                                                 *//* ------------------------------------------------------------------------ *//*    Create a range of datatypes with a given count elements.   This uses a selection of types, rather than an exhaustive collection.   It allocates both send and receive types so that they can have the same   type signature (collection of basic types) but different type maps (layouts   in memory)  */int MTestGetDatatypes( MTestDatatype *sendtype, MTestDatatype *recvtype,		       int count ){    int merr;    int i;    sendtype->InitBuf	  = 0;    sendtype->FreeBuf	  = 0;    sendtype->CheckBuf	  = 0;    sendtype->datatype	  = 0;    sendtype->isBasic	  = 0;    sendtype->printErrors = 0;    recvtype->InitBuf	  = 0;    recvtype->FreeBuf	  = 0;    recvtype->CheckBuf	  = 0;    recvtype->datatype	  = 0;    recvtype->isBasic	  = 0;    recvtype->printErrors = 0;    sendtype->buf	  = 0;    recvtype->buf	  = 0;    /* Set the defaults for the message lengths */    sendtype->count	  = count;    recvtype->count	  = count;    /* Use datatype_index to choose a datatype to use.  If at the end of the       list, return 0 */    switch (datatype_index) {    case 0:	sendtype->datatype = MPI_INT;	sendtype->isBasic  = 1;	recvtype->datatype = MPI_INT;	recvtype->isBasic  = 1;	break;    case 1:	sendtype->datatype = MPI_DOUBLE;	sendtype->isBasic  = 1;	recvtype->datatype = MPI_DOUBLE;	recvtype->isBasic  = 1;	break;    case 2:	sendtype->datatype = MPI_INT;	sendtype->isBasic  = 1;	recvtype->datatype = MPI_BYTE;	recvtype->isBasic  = 1;	recvtype->count    *= sizeof(int);	break;    case 3:	sendtype->datatype = MPI_FLOAT_INT;	sendtype->isBasic  = 1;	recvtype->datatype = MPI_FLOAT_INT;	recvtype->isBasic  = 1;	break;    case 4:	merr = MPI_Type_dup( MPI_INT, &sendtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( sendtype->datatype, "dup of MPI_INT" );	if (merr) MTestPrintError( merr );	merr = MPI_Type_dup( MPI_INT, &recvtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( recvtype->datatype, "dup of MPI_INT" );	if (merr) MTestPrintError( merr );	/* dup'ed types are already committed if the original type 	   was committed (MPI-2, section 8.8) */	break;    case 5:	/* vector send type and contiguous receive type */	/* These sizes are in bytes (see the VectorInit code) */ 	sendtype->stride   = 3 * sizeof(int);	sendtype->blksize  = sizeof(int);	sendtype->nelm     = recvtype->count;	merr = MPI_Type_vector( recvtype->count, 1, 3, MPI_INT, 				&sendtype->datatype );	if (merr) MTestPrintError( merr );        merr = MPI_Type_commit( &sendtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( sendtype->datatype, "int-vector" );	if (merr) MTestPrintError( merr );	sendtype->count    = 1; 	recvtype->datatype = MPI_INT;	recvtype->isBasic  = 1;	sendtype->InitBuf  = MTestTypeVectorInit;	recvtype->InitBuf  = MTestTypeContigInitRecv;	sendtype->FreeBuf  = MTestTypeVectorFree;	recvtype->FreeBuf  = MTestTypeContigFree;	sendtype->CheckBuf = 0;	recvtype->CheckBuf = MTestTypeContigCheckbuf;	break;    case 6:	/* Indexed send using many small blocks and contig receive */	sendtype->blksize  = sizeof(int);	sendtype->nelm     = recvtype->count;	sendtype->basesize = sizeof(int);	sendtype->displs   = (int *)malloc( sendtype->nelm * sizeof(int) );	sendtype->index    = (int *)malloc( sendtype->nelm * sizeof(int) );	if (!sendtype->displs || !sendtype->index) {	    MTestError( "Out of memory in type init\n" );	}	/* Make the sizes larger (4 ints) to help push the total	   size to over 256k in some cases, as the MPICH2 code as of	   10/1/06 used large internal buffers for packing non-contiguous	   messages */	for (i=0; i<sendtype->nelm; i++) {	    sendtype->index[i]   = 4;	    sendtype->displs[i]  = 5*i;	}	merr = MPI_Type_indexed( sendtype->nelm,				 sendtype->index, sendtype->displs, 				 MPI_INT, &sendtype->datatype );	if (merr) MTestPrintError( merr );        merr = MPI_Type_commit( &sendtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( sendtype->datatype, "int-indexed(4-int)" );	if (merr) MTestPrintError( merr );	sendtype->count    = 1;	sendtype->InitBuf  = MTestTypeIndexedInit;	sendtype->FreeBuf  = MTestTypeIndexedFree;	sendtype->CheckBuf = 0; 	recvtype->datatype = MPI_INT;	recvtype->isBasic  = 1;	recvtype->count    = count * 4;	recvtype->InitBuf  = MTestTypeContigInitRecv;	recvtype->FreeBuf  = MTestTypeContigFree;	recvtype->CheckBuf = MTestTypeContigCheckbuf;	break;    case 7:	/* Indexed send using 2 large blocks and contig receive */	sendtype->blksize  = sizeof(int);	sendtype->nelm     = 2;	sendtype->basesize = sizeof(int);	sendtype->displs   = (int *)malloc( sendtype->nelm * sizeof(int) );	sendtype->index    = (int *)malloc( sendtype->nelm * sizeof(int) );	if (!sendtype->displs || !sendtype->index) {	    MTestError( "Out of memory in type init\n" );	}	sendtype->index[0]   = (recvtype->count + 1) / 2;	sendtype->displs[0]  = 0;	sendtype->index[1]   = (recvtype->count + 1) / 2;	sendtype->displs[1]  = sendtype->index[0] + 1;	merr = MPI_Type_indexed( sendtype->nelm,				 sendtype->index, sendtype->displs, 				 MPI_INT, &sendtype->datatype );	if (merr) MTestPrintError( merr );        merr = MPI_Type_commit( &sendtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( sendtype->datatype, "int-indexed(2 blocks)" );	if (merr) MTestPrintError( merr );	sendtype->count    = 1;	sendtype->InitBuf  = MTestTypeIndexedInit;	sendtype->FreeBuf  = MTestTypeIndexedFree;	sendtype->CheckBuf = 0; 	recvtype->datatype = MPI_INT;	recvtype->isBasic  = 1;	recvtype->count    = sendtype->index[0] + sendtype->index[1];	recvtype->InitBuf  = MTestTypeContigInitRecv;	recvtype->FreeBuf  = MTestTypeContigFree;	recvtype->CheckBuf = MTestTypeContigCheckbuf;	break;    case 8:	/* Indexed receive using many small blocks and contig send */	recvtype->blksize  = sizeof(int);	recvtype->nelm     = recvtype->count;	recvtype->basesize = sizeof(int);	recvtype->displs   = (int *)malloc( recvtype->nelm * sizeof(int) );	recvtype->index    = (int *)malloc( recvtype->nelm * sizeof(int) );	if (!recvtype->displs || !recvtype->index) {	    MTestError( "Out of memory in type recv init\n" );	}	/* Make the sizes larger (4 ints) to help push the total	   size to over 256k in some cases, as the MPICH2 code as of	   10/1/06 used large internal buffers for packing non-contiguous	   messages */	for (i=0; i<recvtype->nelm; i++) {	    recvtype->index[i]   = 4;	    recvtype->displs[i]  = 5*i;	}	merr = MPI_Type_indexed( recvtype->nelm,				 recvtype->index, recvtype->displs, 				 MPI_INT, &recvtype->datatype );	if (merr) MTestPrintError( merr );        merr = MPI_Type_commit( &recvtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( recvtype->datatype, "recv-int-indexed(4-int)" );	if (merr) MTestPrintError( merr );	recvtype->count    = 1;	recvtype->InitBuf  = MTestTypeIndexedInitRecv;	recvtype->FreeBuf  = MTestTypeIndexedFree;	recvtype->CheckBuf = MTestTypeIndexedCheckbuf; 	sendtype->datatype = MPI_INT;	sendtype->isBasic  = 1;	sendtype->count    = count * 4;	sendtype->InitBuf  = MTestTypeContigInit;	sendtype->FreeBuf  = MTestTypeContigFree;	sendtype->CheckBuf = 0;	break;#if 0    case 9:	/* vector recv type and contiguous send type */	/* These sizes are in bytes (see the VectorInit code) */	recvtype->stride   = 4 * sizeof(int);	recvtype->blksize  = sizeof(int);	recvtype->nelm     = recvtype->count;	merr = MPI_Type_vector( sendtype->count, 1, 4, MPI_INT, 				&recvtype->datatype );	if (merr) MTestPrintError( merr );        merr = MPI_Type_commit( &recvtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( recvtype->datatype, "int-vector" );	if (merr) MTestPrintError( merr );	recvtype->count    = 1;	sendtype->datatype = MPI_INT;	sendtype->isBasic  = 1;	recvtype->InitBuf  = MTestTypeVectorInit;	sendtype->InitBuf  = MTestTypeContigInitRecv;	recvtype->FreeBuf  = MTestTypeVectorFree;	sendtype->FreeBuf  = MTestTypeContigFree;	recvtype->CheckBuf = MTestTypeVectorCheckbuf;	sendtype->CheckBuf = 0;	break;    case 10:	/* contig send and block indexed recv */	/* Make indexes 5*((count-1) - i), for i=0, ..., count-1, i.e., 	   every 5th element, but starting from the end. */	recvtype->blksize  = sizeof(int);	recvtype->nelm     = recvtype->count;	sendtype->displs = (int *) malloc( sendtype->count );	if (!sendtype->displs) {	    MTestError( "Out of memory in indexed block" );	}	for (i=0; i<sendtype->count; i++) {	    sendtype->displs[i] = 5 * ( (count-1) - i );	}	sendtype->basesize = sizeof(int);	sendtype->nelm     = sendtype->count;	merr = MPI_Type_create_index_block( sendtype->count, 1, 					    sendtype->displs, 					    MPI_INT, &recvtype->datatype );	if (merr) MTestPrintError( merr );        merr = MPI_Type_commit( &recvtype->datatype );	if (merr) MTestPrintError( merr );	merr = MPI_Type_set_name( recvtype->datatype, 				  "int-decreasing-indexed" );	if (merr) MTestPrintError( merr );	recvtype->count    = 1;	sendtype->datatype = MPI_INT;	sendtype->isBasic  = 1;	recvtype->InitBuf  = MTestTypeIndexedInit;	sendtype->InitBuf  = MTestTypeContigInitRecv;	recvtype->FreeBuf  = MTestTypeIndexedFree;	sendtype->FreeBuf  = MTestTypeContigFree;	recvtype->CheckBuf = MTestTypeIndexedCheckBuf;	sendtype->CheckBuf = 0;	break;    case 11: 	/* index send and vector recv (using shorts) */	break;#endif    default:	datatype_index = -1;    }    if (!sendtype->InitBuf) {	sendtype->InitBuf  = MTestTypeContigInit;	recvtype->InitBuf  = MTestTypeContigInitRecv;	sendtype->FreeBuf  = MTestTypeContigFree;	recvtype->FreeBuf  = MTestTypeContigFree;	sendtype->CheckBuf = MTestTypeContigCheckbuf;	recvtype->CheckBuf = MTestTypeContigCheckbuf;    }    datatype_index++;    if (dbgflag && datatype_index > 0) {	int typesize;	fprintf( stderr, "%d: sendtype is %s\n", wrank, MTestGetDatatypeName( sendtype ) );	merr = MPI_Type_size( sendtype->datatype, &typesize );	if (merr) MTestPrintError( merr );	fprintf( stderr, "%d: sendtype size = %d\n", wrank, typesize );	fprintf( stderr, "%d: recvtype is %s\n", wrank, MTestGetDatatypeName( recvtype ) );	merr = MPI_Type_size( recvtype->datatype, &typesize );	if (merr) MTestPrintError( merr );	fprintf( stderr, "%d: recvtype size = %d\n", wrank, typesize );	fflush( stderr );	    }    return datatype_index;}/* Reset the datatype index (start from the initial data type.   Note: This routine is rarely needed; MTestGetDatatypes automatically   starts over after the last available datatype is used.*/void MTestResetDatatypes( void ){    datatype_index = 0;}/* Return the index of the current datatype.  This is rarely needed and   is provided mostly to enable debugging of the MTest package itself */int MTestGetDatatypeIndex( void ){    return datatype_index;}/* Free the storage associated with a datatype */void MTestFreeDatatype( MTestDatatype *mtype ){    int merr;    /* Invoke a datatype-specific free function to handle       both the datatype and the send/receive buffers */    if (mtype->FreeBuf) {	(mtype->FreeBuf)( mtype );    }    /* Free the datatype itself if it was created */    if (!mtype->isBasic) {	merr = MPI_Type_free( &mtype->datatype );	if (merr) MTestPrintError( merr );    }}/* Check that a message was received correctly.  Returns the number of   errors detected.  Status may be NULL or MPI_STATUS_IGNORE */int MTestCheckRecv( MPI_Status *status, MTestDatatype *recvtype ){    int count;    int errs = 0, merr;    if (status && status != MPI_STATUS_IGNORE) {	merr = MPI_Get_count( status, recvtype->datatype, &count );	if (merr) MTestPrintError( merr );		/* Check count against expected count */	if (count != recvtype->count) {	    errs ++;	}    }    /* Check received data */    if (!errs && recvtype->CheckBuf( recvtype )) {	errs++;    }    return errs;}/* This next routine uses a circular buffer of static name arrays just to   simplify the use of the routine */const char *MTestGetDatatypeName( MTestDatatype *dtype ){    static char name[4][MPI_MAX_OBJECT_NAME];    static int sp=0;    int rlen, merr;    if (sp >= 4) sp = 0;    merr = MPI_Type_get_name( dtype->datatype, name[sp], &rlen );    if (merr) MTestPrintError( merr );    return (const char *)name[sp++];}/* ----------------------------------------------------------------------- *//*  * Create communicators.  Use separate routines for inter and intra * communicators (there is a routine to give both) * Note that the routines may return MPI_COMM_NULL, so code should test for * that return value as well. *  */static int interCommIdx = 0;static int intraCommIdx = 0;static const char *intraCommName = 0;static const char *interCommName = 0;/*  * Get an intracommunicator with at least min_size members.  If "allowSmaller" * is true, allow the communicator to be smaller than MPI_COMM_WORLD and * for this routine to return MPI_COMM_NULL for some values.  Returns 0 if * no more communicators are available. */int MTestGetIntracommGeneral( MPI_Comm *comm, int min_size, int allowSmaller ){    int size, rank, merr;    int done=0;    int isBasic = 0;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -