Arrays nccl-我们可以将1个设备GPU上的数组的所有值相加以获得总和吗?

Arrays nccl-我们可以将1个设备GPU上的数组的所有值相加以获得总和吗?,arrays,c++11,parallel-processing,cuda,Arrays,C++11,Parallel Processing,Cuda,我有一个GPU(例如GeForce GTX 980Ti)。我有一个单浮点数组,例如,cudaMalloc'ed(分配在单个设备GPU上),长度为128,所有值均为1.f。我想用nccl将它们相加得到128,即(1+1+…+1)=128 但是,我在NCCL开发人员的文档中读到,如果我正确地解释了它,则减少仅在设备之间,而不是在单个设备之间: 比照 从那里(引用) AllReduce从K个列组中每个列组上N个值的独立数组Vk开始,以N个值的相同数组S结束,其中对于每个列组K,S[i]=V0[i]+V

我有一个GPU(例如GeForce GTX 980Ti)。我有一个单浮点数组,例如,cudaMalloc'ed(分配在单个设备GPU上),长度为128,所有值均为1.f。我想用nccl将它们相加得到128,即(1+1+…+1)=128

但是,我在NCCL开发人员的文档中读到,如果我正确地解释了它,则减少仅在设备之间,而不是在单个设备之间:

比照

从那里(引用)

AllReduce从K个列组中每个列组上N个值的独立数组Vk开始,以N个值的相同数组S结束,其中对于每个列组K,S[i]=V0[i]+V1[i]+…+Vk-1[i]

我想确认我不能在单个GPU上对设备GPU上的阵列进行缩减(求和)

我的完整代码(以及如何编译)在这里作为参考/上下文:

代码的“肉”在这里;(声明)前的“准备”应正确:

ncclCommCount(*comm.get(),&count);

ncclAllReduce( d_in.get(), d_out.get(), size, 
                ncclFloat, ncclSum, *comm.get(), *stream.get() );

// size is 128 for the 128 elements in both the (pointers to) float arrays 
// d_in and d_out
我用C++11智能指针“包装”了我的指针,但我也用原始指针尝试了我的代码,结果是一样的;如果你愿意,我可以发布这个版本

请确认我无法使用nccl在单个设备上、在单个设备GPU上的单个阵列上执行并行缩减,或向我演示如何执行。谢谢

我想确认我不能在单个GPU上对设备GPU上的阵列进行缩减(求和)

这在NCCL中是不可能的

  • NCCL是为多个GPU设计的,试图将其用于仅涉及单个GPU的操作是不明智的,也不符合逻辑的
  • NCCL和操作不会对数组执行缩减以将其缩减为单个数字。它们对数组集执行缩减,以将它们缩减为单个数组
  • 我的建议是使用像or这样的库,在单个GPU上将数组缩减为单个值

    为了解释NCCL和普通减速器(如cub或推力提供的减速器)之间的差异,普通减速器如下所示:

    arr:
     1
    +1
    +1
    --
     3 (sum) result
    
    NCCL Reduce或AllReduce执行以下操作:

    arr1  arr2  arr3      result
     1  +  2  +  3          6
     1  +  3  +  4     =    8
     1  +  4  +  5         10
    
    NCCL AllReduce的行为与您所引用的完全相同:

    AllReduce从K个列组中每个列组上N个值的独立数组Vk开始,以N个值的相同数组S结束,其中对于每个列组K,S[i]=V0[i]+V1[i]+…+Vk-1[i]


    这是很好的了解,进一步的解释既证实了我是如何阅读这段引文的,也希望能帮助其他人。是的,CUB非常适合于reduce和scan,特别是因为它正在积极地更新,而且它的级别低到足以利用nVidia的体系结构,而且级别高到足以发挥作用。太好了,谢谢!