Skip to content

TST: fix test_validate_transcendentals skip condition to match SVML dispatch#31333

Open
stratakis wants to merge 1 commit intonumpy:mainfrom
stratakis:AVX512_x86_64
Open

TST: fix test_validate_transcendentals skip condition to match SVML dispatch#31333
stratakis wants to merge 1 commit intonumpy:mainfrom
stratakis:AVX512_x86_64

Conversation

@stratakis
Copy link
Copy Markdown
Contributor

The test was running on machines with FMA3+AVX2 or AVX512F, but the SVML code path requires AVX512_SKX (F+BW+DQ+VL). On machines without AVX512_SKX, the glibc libm scalar fallback is used, which exceeds the 2 ULP tolerance for some float64 cbrt inputs.

The failing test was discovered with Python 3.14, when running on an RHEL10.2 instance with Intel Xeon E5-2666 v3 (Haswell), with AVX2+FMA3, but no AVX512 and glibc 2.39.

Tried on my machine which runs Fedora 43, with a Meteor Lake CPU, similarly with AVX2 and FMA3 and no AVX512, glibc 2.42 but it was not reproducible, the glibc implementation stayed within the range of the test.

With the fix the test is correctly skipped in CPUs that have no AVX512.

However, I'm not sure if the original purpose of the test is to check only when SVML is dispatched. Maybe it should skip only the SVML dependent functions (cbrt, tan, etc.) on non AVX512 machines, so they don't fall back to unreliable glibc implementations, while continuing to validate exp and log, which have their own custom NumPy AVX2+FMA3 implementations.

Traceback
=================================== FAILURES ===================================
__________________ TestAccuracy.test_validate_transcendentals __________________

self = <test_umath_accuracy.TestAccuracy object at 0x7f400651a710>
    @platform_skip
    def test_validate_transcendentals(self):
        with np.errstate(all='ignore'):
            data_dir = path.join(path.dirname(__file__), 'data')
            files = os.listdir(data_dir)
            files = list(filter(lambda f: f.endswith('.csv'), files))
            for filename in files:
                filepath = path.join(data_dir, filename)
                with open(filepath) as fid:
                    file_without_comments = (
                        r for r in fid if r[0] not in ('$', '#')
                    )
                    data = np.genfromtxt(file_without_comments,
                                         dtype=('|S39', '|S39', '|S39', int),
                                         names=('type', 'input', 'output', 'ulperr'),
                                         delimiter=',',
                                         skip_header=1)
                    npname = path.splitext(filename)[0].split('-')[3]
                    npfunc = getattr(np, npname)
                    for datatype in np.unique(data['type']):
                        data_subset = data[data['type'] == datatype]
                        inval = np.array(str_to_float(data_subset['input'].astype(str), data_subset['type'].astype(str)), dtype=eval(datatype))
                        outval = np.array(str_to_float(data_subset['output'].astype(str), data_subset['type'].astype(str)), dtype=eval(datatype))
                        perm = np.random.permutation(len(inval))
                        inval = inval[perm]
                        outval = outval[perm]
                        maxulperr = data_subset['ulperr'].max()
>                       assert_array_max_ulp(npfunc(inval), outval, maxulperr)
E                       AssertionError: Arrays are not almost equal up to 2 ULP (max difference is 3 ULP)

data       = array([(b'np.float32', b'0x3ee7054c', b'0x3f4459ea', 2),
       (b'np.float32', b'0x7d1e2489', b'0x54095925', 2),
    ...76081e3232', 2)],
      shape=(1428,), dtype=[('type', 'S39'), ('input', 'S39'), ('output', 'S39'), ('ulperr', '<i8')])
data_dir   = '/usr/lib64/python3.14/site-packages/numpy/_core/tests/data'
data_subset = array([(b'np.float64', b'0x800fa025695f404b', b'0xaaa4000ff64bb00c', 2),
       (b'np.float64', b'0xbfecc00198f98003',...e2', b'0xbfec1576081e3232', 2)],
      dtype=[('type', 'S39'), ('input', 'S39'), ('output', 'S39'), ('ulperr', '<i8')])
datatype   = np.bytes_(b'np.float64')
fid        = <_io.TextIOWrapper name='/usr/lib64/python3.14/site-packages/numpy/_core/tests/data/umath-validation-set-cbrt.csv' mode='r' encoding='UTF-8'>
file_without_comments = <generator object TestAccuracy.test_validate_transcendentals.<locals>.<genexpr> at 0x7f3fd2a21f20>
filename   = 'umath-validation-set-cbrt.csv'
filepath   = '/usr/lib64/python3.14/site-packages/numpy/_core/tests/data/umath-validation-set-cbrt.csv'
files      = ['umath-validation-set-arccos.csv', 'umath-validation-set-arccosh.csv', 'umath-validation-set-arcsin.csv', 'umath-validation-set-arcsinh.csv', 'umath-validation-set-arctan.csv', 'umath-validation-set-arctanh.csv', ...]
inval      = array([ 9.11302890e-001,  1.09932153e-308,  1.79132838e+308,
       -1.16432705e-001, -2.14895215e-308,  1.22611887e+3...     9.33478929e-001, -1.22679482e-308,  1.55090437e-308,
       -5.42233899e-001,  6.34026354e-001,  2.09917386e-001])
maxulperr  = np.int64(2)
npfunc     = <ufunc 'cbrt'>
npname     = 'cbrt'
outval     = array([ 9.69514367e-001,  2.22352275e-103,  5.63713457e+102,
       -4.88305553e-001, -2.78019707e-103,  4.96795353e+1...     9.77315620e-001, -2.30634343e-103,  2.49380030e-103,
       -8.15446654e-001,  8.59084276e-001,  5.94314240e-001])
perm       = array([225, 247, 512, 433, 232, 579, 299, 489, 302, 431, 688, 200, 314,
       298,  93,  33,  19, 428, 530, 554, 624,..., 332, 259, 274,  20, 468, 707, 486, 161, 522, 261,
       640, 617, 474, 286, 692, 180, 179, 595, 322, 475, 188, 505])
self       = <test_umath_accuracy.TestAccuracy object at 0x7f400651a710>

/usr/lib64/python3.14/site-packages/numpy/_core/tests/test_umath_accuracy.py:77: AssertionError

AI Disclosure

Claude Code with Opus 4.6 model was used to help investigate the root cause of the test failure by analyzing build logs, CPU feature detection, and the SVML dispatch code path, and ofc to understand the whole issue. Th fix was by me, the comment and commit message were drafted with the help of Claude, and also reviewed by me.

…ispatch

The test was running on machines with FMA3+AVX2 or AVX512F, but the
SVML code path requires AVX512_SKX (F+BW+DQ+VL). On machines without
AVX512_SKX, the glibc libm scalar fallback is used, which exceeds the
2 ULP tolerance for some float64 cbrt inputs.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant