Mathematica中的CUDAFunctionLoad-索引问题。

| 我正在尝试调试CUDA计算机上存在的索引问题
Cuda Machine Info:
  {1-> {名称-> Tesla C2050,时钟速率-> 1147000,计算能力->2。,GPU重叠-> 1,最大块尺寸-> {1024,1024,64},最大网格尺寸-> {65535 ,65535,65535},每块最大线程数-> 1024,每块最大共享内存数-> 49152,总恒定内存-> 65536,经线大小-> 32,最大间距-> 2147483647,每块最大寄存器数-> 32768,纹理对齐-> 512,多处理器计数-> 14,核心计数-> 448,执行超时-> 0,集成->假,可以映射主机内存->真,计算模式->默认,Texture1D Width-> 65536,Texture2D宽度-> 65536,Texture2D高度-> 65535,Texture3D宽度-> 2048,Texture3D高度-> 2048,Texture3D深度-> 2048,Texture2D阵列宽度-> 16384,Texture2D阵列高度-> 16384,Texture2D阵列切片-> 2048,表面对齐-> 512,并发内核-> True,启用ECC-> True,总内存-> 2817982462}, 此代码所做的全部工作就是将3D数组的值设置为等于CUDA使用的索引:
__global __ void cudaMatExp(
float *matrix1, float *matrixStore, int lengthx, int lengthy, int lengthz){

long UniqueBlockIndex = blockIdx.y * gridDim.x + blockIdx.x;

long index = UniqueBlockIndex * blockDim.z * blockDim.y * blockDim.x +
    threadIdx.z * blockDim.y * blockDim.x + threadIdx.y * blockDim.x +
    threadIdx.x;

if (index < lengthx*lengthy*lengthz) {

matrixStore[index] =  index;

}
}
由于某种原因,一旦我的3D数组的尺寸变得太大,索引就会停止。 我尝试了不同的块尺寸(由blockDim.y的blockDim.y划分的blockDim.x): 8x8x8仅在数组尺寸为12x12x12时给出正确的索引 9x9x9仅在数组尺寸为14x14x14时给出正确的索引 10x10x10仅在数组尺寸为15x15x15时给出正确的索引 对于大于这些尺寸的尺寸,所有不同的块大小最终都会再次开始增加,但是它们永远不会达到dim ^ 3-1的值(这是cuda线程应达到的最大索引) 这是一些图解说明此行为: 例如:这是在x轴上绘制3D数组的尺寸(即xxx),在y轴上绘制在cuda执行过程中处理的最大索引号。此特定图适用于10x10x10的块尺寸。 这是(Mathematica)代码来生成该图,但是当我运行该图时,我使用了1024x1x1的块尺寸:
CUDAExp = CUDAFunctionLoad[codeexp, \"cudaMatExp\",
  {{\"Float\", _,\"Input\"}, {\"Float\", _,\"Output\"},
    _Integer, _Integer, _Integer},
  {1024, 1, 1}]; (*These last three numbers are the block dimensions*)

max = 100; (* the maximum dimension of the 3D array *)
hold = Table[1, {i, 1, max}];
compare = Table[i^3, {i, 1, max}];
Do[
   dim = ii;
   AA  = CUDAMemoryLoad[ConstantArray[1.0, {dim, dim, dim}], Real, 
                                     \"TargetPrecision\" -> \"Single\"];
   BB  = CUDAMemoryLoad[ConstantArray[1.0, {dim, dim, dim}], Real, 
                                     \"TargetPrecision\" -> \"Single\"];

   hold[[ii]] = Max[Flatten[
                  CUDAMemoryGet[CUDAExp[AA, BB, dim, dim, dim][[1]]]]];

 , {ii, 1, max}]

ListLinePlot[{compare, Flatten[hold]}, PlotRange -> All]
这是相同的图,但现在将x ^ 3绘制为与应该在的位置进行比较。请注意,它在数组的维数> 32之后发散 我测试了3D数组的尺寸,查看索引进行了多远,并将其与dim ^ 3-1进行了比较。例如。对于dim = 32,cuda max索引是32767(32 ^ 3 -1),但是对于dim = 33,cuda输出是33791,应该是35936(33 ^ 3 -1)。请注意33791-32767 = 1024 = blockDim.x 题: 有没有办法正确索引尺寸大于Mathematica中块尺寸的数组? 现在,我知道有些人在其索引方程式中使用__mul24(threadIdx.y,blockDim.x)来防止位乘法出现错误,但这似乎对我的情况没有帮助。 另外,我看到有人提到您应该使用-arch = sm_11编译代码,因为默认情况下,它是针对计算能力1.0编译的。我不知道Mathematica中是否是这种情况。我假设CUDAFunctionLoad []知道要使用2.0功能进行编译。有人知道吗? 任何建议都将非常有帮助!     
已邀请:
        因此,Mathematica具有隐藏的处理网格尺寸的方法,要将网格尺寸固定为可以使用的尺寸,则必须在要调用的函数的末尾添加另一个数字。 该参数表示要启动的线程数(或网格尺寸乘以块尺寸)。 例如,在我上面的代码中:
CUDAExp = 
  CUDAFunctionLoad[codeexp, 
   \"cudaMatExp\", {
           {\"Float\", _, \"Input\"}, {\"Float\", _,\"Output\"}, 
                        _Integer, _Integer, _Integer}, 
     {8, 8, 8}, \"ShellOutputFunction\" -> Print];
(8,8,8)表示块的尺寸。 在mathematica中调用ѭ4,时,可以添加一个参数来表示要启动的线程数: 在此示例中,我终于将其与以下对象一起使用:
// AA and BB are 3D arrays of 0 with dimensions dim^3
dim = 64;
CUDAExp[AA, BB, dim, dim, dim, 4089];
请注意,使用CUDAFunctionLoad []进行编译时,它只需要5个输入,第一个是您传递给它的数组(尺寸为
dim x dim x dim
),第二个是存储它的内存的位置。第三,第四和第五个是尺寸。 当您将其传递第六时,mathematica会将其转换为
gridDim.x * blockDim.x
,因此,由于我知道我需要gridDim.x = 512才能处理数组中的每个元素,因此我将此数字设置为512 * 8 = 4089。 我希望这对于将来遇到此问题的人来说是清楚且有用的。     

要回复问题请先登录注册