int Pack(void *inbuf, int incount, Datatype type, void *outbuf, int outsize, int *position, Comm * comm) { int i, j; MPI_Aint extent; //check that buffer is large enough Type_extent(type, &extent); for (i = 0; i < incount; i++) { for (j = 0; j < type->count; j++) { if ((*position) + Simpletype_length(type->pairs[j].type) > outsize) { printf("MPI_Pack: data exceeds buffer size\n"); exit(1); } memcpy(((char*) outbuf)+(*position), inbuf+type->pairs[j].disp + (extent*i), Simpletype_length(type->pairs[j].type)); *position += Simpletype_length(type->pairs[j].type); } } }
int Unpack(void * inbuf, int insize, int * position, void *outbuf, int outcount, Datatype type, Comm* comm) { int i, j; MPI_Aint extent; Type_extent(type, &extent); for (i = 0; i < outcount; i++) { for (j = 0; j < type->count; j++) { if ((*position) + Simpletype_length(type->pairs[j].type) > insize) { printf("MPI_Unpack: Data exceeds buffer size\n"); exit(1); } memcpy(outbuf+type->pairs[j].disp + (extent*i), ((char*) inbuf)+(*position) , Simpletype_length(type->pairs[j].type)); *position += Simpletype_length(type->pairs[j].type); } } }
int Type_struct(int count, int * blocklens, MPI_Aint * displacements, Datatype *oldtypes_ptr, Datatype *newtype) { int i, j, k; Datatype temp, temp2; int newcount; char override_lower = 0, //whether to override override_upper = 0; MPI_Aint new_lb = LONG_MAX, new_ub = LONG_MIN, clb, cub; //calculated lb and ub int simpletype_count = 0; //total additional blocks for malloc MPI_Aint tmp_offset; //for contiguous blocks of type MPI_Aint extent; // find the total number of elements in the typemap we need to add. for (i = 0; i < count; i++) { //check for MPI_UB or MPI_LB. These types are special // cases and will be skipped over temp2 = oldtypes_ptr[i]; if (temp2->pairs[0].type == SIMPLE_LOWER) { //found MPI_LB. This is a candidate for the actual lb if (new_lb > displacements[i]) new_lb = displacements[i]; override_lower = 1; } else if (temp2->pairs[0].type == SIMPLE_UPPER) { //same as above, but ub if (new_ub < displacements[i]) new_ub = displacements[i]; override_upper = 1; } else { //this is not MPI_LB or MPI_UB //However it may still have overriding bounds //Test for these and add its size to the typemap. if (temp2->o_lb) // this type's lb has been overridden. // ONLY an overriding lb can be the actual lb now. override_lower = 1; if (temp2->o_ub) //same as above, but ub override_upper = 1; simpletype_count += blocklens[i] * oldtypes_ptr[i]->count; } } temp = malloc(sizeof(Typestruct) + ((simpletype_count-1) * sizeof(typepair))); temp->count = simpletype_count; i = 0; //old type's index newcount = 0; //new type's index while (i < count) { tmp_offset = 0; temp2 = oldtypes_ptr[i]; //test for previous MPI_LB or MPI_UB in one of the comprising types. //If found, skip over. if (!((temp2->pairs[0].type == SIMPLE_LOWER) || (temp2->pairs[0].type == SIMPLE_UPPER))) { for (j = 0; j < blocklens[i]; j++) { //Copy the old type's typemap and merge into the new type //by a "flattening" process Type_extent((Datatype) oldtypes_ptr[i], &extent); tmp_offset = j * extent; if (temp2->o_lb && temp2->lb+displacements[i]+tmp_offset < new_lb) new_lb = temp2->lb+displacements[i]+tmp_offset; if (temp2->o_ub && temp2->ub+displacements[i]+tmp_offset > new_ub) { new_ub = temp2->ub+displacements[i]+tmp_offset; } for (k = 0; k < oldtypes_ptr[i]->count; k++) { Copy_type( (typepair*) oldtypes_ptr[i]->pairs+k, (typepair*) (temp->pairs+newcount)); ((typepair*) temp->pairs+(newcount))->disp += displacements[i] + tmp_offset; newcount++; } } } i++; } //type is NOT committed temp->committed = 0; //assign upper and lower bounds here if (override_lower) { //use lowest previous overridden lower bound temp->o_lb = 1; temp->lb = new_lb; } else { //use calculation temp->lb = calc_lb(temp); } if (override_upper) { temp->o_ub = 1; temp->ub = new_ub; } else { temp->ub = calc_ub(temp); } *newtype = temp; temp = MPI_DATATYPE_NULL; return MPI_SUCCESS; }