Logo AND Algorithmique Numérique Distribuée

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