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

📄 mtest.c

📁 fortran并行计算包
💻 C
📖 第 1 页 / 共 3 页
字号:
    /* The while loop allows us to skip communicators that are too small.       MPI_COMM_NULL is always considered large enough */    while (!done) {	isBasic = 0;	intraCommName = "";	switch (intraCommIdx) {	case 0:	    *comm = MPI_COMM_WORLD;	    isBasic = 1;	    intraCommName = "MPI_COMM_WORLD";	    break;	case 1:	    /* dup of world */	    merr = MPI_Comm_dup(MPI_COMM_WORLD, comm );	    if (merr) MTestPrintError( merr );	    intraCommName = "Dup of MPI_COMM_WORLD";	    break;	case 2:	    /* reverse ranks */	    merr = MPI_Comm_size( MPI_COMM_WORLD, &size );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_split( MPI_COMM_WORLD, 0, size-rank, comm );	    if (merr) MTestPrintError( merr );	    intraCommName = "Rank reverse of MPI_COMM_WORLD";	    break;	case 3:	    /* subset of world, with reversed ranks */	    merr = MPI_Comm_size( MPI_COMM_WORLD, &size );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_split( MPI_COMM_WORLD, (rank < size/2), 				   size-rank, comm );	    if (merr) MTestPrintError( merr );	    intraCommName = "Rank reverse of half of MPI_COMM_WORLD";	    break;	case 4:	    *comm = MPI_COMM_SELF;	    isBasic = 1;	    intraCommName = "MPI_COMM_SELF";	    break;	    /* These next cases are communicators that include some	       but not all of the processes */	case 5:	case 6:	case 7:	case 8:	{	    int newsize;	    merr = MPI_Comm_size( MPI_COMM_WORLD, &size );	    if (merr) MTestPrintError( merr );	    newsize = size - (intraCommIdx - 4);	    	    if (allowSmaller && newsize >= min_size) {		merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );		if (merr) MTestPrintError( merr );		merr = MPI_Comm_split( MPI_COMM_WORLD, rank < newsize, rank, 				       comm );		if (merr) MTestPrintError( merr );		if (rank >= newsize) {		    merr = MPI_Comm_free( comm );		    if (merr) MTestPrintError( merr );		    *comm = MPI_COMM_NULL;		}		else {		    intraCommName = "Split of WORLD";		}	    }	    else {		/* Act like default */		*comm = MPI_COMM_NULL;		isBasic = 1;		intraCommName = "MPI_COMM_NULL";		intraCommIdx = -1;	    }	}	break;	    	    /* Other ideas: dup of self, cart comm, graph comm */	default:	    *comm = MPI_COMM_NULL;	    isBasic = 1;	    intraCommName = "MPI_COMM_NULL";	    intraCommIdx = -1;	    break;	}	if (*comm != MPI_COMM_NULL) {	    merr = MPI_Comm_size( *comm, &size );	    if (merr) MTestPrintError( merr );	    if (size >= min_size) 		done = 1;	    else {		/* Try again */		if (!isBasic) {		    merr = MPI_Comm_free( comm );		    if (merr) MTestPrintError( merr );		}		intraCommIdx++;	    }	}	else	    done = 1;    }    intraCommIdx++;    return intraCommIdx;}/*  * Get an intracommunicator with at least min_size members. */int MTestGetIntracomm( MPI_Comm *comm, int min_size ) {    return MTestGetIntracommGeneral( comm, min_size, 0 );}/* Return the name of an intra communicator */const char *MTestGetIntracommName( void ){    return intraCommName;}/*  * Return an intercomm; set isLeftGroup to 1 if the calling process is  * a member of the "left" group. */int MTestGetIntercomm( MPI_Comm *comm, int *isLeftGroup, int min_size ){    int size, rank, remsize, merr;    int done=0;    MPI_Comm mcomm;    int rleader;    /* The while loop allows us to skip communicators that are too small.       MPI_COMM_NULL is always considered large enough.  The size is       the sum of the sizes of the local and remote groups */    while (!done) {	switch (interCommIdx) {	case 0:	    /* Split comm world in half */	    merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_size( MPI_COMM_WORLD, &size );	    if (merr) MTestPrintError( merr );	    if (size > 1) {		merr = MPI_Comm_split( MPI_COMM_WORLD, (rank < size/2), rank, 				       &mcomm );		if (merr) MTestPrintError( merr );		if (rank == 0) {		    rleader = size/2;		}		else if (rank == size/2) {		    rleader = 0;		}		else {		    /* Remote leader is signficant only for the processes		       designated local leaders */		    rleader = -1;		}		*isLeftGroup = rank < size/2;		merr = MPI_Intercomm_create( mcomm, 0, MPI_COMM_WORLD, rleader,					     12345, comm );		if (merr) MTestPrintError( merr );		merr = MPI_Comm_free( &mcomm );		if (merr) MTestPrintError( merr );		interCommName = "Intercomm by splitting MPI_COMM_WORLD";	    }	    else 		*comm = MPI_COMM_NULL;	    break;	case 1:	    /* Split comm world in to 1 and the rest */	    merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_size( MPI_COMM_WORLD, &size );	    if (merr) MTestPrintError( merr );	    if (size > 1) {		merr = MPI_Comm_split( MPI_COMM_WORLD, rank == 0, rank, 				       &mcomm );		if (merr) MTestPrintError( merr );		if (rank == 0) {		    rleader = 1;		}		else if (rank == 1) {		    rleader = 0;		}		else {		    /* Remote leader is signficant only for the processes		       designated local leaders */		    rleader = -1;		}		*isLeftGroup = rank == 0;		merr = MPI_Intercomm_create( mcomm, 0, MPI_COMM_WORLD, 					     rleader, 12346, comm );		if (merr) MTestPrintError( merr );		merr = MPI_Comm_free( &mcomm );		if (merr) MTestPrintError( merr );		interCommName = "Intercomm by splitting MPI_COMM_WORLD into 1, rest";	    }	    else 		*comm = MPI_COMM_NULL;	    break;	case 2:	    /* Split comm world in to 2 and the rest */	    merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_size( MPI_COMM_WORLD, &size );	    if (merr) MTestPrintError( merr );	    if (size > 3) {		merr = MPI_Comm_split( MPI_COMM_WORLD, rank < 2, rank, 				       &mcomm );		if (merr) MTestPrintError( merr );		if (rank == 0) {		    rleader = 2;		}		else if (rank == 2) {		    rleader = 0;		}		else {		    /* Remote leader is signficant only for the processes		       designated local leaders */		    rleader = -1;		}		*isLeftGroup = rank < 2;		merr = MPI_Intercomm_create( mcomm, 0, MPI_COMM_WORLD, 					     rleader, 12347, comm );		if (merr) MTestPrintError( merr );		merr = MPI_Comm_free( &mcomm );		if (merr) MTestPrintError( merr );		interCommName = "Intercomm by splitting MPI_COMM_WORLD into 2, rest";	    }	    else 		*comm = MPI_COMM_NULL;	    break;	    	default:	    *comm = MPI_COMM_NULL;	    interCommName = "MPI_COMM_NULL";	    interCommIdx = -1;	    break;	}	if (*comm != MPI_COMM_NULL) {	    merr = MPI_Comm_size( *comm, &size );	    if (merr) MTestPrintError( merr );	    merr = MPI_Comm_remote_size( *comm, &remsize );	    if (merr) MTestPrintError( merr );	    if (size + remsize >= min_size) done = 1;	}	else	    done = 1;    }    interCommIdx++;    return interCommIdx;}/* Return the name of an intercommunicator */const char *MTestGetIntercommName( void ){    return interCommName;}/* Get a communicator of a given minimum size.  Both intra and inter    communicators are provided */int MTestGetComm( MPI_Comm *comm, int min_size ){    int idx=0;    static int getinter = 0;    if (!getinter) {	idx = MTestGetIntracomm( comm, min_size );	if (idx == 0) {	    getinter = 1;	}    }    if (getinter) {	int isLeft;	idx = MTestGetIntercomm( comm, &isLeft, min_size );	if (idx == 0) {	    getinter = 0;	}    }    return idx;}/* Free a communicator.  It may be called with a predefined communicator or MPI_COMM_NULL */void MTestFreeComm( MPI_Comm *comm ){    int merr;    if (*comm != MPI_COMM_WORLD &&	*comm != MPI_COMM_SELF &&	*comm != MPI_COMM_NULL) {	merr = MPI_Comm_free( comm );	if (merr) MTestPrintError( merr );    }}/* ------------------------------------------------------------------------ */void MTestPrintError( int errcode ){    int errclass, slen;    char string[MPI_MAX_ERROR_STRING];        MPI_Error_class( errcode, &errclass );    MPI_Error_string( errcode, string, &slen );    printf( "Error class %d (%s)\n", errclass, string );    fflush( stdout );}void MTestPrintErrorMsg( const char msg[], int errcode ){    int errclass, slen;    char string[MPI_MAX_ERROR_STRING];        MPI_Error_class( errcode, &errclass );    MPI_Error_string( errcode, string, &slen );    printf( "%s: Error class %d (%s)\n", msg, errclass, string );     fflush( stdout );}/* ------------------------------------------------------------------------ */void MTestPrintfMsg( int level, const char format[], ... ){    va_list list;    int n;    if (verbose && level >= verbose) {	va_start(list,format);	n = vprintf( format, list );	va_end(list);	fflush(stdout);    }}/* Fatal error.  Report and exit */void MTestError( const char *msg ){    fprintf( stderr, "%s\n", msg );    fflush( stderr );    MPI_Abort( MPI_COMM_WORLD, 1 );}/* ------------------------------------------------------------------------ */#ifdef HAVE_MPI_WIN_CREATE/* * Create MPI Windows */static int win_index = 0;static const char *winName;/* Use an attribute to remember the type of memory allocation (static,   malloc, or MPI_Alloc_mem) */static int mem_keyval = MPI_KEYVAL_INVALID;int MTestGetWin( MPI_Win *win, int mustBePassive ){    static char actbuf[1024];    static char *pasbuf;    char        *buf;    int         n, rank, merr;    MPI_Info    info;    if (mem_keyval == MPI_KEYVAL_INVALID) {	/* Create the keyval */	merr = MPI_Win_create_keyval( MPI_WIN_NULL_COPY_FN, 				      MPI_WIN_NULL_DELETE_FN, 				      &mem_keyval, 0 );	if (merr) MTestPrintError( merr );    }    switch (win_index) {    case 0:	/* Active target window */	merr = MPI_Win_create( actbuf, 1024, 1, MPI_INFO_NULL, MPI_COMM_WORLD, 			       win );	if (merr) MTestPrintError( merr );	winName = "active-window";	merr = MPI_Win_set_attr( *win, mem_keyval, (void *)0 );	if (merr) MTestPrintError( merr );	break;    case 1:	/* Passive target window */	merr = MPI_Alloc_mem( 1024, MPI_INFO_NULL, &pasbuf );	if (merr) MTestPrintError( merr );	merr = MPI_Win_create( pasbuf, 1024, 1, MPI_INFO_NULL, MPI_COMM_WORLD, 			       win );	if (merr) MTestPrintError( merr );	winName = "passive-window";	merr = MPI_Win_set_attr( *win, mem_keyval, (void *)2 );	if (merr) MTestPrintError( merr );	break;    case 2:	/* Active target; all windows different sizes */	merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );	if (merr) MTestPrintError( merr );	n = rank * 64;	if (n) 	    buf = (char *)malloc( n );	else	    buf = 0;	merr = MPI_Win_create( buf, n, 1, MPI_INFO_NULL, MPI_COMM_WORLD, 			       win );	if (merr) MTestPrintError( merr );	winName = "active-all-different-win";	merr = MPI_Win_set_attr( *win, mem_keyval, (void *)1 );	if (merr) MTestPrintError( merr );	break;    case 3:	/* Active target, no locks set */	merr = MPI_Comm_rank( MPI_COMM_WORLD, &rank );	if (merr) MTestPrintError( merr );	n = rank * 64;	if (n) 	    buf = (char *)malloc( n );	else	    buf = 0;	merr = MPI_Info_create( &info );	if (merr) MTestPrintError( merr );	merr = MPI_Info_set( info, "nolocks", "true" );	if (merr) MTestPrintError( merr );	merr = MPI_Win_create( buf, n, 1, info, MPI_COMM_WORLD, win );	if (merr) MTestPrintError( merr );	merr = MPI_Info_free( &info );	if (merr) MTestPrintError( merr );	winName = "active-nolocks-all-different-win";	merr = MPI_Win_set_attr( *win, mem_keyval, (void *)1 );	if (merr) MTestPrintError( merr );	break;    default:	win_index = -1;    }    win_index++;    return win_index;}/* Return a pointer to the name associated with a window object */const char *MTestGetWinName( void ){    return winName;}/* Free the storage associated with a window object */void MTestFreeWin( MPI_Win *win ){    void *addr;    int  flag, merr;    merr = MPI_Win_get_attr( *win, MPI_WIN_BASE, &addr, &flag );    if (merr) MTestPrintError( merr );    if (!flag) {	MTestError( "Could not get WIN_BASE from window" );    }    if (addr) {	void *val;	merr = MPI_Win_get_attr( *win, mem_keyval, &val, &flag );	if (merr) MTestPrintError( merr );	if (flag) {	    if (val == (void *)1) {		free( addr );	    }	    else if (val == (void *)2) {		merr = MPI_Free_mem( addr );		if (merr) MTestPrintError( merr );	    }	    /* if val == (void *)0, then static data that must not be freed */	}    }    merr = MPI_Win_free(win);    if (merr) MTestPrintError( merr );}#endif

⌨️ 快捷键说明

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