[llvm-dev] [RFC][HIPSPV] Emitting HIP device code as SPIR-V (original) (raw)

Anastasia Stulova via llvm-dev llvm-dev at lists.llvm.org
Tue Aug 17 02:53:30 PDT 2021


Hi Henry,

Since the SPIR-V BE might not land in LLVM soon, we will set up the compilation flow to produce the SPIR-V binary by using the LLVM-SPIR-V translator 7 which is used in our experimental branch.

Can you provide more details regarding this? Do you plan to integrate the translator as an external tool?

Overall, there seem to be a huge overlap with what we need for OpenCL so it would be good to make sure we are aligned and the new functionality is reusable for OpenCL too.

Cheers, Anastasia


From: llvm-dev <llvm-dev-bounces at lists.llvm.org> on behalf of Henry Linjamäki via llvm-dev <llvm-dev at lists.llvm.org> Sent: 09 August 2021 07:57 To: cfe-dev at lists.llvm.org <cfe-dev at lists.llvm.org> Cc: llvm-dev at lists.llvm.org <llvm-dev at lists.llvm.org>; yaxun.liu at amd.com <yaxun.liu at amd.com> Subject: [llvm-dev] [RFC][HIPSPV] Emitting HIP device code as SPIR-V

Hi all,

HIP is a C++ Runtime API and kernel language that allows developers to create portable applications for AMD and NVIDIA GPUs from a single source code 0. There are also projects for running HIP code on Intel GPU platforms via the Intel Level Zero API 1 called HIPLZ 3 and HIPCL 2, which runs HIP programs in OpenCL devices with certain advanced features supported. Both of these backends consume SPIR-V binaries.

We are proposing a patch set to be upstreamed that enables SPIR-V emission through the HIP code path. The end goal of the patches to be submitted is to emit SPIR-V binaries from HIP device code so it can be embedded into executables for OpenCL-like environments (at least for starters). Our current focus is on the two above-mentioned projects, HIPCL and HIPLZ which are both work-in-progress HIP implementations. They itself do not consume SPIR-V, but the device binaries are handed over to the OpenCL and Intel Level Zero APIs, respectively.

Coarsely, the current process of translating the HIP code to SPIR-V in LLVM/Clang involves:

The HIPSPIRV experimental branch is available at 4. Note that it is not yet in a state we intend to propose for upstreaming, but shaping up the patches is a work in progress. Before proceeding to shape up and submit the patches, we would like to get feedback for the plans we have for upstreaming. In the following sections, we open up the above points further and sketch our plans for changes to LLVM (mostly to the Clang tool) to achieve the goal.

Retargeting device codegen

For making the HIP toolchain to emit and embed SPIR-V we are tentatively planning the following changes to the LLVM/Clang:

Address space mapping

Translating HIP device code to valid SPIR-V binary requires tweaks on pointers:

Pointers without address space (AS) qualification in HIP programs are considered “flat” pointers - they can point to function local, device, shared and constant memory space dynamically, which matches the idea of ‘generic’ pointers introduced in OpenCL 2.0. Therefore, the logical choice for the flat pointers is to map them to generic pointers of SPIR-V’s OpenCL environment. HIPCL’s and HIPLZ’s SPIR-V environment mandates that the kernel pointer parameters must point to __global, __local or __constant memory (these are named differently in SPIR-V; using OpenCL names as they are more familiar). So HIP pointer parameters in the HIP kernel (global) functions would be mapped to global pointers. Otherwise, HIP pointers with AS qualifiers are mapped to SPIR-V equivalent, if suitable.

Now, there are significant differences between HIP’s constant and SPIR-V/OpenCL’s constant address space:

There are a couple ways to deal with constants:

We plan to start by upstreaming the first option, and time permitting, improve by implementing the second option.

The planned changes to Clang to achieve the aforementioned AS mapping are as follows:

HIP code expansion

There are features in HIP language which do not have direct counterparts in SPIR-V’s OpenCL environment and those features need to be rewritten before translation to SPIR-V (in the future, lowering to SPIR-V machine code through the new BE). The non-exhaustive list of features that need to be expanded includes:

HIPCL/-LZ’s solution to the DSM allocation case is that the runtime allocates a shared buffer and passes it to the kernel as an additional argument (which is hidden from the user). The device code is modified so that the DSM object is replaced with the new kernel argument. Various other cases listed will be handled similarly:

For this and other HIP features we need to apply LLVM IR passes to perform modifications on the device code. In many cases the passes should be run when the device code (as LLVM bitcode) is fully linked. This is simply achieved as the HIP offload mechanism already emits device code as LLVM bitcode in RDC mode (-fgpu-rdc), so during linking we do receive the device code as LLVM bitcode where to apply these expansions with full view of the device code.

The current plan for implementing this is to make the HIPSPVToolChain to build a linker that uses llvm-link for linking device code, opt for running the IR passes needed and the external llvm-spirv tool (llc in the future when the SPIR-V BE lands) for emitting the SPIR-V binary. We load the passes from a path the user provides via --hip-link-pass-path (name pending) or automatically from HIP runtime’s installation location by using the search logic provided by ROCmInstallationDetector.

There is interest in upstreaming the HIPCL/-LZ passes from the HIPCL/-LZ repositories in the future for reduced maintenance burden. However, we are not attempting to upstream them initially, as they are not yet completed and are subject to rapid changes. Question is: Where should the passes eventually be put in within the LLVM project tree? Could it be OK to add a new directory under Clang for tool chain passes?

Testing

We will provide llvm-lit tests for our toolchain in the upstream. We also want to add tests to make sure clang who will run the HIPCL/-LZ runtime passes get run at device code link time. For this we need a dummy pass plugin that the clang loads during the test.

When the new LLVM SPIR-V BE work lands on LLVM, we will add SPIR-V assembly checks that are relevant for HIPSPV.

References


LLVM Developers mailing list llvm-dev at lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20210817/87bbd629/attachment.html>



More information about the llvm-dev mailing list