Skip to content

ENH allow for specifying CPU features to enable via NPY_ENABLE_CPU_FEATURES environment variable#22137

Merged
mattip merged 1 commit intonumpy:mainfrom
Micky774:enable_simd
May 2, 2023
Merged

ENH allow for specifying CPU features to enable via NPY_ENABLE_CPU_FEATURES environment variable#22137
mattip merged 1 commit intonumpy:mainfrom
Micky774:enable_simd

Conversation

@Micky774
Copy link
Copy Markdown
Contributor

@Micky774 Micky774 commented Aug 15, 2022

Related issues/PRs

Fixes #22058

What does this PR add?

This PR enables the usage of a NPY_ENABLE_CPU_FEATURES environment variable whose function is described in #22058.
Note that the enabling function errors when asked to enable features not supported by the CPU, or that numpy was not built with. This breaks symmetry with the disabling semantics, but I think this makes sense since it would be a drastic expectation violation otherwise.

Other comments

@Micky774 Micky774 changed the title Initial implementation ENH allow for specifying CPU features to enable via NPY_ENABLE_CPU_FEATURES environment variable Aug 15, 2022
@Micky774
Copy link
Copy Markdown
Contributor Author

Micky774 commented Aug 15, 2022

@mattip @seiko2plus Do you know where I should add the tests for this?

@seiko2plus
Copy link
Copy Markdown
Member

Do you know where I should add the tests for this?

maybe within [numpy/core/tests/test_cpu_dispatcher.py] (https://github.com/numpy/numpy/blob/main/numpy/core/tests/test_cpu_dispatcher.py) but it will require loading the module in a separate process.

@magsol
Copy link
Copy Markdown

magsol commented Aug 17, 2022

@seiko2plus Is there a preference in NumPy for warnings vs errors? My question here is partially because of the fact that enabling a feature that doesn't exist is not equivalent to disabling a feature that doesn't exist, and so may require different ways of handling the error--a warning for the latter seems appropriate, but in the case of the former, it may be better to throw an error and exit. Thoughts?

@Micky774
Copy link
Copy Markdown
Contributor Author

Micky774 commented Aug 18, 2022

@seiko2plus Is there a preference in NumPy for warnings vs errors? My question here is partially because of the fact that enabling a feature that doesn't exist is not equivalent to disabling a feature that doesn't exist, and so may require different ways of handling the error--a warning for the latter seems appropriate, but in the case of the former, it may be better to throw an error and exit. Thoughts?

For reviewers and interested parties, the current PR's behavior regarding errors/warnings:

* It will set a RuntimeError when
* - CPU baseline features from the build are not supported at runtime
* - 'NPY_DISABLE_CPU_FEATURES' tries to disable a baseline feature
* - 'NPY_DISABLE_CPU_FEATURES' and 'NPY_ENABLE_CPU_FEATURES' are
* simultaneously set
* - 'NPY_ENABLE_CPU_FEATURES' tries to enable a feature that is not supported
* by the machine or build
* - 'NPY_ENABLE_CPU_FEATURES' tries to enable a feature when the project was
* not built with any feature optimization support
*
* It will set an ImportWarning when:
* - 'NPY_DISABLE_CPU_FEATURES' tries to disable a feature that is not supported
* by the machine or build
* - 'NPY_DISABLE_CPU_FEATURES' or 'NPY_ENABLE_CPU_FEATURES' tries to
* disable/enable a feature when the project was not built with any feature
* optimization support

@seiko2plus
Copy link
Copy Markdown
Member

@magsol,

As long as the error does not affect the workflow of the following procedures, then choosing to raise runtime-warning would make sense. according to Python's warning-doc RuntimeWarning is reserved for warnings about dubious runtime features. maybe ImportWarning would be a better choice since it's ignored by default.
however, the end-user has the upper hand here, since this behavior can be changed during the runtime through module warning, for example, warnings can be treated as errors via:

import os, warnings
os.environ['NPY_DISABLE_CPU_FEATURES'] = 'XXXX'
warnings.simplefilter("error", RuntimeWarning)
import numpy as np

@magsol
Copy link
Copy Markdown

magsol commented Sep 6, 2022

@seiko2plus That's perfect. Thank you!

@mattip
Copy link
Copy Markdown
Member

mattip commented Sep 7, 2022

Tests are missing. For an example of tests that change the environment variables and then run python in a subprocess, see env manipulation in numpy/core/tests/test_cpu_feature.py

@Micky774
Copy link
Copy Markdown
Contributor Author

I can't reproduce these errors locally. Even when setting up a machine with --cpu-baseline=native correctly, all the tests pass on my end. Wondering if you may have any insights @mattip @seiko2plus

@seiko2plus
Copy link
Copy Markdown
Member

seiko2plus commented Sep 19, 2022

@Micky774, to reproduce this error, you have to disable the dispatch-able features similar to what the smoke test does, for example:

python setup.py build --cpu-baseline=native --cpu-dispatch=none install --user
python runtests.py -n

or just

python runtests.py --cpu-dispatch=none

In general, you have to escape the dispatch tests if __cpu_dispatch__ is equal to None or if it's an empty list.

@seiko2plus
Copy link
Copy Markdown
Member

seiko2plus commented Sep 19, 2022

@Micky774, please let me know when it's ready for review.

@Micky774
Copy link
Copy Markdown
Contributor Author

Micky774 commented Sep 20, 2022

@Micky774, please let me know when it's ready for review.

@seiko2plus Should be good now! Thanks for the help :)

