1 /* smpi_datatype.cpp -- MPI primitives to handle datatypes */
2 /* Copyright (c) 2009-2015. The SimGrid Team.
3 * All rights reserved. */
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. */
17 XBT_LOG_EXTERNAL_CATEGORY(smpi_datatype);
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){
27 Type_Contiguous::~Type_Contiguous(){
31 void Type_Contiguous::use(){
35 void Type_Contiguous::serialize( void* noncontiguous_buf, void *contiguous_buf,
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());
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_;
47 op->apply( contiguous_buf_char, noncontiguous_buf_char, &n, old_type_);
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){
55 Type_Vector::~Type_Vector(){
59 void Type_Vector::use(){
64 void Type_Vector::serialize( void* noncontiguous_buf, void *contiguous_buf,
67 char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
68 char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
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());
74 old_type_->serialize(noncontiguous_buf_char, contiguous_buf_char, block_length_);
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();
80 noncontiguous_buf_char += block_stride_*old_type_->get_extent();
84 void Type_Vector::unserialize( void* contiguous_buf, void *noncontiguous_buf,
85 int count, MPI_Op op){
87 char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
88 char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
90 for (i = 0; i < block_count_ * count; i++) {
91 if (!(old_type_->flags() & DT_FLAG_DERIVED)){
93 op->apply(contiguous_buf_char, noncontiguous_buf_char, &block_length_,
96 old_type_->unserialize(contiguous_buf_char, noncontiguous_buf_char, block_length_, op);
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();
102 noncontiguous_buf_char += block_stride_*old_type_->get_extent();
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){
109 Type_Hvector::~Type_Hvector(){
112 void Type_Hvector::use(){
116 void Type_Hvector::serialize( void* noncontiguous_buf, void *contiguous_buf,
119 char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
120 char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
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());
126 old_type_->serialize( noncontiguous_buf_char, contiguous_buf_char, block_length_);
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();
132 noncontiguous_buf_char += block_stride_;
137 void Type_Hvector::unserialize( void* contiguous_buf, void *noncontiguous_buf,
138 int count, MPI_Op op){
140 char* contiguous_buf_char = static_cast<char*>(contiguous_buf);
141 char* noncontiguous_buf_char = static_cast<char*>(noncontiguous_buf);
143 for (i = 0; i < block_count_ * count; i++) {
144 if (!(old_type_->flags() & DT_FLAG_DERIVED)){
146 op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_length_, old_type_);
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();
153 noncontiguous_buf_char += block_stride_;
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){
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];
167 Type_Indexed::~Type_Indexed(){
170 delete[] block_lengths_;
171 delete[] block_indices_;
175 void Type_Indexed::use(){
179 void Type_Indexed::serialize( void* noncontiguous_buf, void *contiguous_buf,
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());
188 old_type_->serialize( noncontiguous_buf_char, contiguous_buf_char, block_lengths_[i]);
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();
195 noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
197 noncontiguous_buf=static_cast< void*>(noncontiguous_buf_char);
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)){
211 op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i],
214 old_type_->unserialize( contiguous_buf_char,noncontiguous_buf_char,block_lengths_[i], op);
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();
221 noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
223 noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
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)
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];
239 Type_Hindexed::~Type_Hindexed(){
242 delete[] block_lengths_;
243 delete[] block_indices_;
247 void Type_Hindexed::use(){
250 void Type_Hindexed::serialize( void* noncontiguous_buf, void *contiguous_buf,
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());
259 old_type_->serialize(noncontiguous_buf_char, contiguous_buf_char,block_lengths_[i]);
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];
265 noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
267 noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
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)){
279 op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i],
282 old_type_->unserialize( contiguous_buf_char,noncontiguous_buf_char,block_lengths_[i], op);
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];
288 noncontiguous_buf_char += block_lengths_[i]*old_type_->get_extent();
290 noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
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]->use();
306 Type_Struct::~Type_Struct(){
307 for (int i = 0; i < block_count_; i++) {
308 old_types_[i]->unuse();
311 delete[] block_lengths_;
312 delete[] block_indices_;
317 void Type_Struct::use(){
318 for (int i = 0; i < block_count_; i++) {
319 old_types_[i]->use();
323 void Type_Struct::serialize( void* noncontiguous_buf, void *contiguous_buf,
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());
332 old_types_[i]->serialize( noncontiguous_buf_char,contiguous_buf_char,block_lengths_[i]);
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();
341 noncontiguous_buf=static_cast<void*>(noncontiguous_buf_char);
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)){
353 op->apply( contiguous_buf_char, noncontiguous_buf_char, &block_lengths_[i], old_types_[i]);
355 old_types_[i]->unserialize( contiguous_buf_char, noncontiguous_buf_char,block_lengths_[i], op);
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];
361 noncontiguous_buf_char += block_lengths_[i]*old_types_[i]->get_extent();
363 noncontiguous_buf=reinterpret_cast<void*>(noncontiguous_buf_char);