pygfx / pyshader

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

Provide better debug info #53

Closed almarklein closed 4 years ago

almarklein commented 4 years ago

Closes #23

almarklein commented 4 years ago

As an example. Consider this shader:

from pyshader import Array, f32, i32, ivec3

def compute_shader(
    index: ("input", "GlobalInvocationId", ivec3),
    data1: ("buffer", 0, Array(f32)),
    data2: ("buffer", 1, Array(i32)),
):
    i = index.x
    arr = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
    for j in range(10):
        arr[j] = arr[j] * 2.0
    val_f = f32(arr[i])
    val_i = i32(arr[i])
    data1[i] = val_f + 1.0
    data2[i] = val_i + 1

import pyshader
pyshader.python2shader(compute_shader).to_spirv()

It has an error; when you try to compile this to SpirV it fails. Before this PR, you'd get:

Traceback (most recent call last):
  File "C:\dev\py\tmp.py", line 20, in <module>
    pyshader.python2shader(compute_shader).to_spirv()
  File "c:\dev\pylib\pyshader\pyshader\_module.py", line 39, in to_spirv
    gen.convert(self._bytecode)
  File "c:\dev\pylib\pyshader\pyshader\_generator_base.py", line 196, in convert
    self._convert(input)
  File "c:\dev\pylib\pyshader\pyshader\_generator_bc.py", line 130, in _convert
    method(*args)
  File "c:\dev\pylib\pyshader\pyshader\_generator_bc.py", line 1070, in co_binary_op
    + f"Cannot {op.upper()} two values with different (sub)types: {tn1} and {tn2}"
pyshader._coreutils.ShaderError: Cannot MUL two values with different (sub)types: i32 and f32

Not very useful - good luck finding your bug in a 100-line shader.

But with this new PR:

Traceback (most recent call last):
  File "C:\dev\py\tmp.py", line 20, in <module>
    pyshader.python2shader(compute_shader).to_spirv()
  File "c:\dev\pylib\pyshader\pyshader\_module.py", line 39, in to_spirv
    gen.convert(self._bytecode)
  File "c:\dev\pylib\pyshader\pyshader\_generator_base.py", line 196, in convert
    self._convert(input)
  File "c:\dev\pylib\pyshader\pyshader\_generator_bc.py", line 130, in _convert
    method(*args)
  File "c:\dev\pylib\pyshader\pyshader\_generator_bc.py", line 1070, in co_binary_op
    + f"Cannot {op.upper()} two values with different (sub)types: {tn1} and {tn2}"
pyshader._coreutils.ShaderError: 
  Source file "C:\dev\py\tmp.py", line 11
    arr[j] = arr[j] * 2.0
  Related variables: arr[..], 2.0
  Cannot MUL two values with different (sub)types: i32 and f32
Korijn commented 4 years ago

Would it be possible to also include the verbatim source line in the error message? It's probably a little easier to find the offending line that way?

Also in the example from your comment here, shouldn't that error say line 11 instead of 12?

almarklein commented 4 years ago

Ok, I seem to have been sloppy in creating that example. The source line is normally included, but I ran this interactively, so the filename is not something that can be used to load the source from. Also, in copying the source, I removed some code, and therefore the linenumbers do not match.

Anyway, the example is now updated.

almarklein commented 4 years ago

(it does show how the code falls back nicely when the filename is not os.path.isfile ;) )

Korijn commented 4 years ago

Awesome

almarklein commented 4 years ago

oh right ..... the bytecode now includes the source filename, which is different in CI than on my machine, so all tests fail on a bytecode mismatch ...