deglib 0.2.4__tar.gz → 0.2.5__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. {deglib-0.2.4/src/deglib.egg-info → deglib-0.2.5}/PKG-INFO +1 -1
  2. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/fp32_ip.h +20 -14
  3. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/fp32_l2.h +20 -14
  4. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/int8_l2.h +28 -18
  5. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/uint8_l2.h +28 -18
  6. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/__init__.py +1 -1
  7. {deglib-0.2.4 → deglib-0.2.5/src/deglib.egg-info}/PKG-INFO +1 -1
  8. {deglib-0.2.4 → deglib-0.2.5}/tests/test_builder.py +28 -0
  9. {deglib-0.2.4 → deglib-0.2.5}/CMakeLists.txt +0 -0
  10. {deglib-0.2.4 → deglib-0.2.5}/LICENSE +0 -0
  11. {deglib-0.2.4 → deglib-0.2.5}/MANIFEST.in +0 -0
  12. {deglib-0.2.4 → deglib-0.2.5}/README.md +0 -0
  13. {deglib-0.2.4 → deglib-0.2.5}/lib/CMakeLists.txt +0 -0
  14. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/CMakeLists.txt +0 -0
  15. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/benchmark.h +0 -0
  16. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/build.h +0 -0
  17. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/dataset.h +0 -0
  18. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/file_io.h +0 -0
  19. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/logging.h +0 -0
  20. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/repository.h +0 -0
  21. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/stats.h +0 -0
  22. {deglib-0.2.4 → deglib-0.2.5}/lib/bench/include/stopwatch.h +0 -0
  23. {deglib-0.2.4 → deglib-0.2.5}/lib/cmake_modules/DetectCPUFeatures.cmake +0 -0
  24. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/CMakeLists.txt +0 -0
  25. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/analysis.h +0 -0
  26. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/builder.h +0 -0
  27. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/concurrent.h +0 -0
  28. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/config.h +0 -0
  29. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/deglib.h +0 -0
  30. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/evp_ip.h +0 -0
  31. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/fp16.h +0 -0
  32. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/fp16_ip.h +0 -0
  33. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/fp16_l2.h +0 -0
  34. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/fp32.h +0 -0
  35. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/int8.h +0 -0
  36. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/int8_ip.h +0 -0
  37. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/residual_mode.h +0 -0
  38. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/uint8.h +0 -0
  39. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distance/uint8_ip.h +0 -0
  40. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/distances.h +0 -0
  41. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/filter.h +0 -0
  42. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph/dynamic_graph.h +0 -0
  43. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph/internal_graph.h +0 -0
  44. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph/intrusive_list.h +0 -0
  45. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph/mutable_graph.h +0 -0
  46. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph/readonly_graph.h +0 -0
  47. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph/sizebounded_graph.h +0 -0
  48. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph/visited_list_pool.h +0 -0
  49. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/graph.h +0 -0
  50. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization/flas/fast_linear_assignment_sorter.h +0 -0
  51. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization/flas/fast_linear_assignment_sorter_mt.h +0 -0
  52. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization/flas/junker_volgenant_solver.h +0 -0
  53. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization/pruning.h +0 -0
  54. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization/quantization/evp_quantize.h +0 -0
  55. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization/quantization/scalar_quantize.h +0 -0
  56. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization/transform.h +0 -0
  57. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/optimization.h +0 -0
  58. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/search/searcher.h +0 -0
  59. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/search.h +0 -0
  60. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/utils/cpu.h +0 -0
  61. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/utils/memory.h +0 -0
  62. {deglib-0.2.4 → deglib-0.2.5}/lib/deglib/include/deglib/utils/random.h +0 -0
  63. {deglib-0.2.4 → deglib-0.2.5}/lib/test/CMakeLists.txt +0 -0
  64. {deglib-0.2.4 → deglib-0.2.5}/lib/test/src/common/test_helpers.h +0 -0
  65. {deglib-0.2.4 → deglib-0.2.5}/pyproject.toml +0 -0
  66. {deglib-0.2.4 → deglib-0.2.5}/setup.cfg +0 -0
  67. {deglib-0.2.4 → deglib-0.2.5}/setup.py +0 -0
  68. {deglib-0.2.4 → deglib-0.2.5}/src/deg_cpp/deglib_cpp.cpp +0 -0
  69. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/analysis.py +0 -0
  70. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/builder.py +0 -0
  71. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/cpu.py +0 -0
  72. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/distances.py +0 -0
  73. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/graph.py +0 -0
  74. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/optimization.py +0 -0
  75. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/search.py +0 -0
  76. {deglib-0.2.4 → deglib-0.2.5}/src/deglib/utils.py +0 -0
  77. {deglib-0.2.4 → deglib-0.2.5}/src/deglib.egg-info/SOURCES.txt +0 -0
  78. {deglib-0.2.4 → deglib-0.2.5}/src/deglib.egg-info/dependency_links.txt +0 -0
  79. {deglib-0.2.4 → deglib-0.2.5}/src/deglib.egg-info/requires.txt +0 -0
  80. {deglib-0.2.4 → deglib-0.2.5}/src/deglib.egg-info/top_level.txt +0 -0
  81. {deglib-0.2.4 → deglib-0.2.5}/tests/test_analysis.py +0 -0
  82. {deglib-0.2.4 → deglib-0.2.5}/tests/test_filter.py +0 -0
  83. {deglib-0.2.4 → deglib-0.2.5}/tests/test_graph.py +0 -0
  84. {deglib-0.2.4 → deglib-0.2.5}/tests/test_presort.py +0 -0
  85. {deglib-0.2.4 → deglib-0.2.5}/tests/test_rerank.py +0 -0
  86. {deglib-0.2.4 → deglib-0.2.5}/tests/test_scalar_quantizer.py +0 -0
  87. {deglib-0.2.4 → deglib-0.2.5}/tests/test_searcher.py +0 -0
  88. {deglib-0.2.4 → deglib-0.2.5}/tests/test_transform.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deglib
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: Python bindings for the Dynamic Exploration Graph library by Nico Hezel
5
5
  Author: Nico Hezel
