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

Implement closer integration of AOCL components when using the amd-aocl package #43213

Open
wants to merge 6 commits into
base: develop
Choose a base branch
from

Conversation

amd-toolchain-support
Copy link
Contributor

@amd-toolchain-support amd-toolchain-support commented Mar 15, 2024

Implement closer integration of AOCL components when using the amd-aocl package

1) Implement closer integration of AOCL components when using amd-aocl package
2) Fix for aocl-sparse issue spack#43193
Comment on lines +68 to +73
default=True,
when="@4.1:",
description=(
"Enables tight coupling with AOCL-BLAS library in order to use AOCL-BLAS "
"internal routines"
),
Copy link
Member

Choose a reason for hiding this comment

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

This variant is not needed, since we can make decisions based on:

spec.satisfies("^[virtuals=blas] amdblis")

internally.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

we intend to use the new variants for enabling alternative code paths in the future (there is actually a new code path in libflame since 4.2) - they are not just for the purpose of managing dependencies.

Copy link
Member

Choose a reason for hiding this comment

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

@amd-toolchain-support Not sure what do you mean here. Can't we just do:

if spec.satisfies("@4.2: ^[virtuals=blas] amdblis"):
    args.append("-DAOCL_ROOT:PATH={0}".format(self.spec["blas"].prefix))

in the code below and avoid the variant? This variant seems to be used to select a specific virtual package for blas, and we don't usually do that (e.g. we don't have packages with an mpich variant that selects mpich as a provider for mpi).

Copy link
Member

Choose a reason for hiding this comment

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

In particular this makes it hard for a user to just say ^amdblis as they're used to doing to select a virtual -- what's the other code path you want to enable?

Copy link
Contributor

Choose a reason for hiding this comment

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

what's the other code path you want to enable?

Please have a look at https://github.com/amd/libflame/blob/b51ceb238bb3a597c014f371822fc6963b1d5893/CMakeLists.txt#L98
and then https://github.com/amd/libflame/blob/b51ceb238bb3a597c014f371822fc6963b1d5893/CMakeLists.txt#L988 to see how a CMake option AOCL_BLAS can be used to switch on a variable FLA_ENABLE_AOCL_BLAS. Here is an example of how FLA_ENABLE_AOCL_BLAS is being used in the LAPACK implementation to turn on a different code branch: https://github.com/amd/libflame/blob/b51ceb238bb3a597c014f371822fc6963b1d5893/src/lapack/dec/lu/piv/front/flamec/FLA_LU_piv_z.c#L557

Note that this branch will fail to work if end users provide an alternative BLAS through Spack. So @amd-toolchain-support is correct to say that the proposed change is "not just for the purpose of managing dependencies".

Copy link
Member

Choose a reason for hiding this comment

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

@ningli-amd I don't understand how this #43213 (comment) is not sufficient for what you say above. As far as I understand, you need to pass the correct options to CMake if amdblis is used.

Did you try to use:

if spec.satisfies("^[virtuals=blas] amdblis"):

in the recipe, as suggested above?

Comment on lines +106 to +107
requires("^amdblis", when="+enable-aocl-blas", msg="+enable-aocl-blas requires using amdblis")

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
requires("^amdblis", when="+enable-aocl-blas", msg="+enable-aocl-blas requires using amdblis")

var/spack/repos/builtin/packages/amdlibm/package.py Outdated Show resolved Hide resolved
Comment on lines +49 to +57
variant(
"enable-aocl-blas-lapack",
default=True,
when="@4.1:",
description=(
"Enables tight coupling with AOCL BLAS/LAPACK library in order to use AOCL "
"internal routines"
),
)
Copy link
Member

Choose a reason for hiding this comment

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

Same as above: the variant is not needed, since we can take decisions internally based on the providers of blas and lapack.

Comment on lines +64 to +73
requires(
"^amdblis",
when="+enable-aocl-blas-lapack",
msg="+enable-aocl-blas-lapack requires using amdblis",
)
requires(
"^amdlibflame",
when="+enable-aocl-blas-lapack",
msg="+enable-aocl-blas-lapack requires using amdlibflame",
)
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
requires(
"^amdblis",
when="+enable-aocl-blas-lapack",
msg="+enable-aocl-blas-lapack requires using amdblis",
)
requires(
"^amdlibflame",
when="+enable-aocl-blas-lapack",
msg="+enable-aocl-blas-lapack requires using amdlibflame",
)