@mattip
Copy link
Copy Markdown
Member

mattip commented Sep 29, 2022

@seiko2plus could you take a look? I think the aarch64 failure is systematic and not connected to this PR.

Copy link
Copy Markdown
Member

@seiko2plus seiko2plus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, Just requires some simplifying.

@Micky774
Copy link
Copy Markdown
Contributor Author

@seiko2plus Should be ready when you get a chance to review.

@Micky774
Copy link
Copy Markdown
Contributor Author

@seiko2plus Just a gentle reminder ping. Let me know if you have any other concerns to address for this PR :)

@Micky774
Copy link
Copy Markdown
Contributor Author

Micky774 commented Nov 8, 2022

@seiko2plus @seberg Just wanted to ping again regarding this PR.

Copy link
Copy Markdown
Member

@seiko2plus seiko2plus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The C implementation looks good to me, just the unit testing may need some modification as follows

@mattip
Copy link
Copy Markdown
Member

mattip commented Nov 13, 2022

Coverage thinks tests are missing for some of the corner cases.

return -1;
}
return 0;
}
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The return 0 is not covered, but I think that is because the warning is always turned into an error in tests. Perhaps this was a latent bug?

return -1;
}
if (PyErr_WarnFormat(PyExc_ImportWarning, 1, NOTSUPP_BODY) < 0) {
return -1;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems these cases are not covered in tests?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one (RuntimeError) is covered, however the second one (ImportWarning) wasn't. Upon closer inspection, the only time the latter would run is if:

  1. NPY_CPU_DISABLE_FEATURE was set to an unsupported feature
  2. The unsupported feature is included in dispatch

From my current understanding (I am a bit rusty) an unsupported feature cannot, by default, appear in dispatch. Thus I have now removed this check

@seiko2plus seiko2plus added the component: SIMD Issues in SIMD (fast instruction sets) code or machinery label Dec 30, 2022
@seiko2plus
Copy link
Copy Markdown
Member

rebuild CI

@seiko2plus seiko2plus closed this Mar 2, 2023
@seiko2plus seiko2plus reopened this Mar 2, 2023
@mattip
Copy link
Copy Markdown
Member

mattip commented Mar 24, 2023

@Micky774 will you be continuing this?

@Micky774
Copy link
Copy Markdown
Contributor Author

Admittedly this had fallen off my radar, but yes I'll resume work on it over the next few days! Thank you for the reminder :)

@Micky774
Copy link
Copy Markdown
Contributor Author

Micky774 commented Apr 5, 2023

@mattip Do you know if the failing TestMatmul.test_vector_matrix_values is related to this PR? And what should be done about the code coverage?

@charris
Copy link
Copy Markdown
Member

charris commented Apr 5, 2023

if the failing TestMatmul.test_vector_matrix_values is related to this PR

No. It is one of those failures that happens now and then on Windows for unknown reasons. It is probably compiler related, you can ignore it.

@mattip
Copy link
Copy Markdown
Member

mattip commented Apr 6, 2023

I think this needs to be rebased off main rather than having main merged in for the coverage report to be correct? Otherwise I don't understand why coverage is claiming so much of the code is not tested.

@mattip
Copy link
Copy Markdown
Member

mattip commented Apr 8, 2023

Squashed and rebased off main

@mattip
Copy link
Copy Markdown
Member

mattip commented Apr 8, 2023

Coverage is still claiming the new code is not tested. When I run them locally on my AMD machine, they are skipped since I do not have any features beyond the baseline.

@mattip
Copy link
Copy Markdown
Member

mattip commented May 2, 2023

I have verified the coverage report is bogus and the new tests run.

@mattip mattip dismissed seiko2plus’s stale review May 2, 2023 21:58

Requested changes made.

@mattip mattip merged commit c37a577 into numpy:main May 2, 2023
@mattip
Copy link
Copy Markdown
Member

mattip commented May 2, 2023

Thanks @Micky774

@Micky774 Micky774 deleted the enable_simd branch May 3, 2023 00:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

01 - Enhancement component: SIMD Issues in SIMD (fast instruction sets) code or machinery

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ENH: Add an "opt-in" feature in NumPy for CPU features, NPY_ENABLE_CPU_FEATURES

6 participants