Skip to content

[libclc] Support LLVM_ENABLE_RUNTIMES when building #141574

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

Merged
merged 2 commits into from
Jun 5, 2025

Conversation

frasercrmck
Copy link
Contributor

@frasercrmck frasercrmck commented May 27, 2025

This commit deprecates the use of LLVM_ENABLE_PROJECTS in favour of LLVM_ENABLE_RUNTIMES when building libclc.

Alternatively, using -DLLVM_RUNTIME_TARGETS= combined with -DRUNTIMES__LLVM_ENABLE_RUNTIMES=libclc also gets pretty far but fails due to zlib problems building the LLVM utility 'prepare_builtins'. I'm not sure what's going on there but I don't think it's required at this stage. More work would be required to support that option.

This does nothing to change how the host tools are found in order to be used to actually build the libclc libraries.

Note that under such a configuration the final libclc builtin libraries are placed in <build>/runtimes/runtimes-bins/libclc/, which differs from a non-runtimes build. The installation location remains the same.

Fixes #124013.

@frasercrmck frasercrmck requested a review from a team as a code owner May 27, 2025 10:20
@frasercrmck frasercrmck added the libclc libclc OpenCL library label May 27, 2025
@llvmbot llvmbot added the cmake Build system in general and CMake in particular label May 27, 2025
@frasercrmck frasercrmck requested review from arsenm and petrhosek May 27, 2025 10:20
@arsenm arsenm requested a review from jhuber6 May 27, 2025 10:53
Copy link
Contributor

@jhuber6 jhuber6 left a comment

Choose a reason for hiding this comment

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

The changes make sense for just adding it, but does it actually work? The CMake I've seen in libclc does multiple compilations and some with --target=amdgcn for example, which is a little different from how the runtimes builds handle it.

Do you have an example of how to actually build this stuff?

@frasercrmck
Copy link
Contributor Author

The changes make sense for just adding it, but does it actually work?

Truth be told I haven't grasped exactly how the runtimes system works. This "works" in that -DLLVM_ENABLE_RUNTIMES=libclc will build all libclc targets in, e.g., build/runtimes/runtimes-bins/libclc/amdgcn--amdhsa.bc and CMake options appear to be passed through to libclc correctly: -DLIBCLC_TARGETS_TO_BUILD=amdgcn--amdhsa will build only that libclc target.

That said, I don't believe it "works" in the way it's supposed to. It still grabs the host tools using get_host_tool_path in CMake, and custom commands to build with that. I take it we're supposed to use CMAKE_C_COMPILER as if we were a regular CMake project? Are we able to use opt and llvm-link and other LLVM tools?

The CMake I've seen in libclc does multiple compilations and some with --target=amdgcn for example, which is a little different from how the runtimes builds handle it.

Yes the libclc build system is a little quirky. It uses custom commands to compile OpenCL C to LLVM IR. This was to allow in-tree builds without requiring the compiler to be built before configure time. Now it seems that perhaps, ironically, that this is exactly how the runtimes build works and so we might be best to undo all of that. It was done partly also as OpenCL C and LLVM IR (the two source languages) aren't recognized by CMake as languages and so needed some unsafe & undocumented CMake code to get working. I hope we'd be able to avoid that.

Do you have an example of how to actually build this stuff?

I've been using this command to test:

cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libclc" -DLIBCLC_TARGETS_TO_BUILD=amdgcn--amdhsa -DCMAKE_BUILD_TYPE=Release

That's about it as far as libclc is concerned. It's not integrated into clang and there's no tests for it. That's something I'm hoping to change.

One question you might be able to answer: how can I treat the runtimes build more like a "regular" build? For instance ninja -v doesn't forward -v onto the build so I can't inspect what's happening while building libclc. I also can't build specific libclc targets such as ninja prepare-amdgcn--amdhsa.bc.

@jhuber6
Copy link
Contributor

jhuber6 commented May 27, 2025

That said, I don't believe it "works" in the way it's supposed to. It still grabs the host tools using get_host_tool_path in CMake, and custom commands to build with that. I take it we're supposed to use CMAKE_C_COMPILER as if we were a regular CMake project? Are we able to use opt and llvm-link and other LLVM tools?

Yes, the whole point is that we can use add_library instead of custom commands. You can still find those tools and use them if necessary however. For that you'd want to emit an object library and then add a custom command that uses all the generated objects to link / opt them and finally output them. OpenMP's GPU runtime used to do that but I hacked around it with LTO stuff.

I've been using this command to test:

cmake -S llvm -B build -G Ninja -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_ENABLE_PROJECTS="clang" -DLLVM_ENABLE_RUNTIMES="libclc" -DLIBCLC_TARGETS_TO_BUILD=amdgcn--amdhsa -DCMAKE_BUILD_TYPE=Release

