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

Initialize LLVM's AMDGPU target machine, if available. #51548

Merged
merged 1 commit into from
Jul 3, 2018

Conversation

DiamondLovesYou
Copy link
Contributor

Note this isn't useful, yet. More changes will be necessary to be able to
actually codegen for this machine. As such, it is not enabled by default.

This patch is on its own for the benefit of the reviewers.

Note this isn't useful, yet. More changes will be necessary to be able to
actually codegen for this machine. As such, it is not enabled by default.

This patch is on its own for the benefit of the reviewers.
@rust-highfive
Copy link
Collaborator

r? @michaelwoerister

(rust_highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 14, 2018
@nicokoch
Copy link
Contributor

Will this enable Rust on the GPU in the long term? Is there any kind of RFC/tracking issue one can follow?

@LifeIsStrange
Copy link

LifeIsStrange commented Jun 14, 2018

Rust on the gpu would be fantastic, but this doesn't seems to be an extension to SYCL which support many languages, if it's standard rust, how will it work ?
Because from my understanding, a gpu has more constraints than cpus, e.g you must be able to specify if what you allocate is on the gpu, cpu or shared (unified memory), also some things like recursives are more restricted.
Wouldn't it be better to add rust support to SYCL ?

This doesn't seems to be difficult as it's more about removing feature support than adding them :)
For openCL "Function pointers, bit fields and variable-length arrays are omitted, recursion is forbidden.[17]"
https://en.m.wikipedia.org/wiki/OpenCL

And you should use the language agnostic SPIR-V back-end.
"In order to open the OpenCL programming model to other languages or to protect the kernel source from inspection, the Standard Portable Intermediate Representation (SPIR)[14] can be used as a target-independent way to ship kernels between a front-end compiler and the OpenCL back-end."

It's also more than openCL/SYCL, for example it's used by openGL and Vulkan (and others khronos apis) maybe even for WebGL-next), and HSA.

Rust could arguably be the best language for GPUs, and others accelerators.
I think this could be a massive improvment !

Edit [1]
There already exist many rust to SPIR-V back-end, the most mature seems to be the one of Google !
https://github.com/google/rspirv

There are others interesting results :
https://www.google.fr/search?q=rust+spirV&oq=rust+spirV&aqs=chrome..69i57j0&sourceid=chrome-mobile&ie=UTF-8

There was also this thread on reddit
https://www.reddit.com/r/rust/comments/42efnk/how_feasible_would_be_to_provide_a_spirv_target/?st=jiek8ei9&sh=9d7dc7cd

GPU computing enable massive optimisations and is already used by e.g Pathfinder @pcwalton
https://en.m.wikipedia.org/wiki/List_of_OpenCL_applications
Maybe it could benefit GFX-rs and vulkano too as openCL/SYCL will be merged in Vulkan according to khronos.
Maybe even rustc could be sped up with the GPU.
Also there are some growing domains like the Machine learning World, and the distributed calculus datacenters (and "Rust should be well-equipped for writing robust, high-scale servers" according to the roadmap rust-lang/rust-roadmap-2017#10) that increasingly use them and currently can't use rust for this.

Sorry for the long post.

@pmarcelll
Copy link
Contributor

@LifeIsStrange SYCL is just a nice C++ API/domain specific embedded language on top of OpenCL (there's actually two versions, SYCL 1.2.1 for OpenCL 1.2, and SYLC 2.2 for OpenCL 2.2), so adding support would mean designing something similar for Rust.
The important thing is the supported OpenCL version by the runtime, and there are some problems here. Although SPIR-V is supported by multiple technologies, there are actually two different flavors of it, one for OpneGL/Vulkan, and one for OpenCL 2.1+. Also, SPIR-V is used for shaders in Vulkan, so you only need something like rspirv to convert your shaders to SPIR-V, and this flavor of SPIR-V can be read by a simpler runtime, since IIRC if a GPU supports OpenGL 4.5, then it can probably support Vulkan. Compared to this, if you want to use OpenCL and SPIR-V, you need a runtime that supports OpenCL 2.1, and the compiler itself needs to generate SPIR-V from your source. And there's another problem here, the LLVM developers didn't agree to developing and maintaining SPIR-V support in upstream LLVM, only a couple of months ago there were talks about using Khronos's tools as plugins, which is also not an ideal solution.

@LifeIsStrange
Copy link

LifeIsStrange commented Jun 20, 2018

@pmarcell
Firstly thank you, you said many interesting things.
So when I was saying we need to add rust support for sycl was effectively meaningless as it's not language agnostic.

Quoting Wikipedia, "The OpenCL standard defines host APIs for C and C++; third-party APIs exist for other programming languages and platforms such as Python,[13] Java and .NET.[10]:15"
It would probably be very beneficial to study the github issues/rfcs of those languages.

Then we have two ways for adding rust support for GPUs, either we transpile rust to the c++ Subset that is sycl or to the OpenCL C or even to .NET.
This method (the reverse of the program corrode) would be quite Limited as rust support things that c++ can't support.

The other paradigm would be to port the same gpu restrictions and Syntax (eg the kernel entry point) and the few features (single source, runtime compilation, gpu host memory support and optionally unified memory) than sycl.
That way we would not use the openCL Neither the sycl implementations and so we could use SPIR-V and this would be supported on platforms without openCL 2.1 as rust would not use the openCL runtime at all.
And this would support new rust features without changes (while the first approach need to update the transpiler at every releases).

@pmarcelll
Copy link
Contributor

I think most of the higher level languages generate OpenCL code, which is JIT compiled by the runtime, so no IR is involved. JIT compiling the source code is the default mode of OpenCL 1.2, the Wikipedia article describes some of the problems with this approach. This also works in Rust today via an ordianry API binding (and the kernels are still OpenCL C), and in theory it is possible to create something like SYCL 1.2 for Rust, but it probably would be a more difficult project than SYCL itself.

The second paradigm you described is not possible. The generated SPIR-V is fed to the OpenCL runtime, which is part of the GPU driver itself, it first compiles the SPIR-V to GPU machine code, and then the driver feeds this machine code to the GPU for execution.

If these PRs are accepted, rustc will be able to generate a binary that contains both the CPU and the GPU (in this case AMD) machine code. Rustc can already target Nvidia GPUs, so it's theoretically possible to hack something together to target both GPU vendors, but it still wouldn't be universally usable, like OpenCL (and even OpenCL is not universally usable, the only version that is supported everywhere is 1.2, Nvidia doesn't support 2.0 because they prefer CUDA, and their 1.2 implementation is slower than CUDA, AMD only supports OpenCL 2.0 with their ROCm runtime, and Intel only supports OpenCL 2.1, so the one year old OpenCL 2.2 specification is implemented by exactly zero GPU manufacturers).

@OvermindDL1
Copy link

OvermindDL1 commented Jun 20, 2018

AMD only supports OpenCL 2.0 with their ROCm runtime, and Intel only supports OpenCL 2.1, so the one year old OpenCL 2.2 specification is implemented by exactly zero GPU manufacturers

I thought that was because they were both waiting for the OpenCL 2.2 frontend to land in LLVM mainline, which it is doing right now I think (or just finished)?

@pmarcelll
Copy link
Contributor

Landing it in upstream LLVM is important, but they could have implemented it in closed source drivers earlier.

BTW, sorry for spamming this PR with these conversations.

@OvermindDL1
Copy link

OvermindDL1 commented Jun 21, 2018

Landing it in upstream LLVM is important, but they could have implemented it in closed source drivers earlier.

AMD doesn't have closed source drivers anymore, the last update was over a year ago for it (AMDGPUPRO) and their open-source AMDGPU driver has overtaken it in all functionality now. :-)

/me quite likes that Intel and AMD are well made enough to use fully open source drivers now, unlike nVidia

But yeah, OpenCL 2.2 I think will come out in the drivers shortly after LLVM is released stable with it.

You can of course use OpenCL 2.2 to accelerate work on the CPU or computational cards currently, you are not limited to just the GPU unlike the poorly made cuda.

@pmarcelll
Copy link
Contributor

AMD released an updated to their closed driver very recently, see: https://www.phoronix.com/scan.php?page=news_item&px=Radeon-Software-18.20-Stable

And from the release notes:

  • Supported APIs: ..., OpenCL™1.2

They now have three different OpenCL runtimes: the legacy driver, ROCm, and the new PAL. See: https://www.phoronix.com/scan.php?page=news_item&px=ROCm-PAL-Future

The PAL runtime is also open source, but it's integrated into the closed driver (IIRC it will also become the official runtime on Windows). The PAL runtime seems to only support OpenCL 1.2 and ROCm is a non-standard implementation, it supports OpenCL 1.2, and extra AMD specific stuff. And OpenCL 2.1 is not part of either of them.

I also like that they open up most of the stack, but GPGPU is still a mess, which means it will be a lot harder for Rust to become a part of it.

@OvermindDL1
Copy link

OvermindDL1 commented Jun 21, 2018

Ah, I bet that is for some backwards compatibility bits. the AMDGPUPRO driver is used by some older setups (AMDGPU only supports 'newer' GPU's, like 5 years old or newer).

I also like that they open up most of the stack, but GPGPU is still a mess, which means it will be a lot harder for Rust to become a part of it.

Sounds like PR time? ;-)

@DiamondLovesYou
Copy link
Contributor Author

TBH, this whole ecosystem is a mess. Thankfully, targeting the GPU directly avoids most of this, though it has it's downsides.

@pietroalbini pietroalbini added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 25, 2018
@stokhos
Copy link

stokhos commented Jun 29, 2018

ping from triage @michaelwoerister will you have time to review this in near future?

@michaelwoerister
Copy link
Member

r? @alexcrichton

@alexcrichton
Copy link
Member

@bors: r+

@bors
Copy link
Contributor

bors commented Jul 2, 2018

📌 Commit b4d64b7 has been approved by alexcrichton

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jul 2, 2018
@Mark-Simulacrum
Copy link
Member

@bors rollup

Mark-Simulacrum added a commit to Mark-Simulacrum/rust that referenced this pull request Jul 2, 2018
…ne, r=alexcrichton

Initialize LLVM's AMDGPU target machine, if available.

Note this isn't useful, yet. More changes will be necessary to be able to
actually codegen for this machine. As such, it is not enabled by default.

This patch is on its own for the benefit of the reviewers.
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Jul 3, 2018
…ne, r=alexcrichton

Initialize LLVM's AMDGPU target machine, if available.

Note this isn't useful, yet. More changes will be necessary to be able to
actually codegen for this machine. As such, it is not enabled by default.

This patch is on its own for the benefit of the reviewers.
pietroalbini added a commit to pietroalbini/rust that referenced this pull request Jul 3, 2018
…ne, r=alexcrichton

Initialize LLVM's AMDGPU target machine, if available.

Note this isn't useful, yet. More changes will be necessary to be able to
actually codegen for this machine. As such, it is not enabled by default.

This patch is on its own for the benefit of the reviewers.
bors added a commit that referenced this pull request Jul 3, 2018
Rollup of 13 pull requests

Successful merges:

 - #51548 (Initialize LLVM's AMDGPU target machine, if available.)
 - #51809 (Add read_exact_at and write_all_at methods to FileExt on unix)
 - #51914 (add outlives annotations to `BTreeMap`)
 - #51958 (Show known meta items in unknown meta items error)
 - #51973 (Make Stdio handle UnwindSafe)
 - #51977 (bootstrap: tests should use rustc from config.toml)
 - #51978 (Do not suggest changes to str literal if it isn't one)
 - #51979 (Get rid of `TyImplTraitExistential`)
 - #51980 (Emit column info in debuginfo for non msvc like targets)
 - #51982 (incr.comp.: Take names of children into account when computing the ICH of a module's HIR.)
 - #51997 (add entry for cargo-metadata feature to RELEASES)
 - #52004 (toolstate: Fixed detection of changed submodule, and other fixes.)
 - #52006 ( Change --keep-stage to apply more often)

Failed merges:

r? @ghost
@bors bors merged commit b4d64b7 into rust-lang:master Jul 3, 2018
@DiamondLovesYou DiamondLovesYou deleted the amdgpu-target-machine branch July 3, 2018 18:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion.
Projects
None yet
Development

Successfully merging this pull request may close these issues.