/*@ MPI_File_get_position_shared - Returns the current position of the shared file pointer in etype units relative to the current view Input Parameters: . fh - file handle (handle) Output Parameters: . offset - offset of shared file pointer (nonnegative integer) .N fortran @*/ int MPI_File_get_position_shared(MPI_File fh, MPI_Offset *offset) { int error_code; ADIO_File adio_fh; static char myname[] = "MPI_FILE_GET_POSITION_SHARED"; 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); MPIO_CHECK_FS_SUPPORTS_SHARED(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_TEST_DEFERRED(adio_fh, myname, &error_code); ADIO_Get_shared_fp(adio_fh, 0, offset, &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: return error_code; }
/*@ MPI_File_set_view - Sets the file view Input Parameters: . fh - file handle (handle) . disp - displacement (nonnegative integer) . etype - elementary datatype (handle) . filetype - filetype (handle) . datarep - data representation (string) . info - info object (handle) .N fortran @*/ int MPI_File_set_view(MPI_File mpi_fh, MPI_Offset disp, MPI_Datatype etype, MPI_Datatype filetype, char *datarep, MPI_Info info) { int filetype_size, etype_size, error_code; static char myname[] = "MPI_FILE_SET_VIEW"; ADIO_Offset shared_fp, byte_off; ADIO_File fh; MPIU_THREAD_SINGLE_CS_ENTER("io"); MPIR_Nest_incr(); fh = MPIO_File_resolve(mpi_fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(fh, myname, error_code); if ((disp < 0) && (disp != MPI_DISPLACEMENT_CURRENT)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iobaddisp", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* rudimentary checks for incorrect etype/filetype.*/ if (etype == MPI_DATATYPE_NULL) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**ioetype", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } if (filetype == MPI_DATATYPE_NULL) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iofiletype", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } if ((fh->access_mode & MPI_MODE_SEQUENTIAL) && (disp != MPI_DISPLACEMENT_CURRENT)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iodispifseq", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } if ((disp == MPI_DISPLACEMENT_CURRENT) && !(fh->access_mode & MPI_MODE_SEQUENTIAL)) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iodispifseq", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPI_Type_size(filetype, &filetype_size); MPI_Type_size(etype, &etype_size); /* --BEGIN ERROR HANDLING-- */ if (filetype_size % etype_size != 0) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_ARG, "**iofiletype", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } if (strcmp(datarep, "native") && strcmp(datarep, "NATIVE")) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_UNSUPPORTED_DATAREP, "**unsupporteddatarep",0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ if (disp == MPI_DISPLACEMENT_CURRENT) { MPI_Barrier(fh->comm); ADIO_Get_shared_fp(fh, 0, &shared_fp, &error_code); /* TODO: check error code */ MPI_Barrier(fh->comm); ADIOI_Get_byte_offset(fh, shared_fp, &byte_off); /* TODO: check error code */ disp = byte_off; } ADIO_Set_view(fh, disp, etype, filetype, info, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ /* reset shared file pointer to zero */ if ((fh->file_system != ADIO_PIOFS) && (fh->file_system != ADIO_PVFS) && (fh->file_system != ADIO_PVFS2) && (fh->shared_fp_fd != ADIO_FILE_NULL)) { /* only one process needs to set it to zero, but I don't want to create the shared-file-pointer file if shared file pointers have not been used so far. Therefore, every process that has already opened the shared-file-pointer file sets the shared file pointer to zero. If the file was not opened, the value is automatically zero. Note that shared file pointer is stored as no. of etypes relative to the current view, whereas indiv. file pointer is stored in bytes. */ ADIO_Set_shared_fp(fh, 0, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(fh, error_code); /* --END ERROR HANDLING-- */ } if ((fh->file_system != ADIO_PIOFS) && (fh->file_system != ADIO_PVFS) && (fh->file_system != ADIO_PVFS2 )) { MPI_Barrier(fh->comm); /* for above to work correctly */ } fn_exit: MPIR_Nest_decr(); MPIU_THREAD_SINGLE_CS_EXIT("io"); 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, bufsize, buftype_is_contig, filetype_is_contig; #ifndef PRINT_ERR_MSG static char myname[] = "MPI_FILE_READ_SHARED"; #endif int datatype_size, incr; ADIO_Offset off, shared_fp; #ifdef PRINT_ERR_MSG if ((fh <= (MPI_File) 0) || (fh->cookie != ADIOI_FILE_COOKIE)) { FPRINTF(stderr, "MPI_File_read_shared: Invalid file handle\n"); MPI_Abort(MPI_COMM_WORLD, 1); } #else ADIOI_TEST_FILE_HANDLE(fh, myname); #endif if (count < 0) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_shared: Invalid count argument\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_ARG, MPIR_ERR_COUNT_ARG, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } if (datatype == MPI_DATATYPE_NULL) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_shared: Invalid datatype\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_TYPE, MPIR_ERR_TYPE_NULL, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } MPI_Type_size(datatype, &datatype_size); if (count*datatype_size == 0) return MPI_SUCCESS; if ((count*datatype_size) % fh->etype_size != 0) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_shared: Only an integral number of etypes can be accessed\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ERR_ETYPE_FRACTIONAL, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } if ((fh->file_system == ADIO_PIOFS) || (fh->file_system == ADIO_PVFS)) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_shared: Shared file pointer not supported on PIOFS and PVFS\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_UNSUPPORTED_OPERATION, MPIR_ERR_NO_SHARED_FP, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } ADIOI_Datatype_iscontig(datatype, &buftype_is_contig); ADIOI_Datatype_iscontig(fh->filetype, &filetype_is_contig); incr = (count*datatype_size)/fh->etype_size; ADIO_Get_shared_fp(fh, incr, &shared_fp, &error_code); if (error_code != MPI_SUCCESS) { FPRINTF(stderr, "MPI_File_read_shared: Error! Could not access shared file pointer.\n"); MPI_Abort(MPI_COMM_WORLD, 1); } /* contiguous or strided? */ if (buftype_is_contig && filetype_is_contig) { /* convert count and shared_fp to bytes */ bufsize = datatype_size * count; off = fh->disp + 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 ((fh->atomicity) && (fh->file_system != ADIO_NFS)) ADIOI_WRITE_LOCK(fh, off, SEEK_SET, bufsize); ADIO_ReadContig(fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, off, status, &error_code); if ((fh->atomicity) && (fh->file_system != ADIO_NFS)) ADIOI_UNLOCK(fh, off, SEEK_SET, bufsize); } else ADIO_ReadStrided(fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, status, &error_code); /* For strided and atomic mode, locking is done in ADIO_ReadStrided */ 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, datatype_size, nprocs, myrank, incr; int source, dest; ADIO_Offset shared_fp; ADIO_File adio_fh; static char myname[] = "MPI_FILE_READ_ORDERED_BEGIN"; void *xbuf=NULL, *e32_buf=NULL; MPIU_THREAD_CS_ENTER(ALLFUNC,); 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(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) { error_code = MPIU_datatype_full_size(datatype, &datatype_size); if (error_code != MPI_SUCCESS) goto fn_exit; e32_buf = ADIOI_Malloc(datatype_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: MPIU_THREAD_CS_EXIT(ALLFUNC,); return error_code; }
/*@ MPI_File_write_ordered - Collective write using shared file pointer Input Parameters: . fh - file handle (handle) . buf - initial address of buffer (choice) . count - number of elements in buffer (nonnegative integer) . datatype - datatype of each buffer element (handle) Output Parameters: . status - status object (Status) .N fortran @*/ int MPI_File_write_ordered(MPI_File fh, ROMIO_CONST void *buf, int count, MPI_Datatype datatype, MPI_Status *status) { int error_code, nprocs, myrank; ADIO_Offset incr; MPI_Count datatype_size; int source, dest; static char myname[] = "MPI_FILE_WRITE_ORDERED"; ADIO_Offset shared_fp; ADIO_File adio_fh; void *e32buf=NULL; const void *xbuf; 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_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_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, myname, __LINE__, MPI_ERR_INTERN, "**iosharedfailed", 0); 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) { 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, ADIO_EXPLICIT_OFFSET, shared_fp, 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); /* FIXME: Check for error code from WriteStridedColl? */ return error_code; }
/*@ MPI_File_read_ordered - 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) . status - status object (Status) .N fortran @*/ int MPI_File_read_ordered(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) { int error_code, datatype_size, nprocs, myrank, i, incr; #ifndef PRINT_ERR_MSG static char myname[] = "MPI_FILE_READ_ORDERED"; #endif ADIO_Offset shared_fp; #ifdef PRINT_ERR_MSG if ((fh <= (MPI_File) 0) || (fh->cookie != ADIOI_FILE_COOKIE)) { FPRINTF(stderr, "MPI_File_read_ordered: Invalid file handle\n"); MPI_Abort(MPI_COMM_WORLD, 1); } #else ADIOI_TEST_FILE_HANDLE(fh, myname); #endif if (count < 0) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_ordered: Invalid count argument\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_ARG, MPIR_ERR_COUNT_ARG, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } if (datatype == MPI_DATATYPE_NULL) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_ordered: Invalid datatype\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_TYPE, MPIR_ERR_TYPE_NULL, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } MPI_Type_size(datatype, &datatype_size); if ((count*datatype_size) % fh->etype_size != 0) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_ordered: Only an integral number of etypes can be accessed\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_IO, MPIR_ERR_ETYPE_FRACTIONAL, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } if ((fh->file_system == ADIO_PIOFS) || (fh->file_system == ADIO_PVFS)) { #ifdef PRINT_ERR_MSG FPRINTF(stderr, "MPI_File_read_ordered: Shared file pointer not supported on PIOFS and PVFS\n"); MPI_Abort(MPI_COMM_WORLD, 1); #else error_code = MPIR_Err_setmsg(MPI_ERR_UNSUPPORTED_OPERATION, MPIR_ERR_NO_SHARED_FP, myname, (char *) 0, (char *) 0); return ADIOI_Error(fh, error_code, myname); #endif } MPI_Comm_size(fh->comm, &nprocs); MPI_Comm_rank(fh->comm, &myrank); incr = (count*datatype_size)/fh->etype_size; for (i=0; i<nprocs; i++) { if (i == myrank) { ADIO_Get_shared_fp(fh, incr, &shared_fp, &error_code); if (error_code != MPI_SUCCESS) { FPRINTF(stderr, "MPI_File_read_ordered: Error! Could not access shared file pointer.\n"); MPI_Abort(MPI_COMM_WORLD, 1); } } MPI_Barrier(fh->comm); } ADIO_ReadStridedColl(fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, status, &error_code); 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; MPIU_THREAD_CS_ENTER(ALLFUNC,); 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: MPIU_THREAD_CS_EXIT(ALLFUNC,); return error_code; }
/*@ MPI_File_read_ordered - 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) . status - status object (Status) .N fortran @*/ int MPI_File_read_ordered(MPI_File fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) { int error_code, nprocs, myrank; ADIO_Offset incr; MPI_Count datatype_size; int source, dest; static char myname[] = "MPI_FILE_READ_ORDERED"; ADIO_Offset shared_fp=0; ADIO_File adio_fh; 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_TEST_DEFERRED(adio_fh, "MPI_File_read_ordered", &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); ADIO_ReadStridedColl(adio_fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, 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: /* FIXME: Check for error code from ReadStridedColl? */ return error_code; }
/*@ MPI_File_write_ordered_begin - Begin a split collective write 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_write_ordered_begin(MPI_File mpi_fh, void *buf, int count, MPI_Datatype datatype) { int error_code, datatype_size, nprocs, myrank, incr; int source, dest; static char myname[] = "MPI_FILE_WRITE_ORDERED_BEGIN"; ADIO_Offset shared_fp; ADIO_File fh; MPID_CS_ENTER(); MPIR_Nest_incr(); fh = MPIO_File_resolve(mpi_fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(fh, myname, error_code); MPIO_CHECK_COUNT(fh, count, myname, error_code); MPIO_CHECK_DATATYPE(fh, datatype, myname, error_code); if (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(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ fh->split_coll_count = 1; MPI_Type_size(datatype, &datatype_size); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_INTEGRAL_ETYPE(fh, count, datatype_size, myname, error_code); MPIO_CHECK_FS_SUPPORTS_SHARED(fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_TEST_DEFERRED(fh, myname, &error_code); MPI_Comm_size(fh->comm, &nprocs); MPI_Comm_rank(fh->comm, &myrank); incr = (count*datatype_size)/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, fh->comm, MPI_STATUS_IGNORE); ADIO_Get_shared_fp(fh, incr, &shared_fp, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, myname, __LINE__, MPI_ERR_INTERN, "**iosharedfailed", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ MPI_Send(NULL, 0, MPI_BYTE, dest, 0, fh->comm); ADIO_WriteStridedColl(fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, &fh->split_status, &error_code); fn_exit: MPIR_Nest_decr(); MPID_CS_EXIT(); /* FIXME: Check for error code from WriteStridedColl? */ return error_code; }
/*@ MPI_File_seek_shared - Updates the shared file pointer Input Parameters: . fh - file handle (handle) . offset - file offset (integer) . whence - update mode (state) .N fortran @*/ int MPI_File_seek_shared(MPI_File fh, MPI_Offset offset, int whence) { int error_code=MPI_SUCCESS, tmp_whence, myrank; static char myname[] = "MPI_FILE_SEEK_SHARED"; MPI_Offset curr_offset, eof_offset, tmp_offset; ADIO_File adio_fh; MPIU_THREAD_CS_ENTER(ALLFUNC,); 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); MPIO_CHECK_FS_SUPPORTS_SHARED(adio_fh, myname, error_code); /* --END ERROR HANDLING-- */ tmp_offset = offset; MPI_Bcast(&tmp_offset, 1, ADIO_OFFSET, 0, adio_fh->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_offset != offset) { 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-- */ tmp_whence = whence; MPI_Bcast(&tmp_whence, 1, MPI_INT, 0, adio_fh->comm); /* --BEGIN ERROR HANDLING-- */ if (tmp_whence != whence) { 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-- */ ADIOI_TEST_DEFERRED(adio_fh, "MPI_File_seek_shared", &error_code); MPI_Comm_rank(adio_fh->comm, &myrank); if (!myrank) { 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: /* get current location of shared file pointer */ ADIO_Get_shared_fp(adio_fh, 0, &curr_offset, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, myname, __LINE__, MPI_ERR_INTERN, "**iosharedfailed", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ 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: /* 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_Set_shared_fp(adio_fh, offset, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, myname, __LINE__, MPI_ERR_INTERN, "**iosharedfailed", 0); error_code = MPIO_Err_return_file(adio_fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ } /* FIXME: explain why the barrier is necessary */ MPI_Barrier(adio_fh->comm); error_code = MPI_SUCCESS; fn_exit: MPIU_THREAD_CS_EXIT(ALLFUNC,); return error_code; }
/*@ MPI_File_write_shared - Write using shared file pointer Input Parameters: . fh - file handle (handle) . buf - initial address of buffer (choice) . count - number of elements in buffer (nonnegative integer) . datatype - datatype of each buffer element (handle) Output Parameters: . status - status object (Status) .N fortran @*/ int MPI_File_write_shared(MPI_File mpi_fh, void *buf, int count, MPI_Datatype datatype, MPI_Status *status) { int error_code, bufsize, buftype_is_contig, filetype_is_contig; static char myname[] = "MPI_FILE_READ_SHARED"; int datatype_size, incr; ADIO_Offset off, shared_fp; ADIO_File fh; MPIU_THREAD_SINGLE_CS_ENTER("io"); MPIR_Nest_incr(); fh = MPIO_File_resolve(mpi_fh); /* --BEGIN ERROR HANDLING-- */ MPIO_CHECK_FILE_HANDLE(fh, myname, error_code); MPIO_CHECK_COUNT(fh, count, myname, error_code); MPIO_CHECK_DATATYPE(fh, datatype, myname, error_code); /* --END ERROR HANDLING-- */ MPI_Type_size(datatype, &datatype_size); 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(fh, count, datatype_size, myname, error_code); MPIO_CHECK_FS_SUPPORTS_SHARED(fh, myname, error_code); /* --END ERROR HANDLING-- */ ADIOI_Datatype_iscontig(datatype, &buftype_is_contig); ADIOI_Datatype_iscontig(fh->filetype, &filetype_is_contig); ADIOI_TEST_DEFERRED(fh, myname, &error_code); incr = (count*datatype_size)/fh->etype_size; ADIO_Get_shared_fp(fh, incr, &shared_fp, &error_code); /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) { error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_FATAL, myname, __LINE__, MPI_ERR_INTERN, "**iosharedfailed", 0); error_code = MPIO_Err_return_file(fh, error_code); goto fn_exit; } /* --END ERROR HANDLING-- */ if (buftype_is_contig && filetype_is_contig) { /* convert bufocunt and shared_fp to bytes */ bufsize = datatype_size * count; off = fh->disp + 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_WriteContig.*/ if ((fh->atomicity) && (fh->file_system != ADIO_NFS)) ADIOI_WRITE_LOCK(fh, off, SEEK_SET, bufsize); ADIO_WriteContig(fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, off, status, &error_code); if ((fh->atomicity) && (fh->file_system != ADIO_NFS)) ADIOI_UNLOCK(fh, off, SEEK_SET, bufsize); } else { ADIO_WriteStrided(fh, buf, count, datatype, ADIO_EXPLICIT_OFFSET, shared_fp, status, &error_code); /* For strided and atomic mode, locking is done in ADIO_WriteStrided */ } /* --BEGIN ERROR HANDLING-- */ if (error_code != MPI_SUCCESS) error_code = MPIO_Err_return_file(fh, error_code); /* --END ERROR HANDLING-- */ fn_exit: MPIR_Nest_decr(); MPIU_THREAD_SINGLE_CS_EXIT("io"); 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; }