14 size_t count,
unsigned char * array,
size_t element_size, MPI_Comm comm,
15 size_t(*element_get_pack_size)(
void * element, MPI_Comm comm)) {
17 if (count == 0)
return 0;
20 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &count_pack_size), comm);
22 size_t array_pack_size = 0;
23 for (
size_t i = 0; i < count; ++i)
25 element_get_pack_size((
void*)(array + i * element_size), comm);
27 return (
size_t)count_pack_size + array_pack_size;
48 void *
buffer,
int buffer_size,
int * position,
size_t * count,
49 unsigned char ** array,
size_t element_size, MPI_Comm comm,
50 void(*element_unpack)(
51 void *
buffer,
int buffer_size,
int * position,
52 void * element, MPI_Comm comm)) {
57 buffer, buffer_size, position, &count_int, 1, MPI_INT, comm), comm);
59 *count = (size_t)count_int;
60 *array =
xmalloc(*count * element_size);
62 for (
size_t i = 0; i < *count; ++i)
64 buffer, buffer_size, position, (
void*)(*array + i * element_size), comm);
68 size_t * count,
void ** array,
size_t element_size, MPI_Comm comm,
72 MPI_Comm_rank(comm, &rank);
75 unsigned char * input = *array;
76 size_t input_len = *count;
79 *idx_old_to_new =
xmalloc(input_len *
sizeof(**idx_old_to_new));
80 idx =
xmalloc(input_len *
sizeof(*idx));
81 for(
size_t i = 0;i<input_len;++i) idx[i] = i;
83 unsigned char * arr_new = NULL;
86 YAC_ASSERT(input_len < INT_MAX,
"too many elements");
92 qsort((
void*)input, input_len, element_size, vtable->
compare);
101 input_len, input, element_size, comm, vtable->
get_pack_size);
102 YAC_ASSERT(pack_size <= LONG_MAX,
"packing size too big");
108 } data_pair = {.pack_size = (long)pack_size, .rank = rank};
111 MPI_IN_PLACE, &data_pair, 1, MPI_LONG_INT, MPI_MAXLOC, comm), comm);
114 if (data_pair.pack_size == 0)
break;
118 pack_size = (size_t)data_pair.pack_size;
123 if(data_pair.rank == rank)
125 input_len, input, element_size,
buffer, pack_size, &position, comm,
131 MPI_Bcast(
buffer, pack_size, MPI_PACKED, data_pair.rank, comm), comm);
132 unsigned char * recved = NULL;
136 buffer, pack_size, &position, &num_recved, &recved, element_size, comm,
140 arr_new =
xrealloc(arr_new, (len_new + num_recved)*element_size);
142 arr_new + len_new*element_size, (
void*)recved, num_recved*element_size);
146 size_t input_idx, input_len_new, i = len_new;
147 len_new += num_recved;
148 for(input_idx = 0, input_len_new = 0; i < len_new; ++i) {
149 void* recved_element = arr_new + i*element_size;
155 void * input_element = NULL;
156 while ((input_idx < input_len) &&
159 ((input_element = input + input_idx * element_size)),
160 recved_element))) < 0)) {
164 if (input_idx != input_len_new) {
166 input + input_len_new * element_size,
167 input_element, element_size);
168 if (idx) idx[input_len_new] = idx[input_idx];
175 if (input_idx == input_len)
break;
182 vtable->
merge(recved_element, input_element, comm);
186 if (idx_old_to_new) (*idx_old_to_new)[idx[input_idx]] = i;
191 }
else if (vtable->
merge) {
194 vtable->
merge(recved_element, NULL, comm);
201 for(; i < len_new; ++i)
202 vtable->
merge(arr_new + i*element_size, NULL, comm);
206 for (; input_idx < input_len; ++input_idx, ++input_len_new) {
207 if (input_idx != input_len_new) {
209 input + input_len_new * element_size,
210 input + input_idx * element_size, element_size);
211 if (idx) idx[input_len_new] = idx[input_idx];
215 input_len = input_len_new;
static void pack(size_t count, unsigned char *array, size_t element_size, void *buffer, int buffer_size, int *position, MPI_Comm comm, void(*element_pack)(void *element, void *buffer, int buffer_size, int *position, MPI_Comm))
static void unpack(void *buffer, int buffer_size, int *position, size_t *count, unsigned char **array, size_t element_size, MPI_Comm comm, void(*element_unpack)(void *buffer, int buffer_size, int *position, void *element, MPI_Comm comm))