Tensor Comprehensions 基础算子改写

本文通过定义自定义卷积、ReLU激活、池化、批量归一化及全连接层等核心模块,详细介绍了如何使用TorchCraft库实现深度学习网络的基本组件。这些组件包括卷积层、ReLU激活函数、最大池化、平均池化、批量归一化层及线性层。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

def conv(self, input, outchannel, k_size, stride = 1, padding = 0):
        LANG = """
        def convolution(float(N,C,H,W) I, float(M,C,KH,KW) W1) -> (O) {{
            O(n, m, h, w) +=! I(n, c, {sh} * h + kh, {sw} * w + kw) * W1(m, c, kh, kw)
        }}
        """
        kernel = torch.randn(outchannel, input.size(1), k_size, k_size)
        input = input.type(torch.FloatTensor)
        if padding != 0:
            pad = torch.zeros(input.size(0), input.size(1), padding, input.size(3))
            input = torch.cat((input, pad), 2)
            input = torch.cat((pad, input), 2)
            pad = torch.zeros(input.size(0), input.size(1), input.size(2), padding)
            input = torch.cat((input, pad), 3)
            input = torch.cat((pad, input), 3)


        sh, sw = stride, stride
        convolution = tc.define(LANG, training=True, name="convolution", backward="convolution_grad",constants={"sh":sh, "sw":sw})
        I = Variable(input.cuda(), requires_grad=True)
        W = Parameter(kernel.cuda())
        out = convolution(I, W, options=tc.CudaMappingOptions("conv"))
        return out


    def relu(self, input):
        LANG = """
        def relu(float(Q, W, B, M) I) -> (O1){
            O1(q, w, b, m) = fmax(I(q, w, b, m), 0)
        }
        """
        relu = tc.define(LANG, name="relu")
        inp = input.cuda()
        out = relu(inp, options=tc.CudaMappingOptions("naive"))
        return out


    def maxpool(self, input, p_size, stride, padding = 0):
        LANG = """
        def maxpool(float(B,C,H,W) input) -> (output) {{
            output(b,c,h,w) max=! input(b, c, h * {sH} + kh, w * {sW} + kw)  
            where kh in 0:{kH}, kw in 0:{kW}
        }}
        """
        input = input.type(torch.FloatTensor)
        if padding != 0:
            pad = torch.zeros(input.size(0), input.size(1), padding, input.size(3))
            input = torch.cat((input, pad), 2)
            input = torch.cat((pad, input), 2)
            pad = torch.zeros(input.size(0), input.size(1), input.size(2), padding)
            input = torch.cat((input, pad), 3)
            input = torch.cat((pad, input), 3)
        
        sH, sW = stride, stride
        kH, kW = p_size, p_size
        maxpool = tc.define(LANG, name="maxpool", constants={"sH":sH, "sW":sW, "kH":kH, "kW":kW})
        inp = input.cuda()
        out = maxpool(inp, options=tc.CudaMappingOptions("naive"))
        out = out.type(torch.FloatTensor)
        return out
        
    def avgpool(self, input, p_size, stride, padding = 0):
        LANG = """
        def avgpool(float(B, C, H, W) input) -> (output) {{
            output(b, c, h, w) +=! input(b, c, h * {sH} + kh, w * {sW} + kw) / ({kH} * {kW})
            where kh in 0:{kH}, kw in 0:{kW}
        }}
        """
        input = input.type(torch.FloatTensor)
        if padding != 0:
            pad = torch.zeros(input.size(0), input.size(1), padding, input.size(3))
            input = torch.cat((input, pad), 2)
            input = torch.cat((pad, input), 2)
            pad = torch.zeros(input.size(0), input.size(1), input.size(2), padding)
            input = torch.cat((input, pad), 3)
            input = torch.cat((pad, input), 3)
            
        sH, sW = stride, stride
        kH, kW = p_size, p_size
        avgpool = tc.define(LANG, name="avgpool", constants={"sH":sH, "sW":sW, "kH":kH, "kW":kW})
        inp = input.cuda()
        out = avgpool(inp, options=tc.CudaMappingOptions("naive"))
        out = out.type(torch.FloatTensor)
        return out


    def batchnorm(self, input):
        LANG = """
        def batchnorm(float(N,C,H,W) I, float(C) rMeanIn, float(C) rVarIn)
        -> (O, rMeanOut, rVarOut, mean, centered, variance, expectedVariance, normalizedOut)
        {{
           mean(c) +=! I(nn, c, hh, ww)
           mean(c)  = mean(c) / (N * H * W)
           rMeanOut(c) = (1 - {momentum}) * rMeanIn(c) + {momentum} * mean(c)
           centered(n, c, h, w) = I(n, c, h, w) - rMeanOut(c)
           variance(n, c, h, w) = centered(n, c, h, w) * centered(n, c, h, w)
           expectedVariance(c) +=! (variance(n, c, h, w) + {eps}) / (N * H * W)
           rVarOut(c) = rsqrt(
             (1 - {momentum}) * rVarIn(c) + {momentum} * expectedVariance(c))
           O(n, c, h, w) = centered(n, c, h, w) * rVarOut(c)
           normalizedOut(n, c, h, w) = O(n, c, h, w)
        }}
        """
        channel = input.size(1)
        batchnorm = tc.define(LANG, name="batchnorm", constants={"momentum": 0.9, "eps": 1e-5})
        running_mean, running_var = torch.randn(channel).cuda(), torch.randn(channel).cuda()
        out = batchnorm(input.cuda(), running_mean, running_var, options=tc.CudaMappingOptions("naive"))
        return out[7] 


    def linear(self, input, outchannel):
        LANG = """
        def fc(float(B,M) I, float(N,M) W1, float(N) B1) -> (O1) {
          O1(b, n) +=! I(b, m) * W1(n, m)
          O1(b, n) = O1(b, n) + B1(n)
        }
        """
        I = input.cuda()
        W = torch.randn(outchannel, input.size(1)).cuda()
        B = torch.randn(outchannel).cuda()
        fc = tc.define(LANG, name="fc")
        out = fc(I, W, B, options=tc.CudaMappingOptions("naive"))
        return out