6
6
  Author-email: Bruno Schilling <bruno.schilling@htw-berlin.de>
@@ -143,17 +143,20 @@ class InnerProductFloat_AVX512 {
143
143
  }
144
144
 
145
145
  if constexpr (HasDualSimd) {
146
- const size_t nc16 = dim / 16;
147
- offset = nc16 * 16;
146
+ const size_t nc32 = dim / 32;
147
+ offset = nc32 * 32;
148
148
 
149
- for (size_t c = 0; c < nc16; ++c) {
150
- size_t idx = c * 16;
151
- __m512 q_vec = _mm512_loadu_ps(&query[idx]);
149
+ for (size_t c = 0; c < nc32; ++c) {
150
+ size_t idx = c * 32;
151
+ __m512 q_vec_lo = _mm512_loadu_ps(&query[idx]);
152
+ __m512 q_vec_hi = _mm512_loadu_ps(&query[idx + 16]);
152
153
 
153
154
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
154
155
  const float* db_ = static_cast<const float*>(db[j]);
155
- __m512 db_vec = _mm512_loadu_ps(&db_[idx]);
156
- s[j] = _mm512_fmadd_ps(q_vec, db_vec, s[j]);
156
+ __m512 db_vec_lo = _mm512_loadu_ps(&db_[idx]);
157
+ __m512 db_vec_hi = _mm512_loadu_ps(&db_[idx + 16]);
158
+ s[j] = _mm512_fmadd_ps(q_vec_lo, db_vec_lo, s[j]);
159
+ s[j] = _mm512_fmadd_ps(q_vec_hi, db_vec_hi, s[j]);
157
160
  }
158
161
  }
159
162
  }
@@ -265,17 +268,20 @@ class InnerProductFloat_AVX2 {
265
268
  }
