104 int * position,
int offset);
107 int num_selection,
int *positions,
108 int single_match_only);
125 .get_indices_at_positions = NULL,
129 .get_positions_of_indices_off = NULL,
132 .get_bounding_box = NULL,
171 MPI_Aint base_address, local_size_address;
173 MPI_Get_address(&dim_desc, &base_address);
174 MPI_Get_address(&dim_desc.
local_size, &local_size_address);
176 enum { num_dt_components = 2 };
177 int block_lengths[num_dt_components] = { 4, 1 };
178 MPI_Aint displacements[num_dt_components]
179 = {0, local_size_address - base_address };
180 MPI_Datatype types[num_dt_components]
182 dim_desc_dt_unaligned;
183 xt_mpi_call(MPI_Type_create_struct(num_dt_components,
184 block_lengths, displacements, types,
185 &dim_desc_dt_unaligned), Xt_default_comm);
186 xt_mpi_call(MPI_Type_create_resized(dim_desc_dt_unaligned, 0,
187 (MPI_Aint)
sizeof(dim_desc),
189 xt_mpi_call(MPI_Type_free(&dim_desc_dt_unaligned), Xt_default_comm);
207 if (num_dimensions <= 0)
209 Xt_idxsection idxsection =
xmalloc(
sizeof (*idxsection)
210 + (
size_t)num_dimensions *
211 sizeof (idxsection->
dims[0]));
214 idxsection->
ndim = num_dimensions;
218 for (
int i = 0; i < num_dimensions; ++i) {
234 for (
int i = num_dimensions - 2; i >= 0; --i) {
249 for (
int i = num_dimensions - 1; i >= 0; --i) {
272 for (
int i = 0; i < num_dimensions; ++i) {
295 if (data == NULL)
return;
308 int size_int_type, size_ndim, size_dim_descs, size_xt_int;
310 xt_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &size_int_type), comm);
312 xt_mpi_call(MPI_Pack_size(1, MPI_INT, comm, &size_ndim), comm);
314 comm, &size_dim_descs), comm);
316 return (
size_t)size_int_type + (size_t)size_ndim + (
size_t)size_dim_descs
317 + (size_t)size_xt_int;
332 buffer_size, position, comm), comm);
335 buffer_size, position, comm), comm);
338 buffer_size, position, comm), comm);
340 buffer_size, position, comm), comm);
342 buffer, buffer_size, position, comm), comm);
352 Xt_idxsection section;
355 Xt_int global_start_index, local_start_index;
356 xt_mpi_call(MPI_Unpack(buffer, buffer_size, position,
357 &global_start_index, 1,
Xt_int_dt, comm), comm);
358 xt_mpi_call(MPI_Unpack(buffer, buffer_size, position,
359 &local_start_index, 1,
Xt_int_dt, comm), comm);
360 xt_mpi_call(MPI_Unpack(buffer, buffer_size, position, &ndim, 1, MPI_INT,
364 section =
xmalloc(
sizeof (*section)
365 + (
size_t)ndim *
sizeof(section->
dims[0]));
369 section->
ndim = ndim;
372 xt_mpi_call(MPI_Unpack(buffer, buffer_size, position,
380 for (
int i = 0; i < ndim; ++i) {
410 INSTR_DEF(instr,
"idxsection_get_intersection_with_other_idxlist")
417 int single_match_only = 0;
420 for (i = 1; i < num_dst_idx; ++i)
421 if (dst_idx[i] < dst_idx[i-1])
424 Xt_int const * sorted_dst_idx;
425 Xt_int * temp_dst_idx = NULL;
428 if (num_dst_idx > 1 && i != num_dst_idx) {
430 temp_dst_idx =
xmalloc((
size_t)num_dst_idx *
sizeof(*temp_dst_idx));
431 memcpy(temp_dst_idx, dst_idx, (
size_t)num_dst_idx *
sizeof(*temp_dst_idx));
435 sorted_dst_idx = temp_dst_idx;
437 sorted_dst_idx = dst_idx;
439 pos =
xmalloc((
size_t)num_dst_idx *
sizeof(*pos));
441 src_idxsection, sorted_dst_idx, num_dst_idx, pos,
443 int num_inter_idx = num_dst_idx - num_unmatched;
445 if (num_inter_idx != 0) {
447 *
sizeof(*intersection));
449 for(i = 0, j = 0; i < num_dst_idx && j < num_inter_idx; i++) {
450 intersection[j] = sorted_dst_idx[i];
470 INSTR_DEF(instr,
"idxsection_get_intersection.part")
474 Xt_idxsection idxsection_src, idxsection_dst;
479 if (idxsection_src->
ndim != idxsection_dst->
ndim ||
487 for (i = 1; i < idxsection_src->
ndim; ++i)
491 idxlist_src, idxlist_dst);
499 local_start =
xmalloc((
size_t)idxsection_src->
ndim *
sizeof(*local_start));
500 local_size =
xmalloc((
size_t)idxsection_src->
ndim *
sizeof(*local_size));
501 global_size =
xmalloc((
size_t)idxsection_src->
ndim *
sizeof(*global_size));
506 for (i = 0; i < idxsection_src->
ndim; ++i) {
508 Xt_int src_start, src_end, dst_start, dst_end, local_end;
529 src_end = (
Xt_int)(src_start
531 dst_end = (
Xt_int)(dst_start
534 local_start[i] = (src_start > dst_start)?src_start:dst_start;
535 local_end = (src_end > dst_end)?dst_end:src_end;
537 if (local_end <= local_start[i]) {
545 local_size[i] = (int)(local_end - local_start[i]);
551 idxsection_src->
ndim, global_size,
552 local_size, local_start);
567 int num_dimensions = src->
ndim;
569 Xt_idxsection idxsection =
xmalloc(
sizeof (*idxsection)
570 + (
size_t)num_dimensions
571 *
sizeof (idxsection->
dims[0]));
575 memcpy(idxsection->
dims, src->
dims, (
size_t)num_dimensions *
576 sizeof (src->
dims[0]));
587 for (i = 0; i < section->
ndim; ++i)
589 assert(size <= INT_MAX);
597 int ndim,
struct dim_desc dims[ndim])
605 for (
int i = 0; i < abs_local_size; ++i)
606 indices[i] = (
Xt_int)(start_index + i);
608 for (
int i = 0; i < abs_local_size; ++i)
609 indices[i] = (
Xt_int)(start_index - i);
610 return abs_local_size;
614 int indices_written = 0, overflow = 0;
616 for (
int dim_ofs = 0; dim_ofs < abs_local_size; ++dim_ofs)
618 int indices_written_temp
622 indices + indices_written,
624 overflow |= (indices_written_temp > INT_MAX - indices_written);
625 indices_written += indices_written_temp;
628 return indices_written;
634 INSTR_DEF(instr,
"idxsection_get_indices")
640 if (num_indices > 0) {
645 (
size_t)num_indices *
sizeof(*indices));
660 (
size_t)num_indices *
sizeof(*indices));
682 INSTR_DEF(instr,
"idxsection_get_index_stripes.part")
693 for (
int i = 0; i < section->
ndim-1; ++i)
697 *num_stripes = (int)nstripes;
706 Xt_int *curr_local_position;
708 curr_local_position =
xcalloc((
size_t)(section->
ndim-1),
709 sizeof(*curr_local_position));
711 for (
size_t i = 0; i < nstripes; ++i) {
717 for (
int j = 0; j < section->
ndim - 1; ++j)
719 + curr_local_position[j]
722 for (
int j = section->
ndim - 2; j >= 0; --j)
723 if (curr_local_position[j] < abs(section->
dims[j].
local_size) - 1) {
724 curr_local_position[j]++;
727 curr_local_position[j] = 0;
730 *num_stripes = (int)nstripes;
731 free(curr_local_position);
742 if (position < 0)
return 1;
749 Xt_int curr_local_position;
750 long long pos = (
long long)position;
752 for (dim = 0; dim < section->
ndim; ++dim) {
759 temp_index = (
Xt_int)(temp_index
760 + curr_local_position
775 INSTR_DEF(instr,
"idxsection_get_position_of_index.part")
780 if (index < section->min_index_cache || index > section->
max_index_cache)
791 int temp_position = 0;
793 for (i = 0; i < section->
ndim; ++i) {
798 Xt_int curr_global_position
799 = (
Xt_int)(index / abs_global_stride);
807 index = (
Xt_int)(index % abs_global_stride);
809 if (curr_global_position < section->dims[i].
local_start)
812 Xt_int curr_local_position
823 temp_position += (int)(curr_local_position * section->
dims[i].
local_stride);
826 *position = temp_position;
837 const Xt_int selection_idx[],
840 int single_match_only) {
842 INSTR_DEF(instr,
"idxsection_get_positions_of_indices_v1.part")
844 if (num_selection < 1)
return 0;
846 if (num_selection == 1)
850 int num_unmatched = 0;
852 if (!single_match_only) {
854 for (
int i = 0; i < num_selection; ++i)
858 return num_unmatched;
863 for (
size_t i = 1; i < (size_t)num_selection; ++i)
864 if (selection_idx[i] < selection_idx[i-1])
872 for (
size_t i = 0; i < (size_t)num_selection; i++) {
874 Xt_int curr_index = selection_idx[i];
876 if (prev_index != curr_index) {
881 prev_index = curr_index;
897 for (
size_t i = 0; i < (size_t)num_selection; i++) {
898 v[i].
idx = selection_idx[i];
903 for (
size_t i = 0; i < (size_t)num_selection; i++) {
921 return num_unmatched;
926 const Xt_int selection_idx[],
927 int num_selection,
int positions[],
928 int single_match_only) {
930 INSTR_DEF(instr,
"idxsection_get_positions_of_indices_v2.part")
932 if (num_selection < 1)
return 0;
934 if (num_selection == 1)
939 Xt_int * temp_selection_idx = NULL;
940 const Xt_int *restrict sorted_selection_idx;
941 int * selection_pos = NULL;
944 for (i = 1; i < (size_t)num_selection; ++i)
945 if (selection_idx[i] < selection_idx[i-1])
948 sorted_selection_idx = selection_idx;
953 =
xmalloc((
size_t)num_selection *
sizeof(*temp_selection_idx));
954 memcpy(temp_selection_idx, selection_idx,
955 (
size_t)num_selection *
sizeof(*temp_selection_idx));
956 selection_pos =
xmalloc((
size_t)num_selection *
sizeof(*selection_pos));
959 sorted_selection_idx = temp_selection_idx;
984 if (!single_match_only) {
986 if (selection_pos == NULL) {
988 for (
size_t j = 0; i < (size_t)num_selection && j < num_body_indices; ++i) {
990 while(j < num_body_indices && body_indices[j] < sorted_selection_idx[i]) ++j;
992 if (j >= num_body_indices)
break;
994 positions[i] = (body_indices[j] == sorted_selection_idx[i])?(
int)j:-1;
998 for (
size_t j = 0; i < (size_t)num_selection && j < num_body_indices; ++i) {
1000 while(j < num_body_indices && body_indices[j] < sorted_selection_idx[i]) ++j;
1002 if (j >= num_body_indices)
break;
1004 positions[selection_pos[i]] = (body_indices[j] == sorted_selection_idx[i])?(
int)j:-1;
1009 Xt_int last_idx = (
Xt_int)(sorted_selection_idx[0] - 1);
1011 if (selection_pos == NULL) {
1013 for (
size_t j = 0; i < (size_t)num_selection && j < num_body_indices; ++i) {
1015 while(j < num_body_indices && body_indices[j] < sorted_selection_idx[i]) ++j;
1017 if (j >= num_body_indices)
break;
1019 positions[i] = ((last_idx == sorted_selection_idx[i]) ||
1020 (body_indices[j] != sorted_selection_idx[i]))?-1:(
int)j;
1022 last_idx = sorted_selection_idx[i];
1026 for (
size_t j = 0; i < (size_t)num_selection && j < num_body_indices; ++i) {
1028 while(j < num_body_indices && body_indices[j] < sorted_selection_idx[i]) ++j;
1030 if (j >= num_body_indices)
break;
1032 positions[selection_pos[i]] = ((last_idx == sorted_selection_idx[i]) ||
1033 (body_indices[j] != sorted_selection_idx[i]))?-1:(
int)j;
1035 last_idx = sorted_selection_idx[i];
1041 if (selection_pos == NULL)
1042 for (; i < (size_t)num_selection; ++i)
1045 for (; i < (size_t)num_selection; ++i)
1046 positions[selection_pos[i]] = -1;
1048 free(temp_selection_idx);
1049 free(selection_pos);
1051 int num_unmatched = 0;
1054 for (
size_t j = 0; j < (size_t)num_selection; ++j)
1055 num_unmatched += positions[j] == -1;
1058 return num_unmatched;
1063 int position_offset,
1070 size_t num_processed = 0;
1073 int abs_local_size = abs(dims[0].
local_size);
1086 if (dims[0].global_size < 0)
1087 tmp_local_start = (
Xt_int)(-dims[0].global_size - tmp_local_start -
1090 Xt_int min_index = (
Xt_int)(index_offset + tmp_local_start * abs_global_stride);
1093 while ((num_processed < num_indices)
1094 && (indices[num_processed] < min_index))
1095 positions[num_processed++] = -1;
1098 if ((dims[0].global_stride < 0) ^ (dims[0].
local_stride < 0)) {
1102 while ((num_processed < num_indices) &&
1103 ((curr_position = (
Xt_int)(indices[num_processed] - min_index)) <
1106 positions[num_processed++] = position_offset
1107 + (int)(abs_local_size - curr_position - 1);
1113 while ((num_processed < num_indices) &&
1114 ((curr_position = (
Xt_int)(indices[num_processed] - min_index)) <
1117 positions[num_processed++] = position_offset + (int)curr_position;
1123 while ((num_processed < num_indices) &&
1124 (indices[num_processed] < index_offset + abs_global_size))
1125 positions[num_processed++] = -1;
1135 if (dims[0].global_size < 0)
1136 tmp_local_start = (
Xt_int)(-dims[0].global_size - tmp_local_start -
1140 = (
Xt_int)(index_offset + tmp_local_start * abs_global_stride);
1143 while ((num_processed < num_indices)
1144 && (indices[num_processed] < min_index))
1145 positions[num_processed++] = -1;
1148 while (num_processed < num_indices) {
1150 Xt_int curr_global_position, curr_local_position;
1153 curr_global_position = (
Xt_int)((indices[num_processed] - index_offset) /
1157 if (curr_global_position >= tmp_local_start + abs_local_size)
1161 if ((dims[0].global_size < 0) ^ (dims[0].
local_size < 0))
1163 curr_local_position = (
Xt_int)(abs_local_size - curr_global_position
1164 + tmp_local_start - 1);
1166 curr_local_position = (
Xt_int)(curr_global_position - tmp_local_start);
1169 = (
Xt_int)(index_offset + curr_global_position * abs_global_stride);
1172 int position_offset_ = (int)(curr_local_position * abs_local_stride);
1175 curr_index_offset, position_offset_, indices + num_processed,
1176 num_indices - num_processed, positions + num_processed, ndim-1,
1181 return num_processed;
1186 const Xt_int *restrict selection_idx,
1188 int *restrict positions,
1189 int single_match_only) {
1191 INSTR_DEF(instr,
"idxsection_get_positions_of_indices_v3.part")
1192 INSTR_DEF(instr2,
"idxsection_get_positions_of_indices_recursive")
1196 if (num_selection < 1)
return 0;
1198 if (num_selection == 1)
1203 const Xt_int * restrict sorted_selection_idx;
1204 Xt_int *temp_selection_idx = NULL;
1205 int *sorted_positions;
1206 int *selection_pos = NULL;
1208 for (
size_t i = 1; i < (size_t)num_selection; ++i)
1209 if (selection_idx[i] < selection_idx[i-1])
1210 goto unsorted_selection;
1212 sorted_selection_idx = selection_idx;
1213 sorted_positions = positions;
1214 goto sorted_selection;
1218 =
xmalloc((
size_t)num_selection *
sizeof(*temp_selection_idx));
1220 =
xmalloc((
size_t)num_selection *
sizeof(*sorted_positions) * 2);
1221 selection_pos = sorted_positions + num_selection;
1222 memcpy(temp_selection_idx, selection_idx,
1223 (
size_t)num_selection *
sizeof(*temp_selection_idx));
1226 sorted_selection_idx = temp_selection_idx;
1231 size_t num_processed
1234 0, sorted_selection_idx, (
size_t)num_selection,
1235 sorted_positions, section->
ndim,
1241 for (
size_t i = num_processed; i < (size_t)num_selection; ++i)
1242 sorted_positions[i] = -1;
1245 if (single_match_only)
1246 for (
size_t i = 1; i < num_processed; ++i)
1247 if (sorted_selection_idx[i] == sorted_selection_idx[i-1])
1248 sorted_positions[i] = -1;
1251 if (sorted_selection_idx != selection_idx) {
1253 for (
size_t i = 0; i < (size_t)num_selection; ++i)
1254 positions[i] = sorted_positions[selection_pos[i]];
1256 free(sorted_positions);
1257 free(temp_selection_idx);
1261 size_t num_unmatched = (size_t)num_selection - num_processed;
1263 for (
size_t i = 0; i < num_processed; ++i)
1264 num_unmatched += positions[i] == -1;
1268 return (
int)num_unmatched;
1273 const Xt_int *selection_idx,
1274 int num_selection,
int * positions,
1275 int single_match_only) {
1277 INSTR_DEF(instr,
"idxsection_get_positions_of_indices")
1286 for (
int i = 0; i < section->
ndim; ++i)
1289 num_selection, positions,
1303 (((
size_t)num_section_indices *
sizeof(
Xt_int)
1304 <= (
size_t)128 * 1024U * 1024U)
1305 && ((
Xt_int)num_section_indices <= 1000 * num_selection))) {
1307 num_selection, positions,
1313 num_selection, positions,
1326 int * position,
int offset) {
1333 if (temp_position < offset)
1336 *position = temp_position;
Xt_idxlist xt_default_isect(Xt_idxlist idxlist_src, Xt_idxlist idxlist_dst)
int xt_idxlist_get_num_indices(Xt_idxlist idxlist)
static const struct xt_idxlist_vtable idxsection_vtable
Xt_int * index_array_cache
static MPI_Datatype dim_desc_dt
static int idxsection_get_positions_of_indices_v1(Xt_idxlist body_idxlist, const Xt_int selection_idx[], int num_selection, int positions[], int single_match_only)
add versions of standard API functions not returning on error
static int idxsection_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)
static size_t idxsection_get_pack_size(Xt_idxlist data, MPI_Comm comm)
static int idxsection_get_position_of_index_off(Xt_idxlist idxlist, Xt_int index, int *position, int offset)
Xt_idxlist xt_idxsection_new(Xt_int start, int num_dimensions, const Xt_int global_size[num_dimensions], const int local_size[num_dimensions], const Xt_int local_start[num_dimensions])
struct Xt_idxsection_ * Xt_idxsection
static void idxsection_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
static int idxsection_get_indices_any(Xt_int start_index, Xt_int *indices, int ndim, struct dim_desc dims[ndim])
Xt_idxlist xt_idxempty_new(void)
struct Xt_idxlist_ parent
static Xt_int idxsection_get_min_index(Xt_idxlist idxlist)
static size_t idxsection_get_positions_of_indices_recursive(Xt_int index_offset, int position_offset, const Xt_int indices[], size_t num_indices, int positions[], int ndim, struct dim_desc dims[ndim])
void xt_mergesort_index(Xt_int *val, int n, int *pos, int reset_pos)
#define xcalloc(nmemb, size)
static int idxsection_get_num_indices(Xt_idxsection section)
Provide non-public declarations common to all index lists.
Xt_int global_start_index
Xt_idxlist xt_idxsection_unpack(void *buffer, int buffer_size, int *position, MPI_Comm comm)
void xt_quicksort_index(Xt_int *v_idx, int n, int *v_pos, int reset_pos)
static void Xt_idxlist_init(Xt_idxlist idxlist, const struct xt_idxlist_vtable *vtable, int num_indices)
static int idxsection_get_positions_of_indices_v2(Xt_idxlist body_idxlist, const Xt_int selection_idx[], int num_selection, int positions[], int single_match_only)
void xt_idxsection_finalize(void)
void xt_mergesort_idxpos(idxpos_type *restrict v, size_t n)
static Xt_int idxsection_get_max_index(Xt_idxlist idxlist)
static Xt_int Xt_isign(Xt_int x)
static void idxsection_get_indices(Xt_idxlist idxlist, Xt_int *indices)
Xt_idxlist xt_idxvec_new(const Xt_int *idxlist, int num_indices)
void(* delete)(Xt_idxlist)
static const Xt_int * idxsection_get_indices_const(Xt_idxlist idxlist)
static int idxsection_get_positions_of_indices_v3(Xt_idxlist body_idxlist, const Xt_int *restrict selection_idx, int num_selection, int *restrict positions, int single_match_only)
static Xt_idxlist idxsection_copy(Xt_idxlist idxlist)
Xt_idxlist xt_idxsection_get_intersection_with_other_idxlist(Xt_idxlist src_idxsection, Xt_idxlist dst_idxlist)
static void idxsection_delete(Xt_idxlist data)
static int idxsection_get_positions_of_indices(Xt_idxlist body_idxlist, Xt_int const *selection_idx, int num_selection, int *positions, int single_match_only)
static int idxsection_get_position_of_index(Xt_idxlist idxlist, Xt_int index, int *position)
Xt_idxlist xt_idxsection_get_intersection(Xt_idxlist idxlist_src, Xt_idxlist idxlist_dst)
#define xt_mpi_call(call, comm)
const Xt_int * xt_idxlist_get_indices_const(Xt_idxlist idxlist)
static void idxsection_pack(Xt_idxlist data, void *buffer, int buffer_size, int *position, MPI_Comm comm)
void xt_idxsection_initialize(void)