Skip to content

Instantly share code, notes, and snippets.

@serge-sans-paille
Created December 19, 2018 07:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save serge-sans-paille/c6ee5a7e4f38ca8846992aa5d56765c2 to your computer and use it in GitHub Desktop.
Save serge-sans-paille/c6ee5a7e4f38ca8846992aa5d56765c2 to your computer and use it in GitHub Desktop.
argmin + xsimd
using vT = xsimd::simd_type<T>;
using iT = xsimd::as_integer_t<T>;
static const size_t vN = vT::size;
const long n = elts.size();
if(n >= std::numeric_limits<iT>::max()) {
return _argminmax_seq<Op>(elts, minmax_elts);
}
auto viter = types::vectorizer_nobroadcast::vbegin(elts),
vend = types::vectorizer_nobroadcast::vend(elts);
const long bound = std::distance(viter, vend);
long minmax_index = -1;
if (bound > 0) {
auto vacc = *viter;
iT iota[vN] = {0};
for (long i = 0; i < vN; ++i)
iota[i] = i;
auto curr = xsimd::load_unaligned(iota);
xsimd::simd_type<iT> indices = curr;
xsimd::simd_type<iT> step{vN};
for (++viter; viter != vend; ++viter) {
curr += step;
auto c = *viter;
vacc = typename Op::op{}(vacc, c);
auto mask = c == vacc;
indices = xsimd::select(xsimd::bool_cast(mask), curr, indices);
}
alignas(sizeof(vT)) T stored[vN];
vacc.store_aligned(&stored[0]);
alignas(sizeof(vT)) long indexed[vN];
indices.store_aligned(&indexed[0]);
for (size_t j = 0; j < vN; ++j) {
if (Op::value(stored[j], minmax_elts)) {
minmax_elts = stored[j];
minmax_index = indexed[j];
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment