void mpi_type_lb_f(MPI_Fint *type, MPI_Fint *lb, MPI_Fint *ierr) { MPI_Datatype c_type = MPI_Type_f2c(*type); MPI_Aint c_lb; *ierr = OMPI_INT_2_FINT(MPI_Type_lb(c_type, &c_lb)); if (MPI_SUCCESS == OMPI_FINT_2_INT(*ierr)) { *lb = OMPI_INT_2_FINT(c_lb); } }
void ADIOI_Datatype_iscontig(MPI_Datatype datatype, int *flag) { MPI_Aint displacement; MPI_Type_lb(datatype, &distplacement); /* SGI's MPI_SGI_type_is_contig() returns true for indexed * datatypes with holes at the beginning, which causes * problems with ROMIO's use of this function. */ *flag = MPI_SGI_type_is_contig(datatype) && (displacement == 0); }
void ompi_type_lb_f(MPI_Fint *type, MPI_Fint *lb, MPI_Fint *ierr) { int c_ierr; MPI_Datatype c_type = MPI_Type_f2c(*type); MPI_Aint c_lb; c_ierr = MPI_Type_lb(c_type, &c_lb); if (NULL != ierr) *ierr = OMPI_INT_2_FINT(c_ierr); if (MPI_SUCCESS == c_ierr) { *lb = OMPI_INT_2_FINT(c_lb); } }
/* * Class: mpi_Datatype * Method: lB * Signature: ()I */ JNIEXPORT jint JNICALL Java_mpi_Datatype_lB (JNIEnv *env, jobject jthis) { MPI_Aint result; clearFreeList(env) ; MPI_Type_lb( (MPI_Datatype)((*env)->GetLongField(env,jthis,DatatypehandleID)), &result); return result; }
int main( int argc, char **argv ) { int i, errs; int size; MPI_Aint extent, lb, ub; MPI_Init( &argc, &argv ); /* This should be run by a single process */ SetupBasicTypes(); errs = 0; for (i=0; i<ntypes; i++) { MPI_Type_size( BasicTypes[i], &size ); MPI_Type_extent( BasicTypes[i], &extent ); MPI_Type_lb( BasicTypes[i], &lb ); MPI_Type_ub( BasicTypes[i], &ub ); if (size != extent) { errs++; printf( "size (%d) != extent (%ld) for basic type %s\n", size, (long) extent, BasicTypesName[i] ); } if (size != BasicSizes[i]) { errs++; printf( "size(%d) != C size (%d) for basic type %s\n", size, BasicSizes[i], BasicTypesName[i] ); } if (lb != 0) { errs++; printf( "Lowerbound of %s was %d instead of 0\n", BasicTypesName[i], (int)lb ); } if (ub != extent) { errs++; printf( "Upperbound of %s was %d instead of %d\n", BasicTypesName[i], (int)ub, (int)extent ); } } if (errs) { printf( "Found %d errors in testing C types\n", errs ); } else { printf( "Found no errors in basic C types\n" ); } MPI_Finalize( ); return 0; }
int main( int argc, char **argv) { int blockcnt[2], rank; MPI_Aint offsets[2], lb, ub, extent; MPI_Datatype tmp_type, newtype; MPI_Init(&argc, &argv); /* Set some values in locations that should not be accessed */ blockcnt[1] = -1; offsets[1] = -1; MPI_Comm_rank( MPI_COMM_WORLD, &rank ); if (rank == 0) { blockcnt[0] = 1; offsets[0] = 3; MPI_Type_hindexed(1, blockcnt, offsets, MPI_BYTE, &tmp_type); blockcnt[0] = 1; offsets[0] = 1; MPI_Type_hindexed(1, blockcnt, offsets, tmp_type, &newtype); MPI_Type_commit(&newtype); MPI_Type_lb(newtype, &lb); MPI_Type_extent(newtype, &extent); MPI_Type_ub(newtype, &ub); /* Check that the results are correct */ #ifdef DEBUG printf("lb=%ld, ub=%ld, extent=%ld\n", lb, ub, extent); printf("Should be lb=4, ub=5, extent=1\n"); #endif if (lb != 4 || ub != 5 || extent != 1) { printf ("lb = %d (should be 4), ub = %d (should be 5) extent = %d should be 1\n", (int)lb, (int)ub, (int)extent) ; } else { printf( " No Errors\n" ); } MPI_Type_free(&tmp_type); MPI_Type_free(&newtype); } MPI_Finalize(); return 0; }
void ADIOI_Calc_my_off_len(ADIO_File fd, int bufcount, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Offset **offset_list_ptr, ADIO_Offset **len_list_ptr, ADIO_Offset *start_offset_ptr, ADIO_Offset *end_offset_ptr, int *contig_access_count_ptr) { MPI_Count filetype_size, etype_size; MPI_Count buftype_size; int i, j, k; ADIO_Offset i_offset; ADIO_Offset frd_size=0, old_frd_size=0; int st_index=0; ADIO_Offset n_filetypes, etype_in_filetype; ADIO_Offset abs_off_in_filetype=0; ADIO_Offset bufsize; ADIO_Offset sum, n_etypes_in_filetype, size_in_filetype; int contig_access_count, filetype_is_contig; ADIO_Offset *len_list; MPI_Aint filetype_extent, filetype_lb; ADIOI_Flatlist_node *flat_file; ADIO_Offset *offset_list, off, end_offset=0, disp; #ifdef AGGREGATION_PROFILE MPE_Log_event (5028, 0, NULL); #endif /* For this process's request, calculate the list of offsets and lengths in the file and determine the start and end offsets. */ ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig); MPI_Type_size_x(fd->filetype, &filetype_size); MPI_Type_extent(fd->filetype, &filetype_extent); MPI_Type_lb(fd->filetype, &filetype_lb); MPI_Type_size_x(datatype, &buftype_size); etype_size = fd->etype_size; if ( ! filetype_size ) { *contig_access_count_ptr = 0; *offset_list_ptr = (ADIO_Offset *) ADIOI_Malloc(2*sizeof(ADIO_Offset)); *len_list_ptr = (ADIO_Offset *) ADIOI_Malloc(2*sizeof(ADIO_Offset)); /* 2 is for consistency. everywhere I malloc one more than needed */ offset_list = *offset_list_ptr; len_list = *len_list_ptr; offset_list[0] = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : fd->disp + (ADIO_Offset)etype_size * offset; len_list[0] = 0; *start_offset_ptr = offset_list[0]; *end_offset_ptr = offset_list[0] + len_list[0] - 1; return; } if (filetype_is_contig) { *contig_access_count_ptr = 1; *offset_list_ptr = (ADIO_Offset *) ADIOI_Malloc(2*sizeof(ADIO_Offset)); *len_list_ptr = (ADIO_Offset *) ADIOI_Malloc(2*sizeof(ADIO_Offset)); /* 2 is for consistency. everywhere I malloc one more than needed */ offset_list = *offset_list_ptr; len_list = *len_list_ptr; offset_list[0] = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : fd->disp + (ADIO_Offset)etype_size * offset; len_list[0] = (ADIO_Offset)bufcount * (ADIO_Offset)buftype_size; *start_offset_ptr = offset_list[0]; *end_offset_ptr = offset_list[0] + len_list[0] - 1; /* update file pointer */ if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = *end_offset_ptr + 1; } else { /* First calculate what size of offset_list and len_list to allocate */ /* filetype already flattened in ADIO_Open or ADIO_Fcntl */ flat_file = ADIOI_Flatlist; while (flat_file->type != fd->filetype) flat_file = flat_file->next; disp = fd->disp; #ifdef RDCOLL_DEBUG { int ii; DBG_FPRINTF(stderr, "flattened %3lld : ", flat_file->count ); for (ii=0; ii<flat_file->count; ii++) { DBG_FPRINTF(stderr, "%16lld:%-16lld", flat_file->indices[ii], flat_file->blocklens[ii] ); } DBG_FPRINTF(stderr, "\n" ); } #endif if (file_ptr_type == ADIO_INDIVIDUAL) { /* Wei-keng reworked type processing to be a bit more efficient */ offset = fd->fp_ind - disp; n_filetypes = (offset - flat_file->indices[0]) / filetype_extent; offset -= (ADIO_Offset)n_filetypes * filetype_extent; /* now offset is local to this extent */ /* find the block where offset is located, skip blocklens[i]==0 */ for (i=0; i<flat_file->count; i++) { ADIO_Offset dist; if (flat_file->blocklens[i] == 0) continue; dist = flat_file->indices[i] + flat_file->blocklens[i] - offset; /* frd_size is from offset to the end of block i */ if (dist == 0) { i++; offset = flat_file->indices[i]; frd_size = flat_file->blocklens[i]; break; } if (dist > 0) { frd_size = dist; break; } } st_index = i; /* starting index in flat_file->indices[] */ offset += disp + (ADIO_Offset)n_filetypes*filetype_extent; } else { n_etypes_in_filetype = filetype_size/etype_size; n_filetypes = offset / n_etypes_in_filetype; etype_in_filetype = offset % n_etypes_in_filetype; size_in_filetype = etype_in_filetype * etype_size; sum = 0; for (i=0; i<flat_file->count; i++) { sum += flat_file->blocklens[i]; if (sum > size_in_filetype) { st_index = i; frd_size = sum - size_in_filetype; abs_off_in_filetype = flat_file->indices[i] + size_in_filetype - (sum - flat_file->blocklens[i]); break; } } /* abs. offset in bytes in the file */ offset = disp + n_filetypes* (ADIO_Offset)filetype_extent + abs_off_in_filetype; } /* calculate how much space to allocate for offset_list, len_list */ old_frd_size = frd_size; contig_access_count = i_offset = 0; j = st_index; bufsize = (ADIO_Offset)buftype_size * (ADIO_Offset)bufcount; frd_size = ADIOI_MIN(frd_size, bufsize); while (i_offset < bufsize) { if (frd_size) contig_access_count++; i_offset += frd_size; j = (j + 1) % flat_file->count; frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset); } /* allocate space for offset_list and len_list */ *offset_list_ptr = (ADIO_Offset *) ADIOI_Malloc((contig_access_count+1)*sizeof(ADIO_Offset)); *len_list_ptr = (ADIO_Offset *) ADIOI_Malloc((contig_access_count+1)*sizeof(ADIO_Offset)); /* +1 to avoid a 0-size malloc */ offset_list = *offset_list_ptr; len_list = *len_list_ptr; /* find start offset, end offset, and fill in offset_list and len_list */ *start_offset_ptr = offset; /* calculated above */ i_offset = k = 0; j = st_index; off = offset; frd_size = ADIOI_MIN(old_frd_size, bufsize); while (i_offset < bufsize) { if (frd_size) { offset_list[k] = off; len_list[k] = frd_size; k++; } i_offset += frd_size; end_offset = off + frd_size - 1; /* Note: end_offset points to the last byte-offset that will be accessed. e.g., if start_offset=0 and 100 bytes to be read, end_offset=99*/ if (off + frd_size < disp + flat_file->indices[j] + flat_file->blocklens[j] + n_filetypes* (ADIO_Offset)filetype_extent) { off += frd_size; /* did not reach end of contiguous block in filetype. * no more I/O needed. off is incremented by frd_size. */ } else { j = (j+1) % flat_file->count; n_filetypes += (j == 0) ? 1 : 0; while (flat_file->blocklens[j]==0) { j = (j+1) % flat_file->count; n_filetypes += (j == 0) ? 1 : 0; /* hit end of flattened filetype; start at beginning * again */ } off = disp + flat_file->indices[j] + n_filetypes* (ADIO_Offset)filetype_extent; frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i_offset); } } /* update file pointer */ if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off; *contig_access_count_ptr = contig_access_count; *end_offset_ptr = end_offset; } #ifdef AGGREGATION_PROFILE MPE_Log_event (5029, 0, NULL); #endif }
int MPIR_intra_Scan ( void *sendbuf, void *recvbuf, int count, struct MPIR_DATATYPE *datatype, MPI_Op op, struct MPIR_COMMUNICATOR *comm ) { MPI_Status status; int rank, size; int mpi_errno = MPI_SUCCESS; MPI_User_function *uop; struct MPIR_OP *op_ptr; int mask, dst; MPI_Aint extent, lb; void *partial_scan, *tmp_buf; static char myname[] = "MPI_SCAN"; if (count == 0) return MPI_SUCCESS; MPIR_Comm_size(comm, &size); MPIR_Comm_rank(comm, &rank); /* Switch communicators to the hidden collective */ comm = comm->comm_coll; /* Lock for collective operation */ MPID_THREAD_LOCK(comm->ADIctx,comm); op_ptr = MPIR_GET_OP_PTR(op); MPIR_TEST_MPI_OP(op,op_ptr,comm,myname); uop = op_ptr->op; /* need to allocate temporary buffer to store partial scan*/ MPI_Type_extent(datatype->self, &extent); MPIR_ALLOC(partial_scan,(void *)MALLOC(count*extent), comm, MPI_ERR_EXHAUSTED, myname); /* adjust for potential negative lower bound in datatype */ MPI_Type_lb( datatype->self, &lb ); partial_scan = (void *)((char*)partial_scan - lb); /* need to allocate temporary buffer to store incoming data*/ MPIR_ALLOC(tmp_buf,(void *)MALLOC(count*extent), comm, MPI_ERR_EXHAUSTED, myname); /* adjust for potential negative lower bound in datatype */ tmp_buf = (void *)((char*)tmp_buf - lb); /* Since this is an inclusive scan, copy local contribution into recvbuf. */ mpi_errno = MPI_Sendrecv ( sendbuf, count, datatype->self, rank, MPIR_SCAN_TAG, recvbuf, count, datatype->self, rank, MPIR_SCAN_TAG, comm->self, &status ); if (mpi_errno) return mpi_errno; mpi_errno = MPI_Sendrecv ( sendbuf, count, datatype->self, rank, MPIR_SCAN_TAG, partial_scan, count, datatype->self, rank, MPIR_SCAN_TAG, comm->self, &status ); if (mpi_errno) return mpi_errno; mask = 0x1; while (mask < size) { dst = rank ^ mask; if (dst < size) { /* Send partial_scan to dst. Recv into tmp_buf */ mpi_errno = MPI_Sendrecv(partial_scan, count, datatype->self, dst, MPIR_SCAN_TAG, tmp_buf, count, datatype->self, dst, MPIR_SCAN_TAG, comm->self, &status); if (mpi_errno) return mpi_errno; if (rank > dst) { (*uop)(tmp_buf, partial_scan, &count, &datatype->self); (*uop)(tmp_buf, recvbuf, &count, &datatype->self); } else { if (op_ptr->commute) (*uop)(tmp_buf, partial_scan, &count, &datatype->self); else { (*uop)(partial_scan, tmp_buf, &count, &datatype->self); mpi_errno = MPI_Sendrecv(tmp_buf, count, datatype->self, rank, MPIR_SCAN_TAG, partial_scan, count, datatype->self, rank, MPIR_SCAN_TAG, comm->self, &status); if (mpi_errno) return mpi_errno; } } } mask <<= 1; } FREE((char *)partial_scan+lb); FREE((char *)tmp_buf+lb); /* Unlock for collective operation */ MPID_THREAD_UNLOCK(comm->ADIctx,comm); return (mpi_errno); }
int main(int argc, char **argv) { int errs = 0, err; int rank, size, source, dest; int minsize = 2, count; MPI_Comm comm; MPI_Win win; MPI_Aint extent,lb; MTestDatatype sendtype, recvtype; int onlyInt = 0; MTest_Init(&argc, &argv); /* Check for a simple choice of communicator and datatypes */ if (getenv("MTEST_SIMPLE")) onlyInt = 1; while (MTestGetIntracommGeneral(&comm, minsize, 1)) { if (comm == MPI_COMM_NULL) continue; /* Determine the sender and receiver */ MPI_Comm_rank(comm, &rank); MPI_Comm_size(comm, &size); source = 0; dest = size - 1; MTEST_DATATYPE_FOR_EACH_COUNT(count) { while (MTestGetDatatypes(&sendtype, &recvtype, count)) { MTestPrintfMsg(1, "Putting count = %d of sendtype %s receive type %s\n", count, MTestGetDatatypeName(&sendtype), MTestGetDatatypeName(&recvtype)); /* Make sure that everyone has a recv buffer */ recvtype.InitBuf(&recvtype); MPI_Type_extent(recvtype.datatype, &extent); MPI_Type_lb(recvtype.datatype, &lb); MPI_Win_create(recvtype.buf, recvtype.count * extent + lb, extent, MPI_INFO_NULL, comm, &win); /* To improve reporting of problems about operations, we * change the error handler to errors return */ MPI_Win_set_errhandler(win, MPI_ERRORS_RETURN); /* At this point, we have all of the elements that we * need to begin the multiple fence and put tests */ /* Fence 1 */ err = MPI_Win_fence(MPI_MODE_NOPRECEDE, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } /* Source puts */ if (rank == source) { sendtype.InitBuf(&sendtype); err = MPI_Put(sendtype.buf, sendtype.count, sendtype.datatype, dest, 0, recvtype.count, recvtype.datatype, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } } /* Fence 2 */ err = MPI_Win_fence(0, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } /* dest checks data, then Dest puts */ if (rank == dest) { err = MTestCheckRecv(0, &recvtype); if (err) { if (errs++ < MAX_PERR) { PrintRecvedError("fence 2", &sendtype, &recvtype); } } sendtype.InitBuf(&sendtype); err = MPI_Put(sendtype.buf, sendtype.count, sendtype.datatype, source, 0, recvtype.count, recvtype.datatype, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } } /* Fence 3 */ err = MPI_Win_fence(0, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } /* src checks data, then Src and dest puts */ if (rank == source) { err = MTestCheckRecv(0, &recvtype); if (err) { if (errs++ < MAX_PERR) { PrintRecvedError("fence 3", &sendtype, &recvtype); } } sendtype.InitBuf(&sendtype); err = MPI_Put(sendtype.buf, sendtype.count, sendtype.datatype, dest, 0, recvtype.count, recvtype.datatype, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } } if (rank == dest) { sendtype.InitBuf(&sendtype); err = MPI_Put(sendtype.buf, sendtype.count, sendtype.datatype, source, 0, recvtype.count, recvtype.datatype, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } } /* Fence 4 */ err = MPI_Win_fence(MPI_MODE_NOSUCCEED, win); if (err) { if (errs++ < MAX_PERR) MTestPrintError(err); } /* src and dest checks data */ if (rank == source) { err = MTestCheckRecv(0, &recvtype); if (err) { if (errs++ < MAX_PERR) { PrintRecvedError("src fence4", &sendtype, &recvtype); } } } if (rank == dest) { err = MTestCheckRecv(0, &recvtype); if (err) { if (errs++ < MAX_PERR) { PrintRecvedError("dest fence4", &sendtype, &recvtype); } } } MPI_Win_free(&win); MTestFreeDatatype(&sendtype); MTestFreeDatatype(&recvtype); /* Only do one datatype in the simple case */ if (onlyInt) break; } /* Only do one count in the simple case */ if (onlyInt) break; } MTestFreeComm(&comm); /* Only do one communicator in the simple case */ if (onlyInt) break; } MTest_Finalize(errs); MPI_Finalize(); return 0; }
int main( int argc, char **argv ) { int nsize, n2size; MPI_Aint nlb, nub, n2lb, n2ub; MPI_Datatype ntype, n2type; MPI_Aint displs[2]; MPI_Datatype types[2]; int blockcounts[2]; double myarray[10]; int err = 0; MPI_Init( &argc, &argv ); MPI_Address( &myarray[0], &displs[0] ); MPI_Address( &myarray[3], &displs[1] ); blockcounts[0] = 3; blockcounts[1] = 1; displs[1] = displs[1] - displs[0]; displs[0] = 0; types[0] = MPI_DOUBLE; types[1] = MPI_DOUBLE; MPI_Type_struct( 2, blockcounts, displs, types, &ntype ); MPI_Type_commit( &ntype ); MPI_Type_size( ntype, &nsize ); MPI_Type_lb( ntype, &nlb ); MPI_Type_ub( ntype, &nub ); if (nlb != 0) { err++; printf( "LB for struct is %d\n", (int)nlb ); } if (nub != 4 * sizeof(double)) { err++; printf( "UB for struct is %d != %d\n", (int)nub, 4 * (int)sizeof(double) ); } if (nsize != 4 * sizeof(double)) { err++; printf( "Size for struct %d != %d\n", nsize, 4 * (int)sizeof(double) ); } MPI_Type_contiguous( 3, ntype, &n2type ); MPI_Type_commit( &n2type ); MPI_Type_size( n2type, &n2size ); MPI_Type_lb( n2type, &n2lb ); MPI_Type_ub( n2type, &n2ub ); if (n2size != 3 * nsize) { err++; printf( "Size of contig type %d != %d\n", n2size, 3*nsize ); } if (n2lb != 0) { err++; printf( "LB for contig is %d\n", (int)n2lb ); } if (n2ub != 3 * nub) { err++; printf( "UB for contig %d != %d\n", (int)n2ub, 3 * (int)nub ); } if (err) { printf( "Found %d errors\n", err ); } else { printf( " No Errors\n" ); } MPI_Type_free( &ntype ); MPI_Type_free( &n2type ); MPI_Finalize(); return 0; }
void declareBindings (void) { /* === Point-to-point === */ void* buf; int count; MPI_Datatype datatype; int dest; int tag; MPI_Comm comm; MPI_Send (buf, count, datatype, dest, tag, comm); // L12 int source; MPI_Status status; MPI_Recv (buf, count, datatype, source, tag, comm, &status); // L15 MPI_Get_count (&status, datatype, &count); MPI_Bsend (buf, count, datatype, dest, tag, comm); MPI_Ssend (buf, count, datatype, dest, tag, comm); MPI_Rsend (buf, count, datatype, dest, tag, comm); void* buffer; int size; MPI_Buffer_attach (buffer, size); // L22 MPI_Buffer_detach (buffer, &size); MPI_Request request; MPI_Isend (buf, count, datatype, dest, tag, comm, &request); // L25 MPI_Ibsend (buf, count, datatype, dest, tag, comm, &request); MPI_Issend (buf, count, datatype, dest, tag, comm, &request); MPI_Irsend (buf, count, datatype, dest, tag, comm, &request); MPI_Irecv (buf, count, datatype, source, tag, comm, &request); MPI_Wait (&request, &status); int flag; MPI_Test (&request, &flag, &status); // L32 MPI_Request_free (&request); MPI_Request* array_of_requests; int index; MPI_Waitany (count, array_of_requests, &index, &status); // L36 MPI_Testany (count, array_of_requests, &index, &flag, &status); MPI_Status* array_of_statuses; MPI_Waitall (count, array_of_requests, array_of_statuses); // L39 MPI_Testall (count, array_of_requests, &flag, array_of_statuses); int incount; int outcount; int* array_of_indices; MPI_Waitsome (incount, array_of_requests, &outcount, array_of_indices, array_of_statuses); // L44--45 MPI_Testsome (incount, array_of_requests, &outcount, array_of_indices, array_of_statuses); // L46--47 MPI_Iprobe (source, tag, comm, &flag, &status); // L48 MPI_Probe (source, tag, comm, &status); MPI_Cancel (&request); MPI_Test_cancelled (&status, &flag); MPI_Send_init (buf, count, datatype, dest, tag, comm, &request); MPI_Bsend_init (buf, count, datatype, dest, tag, comm, &request); MPI_Ssend_init (buf, count, datatype, dest, tag, comm, &request); MPI_Rsend_init (buf, count, datatype, dest, tag, comm, &request); MPI_Recv_init (buf, count, datatype, source, tag, comm, &request); MPI_Start (&request); MPI_Startall (count, array_of_requests); void* sendbuf; int sendcount; MPI_Datatype sendtype; int sendtag; void* recvbuf; int recvcount; MPI_Datatype recvtype; MPI_Datatype recvtag; MPI_Sendrecv (sendbuf, sendcount, sendtype, dest, sendtag, recvbuf, recvcount, recvtype, source, recvtag, comm, &status); // L67--69 MPI_Sendrecv_replace (buf, count, datatype, dest, sendtag, source, recvtag, comm, &status); // L70--71 MPI_Datatype oldtype; MPI_Datatype newtype; MPI_Type_contiguous (count, oldtype, &newtype); // L74 int blocklength; { int stride; MPI_Type_vector (count, blocklength, stride, oldtype, &newtype); // L78 } { MPI_Aint stride; MPI_Type_hvector (count, blocklength, stride, oldtype, &newtype); // L82 } int* array_of_blocklengths; { int* array_of_displacements; MPI_Type_indexed (count, array_of_blocklengths, array_of_displacements, oldtype, &newtype); // L87--88 } { MPI_Aint* array_of_displacements; MPI_Type_hindexed (count, array_of_blocklengths, array_of_displacements, oldtype, &newtype); // L92--93 MPI_Datatype* array_of_types; MPI_Type_struct (count, array_of_blocklengths, array_of_displacements, array_of_types, &newtype); // L95--96 } void* location; MPI_Aint address; MPI_Address (location, &address); // L100 MPI_Aint extent; MPI_Type_extent (datatype, &extent); // L102 MPI_Type_size (datatype, &size); MPI_Aint displacement; MPI_Type_lb (datatype, &displacement); // L105 MPI_Type_ub (datatype, &displacement); MPI_Type_commit (&datatype); MPI_Type_free (&datatype); MPI_Get_elements (&status, datatype, &count); void* inbuf; void* outbuf; int outsize; int position; MPI_Pack (inbuf, incount, datatype, outbuf, outsize, &position, comm); // L114 int insize; MPI_Unpack (inbuf, insize, &position, outbuf, outcount, datatype, comm); // L116--117 MPI_Pack_size (incount, datatype, comm, &size); /* === Collectives === */ MPI_Barrier (comm); // L121 int root; MPI_Bcast (buffer, count, datatype, root, comm); // L123 MPI_Gather (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm); // L124--125 int* recvcounts; int* displs; MPI_Gatherv (sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, root, comm); // L128--130 MPI_Scatter (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, root, comm); // L131--132 int* sendcounts; MPI_Scatterv (sendbuf, sendcounts, displs, sendtype, recvbuf, recvcount, recvtype, root, comm); // L134--135 MPI_Allgather (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm); // L136--137 MPI_Allgatherv (sendbuf, sendcount, sendtype, recvbuf, recvcounts, displs, recvtype, comm); // L138--140 MPI_Alltoall (sendbuf, sendcount, sendtype, recvbuf, recvcount, recvtype, comm); // L141--142 int* sdispls; int* rdispls; MPI_Alltoallv (sendbuf, sendcounts, sdispls, sendtype, recvbuf, recvcounts, rdispls, recvtype, comm); // L145--147 MPI_Op op; MPI_Reduce (sendbuf, recvbuf, count, datatype, op, root, comm); // L149 #if 0 MPI_User_function function; int commute; MPI_Op_create (function, commute, &op); // L153 #endif MPI_Op_free (&op); // L155 MPI_Allreduce (sendbuf, recvbuf, count, datatype, op, comm); MPI_Reduce_scatter (sendbuf, recvbuf, recvcounts, datatype, op, comm); MPI_Scan (sendbuf, recvbuf, count, datatype, op, comm); /* === Groups, contexts, and communicators === */ MPI_Group group; MPI_Group_size (group, &size); // L162 int rank; MPI_Group_rank (group, &rank); // L164 MPI_Group group1; int n; int* ranks1; MPI_Group group2; int* ranks2; MPI_Group_translate_ranks (group1, n, ranks1, group2, ranks2); // L170 int result; MPI_Group_compare (group1, group2, &result); // L172 MPI_Group newgroup; MPI_Group_union (group1, group2, &newgroup); // L174 MPI_Group_intersection (group1, group2, &newgroup); MPI_Group_difference (group1, group2, &newgroup); int* ranks; MPI_Group_incl (group, n, ranks, &newgroup); // L178 MPI_Group_excl (group, n, ranks, &newgroup); extern int ranges[][3]; MPI_Group_range_incl (group, n, ranges, &newgroup); // L181 MPI_Group_range_excl (group, n, ranges, &newgroup); MPI_Group_free (&group); MPI_Comm_size (comm, &size); MPI_Comm_rank (comm, &rank); MPI_Comm comm1; MPI_Comm comm2; MPI_Comm_compare (comm1, comm2, &result); MPI_Comm newcomm; MPI_Comm_dup (comm, &newcomm); MPI_Comm_create (comm, group, &newcomm); int color; int key; MPI_Comm_split (comm, color, key, &newcomm); // L194 MPI_Comm_free (&comm); MPI_Comm_test_inter (comm, &flag); MPI_Comm_remote_size (comm, &size); MPI_Comm_remote_group (comm, &group); MPI_Comm local_comm; int local_leader; MPI_Comm peer_comm; int remote_leader; MPI_Comm newintercomm; MPI_Intercomm_create (local_comm, local_leader, peer_comm, remote_leader, tag, &newintercomm); // L204--205 MPI_Comm intercomm; MPI_Comm newintracomm; int high; MPI_Intercomm_merge (intercomm, high, &newintracomm); // L209 int keyval; #if 0 MPI_Copy_function copy_fn; MPI_Delete_function delete_fn; void* extra_state; MPI_Keyval_create (copy_fn, delete_fn, &keyval, extra_state); // L215 #endif MPI_Keyval_free (&keyval); // L217 void* attribute_val; MPI_Attr_put (comm, keyval, attribute_val); // L219 MPI_Attr_get (comm, keyval, attribute_val, &flag); MPI_Attr_delete (comm, keyval); /* === Environmental inquiry === */ char* name; int resultlen; MPI_Get_processor_name (name, &resultlen); // L226 MPI_Errhandler errhandler; #if 0 MPI_Handler_function function; MPI_Errhandler_create (function, &errhandler); // L230 #endif MPI_Errhandler_set (comm, errhandler); // L232 MPI_Errhandler_get (comm, &errhandler); MPI_Errhandler_free (&errhandler); int errorcode; char* string; MPI_Error_string (errorcode, string, &resultlen); // L237 int errorclass; MPI_Error_class (errorcode, &errorclass); // L239 MPI_Wtime (); MPI_Wtick (); int argc; char** argv; MPI_Init (&argc, &argv); // L244 MPI_Finalize (); MPI_Initialized (&flag); MPI_Abort (comm, errorcode); }
void ADIOI_Calc_my_off_len(ADIO_File fd, int bufcount, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Offset **offset_list_ptr, int **len_list_ptr, ADIO_Offset *start_offset_ptr, ADIO_Offset *end_offset_ptr, int *contig_access_count_ptr) { int filetype_size, buftype_size, etype_size; int i, j, k, frd_size=0, old_frd_size=0, st_index=0; int n_filetypes, etype_in_filetype; ADIO_Offset abs_off_in_filetype=0; int bufsize, sum, n_etypes_in_filetype, size_in_filetype; int contig_access_count, *len_list, flag, filetype_is_contig; MPI_Aint filetype_extent, filetype_lb; ADIOI_Flatlist_node *flat_file; ADIO_Offset *offset_list, off, end_offset=0, disp; /* For this process's request, calculate the list of offsets and lengths in the file and determine the start and end offsets. */ ADIOI_Datatype_iscontig(fd->filetype, &filetype_is_contig); MPI_Type_size(fd->filetype, &filetype_size); MPI_Type_extent(fd->filetype, &filetype_extent); MPI_Type_lb(fd->filetype, &filetype_lb); MPI_Type_size(datatype, &buftype_size); etype_size = fd->etype_size; if (filetype_is_contig) { *contig_access_count_ptr = 1; *offset_list_ptr = (ADIO_Offset *) ADIOI_Malloc(2*sizeof(ADIO_Offset)); *len_list_ptr = (int *) ADIOI_Malloc(2*sizeof(int)); /* 2 is for consistency. everywhere I malloc one more than needed */ offset_list = *offset_list_ptr; len_list = *len_list_ptr; offset_list[0] = (file_ptr_type == ADIO_INDIVIDUAL) ? fd->fp_ind : fd->disp + etype_size * offset; len_list[0] = bufcount * buftype_size; *start_offset_ptr = offset_list[0]; *end_offset_ptr = offset_list[0] + len_list[0] - 1; /* update file pointer */ if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = *end_offset_ptr + 1; } else { /* First calculate what size of offset_list and len_list to allocate */ /* filetype already flattened in ADIO_Open or ADIO_Fcntl */ flat_file = ADIOI_Flatlist; while (flat_file->type != fd->filetype) flat_file = flat_file->next; disp = fd->disp; if (file_ptr_type == ADIO_INDIVIDUAL) { offset = fd->fp_ind; /* in bytes */ n_filetypes = -1; flag = 0; while (!flag) { n_filetypes++; for (i=0; i<flat_file->count; i++) { if (disp + flat_file->indices[i] + (ADIO_Offset) n_filetypes*filetype_extent + flat_file->blocklens[i] >= offset) { st_index = i; frd_size = (int) (disp + flat_file->indices[i] + (ADIO_Offset) n_filetypes*filetype_extent + flat_file->blocklens[i] - offset); flag = 1; break; } } } } else { n_etypes_in_filetype = filetype_size/etype_size; n_filetypes = (int) (offset / n_etypes_in_filetype); etype_in_filetype = (int) (offset % n_etypes_in_filetype); size_in_filetype = etype_in_filetype * etype_size; sum = 0; for (i=0; i<flat_file->count; i++) { sum += flat_file->blocklens[i]; if (sum > size_in_filetype) { st_index = i; frd_size = sum - size_in_filetype; abs_off_in_filetype = flat_file->indices[i] + size_in_filetype - (sum - flat_file->blocklens[i]); break; } } /* abs. offset in bytes in the file */ offset = disp + (ADIO_Offset) n_filetypes*filetype_extent + abs_off_in_filetype; } /* calculate how much space to allocate for offset_list, len_list */ old_frd_size = frd_size; contig_access_count = i = 0; j = st_index; bufsize = buftype_size * bufcount; frd_size = ADIOI_MIN(frd_size, bufsize); while (i < bufsize) { if (frd_size) contig_access_count++; i += frd_size; j = (j + 1) % flat_file->count; frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i); } /* allocate space for offset_list and len_list */ *offset_list_ptr = (ADIO_Offset *) ADIOI_Malloc((contig_access_count+1)*sizeof(ADIO_Offset)); *len_list_ptr = (int *) ADIOI_Malloc((contig_access_count+1)*sizeof(int)); /* +1 to avoid a 0-size malloc */ offset_list = *offset_list_ptr; len_list = *len_list_ptr; /* find start offset, end offset, and fill in offset_list and len_list */ *start_offset_ptr = offset; /* calculated above */ i = k = 0; j = st_index; off = offset; frd_size = ADIOI_MIN(old_frd_size, bufsize); while (i < bufsize) { if (frd_size) { offset_list[k] = off; len_list[k] = frd_size; k++; } i += frd_size; end_offset = off + frd_size - 1; /* Note: end_offset points to the last byte-offset that will be accessed. e.g., if start_offset=0 and 100 bytes to be read, end_offset=99*/ if (off + frd_size < disp + flat_file->indices[j] + flat_file->blocklens[j] + (ADIO_Offset) n_filetypes*filetype_extent) off += frd_size; /* did not reach end of contiguous block in filetype. no more I/O needed. off is incremented by frd_size. */ else { if (j < (flat_file->count - 1)) j++; else { j = 0; n_filetypes++; } off = disp + flat_file->indices[j] + (ADIO_Offset) n_filetypes*filetype_extent; frd_size = ADIOI_MIN(flat_file->blocklens[j], bufsize-i); } } /* update file pointer */ if (file_ptr_type == ADIO_INDIVIDUAL) fd->fp_ind = off; *contig_access_count_ptr = contig_access_count; *end_offset_ptr = end_offset; } }
static inline int test(MPI_Comm comm, int rank, int source, int dest, MTestDatatype * sendtype, MTestDatatype * recvtype) { int errs = 0, err; MPI_Aint extent, lb; MPI_Win win; MTestPrintfMsg(1, "Putting count = %ld of sendtype %s - count = %ld receive type %s\n", sendtype->count, MTestGetDatatypeName(sendtype), recvtype->count, MTestGetDatatypeName(recvtype)); /* Make sure that everyone has a recv buffer */ recvtype->InitBuf(recvtype); MPI_Type_extent(recvtype->datatype, &extent); MPI_Type_lb(recvtype->datatype, &lb); MPI_Win_create(recvtype->buf, recvtype->count * extent + lb, extent, MPI_INFO_NULL, comm, &win); MPI_Win_fence(0, win); if (rank == source) { /* To improve reporting of problems about operations, we * change the error handler to errors return */ MPI_Win_set_errhandler(win, MPI_ERRORS_RETURN); sendtype->InitBuf(sendtype); err = MPI_Put(sendtype->buf, sendtype->count, sendtype->datatype, dest, 0, recvtype->count, recvtype->datatype, win); if (err) { errs++; if (errs < 10) { MTestPrintError(err); } } err = MPI_Win_fence(0, win); if (err) { errs++; if (errs < 10) { MTestPrintError(err); } } } else if (rank == dest) { MPI_Win_fence(0, win); /* This should have the same effect, in terms of * transfering data, as a send/recv pair */ err = MTestCheckRecv(0, recvtype); if (err) { if (errs < 10) { printf ("Data in target buffer did not match for destination datatype %s (put with source datatype %s)\n", MTestGetDatatypeName(recvtype), MTestGetDatatypeName(sendtype)); /* Redo the test, with the errors printed */ recvtype->printErrors = 1; (void) MTestCheckRecv(0, recvtype); } errs += err; } } else { MPI_Win_fence(0, win); } MPI_Win_free(&win); return errs; }
int main (int argc, char **argv) { int i, e; MPI_Aint lb; MPI_Datatype type, types[4]; MPI_Aint indices[1]; int blocklens[1]; MPI_Datatype oldtypes[1]; MPI_Init( &argc, &argv ); indices[0] = 0; blocklens[0] = 2; oldtypes[0] = MPI_CHAR; /* generate four distinct datatypes - should trigger a leak report */ for( i = 0; i < 4; i++ ) { MPI_Type_vector( 1, i+2, i+2, MPI_CHAR, types + i ); MPI_Type_commit( types + i ); MPI_Type_lb( types[i], &lb ); } /* now free one and create it again - should not trigger a report */ type = types[3]; MPI_Type_free( types + 3 ); MPI_Type_lb( type, &lb ); MPI_Type_vector( 1, 3+2, 3+2, MPI_CHAR, types + 3 ); MPI_Type_commit( types + 3 ); /* creating the same type over and over again is expected to create new handles */ for( i = 0; i < 2; i++ ) { MPI_Type_vector( 1, 10, 10, MPI_CHAR, types + i ); MPI_Type_commit( types + i ); assert( i == 0 || types[i] != types[0] ); } /* each type has to be freed once */ type = types[1]; MPI_Type_free( types + 1 ); MPI_Type_lb( type, &lb ); MPI_Type_lb( types[0], &lb ); /* now trigger leak report */ for( i = 1; i < 4; i++ ) { MPI_Type_vector( 1, 10, 10, MPI_CHAR, types + i ); MPI_Type_commit( types + i ); assert( i == 0 || types[i] != types[0] ); } /* create the same type (two chars) in four other ways, thus trigger a leak report */ MPI_Type_hvector( 1, 2, 2, MPI_CHAR, &type ); MPI_Type_commit( &type ); MPI_Type_commit( &type ); /* should have no effect */ MPI_Type_contiguous( 2, MPI_CHAR, &type ); /* MPI_Type_commit( &type ); */ /* intentionally missing - should be included in leak report anyway */ MPI_Type_hindexed( 1, blocklens, indices, MPI_CHAR, &type ); MPI_Type_commit( &type ); MPI_Type_struct( 1, blocklens, indices, oldtypes, &type ); MPI_Type_commit( &type ); /* * Create a custom type, then "duplicate" it by creating * a type derived from it which is identical to it * (in MPI-2 one could use MPI_Type_dup()). First create * and free without commit, then with. * * None of this should trigger an error. */ MPI_Type_contiguous( 2, MPI_CHAR, types + 0 ); MPI_Type_contiguous( 1, types[0], types + 1 ); MPI_Type_free( types + 0 ); MPI_Type_free( types + 1 ); MPI_Type_contiguous( 2, MPI_CHAR, types + 0 ); MPI_Type_commit( types + 0); MPI_Type_contiguous( 1, types[0], types + 1 ); MPI_Type_commit( types + 1 ); MPI_Type_free( types + 0 ); MPI_Type_free( types + 1 ); MPI_Finalize( ); return 0; }