Fix orphaned OpenMP directives in IndexRowwiseMinMax training functions (#5096)

Summary:
Pull Request resolved: https://github.com/facebookresearch/faiss/pull/5096

The `train_inplace_impl` and `train_impl` template functions in `IndexRowwiseMinMax.cpp` used `#pragma omp for` without an enclosing `#pragma omp parallel` region. The `omp for` directive is a work-sharing construct that distributes loop iterations among threads that are already within a parallel region. When used as an orphaned directive (outside any parallel region), it simply executes the loop sequentially on the calling thread — the parallelization that was clearly intended never actually happens.

This affects both training code paths for `IndexRowwiseMinMax` and `IndexRowwiseMinMaxFP16`:
- `train_inplace_impl`: normalizes vectors in-place before training the sub-index
- `train_impl`: creates a normalized copy of the input data before training

Both loops are embarrassingly parallel (each iteration processes an independent vector), so `#pragma omp parallel for` is the correct directive.

Additionally, the rescale-back loop in `train_inplace_impl` (which reverses the normalization after sub-index training) was not parallelized at all. Since it is also embarrassingly parallel, this change adds `#pragma omp parallel for` to it as well.

For large training sets, these loops can be a meaningful fraction of the total training time, so enabling actual parallelization improves training throughput on multi-core systems.

Reviewed By: mnorris11

Differential Revision: D100610547

fbshipit-source-id: fab8dc49c5c849090ff3300a8d04d7e13325bec0
This commit is contained in:
Alibek Zhakubayev
2026-04-13 16:05:38 -07:00
committed by meta-codesync[bot]
parent f83ea51eaa
commit 61ed7dc917
+3 -2
View File
@@ -226,7 +226,7 @@ void train_inplace_impl(
std::vector<StorageMinMaxT> minmax(n);
// normalize
#pragma omp for
#pragma omp parallel for
for (idx_t i = 0; i < n; i++) {
// compute min & max values
float minv = std::numeric_limits<float>::max();
@@ -264,6 +264,7 @@ void train_inplace_impl(
sub_index->train(n, x);
// rescale data back
#pragma omp parallel for
for (idx_t i = 0; i < n; i++) {
float scaler = 0;
float minv = 0;
@@ -289,7 +290,7 @@ void train_impl(IndexRowwiseMinMaxBase* const index, idx_t n, const float* x) {
// temp buffer
std::vector<float> tmp(n * d);
#pragma omp for
#pragma omp parallel for
for (idx_t i = 0; i < n; i++) {
// compute min & max values
float minv = std::numeric_limits<float>::max();