MCPcopy Create free account
hub / github.com/dblalock/bolt / byte_dists_vertical

Function byte_dists_vertical

cpp/src/quantize/multi_codebook.hpp:765–806  ·  view source on GitHub ↗

block size, number of dimensions of each vector

Source from the content-addressed store, hash-verified

763
764template<int B, int D> // block size, number of dimensions of each vector
765inline void byte_dists_vertical(const uint8_t* X, const uint8_t* q,
766 uint16_t* dists_out, int64_t N)
767{
768 static constexpr int packet_width = 32; // how many vecs we operate on at once
769 static constexpr int nstripes = B / packet_width; // # of rows of 32B per block
770 static_assert(B % packet_width == 0, "B must be a multiple of packet_width");
771 static_assert(B > 0, "B must be > 0");
772 const int64_t nblocks = N / B * 2;
773 assert(N % B == 0);
774
775 // we assume that pairs of bytes are from the same vector for our
776 // maddubs; so pretending q points to int16s makes broadcasting pairs work
777 const uint16_t* q16 = reinterpret_cast<const uint16_t*>(q);
778
779 __m256i accumulators[nstripes];
780
781 for (int64_t b = 0; b < nblocks; b++) { // for each block
782 for (int i = 0; i < nstripes; i++) {
783 accumulators[i] = _mm256_setzero_si256(); // zero dists
784 }
785 for (int j = 0; j < D / 2; j++) { // for each pair of dimensions
786 auto q_broadcast = _mm256_set1_epi16(q16[j]);
787 for (int i = 0; i < nstripes; i++) { // for each stripe
788 // auto x_col = _mm256_load_si256((__m256i*)X);
789 auto x_col = stream_load_si256i((__m256i*)X);
790 X += packet_width;
791
792 auto diffs = _mm256_sub_epi8(q_broadcast, x_col);
793 auto abs_diffs = _mm256_abs_epi8(diffs);
794 auto prods = _mm256_maddubs_epi16(abs_diffs, abs_diffs);
795 accumulators[i] = _mm256_adds_epi16(accumulators[i], prods);
796 }
797 }
798 for (uint8_t i = 0; i < nstripes; i++) { // for each stripe
799 _mm256_store_si256((__m256i*)dists_out, accumulators[i]);
800 // we compute 16 dists because we assume that adjacent pairs of
801 // bytes belong to the same vector; this is necessary for the
802 // maddubs to be meaningful
803 dists_out += packet_width / 2;
804 }
805 }
806}
807
808// just sums up the inputs and stores results; upper bound on how fast
809// any of these functions could be

Callers

nothing calls this directly

Calls 1

stream_load_si256iFunction · 0.85

Tested by

no test coverage detected