Tensorflow:索引在CUDA_1D_KERNEL_LOOP(index,nthreads)op user中表示的是什么

时间:2016-09-13 12:28:20

标签: tensorflow

我已经在几个张量流层的标准操作中看到过(例如https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/kernels/maxpooling_op_gpu.cu.cc),代码CUDA_1D_KERNEL_LOOP(索引,nthreads)作为前向和后向传递的一部分......

我认为"指数"这里与底部特征地图坐标有某种关系,但我不确定它的确切含义......有谁可以提供帮助?

2 个答案:

答案 0 :(得分:5)

CUDA_1D_KERNEL_LOOP(i, n)tensorflow/core/util/cuda_kernel_helper.h中定义的预处理器宏。它提供了一个通用控制流语句,用于Tensorflow代码库中的许多Cuda内核。

该语句通常用于迭代内核中数组的元素。参数i是控制变量的名称,参数n是控制语句的停止条件。 Cuda内核以并行线程启动。每个线程通常在数组元素的子集上操作。宏为访问所需的数组元素提供了一些便利。

在您链接到的示例中,CUDA_1D_KERNEL_LOOP(index, nthreads)被解释为:

for (int index = blockIdx.x * blockDim.x + threadIdx.x; index < nthreads; index += blockDim.x * gridDim.x)

因此,在进入后续代码块之前,indexCUDA_1D_KERNEL_LOOP内被声明并初始化。 index的确切含义取决于它在代码块中的使用方式。

答案 1 :(得分:0)

当我第一次阅读这个宏时,让我困惑的一件事是,“为什么它是一个循环,这不是内核已经并行化了吗?”答案是,当你拥有比GPU实际支持的更多“线程”时,循环处理这种情况。

例如,假设您正在进行并行向量添加,并且您已经决定对于GPU,每个块将使用512个线程,最多安排4096个块(这些是Caffe2中的默认参数)。这意味着您最多只能安排2097152个线程。假设你的矢量实际上有4M个元素;现在你无法为每个元素分配一个线程。因此每个线程必须负责对向量中的多个元素求和:这就是这个循环的用途!

这是一个较小的示例,它精确地描述了工作最终如何安排。假设blockDim.x == 2gridDim.x == 2nthreads == 7。然后,如果我们将GPU线程标识为(blockIdx.x, threadIdx.x),我们会分配它们以对向量执行以下工作:[(0,0), (0,1), (1,0), (1,1), (0,0), (0,1), (1,0)]。特别是,我们可以看到,根据网格大小,只有四个GPU线程可用;因此,对于blockIdx.x == 0 threadIdx.x == 0index将处理两个04处的向量元素。