用vulkan进行双精度计算时,哪些运算符不能用?

我在使用默认的ti.init(arch = ti.vulkan)计算时没有报错,但加上default_fp=ti.f64之后有如下报错

[E 10/11/23 17:43:21.712 37532] [spirv_codegen.cpp:taichi::lang::spirv::`anonymous-namespace'::TaskCodegen::visit@866] Instruction Exp(27) does not 64bits operation


Traceback (most recent call last):
  File "c:\Users\liuyu\Desktop\taichi new shear rate\run_simlation.py", line 62, in <module>
    solver.step()
    ^^^^^^^^^^^^^
  File "c:\Users\liuyu\Desktop\taichi new shear rate\sph_base.py", line 259, in step
    self.substep()
  File "c:\Users\liuyu\Desktop\taichi new shear rate\WCSPH.py", line 724, in substep
    self.compute_As__sound_velocity__pressure()
  File "C:\Users\liuyu\anaconda3\Lib\site-packages\taichi\lang\kernel_impl.py", line 1033, in __call__
    return self._primal(self._kernel_owner, *args, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\liuyu\anaconda3\Lib\site-packages\taichi\lang\kernel_impl.py", line 906, in __call__
    return self.runtime.compiled_functions[key](*args)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\liuyu\anaconda3\Lib\site-packages\taichi\lang\kernel_impl.py", line 817, in func__
    raise e from None
  File "C:\Users\liuyu\anaconda3\Lib\site-packages\taichi\lang\kernel_impl.py", line 814, in func__
    t_kernel(launch_ctx)
RuntimeError: [spirv_codegen.cpp:taichi::lang::spirv::`anonymous-namespace'::TaskCodegen::visit@866] Instruction Exp(27) does not 64bits operation

请问是哪个运算是不支持双精度的呢?

此外还有一个发现,vulkan的单精度计算居然比使用cuda backend 快诶,好神奇

目前Vulkan后端的双精度支持确实比较混乱,看代码里面下面这些操作不支持fp64:

    UNARY_OP_TO_SPIRV(sin, Sin, 13, 32)
    UNARY_OP_TO_SPIRV(asin, Asin, 16, 32)
    UNARY_OP_TO_SPIRV(cos, Cos, 14, 32)
    UNARY_OP_TO_SPIRV(acos, Acos, 17, 32)
    UNARY_OP_TO_SPIRV(tan, Tan, 15, 32)
    UNARY_OP_TO_SPIRV(tanh, Tanh, 21, 32)
    UNARY_OP_TO_SPIRV(exp, Exp, 27, 32)
    UNARY_OP_TO_SPIRV(log, Log, 28, 32)

我的代码里应该是用了ti.exp来计算一个field的值,请问这个有什么办法吗?未来vulkan backend会支持这些双精度操作吗?

我建议先试试CUDA,CUDA是专门给桌面端/服务端显卡用的,所以对于高精度支持比较完善

Vulkan的问题在于他即支持桌面端显卡,也支持移动端显卡。所以双精度对他来说是个额外的extension,不是所有设备都能支持的。也因此部分操作生成fp64对于SpirV来说相对没那么好支持。

我是发现在单精度下vulkan比cuda算的更快(我用的显卡是nvidia 3060ti),所以我想之后就一直用vulkan的。

找到一个折中的办法,在算这些操作时可以暂时把他们转换为单精度

#some_field[i] = ti.exp(some_field[i])
some_field[i] = ti.exp(ti.cast(some_field[i], ti.f32))