pygfx / pyshader

Write modern GPU shaders in Python!
BSD 2-Clause "Simplified" License
72 stars 1 forks source link

Error processing resulting SPIR-V shader in Vulkan 1.2.x (Kompute v0.4.2) #59

Closed axsaucedo closed 3 years ago

axsaucedo commented 3 years ago

Great project, thank you for creating it. I'm currently working on using it to integrate with our Vulkan Kompute project specifically through the Kompute Python SDK.

The initial basic example I have to showcase the workflow is a basic multiplication operation as follows:

from kp import Tensor, Manager, Sequence
from pyshader import python2shader, f32, ivec3, Array

# Define simple multiplication shader
@python2shader
def compute_shader_multiply(index: ("input", "GlobalInvocationId", ivec3),
                            data1: ("buffer", 0, Array(f32)),
                            data2: ("buffer", 1, Array(f32)),
                            data3: ("buffer", 2, Array(f32))):
    i = index.x
    data3[i] = data1[i] * data2[i]

# Create tensors that we'll be using
tensor_in_a = Tensor([2, 2, 2])
tensor_in_b = Tensor([1, 2, 3])
tensor_out = Tensor([0, 0, 0])

# Default manager (chooses device 0 and first compute capable queue)
mgr = Manager()

# Initialise the GPU memory & buffers
mgr.eval_tensor_create_def([tensor_in_a, tensor_in_b, tensor_out])

# Run the compute shader
mgr.eval_algo_data_def([tensor_in_a, tensor_in_b, tensor_out], compute_shader_multiply.to_spirv())

# Map the data back to local 
mgr.eval_tensor_sync_local_def([tensor_out])

# Confirm successful operation
assert tensor_out.data() == [2.0, 4.0, 6.0]

Unfortunately when running this, it seems to fail when creating the Vulkan Pipeline, which seems to be due to an error on the shader structure, namely the error is Error reading file: #, which seems to happen if the shader doesn't have the expected structure.

When introspecting the shader I don't think it's possible to specify things like the version of the shader, if you look at the current shader that works correctly (this is the glsl code), the main difference is that it contains the #version 450 definition.

Have you come across this issue before? I would be quite keen to get this working, as I'm planning to write a blog post similar to the ones outlined in the end to end examples and integration with this would make it fully pythonic, so I'd be keen to do it using this library.

Thanks, let me know if you need further details to get more insights on what may be the issue.

Edit: If you would like to try running the example above, there is a slight fix required that is currently in the branch python_shader_extension, which would require running pip install . from that branch to install the kompute Python package.

axsaucedo commented 3 years ago

It seems that the issue was not with the PyShader library but with the interface in the eval_op_algo_data_def function. It actually works correctly, I initially confirmed this by dumping the bytes into a file and running it, and now I've fixed it so the code above runs as expected. Thank you, I'll share the blog post once it's published 👍

almarklein commented 3 years ago

[...] our Vulkan Kompute project

Impressive!