266
269
 
267
270
  if constexpr (HasDualSimd) {
268
- const size_t nc8 = dim / 8;
269
- offset = nc8 * 8;
271
+ const size_t nc16 = dim / 16;
272
+ offset = nc16 * 16;
270
273
 
271
- for (size_t c = 0; c < nc8; ++c) {
272
- size_t idx = c * 8;
273
- __m256 q_vec = _mm256_loadu_ps(&query[idx]);
274
+ for (size_t c = 0; c < nc16; ++c) {
275
+ size_t idx = c * 16;
276
+ __m256 q_vec_lo = _mm256_loadu_ps(&query[idx]);
277
+ __m256 q_vec_hi = _mm256_loadu_ps(&query[idx + 8]);
274
278
 
275
279
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
276
280
  const float* db_ = static_cast<const float*>(db[j]);
277
- __m256 db_vec = _mm256_loadu_ps(&db_[idx]);
278
- s[j] = _mm256_fmadd_ps(q_vec, db_vec, s[j]);
281
+ __m256 db_vec_lo = _mm256_loadu_ps(&db_[idx]);
282
+ __m256 db_vec_hi = _mm256_loadu_ps(&db_[idx + 8]);
283
+ s[j] = _mm256_fmadd_ps(q_vec_lo, db_vec_lo, s[j]);
284
+ s[j] = _mm256_fmadd_ps(q_vec_hi, db_vec_hi, s[j]);
279
285
  }
280
286
  }
281
287
  }
@@ -142,17 +142,20 @@ class L2Float_AVX512 {
142
142
  }
143
143
 
144
144
  if constexpr (HasDualSimd) {
145
- const size_t nc16 = dim / 16;
146
- offset = nc16 * 16;
145
+ const size_t nc32 = dim / 32;
146
+ offset = nc32 * 32;
147
147
 
148
- for (size_t c = 0; c < nc16; ++c) {
149
- size_t idx = c * 16;
150
- __m512 q_vec = _mm512_loadu_ps(&query[idx]);
148
+ for (size_t c = 0; c < nc32; ++c) {
149
+ size_t idx = c * 32;
150
+ __m512 q_vec_lo = _mm512_loadu_ps(&query[idx]);
151
+ __m512 q_vec_hi = _mm512_loadu_ps(&query[idx + 16]);
151
152
 
152
153
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
153
154
  const float* db_ = static_cast<const float*>(db[j]);
154
- __m512 diff = _mm512_sub_ps(q_vec, _mm512_loadu_ps(&db_[idx]));
155
- s[j] = _mm512_fmadd_ps(diff, diff, s[j]);
155
+ __m512 diff_lo = _mm512_sub_ps(q_vec_lo, _mm512_loadu_ps(&db_[idx]));
156
+ __m512 diff_hi = _mm512_sub_ps(q_vec_hi, _mm512_loadu_ps(&db_[idx + 16]));
157
+ s[j] = _mm512_fmadd_ps(diff_lo, diff_lo, s[j]);
158
+ s[j] = _mm512_fmadd_ps(diff_hi, diff_hi, s[j]);
156
159
  }
157
160
  }
158
161
  }
@@ -264,17 +267,20 @@ class L2Float_AVX2 {
264
267
  }
265
268
 
