如果我有一段代码将结构变量作为输入并操作它的元素,我如何使用 CUDA 并行化它?
void BackpropagateLayer(NET* Net, LAYER* Upper, LAYER* Lower)
{
INT i,j;
REAL Out, Err;
for (i=1; i<=Lower->Units; i++) {
Out = Lower->Output[i];
Err = 0;
for (j=1; j<=Upper->Units; j++) {
Err += Upper->Weight[j][i] * Upper->Error[j];
}
Lower->Error[i] = Net->Gain * Out * (1-Out) * Err;
}
}
Where NET and LAYER are structs defined as:
typedef struct { /* A LAYER OF A NET: */
INT Units; /* - number of units in this layer */
REAL* Output; /* - output of ith unit */
REAL* Error; /* - error term of ith unit */
REAL** Weight; /* - connection weights to ith unit */
REAL** WeightSave; /* - saved weights for stopped training */
REAL** dWeight; /* - last weight deltas for momentum */
} LAYER;
typedef struct { /* A NET: */
LAYER** Layer; /* - layers of this net */
LAYER* InputLayer; /* - input layer */
LAYER* OutputLayer; /* - output layer */
REAL Alpha; /* - momentum factor */
REAL Eta; /* - learning rate */
REAL Gain; /* - gain of sigmoid function */
REAL Error; /* - total net error */
} NET;
我能想到的是首先将2d权重转换为1d。然后将其发送到内核以获取产品或仅使用 CUBLAS 库。有什么建议吗?
最佳答案
如果您正在实现自己的神经网络库,那么对于简单的情况(具有完全连接或稀疏层的网络),我强烈建议使用 CUBLAS/CUSPARSE。在这种情况下,所有 3 个基本线性运算都可以通过调用这些库来优雅地表达:
- 前馈:gemv(如果小批量大小 > 1,则为 gemm)
- 后置属性:gemv(如果小批量大小 > 1,则为 gemm),并带有适当的转置标志。
- 权重更新:ger(如果小批量大小 > 1,则为 gemm)。
动量可以使用 3 个基本操作来表示(或使用单独的内核以获得更好的性能)。 当您超越基本内容并开始添加卷积层等内容时,事情会变得更加有趣。 在神经网络中,您有无数的超参数,因此我建议查看一些有关如何设计库的现有实现(例如 convnet )。
关于c - 使用 CUDA 并行化使用具有指向指针类型元素的指针的结构的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19899755/