1 /* -*- Mode: C; c-basic-offset:4 ; -*- */
2 /*
3 * Copyright (c) 2004-2006 The Trustees of Indiana University and Indiana
4 * University Research and Technology
5 * Corporation. All rights reserved.
6 * Copyright (c) 2004-2019 The University of Tennessee and The University
7 * of Tennessee Research Foundation. All rights
8 * reserved.
9 * Copyright (c) 2004-2006 High Performance Computing Center Stuttgart,
10 * University of Stuttgart. All rights reserved.
11 * Copyright (c) 2004-2006 The Regents of the University of California.
12 * All rights reserved.
13 * Copyright (c) 2009 Sun Microsystems, Inc. All rights reserved.
14 * Copyright (c) 2009 Oak Ridge National Labs. All rights reserved.
15 * Copyright (c) 2010 Cisco Systems, Inc. All rights reserved.
16 * Copyright (c) 2015-2017 Research Organization for Information Science
17 * and Technology (RIST). All rights reserved.
18 * Copyright (c) 2019 IBM Corporation. All rights reserved.
19 * $COPYRIGHT$
20 *
21 * Additional copyrights may follow
22 *
23 * $HEADER$
24 */
25
26 #include "ompi_config.h"
27
28 #include <stddef.h>
29
30 #include "ompi/datatype/ompi_datatype.h"
31
32
33 /* We try to merge together data that are contiguous */
ompi_datatype_create_indexed(int count,const int * pBlockLength,const int * pDisp,const ompi_datatype_t * oldType,ompi_datatype_t ** newType)34 int32_t ompi_datatype_create_indexed( int count, const int* pBlockLength, const int* pDisp,
35 const ompi_datatype_t* oldType, ompi_datatype_t** newType )
36 {
37 ptrdiff_t extent, disp, endat;
38 ompi_datatype_t* pdt;
39 size_t dLength;
40 int i;
41
42 /* ignore all cases that lead to an empty type */
43 ompi_datatype_type_size(oldType, &dLength);
44 for( i = 0; (i < count) && (0 == pBlockLength[i]); i++ ); /* find first non zero */
45 if( (i == count) || (0 == dLength) ) {
46 return ompi_datatype_duplicate( &ompi_mpi_datatype_null.dt, newType);
47 }
48
49 disp = pDisp[i];
50 dLength = pBlockLength[i];
51 endat = disp + dLength;
52 ompi_datatype_type_extent( oldType, &extent );
53
54 pdt = ompi_datatype_create( (count - i) * (2 + oldType->super.desc.used) );
55 for( i += 1; i < count; i++ ) {
56 if( 0 == pBlockLength[i] ) /* ignore empty length */
57 continue;
58 if( endat == pDisp[i] ) { /* contiguous with the previsious */
59 dLength += pBlockLength[i];
60 endat += pBlockLength[i];
61 } else {
62 ompi_datatype_add( pdt, oldType, dLength, disp * extent, extent );
63 disp = pDisp[i];
64 dLength = pBlockLength[i];
65 endat = disp + pBlockLength[i];
66 }
67 }
68 ompi_datatype_add( pdt, oldType, dLength, disp * extent, extent );
69
70 *newType = pdt;
71 return OMPI_SUCCESS;
72 }
73
74
ompi_datatype_create_hindexed(int count,const int * pBlockLength,const ptrdiff_t * pDisp,const ompi_datatype_t * oldType,ompi_datatype_t ** newType)75 int32_t ompi_datatype_create_hindexed( int count, const int* pBlockLength, const ptrdiff_t* pDisp,
76 const ompi_datatype_t* oldType, ompi_datatype_t** newType )
77 {
78 ptrdiff_t extent, disp, endat;
79 ompi_datatype_t* pdt;
80 size_t dLength;
81 int i;
82
83 /* ignore all cases that lead to an empty type */
84 ompi_datatype_type_size(oldType, &dLength);
85 for( i = 0; (i < count) && (0 == pBlockLength[i]); i++ ); /* find first non zero */
86 if( (i == count) || (0 == dLength) ) {
87 return ompi_datatype_duplicate( &ompi_mpi_datatype_null.dt, newType);
88 }
89
90 ompi_datatype_type_extent( oldType, &extent );
91 disp = pDisp[i];
92 dLength = pBlockLength[i];
93 endat = disp + dLength * extent;
94
95 pdt = ompi_datatype_create( (count - i) * (2 + oldType->super.desc.used) );
96 for( i += 1; i < count; i++ ) {
97 if( 0 == pBlockLength[i] ) /* ignore empty length */
98 continue;
99 if( endat == pDisp[i] ) { /* contiguous with the previsious */
100 dLength += pBlockLength[i];
101 endat += pBlockLength[i] * extent;
102 } else {
103 ompi_datatype_add( pdt, oldType, dLength, disp, extent );
104 disp = pDisp[i];
105 dLength = pBlockLength[i];
106 endat = disp + pBlockLength[i] * extent;
107 }
108 }
109 ompi_datatype_add( pdt, oldType, dLength, disp, extent );
110
111 *newType = pdt;
112 return OMPI_SUCCESS;
113 }
114
115
ompi_datatype_create_indexed_block(int count,int bLength,const int * pDisp,const ompi_datatype_t * oldType,ompi_datatype_t ** newType)116 int32_t ompi_datatype_create_indexed_block( int count, int bLength, const int* pDisp,
117 const ompi_datatype_t* oldType, ompi_datatype_t** newType )
118 {
119 ptrdiff_t extent, disp, endat;
120 ompi_datatype_t* pdt;
121 size_t dLength;
122 int i;
123
124 if( (count == 0) || (bLength == 0) ) {
125 return ompi_datatype_duplicate(&ompi_mpi_datatype_null.dt, newType);
126 }
127 ompi_datatype_type_extent( oldType, &extent );
128 pdt = ompi_datatype_create( count * (2 + oldType->super.desc.used) );
129 disp = pDisp[0];
130 dLength = bLength;
131 endat = disp + dLength;
132 for( i = 1; i < count; i++ ) {
133 if( endat == pDisp[i] ) {
134 /* contiguous with the previsious */
135 dLength += bLength;
136 endat += bLength;
137 } else {
138 ompi_datatype_add( pdt, oldType, dLength, disp * extent, extent );
139 disp = pDisp[i];
140 dLength = bLength;
141 endat = disp + bLength;
142 }
143 }
144 ompi_datatype_add( pdt, oldType, dLength, disp * extent, extent );
145
146 *newType = pdt;
147 return OMPI_SUCCESS;
148 }
149
ompi_datatype_create_hindexed_block(int count,int bLength,const ptrdiff_t * pDisp,const ompi_datatype_t * oldType,ompi_datatype_t ** newType)150 int32_t ompi_datatype_create_hindexed_block( int count, int bLength, const ptrdiff_t* pDisp,
151 const ompi_datatype_t* oldType, ompi_datatype_t** newType )
152 {
153 ptrdiff_t extent, disp, endat;
154 ompi_datatype_t* pdt;
155 size_t dLength;
156 int i;
157
158 if( (count == 0) || (bLength == 0) ) {
159 return ompi_datatype_duplicate(&ompi_mpi_datatype_null.dt, newType);
160 }
161 ompi_datatype_type_extent( oldType, &extent );
162 pdt = ompi_datatype_create( count * (2 + oldType->super.desc.used) );
163 disp = pDisp[0];
164 dLength = bLength;
165 endat = disp + dLength * extent;
166 for( i = 1; i < count; i++ ) {
167 if( endat == pDisp[i] ) {
168 /* contiguous with the previsious */
169 dLength += bLength;
170 endat += bLength * extent;
171 } else {
172 ompi_datatype_add( pdt, oldType, dLength, disp, extent );
173 disp = pDisp[i];
174 dLength = bLength;
175 endat = disp + bLength * extent;
176 }
177 }
178 ompi_datatype_add( pdt, oldType, dLength, disp, extent );
179
180 *newType = pdt;
181 return OMPI_SUCCESS;
182 }
183