taichi icon indicating copy to clipboard operation
taichi copied to clipboard

cornell_box.py example doesn't work on macOS with Metal backend

Open curldivergence opened this issue 1 year ago • 1 comments

Describe the bug Hi, I'm trying to run the latest taichi release (upd: and the latest nightly build - [Taichi] version 1.8.0, llvm 15.0.7, commit 52b24f3e, osx, python 3.11.7, outcome is the same) on macOS, but unfortunately, the Cornell Box sample fails to start. Other samples (in particular, sdf_renderer.py) seem to work.

To Reproduce

  1. Run
ti gallery
  1. Click on the Cornell Box icon
  2. Observe the error

Log/Screenshots

> ti gallery
[Taichi] version 1.7.0, llvm 15.0.7, commit 2fd24490, osx, python 3.11.7

*******************************************
**      Taichi Programming Language      **
*******************************************

Docs:   https://docs.taichi-lang.org/
GitHub: https://github.com/taichi-dev/taichi/
Forum:  https://forum.taichi.graphics/

Demo source code:

    1 # pylint: disable=W0622,W0621,W0401
    2 import taichi as ti
    3 from taichi.math import *
    4
    5 ti.init(arch=ti.gpu, default_ip=ti.i32, default_fp=ti.f32)
    6
    7 image_resolution = (512, 512)
    8 image_buffer = ti.Vector.field(4, float, image_resolution)
    9 image_pixels = ti.Vector.field(3, float, image_resolution)
   10
   11 Ray = ti.types.struct(origin=vec3, direction=vec3, color=vec3)
   12 Material = ti.types.struct(albedo=vec3, emission=vec3)
   13 Transform = ti.types.struct(position=vec3, rotation=vec3, scale=vec3, matrix=mat3)
   14 SDFObject = ti.types.struct(distance=float, transform=Transform, material=Material)
   15
   16 objects = SDFObject.field(shape=8)
   17 objects[0] = SDFObject(
   18     transform=Transform(vec3(0, 0, -1), vec3(0, 0, 0), vec3(1, 1, 0.2)),
   19     material=Material(vec3(1, 1, 1) * 0.4, vec3(1)),
   20 )
   21 objects[1] = SDFObject(
   22     transform=Transform(vec3(0, 1, 0), vec3(90, 0, 0), vec3(1, 1, 0.2)),
   23     material=Material(vec3(1, 1, 1) * 0.4, vec3(1)),
   24 )
   25 objects[2] = SDFObject(
   26     transform=Transform(vec3(0, -1, 0), vec3(90, 0, 0), vec3(1, 1, 0.2)),
   27     material=Material(vec3(1, 1, 1) * 0.4, vec3(1)),
   28 )
   29 objects[3] = SDFObject(
   30     transform=Transform(vec3(-1, 0, 0), vec3(0, 90, 0), vec3(1, 1, 0.2)),
   31     material=Material(vec3(1, 0, 0) * 0.5, vec3(1)),
   32 )
   33 objects[4] = SDFObject(
   34     transform=Transform(vec3(1, 0, 0), vec3(0, 90, 0), vec3(1, 1, 0.2)),
   35     material=Material(vec3(0, 1, 0) * 0.5, vec3(1)),
   36 )
   37 objects[5] = SDFObject(
   38     transform=Transform(vec3(-0.275, -0.3, -0.2), vec3(0, 112, 0), vec3(0.25, 0.5, 0.25)),
   39     material=Material(vec3(1, 1, 1) * 0.4, vec3(1)),
   40 )
   41 objects[6] = SDFObject(
   42     transform=Transform(vec3(0.275, -0.55, 0.2), vec3(0, -197, 0), vec3(0.25, 0.25, 0.25)),
   43     material=Material(vec3(1, 1, 1) * 0.4, vec3(1)),
   44 )
   45 objects[7] = SDFObject(
   46     transform=Transform(vec3(0, 0.809, 0), vec3(90, 0, 0), vec3(0.2, 0.2, 0.01)),
   47     material=Material(vec3(1, 1, 1) * 1, vec3(100)),
   48 )
   49
   50
   51 @ti.real_func
   52 def rotate(a: vec3) -> mat3:
   53     s, c = sin(a), cos(a)
   54     return (
   55         mat3(c.z, s.z, 0, -s.z, c.z, 0, 0, 0, 1)
   56         @ mat3(c.y, 0, -s.y, 0, 1, 0, s.y, 0, c.y)
   57         @ mat3(1, 0, 0, 0, c.x, s.x, 0, -s.x, c.x)
   58     )
   59
   60
   61 @ti.real_func
   62 def signed_distance(obj: SDFObject, pos: vec3) -> float:
   63     p = obj.transform.matrix @ (pos - obj.transform.position)
   64     q = abs(p) - obj.transform.scale
   65     return length(max(q, 0)) + min(max(q.x, max(q.y, q.z)), 0)
   66
   67
   68 @ti.real_func
   69 def nearest_object(p: vec3) -> (int, float):
   70     index, min_dis = 0, 1e32
   71     for i in ti.static(range(8)):
   72         dis = signed_distance(objects[i], p)
   73         if dis < min_dis:
   74             min_dis, index = dis, i
   75     return index, min_dis
   76
   77
   78 @ti.real_func
   79 def calc_normal(obj: SDFObject, p: vec3) -> vec3:
   80     e = vec2(1, -1) * 0.5773 * 0.005
   81     return normalize(
   82         e.xyy * signed_distance(obj, p + e.xyy)
   83         + e.yyx * signed_distance(obj, p + e.yyx)
   84         + e.yxy * signed_distance(obj, p + e.yxy)
   85         + e.xxx * signed_distance(obj, p + e.xxx)
   86     )
   87
   88
   89 @ti.real_func
   90 def raycast(ray: Ray) -> (SDFObject, vec3, bool):
   91     w, s, d, cerr = 1.6, 0.0, 0.0, 1e32
   92     index, t, position, hit = 0, 0.005, vec3(0), False
   93     for _ in range(64):
   94         position = ray.origin + ray.direction * t
   95         index, distance = nearest_object(position)
   96
   97         ld, d = d, distance
   98         if ld + d < s:
   99             s -= w * s
  100             t += s
  101             w *= 0.5
  102             w += 0.5
  103             continue
  104         err = d / t
  105         if err < cerr:
  106             cerr = err
  107
  108         s = w * d
  109         t += s
  110         hit = err < 0.001
  111         if t > 5.0 or hit:
  112             break
  113     return objects[index], position, hit
  114
  115
  116 @ti.real_func
  117 def hemispheric_sampling(normal: vec3) -> vec3:
  118     z = 2.0 * ti.random() - 1.0
  119     a = ti.random() * 2.0 * pi
  120     xy = sqrt(1.0 - z * z) * vec2(sin(a), cos(a))
  121     return normalize(normal + vec3(xy, z))
  122
  123
  124 @ti.real_func
  125 def raytrace(ray: Ray) -> Ray:
  126     for _ in range(3):
  127         object, position, hit = raycast(ray)
  128         if not hit:
  129             ray.color = vec3(0)
  130             break
  131
  132         normal = calc_normal(object, position)
  133         ray.direction = hemispheric_sampling(normal)
  134         ray.color *= object.material.albedo
  135         ray.origin = position
  136
  137         intensity = dot(ray.color, vec3(0.299, 0.587, 0.114))
  138         ray.color *= object.material.emission
  139         visible = dot(ray.color, vec3(0.299, 0.587, 0.114))
  140         if intensity < visible or visible < 0.000001:
  141             break
  142     return ray
  143
  144
  145 @ti.kernel
  146 def build_scene():
  147     for i in objects:
  148         rotation = radians(objects[i].transform.rotation)
  149         objects[i].transform.matrix = rotate(rotation)
  150
  151
  152 @ti.kernel
  153 def render(camera_position: vec3, camera_lookat: vec3, camera_up: vec3):
  154     for i, j in image_pixels:
  155         z = normalize(camera_position - camera_lookat)
  156         x = normalize(cross(camera_up, z))
  157         y = cross(z, x)
  158
  159         half_width = half_height = tan(radians(35) * 0.5)
  160         lower_left_corner = camera_position - half_width * x - half_height * y - z
  161         horizontal = 2.0 * half_width * x
  162         vertical = 2.0 * half_height * y
  163
  164         uv = (vec2(i, j) + vec2(ti.random(), ti.random())) / vec2(image_resolution)
  165         po = lower_left_corner + uv.x * horizontal + uv.y * vertical
  166         rd = normalize(po - camera_position)
  167
  168         ray = raytrace(Ray(camera_position, rd, vec3(1)))
  169         buffer = image_buffer[i, j]
  170         buffer += vec4(ray.color, 1.0)
  171         image_buffer[i, j] = buffer
  172
  173         color = buffer.rgb / buffer.a
  174         color = pow(color, vec3(1.0 / 2.2))
  175         color = (
  176             mat3(
  177                 0.597190,
  178                 0.35458,
  179                 0.04823,
  180                 0.07600,
  181                 0.90834,
  182                 0.01566,
  183                 0.02840,
  184                 0.13383,
  185                 0.83777,
  186             )
  187             @ color
  188         )
  189         color = (color * (color + 0.024578) - 0.0000905) / (color * (0.983729 * color + 0.4329510) + 0.238081)
  190         color = (
  191             mat3(
  192                 1.60475,
  193                 -0.531,
  194                 -0.0736,
  195                 -0.102,
  196                 1.10813,
  197                 -0.00605,
  198                 -0.00327,
  199                 -0.07276,
  200                 1.07602,
  201             )
  202             @ color
  203         )
  204         image_pixels[i, j] = clamp(color, 0, 1)
  205
  206
  207 def main():
  208     window = ti.ui.Window("Cornell Box", image_resolution)
  209     canvas = window.get_canvas()
  210     build_scene()
  211     while window.running:
  212         render(vec3(0, 0, 3.5), vec3(0, 0, -1), vec3(0, 1, 0))
  213         canvas.set_image(image_pixels)
  214         window.show()
  215
  216
  217 if __name__ == "__main__":
  218     main()
  219