var/spack/repos/builtin/packages/aocl-sparse/package.py Outdated Show resolved Hide resolved
args.extend(
[
"-DLAPACK_FOUND=true",
"-DUSE_OPTIMIZED_LAPACK_BLAS=true",
Copy link
Member

Choose a reason for hiding this comment

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

What is this change about?

Copy link
Contributor

Choose a reason for hiding this comment

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

We decided to switch to an alternative BLAS/LAPACK detection mechanism in amdscalapack's CMake build system.

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 work with previous versions of amdscalapack or should we use a different option based on versions?

@alalazo alalazo self-assigned this Mar 18, 2024
@alalazo
Copy link
Member

alalazo commented Mar 18, 2024

Can you also please improve the title? "Following changes were done for AOCL libraries:" is not really representative of what the PR is doing.

@amd-toolchain-support amd-toolchain-support changed the title Following changes were done for AOCL libraries: Implement closer integration of AOCL components when using the amd-aocl package Mar 19, 2024
@amd-toolchain-support
Copy link
Contributor Author

Can you also please improve the title? "Following changes were done for AOCL libraries:" is not really representative of what the PR is doing.

Done

@amd-toolchain-support
Copy link
Contributor Author

amd-toolchain-support commented May 21, 2024

We are writing to discuss a challenge we are encountering with the use of 'spack virtuals' as opposed to the 'enable-aocl-blas' variant in amdlibflame and the 'enable-aocl-blas-lapack' variant in amdscalapack.

While the benefits of 'spack virtuals' are clear, we have found that when installing amdlibflame or amdscalapack from a fresh workspace, the spack concretizer defaults to pulling openblas. This is not our intended result, as we aim to ensure the installation of AMD products exclusively.

We can achieve this within the amd-aocl spack bundle using the commands:

'depends_on(f"amdlibflame@={vers} ^[virtuals=blas] amdblis")' and 'depends_on(f"amdscalapack@={vers} ^[virtuals=blas] amdblis ^[virtuals=lapack] amdlibflame")'

However, replicating this process for HPC applications installation is inefficient and cumbersome. As such, we propose the use of 'variant' as a more practical solution for our needs.

We have attached the spec results for your reference. We welcome further discussions and suggestions on this matter. Thank you for your understanding and continued support.

spack_amdscalapack_spec_output_with_virtuals.txt
spack_amdscalapack_spec_output.txt

@alalazo
Copy link
Member

alalazo commented May 22, 2024

This is not our intended result, as we aim to ensure the installation of AMD products exclusively.

You can use requirements for that: https://spack.readthedocs.io/en/latest/packages_yaml.html#setting-requirements-on-virtual-specs

@amd-toolchain-support
Copy link
Contributor Author

Hi @alalazo, @tgamblin,

I realise that we've not really explained very well what we are trying to achieve with our AOCL Spack support. Please allow me to try and give the full picture here, so that we can try to find something that will hopefully work for everyone.

Currently we do not ship a monolithic library recipe because we are aware that some users do value being able to mix-and-match blas and lapack providers. We also have users who would like to use the full AMD stack, and be able to install it via the amd-aocl metapackage. This is why our historically preferred solution has been the per-lib recipes plus a metapackage.

The problem we are running into is that following the provider rework from a few months ago, we are not able to encode the metapackage dependency requirements to ensure that a full AOCL-only stack is built. We are instead finding that no matter what we do, OpenBLAS sneaks into the dep graph, usually as a dependency of amdlibflame. That results in having two blas and two lapack providers in the same spec, with implementation details determining which routines actually get called at runtime.

So with that in mind, the reason we have introduced the variants is to try to force the concretizer to give us what want when building the amd-aocl metapackage. If we can solve that dependency problem without those variants, then I think that the implementation route that you have suggested will work without issue.

Below is a small example that boils down what we are trying to achieve in the metapackage to a minimal example. If you can help us understand how to encode the requirements in mymetapackage to ensure that blasuserpackage always selects amdblis as the provider, then we can use that logic in our amd-aocl metapackage. Currently I cannot find a valid expression of this that the concretizer will accept and honor.

I realise the user can provide install-time dependency statements to acheive this control, but we would like to find a way of ensuring that the metapackage behaves correctly for the simple spack install amd-aocl case.

We would appreciate your input on how best to achieve this.

class Mymetapackage(BundlePackage):
    """Test package for concretization"""
    
    homepage = "https://www.example.com"
    url = "mymetapackage"

    version("0.1.2")

    depends_on("blasuserpackage ^[virtuals=blas] amdblis") # What goes here?
    requires("blasuserpackage ^[virtuals=blas] amdblis") # and what goes here?

class Blasuserpackage(MakefilePackage):
    """Test package consuming blas"""

    homepage = "https://www.example.com"
    url = "blasuserpackage"

    version("0.1.2")

    depends_on("blas")

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants