Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
cuda:为图像和图像分配指针数组_Cuda - Fatal编程技术网

cuda:为图像和图像分配指针数组

cuda:为图像和图像分配指针数组,cuda,Cuda,我是CUDA的新手。 我想将图像堆栈复制到设备上 unsigned char** _devStackImagesCuda = NULL; int stackSize = 5;//should be replaced by argument to the function if(_devStackImagesCuda == NULL)\\allocate array of pointers on the device { cudaMalloc(&_devStackImagesCud

我是CUDA的新手。 我想将图像堆栈复制到设备上

unsigned char** _devStackImagesCuda = NULL;
int stackSize = 5;//should be replaced by argument to the function
if(_devStackImagesCuda == NULL)\\allocate array of pointers on the device
{
    cudaMalloc(&_devStackImagesCuda,  sizeof(unsigned char*)  * stackSize);
    cudaMemset(_devStackImagesCuda, 0, sizeof(unsigned char*) * stackSize);
}

for(int i = 0; i < stackSize; i++)
{

    if(_devStackImagesCuda[i] == NULL) //allocates one image on the device.
        cudaMalloc(&_devStackImagesCuda[i], imageSize * sizeof(unsigned char));
    cudaMemcpy(_devStackImagesCuda[i], _imageStack->GetImage(i, dummy, true), imageSize, cudaMemcpyHostToDevice);//copy image data to device
}
无符号字符**\u devStackImagesCuda=NULL;
int stackSize=5//应替换为函数的参数
如果(\u devStackImagesCuda==NULL)\\在设备上分配指针数组
{
cudamaloc(&&u devStackImagesCuda,sizeof(无符号字符*)*stackSize);
cudaMemset(_devStackImagesCuda,0,sizeof(unsigned char*)*stackSize);
}
对于(int i=0;iGetImage(i,dummy,true),imageSize,cudamemcpyhostodevice);//将图像数据复制到设备
}

可以吗?

如评论所示,您的方法存在一些问题

  • 特别是作为初学者,您应该始终对cuda调用(包括内核调用)进行错误检查。下面的代码是一个示例,或参考
  • 在cuda中创建指针到指针的排列有时并不直观,因为cudaMalloc’s top level pointer,然后cudaMalloc’s under the pointer将不起作用。这是因为要使用cudamaloc下面的指针,我们必须将顶级指针传递给cudamaloc,但这已经是一个设备指针了。Cudamaloc希望您传递一个主机指针,然后它将在设备上运行Cudamaloc。因此,为了解决这个问题,通常需要在主机上创建一个阴影或平行指针排列,然后依次将所有这些指针传递给Cudamaloc,然后将这些指针复制到设备上。有关示例,请参见下面的代码
  • 您还想测试主机上设备指针的有效性,以查看是否需要对其进行cudaMalloc。这将不起作用,因为它会导致取消对主机上设备指针的引用。特别是在这一行:
    如果(\u-devStackImagesCuda[i]==NULL)
    ,您将尝试查看\u-devStackImagesCuda[i]是否有效,但为了做到这一点,您必须取消引用
    \u-devStackImagesCuda
    ,但是您以前对该指针(指向指针)执行了cudaMalloc,因此它现在是一个设备指针,不允许您在主机上取消引用。我建议你记录下是否需要用其他方式来使用这些指针
  • 我相信这样做会奏效:

    #include <stdio.h>
    
    #define cudaCheckErrors(msg) \
        do { \
            cudaError_t __err = cudaGetLastError(); \
            if (__err != cudaSuccess) { \
                fprintf(stderr, "Fatal error: %s (%s at %s:%d)\n", \
                    msg, cudaGetErrorString(__err), \
                    __FILE__, __LINE__); \
                fprintf(stderr, "*** FAILED - ABORTING\n"); \
                exit(1); \
            } \
        } while (0)
    
    
    int main(){
    
      unsigned char ** _devStackImagesCuda=0;
    
      int stackSize = 5;
      int imageSize = 4;
      unsigned char *temp[stackSize];
      unsigned char dummy_image[imageSize];
    // first create top level pointer
      if ( _devStackImagesCuda == 0) //allocate array of pointers on the device
        {
        cudaMalloc(&_devStackImagesCuda,  sizeof(unsigned char*)  * stackSize);
        cudaCheckErrors("cm 1");
        }
    // then create child pointers on host, and copy to device, then copy image
      for(int i = 0; i < stackSize; i++)
        {
    
        cudaMalloc(&temp[i], imageSize * sizeof(unsigned char));
        cudaCheckErrors("cm 2");
        cudaMemcpy(&(_devStackImagesCuda[i]), &(temp[i]), sizeof(unsigned char *), cudaMemcpyHostToDevice);//copy child pointer to device
        cudaCheckErrors("cudamemcopy1");
        cudaMemcpy(temp[i], dummy_image, imageSize*sizeof(unsigned char), cudaMemcpyHostToDevice); // copy image to device
        cudaCheckErrors("cudamemcpy2");
    
        }
    
    
    return 0;
    }
    
    并通过以下方式访问各个图像元素:

    unsigned char mypixel = images[i + (IMAGE_SIZE * j)]; // to access element i in image j
    

    这是一个调试问题?也许你可以改变标题来反映这一点?你确定你没有在没有重新编译的情况下编辑程序的源文件吗?在你的cuda调用中如何?要在设备上访问指向指针的指针排列,不能先cudamaloc顶层指针,然后cudamaloc底层指针。有必要在主机上创建指针排列,然后将其复制到设备上。请参见示例。另外,这一行:
    如果(\u devStackImagesCuda[i]==NULL)
    正在主机代码中解除对设备指针的引用。这是非法的,不起作用(segfault)。因此,这种试图通过测试设备指针是否为零(主机上)来确定设备指针是否需要分配的方法是一个坏主意。如果你真的想,你可以在测试它是否为零之前将指针调回主机,但我会寻找更好的方法来完成分配。非常感谢!!正如你所说,这对我来说不是直觉。。即使使用unsigned char**temp,也可以使用您的示例,还是应该使用unsigned char*temp[MAX_SIZE_FOR_STACK_SIZE]?我认为unsigned char**temp也可以。从这个意义上讲,temp的两种表示形式是相同的,不是吗(都是指向无符号字符的指针)?你为什么不试试你喜欢的,看看能不能成功。再次感谢你!只是为了检查我是否理解逻辑:对于未签名字符**temp版本:1。我应该malloc(而不是cudamaloc):temp=newunsignedchar*[stackSize]。2.循环(i=0;iyes)以使**temp等同于temp[stackSize],您需要使用**temp进行malloc。其余应相同。
    unsigned char mypixel = images[i + (IMAGE_SIZE * j)]; // to access element i in image j