/*@ MPI_File_get_group - Returns the group of processes that opened the file Input Parameters: . fh - file handle (handle) Output Parameters: . group - group that opened the file (handle) .N fortran @*/ int MPI_File_get_group(MPI_File fh, MPI_Group *group) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_GET_GROUP"; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ /* note: this will return the group of processes that called open, but * with deferred open this might not be the group of processes that * actually opened the file from the file system's perspective */ error_code = MPI_Comm_group(adio_fh->comm, group); fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_get_view - Returns the file view Input Parameters: . fh - file handle (handle) Output Parameters: . disp - displacement (nonnegative integer) . etype - elementary datatype (handle) . filetype - filetype (handle) . datarep - data representation (string) .N fortran @*/ int MPI_File_get_view(MPI_File fh, MPI_Offset * disp, MPI_Datatype * etype, MPI_Datatype * filetype, char *datarep) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_GET_VIEW"; int i, j, k, combiner; MPI_Datatype copy_etype, copy_filetype; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); if (datarep == NULL) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iodatarepnomem", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ *disp = adio_fh->disp; ADIOI_Strncpy(datarep, (adio_fh->is_external32 ? "external32" : "native"), MPI_MAX_DATAREP_STRING); MPI_Type_get_envelope(adio_fh->etype, &i, &j, &k, &combiner); if (combiner == MPI_COMBINER_NAMED) *etype = adio_fh->etype; else { /* FIXME: It is wrong to use MPI_Type_contiguous; the user could choose to * re-implement MPI_Type_contiguous in an unexpected way. Either use * MPID_Barrier as in MPICH or PMPI_Type_contiguous */ MPI_Type_contiguous(1, adio_fh->etype, ©_etype); /* FIXME: Ditto for MPI_Type_commit - use NMPI or PMPI */ MPI_Type_commit(©_etype); *etype = copy_etype; } /* FIXME: Ditto for MPI_Type_xxx - use NMPI or PMPI */ MPI_Type_get_envelope(adio_fh->filetype, &i, &j, &k, &combiner); if (combiner == MPI_COMBINER_NAMED) *filetype = adio_fh->filetype; else { MPI_Type_contiguous(1, adio_fh->filetype, ©_filetype); MPI_Type_commit(©_filetype); *filetype = copy_filetype; } fn_exit: ROMIO_THREAD_CS_EXIT(); return MPI_SUCCESS; }
int MPIO_Testsome(int count, MPIO_Request requests[], int *outcount, int indices[], MPI_Status *statuses) { int i, err; int flag; MPID_THREADPRIV_DECL; ROMIO_THREAD_CS_ENTER(); if (count == 1) { err = MPIO_Test( requests, &flag, statuses ); if (!err) { if (flag) { indices[0] = 0; *outcount = 1; } else { *outcount = 0; } } goto fn_exit; } /* Check for no active requests */ for (i=0; i<count; i++) { if (requests[i] != MPIO_REQUEST_NULL) { break; } } if (i == count) { *outcount = MPI_UNDEFINED; err = MPI_SUCCESS; goto fn_exit; } err = MPI_SUCCESS; *outcount = 0; for (i=0; i<count; i++) { if (requests[i] != MPIO_REQUEST_NULL) { err = MPIO_Test( &requests[i], &flag, statuses ); if (flag) { if (!err) { indices[0] = i; indices++; statuses++; *outcount = *outcount + 1; } } } } fn_exit: ROMIO_THREAD_CS_EXIT(); return err; }
int MPIO_Waitany(int count, MPIO_Request requests[], int *index, MPI_Status *status) { int i, flag, err; MPID_THREADPRIV_DECL; ROMIO_THREAD_CS_ENTER(); if (count == 1) { err = MPIO_Wait( requests, status ); if (!err) *index = 0; goto fn_exit; } /* Check for no active requests */ for (i=0; i<count; i++) { if (requests[i] != MPIO_REQUEST_NULL) { break; } } if (i == count) { *index = MPI_UNDEFINED; #ifdef MPICH /* need to set empty status */ if (status != MPI_STATUS_IGNORE) { status->MPI_SOURCE = MPI_ANY_SOURCE; status->MPI_TAG = MPI_ANY_TAG; MPIR_STATUS_SET_COUNT(*status, 0); MPIR_STATUS_SET_CANCEL_BIT(*status, 0); } #endif err = MPI_SUCCESS; goto fn_exit; } err = MPI_SUCCESS; do { flag = 0; for (i=0; i<count; i++) { if (requests[i] != MPIO_REQUEST_NULL) { err = MPIO_Test( &requests[i], &flag, status ); if (flag) { if (!err) *index = i; break; } } } } while (flag == 0); fn_exit: ROMIO_THREAD_CS_EXIT(); return err; }
int MPIO_Testall(int count, MPIO_Request requests[], int *flag, MPI_Status statuses[]) { int done, i, err; ROMIO_THREAD_CS_ENTER(); if (count == 1) { err = MPIO_Test( requests, flag, statuses ); goto fn_exit; } /* This is actually very difficult to do. We can't use MPIO_Test, since we must change the requests only if *ALL* requests are complete */ /* FIXME: THIS IS NOT CORRECT (see above). But most applications won't care */ done = 1; for (i=0; i<count; i++) { if (requests[i] != MPIO_REQUEST_NULL) { err = MPIO_Test( &requests[i], flag, &statuses[i] ); if (!*flag) done = 0; if (err) goto fn_exit; } else { #ifdef MPICH /* need to set empty status */ if (statuses != MPI_STATUSES_IGNORE) { statuses[i].MPI_SOURCE = MPI_ANY_SOURCE; statuses[i].MPI_TAG = MPI_ANY_TAG; MPIR_STATUS_SET_COUNT(statuses[i], 0); MPIR_STATUS_SET_CANCEL_BIT(statuses[i], 0); } #else ; #endif } } *flag = done; err = MPI_SUCCESS; fn_exit: ROMIO_THREAD_CS_EXIT(); return err; }
/*@ MPI_File_sync - Causes all previous writes to be transferred to the storage device Input Parameters: . fh - file handle (handle) .N fortran @*/ int MPI_File_sync(MPI_File fh) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_SYNC"; #ifdef MPI_hpux int fl_xmpi; HPMP_IO_START(fl_xmpi, BLKMPIFILESYNC, TRDTBLOCK, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ if ((adio_fh <= (MPI_File) 0) || ((adio_fh)->cookie != ADIOI_FILE_COOKIE)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadfh", 0); error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code); goto fn_exit; } MPIO_CHECK_WRITABLE(fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIO_Flush(adio_fh, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ #ifdef MPI_hpux HPMP_IO_END(fl_xmpi, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_get_info - Returns the hints for a file that are actually being used by MPI Input Parameters: . fh - file handle (handle) Output Parameters: . info_used - info object (handle) .N fortran @*/ int MPI_File_get_info(MPI_File fh, MPI_Info *info_used) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_GET_INFO"; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ error_code = MPI_Info_dup(adio_fh->info, info_used); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_write_ordered_end - Complete a split collective write using shared file pointer Input Parameters: . fh - file handle (handle) Output Parameters: . buf - initial address of buffer (choice) . status - status object (Status) .N fortran @*/ int MPI_File_write_ordered_end(MPI_File fh, ROMIO_CONST void *buf, MPI_Status *status) { int error_code; static char myname[] = "MPI_FILE_WRITE_ORDERED_END"; ADIO_File adio_fh; MPIU_UNREFERENCED_ARG(buf); ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); if (!(adio_fh->split_coll_count)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**iosplitcollnone", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ #ifdef HAVE_STATUS_SET_BYTES if (status != MPI_STATUS_IGNORE) *status = adio_fh->split_status; #endif adio_fh->split_coll_count = 0; fn_exit: ROMIO_THREAD_CS_EXIT(); return MPI_SUCCESS; }
/*@ MPI_File_set_size - Sets the file size Input Parameters: . fh - file handle (handle) . size - size to truncate or expand file (nonnegative integer) .N fortran @*/ int MPI_File_set_size(MPI_File fh, MPI_Offset size) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_SET_SIZE"; MPI_Offset tmp_sz, max_sz, min_sz; #ifdef MPI_hpux int fl_xmpi; HPMP_IO_START(fl_xmpi, BLKMPIFILESETSIZE, TRDTBLOCK, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_NOT_SEQUENTIAL_MODE(adio_fh, myname, error_code); if (size < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadsize", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } MPIO_CHECK_WRITABLE(fh, myname, error_code); /* --END ERROR HANDLING-- */ tmp_sz = size; MPI_Allreduce(&tmp_sz, &max_sz, 1, ADIO_OFFSET, MPI_MAX, adio_fh->comm); MPI_Allreduce(&tmp_sz, &min_sz, 1, ADIO_OFFSET, MPI_MIN, adio_fh->comm); /* --BEGIN ERROR HANDLING-- */ if (max_sz != min_sz) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**notsame", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ if (!ADIO_Feature(adio_fh, ADIO_SCALABLE_RESIZE)) { /* rare stupid file systems (like NFS) need to carry out resize on all * processes */ ADIOI_TEST_DEFERRED(adio_fh, "MPI_File_set_size", &error_code); } ADIO_Resize(adio_fh, size, &error_code); /* TODO: what to do with error code? */ /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ #ifdef MPI_hpux HPMP_IO_END(fl_xmpi, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_read_ordered_begin - Begin a split collective read using shared file pointer Input Parameters: . fh - file handle (handle) . count - number of elements in buffer (nonnegative integer) . datatype - datatype of each buffer element (handle) Output Parameters: . buf - initial address of buffer (choice) .N fortran @*/ int MPI_File_read_ordered_begin(MPI_File fh, void *buf, int count, MPI_Datatype datatype) { int error_code, nprocs, myrank; MPI_Count datatype_size; int source, dest; ADIO_Offset shared_fp, incr; ADIO_File adio_fh; static char myname[] = "MPI_FILE_READ_ORDERED_BEGIN"; void *xbuf=NULL, *e32_buf=NULL; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_COUNT(adio_fh, count, myname, error_code); MPIO_CHECK_DATATYPE(adio_fh, datatype, myname, error_code); if (adio_fh->split_coll_count) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**iosplitcoll", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ adio_fh->split_coll_count = 1; MPI_Type_size_x(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(adio_fh, count, datatype_size, myname, error_code); MPIO_CHECK_FS_SUPPORTS_SHARED(adio_fh, myname, error_code); MPIO_CHECK_COUNT_SIZE(adio_fh, count, datatype_size, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_TEST_DEFERRED(adio_fh, myname, &error_code); MPI_Comm_size(adio_fh->comm, &nprocs); MPI_Comm_rank(adio_fh->comm, &myrank); incr = (count*datatype_size)/adio_fh->etype_size; /* Use a message as a 'token' to order the operations */ source = myrank - 1; dest = myrank + 1; if (source < 0) source = MPI_PROC_NULL; if (dest >= nprocs) dest = MPI_PROC_NULL; MPI_Recv(NULL, 0, MPI_BYTE, source, 0, adio_fh->comm, MPI_STATUS_IGNORE); ADIO_Get_shared_fp(adio_fh, incr, &shared_fp, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPI_Send(NULL, 0, MPI_BYTE, dest, 0, adio_fh->comm); xbuf = buf; if (adio_fh->is_external32) { MPI_Aint e32_size = 0; error_code = MPIU_datatype_full_size(datatype, &e32_size); if (error_code != MPI_SUCCESS) goto fn_exit; e32_buf = ADIOI_Malloc(e32_size*count); xbuf = e32_buf; } ADIO_ReadStridedColl(adio_fh, xbuf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, &adio_fh->split_status, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ if (e32_buf != NULL) { error_code = MPIU_read_external32_conversion_fn(xbuf, datatype, count, e32_buf); ADIOI_Free(e32_buf); } fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
int MPIOI_File_iread_all(MPI_File fh, MPI_Offset offset, int file_ptr_type, void *buf, int count, MPI_Datatype datatype, char *myname, MPI_Request *request) { int error_code; MPI_Count datatype_size; ADIO_File adio_fh; void *xbuf=NULL, *e32_buf=NULL; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_COUNT(adio_fh, count, myname, error_code); MPIO_CHECK_DATATYPE(adio_fh, datatype, myname, error_code); if (file_ptr_type == ADIO_EXPLICIT_OFFSET && offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadoffset", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPI_Type_size_x(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(adio_fh, count, datatype_size, myname, error_code); MPIO_CHECK_READABLE(adio_fh, myname, error_code); MPIO_CHECK_NOT_SEQUENTIAL_MODE(adio_fh, myname, error_code); MPIO_CHECK_COUNT_SIZE(adio_fh, count, datatype_size, myname, error_code); /* --END ERROR HANDLING-- */ xbuf = buf; if (adio_fh->is_external32) { MPI_Aint e32_size = 0; error_code = MPIU_datatype_full_size(datatype, &e32_size); if (error_code != MPI_SUCCESS) goto fn_exit; e32_buf = ADIOI_Malloc(e32_size*count); xbuf = e32_buf; } ADIO_IreadStridedColl(adio_fh, xbuf, count, datatype, file_ptr_type, offset, request, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ if (e32_buf != NULL) { error_code = MPIU_read_external32_conversion_fn(buf, datatype, count, e32_buf); ADIOI_Free(e32_buf); } fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_read_shared - Read using shared file pointer Input Parameters: . fh - file handle (handle) . count - number of elements in buffer (nonnegative integer) . datatype - datatype of each buffer element (handle) Output Parameters: . buf - initial address of buffer (choice) . status - status object (Status) .N fortran @*/ int MPI_File_read_shared(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) { int error_code, buftype_is_contig, filetype_is_contig; static char myname[] = "MPI_FILE_READ_SHARED"; MPI_Count datatype_size; ADIO_Offset off, shared_fp, incr, bufsize; ADIO_File adio_fh; void *xbuf=NULL, *e32_buf=NULL; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_COUNT(adio_fh, count, myname, error_code); MPIO_CHECK_DATATYPE(adio_fh, datatype, myname, error_code); /* --END ERROR HANDLING-- */ MPI_Type_size_x(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_COUNT_SIZE(adio_fh, count, datatype_size, myname, error_code); /* --END ERROR HANDLING-- */ if (count*datatype_size == 0) { #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, 0); #endif error_code = MPI_SUCCESS; goto fn_exit; } /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(adio_fh, count, datatype_size, myname, error_code); MPIO_CHECK_READABLE(adio_fh, myname, error_code); MPIO_CHECK_FS_SUPPORTS_SHARED(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_Datatype_iscontig(datatype, &buftype_is_contig); ADIOI_Datatype_iscontig(adio_fh->filetype, &filetype_is_contig); ADIOI_TEST_DEFERRED(adio_fh, myname, &error_code); incr = (count*datatype_size)/adio_fh->etype_size; ADIO_Get_shared_fp(adio_fh, incr, &shared_fp, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ xbuf = buf; if (adio_fh->is_external32) { MPI_Aint e32_size = 0; error_code = MPIU_datatype_full_size(datatype, &e32_size); if (error_code != MPI_SUCCESS) goto fn_exit; e32_buf = ADIOI_Malloc(e32_size*count); xbuf = e32_buf; } /* contiguous or strided? */ if (buftype_is_contig && filetype_is_contig) { /* convert count and shared_fp to bytes */ bufsize = datatype_size * count; off = adio_fh->disp + adio_fh->etype_size * shared_fp; /* if atomic mode requested, lock (exclusive) the region, because there could be a concurrent noncontiguous request. On NFS, locking is done in the ADIO_ReadContig.*/ if ((adio_fh->atomicity) && (adio_fh->file_system != ADIO_NFS)) ADIOI_WRITE_LOCK(adio_fh, off, SEEK_SET, bufsize); ADIO_ReadContig(adio_fh, xbuf, count, datatype, ADIO_EXPLICIT_OFFSET, off, status, &error_code); if ((adio_fh->atomicity) && (adio_fh->file_system != ADIO_NFS)) ADIOI_UNLOCK(adio_fh, off, SEEK_SET, bufsize); } else { ADIO_ReadStrided(adio_fh, xbuf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, status, &error_code); /* For strided and atomic mode, locking is done in ADIO_ReadStrided */ } /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ if (e32_buf != NULL) { error_code = MPIU_read_external32_conversion_fn(buf, datatype, count, e32_buf); ADIOI_Free(e32_buf); } fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_Register_datarep - Register functions for user-defined data representations Input Parameters: + datarep - data representation name (string) . read_conversion_fn - function invoked to convert from file representation to native representation (function) . write_conversion_fn - function invoked to convert from native representation to file representation (function) . dtype_file_extent_fn - function invoked to get the exted of a datatype as represented in the file (function) - extra_state - pointer to extra state that is passed to each of the three functions Notes: This function allows the user to provide routines to convert data from an external representation, used within a file, and the native representation, used within the CPU. There is one predefined data representation, 'external32'. Please consult the MPI-2 standard for details on this function. .N fortran @*/ int MPI_Register_datarep(ROMIO_CONST char *datarep, MPI_Datarep_conversion_function *read_conversion_fn, MPI_Datarep_conversion_function *write_conversion_fn, MPI_Datarep_extent_function *dtype_file_extent_fn, void *extra_state) { int error_code; ADIOI_Datarep *adio_datarep; static char myname[] = "MPI_REGISTER_DATAREP"; ROMIO_THREAD_CS_ENTER(); /* --BEGIN ERROR HANDLING-- */ /* check datarep name (use strlen instead of strnlen because strnlen is not portable) */ if (datarep == NULL || strlen(datarep) < 1 || strlen(datarep) > MPI_MAX_DATAREP_STRING) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**datarepname", 0); error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPIR_MPIOInit(&error_code); if (error_code != MPI_SUCCESS) goto fn_exit; /* --BEGIN ERROR HANDLING-- */ /* check datarep isn't already registered */ for (adio_datarep = ADIOI_Datarep_head; adio_datarep; adio_datarep = adio_datarep->next) { if (!strncmp(datarep, adio_datarep->name, MPI_MAX_DATAREP_STRING)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_DUP_DATAREP, "**datarepused", "**datarepused %s", datarep); error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code); goto fn_exit; } } /* Check Non-NULL Read and Write conversion function pointer */ /* Read and Write conversions are currently not supported. */ if ( (read_conversion_fn != NULL) || (write_conversion_fn != NULL) ) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_CONVERSION, "**drconvnotsupported", 0); error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code); goto fn_exit; } /* check extent function pointer */ if (dtype_file_extent_fn == NULL) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**datarepextent", 0); error_code = MPIO_Err_return_file(MPI_FILE_NULL, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ adio_datarep = ADIOI_Malloc(sizeof(ADIOI_Datarep)); adio_datarep->name = ADIOI_Strdup(datarep); adio_datarep->state = extra_state; adio_datarep->read_conv_fn = read_conversion_fn; adio_datarep->write_conv_fn = write_conversion_fn; adio_datarep->extent_fn = dtype_file_extent_fn; adio_datarep->next = ADIOI_Datarep_head; ADIOI_Datarep_head = adio_datarep; error_code = MPI_SUCCESS; fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_seek - Updates the individual file pointer Input Parameters: . fh - file handle (handle) . offset - file offset (integer) . whence - update mode (state) .N fortran @*/ int MPI_File_seek(MPI_File fh, MPI_Offset offset, int whence) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_SEEK"; MPI_Offset curr_offset, eof_offset; #ifdef MPI_hpux int fl_xmpi; HPMP_IO_START(fl_xmpi, BLKMPIFILESEEK, TRDTBLOCK, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_NOT_SEQUENTIAL_MODE(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ switch (whence) { case MPI_SEEK_SET: /* --BEGIN ERROR HANDLING-- */ if (offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadoffset", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ break; case MPI_SEEK_CUR: /* find offset corr. to current location of file pointer */ ADIOI_Get_position(adio_fh, &curr_offset); offset += curr_offset; /* --BEGIN ERROR HANDLING-- */ if (offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**ionegoffset", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ break; case MPI_SEEK_END: /* we can in many cases do seeks w/o a file actually opened, but not in * the MPI_SEEK_END case */ ADIOI_TEST_DEFERRED(adio_fh, "MPI_File_seek", &error_code); /* find offset corr. to end of file */ ADIOI_Get_eof_offset(adio_fh, &eof_offset); offset += eof_offset; /* --BEGIN ERROR HANDLING-- */ if (offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**ionegoffset", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ break; default: /* --BEGIN ERROR HANDLING-- */ error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadwhence", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; /* --END ERROR HANDLING-- */ } ADIO_SeekIndividual(adio_fh, offset, ADIO_SEEK_SET, &error_code); /* TODO: what do we do with this error? */ /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ #ifdef MPI_hpux HPMP_IO_END(fl_xmpi, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ error_code = MPI_SUCCESS; fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_iread_shared - Nonblocking read using shared file pointer Input Parameters: . fh - file handle (handle) . count - number of elements in buffer (nonnegative integer) . datatype - datatype of each buffer element (handle) Output Parameters: . buf - initial address of buffer (choice) . request - request object (handle) .N fortran @*/ int MPI_File_iread_shared(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Request *request) { int error_code, buftype_is_contig, filetype_is_contig; ADIO_Offset bufsize; ADIO_File adio_fh; static char myname[] = "MPI_FILE_IREAD_SHARED"; MPI_Count datatype_size, incr; MPI_Status status; ADIO_Offset off, shared_fp; MPI_Offset nbytes=0; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_COUNT(adio_fh, count, myname, error_code); MPIO_CHECK_DATATYPE(adio_fh, datatype, myname, error_code); /* --END ERROR HANDLING-- */ MPI_Type_size_x(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(adio_fh, count, datatype_size, myname, error_code); MPIO_CHECK_FS_SUPPORTS_SHARED(adio_fh, myname, error_code); MPIO_CHECK_COUNT_SIZE(adio_fh, count, datatype_size, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_Datatype_iscontig(datatype, &buftype_is_contig); ADIOI_Datatype_iscontig(adio_fh->filetype, &filetype_is_contig); ADIOI_TEST_DEFERRED(adio_fh, myname, &error_code); incr = (count*datatype_size)/adio_fh->etype_size; ADIO_Get_shared_fp(adio_fh, incr, &shared_fp, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { /* note: ADIO_Get_shared_fp should have set up error code already? */ MPIO_Err_return_file(adio_fh, error_code); } /* --END ERROR HANDLING-- */ if (buftype_is_contig && filetype_is_contig) { /* convert count and shared_fp to bytes */ bufsize = datatype_size * count; off = adio_fh->disp + adio_fh->etype_size * shared_fp; if (!(adio_fh->atomicity)) { ADIO_IreadContig(adio_fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, off, request, &error_code); } else { /* to maintain strict atomicity semantics with other concurrent operations, lock (exclusive) and call blocking routine */ if (adio_fh->file_system != ADIO_NFS) { ADIOI_WRITE_LOCK(adio_fh, off, SEEK_SET, bufsize); } ADIO_ReadContig(adio_fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, off, &status, &error_code); if (adio_fh->file_system != ADIO_NFS) { ADIOI_UNLOCK(adio_fh, off, SEEK_SET, bufsize); } if (error_code == MPI_SUCCESS){ nbytes = count * datatype_size; } MPIO_Completed_request_create(&adio_fh, nbytes, &error_code, request); } } else { ADIO_IreadStrided(adio_fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, request, &error_code); } /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
int MPIOI_File_read(MPI_File fh, MPI_Offset offset, int file_ptr_type, void *buf, int count, MPI_Datatype datatype, char *myname, MPI_Status *status) { int error_code, buftype_is_contig, filetype_is_contig; MPI_Count datatype_size; ADIO_File adio_fh; ADIO_Offset off, bufsize; void *xbuf=NULL, *e32_buf=NULL; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_COUNT(adio_fh, count, myname, error_code); MPIO_CHECK_DATATYPE(adio_fh, datatype, myname, error_code); if (file_ptr_type == ADIO_EXPLICIT_OFFSET && offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadoffset", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPI_Type_size_x(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_COUNT_SIZE(adio_fh, count, datatype_size, myname, error_code); /* --END ERROR HANDLING-- */ if (count*datatype_size == 0) { #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, 0); #endif error_code = MPI_SUCCESS; goto fn_exit; } /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(adio_fh, count, datatype_size, myname, error_code); MPIO_CHECK_READABLE(adio_fh, myname, error_code); MPIO_CHECK_NOT_SEQUENTIAL_MODE(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_Datatype_iscontig(datatype, &buftype_is_contig); ADIOI_Datatype_iscontig(adio_fh->filetype, &filetype_is_contig); ADIOI_TEST_DEFERRED(adio_fh, myname, &error_code); xbuf = buf; if (adio_fh->is_external32) { MPI_Aint e32_size = 0; error_code = MPIU_datatype_full_size(datatype, &e32_size); if (error_code != MPI_SUCCESS) goto fn_exit; e32_buf = ADIOI_Malloc(e32_size*count); xbuf = e32_buf; } if (buftype_is_contig && filetype_is_contig) { /* convert count and offset to bytes */ bufsize = datatype_size * count; if (file_ptr_type == ADIO_EXPLICIT_OFFSET) { off = adio_fh->disp + adio_fh->etype_size * offset; } else /* ADIO_INDIVIDUAL */ { off = adio_fh->fp_ind; } /* if atomic mode requested, lock (exclusive) the region, because there could be a concurrent noncontiguous request. */ if ((adio_fh->atomicity) && ADIO_Feature(adio_fh, ADIO_LOCKS)) { ADIOI_WRITE_LOCK(adio_fh, off, SEEK_SET, bufsize); } ADIO_ReadContig(adio_fh, xbuf, count, datatype, file_ptr_type, off, status, &error_code); if ((adio_fh->atomicity) && ADIO_Feature(adio_fh, ADIO_LOCKS)) { ADIOI_UNLOCK(adio_fh, off, SEEK_SET, bufsize); } } else { ADIO_ReadStrided(adio_fh, xbuf, count, datatype, file_ptr_type, offset, status, &error_code); /* For strided and atomic mode, locking is done in ADIO_ReadStrided */ } /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ if (e32_buf != NULL) { error_code = MPIU_read_external32_conversion_fn(buf, datatype, count, e32_buf); ADIOI_Free(e32_buf); } fn_exit: ROMIO_THREAD_CS_EXIT(); return error_code; }
int MPIOI_File_write_all(MPI_File fh, MPI_Offset offset, int file_ptr_type, const void *buf, int count, MPI_Datatype datatype, char *myname, MPI_Status *status) { int error_code; MPI_Count datatype_size; ADIO_File adio_fh; void *e32buf=NULL; const void *xbuf=NULL; ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); MPIO_CHECK_COUNT(adio_fh, count, myname, error_code); MPIO_CHECK_DATATYPE(adio_fh, datatype, myname, error_code); if (file_ptr_type == ADIO_EXPLICIT_OFFSET && offset < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadoffset", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPI_Type_size_x(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(adio_fh, count, datatype_size, myname, error_code); MPIO_CHECK_WRITABLE(adio_fh, myname, error_code); MPIO_CHECK_NOT_SEQUENTIAL_MODE(adio_fh, myname, error_code); MPIO_CHECK_COUNT_SIZE(adio_fh, count, datatype_size, myname, error_code); /* --END ERROR HANDLING-- */ xbuf = buf; if (adio_fh->is_external32) { error_code = MPIU_external32_buffer_setup(buf, count, datatype, &e32buf); if (error_code != MPI_SUCCESS) goto fn_exit; xbuf = e32buf; } ADIO_WriteStridedColl(adio_fh, xbuf, count, datatype, file_ptr_type, offset, status, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ fn_exit: if (e32buf != NULL) ADIOI_Free(e32buf); ROMIO_THREAD_CS_EXIT(); return error_code; }
/*@ MPI_File_preallocate - Preallocates storage space for a file Input Parameters: . fh - file handle (handle) . size - size to preallocate (nonnegative integer) .N fortran @*/ int MPI_File_preallocate(MPI_File fh, MPI_Offset size) { ADIO_Fcntl_t *fcntl_struct; int error_code=0, mynod=0; ADIO_File adio_fh; static char myname[] = "MPI_FILE_PREALLOCATE"; MPI_Offset tmp_sz, max_sz, min_sz; #ifdef MPI_hpux int fl_xmpi; HPMP_IO_START(fl_xmpi, BLKMPIFILEPREALLOCATE, TRDTBLOCK, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ ROMIO_THREAD_CS_ENTER(); adio_fh = MPIO_File_resolve(fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(adio_fh, myname, error_code); if (size < 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobadsize", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } tmp_sz = size; MPI_Allreduce(&tmp_sz, &max_sz, 1, ADIO_OFFSET, MPI_MAX, adio_fh->comm); MPI_Allreduce(&tmp_sz, &min_sz, 1, ADIO_OFFSET, MPI_MIN, adio_fh->comm); if (max_sz != min_sz) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**notsame", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ if (size == 0) goto fn_exit; ADIOI_TEST_DEFERRED(adio_fh, myname, &error_code); MPI_Comm_rank(adio_fh->comm, &mynod); if (!mynod) { fcntl_struct = (ADIO_Fcntl_t *) ADIOI_Malloc(sizeof(ADIO_Fcntl_t)); fcntl_struct->diskspace = size; ADIO_Fcntl(adio_fh, ADIO_FCNTL_SET_DISKSPACE, fcntl_struct, &error_code); ADIOI_Free(fcntl_struct); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(adio_fh, error_code); /* --END ERROR HANDLING-- */ } MPI_Barrier(adio_fh->comm); #ifdef MPI_hpux HPMP_IO_END(fl_xmpi, adio_fh, MPI_DATATYPE_NULL, -1); #endif /* MPI_hpux */ fn_exit: ROMIO_THREAD_CS_EXIT(); /* TODO: bcast result? */ if (!mynod) return error_code; else return MPI_SUCCESS; }