11 size_t count,
unsigned char * array,
size_t element_size, MPI_Comm comm,
12 size_t(*element_get_pack_size)(
void * element, MPI_Comm comm)) {
14 if (count == 0)
return 0;
17 yac_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &count_pack_size), comm);
19 size_t array_pack_size = 0;
20 for (
size_t i = 0; i < count; ++i)
22 element_get_pack_size((
void*)(array + i * element_size), comm);
24 return (
size_t)count_pack_size + array_pack_size;
45 void *
buffer,
int buffer_size,
int * position,
size_t * count,
46 unsigned char ** array,
size_t element_size, MPI_Comm comm,
47 void(*element_unpack)(
48 void *
buffer,
int buffer_size,
int * position,
49 void * element, MPI_Comm comm)) {
54 buffer, buffer_size, position, &count_int, 1, MPI_INT, comm), comm);
56 *count = (size_t)count_int;
57 *array =
xmalloc(*count * element_size);
59 for (
size_t i = 0; i < *count; ++i)
61 buffer, buffer_size, position, (
void*)(*array + i * element_size), comm);
65 size_t * count,
void ** array,
size_t element_size, MPI_Comm comm,
69 MPI_Comm_rank(comm, &rank);
72 unsigned char * input = *array;
73 size_t input_len = *count;
76 *idx_old_to_new =
xmalloc(input_len *
sizeof(**idx_old_to_new));
77 idx =
xmalloc(input_len *
sizeof(*idx));
78 for(
size_t i = 0;i<input_len;++i) idx[i] = i;
80 unsigned char * arr_new = NULL;
84 input_len < INT_MAX,
"ERROR(yac_dist_merge): too many elements");
90 qsort((
void*)input, input_len, element_size, vtable->
compare);
101 pack_size <= LONG_MAX,
"ERROR(yac_dist_merge): packing size too big");
107 } data_pair = {.pack_size = (long)pack_size, .rank = rank};
110 MPI_IN_PLACE, &data_pair, 1, MPI_LONG_INT, MPI_MAXLOC, comm), comm);
113 if (data_pair.pack_size == 0)
break;
117 pack_size = (size_t)data_pair.pack_size;
122 if(data_pair.rank == rank)
124 input_len, input, element_size,
buffer, pack_size, &position, comm,
130 MPI_Bcast(
buffer, pack_size, MPI_PACKED, data_pair.rank, comm), comm);
131 unsigned char * recved = NULL;
135 buffer, pack_size, &position, &num_recved, &recved, element_size, comm,
139 arr_new =
xrealloc(arr_new, (len_new + num_recved)*element_size);
141 arr_new + len_new*element_size, (
void*)recved, num_recved*element_size);
145 size_t input_idx, input_len_new, i = len_new;
146 len_new += num_recved;
147 for(input_idx = 0, input_len_new = 0; i < len_new; ++i) {
148 void* recved_element = arr_new + i*element_size;
154 void * input_element = NULL;
155 while ((input_idx < input_len) &&
158 ((input_element = input + input_idx * element_size)),
159 recved_element))) < 0)) {
163 if (input_idx != input_len_new) {
165 input + input_len_new * element_size,
166 input_element, element_size);
167 if (idx) idx[input_len_new] = idx[input_idx];
174 if (input_idx == input_len)
break;
181 vtable->
merge(recved_element, input_element, comm);
185 if (idx_old_to_new) (*idx_old_to_new)[idx[input_idx]] = i;
190 }
else if (vtable->
merge) {
193 vtable->
merge(recved_element, NULL, comm);
200 for(; i < len_new; ++i)
201 vtable->
merge(arr_new + i*element_size, NULL, comm);
205 for (; input_idx < input_len; ++input_idx, ++input_len_new) {
206 if (input_idx != input_len_new) {
208 input + input_len_new * element_size,
209 input + input_idx * element_size, element_size);
210 if (idx) idx[input_len_new] = idx[input_idx];
214 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))