bheisler / blog-hugo-source

3 stars 0 forks source link

Comments for The State of GPGPU in Rust #1

Open bheisler opened 5 years ago

HadrienG2 commented 5 years ago

A couple of comments from someone who has played with GPGPU in the past, before concluding that it's currently too much of a minefield compared to how much of interest it is to my workplace.

Modern OpenCL (2.1+) does not force the use of OpenCL C anymore, but instead ingests a standardized variant of LLVM's IR called SPIR-V. It is then up to the GPU driver to transpile that into a device-specific binary, a much easier task than compiling a dialect of of C. Sadly, NVidia do not care much about compute standards, like any company in a position of power, and will not support anything higher than OpenCL 1.2 with some beta-quality 2.0 extensions. They also changed their tools (profiling, debugging...) a while ago in order to prevent them from correctly operating on OpenCL programs as they did before. The situation is so bad that a colleague of mine is transpiling his OpenCL code to CUDA when targeting NVidia GPUs (this is reasonably easy to do, unlike the reverse operation).

Unlike OpenGL, Vulkan was built to handle compute and to only accept SPIR-V shaders from day one. Compute is not an extension that is grafted on top of the graphics spec, every hardware that supports graphics is also required to support compute in order to comply with the Vulkan spec. For a while, NVidia tried to fight the use of SPIR-V by providing a vendor-specific extension to their Vulkan implementation which allows it to ingest GLSL. But since they do not have a monopoly in the graphics space, they eventually had to surrender and deprecate that extension. Personally, if I had to get back into GPU computing, I would seriously consider using Vulkan for this purpose nowadays. This would protect me from NVidia's anti-competitive practices (unlike Microsoft and Apple, they are not powerful enough to build a proprietary graphics ecosystem), at the cost of losing some manual optimization headroom (a few nice OpenCL concepts are not yet exposed in the Vulkan API) and portability (OpenCL can also target CPUs and FPGAs, Vulkan currently cannot).

OpenCL and Vulkan are both meant as infrastructure, rather than for direct end-user consumption. A developer will typically write a few hundred lines of "engine" code at the beginning in order to handle device detection and selection, then re-use that engine across all of his subsequent GPU codebases. CUDA has a similar layer under the hood, called the CUDA Driver API. If you want something like the "regular" CUDA API in the OpenCL ecosystem, you may want to look up SyCL, AFAIK no similar project has been attempted in Rust at this point in time.

Building an (end-user) CUDA equivalent in Rust needs an enormous amount of work, something which "regular" CUDA gets for free due to NVidia's corporate backing. Therefore, I am skeptical that you could reach parity with upstream CUDA, and keep that position over time. Further, before you go on and decide to help NVidia's proprietary technologies with your effort, you may want to look up how they treat their customers, and anything that looks like a threat to their monopoly:

Therefore, in my opinion, any open-source project which cares about a healthy hardware ecosystem should be doing anything it can to break NVidia's monopoly, and leave them the work of trying to sustain it.

bheisler commented 5 years ago

Therefore, I am skeptical that you could reach parity with upstream CUDA, and keep that position over time.

I think it's possible because most of the work is already done. The LLVM NVPTX backend and bindgen-generated wrappers around the CUDA API get us most of the way there. I just need to improve rustc so it stops crashing and generating invalid PTX files, and build out some supporting tooling.

Yeah, true parity with C is probably an overly ambitious goal, but that doesn't mean things can't be made better than they are.

If you don't like NVidia, you're perfectly free to build out your own tools. Is there an LLVM backend for SPIR-V? Is it integrated into rustc yet? That would probably be the place to start.

peterhj commented 5 years ago

If you are comfortable w/ writing CUDA C code, the cc crate already supports an nvcc mode, via my own PR :). An example build script using both bindgen and cc to expose CUDA C via FFI bindings can be found at: https://github.com/peterhj/gpudevicemem/blob/master/build.rs. Admittedly this workflow can be streamlined.

Note that cc also supports building on Windows, but its current nvcc support is Linux-centric since I don't have a Windows development environment.

crinklywrappr commented 5 years ago

FYI, managing cuda contexts can be a bit sticky.

Dithermaster commented 5 years ago

If you're looking for single-source model for but OpenCL, I'd recommend looking at SYCL (also mentioned by HadrienG2).

SPIR-V is the intermediate representation for OpenCL and Vulkan, so anything that can compile into SPIR-V can be used to write kernels. Unfortunately, there are OpenCL and Vulkan "flavors" of SPIR-V; you can't just take an OpenCL kernel and blindly run it on Vulkan, although Khronos is looking at the ability to run OpenCL kernels on Vulkan runtime (see clspv project).

kgreenek commented 5 years ago

@bheisler RE: llvm backend for spir-v, it looks like there is a stand-alone translator, and there is at least a desire to make it an official part of llvm soon: https://www.phoronix.com/scan.php?page=news_item&px=SPIRV-LLVM-Translator https://github.com/KhronosGroup/SPIRV-LLVM-Translator

I'm admittedly too new at this to understand how that could be integrated into rustc.

pinnaclesystemsgroup commented 4 years ago

Thanking everyone here for their comments and contributions on how to create a crate in Rust to leverage the CUDA.

Clearly, an effort to create a quality crate for Rust CUDA programming will require substantial effort by OSS contributors and a tacit approval by NVida to support the effort as it moves toward a production release of a Rust CUDA implementation. A draft formal written request for that approval addressed to NVida is being reviewed the Rust Language group.

The CUDA licensing issues to reverse engineer a Rust implementation using the current! supported C/C++ libraries is an outstanding challenge, but not one to prohibit or obstruct such an effort under the DCMA exception mechanism now enacted into law.

A more generalized, vendor-neutral abstraction layer for the Rust GPU library would be the preferred goal. This library could support other GPUs in a consistent manner and smooth the learning path other Rusticans would follow to build GPU applications in Rust.