-
Notifications
You must be signed in to change notification settings - Fork 32
Separate query and storage alignment requirements [MOD-13837] #946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
1aa94b7
a62aefc
7d45514
fc1fe28
b9f8af9
fb292c3
509adcb
ca816e3
c6443af
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,23 +70,32 @@ dist_func_t<float> IP_SQ8_FP32_GetDistFunc(size_t dim, unsigned char *alignment, | |
| if (dim < 16) { | ||
| return ret_dist_func; | ||
| } | ||
| // Alignment hints below refer to the SQ8 (first) operand per the GetDistFunc contract. | ||
| #ifdef OPT_AVX512_F_BW_VL_VNNI | ||
| if (features.avx512f && features.avx512bw && features.avx512vnni) { | ||
| if (dim % 16 == 0) // SQ8 chunk = 16 bytes | ||
| *alignment = 16 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_IP_implementation_AVX512F_BW_VL_VNNI(dim); | ||
| } | ||
| #endif | ||
| #ifdef OPT_AVX2_FMA | ||
| if (features.avx2 && features.fma3) { | ||
| if (dim % 8 == 0) // SQ8 chunk = 8 bytes | ||
| *alignment = 8 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_IP_implementation_AVX2_FMA(dim); | ||
| } | ||
| #endif | ||
| #ifdef OPT_AVX2 | ||
| if (features.avx2) { | ||
| if (dim % 8 == 0) // SQ8 chunk = 8 bytes | ||
| *alignment = 8 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_IP_implementation_AVX2(dim); | ||
| } | ||
| #endif | ||
| #ifdef OPT_SSE4 | ||
| if (features.sse4_1) { | ||
| if (dim % 4 == 0) // SQ8 chunk = 4 bytes | ||
| *alignment = 4 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_IP_implementation_SSE4(dim); | ||
| } | ||
| #endif | ||
|
|
@@ -129,23 +138,32 @@ dist_func_t<float> Cosine_SQ8_FP32_GetDistFunc(size_t dim, unsigned char *alignm | |
| if (dim < 16) { | ||
| return ret_dist_func; | ||
| } | ||
| // Alignment hints below refer to the SQ8 (first) operand per the GetDistFunc contract. | ||
| #ifdef OPT_AVX512_F_BW_VL_VNNI | ||
| if (features.avx512f && features.avx512bw && features.avx512vnni) { | ||
| if (dim % 16 == 0) // SQ8 chunk = 16 bytes | ||
| *alignment = 16 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_Cosine_implementation_AVX512F_BW_VL_VNNI(dim); | ||
|
Comment on lines
+141
to
146
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same convention as the rest of the dispatcher layer (see e.g. |
||
| } | ||
| #endif | ||
| #ifdef OPT_AVX2_FMA | ||
| if (features.avx2 && features.fma3) { | ||
| if (dim % 8 == 0) // SQ8 chunk = 8 bytes | ||
| *alignment = 8 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_Cosine_implementation_AVX2_FMA(dim); | ||
| } | ||
| #endif | ||
| #ifdef OPT_AVX2 | ||
| if (features.avx2) { | ||
| if (dim % 8 == 0) // SQ8 chunk = 8 bytes | ||
| *alignment = 8 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_Cosine_implementation_AVX2(dim); | ||
| } | ||
| #endif | ||
| #ifdef OPT_SSE4 | ||
| if (features.sse4_1) { | ||
| if (dim % 4 == 0) // SQ8 chunk = 4 bytes | ||
| *alignment = 4 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_Cosine_implementation_SSE4(dim); | ||
| } | ||
| #endif | ||
|
|
@@ -218,7 +236,10 @@ dist_func_t<float> IP_SQ8_SQ8_GetDistFunc(size_t dim, unsigned char *alignment, | |
|
|
||
| #ifdef CPU_FEATURES_ARCH_X86_64 | ||
| #ifdef OPT_AVX512_F_BW_VL_VNNI | ||
| // AVX512 VNNI SQ8_SQ8 uses 64-element chunks; residual handling is in 32-byte sub-chunks. | ||
| if (dim >= 64 && features.avx512f && features.avx512bw && features.avx512vnni) { | ||
| if (dim % 32 == 0) // align to 256 bits when there is no offsetting residual | ||
| *alignment = 32 * sizeof(uint8_t); | ||
| return Choose_SQ8_SQ8_IP_implementation_AVX512F_BW_VL_VNNI(dim); | ||
|
Comment on lines
+239
to
243
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same convention as the rest of the dispatcher layer (see e.g. |
||
| } | ||
| #endif | ||
|
|
@@ -262,7 +283,10 @@ dist_func_t<float> Cosine_SQ8_SQ8_GetDistFunc(size_t dim, unsigned char *alignme | |
|
|
||
| #ifdef CPU_FEATURES_ARCH_X86_64 | ||
| #ifdef OPT_AVX512_F_BW_VL_VNNI | ||
| // AVX512 VNNI SQ8_SQ8 uses 64-element chunks; residual handling is in 32-byte sub-chunks. | ||
| if (dim >= 64 && features.avx512f && features.avx512bw && features.avx512vnni) { | ||
| if (dim % 32 == 0) // align to 256 bits when there is no offsetting residual | ||
| *alignment = 32 * sizeof(uint8_t); | ||
| return Choose_SQ8_SQ8_Cosine_implementation_AVX512F_BW_VL_VNNI(dim); | ||
|
Comment on lines
+286
to
290
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same convention as the rest of the dispatcher layer (see e.g. |
||
| } | ||
| #endif | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,23 +70,32 @@ dist_func_t<float> L2_SQ8_FP32_GetDistFunc(size_t dim, unsigned char *alignment, | |
| if (dim < 16) { | ||
| return ret_dist_func; | ||
| } | ||
| // Alignment hints below refer to the SQ8 (first) operand per the GetDistFunc contract. | ||
| #ifdef OPT_AVX512_F_BW_VL_VNNI | ||
| if (features.avx512f && features.avx512bw && features.avx512vnni) { | ||
| if (dim % 16 == 0) // SQ8 chunk = 16 bytes; no point in aligning if there's a residual | ||
| *alignment = 16 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_L2_implementation_AVX512F_BW_VL_VNNI(dim); | ||
|
Comment on lines
+73
to
78
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same convention as the rest of the dispatcher layer (see e.g. |
||
| } | ||
| #endif | ||
| #ifdef OPT_AVX2_FMA | ||
| if (features.avx2 && features.fma3) { | ||
| if (dim % 8 == 0) // SQ8 chunk = 8 bytes | ||
| *alignment = 8 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_L2_implementation_AVX2_FMA(dim); | ||
| } | ||
| #endif | ||
| #ifdef OPT_AVX2 | ||
| if (features.avx2) { | ||
| if (dim % 8 == 0) // SQ8 chunk = 8 bytes | ||
| *alignment = 8 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_L2_implementation_AVX2(dim); | ||
| } | ||
| #endif | ||
| #ifdef OPT_SSE4 | ||
| if (features.sse4_1) { | ||
| if (dim % 4 == 0) // SQ8 chunk = 4 bytes | ||
| *alignment = 4 * sizeof(uint8_t); | ||
| return Choose_SQ8_FP32_L2_implementation_SSE4(dim); | ||
| } | ||
| #endif | ||
|
|
@@ -470,8 +479,10 @@ dist_func_t<float> L2_SQ8_SQ8_GetDistFunc(size_t dim, unsigned char *alignment, | |
|
|
||
| #ifdef CPU_FEATURES_ARCH_X86_64 | ||
| #ifdef OPT_AVX512_F_BW_VL_VNNI | ||
| // AVX512 VNNI SQ8_SQ8 uses 64-element chunks | ||
| // AVX512 VNNI SQ8_SQ8 uses 64-element chunks; residual handling is in 32-byte sub-chunks. | ||
| if (dim >= 64 && features.avx512f && features.avx512bw && features.avx512vnni) { | ||
| if (dim % 32 == 0) // align to 256 bits when there is no offsetting residual | ||
| *alignment = 32 * sizeof(uint8_t); | ||
| return Choose_SQ8_SQ8_L2_implementation_AVX512F_BW_VL_VNNI(dim); | ||
|
Comment on lines
+482
to
486
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same convention as the rest of the dispatcher layer (see e.g. |
||
| } | ||
| #endif | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This matches the long-standing convention used by every existing dispatcher in
IP_space.cpp/L2_space.cpp(FP32, FP64, BF16, FP16, INT8, UINT8). E.g.IP_FP32_GetDistFuncwrites*alignmentonly inside the optimized branches and leaves it untouched on the scalar fallback. The contract — honored by the single production callerCreateIndexComponents— is that the caller initializes*alignment = 0before invokingGetDistFunc. Flipping that to "fallback unconditionally writes 0" would have to be done across every*_GetDistFuncfor consistency, which is out of scope for MOD-13837.