rust-gpu icon indicating copy to clipboard operation
rust-gpu copied to clipboard

Pass constants into #[spirv(compute(threads(...)))] ?

Open hrydgard opened this issue 4 years ago • 6 comments

Quite often, an algorithm will have a working data size configurable by a constant, and this size is correlated with the thread group size. Here's what I would like to do, but doesn't work:

const BUF_SIZE: u32 = 64;

// use BUF_SIZE to declare arrays and what not

#[spirv(compute(threads(BUF_SIZE, 1, 1)))]
pub fn main_cs(...) { ... }

Instead I have to fall back to:

#[spirv(compute(threads(64, 1, 1)))]  // 64 == BUF_SIZE

I guess the way attributes work might make this impossible? Or is there a way?

In GLSL/HLSL, this is trivial but that's because there's a preprocessor which just injects a #define-d value through text replacement.

hrydgard avatar Jul 29 '21 08:07 hrydgard

Seems like you might be able to use https://github.com/rust-lang/rust/pull/83366

DJMcNab avatar Jul 29 '21 14:07 DJMcNab

yeah! Would have to define a tiny macro though instead of using a constant :)

hrydgard avatar Jul 29 '21 14:07 hrydgard

Perhaps unsurprisingly, that doesn't actually work, unfortunately.

I've been investigating doing this properly, and it has me stumped.

Basically, I can't find any way to go from TyCtxt and a name (in some form) to a constant item (having spent a couple of hours poking at rust-analyzer's suggestions and reading the source code). I say it might be trivial because such a method might exist (I may as well ask @bjorn3, who I think is the person most likely to know). I can't think of any standard attributes which need to do name resolution (I doubt that you can define a niche based on a constant's value)

But if there is no way to do this, I have to take it as intentional - during the couse of my search this zulip message:

I had thought there were (well-established?) issues with putting variables/expressions into attributes, in terms of how that interacts with hygiene and name-resolution.

Although this is in a very specific context, so I might be over extrapolating.

If this is truly impossible, then one way we could do this is to abuse const generics, i.e. basically:

const N_THREADS: u64 = 100;
#[spirv(compute)]
fn my_entry_point(threads: NumberOfThreads<{N_THREADS}, 0, 0>){}

DJMcNab avatar Jul 31 '21 19:07 DJMcNab

Basically, I can't find any way to go from TyCtxt and a name (in some form) to a constant item (having spent a couple of hours poking at rust-analyzer's suggestions and reading the source code).

The Resolver no longer exists once the HIR is built. Rustdoc uses a hack to keep it alive for intra doc links, but this has caused ICEs and is impossible for hotpluggable codegen backends, only custom drivers can do this.

Clippy uses this function: https://github.com/rust-lang/rust-clippy/blob/43905d9f8d0f27d7ad71008bec9ef3c0b0982782/clippy_utils/src/lib.rs#L476 It doesn't handle for example hygiene though and it requires an absolute path.

bjorn3 avatar Jul 31 '21 19:07 bjorn3

Is there any reason the entry can't have const generic parameters?

#[spirv(compute)]
fn my_entry<N_THREADS>( .. ) { .. }

charles-r-earp avatar Aug 01 '21 03:08 charles-r-earp

That won't resolve to the const. It will introduce a completely new binding.

bjorn3 avatar Aug 01 '21 06:08 bjorn3

Closing this as a won't fix. Our hands are tied wrt Rust support, and we're not considering another design atm.

oisyn avatar Nov 17 '22 22:11 oisyn