Yeah, something like LIBCLC_TARGETS_TO_BUILD is likely what should be implied by the LLVM_DEFAULT_TARGET_TRIPLE value that the runtimes build passes in. (Also, does amdgcn-amd-amdhsa not work? That's the canonical one).

One question you might be able to answer: how can I treat the runtimes build more like a "regular" build? For instance ninja -v doesn't forward -v onto the build so I can't inspect what's happening while building libclc. I also can't build specific libclc targets such as ninja prepare-amdgcn--amdhsa.bc.

It's an external project, it uses the same handling. You can do ninja -C ./runtimes/runtimes-<triple>-bins and it will behave the same.

@frasercrmck
Copy link
Contributor Author

That said, I don't believe it "works" in the way it's supposed to. It still grabs the host tools using get_host_tool_path in CMake, and custom commands to build with that. I take it we're supposed to use CMAKE_C_COMPILER as if we were a regular CMake project? Are we able to use opt and llvm-link and other LLVM tools?

Yes, the whole point is that we can use add_library instead of custom commands. You can still find those tools and use them if necessary however. For that you'd want to emit an object library and then add a custom command that uses all the generated objects to link / opt them and finally output them. OpenMP's GPU runtime used to do that but I hacked around it with LTO stuff.

I'll need to look into that - maybe we can talk offline. Since libclc is used by downstream toolchains I feel it'll be hard to significantly change how it's built or presented to the host. We could support two methods of building but that would get sticky pretty quickly.

Yeah, something like LIBCLC_TARGETS_TO_BUILD is likely what should be implied by the LLVM_DEFAULT_TARGET_TRIPLE value that the runtimes build passes in. (Also, does amdgcn-amd-amdhsa not work? That's the canonical one).

I'm not sure about how best to deal with LIBCLC_TARGETS_TO_BUILD. It could also pick up from LLVM_TARGETS_TO_BUILD but we have targets like clspv and clspv64 which don't conveniently match any LLVM triple and are used by a downstream.

I'm not sure about how the AMD triples work, perhaps @arsenm can answer that. I know that downstream we're changing the final bytecode library to amdgcn-amd-amdhsa - perhaps for a similar reason.

It's an external project, it uses the same handling. You can do ninja -C ./runtimes/runtimes-<triple>-bins and it will behave the same.

Ah yes, thank you 👍.

@arsenm
Copy link
Contributor

arsenm commented May 28, 2025

There are 3 triples. amdgcn-mesa-mesa3d is the only one that ever used libclc for OpenCL. amdgcn-- ideally wouldn't exist, and would migrate to using mesa-mesa3d, but I think only OpenGL ever used it. There's also amdgcn-amd-amdpal used on Vulkan, but also does not use libclc. amdgcn-amd-amdhsa is slightly different from amdgcn-mesa-mesa3d (the mesa3d one was attempting to emulate amdhsa but couldn't 100% match)

@jhuber6
Copy link
Contributor

jhuber6 commented May 28, 2025

I'll need to look into that - maybe we can talk offline. Since libclc is used by downstream toolchains I feel it'll be hard to significantly change how it's built or presented to the host. We could support two methods of building but that would get sticky pretty quickly.

Sure, feel free to email me or ping me on the LLVM Discord.

@frasercrmck
Copy link
Contributor Author

I'm assuming the libc++ tests aren't failing due to this PR. They seem unstable, looking at jobs run for other PRs.

@@ -72,7 +72,7 @@ else()
# Note that we check this later (for both build types) but we can provide a
# more useful error message when built in-tree. We assume that LLVM tools are
# always available so don't warn here.
if( NOT clang IN_LIST LLVM_ENABLE_PROJECTS )
if( NOT LLVM_RUNTIMES_BUILD AND NOT clang IN_LIST LLVM_ENABLE_PROJECTS )
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'd quite like to keep this check/error if possible. The error you get if you forget -LLVM_ENABLE_PROJECTS=clang is horrible. Do you think it would it acceptable to pass through LLVM_ENABLE_PROJECTS to the runtimes build, @jhuber6?

Copy link
Contributor

Choose a reason for hiding this comment

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

The runtimes builds pass this USE_TOOLCHAIN argument which tells the external project utility to grab the clang from the build directory. If we don't have clang it might be more reasonable to just emit a warning there. @petrhosek Is there a reason we don't already emit a warning / error if the user does a runtimes build without clang to bootstrap?

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. Yes I suppose in the absence of a higher-level warning like you describe, we could probably use USE_TOOLCHAIN to accomplish the same thing in a runtimes build.

With any luck this is all temporary, and a runtimes build will allow us to just take the cmake c compiler.

This commit deprecates the use of LLVM_ENABLE_PROJECTS in favour of
LLVM_ENABLE_RUNTIMES.

Alternatively, using -DLLVM_RUNTIME_TARGETS=<triple> combined with
-DRUNTIMES_<triple>_LLVM_ENABLE_RUNTIMES=libclc also gets pretty far but
fails due to zlib problems building the LLVM utility 'prepare_builtins'.
I'm not sure what's going on there but I don't think it's required at
this stage. More work would be required to support that option.

This does nothing to change how the host tools are found in order to be
used to actually build the libclc libraries.

Fixes llvm#124013.
@frasercrmck frasercrmck force-pushed the libclc-runtimes-build branch from fa24e06 to 22e11c9 Compare June 5, 2025 14:32
@frasercrmck frasercrmck merged commit 6306f0f into llvm:main Jun 5, 2025
69 of 82 checks passed
@frasercrmck frasercrmck deleted the libclc-runtimes-build branch June 5, 2025 16:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cmake Build system in general and CMake in particular libclc libclc OpenCL library
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Deprecate the use of LLVM_ENABLE_PROJECTS for libclc
4 participants