Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Add support for huge pages in shared malloc.
[simgrid.git] / src / smpi / smpi_datatype_derived.cpp
1 /* smpi_datatype.cpp -- MPI primitives to handle datatypes                  */
2 /* Copyright (c) 2009-2017. The SimGrid Team. All rights reserved.          */
3
4 /* This program is free software; you can redistribute it and/or modify it
5  * under the terms of the license (GNU LGPL) which comes with this package. */
6
7 #include "src/smpi/smpi_datatype_derived.hpp"
8 #include "src/smpi/smpi_op.hpp"
9
10 XBT_LOG_EXTERNAL_CATEGORY(smpi_datatype);
11
12 namespace simgrid{
13 namespace smpi{
14
15
16 Type_Contiguous::Type_Contiguous(int size, MPI_Aint lb, MPI_Aint ub, int flags, int block_count, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(block_count), old_type_(old_type){
17   old_type_->ref();
18 }
19
20 Type_Contiguous::~Type_Contiguous(){
21   Datatype::unref(old_type_);
22 }
23
24
25 void Type_Contiguous::serialize( void* noncontiguous_buf, void *contiguous_buf, 
26                             int count){
27   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
28   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+lb();
29   memcpy(contiguous_buf_char, noncontiguous_buf_char, count * block_count_ * old_type_->size());
30 }
31 void Type_Contiguous::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
32                               int count, MPI_Op op){
33   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
34   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+lb();
35   int n= count*block_count_;
36   if(op!=MPI_OP_NULL)
37     op->apply( contiguous_buf_char, noncontiguous_buf_char, &n, old_type_);
38 }
39
40
41 Type_Vector::Type_Vector(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int block_length, int stride, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(count), block_length_(block_length),block_stride_(stride),  old_type_(old_type){
42   old_type_->ref();
43 }
44
45 Type_Vector::~Type_Vector(){
46   Datatype::unref(old_type_);
47 }
48
49
50 void Type_Vector::serialize( void* noncontiguous_buf, void *contiguous_buf, 
51                             int count){
52   int i;
53   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
54   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
55
56   for (i = 0; i < block_count_ * count; i++) {
57       if (!(old_type_->flags() & DT_FLAG_DERIVED))
58         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_length_ * old_type_->size());
59       else        
60         old_type_->serialize(noncontiguous_buf_char, contiguous_buf_char, block_length_);
61
62     contiguous_buf_char += block_length_*old_type_->size();
63     if((i+1)%block_count_ ==0)
64       noncontiguous_buf_char += block_length_*old_type_->get_extent();
65     else
66       noncontiguous_buf_char += block_stride_*old_type_->get_extent();
67   }
68 }
69
70 void Type_Vector::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
71                               int count, MPI_Op op){
72   int i;
73   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
74   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
75
76   for (i = 0; i < block_count_ * count; i++) {
77     if (!(old_type_->flags() & DT_FLAG_DERIVED)){
78       if(op != MPI_OP_NULL)
79         op->apply(contiguous_buf_char, noncontiguous_buf_char, &block_length_,
80           old_type_);
81     }else
82       old_type_->unserialize(contiguous_buf_char, noncontiguous_buf_char, block_length_, op);
83
84     contiguous_buf_char += block_length_*old_type_->size();
85     if((i+1)%block_count_ ==0)
86       noncontiguous_buf_char += block_length_*old_type_->get_extent();
87     else
88       noncontiguous_buf_char += block_stride_*old_type_->get_extent();
89   }
90 }
91
92 Type_Hvector::Type_Hvector(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int block_length, MPI_Aint stride, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(count), block_length_(block_length), block_stride_(stride), old_type_(old_type){
93   old_type->ref();
94 }
95 Type_Hvector::~Type_Hvector(){
96   Datatype::unref(old_type_);
97 }
98
99 void Type_Hvector::serialize( void* noncontiguous_buf, void *contiguous_buf, 
100                     int count){
101   int i;
102   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
103   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
104
105   for (i = 0; i < block_count_ * count; i++) {
106     if (!(old_type_->flags() & DT_FLAG_DERIVED))
107       memcpy(contiguous_buf_char, noncontiguous_buf_char, block_length_ * old_type_->size());
108     else
109       old_type_->serialize( noncontiguous_buf_char, contiguous_buf_char, block_length_);
110
111     contiguous_buf_char += block_length_*old_type_->size();
112     if((i+1)%block_count_ ==0)
113       noncontiguous_buf_char += block_length_*old_type_->size();
114     else
115       noncontiguous_buf_char += block_stride_;
116   }
117 }
118
119
120 void Type_Hvector::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
121                               int count, MPI_Op op){
122   int i;
123   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
124   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
125
126   for (i = 0; i < block_count_ * count; i++) {
127     if (!(old_type_->flags() & DT_FLAG_DERIVED)){
128       if(op!=MPI_OP_NULL) 
129         op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_length_, old_type_);
130     }else
131       old_type_->unserialize( contiguous_buf_char, noncontiguous_buf_char, block_length_, op);
132     contiguous_buf_char += block_length_*old_type_->size();
133     if((i+1)%block_count_ ==0)
134       noncontiguous_buf_char += block_length_*old_type_->size();
135     else
136       noncontiguous_buf_char += block_stride_;
137   }
138 }
139
140 Type_Indexed::Type_Indexed(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths, int* block_indices, MPI_Datatype old_type): Datatype(size, lb, ub, flags), block_count_(count), old_type_(old_type){
141   old_type->ref();
142   block_lengths_ = new int[count];
143   block_indices_ = new int[count];
144   for (int i = 0; i < count; i++) {
145     block_lengths_[i]=block_lengths[i];
146     block_indices_[i]=block_indices[i];
147   }
148 }
149
150 Type_Indexed::~Type_Indexed(){
151   Datatype::unref(old_type_);
152   if(refcount()==0){
153     delete[] block_lengths_;
154     delete[] block_indices_;
155   }
156 }
157
158
159 void Type_Indexed::serialize( void* noncontiguous_buf, void *contiguous_buf, 
160                         int count){
161   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
162   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+block_indices_[0] * old_type_->size();
163   for (int j = 0; j < count; j++) {
164     for (int i = 0; i < block_count_; i++) {
165       if (!(old_type_->flags() & DT_FLAG_DERIVED))
166         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_lengths_[i] * old_type_->size());
167       else
168         old_type_->serialize( noncontiguous_buf_char, contiguous_buf_char, block_lengths_[i]);
169
170       contiguous_buf_char += block_lengths_[i]*old_type_->size();
171       if (i<block_count_-1)
172         noncontiguous_buf_char =
173           static_cast<char*>(noncontiguous_buf) + block_indices_[i+1]*old_type_->get_extent();
174       else
175         noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
176     }
177     noncontiguous_buf=static_cast< void*>(noncontiguous_buf_char);
178   }
179 }
180
181
182 void Type_Indexed::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
183                       int count, MPI_Op op){
184   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
185   char* noncontiguous_buf_char =
186     static_cast<char*>(noncontiguous_buf)+block_indices_[0]*old_type_->get_extent();
187   for (int j = 0; j < count; j++) {
188     for (int i = 0; i < block_count_; i++) {
189       if (!(old_type_->flags() & DT_FLAG_DERIVED)){
190         if(op!=MPI_OP_NULL) 
191           op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i],
192                     old_type_);
193       }else
194         old_type_->unserialize( contiguous_buf_char,noncontiguous_buf_char,block_lengths_[i], op);
195
196       contiguous_buf_char += block_lengths_[i]*old_type_->size();
197       if (i<block_count_-1)
198         noncontiguous_buf_char =
199           static_cast<char*>(noncontiguous_buf) + block_indices_[i+1]*old_type_->get_extent();
200       else
201         noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
202     }
203     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
204   }
205 }
206
207 Type_Hindexed::Type_Hindexed(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths, MPI_Aint* block_indices, MPI_Datatype old_type)
208 : Datatype(size, lb, ub, flags), block_count_(count), old_type_(old_type)
209 {
210   old_type_->ref();
211   block_lengths_ = new int[count];
212   block_indices_ = new MPI_Aint[count];
213   for (int i = 0; i < count; i++) {
214     block_lengths_[i]=block_lengths[i];
215     block_indices_[i]=block_indices[i];
216   }
217 }
218
219     Type_Hindexed::~Type_Hindexed(){
220   Datatype::unref(old_type_);
221   if(refcount()==0){
222     delete[] block_lengths_;
223     delete[] block_indices_;
224   }
225 }
226
227 void Type_Hindexed::serialize( void* noncontiguous_buf, void *contiguous_buf, 
228                 int count){
229   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
230   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
231   for (int j = 0; j < count; j++) {
232     for (int i = 0; i < block_count_; i++) {
233       if (!(old_type_->flags() & DT_FLAG_DERIVED))
234         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_lengths_[i] * old_type_->size());
235       else
236         old_type_->serialize(noncontiguous_buf_char, contiguous_buf_char,block_lengths_[i]);
237
238       contiguous_buf_char += block_lengths_[i]*old_type_->size();
239       if (i<block_count_-1)
240         noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf) + block_indices_[i+1];
241       else
242         noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
243     }
244     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
245   }
246 }
247
248 void Type_Hindexed::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
249                           int count, MPI_Op op){
250   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
251   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
252   for (int j = 0; j < count; j++) {
253     for (int i = 0; i < block_count_; i++) {
254       if (!(old_type_->flags() & DT_FLAG_DERIVED)){
255         if(op!=MPI_OP_NULL) 
256           op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i],
257                             old_type_);
258       }else
259         old_type_->unserialize( contiguous_buf_char,noncontiguous_buf_char,block_lengths_[i], op);
260
261       contiguous_buf_char += block_lengths_[i]*old_type_->size();
262       if (i<block_count_-1)
263         noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf) + block_indices_[i+1];
264       else
265         noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
266     }
267     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
268   }
269 }
270
271 Type_Struct::Type_Struct(int size,MPI_Aint lb, MPI_Aint ub, int flags, int count, int* block_lengths, MPI_Aint* block_indices, MPI_Datatype* old_types): Datatype(size, lb, ub, flags), block_count_(count), block_lengths_(block_lengths), block_indices_(block_indices), old_types_(old_types){
272   block_lengths_= new int[count];
273   block_indices_= new MPI_Aint[count];
274   old_types_=  new MPI_Datatype[count];
275   for (int i = 0; i < count; i++) {
276     block_lengths_[i]=block_lengths[i];
277     block_indices_[i]=block_indices[i];
278     old_types_[i]=old_types[i];
279     old_types_[i]->ref();
280   }
281 }
282
283 Type_Struct::~Type_Struct(){
284   for (int i = 0; i < block_count_; i++) {
285     Datatype::unref(old_types_[i]);
286   }
287   if(refcount()==0){
288     delete[] block_lengths_;
289     delete[] block_indices_;
290     delete[] old_types_;
291   }
292 }
293
294
295 void Type_Struct::serialize( void* noncontiguous_buf, void *contiguous_buf, 
296                         int count){
297   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
298   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
299   for (int j = 0; j < count; j++) {
300     for (int i = 0; i < block_count_; i++) {
301       if (!(old_types_[i]->flags() & DT_FLAG_DERIVED))
302         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_lengths_[i] * old_types_[i]->size());
303       else
304         old_types_[i]->serialize( noncontiguous_buf_char,contiguous_buf_char,block_lengths_[i]);
305
306
307       contiguous_buf_char += block_lengths_[i]*old_types_[i]->size();
308       if (i<block_count_-1)
309         noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf) + block_indices_[i+1];
310       else //let's hope this is MPI_UB ?
311         noncontiguous_buf_char += block_lengths_[i]*old_types_[i]->get_extent();
312     }
313     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
314   }
315 }
316
317 void Type_Struct::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
318                               int count, MPI_Op op){
319   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
320   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
321   for (int j = 0; j < count; j++) {
322     for (int i = 0; i < block_count_; i++) {
323       if (!(old_types_[i]->flags() & DT_FLAG_DERIVED)){
324         if(op!=MPI_OP_NULL) 
325           op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i], old_types_[i]);
326       }else
327         old_types_[i]->unserialize( contiguous_buf_char, noncontiguous_buf_char,block_lengths_[i], op);
328
329       contiguous_buf_char += block_lengths_[i]*old_types_[i]->size();
330       if (i<block_count_-1)
331         noncontiguous_buf_char =  static_cast<char*>(noncontiguous_buf) + block_indices_[i+1];
332       else
333         noncontiguous_buf_char += block_lengths_[i]*old_types_[i]->get_extent();
334     }
335     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
336   }
337 }
338
339 }
340 }