Skip to content
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

Closed
wants to merge 2 commits into from

Conversation

terjekv
Copy link
Contributor

@terjekv terjekv commented Feb 6, 2020

  • A first and very raw implementation, mapping optarch's march
    directly to targets known to OpenBLAS.
  • A better mapping is required. Skylake-avx512 vs SKYLAKEX as
    an obvious example.

easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
@boegel boegel added this to the next release (4.1.2?) milestone Feb 6, 2020
@terjekv terjekv requested a review from boegel February 10, 2020 20:19
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
easybuild/easyblocks/o/openblas.py Outdated Show resolved Hide resolved
@terjekv
Copy link
Contributor Author

terjekv commented Sep 6, 2020

@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:

  1. My current thinking is that the goal should be to map an architecture specification, be it GCCs nomenclature, OpenBLAS' own, or something completely different, to a label from archspec. From there we can thus "translate" from one naming scheme to another at will, using archspec as our Rosetta Stone,

  2. The question then becomes one of implementation. Should these distinct nomenclatures be integrated as "plugins" or something similar to archspec, or should these individual libraries be "consumers" of archspec, remaining completely distinct from the central project? Separation removes clutter, but it require more "bits" to be installed in the form of distinct libraries, and this will be something the user will have to maintain (or optionally EasyBuild?)

  3. Versioning of a given local nomenclature to archspec mappings. Archspec is already familiar with how to make certain supported compilers optimise for a given architecture, and what versions of the compilers are required. But, we would need an even broader mapping for applications. The OpenBLAS TargetList both adds and renames targets. This implies that a correct mapping will have to be release-dependent.

  4. As a side note to this work... If we get this working, someone needs to decide the extent of EasyBuild's optarch support. Long term, support for cross-compiling will probably become a question that will require a definitive answer.

@tgamblin
Copy link

tgamblin commented Sep 6, 2020

Did you look at the Spack openblas package? The mapping from archspec to openblas is here:

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 archspec -- I think the translation belongs in the package file. If the goal is to avoid duplicating that work for lots of package managers, I'd say we should try to upstream archspec support to openblas -- it's already pretty close so they might go for something like this.

@terjekv
Copy link
Contributor Author

terjekv commented Sep 6, 2020

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.)

@terjekv terjekv reopened this Sep 9, 2020

for piece in pieces:
spec = piece.split('=')
if spec[0] == 'march' or spec[0] == '-march':
Copy link
Contributor

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

Copy link
Contributor Author

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. :(

Copy link
Contributor

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)
Copy link
Contributor

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)

Copy link
Contributor Author

@terjekv terjekv Oct 2, 2020

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.

Copy link
Contributor

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):
Copy link
Contributor

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

Copy link
Contributor Author

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__
Copy link
Contributor

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:
Copy link
Contributor

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

Copy link
Contributor Author

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:
Copy link
Contributor

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?

Copy link
Contributor Author

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:
Copy link
Contributor

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

Copy link
Contributor Author

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.")
Copy link
Contributor

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?

Copy link
Contributor Author

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.

@boegel boegel modified the milestones: 4.3.1 (next release), 4.3.2 Oct 25, 2020
@boegel
Copy link
Member

boegel commented Jun 15, 2023

@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 DYNAMIC_ARCH=1 when using --optarch=GENERIC.

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 DYNAMIC_ARCH=1.

@terjekv
Copy link
Contributor Author

terjekv commented Jun 23, 2023

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. :)

@terjekv terjekv closed this Jun 23, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
EESSI Related to EESSI project enhancement
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants