4

Vcc: a Clang compiler for Vulkan

 8 months ago
source link: https://lwn.net/Articles/957269/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Vcc: a Clang compiler for Vulkan

[Posted January 9, 2024 by corbet]
The Vcc compiler has been announced.
It’s exactly what the name implies: a clang-based compiler that outputs code that runs on Vulkan.

Vcc can be thought of as a GLSL and HLSL competitor, but the true intent of this project is to retire the concept of shading languages entirely. Unlike existing shading languages, Vcc makes a honest attempt to bring the entire C/C++ language family to Vulkan, which means implementing a number of previously unseen features in Vulkan shaders


(Log in to post comments)

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 3:36 UTC (Wed) by atnot (subscriber, #124910) [Link]

This is technically very impressive and a cool research project.

I will draw attention to the lack of any benchmarks. In general, the reason that we don't run (standard) C and C++ on GPUs is not because that's been technically impossible, but because it's just mostly undesirable. GPU languages make it very easy to write embarrassingly parallel code and difficult to write code that performs badly, to the point of refusing to compile a lot of CPU idioms. This is a good thing.

Every language has a style of programming it encourages, C already copes badly with just basic multi-core simd scenarios and it doesn't really get any better on the GPU. If you've ever had to rely on autovectorization you know what I mean. Yes, Rust does a little bit better here but it's not even close.

> the true intent of this project is to retire the concept of shading languages entirely

We can see a version of how this goes with a brief look at FPGAs and ASICs. For decades now, the companies have invested millions a year into various "HLS" platforms for turning C into usable gateware and it has not yielded much except for a few niche use cases like ffmpeg. Certainly nobody uses them for developing high performance hardware. There's also a long trail of academics with background in cpu compilers claiming they'll fix hardware design with LLVM and failing (llhd, circt, ...). The reason is fairly simple: If you want to write efficient gateware you need to be thinking in terms of digital logic, networks of gates and combinatorial functions. Using HLS means lossily converting those concepts to C in your head and then the compiler has to re-derive those concepts and lossily convert back to gates. The result is that unless you try extremely hard, the output you get out will just be a big state machine that looks suspiciously like a PDP11 with hardcoded instructions churned through a logic optimizer.

There is definitely room for more expressive languages on the GPU and especially on FPGAs. But C isn't that. And I wish more people were exploring those genuinely exciting problem spaces instead of trying to squash these square dead horses through yet another round hole.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 9:29 UTC (Wed) by spacefrogg (subscriber, #119608) [Link]

I fully agree! There is more to hardware design than the common software developer is willing to admit. And all Algol-like sequential programming languages systematically fail to address the differences. So, adding another compiler won't fix anything.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 9:36 UTC (Wed) by spacefrogg (subscriber, #119608) [Link]

But to follow up on myself. There is a dire need for input language improvements for hardware design. This community is still programming in the 80s and it shows.

Much more than fancy object systems, though, does the hardware community need accessible proving systems (theorem provers, model checking etc.). You can hardly patch hardware in the field, so you must be able to identify unintended information leaks and instruction paths like recently seen in Apple SoCs or Intel or AMD or ARM...

This is where the community lacks completely. Describing a piece of hardware? Doable. Evaluating a complex hardware design? Obviously not possible anymore.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 12:40 UTC (Wed) by farnz (subscriber, #17727) [Link]

The problem is that such proof systems (for software or hardware) are an open area of research - dependently typed programming languages as one example. After all, being able to laboriously hand-prove that your system meets its specification (as was done for seL4) is not helpful if the system is changing rapidly, nor is it helpful if you deliberately limit your proven correctness to only cover the things that are easy to prove quickly and not the things that matter in the final system.

This, in turn, implies that you need proofs that can be machine-checked against the hardware description, that are simple to write, and that the tools that do the checking also assist you in understanding why your description does not meet the specification. We do this to a degree with type systems in software (e.g. Rust's Sync trait helping prove that your code doesn't contain data races), but not to the degree that hardware verification would like.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 15:29 UTC (Wed) by atnot (subscriber, #124910) [Link]

> This, in turn, implies that you need proofs that can be machine-checked against the hardware description, that are simple to write, and that the tools that do the checking also assist you in understanding why your description does not meet the specification.

The beauty of using different computation paradigms is that you get to avoid this whole circuitous process. Instead of writing some code in e.g. C, then a TLA+ model for that code, proving the equivalence of the two and then making proofs about that model, you could just code for TLA+ directly. Then you can write code normally, have the proofs inline as assertions and there's nothing to laboriously adjust or get out of sync. If we chose our primitives carefully, we might not even have to prove anything at all and our code will just have certain properties By Construction.

Of course on CPUs we don't do that because it's hard to turn that into efficient CPU assembly and people aren't used to thinking that way. But in hardware design this is ubiquitous and easy. Languages like verilog were actually originally built for formal verification and newer ones like bluespec are directly inspired by things like TLA+. You just write your model of how the hardware should behave, say "on every clock cycle, the value needs to be one larger than the last" and the toolchain figures out how to make that happen.

GPUs are admittedly a lot closer to CPUs in this regard, but there's still plenty to be lost here by moving to C-likes instead of embracing the unique parallel computational model of modern hardware.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 16:07 UTC (Wed) by farnz (subscriber, #17727) [Link]

On the other hand, when you write code in Agda, TLA+ or Bluespec, you're writing two things in the same language:

  1. A set of proofs that the code has the properties you want.
  2. The implementation that has those properties - bearing in mind that if your properties are well-specified, the implementation can be inferred for you by the compiler (anywhere where there's only one way to do it can be inferred, and where there's a common way to do it, that can be inferred unless you override it with a different implementation).

They're interlinked, so that you get the machine-checking and the assistance in understanding why your description does not meet the specification as part of the compilation process, but it's telling that none of the options for doing this sort of thing with software (Agda, Coq, Epigram, Idris, Alloy, TLA+, Lean, ATS, Eiffel) have made a significant impact on software development practices.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 16:20 UTC (Wed) by Vipketsh (guest, #134480) [Link]

> have the proofs inline as assertions

System Verilog has this and there are tools which try to prove correctness. Unfortunately, very often the result is "undetermined" without a whole bunch of manual inputs to the verification tool. Also not helping is the exponential runtime the tools have, though not much can be done about that short of proving P=NP.

From a practical perspective I get quite annoyed with such things. What happens is that people write assertions into code and then claim "formally verified" and it is thus "correct". However digging deeper turns out that there is actually no proof per-se just that the assertions didn't trigger during whatever stimuli where applied in testing, which not exactly a "proof" of anything. Also no one I talked to seems to have thought about if their assertions are anywhere close to complete or not. if your assertions aren't complete all you have is that your design has certain properties (which may be useful) but nothing is said about if the thing will actually work in the end.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 16:55 UTC (Wed) by farnz (subscriber, #17727) [Link]

That last bit ("if your assertions aren't complete all you have is that your design has certain properties") is really significant in terms of tooling; your tooling needs to help you build a proof that covers all the interesting properties of your design, even if at most of that proof is just "trust me" instead of a proper proof.

In turn, that forces you to have a way to have proofs that are incomplete for now (such as a "trust me" annotation), so that you can write out the full set of interesting properties that you want your code to have, and leave them mostly set to "trust me" in early development.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 17:51 UTC (Wed) by atnot (subscriber, #124910) [Link]

I think there's two things here. For one, there's definitely a spectrum of formal verificatedness. Using a Bounded Model Checker to prove that some assertion can't be violated within n cycles might not be a full rigorous proof, but it's still tremendously useful and extremely easy to do. It's certainly much better than guided fuzzing.

The second is that I think the popularity of Rust has shown the viability of just leaning heavily into correctness by construction. It turns out people are willing to give up a lot of convenience in uncommon cases for the peace of mind that comes with certain properties being easily provable (See once again: GPU languages). That avoids the whole "trust me" situation in the common case and can even accelerate development instead of hindering it. I think doing more of that is really the future.

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 11:08 UTC (Thu) by farnz (subscriber, #17727) [Link]

When we talk about "correctness by construction" in the Rust context, what we're actually talking about is machine-inferred proofs of correctness, with compiler errors where the machine is unable to prove that a construct is correct. And one of the selling points of Rust is that where the compiler cannot infer a proof of correctness, there are routes for you as the programmer to effectively override the compiler via unsafe code, telling the compiler that it can trust you to get it right.

Doing much better than Rust is still a research area for both software and hardware; it'd be nice to have a well-designed system for inferring more proofs, but that gets into a whole variety of interesting research. It's notable, for example, that Rust doesn't have user-defined auto-traits, nor does it have negative trait constraints, because both of those are open research areas right now.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 16:22 UTC (Wed) by Vipketsh (guest, #134480) [Link]

> Describing a piece of hardware? Doable.

The same as describing a piece of software is doable in assembly. Instead of SystemVerilog putting crazy amount of effort into incorporating C++ with changed syntax (objects, inheretence, etc.) and UVM junk, lot better results would be had if they moved the language into the direction where more high-level *hardware* structures are made available. e.g. Have a syntax for describing statemachines, efficient pipeline descriptions and so on.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 16:53 UTC (Wed) by atnot (subscriber, #124910) [Link]

> This community is still programming in the 80s and it shows.

People say this a lot and it always irks me. Not because it's wrong—it is painfully true—but because of the unwarranted dismissiveness it usually comes with. Software is just as stuck in the 80s as gateware is, they're just stuck in different ways. There are the distinctly 80s flavored syntax languages yes, the's the abundance of Tcl and the huge proprietary toolchains from companies that have clearly been phoning it in from their dominant market position for years. It's definitely a contrast to the vibrant cabrian explosion of programming languages and foss toolchains software has seen. But equally we have our own 80s languages, 80s OS designs and insist on using the same 80s computers and we barely even have any monopolists to blame.

And if there is much to be done about formal verification in the hardware world, I don't know what to say about software. In hardware it's ubiquitous and a job description a subatantial portion of the industry has made a career out of. In software it's a niche academic pursuit.

There's a lot to learn here in either direction. If anything what this shows is the need for tighter collaboration. But that is a different problem probably beyond the scope of this comment section.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 20:15 UTC (Wed) by Vipketsh (guest, #134480) [Link]

> In hardware it's ubiquitous

One problem of "formal verification" is not that same as another. What you often hear with "formal verification" in hardware is really "proof that the synthesis tool's input and output are functionally equivalent"*. That is very different from "I have a proof that my code has these properties" being discussed above.

The former is so common that no-one goes into manufacturing without such a proof and the whole ecosystem is geared toward making this proof happen even at the expense of performance/power/area (e.g. synthesis tools have avoided any state-machine recoding because of the difficulty it has in making the proof). The later has been successfully used a few times for some things (e.g. FPU designs) but as farnz said before this is an open area of research and nowhere as easy in practice as the sales people would have you believe.

* At least insofar as the tools themselves are correct. I have personally had cases where the formal verification tool has miss-interpreted the input the same way the synthesis tool did.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 23:24 UTC (Wed) by atnot (subscriber, #124910) [Link]

> What you often hear with "formal verification" in hardware is really "proof that the synthesis tool's input and output are functionally equivalent"*. That is very different from "I have a proof that my code has these properties" being discussed above.

This is sort of the opposite of what I've experienced. For example I know both people who work on the tooling side and someone who is a verification engineer at a well known british CPU core IP vendor. I don't want to risk getting anyone in trouble but they certainly seem to be running pretty cutting edge functional correctness verifications on almost every aspect of their designs. I don't get the impression they have a huge leg up on everyone else there either.
The tooling people are barely concerned about it in comparison. Sure, they run a bunch of equivalence checking, it's in their CI, but it's not really something they think about a lot.

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 7:13 UTC (Thu) by jem (subscriber, #24231) [Link]

There are two aspects to this. One thing is the formal verification that the design works exactly as intended. For example, a CPU should work exactly as specified in its reference manual. The other thing is what the implementation of the design also does, including things that are undesirable, like unintended information leaks. How can you formally prove that the final silicon does not leak information, when not even all leak mechanisms are yet known?

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 10:37 UTC (Thu) by farnz (subscriber, #17727) [Link]

CPU teams are unusual in the hardware world, in that they tend to have a complete formal specification of the architectural behaviour of the hardware, and they validate that the hardware design complies with that formal specification.

There's two things that are hidden in that statement, though, and that need unpacking. The first is that the specification only covers the architectural behaviour, and not microarchitectural behaviour; thus, things like timing-based side-channels are often not included in the specification at all, since the architecture is silent on side-channels. Second is that the formal specification does not have to define everything; for example, there are plenty of ARMv8 instructions where the formal specification of behaviour includes "UNDEFINED" (many of the system instructions have this as a possible outcome depending on PSTATE, for example, and PACDA/PACDZA are "UNDEFINED" if the appropriate feature flag is not set), and thus while your CPU may meet the formal specification, it still has a lot of room for surprising behaviour.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 20:31 UTC (Wed) by chris_se (subscriber, #99706) [Link]

> There is a dire need for input language improvements for hardware design.

Recently there was a very interesting talk about a completely new open CPU RISC-V design for FPGAs with modern CPU features, implemented in a Scala framework called SpinalHDL:

https://media.ccc.de/v/37c3-11777-open_cpu_soc_design_all...

I've never done anything related to chip design myself, so I can't really comment on the merits, but the fact that they could design an entire open CPU[*] with this that even runs Linux was very impressive to me from an outside perspective.

Links to the actual projects referenced in the video:

Scala-based HDL: https://github.com/SpinalHDL/SpinalHDL
64bit RISC-V CPU: https://github.com/SpinalHDL/VexiiRiscv

[*] Well, technically they still integrated 3rd-party components from LiteX <https://github.com/enjoy-digital/litex> for the memory controller and I/O to make this more of a SOC for their demo, but the actual CPU part itself is a completely new design.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 22:55 UTC (Wed) by atnot (subscriber, #124910) [Link]

There's actually a number of exciting newer open HDLs like this. Most have at least one RISC-V core written in them, a lot of them Linux capable too. Most of them aren't anywhere near as good as vexriscv of course but it's actually a surprisingly attainable project if you have around half a year of weekends to spare.

They generally fall into two categories, which I've seen called native HDLs and meta HDLs.

Meta HDLs are things like SpinalHDL, Chisel, Amaranth, MyHDL, Hardcaml and many more. You write code in a host language like Python that builds a big data structure that describes your design, and then dump it out as a big verilog file. They're pretty popular because they're easy to make and much more pleasant to do metaprogramming in than things like standard verilog. Think of it like programming by writing scripts that output LLVM IR. Very powerful, but also a bit clumsy. But because they're just fancy macro tools, they're pretty restricted to what can be done in their host language.

This is different from native HDLs like (System) Verilog and VHDL, which work the traditional way by having bespoke syntax with a parser, passes etc. There's a lot fewer of these in active development: Bluespec SV, PipelineC, Silice, Spade, that's about it. Of those only Bluespec has any significant users. This is generally what people mean when they complain about the state of input languages and where there's a lot of potential to improve things.

Vcc: a Clang compiler for Vulkan

Posted Jan 10, 2024 20:41 UTC (Wed) by airlied (subscriber, #9104) [Link]

When you write a GLSL shader (take compute shader for an example) you don't worry about vectorization or any of that, it gets executed in parallel depending on the workgroup sizing parameters given. This just replaces that GLSL with C.

It's just a nicer GLSL/HLSL instead of one of those trying to auto vectorise straight C code and have it work.

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 15:46 UTC (Thu) by spacefrogg (subscriber, #119608) [Link]

If this were true, then Vcc would consume C/C++ lookalike source code, with wildly different semantics CPU code. Otherwise you would have to worry about vectorization and describe that properly. So, which of the two is it in Vcc?

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 16:36 UTC (Thu) by farnz (subscriber, #17727) [Link]

Vcc outputs SPIR-V, which is a single-program, single-thread bytecode. The GPU drivers read in SPIR-V and use it as part of an SPMD compilation process, where the SPIR-V bytecode provides the program, and the driver extends it to support multiple data items in parallel (vectorization, threading).

The only difficulty is that you'll have to think a bit about divergent control flow in your C source code fed into Vcc, since most GPU drivers handle divergence between SIMD lanes via masking, so you can have performance problems where only one lane of 8 to 64 (depending on the GPU) is producing useful data, and the others are masked off due to divergent control flow. But this is already an issue with GLSL, HLSL, Metal SL and other shading languages; it's not a new problem.

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 10:44 UTC (Thu) by farnz (subscriber, #17727) [Link]

I would note that one of the problems with GLSL (and HLSL, Metal SL etc) is that while these are C-like languages, they're relatively challenging to test. You need to run the shader on the GPU, where you have no access to a debug console or an inspection tool for shader state; making it possible to write your shader program in C (or C++, or Rust, or Python, or Java) means that you can do much of the debugging of a shader on the CPU, and only need the GPU for cases where the bug requires GPU-level concurrency to show up.

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 11:06 UTC (Thu) by atnot (subscriber, #124910) [Link]

You'd think so but I disagree for two reasons. For one it's perfectly possible to execute existing GPU languages on the CPU already. However, nobody does it because more importantly, the data shaders deal with is usually highly complex multi-dimensional data that is just hard to test out of context. Printf or a debugger would only let you see "ah yes at x=1.23013,y=15.1849, u=0.1324,v=0.4362 delivering a value of rgb(0.31, 0.48, 0.93)" which is just meaningless without more context. But if you just output the coordinates to a texure as a color and look it at in something like renderdoc, it'll be super obvious.

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 4:02 UTC (Thu) by kloczek (guest, #6391) [Link]

Cannot find vcc github repo.
Someone know where it is?🤔

Vcc: a Clang compiler for Vulkan

Posted Jan 11, 2024 4:59 UTC (Thu) by passcod (subscriber, #167192) [Link]

It's a bit unclear, but it's apparently part of the repo for their "shady" project, linked in the article: https://github.com/Hugobros3/shady/blob/master/src/driver...

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK