Skip to content

Using Intel MKL on AMD CPUs

Intel oneMKL provides optimized BLAS, LAPACK, FFT, and other numerical routines. On AMD processors, however, some MKL versions have historically selected less-optimized code paths based on CPU identification, which can significantly reduce performance.

This behaviour has been documented by Intel, AMD, and HPC centres. AMD's EPYC tuning guide, for example, describes cases where MKL did not select the AVX2 implementation by default on EPYC processors.

Workaround

The CPU partition of Perun uses AMD processors based on the Zen 5c microarchitecture, so it is recommended to use the following workaround to ensure that MKL uses the optimized code paths. There is a special module called fakeintel that can be loaded to make MKL believe it is running on an Intel CPU, which will force it to use the optimized code paths. One has to keep it mind that this load only workaround not the library itself, so it is necessary to load the fakeintel module along with the desired Intel module.

Usage

To use the fakeintel module is simple:

module load vasp-intel

mpirun -np 4 vasp_std     # VASP goes slow

module load fakeintel

mpirun -np 4 vasp_std     # VASP goes fast

module unload fakeintel

mpirun -np 4 vasp_std     # VASP goes slow again

Performance comparison

The perfromance difference can be significant, but in the end it depends on the aplicatoin and the version of Intel libraries used. The following table shows the performance of BLAS/LAPACK routines on AMD EPYC 9845 (Zen 5c) with and without the fakeintel module loaded. The tests were performed using Intel MKL version 2025.2.0.

Routine Size Without fakeintel
[GFLOP/s]
With fakeintel
[GFLOP/s]
Speedup [%]
daxpy 256 8.523 12.785 50.01
dgemv 256 23.115 27.536 19.13
dgemm 256 184.617 878.039 375.60
dgetrf 256 6.221 6.453 3.73
dpotrf 256 6.767 0.986 -85.43
dgesv 256 6.179 6.457 4.50
daxpy 512 9.318 20.361 118.51
dgemv 512 18.393 19.197 4.37
dgemm 512 610.988 2101.980 244.03
dgetrf 512 32.146 31.704 -1.37
dpotrf 512 51.615 80.713 56.38
dgesv 512 30.362 31.261 2.96
daxpy 1024 10.780 25.570 137.20
dgemv 1024 18.387 24.084 30.98
dgemm 1024 2228.815 4945.587 121.89
dgetrf 1024 111.525 125.336 12.38
dpotrf 1024 108.575 226.515 108.63
dgesv 1024 105.547 121.019 14.66

As one can see, the performance difference can be significant, especially for larger matrix sizes and certain routines. For example, the dgemm routine shows a speedup of over 375% for size 256 and over 244% for size 512 when using the fakeintel module. However, some routines like show slowdown (e.g., dpotrf for size 256) when using the fakeintel module, indicating that the performance impact can vary depending on the specific routine and matrix size. These measurements were taken with warm up runs from large ensamble of random matrices, so the results are representative of typical usage scenarios and are reproducible. The performance difference can be significant, but in the end it depends on the application and the version of Intel libraries used.

Created by: Ot(t)o Kohulák