[Taichi] version 1.7.0, llvm 15.0.7, commit 2fd24490, osx, python 3.11.7
[Taichi] Starting on arch=metal
[E 02/24/24 13:10:29.644 2395910] [spirv_ir_builder.cpp:query_value@1316] Value "tmp26" does not yet exist.


Traceback (most recent call last):
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/examples/real_func/rendering/cornell_box.py", line 218, in <module>
    main()
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/examples/real_func/rendering/cornell_box.py", line 210, in main
    build_scene()
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/lang/kernel_impl.py", line 1103, in wrapped
    return primal(*args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/lang/kernel_impl.py", line 1035, in __call__
    return self.launch_kernel(kernel_cpp, *args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/lang/kernel_impl.py", line 966, in launch_kernel
    raise e from None
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/lang/kernel_impl.py", line 959, in launch_kernel
    compiled_kernel_data = prog.compile_kernel(prog.config(), prog.get_device_caps(), t_kernel)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
RuntimeError: [spirv_ir_builder.cpp:query_value@1316] Value "tmp26" does not yet exist.
>>> Running time: 5.81s

Additional comments Here is the output of ti diagnose:

> ti diagnose
[Taichi] version 1.7.0, llvm 15.0.7, commit 2fd24490, osx, python 3.11.7

*******************************************
**      Taichi Programming Language      **
*******************************************

Docs:   https://docs.taichi-lang.org/
GitHub: https://github.com/taichi-dev/taichi/
Forum:  https://forum.taichi.graphics/

Taichi system diagnose:

python: 3.11.7 (main, Dec  4 2023, 18:10:11) [Clang 15.0.0 (clang-1500.1.0.2.5)]
system: darwin
executable: /opt/homebrew/opt/[email protected]/bin/python3.11
platform: macOS-14.3.1-arm64-arm-64bit
architecture: 64bit
uname: uname_result(system='Darwin', node='macbook.local', release='23.3.0', version='Darwin Kernel Version 23.3.0: Wed Dec 20 21:30:44 PST 2023; root:xnu-10002.81.5~7/RELEASE_ARM64_T6000', machine='arm64')
/opt/homebrew/lib/python3.11/site-packages/taichi/tools/diagnose.py:20: DeprecationWarning: 'locale.getdefaultlocale' is deprecated and slated for removal in Python 3.15. Use setlocale(), getencoding() and getlocale() instead.
  print(f'locale: {".".join(locale.getdefaultlocale())}')
Traceback (most recent call last):
  File "/opt/homebrew/bin/ti", line 8, in <module>
    sys.exit(main())
             ^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/_main.py", line 897, in main
    return cli()
           ^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/_main.py", line 33, in wrapper
    result = func(*args, **kwargs)
             ^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/_main.py", line 92, in __call__
    return getattr(self, args.command)(sys.argv[2:])
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/_main.py", line 806, in diagnose
    diagnose.main()
  File "/opt/homebrew/lib/python3.11/site-packages/taichi/tools/diagnose.py", line 20, in main
    print(f'locale: {".".join(locale.getdefaultlocale())}')
                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: sequence item 0: expected str instance, NoneType found

curldivergence avatar Feb 24 '24 12:02 curldivergence

Same issue. Same environment.

Lucascuibu avatar Mar 19 '24 13:03 Lucascuibu