Taichi 语言是否能应对流体计算的需求
时间:2022-10-27 23:20:07 阅读:99
Taichi 作为图形学研究的工具而诞生,使得其天生就具备了很多为大规模数值计算准备的数据结构和并行运算加速机制。同时,作为一门内嵌在 Python 中的领域特定语言(DSL),你可以直接用 Python 来处理不需要高性能并行计算的部分,而把 Taichi 专门用在需要大量并行运算的代码上。
用 Taichi 来加速流场求解中需要大规模并行运算的部分
我们再次以上面的欧拉视角流体算法为例。
数据结构
为了让 Taichi 将求解部分的计算进行并行化处理,我们需要将流场数据保存成 Taichi 提供的 field 的形式。对于流体计算中经常出现的标量场和向量场,Taichi 都提供了对应的数据结构。比如一个 640x480 的由浮点数组成的标量场可以表示为:
f_2d = ti.field(float, shape=(640, 480))
类似的,一个 640x480 的 2 维向量场可以表示为:
v_2d = ti.Vector.field(n=2, dtype=float, shape=(640, 480))
除此之外,Taichi 中还提供了 Matrix 场以及自定义 Struct 场等更多丰富的数据结构,有兴趣的读者可以参阅官方文档的 field 的相关部分。
并行加速机制
假设我们要计算上面的 f_2d 这个标量场印加拉普拉斯算子的结果,我们可以先申请一个用来保存结果的场:
f_2d_grad2 = ti.field(float, shape=(640, 480))
然后我们需要遍历 f_2d_grad2 中的元素,计算其在施加了拉普拉斯算子后的值。为了方便地遍历场中的元素,Taichi 提供了好用的 struct-for 语句:
for i,j in f_2d_grad2:
f_2d_grad2[i,j] = 4 * f_2d[i,j] - f_2d[i-1,j] \
- f_2d[i+1,j] - f_2d[i,j-1] - f_2d[i,j+1]
不过上面的 struct-for 语句是 Taichi 的语法,并不能被 Python 处理。为了让 Taichi 来接管并加速这个计算,我们需要把上述计算包裹成一个 Taichi kernel:
@ti.kernel
def fgrad2():
for i,j in f_2d_grad:
f_2d_grad2[i,j] = 4 * f_2d[i,j] - f_2d[i-1,j] \
- f_2d[i+1,j] - f_2d[i,j-1] - f_2d[i,j+1]
这里的装饰器 @ti.kernel 就是所有 Taichi 加速魔法的入口,它的工作可以理解为接收并分析我们的函数代码,并返回一个自动并行化版本的函数:
fgrad2_ti = ti.kernel(fgrad2)
最后当我们调用这个函数的时候,程序就会把控制从 Python 交入 Taichi 手中,并在多个核心上并行执行上述运算,从而达到大大提升计算速度的目的。
数据可视化
Taichi 提供了内建的一个简易 GUI 系统,可以在构建数值计算代码时方便地作为快速检视流场动态的辅助工具。比如说,可以用下面的简单语句来用一个灰度图来可视化上面的 f_2d( gui.set_image 可以接收 Taichi field 或者 Numpy ndarray):
gui = ti.GUI('Title', (640, 480))
while gui.running:
gui.set_image(f_2d)
gui.show()
当然,如果你需要实现比较复杂的后期渲染效果,那么可能需要利用一些其他的后期软件进行动画制作。关于 taichi的 GUI 系统是否可以满足你的需求,可以参考官方文档的 GUI 部分。taichi https://taichi-lang.cn/
用 Taichi 来加速流场求解中需要大规模并行运算的部分
我们再次以上面的欧拉视角流体算法为例。
数据结构
为了让 Taichi 将求解部分的计算进行并行化处理,我们需要将流场数据保存成 Taichi 提供的 field 的形式。对于流体计算中经常出现的标量场和向量场,Taichi 都提供了对应的数据结构。比如一个 640x480 的由浮点数组成的标量场可以表示为:
f_2d = ti.field(float, shape=(640, 480))
类似的,一个 640x480 的 2 维向量场可以表示为:
v_2d = ti.Vector.field(n=2, dtype=float, shape=(640, 480))
除此之外,Taichi 中还提供了 Matrix 场以及自定义 Struct 场等更多丰富的数据结构,有兴趣的读者可以参阅官方文档的 field 的相关部分。
并行加速机制
假设我们要计算上面的 f_2d 这个标量场印加拉普拉斯算子的结果,我们可以先申请一个用来保存结果的场:
f_2d_grad2 = ti.field(float, shape=(640, 480))
然后我们需要遍历 f_2d_grad2 中的元素,计算其在施加了拉普拉斯算子后的值。为了方便地遍历场中的元素,Taichi 提供了好用的 struct-for 语句:
for i,j in f_2d_grad2:
f_2d_grad2[i,j] = 4 * f_2d[i,j] - f_2d[i-1,j] \
- f_2d[i+1,j] - f_2d[i,j-1] - f_2d[i,j+1]
不过上面的 struct-for 语句是 Taichi 的语法,并不能被 Python 处理。为了让 Taichi 来接管并加速这个计算,我们需要把上述计算包裹成一个 Taichi kernel:
@ti.kernel
def fgrad2():
for i,j in f_2d_grad:
f_2d_grad2[i,j] = 4 * f_2d[i,j] - f_2d[i-1,j] \
- f_2d[i+1,j] - f_2d[i,j-1] - f_2d[i,j+1]
这里的装饰器 @ti.kernel 就是所有 Taichi 加速魔法的入口,它的工作可以理解为接收并分析我们的函数代码,并返回一个自动并行化版本的函数:
fgrad2_ti = ti.kernel(fgrad2)
最后当我们调用这个函数的时候,程序就会把控制从 Python 交入 Taichi 手中,并在多个核心上并行执行上述运算,从而达到大大提升计算速度的目的。
数据可视化
Taichi 提供了内建的一个简易 GUI 系统,可以在构建数值计算代码时方便地作为快速检视流场动态的辅助工具。比如说,可以用下面的简单语句来用一个灰度图来可视化上面的 f_2d( gui.set_image 可以接收 Taichi field 或者 Numpy ndarray):
gui = ti.GUI('Title', (640, 480))
while gui.running:
gui.set_image(f_2d)
gui.show()
当然,如果你需要实现比较复杂的后期渲染效果,那么可能需要利用一些其他的后期软件进行动画制作。关于 taichi的 GUI 系统是否可以满足你的需求,可以参考官方文档的 GUI 部分。taichi https://taichi-lang.cn/
郑重声明:文章内容来自互联网,纯属作者个人观点,仅供参考,并不代表本站立场 ,版权归原作者所有!
相关推荐