📄 noncontig_coll2.c
字号:
dest[strlen(dest) - 1] = '\0'; } MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);}void simple_shuffle_str(int mynod, int len, ADIO_cb_name_array array, char *dest){ char *ptr; int i, p; if (!mynod) { ptr = dest; for (i=(array->namect / 2 ); i < array->namect; i++) { p = snprintf(ptr, len, "%s,", array->names[i]); ptr += p; } for (i=0; i < (array->namect / 2); i++ ) { p = snprintf(ptr, len, "%s,", array->names[i]); ptr += p; } dest[strlen(dest) - 1] = '\0'; } MPI_Bcast(dest, len, MPI_CHAR, 0, MPI_COMM_WORLD);}int main(int argc, char **argv){ int i, mynod, nprocs, len, errs=0, sum_errs=0, verbose=0; char *filename; char * cb_config_string; int cb_config_len; ADIO_cb_name_array array; MPI_Init(&argc,&argv); MPI_Comm_size(MPI_COMM_WORLD, &nprocs); MPI_Comm_rank(MPI_COMM_WORLD, &mynod); /* process 0 takes the file name as a command-line argument and broadcasts it to other processes */ if (!mynod) { i = 1; /* TODO: at some point, accept -v for verbose */ while ((i < argc) && strcmp("-fname", *argv)) { i++; argv++; } if (i >= argc) { fprintf(stderr, "\n*# Usage: noncontig_coll -fname filename\n\n"); MPI_Abort(MPI_COMM_WORLD, 1); } argv++; len = strlen(*argv); filename = (char *) malloc(len+1); strcpy(filename, *argv); MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD); } else { MPI_Bcast(&len, 1, MPI_INT, 0, MPI_COMM_WORLD); filename = (char *) malloc(len+1); MPI_Bcast(filename, len+1, MPI_CHAR, 0, MPI_COMM_WORLD); } /* want to hint the cb_config_list, but do so in a non-sequential way */ cb_gather_name_array(MPI_COMM_WORLD, &array); /* sanity check */ if (!mynod) { if (array->namect < 2 ) { fprintf(stderr, "Run this test on two or more hosts\n"); MPI_Abort(MPI_COMM_WORLD, 1); } } /* get space for the permuted cb_config_string */ if (!mynod) { cb_config_len = 0; for (i=0; i < array->namect; i++) { /* +1: space for either a , or \0 if last */ cb_config_len += strlen(array->names[i]) + 1; } ++cb_config_len; } MPI_Bcast(&cb_config_len, 1, MPI_INT, 0, MPI_COMM_WORLD); if ( (cb_config_string = malloc(cb_config_len)) == NULL ) { perror("malloc"); MPI_Abort(MPI_COMM_WORLD, 1); } /* first, no hinting */ errs += test_file(filename, mynod, nprocs, NULL, "collective w/o hinting", verbose); /* hint, but no change in order */ default_str(mynod, cb_config_len, array, cb_config_string); errs += test_file(filename, mynod, nprocs, cb_config_string, "collective w/ hinting: default order", verbose); /* reverse order */ reverse_str(mynod, cb_config_len, array, cb_config_string); errs += test_file(filename, mynod, nprocs, cb_config_string, "collective w/ hinting: reverse order", verbose); /* reverse, every other */ reverse_alternating_str(mynod, cb_config_len, array, cb_config_string); errs += test_file(filename, mynod, nprocs, cb_config_string,"collective w/ hinting: permutation1", verbose); /* second half, first half */ simple_shuffle_str(mynod, cb_config_len, array, cb_config_string); errs += test_file(filename, mynod, nprocs, cb_config_string, "collective w/ hinting: permutation2", verbose); MPI_Allreduce(&errs, &sum_errs, 1, MPI_INT, MPI_SUM, MPI_COMM_WORLD); if (!mynod) { if (sum_errs) fprintf(stderr, "Found %d error cases\n", sum_errs); else printf(" No Errors\n"); } free(filename); free(cb_config_string); MPI_Finalize(); return 0;}#define SEEDER(x,y,z) ((x)*1000000 + (y) + (x)*(z))int test_file(char *filename, int mynod, int nprocs, char * cb_hosts, char *msg, int verbose) { MPI_Datatype typevec, newtype, t[3]; int *buf, i, b[3], errcode, errors=0; MPI_File fh; MPI_Aint d[3]; MPI_Status status; int SIZE = (STARTING_SIZE/nprocs)*nprocs; MPI_Info info; if (mynod==0 && verbose) fprintf(stderr, "%s\n", msg); buf = (int *) malloc(SIZE*sizeof(int)); if (buf == NULL) { perror("test_file"); MPI_Abort(MPI_COMM_WORLD, -1); } if (cb_hosts != NULL ) { MPI_Info_create(&info); MPI_Info_set(info, "cb_config_list", cb_hosts); } else { info = MPI_INFO_NULL; } MPI_Type_vector(SIZE/nprocs, 1, nprocs, MPI_INT, &typevec); b[0] = b[1] = b[2] = 1; d[0] = 0; d[1] = mynod*sizeof(int); d[2] = SIZE*sizeof(int); t[0] = MPI_LB; t[1] = typevec; t[2] = MPI_UB; MPI_Type_struct(3, b, d, t, &newtype); MPI_Type_commit(&newtype); MPI_Type_free(&typevec); if (!mynod) { if(verbose) fprintf(stderr, "\ntesting noncontiguous in memory, noncontiguous in file using collective I/O\n"); MPI_File_delete(filename, info); } MPI_Barrier(MPI_COMM_WORLD); errcode = MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); if (errcode != MPI_SUCCESS) { handle_error(errcode, "MPI_File_open"); } MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info); for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod,i,SIZE); MPI_File_write_all(fh, buf, 1, newtype, &status); MPI_Barrier(MPI_COMM_WORLD); for (i=0; i<SIZE; i++) buf[i] = -1; MPI_File_read_at_all(fh, 0, buf, 1, newtype, &status); /* the verification for N compute nodes is tricky. Say we have 3 * processors. * process 0 sees: 0 -1 -1 3 -1 -1 ... * process 1 sees: -1 34 -1 -1 37 -1 ... * process 2 sees: -1 -1 68 -1 -1 71 ... */ /* verify those leading -1s exist if they should */ for (i=0; i<mynod; i++ ) { if ( buf[i] != -1 ) { if(verbose) fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]); errors++; } } /* now the modulo games are hairy. processor 0 sees real data in the 0th, * 3rd, 6th... elements of the buffer (assuming nprocs==3 ). proc 1 sees * the data in 1st, 4th, 7th..., and proc 2 sees it in 2nd, 5th, 8th */ for(/* 'i' set in above loop */; i<SIZE; i++) { if ( ((i-mynod)%nprocs) && buf[i] != -1) { if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); errors++; } if ( !((i-mynod)%nprocs) && buf[i] != SEEDER(mynod,i,SIZE) ) { if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], SEEDER(mynod,i,SIZE)); errors++; } } MPI_File_close(&fh); MPI_Barrier(MPI_COMM_WORLD); if (!mynod) { if(verbose) fprintf(stderr, "\ntesting noncontiguous in memory, contiguous in file using collective I/O\n"); MPI_File_delete(filename, info); } MPI_Barrier(MPI_COMM_WORLD); MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod,i,SIZE); MPI_File_write_at_all(fh, mynod*(SIZE/nprocs)*sizeof(int), buf, 1, newtype, &status); MPI_Barrier(MPI_COMM_WORLD); for (i=0; i<SIZE; i++) buf[i] = -1; MPI_File_read_at_all(fh, mynod*(SIZE/nprocs)*sizeof(int), buf, 1, newtype, &status); /* just like as above */ for (i=0; i<mynod; i++ ) { if ( buf[i] != -1 ) { if(verbose) fprintf(stderr, "Process %d: buf is %d, should be -1\n", mynod, buf[i]); errors++; } } for(/* i set in above loop */; i<SIZE; i++) { if ( ((i-mynod)%nprocs) && buf[i] != -1) { if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be -1\n", mynod, i, buf[i]); errors++; } if ( !((i-mynod)%nprocs) && buf[i] != SEEDER(mynod,i,SIZE)) { if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], SEEDER(mynod,i,SIZE) ); errors++; } } MPI_File_close(&fh); MPI_Barrier(MPI_COMM_WORLD); if (!mynod) { if(verbose) fprintf(stderr, "\ntesting contiguous in memory, noncontiguous in file using collective I/O\n"); MPI_File_delete(filename, info); } MPI_Barrier(MPI_COMM_WORLD); MPI_File_open(MPI_COMM_WORLD, filename, MPI_MODE_CREATE | MPI_MODE_RDWR, info, &fh); MPI_File_set_view(fh, 0, MPI_INT, newtype, "native", info); for (i=0; i<SIZE; i++) buf[i] = SEEDER(mynod, i, SIZE); MPI_File_write_all(fh, buf, SIZE, MPI_INT, &status); MPI_Barrier(MPI_COMM_WORLD); for (i=0; i<SIZE; i++) buf[i] = -1; MPI_File_read_at_all(fh, 0, buf, SIZE, MPI_INT, &status); /* same crazy checking */ for (i=0; i<SIZE; i++) { if (buf[i] != SEEDER(mynod, i, SIZE)) { if(verbose) fprintf(stderr, "Process %d: buf %d is %d, should be %d\n", mynod, i, buf[i], SEEDER(mynod, i, SIZE)); errors++; } } MPI_File_close(&fh); MPI_Type_free(&newtype); free(buf); if (info != MPI_INFO_NULL) MPI_Info_free(&info); return errors;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -