Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
7a8bc0fd58105f49ed54da050683722d0ee60b96
[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 void Type_Contiguous::ref(){
32   old_type_->ref();
33 };
34
35 void Type_Contiguous::serialize( void* noncontiguous_buf, void *contiguous_buf, 
36                             int count){
37   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
38   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+lb_;
39   memcpy(contiguous_buf_char, noncontiguous_buf_char, count * block_count_ * old_type_->size());
40 }
41 void Type_Contiguous::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
42                               int count, MPI_Op op){
43   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
44   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+lb_;
45   int n= count*block_count_;
46   if(op!=MPI_OP_NULL)
47     op->apply( contiguous_buf_char, noncontiguous_buf_char, &n, old_type_);
48 }
49
50
51 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){
52   old_type_->ref();
53 }
54
55 Type_Vector::~Type_Vector(){
56   Datatype::unref(old_type_);
57 }
58
59 void Type_Vector::ref(){
60   old_type_->ref();
61 }
62
63
64 void Type_Vector::serialize( void* noncontiguous_buf, void *contiguous_buf, 
65                             int count){
66   int i;
67   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
68   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
69
70   for (i = 0; i < block_count_ * count; i++) {
71       if (!(old_type_->flags() & DT_FLAG_DERIVED))
72         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_length_ * old_type_->size());
73       else        
74         old_type_->serialize(noncontiguous_buf_char, contiguous_buf_char, block_length_);
75
76     contiguous_buf_char += block_length_*old_type_->size();
77     if((i+1)%block_count_ ==0)
78       noncontiguous_buf_char += block_length_*old_type_->get_extent();
79     else
80       noncontiguous_buf_char += block_stride_*old_type_->get_extent();
81   }
82 }
83
84 void Type_Vector::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
85                               int count, MPI_Op op){
86   int i;
87   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
88   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
89
90   for (i = 0; i < block_count_ * count; i++) {
91     if (!(old_type_->flags() & DT_FLAG_DERIVED)){
92       if(op != MPI_OP_NULL)
93         op->apply(contiguous_buf_char, noncontiguous_buf_char, &block_length_,
94           old_type_);
95     }else
96       old_type_->unserialize(contiguous_buf_char, noncontiguous_buf_char, block_length_, op);
97
98     contiguous_buf_char += block_length_*old_type_->size();
99     if((i+1)%block_count_ ==0)
100       noncontiguous_buf_char += block_length_*old_type_->get_extent();
101     else
102       noncontiguous_buf_char += block_stride_*old_type_->get_extent();
103   }
104 }
105
106 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){
107   old_type->ref();
108 }
109 Type_Hvector::~Type_Hvector(){
110   Datatype::unref(old_type_);
111 }
112 void Type_Hvector::ref(){
113   old_type_->ref();
114 }
115
116 void Type_Hvector::serialize( void* noncontiguous_buf, void *contiguous_buf, 
117                     int count){
118   int i;
119   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
120   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
121
122   for (i = 0; i < block_count_ * count; i++) {
123     if (!(old_type_->flags() & DT_FLAG_DERIVED))
124       memcpy(contiguous_buf_char, noncontiguous_buf_char, block_length_ * old_type_->size());
125     else
126       old_type_->serialize( noncontiguous_buf_char, contiguous_buf_char, block_length_);
127
128     contiguous_buf_char += block_length_*old_type_->size();
129     if((i+1)%block_count_ ==0)
130       noncontiguous_buf_char += block_length_*old_type_->size();
131     else
132       noncontiguous_buf_char += block_stride_;
133   }
134 }
135
136
137 void Type_Hvector::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
138                               int count, MPI_Op op){
139   int i;
140   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
141   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
142
143   for (i = 0; i < block_count_ * count; i++) {
144     if (!(old_type_->flags() & DT_FLAG_DERIVED)){
145       if(op!=MPI_OP_NULL) 
146         op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_length_, old_type_);
147     }else
148       old_type_->unserialize( contiguous_buf_char, noncontiguous_buf_char, block_length_, op);
149     contiguous_buf_char += block_length_*old_type_->size();
150     if((i+1)%block_count_ ==0)
151       noncontiguous_buf_char += block_length_*old_type_->size();
152     else
153       noncontiguous_buf_char += block_stride_;
154   }
155 }
156
157 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){
158   old_type->ref();
159   block_lengths_ = new int[count];
160   block_indices_ = new int[count];
161   for (int i = 0; i < count; i++) {
162     block_lengths_[i]=block_lengths[i];
163     block_indices_[i]=block_indices[i];
164   }
165 }
166
167 Type_Indexed::~Type_Indexed(){
168   Datatype::unref(old_type_);
169   if(refcount_==0){
170     delete[] block_lengths_;
171     delete[] block_indices_;
172   }
173 }
174
175 void Type_Indexed::ref(){
176   old_type_->ref();
177 }
178
179 void Type_Indexed::serialize( void* noncontiguous_buf, void *contiguous_buf, 
180                         int count){
181   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
182   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+block_indices_[0] * old_type_->size();
183   for (int j = 0; j < count; j++) {
184     for (int i = 0; i < block_count_; i++) {
185       if (!(old_type_->flags() & DT_FLAG_DERIVED))
186         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_lengths_[i] * old_type_->size());
187       else
188         old_type_->serialize( noncontiguous_buf_char, contiguous_buf_char, block_lengths_[i]);
189
190       contiguous_buf_char += block_lengths_[i]*old_type_->size();
191       if (i<block_count_-1)
192         noncontiguous_buf_char =
193           static_cast<char*>(noncontiguous_buf) + block_indices_[i+1]*old_type_->get_extent();
194       else
195         noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
196     }
197     noncontiguous_buf=static_cast< void*>(noncontiguous_buf_char);
198   }
199 }
200
201
202 void Type_Indexed::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
203                       int count, MPI_Op op){
204   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
205   char* noncontiguous_buf_char =
206     static_cast<char*>(noncontiguous_buf)+block_indices_[0]*old_type_->get_extent();
207   for (int j = 0; j < count; j++) {
208     for (int i = 0; i < block_count_; i++) {
209       if (!(old_type_->flags() & DT_FLAG_DERIVED)){
210         if(op!=MPI_OP_NULL) 
211           op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i],
212                     old_type_);
213       }else
214         old_type_->unserialize( contiguous_buf_char,noncontiguous_buf_char,block_lengths_[i], op);
215
216       contiguous_buf_char += block_lengths_[i]*old_type_->size();
217       if (i<block_count_-1)
218         noncontiguous_buf_char =
219           static_cast<char*>(noncontiguous_buf) + block_indices_[i+1]*old_type_->get_extent();
220       else
221         noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
222     }
223     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
224   }
225 }
226
227 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)
228 : Datatype(size, lb, ub, flags), block_count_(count), old_type_(old_type)
229 {
230   old_type_->ref();
231   block_lengths_ = new int[count];
232   block_indices_ = new MPI_Aint[count];
233   for (int i = 0; i < count; i++) {
234     block_lengths_[i]=block_lengths[i];
235     block_indices_[i]=block_indices[i];
236   }
237 }
238
239     Type_Hindexed::~Type_Hindexed(){
240   Datatype::unref(old_type_);
241   if(refcount_==0){
242     delete[] block_lengths_;
243     delete[] block_indices_;
244   }
245 }
246
247 void Type_Hindexed::ref(){
248   old_type_->ref();
249 }
250 void Type_Hindexed::serialize( void* noncontiguous_buf, void *contiguous_buf, 
251                 int count){
252   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
253   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
254   for (int j = 0; j < count; j++) {
255     for (int i = 0; i < block_count_; i++) {
256       if (!(old_type_->flags() & DT_FLAG_DERIVED))
257         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_lengths_[i] * old_type_->size());
258       else
259         old_type_->serialize(noncontiguous_buf_char, contiguous_buf_char,block_lengths_[i]);
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 void Type_Hindexed::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
272                           int count, MPI_Op op){
273   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
274   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
275   for (int j = 0; j < count; j++) {
276     for (int i = 0; i < block_count_; i++) {
277       if (!(old_type_->flags() & DT_FLAG_DERIVED)){
278         if(op!=MPI_OP_NULL) 
279           op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i],
280                             old_type_);
281       }else
282         old_type_->unserialize( contiguous_buf_char,noncontiguous_buf_char,block_lengths_[i], op);
283
284       contiguous_buf_char += block_lengths_[i]*old_type_->size();
285       if (i<block_count_-1)
286         noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf) + block_indices_[i+1];
287       else
288         noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
289     }
290     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
291   }
292 }
293
294 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){
295   block_lengths_= new int[count];
296   block_indices_= new MPI_Aint[count];
297   old_types_=  new MPI_Datatype[count];
298   for (int i = 0; i < count; i++) {
299     block_lengths_[i]=block_lengths[i];
300     block_indices_[i]=block_indices[i];
301     old_types_[i]=old_types[i];
302     old_types_[i]->ref();
303   }
304 }
305
306 Type_Struct::~Type_Struct(){
307   for (int i = 0; i < block_count_; i++) {
308     Datatype::unref(old_types_[i]);
309   }
310   if(refcount_==0){
311     delete[] block_lengths_;
312     delete[] block_indices_;
313     delete[] old_types_;
314   }
315 }
316
317 void Type_Struct::ref(){
318   for (int i = 0; i < block_count_; i++) {
319     old_types_[i]->ref();
320   }
321 }
322
323 void Type_Struct::serialize( void* noncontiguous_buf, void *contiguous_buf, 
324                         int count){
325   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
326   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
327   for (int j = 0; j < count; j++) {
328     for (int i = 0; i < block_count_; i++) {
329       if (!(old_types_[i]->flags() & DT_FLAG_DERIVED))
330         memcpy(contiguous_buf_char, noncontiguous_buf_char, block_lengths_[i] * old_types_[i]->size());
331       else
332         old_types_[i]->serialize( noncontiguous_buf_char,contiguous_buf_char,block_lengths_[i]);
333
334
335       contiguous_buf_char += block_lengths_[i]*old_types_[i]->size();
336       if (i<block_count_-1)
337         noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf) + block_indices_[i+1];
338       else //let's hope this is MPI_UB ?
339         noncontiguous_buf_char += block_lengths_[i]*old_types_[i]->get_extent();
340     }
341     noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
342   }
343 }
344
345 void Type_Struct::unserialize( void* contiguous_buf, void *noncontiguous_buf, 
346                               int count, MPI_Op op){
347   char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
348   char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf)+ block_indices_[0];
349   for (int j = 0; j < count; j++) {
350     for (int i = 0; i < block_count_; i++) {
351       if (!(old_types_[i]->flags() & DT_FLAG_DERIVED)){
352         if(op!=MPI_OP_NULL) 
353           op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i], old_types_[i]);
354       }else
355         old_types_[i]->unserialize( contiguous_buf_char, noncontiguous_buf_char,block_lengths_[i], op);
356
357       contiguous_buf_char += block_lengths_[i]*old_types_[i]->size();
358       if (i<block_count_-1)
359         noncontiguous_buf_char =  static_cast<char*>(noncontiguous_buf) + block_indices_[i+1];
360       else
361         noncontiguous_buf_char += block_lengths_[i]*old_types_[i]->get_extent();
362     }
363     noncontiguous_buf=reinterpret_cast<void*>(noncontiguous_buf_char);
364   }
365 }
366
367 }
368 }