Skip to content

BLD: Add NPY_DISABLE_SVML env var to opt out of SVML#20695

Merged
mattip merged 1 commit intonumpy:mainfrom
ahesford:x-the-avx
Jan 5, 2022
Merged

BLD: Add NPY_DISABLE_SVML env var to opt out of SVML#20695
mattip merged 1 commit intonumpy:mainfrom
ahesford:x-the-avx

Conversation

@ahesford
Copy link
Contributor

@ahesford ahesford commented Jan 1, 2022

SVML uses AVX-512 extensions that are only supported on sufficiently new Intel CPUs. Hard-requiring this vendored library for all x86_64 Linux platforms is not appropriate. When I build on an AMD Zen 2 CPU, I get errors to the effect of

/usr/lib/python3.10/site-packages/numpy/core/_multiarray_umath.so: undefined symbol: __svml_log108

when trying to import numpy. Furthermore, the simple platform check thwarts cross-compilation because it is the host, rather than the target, that is checked.

This patch adds recogniton for NPY_DISABLE_SVML=1 in the environment, which will Numpy to build without the vendored SVML library. It might also be desirable to make the default-on behavior a little more nuanced than simply looking for Linux x86_64. However, I dont' have any specific ideas about the circumstances under which it should be enabled by default.

@github-actions github-actions bot added the 36 - Build Build related PR label Jan 1, 2022
@charris
Copy link
Member

charris commented Jan 1, 2022

I think we try to dispatch to the proper loops at runtime. @seiko2plus Thoughts?

@charris charris added this to the 1.22.1 release milestone Jan 1, 2022
@ahesford
Copy link
Contributor Author

ahesford commented Jan 1, 2022

I didn't try too hard to fix the undefined symbol issue on the AMD so I don't know if this was some oversight on my end. The bigger motivator here is the cross-compilation issue. Since SVML supports a very limited slice of numpy targets and is disabled (for native builds) on all others, it seems that the cleanest way around this is and any potential incompatibilities is to just add a switch that short-circuits the compatibility check and disables the library.

@rgommers
Copy link
Member

rgommers commented Jan 2, 2022

It seems to hook into the dispatch mechanism in a correct way in gh-19478. @ahesford what compiler and Linux distro are you using?

Adding a short-circuit for cross-compiling seems fine to me.

@ahesford
Copy link
Contributor Author

ahesford commented Jan 2, 2022