266
269
  if constexpr (HasDualSimd) {
267
- const size_t nc8 = dim / 8;
268
- offset = nc8 * 8;
270
+ const size_t nc16 = dim / 16;
271
+ offset = nc16 * 16;
269
272
 
270
- for (size_t c = 0; c < nc8; ++c) {
271
- size_t idx = c * 8;
272
- __m256 q_vec = _mm256_loadu_ps(&query[idx]);
273
+ for (size_t c = 0; c < nc16; ++c) {
274
+ size_t idx = c * 16;
275
+ __m256 q_vec_lo = _mm256_loadu_ps(&query[idx]);
276
+ __m256 q_vec_hi = _mm256_loadu_ps(&query[idx + 8]);
273
277
 
274
278
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
275
279
  const float* db_ = static_cast<const float*>(db[j]);
276
- __m256 diff = _mm256_sub_ps(q_vec, _mm256_loadu_ps(&db_[idx]));
277
- s[j] = _mm256_fmadd_ps(diff, diff, s[j]);
280
+ __m256 diff_lo = _mm256_sub_ps(q_vec_lo, _mm256_loadu_ps(&db_[idx]));
281
+ __m256 diff_hi = _mm256_sub_ps(q_vec_hi, _mm256_loadu_ps(&db_[idx + 8]));
282
+ s[j] = _mm256_fmadd_ps(diff_lo, diff_lo, s[j]);
283
+ s[j] = _mm256_fmadd_ps(diff_hi, diff_hi, s[j]);
278
284
  }
279
285
  }
280
286
  }
@@ -169,19 +169,24 @@ class L2Int8_AVX512 {
169
169
  }
170
170
 
171
171
  if constexpr (HasDualSimd) {
172
- const size_t nc32 = dim / 32;
173
- offset = nc32 * 32;
172
+ const size_t nc64 = dim / 64;
173
+ offset = nc64 * 64;
174
174
 
175
- for (size_t c = 0; c < nc32; ++c) {
176
- size_t idx = c * 32;
177
- __m256i q_raw = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&query[idx]));
178
- __m512i q_vec = _mm512_cvtepi8_epi16(q_raw);
175
+ for (size_t c = 0; c < nc64; ++c) {
176
+ size_t idx = c * 64;
177
+ __m256i q_raw_lo = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&query[idx]));
178
+ __m256i q_raw_hi = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&query[idx + 32]));
179
+ __m512i q_vec_lo = _mm512_cvtepi8_epi16(q_raw_lo);
180
+ __m512i q_vec_hi = _mm512_cvtepi8_epi16(q_raw_hi);
179
181
 
180
182
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
181
183
  const int8_t* db_ = static_cast<const int8_t*>(db[j]);
182
- __m256i r_raw = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&db_[idx]));
183
- __m512i diff = _mm512_sub_epi16(q_vec, _mm512_cvtepi8_epi16(r_raw));
184
- s[j] = _mm512_add_epi32(s[j], _mm512_madd_epi16(diff, diff));
184
+ __m256i r_raw_lo = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&db_[idx]));
185
+ __m256i r_raw_hi = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&db_[idx + 32]));
186
+ __m512i diff_lo = _mm512_sub_epi16(q_vec_lo, _mm512_cvtepi8_epi16(r_raw_lo));
187
+ __m512i diff_hi = _mm512_sub_epi16(q_vec_hi, _mm512_cvtepi8_epi16(r_raw_hi));
188
+ s[j] = _mm512_add_epi32(s[j], _mm512_madd_epi16(diff_lo, diff_lo));
189
+ s[j] = _mm512_add_epi32(s[j], _mm512_madd_epi16(diff_hi, diff_hi));
185
190
  }
186
191
  }
187
192
  }
@@ -290,19 +295,24 @@ class L2Int8_AVX2 {
290
295
  }
291
296
 
292
297
  if constexpr (HasDualSimd) {
293
- const size_t nc16 = dim / 16;
294
- offset = nc16 * 16;
298
+ const size_t nc32 = dim / 32;
299
+ offset = nc32 * 32;
295
300
 
296
- for (size_t c = 0; c < nc16; ++c) {
297
- size_t idx = c * 16;
298
- __m128i q_raw = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&query[idx]));
299
- __m256i q_vec = _mm256_cvtepi8_epi16(q_raw);
301
+ for (size_t c = 0; c < nc32; ++c) {
302
+ size_t idx = c * 32;
303
+ __m128i q_raw_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&query[idx]));
304
+ __m128i q_raw_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&query[idx + 16]));
305
+ __m256i q_vec_lo = _mm256_cvtepi8_epi16(q_raw_lo);
306
+ __m256i q_vec_hi = _mm256_cvtepi8_epi16(q_raw_hi);
300
307
 
