支持:
计算图由表示各种操作的节点构建,如矩阵乘法、元素级操作和激活函数。所有操作都使用CUDA核函数实现,以便在NVIDIA GPU上并行执行。
enum OpType
: 定义操作类型枚举,包括输入、加法、减法、乘法、除法、矩阵乘法和各种激活函数。
xxxxxxxxxx
struct ComputeNode
: 计算图节点结构体,包含操作类型、前向传播值、梯度值和输入节点列表。
ComputeNode(int rows, int cols, int batch = 1)
: 构造函数,初始化节点的维度和批处理大小。~ComputeNode()
: 析构函数,防止内存泄漏。zeroGrad()
: 重置节点的梯度为零。reluForwardKernel
: 实现ReLU前向传播,对输入大于0的部分保持不变,小于0的部分置为0。reluBackwardKernel
: 实现ReLU反向传播,对输入大于0的部分传递梯度,小于0的部分梯度置为0。sigmoidForwardKernel
: 实现Sigmoid前向传播,计算1/(1+e^(-x))。sigmoidBackwardKernel
: 实现Sigmoid反向传播,计算梯度:output * (1 - output) * 输出梯度。matmulForwardKernel
: 实现矩阵乘法前向传播,计算C = A * B。matmulBackwardAKernel
: 实现矩阵乘法对输入A的反向传播,计算A的梯度。matmulBackwardBKernel
: 实现矩阵乘法对输入B的反向传播,计算B的梯度。negGradKernel
: 辅助核函数,用于计算负梯度(减法操作中使用)。mulBackwardKernel
: 实现元素级乘法的反向传播,计算两个输入的梯度。divBackwardKernel
: 实现元素级除法的反向传播,计算两个输入的梯度。addBackwardCUDA
: 实现加法操作的反向传播,直接将输出梯度复制到两个输入的梯度中。subBackwardCUDA
: 实现减法操作的反向传播,对第一个输入直接传递梯度,对第二个输入传递负梯度。mulBackwardCUDA
: 实现元素级乘法操作的反向传播,调用相应的CUDA核函数。divBackwardCUDA
: 实现元素级除法操作的反向传播,调用相应的CUDA核函数。matrixMatMulCPU
: CPU版本的矩阵乘法(用于验证CUDA实现的正确性)。class ComputeGraph
: 计算图管理类,提供以下方法:
~ComputeGraph()
: 析构函数,释放所有节点的内存。addInput(int rows, int cols, int batchSize = 1)
: 添加输入节点。addAdd(ComputeNode* a, ComputeNode* b)
: 添加加法节点。addSub(ComputeNode* a, ComputeNode* b)
: 添加减法节点。addMul(ComputeNode* a, ComputeNode* b)
: 添加元素级乘法节点。addDiv(ComputeNode* a, ComputeNode* b)
: 添加元素级除法节点。addMatMul(ComputeNode* a, ComputeNode* b)
: 添加矩阵乘法节点。addReLU(ComputeNode* input)
: 添加ReLU激活函数节点。addSigmoid(ComputeNode* input)
: 添加Sigmoid激活函数节点。forward()
: 执行前向传播,按照拓扑排序依次计算每个节点的值。backward(ComputeNode* outputNode)
: 执行反向传播,计算每个节点的梯度,从输出节点开始向输入节点传播。main()
: 示例程序入口点,演示如何使用计算图框架:
reluForwardKernel
: 对输入数据应用ReLU激活函数(max(0,x)),每个线程处理一个元素。reluBackwardKernel
: 计算ReLU的梯度,当输入大于0时梯度为上游梯度,否则为0。sigmoidForwardKernel
: 计算Sigmoid激活函数(1/(1+e^(-x))),每个线程处理一个元素。sigmoidBackwardKernel
: 计算Sigmoid的梯度,公式为out_grad * sigmoid(x) * (1-sigmoid(x))。matmulForwardKernel
: 实现矩阵乘法,每个线程负责计算结果矩阵中的一个元素。matmulBackwardAKernel
: 计算矩阵乘法关于第一个输入矩阵的梯度,实现了dL/dA的计算。matmulBackwardBKernel
: 计算矩阵乘法关于第二个输入矩阵的梯度,实现了dL/dB的计算。negGradKernel
: 计算负梯度,用于减法操作的反向传播。mulBackwardKernel
: 计算元素级乘法的梯度,对A的梯度为Bout_grad,对B的梯度为Aout_grad。divBackwardKernel
: 计算元素级除法的梯度,对A的梯度为out_grad/B,对B的梯度为-A*out_grad/(B²)。addBackwardCUDA
: 实现加法操作的梯度计算,由于加法的性质,输出梯度会直接传递给两个输入。subBackwardCUDA
: 实现减法操作的梯度计算,第一个输入接收正梯度,第二个输入接收负梯度。mulBackwardCUDA
: 封装元素级乘法的CUDA核函数调用,管理内存分配和传输。divBackwardCUDA
: 封装元素级除法的CUDA核函数调用,管理内存分配和传输。matrixMatMulCPU
: 在CPU上实现矩阵乘法,用于验证CUDA实现的正确性。~ComputeGraph()
: 析构函数,负责释放所有节点占用的内存,防止内存泄漏。addInput
, addAdd
, addSub
, addMul
, addDiv
, addMatMul
, addReLU
, addSigmoid
: 这些方法用于创建不同类型的计算节点并添加到计算图中。每个方法创建一个特定类型的节点,设置其操作类型和输入节点,并将节点添加到图中。forward()
: 按照拓扑排序顺序执行前向传播。对于每个节点,根据其操作类型调用相应的CUDA函数计算其值。backward(ComputeNode* outputNode)
: 执行反向传播。首先重置所有节点的梯度,然后从输出节点开始,按照拓扑排序的逆序计算每个节点的输入梯度。每种操作类型都有特定的反向传播逻辑。main()
: 演示如何使用计算图框架构建和训练简单的神经网络模型:
完整代码:
https://github.com/AllenZYJ/Edge-Computing-Engine/blob/master/cuda_mat/mat_grad.cu