本文以取 (bs, n, n) 张量的右上三角阵并展平为向量 (bs, n*(n+1)//2)) 为例,展示如何用 taichi 编写深度学习算子。

 如图,要把形状为 
    
     
      
       
        (
       
       
        b
       
       
        s
       
       
        ,
       
       
        n
       
       
        ,
       
       
        n
       
       
        )
       
      
      
       (bs,n,n)
      
     
    (bs,n,n) 的张量,转化为 
    
     
      
       
        (
       
       
        b
       
       
        s
       
       
        ,
       
       
        
         
          n
         
         
          (
         
         
          n
         
         
          +
         
         
          1
         
         
          )
         
        
        
         2
        
       
       
        )
       
      
      
       (bs,\frac{n(n+1)}{2})
      
     
    (bs,2n(n+1)) 的向量。我们先写一个最简单的最慢的纯 python 循环实现方法
纯 python for 循环
def get_tensor_up_right_tri_slow(t):
    # t shape (bs, n, n)
    # out shape (bs, n*(n+1)//2)
    out = torch.zeros(t.shape[0], t.shape[1]*(t.shape[1]+1)//2)
    n = t.shape[1]
    # k = i*n + j - i*(i+1)//2
    for b in range(t.shape[0]):
        # 遍历右上三角阵,包括主对角线
        for i in range(t.shape[1]):
            for j in range(i, t.shape[1]):
                k = i*n + j - i*(i+1)//2
                out[b, k] = t[b, i, j]
    return out
可想而知,三层 python for 循环,必然是极慢的了。
转化为 taichi
在此基础上,稍微做一些修改,就可以得到我们的 taichi 版本函数
import taichi as ti
ti.init(arch=ti.gpu)
@ti.kernel
def get_tensor_up_right_tri(t: ti.types.ndarray(ndim=3, dtype=ti.f32), out: ti.types.ndarray(ndim=2, dtype=ti.f32)):
    # t shape (bs, n, n)
    # out shape (bs, n*(n+1)//2)
    n = t.shape[1]
    for b, i, j in t:
        # 遍历右上三角阵,包括主对角线
        if i <= j:
            k = i*n + j - i*(i+1)//2
            out[b, k] = t[b, i, j]
taichi 支持同时遍历多层循环,将三层循环改为一层循环后,和 python for 循环版本基本没有什么差别。taichi 将此函数转化为 CUDA 版本进行加速,从而提高运算速度。


