301
308
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
302
309
  const int8_t* db_ = static_cast<const int8_t*>(db[j]);
303
- __m128i r_raw = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&db_[idx]));
304
- __m256i diff = _mm256_sub_epi16(q_vec, _mm256_cvtepi8_epi16(r_raw));
305
- s[j] = _mm256_add_epi32(s[j], _mm256_madd_epi16(diff, diff));
310
+ __m128i r_raw_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&db_[idx]));
311
+ __m128i r_raw_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&db_[idx + 16]));
312
+ __m256i diff_lo = _mm256_sub_epi16(q_vec_lo, _mm256_cvtepi8_epi16(r_raw_lo));
313
+ __m256i diff_hi = _mm256_sub_epi16(q_vec_hi, _mm256_cvtepi8_epi16(r_raw_hi));
314
+ s[j] = _mm256_add_epi32(s[j], _mm256_madd_epi16(diff_lo, diff_lo));
315
+ s[j] = _mm256_add_epi32(s[j], _mm256_madd_epi16(diff_hi, diff_hi));
306
316
  }
307
317
  }
308
318
  }
@@ -173,19 +173,24 @@ class L2Uint8_AVX512 {
173
173
  }
174
174
 
175
175
  if constexpr (HasDualSimd) {
176
- const size_t nc32 = dim / 32;
177
- offset = nc32 * 32;
176
+ const size_t nc64 = dim / 64;
177
+ offset = nc64 * 64;
178
178
 
179
- for (size_t c = 0; c < nc32; ++c) {
180
- size_t idx = c * 32;
181
- __m256i q_raw = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&query[idx]));
182
- __m512i q_vec = _mm512_cvtepu8_epi16(q_raw);
179
+ for (size_t c = 0; c < nc64; ++c) {
180
+ size_t idx = c * 64;
181
+ __m256i q_raw_lo = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&query[idx]));
182
+ __m256i q_raw_hi = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&query[idx + 32]));
183
+ __m512i q_vec_lo = _mm512_cvtepu8_epi16(q_raw_lo);
184
+ __m512i q_vec_hi = _mm512_cvtepu8_epi16(q_raw_hi);
183
185
 
184
186
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
185
187
  const unsigned char* db_ = static_cast<const unsigned char*>(db[j]);
186
- __m256i r_raw = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&db_[idx]));
187
- __m512i diff = _mm512_sub_epi16(q_vec, _mm512_cvtepu8_epi16(r_raw));
188
- s[j] = _mm512_add_epi32(s[j], _mm512_madd_epi16(diff, diff));
188
+ __m256i r_raw_lo = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&db_[idx]));
189
+ __m256i r_raw_hi = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(&db_[idx + 32]));
190
+ __m512i diff_lo = _mm512_sub_epi16(q_vec_lo, _mm512_cvtepu8_epi16(r_raw_lo));
191
+ __m512i diff_hi = _mm512_sub_epi16(q_vec_hi, _mm512_cvtepu8_epi16(r_raw_hi));
192
+ s[j] = _mm512_add_epi32(s[j], _mm512_madd_epi16(diff_lo, diff_lo));
193
+ s[j] = _mm512_add_epi32(s[j], _mm512_madd_epi16(diff_hi, diff_hi));
189
194
  }
190
195
  }
191
196
  }
@@ -294,19 +299,24 @@ class L2Uint8_AVX2 {
294
299
  }
295
300
 
296
301
  if constexpr (HasDualSimd) {
297
- const size_t nc16 = dim / 16;
298
- offset = nc16 * 16;
302
+ const size_t nc32 = dim / 32;
303
+ offset = nc32 * 32;
299
304
 
300
- for (size_t c = 0; c < nc16; ++c) {
301
- size_t idx = c * 16;
302
- __m128i q_raw = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&query[idx]));
303
- __m256i q_vec = _mm256_cvtepu8_epi16(q_raw);
305
+ for (size_t c = 0; c < nc32; ++c) {
306
+ size_t idx = c * 32;
307
+ __m128i q_raw_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&query[idx]));
308
+ __m128i q_raw_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&query[idx + 16]));
309
+ __m256i q_vec_lo = _mm256_cvtepu8_epi16(q_raw_lo);
310
+ __m256i q_vec_hi = _mm256_cvtepu8_epi16(q_raw_hi);
304
311
 