### 关于Tensor库中算子的使用方法 #### 自定义算子集成至TensorFlow 对于希望扩展TensorFlow功能的情况,可以通过自定义算子法来实现这一目标。此方法涉及将自定义算子文件放置于TensorFlow源码指定位置,并借助Bazel工具完成整个项目的重新编译与安装过程[^1]。 ```bash bazel build --config=opt //tensorflow/tools/pip_package:build_pip_package ``` 这段命令展示了如何配置优化选项并构建pip包用于分发新版本的TensorFlow,其中已包含用户自定义的操作函数。 #### Tensor描述符的作用 当涉及到具体的张量(Tensor)处理时,`TensorDesc`作为其描述符起着至关重要的作用。这个结构体不仅记录了张量的名字、维度大小等基本信息,还明确了内部元素的数据类型及其排列方式,这对于确保程序逻辑无误至关重要[^2]。 #### MegEngine下的卷积算子细节 针对更复杂的场景比如图像识别等领域应用广泛的卷积神经网络(CNN),MegEngine提供了详尽的支持材料解释了CUDA平台上此类核心组件的设计思路和技术要点;特别是有关CUTLASS框架下隐式GEMM算法的应用案例分析有助于开发者深入了解高性能计算背后的机制[^3]。 #### 利用TVM创建高效算子 除了上述提及的技术栈外,Apache TVM也是一个强大的开源项目,在异构硬件环境中提供灵活高效的机器学习模型部署方案。通过编写简单的脚本就可以快速定义新的运算单元并通过JIT即时编译技术生成适用于不同设备的目标代码片段,极大地方便了研究者们测试原型想法或者加速现有应用程序性能[^4]。 ```python import tvm from tvm import te A = te.placeholder((m,), name='A') B = te.compute((m,), lambda i: A[i] + 1, name='B') s = te.create_schedule(B.op) mod = tvm.build(s, [A, B], target="llvm") # 编译成LLVM IR形式 ``` 以上示例演示了怎样利用TVM API轻松搭建一个基本的向量增量操作流程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值