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