Logo AND Algorithmique Numérique Distribuée

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