+
+/*
+Hindexed Implementation - Indexed with indices in bytes
+*/
+
+/*
+ * Copies noncontiguous data into contiguous memory.
+ * @param contiguous_hindexed - output hindexed
+ * @param noncontiguous_hindexed - input hindexed
+ * @param type - pointer contening :
+ * - block_lengths - the width or height of blocked matrix
+ * - block_indices - indices of each data, in bytes
+ * - count - the number of rows of matrix
+ */
+void serialize_hindexed( const void *noncontiguous_hindexed,
+ void *contiguous_hindexed,
+ size_t count,
+ void *type)
+{
+ s_smpi_mpi_hindexed_t* type_c = (s_smpi_mpi_hindexed_t*)type;
+ int i,j;
+ char* contiguous_hindexed_char = (char*)contiguous_hindexed;
+ char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed+ type_c->block_indices[0];
+ for(j=0; j<count;j++){
+ for (i = 0; i < type_c->block_count; i++) {
+ if (type_c->old_type->has_subtype == 0)
+ memcpy(contiguous_hindexed_char,
+ noncontiguous_hindexed_char, type_c->block_lengths[i] * type_c->size_oldtype);
+ else
+ ((s_smpi_subtype_t*)type_c->old_type->substruct)->serialize( noncontiguous_hindexed_char,
+ contiguous_hindexed_char,
+ type_c->block_lengths[i],
+ type_c->old_type->substruct);
+
+ contiguous_hindexed_char += type_c->block_lengths[i]*type_c->size_oldtype;
+ if (i<type_c->block_count-1)noncontiguous_hindexed_char = (char*)noncontiguous_hindexed + type_c->block_indices[i+1];
+ else noncontiguous_hindexed_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_type);
+ }
+ noncontiguous_hindexed=(void*)noncontiguous_hindexed_char;
+ }
+}
+/*
+ * Copies contiguous data into noncontiguous memory.
+ * @param noncontiguous_hindexed - output hindexed
+ * @param contiguous_hindexed - input hindexed
+ * @param type - pointer contening :
+ * - block_lengths - the width or height of blocked matrix
+ * - block_indices - indices of each data, in bytes
+ * - count - the number of rows of matrix
+ */
+void unserialize_hindexed( const void *contiguous_hindexed,
+ void *noncontiguous_hindexed,
+ size_t count,
+ void *type)
+{
+ s_smpi_mpi_hindexed_t* type_c = (s_smpi_mpi_hindexed_t*)type;
+ int i,j;
+
+ char* contiguous_hindexed_char = (char*)contiguous_hindexed;
+ char* noncontiguous_hindexed_char = (char*)noncontiguous_hindexed+ type_c->block_indices[0];
+ for(j=0; j<count;j++){
+ for (i = 0; i < type_c->block_count; i++) {
+ if (type_c->old_type->has_subtype == 0)
+ memcpy(noncontiguous_hindexed_char,
+ contiguous_hindexed_char, type_c->block_lengths[i] * type_c->size_oldtype);
+ else
+ ((s_smpi_subtype_t*)type_c->old_type->substruct)->unserialize( contiguous_hindexed_char,
+ noncontiguous_hindexed_char,
+ type_c->block_lengths[i],
+ type_c->old_type->substruct);
+
+ contiguous_hindexed_char += type_c->block_lengths[i]*type_c->size_oldtype;
+ if (i<type_c->block_count-1)noncontiguous_hindexed_char = (char*)noncontiguous_hindexed + type_c->block_indices[i+1];
+ else noncontiguous_hindexed_char += type_c->block_lengths[i]*smpi_datatype_get_extent(type_c->old_type);
+ }
+ noncontiguous_hindexed=(void*)noncontiguous_hindexed_char;
+ }
+}
+
+void free_hindexed(MPI_Datatype* type){
+ xbt_free(((s_smpi_mpi_hindexed_t *)(*type)->substruct)->block_lengths);
+ xbt_free(((s_smpi_mpi_hindexed_t *)(*type)->substruct)->block_indices);
+}
+
+/*
+ * Create a Sub type hindexed to be able to serialize and unserialize it
+ * the structure s_smpi_mpi_hindexed_t is derived from s_smpi_subtype which
+ * required the functions unserialize and serialize
+ */
+s_smpi_mpi_hindexed_t* smpi_datatype_hindexed_create( int* block_lengths,
+ MPI_Aint* block_indices,
+ int block_count,
+ MPI_Datatype old_type,
+ int size_oldtype){
+ s_smpi_mpi_hindexed_t *new_t= xbt_new(s_smpi_mpi_hindexed_t,1);
+ new_t->base.serialize = &serialize_hindexed;
+ new_t->base.unserialize = &unserialize_hindexed;
+ new_t->base.subtype_free = &free_hindexed;
+ //TODO : add a custom function for each time to clean these
+ new_t->block_lengths= xbt_new(int, block_count);
+ new_t->block_indices= xbt_new(MPI_Aint, block_count);
+ int i;
+ for(i=0;i<block_count;i++){
+ new_t->block_lengths[i]=block_lengths[i];
+ new_t->block_indices[i]=block_indices[i];
+ }
+ new_t->block_count = block_count;
+ new_t->old_type = old_type;
+ new_t->size_oldtype = size_oldtype;
+ return new_t;
+}
+
+