305
312
  for (size_t j = 0; j < BATCH_SIZE; ++j) {
306
313
  const unsigned char* db_ = static_cast<const unsigned char*>(db[j]);
307
- __m128i r_raw = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&db_[idx]));
308
- __m256i diff = _mm256_sub_epi16(q_vec, _mm256_cvtepu8_epi16(r_raw));
309
- s[j] = _mm256_add_epi32(s[j], _mm256_madd_epi16(diff, diff));
314
+ __m128i r_raw_lo = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&db_[idx]));
315
+ __m128i r_raw_hi = _mm_loadu_si128(reinterpret_cast<const __m128i*>(&db_[idx + 16]));
316
+ __m256i diff_lo = _mm256_sub_epi16(q_vec_lo, _mm256_cvtepu8_epi16(r_raw_lo));
317
+ __m256i diff_hi = _mm256_sub_epi16(q_vec_hi, _mm256_cvtepu8_epi16(r_raw_hi));
318
+ s[j] = _mm256_add_epi32(s[j], _mm256_madd_epi16(diff_lo, diff_lo));
319
+ s[j] = _mm256_add_epi32(s[j], _mm256_madd_epi16(diff_hi, diff_hi));
310
320
  }
311
321
  }
312
322
  }
@@ -20,7 +20,7 @@ from .graph import (
20
20
  )
21
21
  from .distances import FloatSpace, Metric
22
22
 
23
- __version__ = "0.2.4"
23
+ __version__ = "0.2.5"
24
24
 
25
25
  __all__ = [
26
26
  "DynamicExplorationGraph",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: deglib
3
- Version: 0.2.4
3
+ Version: 0.2.5
4
4
  Summary: Python bindings for the Dynamic Exploration Graph library by Nico Hezel
5
5
  Author: Nico Hezel
6
6
  Author-email: Bruno Schilling <bruno.schilling@htw-berlin.de>
@@ -221,3 +221,31 @@ class TestGraphs:
221
221
  assert status.deleted > 0
222
222
  assert len(status.total_added_ids) == self.data.shape[0]
223
223
  assert len(status.total_deleted_ids) > 0
224
+
225
+ @pytest.mark.parametrize("dim", [48, 80, 100, 784])
226
+ @pytest.mark.parametrize("metric", [Metric.FP32_L2, Metric.FP32_InnerProduct])
227
+ def test_build_unaligned_dimensions(self, dim, metric):
228
+ samples = 60
229
+ edges_per_vertex = 16
230
+ np.random.seed(42)
231
+ data = np.random.random((samples, dim)).astype(np.float32)
232
+ if metric == Metric.FP32_InnerProduct:
233
+ data = data / np.linalg.norm(data, axis=1, keepdims=True)
234
+
235
+ graph = deglib.create_empty(samples, FloatSpace.create(dim, metric), edges_per_vertex)
236
+ builder = deglib.GraphBuilder(
237
+ graph,
238
+ extend_k=32,
239
+ extend_eps=0.1,
240
+ optimization_target=deglib.builder.OptimizationTarget.LowLID if metric == Metric.FP32_L2 else deglib.builder.OptimizationTarget.HighLID,
241
+ )
242
+ builder.add_entry(range(samples), data)
243
+ status = builder.build()
244
+ assert status.added == samples
245
+ assert graph.size() == samples
246
+
247
+ # Verify search works and returns valid neighbors
248
+ res = graph.search(data[0], k=10, eps=0.1)
249
+ indices, dists = res
250
+ assert len(indices) == 10
251
+ assert not np.isnan(dists).any()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes