75 #define MIN(a,b) (((a)<(b))?(a):(b)) 76 #define MAX(a,b) (((a)>(b))?(a):(b)) 115 int single_match_only);
123 int * position,
int offset);
142 .get_positions_of_indices = NULL,
145 .get_positions_of_indices_off = NULL,
148 .get_bounding_box = NULL,
159 MPI_Aint base_address, start_address, nstrides_address, stride_address;
161 MPI_Get_address(&stripe, &base_address);
162 MPI_Get_address(&stripe.
start, &start_address);
163 MPI_Get_address(&stripe.
stride, &stride_address);
164 MPI_Get_address(&stripe.
nstrides, &nstrides_address);
166 enum { num_stripe_dt_elems = 3 };
167 int block_lengths[num_stripe_dt_elems] = {1,1,1};
168 MPI_Aint displacements[num_stripe_dt_elems]
169 = {start_address - base_address,
170 stride_address - base_address,
171 nstrides_address - base_address };
175 xt_mpi_call(MPI_Type_create_struct(num_stripe_dt_elems,
176 block_lengths, displacements, types,
177 &stripe_dt_unaligned), Xt_default_comm);
178 xt_mpi_call(MPI_Type_create_resized(stripe_dt_unaligned, 0,
179 (MPI_Aint)
sizeof(stripe),
181 xt_mpi_call(MPI_Type_free(&stripe_dt_unaligned), Xt_default_comm);
226 return ((a->range.min > b->range.min) -
227 (a->range.min < b->range.min));
239 stripes_sort[0].range = stripe_range;
240 stripes_sort[0].position = 0;
241 min = stripe_range.
min;
242 max = stripe_range.
max;
244 size_t num_stripes = (size_t)idxstripes->
num_stripes;
245 long long num_indices = (
long long)stripes[0].nstrides;
246 int sign_err = stripes[0].nstrides;
247 int have_zero_stride = stripes[0].stride == 0;
248 for (
size_t i = 1; i < num_stripes; ++i) {
250 stripes_sort[i].range = stripe_range;
251 stripes_sort[i].position = (int)i;
252 min =
MIN(stripe_range.
min, min);
253 max =
MAX(stripe_range.
max, max);
254 num_indices += (
long long)stripes[i].nstrides;
255 sign_err |= stripes[i].nstrides;
256 have_zero_stride |= stripes[i].stride == 0;
260 static const char template[] =
"ERROR: %s called with invalid stripes";
261 size_t buf_size =
sizeof (
template) - 2 + strlen(caller);
263 snprintf(msg, buf_size,
template, caller);
266 assert(num_indices <= INT_MAX);
269 stripes_sort[stripes_sort[0].position].inv_position = 0;
270 int stripes_do_overlap = 0;
271 for (
size_t i = 1; i < num_stripes; ++i) {
273 |= stripes_sort[i - 1].range.max >= stripes_sort[i].range.min;
274 stripes_sort[stripes_sort[i].position].inv_position = (int)i;
293 if (num_stripes > 0) {
295 + (sizeof (struct Xt_stripes_sort)
296 * (size_t)num_stripes)
298 / sizeof (struct Xt_stripe))
299 *
sizeof (
struct Xt_stripe),
300 body_size =
sizeof (
struct Xt_stripe) * (size_t)num_stripes;
301 Xt_idxstripes idxstripes =
xmalloc(header_size + body_size);
302 idxstripes->num_stripes = num_stripes;
304 struct Xt_stripe *stripes_assign
305 = (
struct Xt_stripe *)(
void *)((
unsigned char *)idxstripes
307 idxstripes->stripes = stripes_assign;
308 memcpy(stripes_assign, stripes,
309 (
size_t)num_stripes *
sizeof(*stripes_assign));
325 if (num_stripes > 0) {
328 + (sizeof (struct Xt_stripes_sort)
329 * (size_t)num_stripes)
331 / sizeof (struct Xt_stripe))
332 *
sizeof (
struct Xt_stripe),
333 body_size =
sizeof (
struct Xt_stripe) * (size_t)num_stripes;
334 Xt_idxstripes idxstripes =
xrealloc(stripes, header_size + body_size);
335 struct Xt_stripe *stripes_moved
336 = (
struct Xt_stripe *)(
void *)((
unsigned char *)idxstripes + header_size);
338 memmove(stripes_moved, idxstripes,
sizeof (*stripes) * (
size_t)num_stripes);
339 idxstripes->stripes = stripes_moved;
340 idxstripes->num_stripes = num_stripes;
355 if (num_stripes > 0) {
357 + ((size_t)num_stripes
359 + sizeof (struct Xt_stripe) - 1)
360 / sizeof (struct Xt_stripe))
361 *
sizeof (
struct Xt_stripe);
362 Xt_idxstripes idxstripes =
xmalloc(header_size);
376 if (data == NULL)
return;
389 int size_header, size_stripes = 0;
391 xt_mpi_call(MPI_Pack_size(2, MPI_INT, comm, &size_header), comm);
394 &size_stripes), comm);
396 return (
size_t)size_header + (size_t)size_stripes;
410 buffer_size, position, comm), comm);
413 buffer_size, position, comm), comm);
416 buffer, buffer_size, position, comm), comm);
427 xt_mpi_call(MPI_Unpack(buffer, buffer_size, position,
428 &num_stripes, 1, MPI_INT, comm), comm);
433 + ((size_t)num_stripes
435 + sizeof (struct Xt_stripe) - 1)
436 / sizeof (struct Xt_stripe))
437 *
sizeof (
struct Xt_stripe),
438 body_size =
sizeof (
struct Xt_stripe) * (size_t)num_stripes;
439 Xt_idxstripes idxstripes =
xmalloc(header_size + body_size);
440 idxstripes->num_stripes = num_stripes;
442 struct Xt_stripe *stripes_assign
443 = (
struct Xt_stripe *)(
void *)((
unsigned char *)idxstripes
445 idxstripes->stripes = stripes_assign;
446 xt_mpi_call(MPI_Unpack(buffer, buffer_size, position, stripes_assign,
460 Xt_idxstripes idxstripes_dst) {
461 INSTR_DEF(instr,
"compute_intersection_fallback")
467 idxvec_from_stripes_src
470 idxvec_from_stripes_dst
477 idxvec_from_stripes_dst);
493 Xt_int t = 1, u = 1, v = 0, s = 0;
499 b = (
Xt_int)(prev_a - q * b);
502 s = (
Xt_int)(prev_u - q * s);
505 t = (
Xt_int)(prev_v - q * t);
519 INSTR_DEF(instr,
"get_stripe_intersection")
522 struct Xt_bounded_stripe {
523 Xt_int min, max, stride, representative;
526 struct Xt_bounded_stripe bsa, bsb, bsi;
528 Xt_int stride_zero_mask_a = (stripe_a.stride != 0) - 1,
529 stride_zero_mask_b = (stripe_b.stride != 0) - 1;
532 bsa.min = (
Xt_int)(stripe_a.start
533 + (mask & (stripe_a.stride * (stripe_a.nstrides - 1))));
534 bsa.max = (
Xt_int)(stripe_a.start
535 + (~mask & (stripe_a.stride * (stripe_a.nstrides - 1))));
537 bsa.representative = stripe_a.start;
540 bsb.min = (
Xt_int)(stripe_b.start
541 + (mask & (stripe_b.stride * (stripe_b.nstrides - 1))));
542 bsb.max = (
Xt_int)(stripe_b.start
543 + (~mask & (stripe_b.stride * (stripe_b.nstrides - 1))));
545 bsb.representative = stripe_b.start;
547 bsa.stride = (
Xt_int)((stripe_a.stride & ~stride_zero_mask_a)
548 | (stride_zero_mask_a & 1));
549 bsb.stride = (
Xt_int)((stripe_b.stride & ~stride_zero_mask_b)
550 | (stride_zero_mask_b & 1));
553 Xt_int abs_bsb_stride = XT_INT_ABS(bsb.stride);
554 long long start_diff = (
long long)stripe_a.start - (
long long)stripe_b.start;
556 = (
Xt_int)(bsb.representative
557 + (start_diff/abs_bsb_stride
558 + (start_diff%abs_bsb_stride > abs_bsb_stride/2))
561 bsi.min =
MAX(bsa.min, bsb.min);
562 bsi.max =
MIN(bsa.max, bsb.max);
565 long long temp_stride
566 = ((
long long)(XT_INT_ABS(bsa.stride)) * bsb.stride)/eg.
gcd;
567 bsi.stride = (
Xt_int)temp_stride;
574 = (
long long)bsa.representative
575 + ((
long long)(bsb.representative - bsa.representative) * eg.
u 576 * XT_INT_ABS(bsa.stride) / eg.
gcd);
578 long long abs_bsi_stride = llabs(temp_stride),
579 r_diff = bsi.min - temp,
580 steps = r_diff / abs_bsi_stride;
581 steps = steps + (steps * abs_bsi_stride < r_diff);
582 min_rep = temp + steps * abs_bsi_stride;
583 bsi.representative = (
Xt_int)min_rep;
585 int nstrides = (int)((bsi.max - min_rep)/temp_stride +
llsign(temp_stride));
587 = ((((bsb.representative - bsa.representative) % eg.
gcd) == 0)
588 & (bsi.stride == temp_stride || abs(nstrides) == 1));
590 int strides_mask = ~(((even_divide) & (bsi.min <= bsi.max)
591 & (min_rep <= bsi.max) & (min_rep >= bsi.min)) - 1);
593 = (
Xt_int)(min_rep + (nstrides -
llsign(temp_stride)) * bsi.stride);
595 intersection.
start = (
Xt_int)((bsa.stride >= 0) ? min_rep : max_rep);
599 = (abs(nstrides) & strides_mask
600 & ~((int)stride_zero_mask_a & (
int)stride_zero_mask_b))
601 | (stripe_b.nstrides & (int)stride_zero_mask_a & (
int)stride_zero_mask_b);
609 Xt_idxstripes idxstripes_dst) {
611 INSTR_DEF(instr,
"idxstripes_compute_intersection")
614 struct Xt_stripe *restrict inter_stripes = NULL;
615 size_t num_inter_stripes = 0;
616 size_t inter_stripes_array_size = 0;
620 *restrict dst_stripes_sort = idxstripes_dst->
stripes_sort;
622 *restrict stripes_dst = idxstripes_dst->
stripes;
624 size_t i_src = 0, i_dst = 0;
625 size_t num_stripes_src = (size_t)idxstripes_src->
num_stripes,
626 num_stripes_dst = (
size_t)idxstripes_dst->
num_stripes;
628 while ((i_src < num_stripes_src) &
629 (i_dst < num_stripes_dst)) {
631 while (i_src < num_stripes_src &&
633 < dst_stripes_sort[i_dst].range.min) ++i_src;
635 if ( i_src >= num_stripes_src )
break;
637 while (i_dst < num_stripes_dst &&
639 < src_stripes_sort[i_src].range.min) ++i_dst;
641 if ( i_dst >= num_stripes_dst )
break;
643 if ((src_stripes_sort[i_src].
range.
min 644 <= dst_stripes_sort[i_dst].range.max)
645 & (src_stripes_sort[i_src].range.max
646 >= dst_stripes_sort[i_dst].range.min)) {
648 num_inter_stripes+1);
651 inter_stripes[num_inter_stripes] = intersection_stripe =
653 stripes_dst[dst_stripes_sort[i_dst].position]);
654 num_inter_stripes += intersection_stripe.
nstrides > 0;
657 if (dst_stripes_sort[i_dst].
range.
max 658 < src_stripes_sort[i_src].range.max)
664 if (num_inter_stripes) {
666 struct Xt_stripe prev_stripe = inter_stripes[0];
667 if (prev_stripe.
stride < 0) {
673 inter_stripes[0] = prev_stripe;
675 for (
size_t i = 1; i < num_inter_stripes; ++i) {
676 struct Xt_stripe stripe = inter_stripes[i];
684 == (prev_stripe.
start 688 inter_stripes[j].nstrides = prev_stripe.
nstrides;
692 inter_stripes[++j] = stripe;
693 prev_stripe = stripe;
696 num_inter_stripes = j + 1;
712 idxstripes_dst = (Xt_idxstripes)idxlist_dst;
714 if ((idxstripes_src->
flags | idxstripes_dst->flags)
731 INSTR_DEF(instr,
"idxstripes_get_indices")
769 INSTR_DEF(instr,
"idxstripes_get_index_stripes")
775 size_t temp_stripes_array_size = 0;
776 size_t num_temp_stripes = 0;
778 for (
int i = 0; i < idxstripes->
num_stripes; ++i) {
787 temp_stripes[num_temp_stripes-1] = idxstripes->
stripes[i];
797 temp_stripes[num_temp_stripes].
start 800 temp_stripes[num_temp_stripes].
nstrides = 1;
801 temp_stripes[num_temp_stripes].
stride = 1;
808 *stripes =
xrealloc(temp_stripes, num_temp_stripes *
sizeof(*temp_stripes));
809 *num_stripes = (int)num_temp_stripes;
818 INSTR_DEF(instr,
"idxstripes_get_index_at_position")
825 if (position < 0)
goto fun_exit;
845 int num_pos,
Xt_int *index,
848 INSTR_DEF(instr,
"idxstripes_get_indices_at_positions")
857 int stripe_start_pos = 0;
861 for (
int ipos = 0; ipos < num_pos; ipos++) {
863 seek_pos = positions[ipos];
865 if (seek_pos < 0 || seek_pos > max_pos) {
866 index[ipos] = undef_idx;
871 while (seek_pos < stripe_start_pos) {
874 die(
"idxstripes_get_indices_at_positions: internal error:" 875 " crossed 0-boundary");
876 stripe_start_pos -= (int)stripes[istripe].
nstrides;
879 while (seek_pos > stripe_start_pos + stripes[istripe].
nstrides - 1) {
880 stripe_start_pos += (int)stripes[istripe].
nstrides;
883 die(
"idxstripes_get_indices_at_positions: internal error:" 884 " crossed boundary");
887 sub_pos = seek_pos - stripe_start_pos;
908 INSTR_DEF(instr,
"idxstripes_get_position_of_index_off")
916 Xt_int position_offset = 0;
918 while(i < stripes->num_stripes &&
927 if ((stripes->
stripes[i].
stride > 0 && index < stripes->stripes[i].start)
940 *position = (int)(rel_start/stripes->
stripes[i].
stride + position_offset);
956 size_t num_pos_exts_ = result->num_pos_ext,
957 size_pos_exts_ = result->size_pos_ext;
958 struct Xt_pos_ext *restrict pos_exts_ = result->pos_ext;
961 if (num_pos_exts_ + 1 == size_pos_exts_)
963 size_pos_exts_ += 16;
965 result->pos_ext = pos_exts_ = (
struct Xt_pos_ext *)
966 xrealloc(pos_exts_ - 1, (size_pos_exts_ + 1) *
sizeof (*pos_exts_)) + 1;
967 result->size_pos_ext = size_pos_exts_;
969 pos_exts_[num_pos_exts_] = pos_ext;
970 result->num_pos_ext = num_pos_exts_ + 1;
974 pos_exts_[num_pos_exts_ - 1].
size 975 =
isign(pos_ext.
start - pos_exts_[num_pos_exts_ - 1].start)
976 * (abs(pos_exts_[num_pos_exts_ - 1].
size) + abs(pos_ext.
size));
990 Xt_idxstripes idxstripes) {
991 const struct Xt_stripe *restrict stripes;
992 db->stripes = stripes = idxstripes->
stripes;
993 size_t num_db_stripes = (size_t)idxstripes->
num_stripes;
995 int *restrict db_stripes_nstrides_psum
997 *
sizeof (db->stripes_nstrides_psum[0]));
998 db_stripes_nstrides_psum[0] = 0;
999 for (
size_t j = 0; j < num_db_stripes; ++j) {
1000 db_stripes_nstrides_psum[j + 1]
1001 = db_stripes_nstrides_psum[j] + stripes[j].nstrides;
1004 db->num_stripes = num_db_stripes;
1005 db->stripes_nstrides_psum = db_stripes_nstrides_psum;
1011 free((
void *)db->stripes_nstrides_psum);
1020 static inline size_t 1025 size_t left = 0, right = n - 1;
1026 if ((a && n > 0)) ;
else return n;
1027 while (left < right)
1032 size_t m = (left + right + 1) / 2;
1041 return a[right].range.min <= min_key ? right : n;
1050 size_t num_db_stripes = db->num_stripes;
1051 const struct Xt_stripes_sort *restrict db_stripes_sort = db->stripes_sort;
1054 if (start_pos != num_db_stripes) {
1055 assert(db_stripes_sort[start_pos].
range.
min <= query_minmax.
max);
1056 size_t end_pos = start_pos;
1057 while (end_pos < num_db_stripes
1058 && db_stripes_sort[end_pos].
range.
min <= query_minmax.
max)
1062 size_t num_candidates;
1063 if (!db->stripes_do_overlap)
1065 while (start_pos > 0
1066 && (db_stripes_sort[start_pos - 1].
range.
max >= query_minmax.
min))
1068 num_candidates = end_pos - start_pos;
1069 if (candidates->
size < num_candidates) {
1072 * sizeof (candidates->
vec[0]));
1073 candidates->
size = num_candidates;
1075 candidates->
num = num_candidates;
1076 int *restrict candidates_vec = candidates->
vec;
1077 for (
size_t i = 0; i < num_candidates; ++i)
1078 candidates_vec[i] = db_stripes_sort[start_pos + i].
position;
1083 size_t min_candidate = start_pos;
1084 for (
size_t i = end_pos - 1; i != SIZE_MAX; --i)
1087 = ((db_stripes_sort[i].range.min <= query_minmax.
max)
1088 & (db_stripes_sort[i].
range.
max >= query_minmax.
min));
1089 num_candidates += predicate;
1090 size_t predicate_mask = predicate - 1;
1091 min_candidate = (min_candidate & predicate_mask)
1092 | (i & ~predicate_mask);
1094 if (candidates->
size < num_candidates + 1)
1097 (num_candidates + 1)
1098 * sizeof (candidates[0]));
1099 candidates->
size = num_candidates + 1;
1101 candidates->
num = num_candidates;
1102 int *restrict candidates_vec = candidates->
vec;
1104 for (
size_t i = min_candidate; i < end_pos; ++i) {
1105 candidates_vec[j] = db_stripes_sort[i].position;
1106 j += ((size_t)(db_stripes_sort[i].
range.
min <= query_minmax.
max)
1107 & (size_t)(db_stripes_sort[i].
range.
max >= query_minmax.
min));
1109 assert(j == num_candidates);
1113 candidates->
num = 0;
1120 size_t expansion = 0;
1122 expansion += stripes[i].stride == 0 ? (size_t)(stripes[i].nstrides - 1) : 0;
1124 struct Xt_stripe *restrict expanded_stripes
1125 =
xmalloc((num_stripes + expansion) *
sizeof (expanded_stripes[0]));
1127 for (
size_t i = 0; i < num_stripes; ++i) {
1129 if (stripe.
stride == 0) {
1130 for (
size_t k = 0; k < (size_t)stripe.
nstrides; ++k)
1136 expanded_stripes[j] = stripe;
1142 (
int)(num_stripes + expansion));
1152 bool single_match_only,
1153 size_t num_candidates,
1154 int *restrict candidates);
1160 const struct Xt_stripe stripes[num_stripes],
1163 int single_match_only)
1165 size_t unmatched = 0;
1169 if (num_stripes > 0)
1173 idxstripes->stripes);
1185 struct int_vec candidates = { .
size = 0, .vec = NULL };
1186 for (
size_t i = 0; i < (size_t)num_stripes; ++i) {
1196 query, &stripes_db, &result, &cover, single_match_only != 0,
1197 candidates.
num, candidates.
vec);
1198 }
while ((stripes[i].
stride == 0) & (--j > 0));
1200 free(candidates.
vec);
1209 free((
void *)idxstripes->stripes);
1214 return (
int)unmatched;
1223 size_t num_candidates,
1224 int *restrict candidates);
1238 bool single_match_only,
1239 size_t num_candidates,
1240 int *restrict candidates);
1248 bool single_match_only,
1249 size_t num_candidates,
1250 int *restrict candidates)
1252 size_t unmatched = 0;
1253 if (single_match_only)
1255 query, pos_ext2add, stripes_lookup, result, cover,
1256 num_candidates, candidates);
1270 bool single_match_only,
1271 size_t num_candidates,
1272 int *restrict candidates)
1274 size_t unmatched = 0;
1276 const struct Xt_stripe *restrict db_stripes = db->stripes;
1277 const int *restrict db_stripes_nstrides_psum = db->stripes_nstrides_psum;
1278 const struct Xt_stripes_sort *restrict db_stripes_sort = db->stripes_sort;
1279 for (
size_t j = 0; j < num_candidates; ++j) {
1280 size_t unsort_pos = (size_t)candidates[j];
1281 size_t sort_pos = (size_t)db_stripes_sort[unsort_pos].
inv_position;
1282 if ((query_minmax.
min <= db_stripes_sort[sort_pos].range.max)
1283 & (query_minmax.
max >= db_stripes_sort[sort_pos].range. min))
1287 struct Xt_stripe db_stripe = db_stripes[unsort_pos];
1291 & (stride == db_stripe.
stride)
1292 & ((query.
start - db_stripe.
start) % stride == 0)) {
1297 int skipLen = (int)((overlap_start - query.
start) /
stride);
1306 query_head, db, result, cover, single_match_only,
1307 num_candidates - j - 1, candidates + j + 1);
1313 = (int)((overlap_start - db_stripe.
start) /
stride);
1314 int overlap_nstrides
1320 .stride = overlap_nstrides > 1 ? query.
stride : (
Xt_int)1,
1323 = db_stripes_nstrides_psum[unsort_pos] + db_stripe_skip,
1324 .size = overlap_nstrides
1325 }, db, result, cover, single_match_only, num_candidates - j - 1,
1326 candidates + j + 1);
1328 if (!(query.
nstrides -= overlap_nstrides))
1329 goto search_finished;
1331 query.
start = (
Xt_int)(overlap_start + stride * overlap_nstrides);
1342 query, db, result, cover, single_match_only,
1343 num_candidates - j, candidates + j);
1346 goto search_finished;
1353 unmatched += (size_t)query.
nstrides;
1366 size_t num_candidates,
1367 int *restrict candidates)
1372 if (pos_ext2add.
size == -1)
1373 pos_ext2add.
size = 1;
1377 int pos_ext2add_s = pos_ext2add.
start 1378 + (querySizeMaskNeg & (pos_ext2add.
size + 1)),
1379 pos_ext2add_e = pos_ext2add.
start 1380 + (~querySizeMaskNeg & (pos_ext2add.
size - 1));
1382 = { .
start = pos_ext2add_s, .end = pos_ext2add_e };
1384 size_t overlap_pos =
1386 if (overlap_pos == SIZE_MAX) {
1390 struct Xt_pos_ext *restrict pos_exts_ = cover->pos_ext;
1392 db_s = pos_exts_[overlap_pos].start
1393 + (dbSizeMaskNeg & (pos_exts_[overlap_pos].size + 1)),
1394 db_e = pos_exts_[overlap_pos].start
1395 + (~dbSizeMaskNeg & (pos_exts_[overlap_pos].size - 1));
1397 int lowQuerySkip = db_s - pos_ext2add_s;
1398 int lowDbSkip = -lowQuerySkip;
1399 lowQuerySkip = (int)((
unsigned)(lowQuerySkip + abs(lowQuerySkip))/2);
1400 lowDbSkip = (int)((
unsigned)(lowDbSkip + abs(lowDbSkip))/2);
1401 int overlapLen =
MIN(db_e - db_s - lowDbSkip + 1,
1402 abs(pos_ext2add.
size) - lowQuerySkip);
1403 int highQuerySkip = abs(pos_ext2add.
size) - lowQuerySkip - overlapLen;
1406 int querySkipLen = (~querySizeMaskNeg & lowQuerySkip)
1407 | (querySizeMaskNeg & -highQuerySkip),
1408 queryTailLen = (querySizeMaskNeg & -lowQuerySkip)
1409 | (~querySizeMaskNeg & highQuerySkip);
1412 int absQuerySkipLen = abs(querySkipLen);
1420 .size = querySkipLen
1424 query_skip, pos_ext2add_skip, db,
1425 result, cover, num_candidates, candidates);
1426 pos_exts_ = result->pos_ext;
1428 + stride * (
Xt_int)absQuerySkipLen);
1431 pos_ext2add.
start += querySkipLen;
1432 pos_ext2add.
size -= querySkipLen;
1443 query_head, db, result, cover,
true,
1444 num_candidates, candidates);
1445 pos_exts_ = result->pos_ext;
1451 int directedOverlapLen = (~querySizeMaskNeg & overlapLen)
1452 | (querySizeMaskNeg & -overlapLen);
1453 pos_ext2add.
start += directedOverlapLen;
1454 pos_ext2add.
size -= directedOverlapLen;
1468 bool single_match_only,
1469 size_t num_candidates,
1470 int *restrict candidates)
1472 size_t unmatched = 0;
1473 const struct Xt_stripe *restrict db_stripes = db->stripes;
1474 size_t db_stripe_pos = (size_t)candidates[0];
1476 db_stripes[db_stripe_pos]);
1478 return (
struct unmatched_tail){ .unmatched = 0, .query_tail = query};
1486 .
nstrides = skipped}, db, result, cover,
1487 single_match_only, num_candidates - 1, candidates + 1);
1499 = (int)((overlap.
start - db_stripes[db_stripe_pos].start)
1500 / db_stripes[db_stripe_pos].stride);
1501 int db_pos = db->stripes_nstrides_psum[db_stripe_pos] + db_stripe_skip;
1503 & (overlap.
stride == db_stripes[db_stripe_pos].stride))
1509 db, result, cover, single_match_only, num_candidates - 1, candidates + 1);
1515 & (overlap.
stride == -db_stripes[db_stripe_pos].stride))
1521 db, result, cover, single_match_only,
1522 num_candidates - 1, candidates + 1);
1531 int db_step = (int)(overlap.
stride/db_stripes[db_stripe_pos].stride);
1534 for (
int i = 0; i < overlap.
nstrides; ++i, db_pos += db_step)
1537 (
struct Xt_pos_ext){ .start = db_pos, .size = 1 },
1538 db, result, cover, single_match_only,
1539 num_candidates - 1, candidates + 1);
1550 int stride_step = (int)(overlap.
stride / query.
stride);
1551 int db_step = (int)(overlap.
stride/db_stripes[db_stripe_pos].stride);
1558 .nstrides =
MIN(query.
nstrides - 1, stride_step - 1) };
1562 .
start = db_pos, .size = 1 },
1563 db, result, cover, single_match_only,
1564 num_candidates - 1, candidates + 1);
1569 intervening, db, result, cover, single_match_only,
1570 num_candidates - 1, candidates + 1);
1571 query.
nstrides -= intervening.nstrides;
1578 return (
struct unmatched_tail){ .unmatched = unmatched, .query_tail = query};
static size_t conditional_pos_ext_insert(struct Xt_stripe query, struct Xt_pos_ext pos_ext2add, const struct Xt_stripes_lookup *restrict db, struct Xt_pos_ext_vec *restrict result, struct Xt_pos_ext_vec *restrict cover, size_t num_candidates, int *restrict candidates)
static Xt_idxlist idxstripes_copy(Xt_idxlist idxlist)
Xt_idxlist xt_idxvec_from_stripes_new(const struct Xt_stripe *stripes, int num_stripes)
static void idxstripes_pack(Xt_idxlist data, void *buffer, int buffer_size, int *position, MPI_Comm comm)
const struct Xt_stripe * stripes
static struct Xt_stripe get_stripe_intersection(struct Xt_stripe stripe_a, struct Xt_stripe stripe_b)
struct Xt_idxlist_ parent
base definitions header file
static void append_ext(struct Xt_pos_ext pos_ext, struct Xt_pos_ext_vec *restrict result)
struct Xt_stripe query_tail
Xt_idxlist xt_idxstripes_from_idxlist_new(Xt_idxlist idxlist_src)
static struct Xt_idxstripes_ * expand_zero_stripes(size_t num_stripes, const struct Xt_stripe *restrict stripes)
static Xt_idxlist compute_intersection_fallback(Xt_idxstripes idxstripes_src, Xt_idxstripes idxstripes_dst)
static void idxstripes_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
struct Xt_stripes_sort stripes_sort[]
struct Xt_stripe_minmax range
static int imin(int a, int b)
Xt_idxlist xt_idxstripes_new(struct Xt_stripe const *stripes, int num_stripes)
Xt_idxlist xt_idxstripes_prealloc_new(const struct Xt_stripe *stripes, int num_stripes)
static MPI_Datatype stripe_dt
static Xt_int idxstripes_get_min_index(Xt_idxlist idxlist)
add versions of standard API functions not returning on error
static size_t bsearch_stripes_sort(size_t n, const struct Xt_stripes_sort a[n], Xt_int min_key)
Xt_idxlist xt_idxstripes_get_intersection(Xt_idxlist idxlist_src, Xt_idxlist idxlist_dst)
static struct extended_gcd extended_gcd(Xt_int a, Xt_int b)
void xt_idxlist_delete(Xt_idxlist idxlist)
const struct Xt_stripes_sort * stripes_sort
static void idxstripes_aggregate(Xt_idxstripes idxstripes, const char *caller)
struct Xt_pos_ext * pos_ext
void xt_idxlist_get_index_stripes(Xt_idxlist idxlist, struct Xt_stripe **stripes, int *num_stripes)
static void destroy_stripes_lookup(struct Xt_stripes_lookup *restrict db)
static int idxstripes_get_position_of_index(Xt_idxlist idxlist, Xt_int index, int *position)
static int idxstripes_get_position_of_index_off(Xt_idxlist idxlist, Xt_int index, int *position, int offset)
#define xrealloc(ptr, size)
const int * stripes_nstrides_psum
static int idxstripes_get_indices_at_positions(Xt_idxlist idxlist, const int *positions, int num, Xt_int *index, Xt_int undef_idx)
static size_t idxstripes_get_pos_exts_of_index_stripe(struct Xt_stripe query, const struct Xt_stripes_lookup *restrict db, struct Xt_pos_ext_vec *restrict result, struct Xt_pos_ext_vec *restrict cover, bool single_match_only, size_t num_candidates, int *restrict candidates)
Xt_idxlist xt_idxempty_new(void)
static const Xt_int * idxstripes_get_indices_const(Xt_idxlist idxlist)
static int idxstripes_get_pos_exts_of_index_stripes(Xt_idxlist idxlist, int num_stripes, const struct Xt_stripe *stripes, int *num_ext, struct Xt_pos_ext **pos_ext, int single_match_only)
Provide non-public declarations common to all index lists.
static size_t pos_ext_insert(struct Xt_stripe query, struct Xt_pos_ext pos_ext2add, const struct Xt_stripes_lookup *stripes_lookup, struct Xt_pos_ext_vec *restrict result, struct Xt_pos_ext_vec *restrict cover, bool single_match_only, size_t num_candidates, int *restrict candidates)
Xt_idxlist xt_idxstripes_unpack(void *buffer, int buffer_size, int *position, MPI_Comm comm)
static int isign_mask(int x)
static Xt_int Xt_isign_mask(Xt_int x)
struct Xt_idxlist_ * Xt_idxlist
static int compare_xtstripes(const void *a_, const void *b_)
static void Xt_idxlist_init(Xt_idxlist idxlist, const struct xt_idxlist_vtable *vtable, int num_indices)
#define ENSURE_ARRAY_SIZE(arrayp, curr_array_size, req_size)
static Xt_int Xt_isign(Xt_int x)
static const struct xt_idxlist_vtable idxstripes_vtable
static struct Xt_stripe_minmax xt_stripe2minmax(struct Xt_stripe stripe)
void(* delete)(Xt_idxlist)
static void create_stripes_lookup(struct Xt_stripes_lookup *restrict db, Xt_idxstripes idxstripes)
static void find_candidates(struct Xt_stripe query, const struct Xt_stripes_lookup *restrict db, struct int_vec *candidates)
void xt_idxstripes_initialize(void)
static Xt_int idxstripes_get_max_index(Xt_idxlist idxlist)
static Xt_idxlist idxstripes_compute_intersection(Xt_idxstripes idxstripes_src, Xt_idxstripes idxstripes_dst)
static long long llsign(long long x)
static int xt_pos_ext_is_appendable(struct Xt_pos_ext db_last, struct Xt_pos_ext to_append)
void xt_idxstripes_finalize(void)
#define xt_mpi_call(call, comm)
static size_t idxstripes_get_pack_size(Xt_idxlist data, MPI_Comm comm)
static void idxstripes_delete(Xt_idxlist data)
Xt_int * index_array_cache
static void idxstripes_get_indices(Xt_idxlist idxlist, Xt_int *indices)
static struct unmatched_tail idxstripes_complex_get_pos_exts_of_index_stripe(struct Xt_stripe query, const struct Xt_stripes_lookup *restrict stripes_lookup, struct Xt_pos_ext_vec *restrict result, struct Xt_pos_ext_vec *restrict cover, bool single_match_only, size_t num_candidates, int *restrict candidates)
void xt_cover_start(struct Xt_pos_ext_vec *restrict cover, size_t initial_size)
const struct Xt_stripe * stripes
struct Xt_idxstripes_ * Xt_idxstripes
void xt_cover_finish(struct Xt_pos_ext_vec *restrict cover)
void(* xt_sort_int)(int *a, size_t n)
size_t xt_cover_insert_or_overlap(struct Xt_pos_ext_vec *restrict cover, struct Xt_pos_range range, bool forward, size_t search_start_pos)
Xt_idxlist xt_idxlist_get_intersection(Xt_idxlist idxlist_src, Xt_idxlist idxlist_dst)
static int idxstripes_get_index_at_position(Xt_idxlist idxlist, int position, Xt_int *index)