-
Notifications
You must be signed in to change notification settings - Fork 283
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
A path to making OpenBLAS optarch aware. #1946
Conversation
@boegel and @tgamblin, I'm trying to return to resolving the lack of optarch support for OpenBLAS, but in a slightly more generic fashion. @boegel asked if leaning on https://github.com/archspec/archspec would be a good idea, and that most certainly seems like a very good idea indeed. However, there are a few thoughts on how to proceed:
|
Did you look at the Spack It's close enough that we just search for a target based on the archspec name, with a few special cases. Given that OpenBLAS is one package, I'm not inclined to add its names to |
Hi @tgamblin and thank you for your input! I poked at at the Spack implementation and it looks very smooth. I feel there needs to be a bit of version checking on the TargetList, but that's another problem all together. As you say, cluttering the main archspec JSON is a bad idea, which is why I thought of secondary mappings or "plugins" to provide extended support. There are also cases beyond OpenBLAS that will eventually need addressing. However, in the short term, using archspec and the Spack implementation as a reference would solve the immediate issue, and then we can take it from there. Hm. Thanks again for your input, very helpful! (And if you can get OpenBLAS to be a little bit more conformant, that'd be amazing.) |
951167d
to
9885496
Compare
|
||
for piece in pieces: | ||
spec = piece.split('=') | ||
if spec[0] == 'march' or spec[0] == '-march': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about -mcpu
? I see that used on POWER
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
-mcpu is used, but it is a deprecated synonym for -mtune, which only takes two values on x86, generic and Intel, neither of which have an effect on OpenBLAS targeting, which only cares about CPU architecture. I have no idea what this option does on Power. :(
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See https://stackoverflow.com/questions/42718572/gcc-mtune-vs-march-vs-mcpu
-mcpu unfortunately has different semantics for different targets. It's deprecated for x86 (being a synonym for -mtune) but not for ARM, where it's a sum of -march and -mtune.
% (self.toolchain.comp_family(), compiler_optarch)) | ||
self.log.warning("Unable to map %s to an OpenBLAS target, falling back to runtime optimization." | ||
% compiler_optarch) | ||
self._set_dynamic_architecture(default_opts) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm very unsure about this. If I build OpenBLAS currently, it seems to autodetect the current arch and optimizes for it. It seems to even overwrite our optarch settings etc which is fine when building for native. Additionally e.g. for POWER and OpenBLAS until 0.3.7 (IIRC) DYNAMIC_ARCH is broken to the point where even the simple tests fail (so in this case the EC wouldn't build)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, thanks! With DYNAMIC_ARCH being broken on POWER, we should certainly it for Power.
But the thing is, if you ask for optarch=haswell
and OpenBLAS optimises for native, and you're on a skylake build host, your compute nodes will cease to function. For me (and I presume others), optarch
is not something that may be ignored.
My strong preference is that if an EasyBuild user sets optarch=haswell
EasyBuild offers the guarantee that the code produced will indeed run on haswell. If this can't be done for an EasyConfig, it is, at least for me, vastly preferable for the EasyConfig to fail during build.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alright sure. I just wanted to highlight that the default (native) should still work as before (hence my restriction to "when building for native")
|
||
return target_arch.lower() | ||
|
||
def _get_openblas_targets(self, targetfile): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For all those functions: Could you make them free functions? In PyTorch/TensorFlow I found it a good idea so you can just import this from regular python and run/test it
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@lexming (I think) suggested generalising a number of these functions and shipping them off to Framework. The ones that are OpenBLAS specific should probably suffer a similar fate. This will require another rewrite though, not sure about the ETA on that.
if compiler in optarch: | ||
compiler_specific_optarch_string = optarch[compiler] | ||
else: | ||
raise EasyBuildError("optarch in an unexpected format: '%s'" % type(optarch)).__class__.__name__ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please remove the .__class__.__name__
. Also maybe include the optarch value and use ,
instead of %
compiler = self.toolchain.comp_family() | ||
compiler_specific_optarch_string = '' | ||
|
||
if type(optarch) == str: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can (and IIRC should) use isinstance
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, will do.
# strip march from all environment variables except the EBVAR-prefixed ones. | ||
# For dynamic builds we should ignore optarch completely and for optarch-set builds | ||
# we need to adhere to TARGET and not march. | ||
if self._dynamic_target is True or self._optarch_architecture is True: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In which case can self._optarch_architecture
be True? It is either False or a string isn't it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hm, yeah. I think this was a suggested change from the editor of best practices for python. There was something odd about that. I'll check it out.
:param optarch: A complete optarch statement. | ||
https://easybuild.readthedocs.io/en/latest/Controlling_compiler_optimization_flags.html | ||
""" | ||
if optarch is False: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For me (on POWER) optarch is None
, so maybe if not optarch:
? And I'd return None
too as that seems to better fit the meaning
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, certainly.
if uarch.name in available_targets: | ||
result = uarch.name | ||
else: | ||
self.log.info("No direct match for '" + march + "' between archspec and OpenBLAS, traversing ancestry.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Don't we use formatted logs instead of string concatting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably? I'll have to look at that.
@terjekv I think you'll agree with me that it's unlikely that this PR will get merged. It was at least partially motivated by a need in EESSI, and we've started taking a different approach there in EESSI/software-layer#260 by implementing a custom hook for OpenBLAS which injects That could/should probably also be implemented in the OpenBLAS easyblock, but in a different way than is being done here - this PR does way more than just injecting |
I'd wager it could be merged if I rewrote it to use DYNAMIC_ARCH in a sane way when seeing optarch=GENERIC, but hooks work fine for now. So fine I've been using it for long while myself. Close and let a new, maybe working, PR arise if one ha the energy. :) |
directly to targets known to OpenBLAS.
an obvious example.