1 /*
2  * Copyright (C) by Argonne National Laboratory
3  *     See COPYRIGHT in top-level directory
4  */
5 
6 #include <mpiimpl.h>
7 #include <mpir_typerep.h>
8 #include <dataloop.h>
9 #include <stdlib.h>
10 
MPIR_Typerep_to_iov(const void * buf,MPI_Aint count,MPI_Datatype type,MPI_Aint byte_offset,struct iovec * iov,MPI_Aint max_iov_len,MPI_Aint max_iov_bytes,MPI_Aint * actual_iov_len,MPI_Aint * actual_iov_bytes)11 int MPIR_Typerep_to_iov(const void *buf, MPI_Aint count, MPI_Datatype type, MPI_Aint byte_offset,
12                         struct iovec *iov, MPI_Aint max_iov_len, MPI_Aint max_iov_bytes,
13                         MPI_Aint * actual_iov_len, MPI_Aint * actual_iov_bytes)
14 {
15     MPIR_Segment *seg;
16     int mpi_errno = MPI_SUCCESS;
17 
18     seg = MPIR_Segment_alloc(buf, count, type);
19 
20     MPI_Aint last = byte_offset + max_iov_bytes;
21     *actual_iov_len = max_iov_len;
22     MPIR_Segment_to_iov(seg, byte_offset, &last, iov, (int *) actual_iov_len);
23     *actual_iov_bytes = last - byte_offset;
24 
25     MPIR_Segment_free(seg);
26 
27     return mpi_errno;
28 }
29 
MPIR_Typerep_to_iov_offset(const void * buf,MPI_Aint count,MPI_Datatype type,MPI_Aint iov_offset,struct iovec * iov,MPI_Aint max_iov_len,MPI_Aint * actual_iov_len)30 int MPIR_Typerep_to_iov_offset(const void *buf, MPI_Aint count, MPI_Datatype type,
31                                MPI_Aint iov_offset, struct iovec *iov, MPI_Aint max_iov_len,
32                                MPI_Aint * actual_iov_len)
33 {
34     MPIR_Segment *seg;
35     int mpi_errno = MPI_SUCCESS;
36 
37     seg = MPIR_Segment_alloc(buf, count, type);
38 
39     MPI_Aint last;
40 
41     /* skip through IOV elements to get to the required IOV offset */
42     MPI_Aint byte_offset = 0;
43     MPI_Aint rem_iov_offset = iov_offset;
44     while (rem_iov_offset) {
45         last = MPIR_AINT_MAX;
46         int iov_len = MPL_MIN(max_iov_len, rem_iov_offset);
47         MPIR_Segment_to_iov(seg, byte_offset, &last, iov, &iov_len);
48         rem_iov_offset += iov_len;
49         for (int i = 0; i < iov_len; i++)
50             byte_offset += iov[i].iov_len;
51     }
52 
53     /* Final conversion to get the correct IOV set */
54     last = MPIR_AINT_MAX;
55     int iov_len = max_iov_len;
56     MPIR_Segment_to_iov(seg, byte_offset, &last, iov, &iov_len);
57     *actual_iov_len = (MPI_Aint) iov_len;
58 
59     MPIR_Segment_free(seg);
60 
61     return mpi_errno;
62 }
63 
MPIR_Typerep_iov_len(MPI_Aint count,MPI_Datatype type,MPI_Aint max_iov_bytes,MPI_Aint * iov_len)64 int MPIR_Typerep_iov_len(MPI_Aint count, MPI_Datatype type, MPI_Aint max_iov_bytes,
65                          MPI_Aint * iov_len)
66 {
67     MPIR_Segment *seg;
68     int mpi_errno = MPI_SUCCESS;
69 
70     seg = MPIR_Segment_alloc(NULL, count, type);
71 
72     MPI_Aint last = max_iov_bytes;
73     MPIR_Segment_count_contig_blocks(seg, 0, &last, iov_len);
74 
75     MPIR_Segment_free(seg);
76 
77     return mpi_errno;
78 }
79