I am building this with xbps-src in Void Linux in preparation for updating our distribution package (void-linux/void-packages#34817). After rebuilding the package, I can't seem to reproduce the unresolved symbol issue, so that was likely an oversight (like a dirty build directory) on my end. The shlib _multiarray_umath.so in my latest build definitely containts __svml_log108 (and other __svml_* symbols) and is importable without issue on an AMD Zen 2 system. The numpy.test() suite passes just fine (except for two expected failures that result from Void's renaming of Python shlibs).

Thus, it seems the only real utility here is easy support for cross-compilation.

@seiko2plus
Copy link
Member

@ahesford, you can disable avx512 features through CPU build options, it will not exclude SVML objects from the final linking but it gonna fix this undefined symbol error.

@ahesford
Copy link
Contributor Author

ahesford commented Jan 4, 2022

The undefined symbol error is no longer an issue. It seems to have been a one-off error as a result of repeated build trials.

@seiko2plus
Copy link
Member

@ahesford, May I know what is the current issue this pr trying to solve?

@ahesford
Copy link
Contributor Author

ahesford commented Jan 4, 2022

At this point, convenient disabling of SVML when cross-compiling numpy. (The build will fail when an x86_64 host is used to compile for any other architecture because the runtime checks on the host will enable the build but the cross assembler will be unable to understand the instructions.)

@r-devulap
Copy link
Member

LGTM +1.

NPY_RELAXED_STRIDES_DEBUG = NPY_RELAXED_STRIDES_DEBUG and NPY_RELAXED_STRIDES_CHECKING

# Set NPY_DISABLE_SVML=1 in the environment to disable the vendored SVML
# library. This option only has significance on Linux x86_64.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
# library. This option only has significance on Linux x86_64.
# library. This option only has significance on Linux x86_64 when
# cross-compiling for a non-x86 platform.

Copy link
Member

Choose a reason for hiding this comment

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

Does this make it more clear?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I clarified the text along these lines and rebased on the latest main branch.

Copy link
Member

Choose a reason for hiding this comment

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

Looks good. Is "cross-build" more commonly used? In any case, this documentation should be copied to a new section (cross-compiling or cross-building) in doc/source/user/building.rst. If you wish it could be done in a follow on PR (maybe even by someone else), in that case please open a DOC issue and I will merge this as-is. If there is any other information that would be helpful to people trying to cross-build, please add it to the issue/section.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure if it's more common, but I changed the wording to "cross compiling" to maximize understanding.

Let's add documentation in a separate issue. I'll take a look at some of the accommodations we make in Void and will add some generalized tips as appropriate.

@mattip mattip merged commit c69ca2e into numpy:main Jan 5, 2022
@mattip
Copy link
Member

mattip commented Jan 5, 2022

Thanks @ahesford

@ahesford ahesford deleted the x-the-avx branch January 5, 2022 15:47
@ahesford
Copy link
Contributor Author

ahesford commented Jan 5, 2022

Thanks!

@InessaPawson
Copy link
Member

Hi-five on merging your first pull request to NumPy, @ahesford! We hope you stick around! Your choices aren’t limited to programming – you can review pull requests, help us stay on top of new and old issues, develop educational material, work on our website, add or improve graphic design, create marketing materials, translate website content, write grant proposals, and help with other fundraising initiatives. For more info, check out: https://numpy.org/contribute/.
Also, consider joining our mailing list. This is a great way to connect with other cool people in our community and be part of important conversations that affect the development of NumPy: https://mail.python.org/mailman/listinfo/numpy-discussion

@seiko2plus
Copy link
Member

I want to revert these changes, there are two ways to fix this issue rather than adding an optional environment variable:

  • add support to dispatchable sources to handle ASM sources similar to C/C++ sources so it can be fully controlled via --cpu-baseline, --cpu-dispatch note: current situation SVML functions are ignored only and still passed to the linker
  • test avx512 compiler/linker capability inside core/setup.py before attaching SVML sources.

@ahesford
Copy link
Contributor Author

ahesford commented Jan 5, 2022

The second is the only viable option, since dispatch options do not overcome the fact that non-x86_64 cross compilers will fail when trying to assemble the SVML sources.

I do agree that a build-time check that the sources successfully compile should gate the SVML requirement rather than the current platform check. However, why prohibit exclusion even for native builds given that SVML currently supports only a tiny subset of the target platforms?

I recommend the current SVML disable flag remain until SVML supports a wide range of supported hardware and becomes more critical to NumPy operation. The flag is off by default and doesn't hurt anybody.

@seiko2plus
Copy link
Member

@ahesford,

The second is the only viable option, since dispatch options do not overcome the fact that non-x86_64 cross compilers will fail when trying to assemble the SVML sources.

it isn't true since we have an internal mechanism for testing each specified CPU feature against compiler and assembler before enabling it, that's why you didn't face the same issue with AVX512/C intrinsics. you can check the build log or try to take a look at the SIMD doc for more details.

However, why prohibit exclusion even for native builds given that SVML currently supports only a tiny subset of the target platforms?

SVML functions aren't executed unless the target CPU support it, otherwise we fall back to C standard math lib. It's hard for maintainers to miss the chance for Linux users to get SVML/AVX512 for free so I think it was the right decision to accept the Intel gift. currently, we are trying to convert Intel ASM code into universal intrinsics see #20363.

@ahesford
Copy link
Contributor Author

ahesford commented Jan 6, 2022

I understand that SVML functions aren't executed unless the target CPU supports it and it's nice to have accelerated routines on those (few) systems that support them. My point is that, because the build process must always support not compiling SVML because it is only compilable on native x86_64 Linux builds, I fail to see the downside of keeping a switch that short-circuits the check (which is currently "Am I a Linux x86_64 host?" and is inaccurate for cross builds, but will hopefully one day become "Will the library successfully compile?") and always returns False in answer to these questions. At a minimum, having the switch is good for debugging and testing by allowing quick removal of the AVX512 routines. Even better, it solves a real problem---cross compilation when packaging NumPy for Void Linux---even before a more complicated build process gets smarter about checking for SVML support on the target.

@rgommers
Copy link
Member

@charris you marked this for 1.22.1 but it wasn't actually backported - I think that's an oversight?

@charris charris added the 09 - Backport-Candidate PRs tagged should be backported label Jan 16, 2022
@charris charris removed the 09 - Backport-Candidate PRs tagged should be backported label Jan 17, 2022
@charris charris removed this from the 1.22.2 release milestone Jan 17, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

36 - Build Build related PR

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: svml check in numpy/core/setup.py does not work when cross-compiling

7 participants