typetest.c

来自「MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程」· C语言 代码 · 共 311 行

C
311
字号
/*  * Patrick Bridges * bridges@mcs.anl.gov * patrick@CS.MsState.Edu  * * Modified by William Gropp */#include <stdio.h>#include <stdlib.h>#include "test.h"#include "mpi.h"#include <string.h>/* CM5 users need to comment out the next include (memory.h) because    of an error in the CM5 include file (memory.h is inconsistent with   string.h) *//* #include <memory.h> */struct struct1 {    double d1;    char   c1[8];};struct struct2 {    double d1;    double d2;    char   c1[8];    char   c2[8];    double d3;    char   c3[8];    double d4;    char   c4[8];};struct struct3 {    double d1[2];    char  c1[2][8];    struct struct1 s1[2];};/* Structure with probable gap */struct struct4 {    int a1;    char c1, c2;    int a2;};   int main( int argc, char **argv ){    int rank, size, ret;     MPI_Status Status;    MPI_Datatype struct1_t, struct2_t, struct3_t, struct4_t, struct4a_t,	astruct1_t, carray_t;    static int block1[2] = {1, 1};    static int block2[6] = {2, 2, 1, 1, 1, 1};    static int block3[3] = {2, 2, 1};    static int block4[4] = {1, 1, 1, 1};    static int block4a[3] = {1, 2, 1};    MPI_Aint disp1[2], disp2[6], disp3[6], disp4[4], disp4a[3];    MPI_Datatype type1[2], type2[6], type3[3];    static MPI_Datatype type4[4] = {MPI_INT, MPI_CHAR, MPI_CHAR, MPI_INT};    static MPI_Datatype type4a[3] = {MPI_INT, MPI_CHAR, MPI_INT};    struct struct1 dummy1;    struct struct2 dummy2;    struct struct3 dummy3;    struct struct4 dummy4;    int i, master_rank = 0, slave_rank = 1;    MPI_Init(&argc, &argv);    MPI_Comm_rank(MPI_COMM_WORLD, &rank);    MPI_Comm_size(MPI_COMM_WORLD, &size);    for (i=1; i<argc; i++) {	if (argv[i] && strcmp("-alt",argv[i]) == 0) {	    master_rank = 1;	    slave_rank  = 0;	    printf( "[%d] setting master rank to 1\n", rank );	    }	}    Test_Init("typetest", rank);    /* Create some types to try out */    /* A simple array of characters */     MPI_Type_contiguous(8, MPI_CHAR, &carray_t);     ret = MPI_Type_commit(&carray_t);    if (ret != MPI_SUCCESS) {	fprintf(stderr, "Could not make char array type."), fflush(stderr); 	MPI_Abort( MPI_COMM_WORLD, 1 );    }    /* A fairly simple structure */    MPI_Address( &dummy1, &disp1[0] );    MPI_Address( &dummy1.c1[0], &disp1[1] );    disp1[1] = disp1[1] - disp1[0];    disp1[0] = 0;    type1[0] = MPI_DOUBLE;    type1[1] = carray_t;    MPI_Type_struct(2, block1, disp1, type1, &struct1_t);    ret = MPI_Type_commit(&struct1_t);    if (ret != MPI_SUCCESS) {	fprintf(stderr, "Could not make struct 1."); fflush(stderr);         MPI_Abort( MPI_COMM_WORLD, 1 );    }    /* And a short array of this type */    MPI_Type_contiguous(2, struct1_t, &astruct1_t);    ret = MPI_Type_commit(&astruct1_t);    if (ret != MPI_SUCCESS) {	fprintf(stderr, "Could not make struct 1 array."); fflush(stderr);        MPI_Abort( MPI_COMM_WORLD, 1 );    }        /* A more complex structure */    MPI_Address( &dummy2, &disp2[0] );    MPI_Address( &dummy2.c1[0], &disp2[1] );    MPI_Address( &dummy2.d3, &disp2[2] );    MPI_Address( &dummy2.c3[0], &disp2[3] );    MPI_Address( &dummy2.d4, &disp2[4] );    MPI_Address( &dummy2.c4[0], &disp2[5] );    for (i=1; i<6; i++) {      disp2[i] = disp2[i] - disp2[0];    }    disp2[0] = 0;                        type2[0] = MPI_DOUBLE; type2[1] = carray_t; type2[2] = MPI_DOUBLE;    type2[3] = carray_t; type2[4] = MPI_DOUBLE; type2[5] = carray_t;    MPI_Type_struct(6, block2, disp2, type2, &struct2_t);    ret = MPI_Type_commit(&struct2_t);    if (ret != MPI_SUCCESS) {	fprintf(stderr, "Could not make struct 2."), fflush(stderr);	MPI_Abort( MPI_COMM_WORLD, 1 );    }    /* Another (hopefully compatible) complex structure */    MPI_Address( &dummy3, &disp3[0] );    MPI_Address( &dummy3.c1[0][0], &disp3[1] );    MPI_Address( &dummy3.s1[0], &disp3[2] );    for (i=1; i<3; i++)       disp3[i] = disp3[i] - disp3[0];    disp3[0] = 0;     type3[0] = MPI_DOUBLE; type3[1] = carray_t; type3[2] = astruct1_t;    MPI_Type_struct(3, block3, disp3, type3, &struct3_t);    ret = MPI_Type_commit(&struct3_t);    if (ret != MPI_SUCCESS) {	fprintf(stderr, "Could not make struct 3."), fflush(stderr);	MPI_Abort( MPI_COMM_WORLD, 1 );    }    /* A structure with gaps (invokes padding) */    MPI_Address( &dummy4.a1, &disp4[0] );    MPI_Address( &dummy4.c1, &disp4[1] );    MPI_Address( &dummy4.c2, &disp4[2] );    MPI_Address( &dummy4.a2, &disp4[3] );    for (i=1; i<4; i++) 	disp4[i] = disp4[i] - disp4[0];    disp4[0] = 0;    MPI_Type_struct(4, block4, disp4, type4, &struct4_t);    ret = MPI_Type_commit(&struct4_t);    MPI_Address( &dummy4.a1, &disp4a[0] );    MPI_Address( &dummy4.c1, &disp4a[1] );    MPI_Address( &dummy4.a2, &disp4a[2] );    for (i=1; i<3; i++) 	disp4a[i] = disp4a[i] - disp4a[0];    disp4a[0] = 0;    MPI_Type_struct(3, block4a, disp4a, type4a, &struct4a_t);    ret = MPI_Type_commit(&struct4a_t);    /* Wait for everyone to be ready */    MPI_Barrier(MPI_COMM_WORLD);    if (rank == master_rank) { 		/* Fill up the type */	dummy2.d1 = 11.0; dummy2.d2 = 12.0; dummy2.d3 = 13.0; dummy2.d4 = 14.0;	strncpy(dummy2.c1, "two", 8);	strncpy(dummy2.c2, "four", 8);	strncpy(dummy2.c3, "six", 8);	strncpy(dummy2.c4, "eight", 8);		/* Send the type */	MPI_Send(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD);	/* Clear out the type */	memset(&dummy2, 0, sizeof(dummy2));	/* And receive it back */	MPI_Recv(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD, 		 &Status);		/* Did it make it OK? */	if ((dummy2.d1 != 11.0) || (dummy2.d2 != 12.0) || 	    (dummy2.d3 != 13.0) || (dummy2.d4 != 14.0) || 	    strncmp(dummy2.c1, "two", 8) || strncmp(dummy2.c2, "four", 8) || 	    strncmp(dummy2.c3, "six", 8) || strncmp(dummy2.c4, "eight", 8)) {	    Test_Failed("Complex Type Round Trip Test");#ifdef MPE_USE_EXTENSIONS	    printf( "Pack action is\n" );	    MPIR_PrintDatatypePack( stdout, 1, struct2_t, (long)&dummy2, 0 );	    printf( "Unpack action is\n" );	    MPIR_PrintDatatypeUnpack( stdout, 1, struct2_t, 0, (long)&dummy2 );#endif	} else {	    Test_Passed("Complex Type Round Trip Test");	}	/* Fill up the type again */	dummy2.d1 = 11.0; dummy2.d2 = 12.0; dummy2.d3 = 13.0; dummy2.d4 = 14.0;	strncpy(dummy2.c1, "two", 8);	strncpy(dummy2.c2, "four", 8);	strncpy(dummy2.c3, "six", 8);	strncpy(dummy2.c4, "eight", 8);		/* Send the type */	MPI_Send(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD);	/* Clear out the type */	memset(&dummy2, 0, sizeof(dummy2));	/* And receive it back */	MPI_Recv(&dummy2, 1, struct2_t, slave_rank, 2000, MPI_COMM_WORLD, 		 &Status);		/* Did it make it OK? */	if ((dummy2.d1 != 11.0) || (dummy2.d2 != 12.0) || 	    (dummy2.d3 != 13.0) || (dummy2.d4 != 14.0) || 	    strncmp(dummy2.c1, "two", 8) || strncmp(dummy2.c2, "four", 8) || 	    strncmp(dummy2.c3, "six", 8) || strncmp(dummy2.c4, "eight", 8))	    Test_Failed("Compatible Complex Type Round Trip Test");	else	    Test_Passed("Compatible Complex Type Round Trip Test");	/* Expect ints to be at least 4 bytes.  Make sure that the MSbit is	   0 so that there are no sign-extension suprises. */	dummy4.a1 = 0x17faec2b;	dummy4.c1 = 'c';	dummy4.c2 = 'F';	dummy4.a2 = 0x91fb8354;	MPI_Send( &dummy4, 1, struct4_t, slave_rank, 2004, MPI_COMM_WORLD );	memset( &dummy4, 0, sizeof(dummy4) );	MPI_Recv( &dummy4, 1, struct4a_t, slave_rank, 2004, MPI_COMM_WORLD, 		  &Status );	/* Check for correct data */	if (dummy4.a1 != 0x17faec2b || dummy4.c1 != 'c' ||	    dummy4.c2 != 'F' || dummy4.a2 != 0x91fb8354) {	    Test_Failed( "Padded Structure Type Round Trip Test" );	    }	else {	    Test_Passed( "Padded Structure Type Round Trip Test" );	    }	if ((MPI_Type_free(&struct3_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct1_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct2_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct4_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct4a_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&astruct1_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&carray_t) != MPI_SUCCESS))	    Test_Failed("Type Free test");	else	    Test_Passed("Type Free test");		Test_Waitforall( );    } else {	MPI_Recv(&dummy2, 1, struct2_t, master_rank, 2000, 		 MPI_COMM_WORLD, &Status);	MPI_Send(&dummy2, 1, struct2_t, master_rank, 2000, MPI_COMM_WORLD);	MPI_Recv(&dummy3, 1, struct3_t, master_rank, 2000, MPI_COMM_WORLD, 		 &Status);	if ((dummy3.d1[0] != 11.0) || (dummy3.d1[1] != 12.0) || 	    (dummy3.s1[0].d1 != 13.0) || (dummy3.s1[1].d1 != 14.0) || 	    strncmp(dummy3.c1[0], "two", 8) || 	    strncmp(dummy3.c1[1], "four", 8) || 	    strncmp(dummy3.s1[0].c1, "six", 8) || 	    strncmp(dummy3.s1[1].c1, "eight", 8)) {	    /* Kill dummy3 so it will die after it's sent back */	    memset(&dummy3, 0, sizeof(dummy3));	    Test_Message("Message didn't convert properly. Hosing \return message.");	}	MPI_Send(&dummy3, 1, struct3_t, master_rank, 2000, MPI_COMM_WORLD);	/* Use same structure type */	MPI_Recv( &dummy4, 1, struct4_t, master_rank, 2004, MPI_COMM_WORLD, 		  &Status );	MPI_Send( &dummy4, 1, struct4_t, master_rank, 2004, MPI_COMM_WORLD );	if ((MPI_Type_free(&struct3_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct1_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct2_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct4_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&struct4a_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&astruct1_t) != MPI_SUCCESS) ||	    (MPI_Type_free(&carray_t) != MPI_SUCCESS))	    Test_Failed("Type Free test");	else	    Test_Passed("Type Free test");	Test_Waitforall( );    }    if (rank == master_rank) { 		(void)Summarize_Test_Results();	}    Test_Finalize();    MPI_Finalize();return 0;}

⌨️ 快捷键说明

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