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

Cross-kernel influence in binding allocation #614

Closed
kpet opened this issue Aug 3, 2020 · 5 comments
Closed

Cross-kernel influence in binding allocation #614

kpet opened this issue Aug 3, 2020 · 5 comments

Comments

@kpet
Copy link
Contributor

kpet commented Aug 3, 2020

Clvk currently assumes that the highest binding number in a descriptor set is less than the number of resources that require a binding. This no longer seems to be true with recent versions of clspv (kpet/clvk#233). While accomodating this in clvk is trivial, I wanted to double check that this bit of clspv behaviour was expected before doing so. Specifically, it seems that in some cases bindings for one kernel are allocated after those for another kernel. Consider the following code:

kernel void k0(int v, local int* l, global int* b){}
kernel void k1(global int* b){}

which leads to the following descriptor map:

kernel_decl,k0
kernel,k0,arg,l,argOrdinal,1,argKind,local,arrayElemSize,4,arrayNumElemSpecId,3
kernel,k0,arg,b,argOrdinal,2,descriptorSet,0,binding,0,offset,0,argKind,buffer
kernel,k0,arg,v,argOrdinal,0,offset,0,argKind,pod_pushconstant,argSize,4
kernel_decl,k1
kernel,k1,arg,b,argOrdinal,0,descriptorSet,0,binding,2,offset,0,argKind,buffer
spec_constant,workgroup_size_x,spec_id,0
spec_constant,workgroup_size_y,spec_id,1
spec_constant,workgroup_size_z,spec_id,2

Generally, this seems to happen when there are POD and local arguments. I haven't looked into the details.

Is this expected behaviour? If yes, what is the rationale for this behaviour?

@alan-baker
Copy link
Collaborator

If the sample was rewritten as:

kernel void k0(global int* b, int v, local int* l){}
kernel void k1(global int* b){}

Clspv would reuse binding 0 for by k0 and k1 b arguments. Currently clspv only shares bindings when the argument index and types match. This allows code generation to generate a single variable for the descriptor set and binding pair. That's why you end up with binding 2.

There are improvements in this regard. For example, DirectResourceAccess attempts to leverage reused bindings to avoid variable pointers. It should be the other way around and AllocateDescriptors should consider which resources can be shared before assigning bindings (a sort of graph colouring problem). Any change here though would necessitate changes in the SPIR-V producer to generate variables differently. This isn't necessarily difficult, but it is not currently accounted for.

@kpet
Copy link
Contributor Author

kpet commented Aug 16, 2020

I see, makes sense. Thank you for the explanation. I'm amazed I'm only bumping into this now! I'll push a fix to clvk.

@rjodinchr
Copy link
Collaborator

@kpet, Can we close this issue now?

@kpet
Copy link
Contributor Author

kpet commented Mar 29, 2023

Maybe @alan-baker wants to keep it to track his suggested improvements. Maybe a new issue would be better. I'm fine with closing it if Alan's fine.

@alan-baker
Copy link
Collaborator

I've filed #1061.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants