pairwise_distances_argmin_min / ArgKMin64 is not thread-safe

### Describe the bug

Problem found while test investigating failures found in #30041. I crafted a minimal reproducer below. It might be caused by a race condition (corruption) of shared intermediate buffers used in OpenMP threads.

Some remarks:

- the problem happens with either strategy ("parallel_on_X" vs "parallel_on_Y");
- running the reproducer with `OMP_NUM_THREADS=1` hides the problem;
- running the reproducer with a lower than default value for `OMP_NUM_THREADS` makes the problem less likely to happen;
- using `threadpoolctl.threadpool_limits(limits=1, user_api="openmp")` does not hide the problem for some reason...

### Steps/Code to Reproduce

```python
from sklearn.metrics._pairwise_distances_reduction._argkmin import ArgKmin64
import numpy as np
from joblib import delayed, Parallel
from threadpoolctl import threadpool_info
from pprint import pprint

pprint(threadpool_info())
rng = np.random.RandomState(0)
X = rng.randn(97, 149)
Y = rng.randn(111, 149)


# Note: strategy does not matter.
shared_kwargs = dict(
    k=1, metric="euclidean", strategy="parallel_on_X", return_distance=True
)
reference_results = ArgKmin64.compute(X, Y, **shared_kwargs)

for n_iter in range(10):
    print(".", end="")
    for results in Parallel(n_jobs=4, backend="threading")(
        delayed(ArgKmin64.compute)(X, Y, **shared_kwargs) for _ in range(100)
    ):
        if shared_kwargs["return_distance"]:
            result_distances, result_indices = results
            np.testing.assert_allclose(result_distances, reference_results[0])
            np.testing.assert_array_equal(result_indices, reference_results[1])
        else:
            np.testing.assert_array_equal(results, reference_results)
```

### Expected Results

No error.

### Actual Results

```python-traceback
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[20], line 27
     25 if shared_kwargs["return_distance"]:
     26     result_distances, result_indices = results
---> 27     np.testing.assert_allclose(result_distances, reference_results[0])
     28     np.testing.assert_array_equal(result_indices, reference_results[1])
     29 else:

    [... skipping hidden 1 frame]

File ~/miniforge3/envs/dev/lib/python3.13/site-packages/numpy/testing/_private/utils.py:926, in assert_array_compare(comparison, x, y, err_msg, verbose, header, precision, equal_nan, equal_inf, strict, names)
    921         err_msg += '\n' + '\n'.join(remarks)
    922         msg = build_err_msg([ox, oy], err_msg,
    923                             verbose=verbose, header=header,
    924                             names=names,
    925                             precision=precision)
--> 926         raise AssertionError(msg)
    927 except ValueError:
    928     import traceback

AssertionError: 
Not equal to tolerance rtol=1e-07, atol=0

Mismatched elements: 41 / 97 (42.3%)
Max absolute difference among violations: 0.88436841
Max relative difference among violations: 0.06194002
 ACTUAL: array([[14.721555],
       [15.009136],
       [14.586221],...
 DESIRED: array([[14.721555],
       [15.009136],
       [14.586221],...
```

The values of the difference among violations change from one run to the next, but are always much larger than what could be expected from rounding errors.

### Versions

```shell
System:
    python: 3.13.3 | packaged by conda-forge | (main, Apr 14 2025, 20:44:30) [Clang 18.1.8 ]
executable: /Users/ogrisel/miniforge3/envs/dev/bin/python
   machine: macOS-15.5-arm64-arm-64bit-Mach-O

Python dependencies:
      sklearn: 1.8.dev0
          pip: 25.1.1
   setuptools: 75.8.2
        numpy: 2.3.2
        scipy: 1.16.0
       Cython: 3.1.1
       pandas: 2.2.3
   matplotlib: 3.10.3
       joblib: 1.5.1
threadpoolctl: 3.6.0

Built with OpenMP: True

threadpoolctl info:
       user_api: blas
   internal_api: openblas
    num_threads: 1
         prefix: libopenblas
       filepath: /Users/ogrisel/miniforge3/envs/dev/lib/libopenblas.0.dylib
        version: 0.3.30
threading_layer: openmp
   architecture: VORTEX

       user_api: openmp
   internal_api: openmp
    num_threads: 10
         prefix: libomp
       filepath: /Users/ogrisel/miniforge3/envs/dev/lib/libomp.dylib
        version: None
```

COMMENT:
> Could you also try [the new accelerate support for macOS](https://conda-forge.org/news/2025/07/31/new-accelerate-macos/)?

No bug with "new_accelerate" either.

> Could you try whether you have problem with the libopenblas==*=pthreads_* which have been or are being published for macOS thanks to the merge of https://github.com/conda-forge/openblas-feedstock/pull/177?

Thanks, I tried and there is no problem either. So it's definitely a problem that is specific to the use of openblas built with openmp.

Labels: Bug