15.4.5. Split Collective Data Access Routines
Up: Data Access
Next: File Interoperability
Previous: Seek
MPI provides a restricted form of ``nonblocking collective'' I/O
operations for all data accesses
using split collective data access routines.
These routines are referred to as ``split'' collective routines,
because a single collective operation is split in two:
a begin routine and an end routine.
The begin routine begins the operation,
much like a nonblocking data access (e.g., MPI_FILE_IREAD).
The end routine completes the operation,
much like the matching test or wait (e.g., MPI_WAIT).
As with nonblocking data access operations,
the user must not use the buffer
passed to a begin routine while the routine is outstanding;
the operation must be completed with an end routine before it
is safe to free buffers, etc.
Split collective data access operations on a file handle fh
are subject to the semantic rules given below.
- On any MPI process,
each file handle may have at most one active split collective
operation at any time.
- Begin calls are collective over the group of processes
that participated in the collective open and follow the ordering
rules for collective calls.
- End calls are collective over the group of processes that
participated in the collective open and follow the ordering
rules for collective calls.
Each end call matches
the preceding begin call for the same collective
operation. When an ``end'' call is made, exactly one unmatched ``begin''
call for the same operation must precede it.
- An implementation is free to implement any split collective
data access routine using the corresponding blocking collective
routine when either the begin call (e.g.,
MPI_FILE_READ_ALL_BEGIN) or the end call (e.g.,
MPI_FILE_READ_ALL_END) is issued. The begin and end calls are
provided to allow the user and MPI implementation to optimize the
collective operation.
According to the definitions in Section MPI Procedures,
the begin procedures are incomplete.
They are also nonlocal procedures because they may or may not return
before they are called in all MPI processes of the process group.
Advice to users.
This is one of the exceptions in which incomplete procedures are nonlocal and therefore blocking.
( End of advice to users.)
- Split collective operations do not match the corresponding
regular collective operation.
For example, in a single collective read operation,
an MPI_FILE_READ_ALL on one process does not match
an MPI_FILE_READ_ALL_BEGIN/ MPI_FILE_READ_ALL_END pair
on another process.
- Split collective routines must specify a buffer
in both the begin and end routines. By specifying the buffer
that receives data in the end routine, we can avoid
the problems described
in Problems with Code Movement and Register Optimization,
Section Problems with Code Movement and Register Optimization,
but not all of the problems, such as those described in
Sections Problems Due to Data Copying and Sequence Association with Subscript Triplets,
Problems Due to Data Copying and Sequence Association with Vector Subscripts,
and Optimization Problems, an Overview.
- No collective I/O operations are permitted on a file handle
concurrently with a split collective access on that file handle
(i.e., between the begin and end of the access). That is, the following example is erroneous.
Example
Erroneous example fragment of concurrent split collective access on a
file handle:
- In a multithreaded implementation, any split collective
begin and end operation called by a process must be
called from the same thread. This restriction is made
to simplify the implementation in the multithreaded
case.
(Note that we have already disallowed having two
threads begin a split collective operation on the same
file handle since only one split collective operation can be
active on a file handle at any time.)
The arguments for these routines have the same meaning as for
the equivalent collective versions
(e.g., the argument definitions for MPI_FILE_READ_ALL_BEGIN
and MPI_FILE_READ_ALL_END are equivalent to the
arguments for MPI_FILE_READ_ALL).
The begin routine (e.g., MPI_FILE_READ_ALL_BEGIN)
begins a split collective operation that,
when completed with the matching end routine
(i.e., MPI_FILE_READ_ALL_END)
produces the result as defined for the equivalent collective
routine (i.e., MPI_FILE_READ_ALL).
For the purpose of consistency semantics
(Section File Consistency),
a matched pair of split collective data access operations
(e.g., MPI_FILE_READ_ALL_BEGIN and MPI_FILE_READ_ALL_END)
compose a single data access.
MPI_FILE_READ_AT_ALL_BEGIN(fh, offset, buf, count, datatype) |
IN fh | file handle (handle) |
IN offset | file offset (integer) |
OUT buf | initial address of buffer (choice) |
IN count | number of elements in buffer (integer) |
IN datatype | datatype of each buffer element (handle) |
C binding
int MPI_File_read_at_all_begin(MPI_File fh, MPI_Offset offset, void *buf, int count, MPI_Datatype datatype)
int MPI_File_read_at_all_begin_c(MPI_File fh, MPI_Offset offset, void *buf, MPI_Count count, MPI_Datatype datatype)
Fortran 2008 binding
MPI_File_read_at_all_begin(fh, offset, buf, count, datatype, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: offset
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
INTEGER, INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_File_read_at_all_begin(fh, offset, buf, count, datatype, ierror) !(_c)
TYPE(MPI_File), INTENT(IN) :: fh
INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: offset
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_READ_AT_ALL_BEGIN(FH, OFFSET, BUF, COUNT, DATATYPE, IERROR)
INTEGER FH, COUNT, DATATYPE, IERROR
INTEGER(KIND=MPI_OFFSET_KIND) OFFSET
<type> BUF(*)
MPI_FILE_READ_AT_ALL_END(fh, buf, status) |
IN fh | file handle (handle) |
OUT buf | initial address of buffer (choice) |
OUT status | status object (status) |
C binding
int MPI_File_read_at_all_end(MPI_File fh, void *buf, MPI_Status *status)
Fortran 2008 binding
MPI_File_read_at_all_end(fh, buf, status, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
TYPE(MPI_Status) :: status
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_READ_AT_ALL_END(FH, BUF, STATUS, IERROR)
INTEGER FH, STATUS(MPI_STATUS_SIZE), IERROR
<type> BUF(*)
MPI_FILE_WRITE_AT_ALL_BEGIN(fh, offset, buf, count, datatype) |
INOUT fh | file handle (handle) |
IN offset | file offset (integer) |
IN buf | initial address of buffer (choice) |
IN count | number of elements in buffer (integer) |
IN datatype | datatype of each buffer element (handle) |
C binding
int MPI_File_write_at_all_begin(MPI_File fh, MPI_Offset offset, const void *buf, int count, MPI_Datatype datatype)
int MPI_File_write_at_all_begin_c(MPI_File fh, MPI_Offset offset, const void *buf, MPI_Count count, MPI_Datatype datatype)
Fortran 2008 binding
MPI_File_write_at_all_begin(fh, offset, buf, count, datatype, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: offset
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
INTEGER, INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_File_write_at_all_begin(fh, offset, buf, count, datatype, ierror) !(_c)
TYPE(MPI_File), INTENT(IN) :: fh
INTEGER(KIND=MPI_OFFSET_KIND), INTENT(IN) :: offset
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_WRITE_AT_ALL_BEGIN(FH, OFFSET, BUF, COUNT, DATATYPE, IERROR)
INTEGER FH, COUNT, DATATYPE, IERROR
INTEGER(KIND=MPI_OFFSET_KIND) OFFSET
<type> BUF(*)
MPI_FILE_WRITE_AT_ALL_END(fh, buf, status) |
INOUT fh | file handle (handle) |
IN buf | initial address of buffer (choice) |
OUT status | status object (status) |
C binding
int MPI_File_write_at_all_end(MPI_File fh, const void *buf, MPI_Status *status)
Fortran 2008 binding
MPI_File_write_at_all_end(fh, buf, status, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
TYPE(MPI_Status) :: status
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_WRITE_AT_ALL_END(FH, BUF, STATUS, IERROR)
INTEGER FH, STATUS(MPI_STATUS_SIZE), IERROR
<type> BUF(*)
MPI_FILE_READ_ALL_BEGIN(fh, buf, count, datatype) |
INOUT fh | file handle (handle) |
OUT buf | initial address of buffer (choice) |
IN count | number of elements in buffer (integer) |
IN datatype | datatype of each buffer element (handle) |
C binding
int MPI_File_read_all_begin(MPI_File fh, void *buf, int count, MPI_Datatype datatype)
int MPI_File_read_all_begin_c(MPI_File fh, void *buf, MPI_Count count, MPI_Datatype datatype)
Fortran 2008 binding
MPI_File_read_all_begin(fh, buf, count, datatype, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
INTEGER, INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_File_read_all_begin(fh, buf, count, datatype, ierror) !(_c)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_READ_ALL_BEGIN(FH, BUF, COUNT, DATATYPE, IERROR)
INTEGER FH, COUNT, DATATYPE, IERROR
<type> BUF(*)
MPI_FILE_READ_ALL_END(fh, buf, status) |
INOUT fh | file handle (handle) |
OUT buf | initial address of buffer (choice) |
OUT status | status object (status) |
C binding
int MPI_File_read_all_end(MPI_File fh, void *buf, MPI_Status *status)
Fortran 2008 binding
MPI_File_read_all_end(fh, buf, status, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
TYPE(MPI_Status) :: status
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_READ_ALL_END(FH, BUF, STATUS, IERROR)
INTEGER FH, STATUS(MPI_STATUS_SIZE), IERROR
<type> BUF(*)
MPI_FILE_WRITE_ALL_BEGIN(fh, buf, count, datatype) |
INOUT fh | file handle (handle) |
IN buf | initial address of buffer (choice) |
IN count | number of elements in buffer (integer) |
IN datatype | datatype of each buffer element (handle) |
C binding
int MPI_File_write_all_begin(MPI_File fh, const void *buf, int count, MPI_Datatype datatype)
int MPI_File_write_all_begin_c(MPI_File fh, const void *buf, MPI_Count count, MPI_Datatype datatype)
Fortran 2008 binding
MPI_File_write_all_begin(fh, buf, count, datatype, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
INTEGER, INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_File_write_all_begin(fh, buf, count, datatype, ierror) !(_c)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_WRITE_ALL_BEGIN(FH, BUF, COUNT, DATATYPE, IERROR)
INTEGER FH, COUNT, DATATYPE, IERROR
<type> BUF(*)
MPI_FILE_WRITE_ALL_END(fh, buf, status) |
INOUT fh | file handle (handle) |
IN buf | initial address of buffer (choice) |
OUT status | status object (status) |
C binding
int MPI_File_write_all_end(MPI_File fh, const void *buf, MPI_Status *status)
Fortran 2008 binding
MPI_File_write_all_end(fh, buf, status, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
TYPE(MPI_Status) :: status
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_WRITE_ALL_END(FH, BUF, STATUS, IERROR)
INTEGER FH, STATUS(MPI_STATUS_SIZE), IERROR
<type> BUF(*)
MPI_FILE_READ_ORDERED_BEGIN(fh, buf, count, datatype) |
INOUT fh | file handle (handle) |
OUT buf | initial address of buffer (choice) |
IN count | number of elements in buffer (integer) |
IN datatype | datatype of each buffer element (handle) |
C binding
int MPI_File_read_ordered_begin(MPI_File fh, void *buf, int count, MPI_Datatype datatype)
int MPI_File_read_ordered_begin_c(MPI_File fh, void *buf, MPI_Count count, MPI_Datatype datatype)
Fortran 2008 binding
MPI_File_read_ordered_begin(fh, buf, count, datatype, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
INTEGER, INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_File_read_ordered_begin(fh, buf, count, datatype, ierror) !(_c)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_READ_ORDERED_BEGIN(FH, BUF, COUNT, DATATYPE, IERROR)
INTEGER FH, COUNT, DATATYPE, IERROR
<type> BUF(*)
MPI_FILE_READ_ORDERED_END(fh, buf, status) |
INOUT fh | file handle (handle) |
OUT buf | initial address of buffer (choice) |
OUT status | status object (status) |
C binding
int MPI_File_read_ordered_end(MPI_File fh, void *buf, MPI_Status *status)
Fortran 2008 binding
MPI_File_read_ordered_end(fh, buf, status, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), ASYNCHRONOUS :: buf
TYPE(MPI_Status) :: status
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_READ_ORDERED_END(FH, BUF, STATUS, IERROR)
INTEGER FH, STATUS(MPI_STATUS_SIZE), IERROR
<type> BUF(*)
MPI_FILE_WRITE_ORDERED_BEGIN(fh, buf, count, datatype) |
INOUT fh | file handle (handle) |
IN buf | initial address of buffer (choice) |
IN count | number of elements in buffer (integer) |
IN datatype | datatype of each buffer element (handle) |
C binding
int MPI_File_write_ordered_begin(MPI_File fh, const void *buf, int count, MPI_Datatype datatype)
int MPI_File_write_ordered_begin_c(MPI_File fh, const void *buf, MPI_Count count, MPI_Datatype datatype)
Fortran 2008 binding
MPI_File_write_ordered_begin(fh, buf, count, datatype, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
INTEGER, INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
MPI_File_write_ordered_begin(fh, buf, count, datatype, ierror) !(_c)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
INTEGER(KIND=MPI_COUNT_KIND), INTENT(IN) :: count
TYPE(MPI_Datatype), INTENT(IN) :: datatype
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_WRITE_ORDERED_BEGIN(FH, BUF, COUNT, DATATYPE, IERROR)
INTEGER FH, COUNT, DATATYPE, IERROR
<type> BUF(*)
MPI_FILE_WRITE_ORDERED_END(fh, buf, status) |
INOUT fh | file handle (handle) |
IN buf | initial address of buffer (choice) |
OUT status | status object (status) |
C binding
int MPI_File_write_ordered_end(MPI_File fh, const void *buf, MPI_Status *status)
Fortran 2008 binding
MPI_File_write_ordered_end(fh, buf, status, ierror)
TYPE(MPI_File), INTENT(IN) :: fh
TYPE(*), DIMENSION(..), INTENT(IN), ASYNCHRONOUS :: buf
TYPE(MPI_Status) :: status
INTEGER, OPTIONAL, INTENT(OUT) :: ierror
Fortran binding
MPI_FILE_WRITE_ORDERED_END(FH, BUF, STATUS, IERROR)
INTEGER FH, STATUS(MPI_STATUS_SIZE), IERROR
<type> BUF(*)
Up: Data Access
Next: File Interoperability
Previous: Seek
Return to MPI-4.1 Standard Index
Return to MPI Forum Home Page
(Unofficial) MPI-4.1 of November 2, 2023
HTML Generated on November 19, 2023