【问题标题】:How to index a Matlab array inside a CUDA kernel [duplicate]如何在 CUDA 内核中索引 Matlab 数组[重复]
【发布时间】:2014-03-16 19:59:43
【问题描述】:

我正在对一个用 Matlab 编写的程序进行并行化。

目前我有以下代码:

#define _USE_MATH_DEFINES

#include "cuda_runtime.h"
#include "device_launch_parameters.h"

#include <math.h>

__global__ void radialAverage(double** image, int x_center, int y_center)
{
    int i, x, y;

    const int x_size = 400;
    const int y_size = 400;

    int thread = blockIdx.x*blockDim.x+threadIdx.x;

    double angle     = 0;
    double dAngle    = M_PI/360;

    double radImgMat[x_size][y_size];
    double angleMatPi[x_size][y_size];


    //radImMap erstellen
    for( x = 0; x < x_size; x++) {
        for( y = 0; y < y_size; y++) {
        radImgMat[x][y]  = sqrt((double)(x+1-x_center)*(x+1-x_center) + (y+1-y_center)*(y+1-y_center));
        }
    }

    //Angle-Matrix (pi-pi) erstellen
    for ( x = 0; x < x_size; x++) {
        for( y = 0; y < y_size; y++) {
            float xD = x+1-x_center;
            float yD = y+1-y_center;
            if(yD>0) {
                angleMatPi[x][y] = -1*(atan(xD/yD)+M_PI/2)+M_PI;
            } else if(yD==0 && xD<0) {
                angleMatPi[x][y] = M_PI;
            } else if(yD==0 && xD>0) {
                angleMatPi[x][y] = 0;
            } else {
                angleMatPi[x][y] = -1*(atan(xD/yD)+M_PI/2);
            }
        }
    }

    //Cut ImgMat
    for(x=0; x < x_size; x++) {
        for(y = 0; y < y_size; y++) {
            if((angleMatPi[x][y] < (angle-dAngle)) || (angleMatPi[x][y] > (angle+dAngle))) {
                image[x][y] = 0;
            }               
        }
    }
}

在纯 C++ 中它工作得非常好,但是当我尝试时出现错误 索引int* image 矩阵,它应该是二维的。你们有谁 知道如何访问给定矩阵的内容?

【问题讨论】:

  • 您可能已经使用int** image 编译了您的代码,但除非您仔细处理@talonmies 提供的链接以及下面给出的答案.
  • 如果您没有注意到,您的代码格式完全是一团糟。代码行的格式应与问题文本分开,缩进 4 个空格。不要将特殊格式字符 &gt; 放在您发布的每一行的开头。如果您想在此处发布问题,请找出适当的格式并重新编辑您的问题直到格式正确,以方便其他人阅读。
  • 哦!我现在没有注意到它:/ sry 编辑:我更新了问题

标签: c++ matlab matrix cuda


【解决方案1】:

我发现代码存在三个问题。首先,我们需要确保将图像数据复制到 GPU 并传递给内核。您可能已经这样做了,但我们需要查看主机代码才能知道。在主机上运行的代码应该是这样的,

int *d_image;
cudaMalloc((void**)&d_image,x_size*y_size*sizeof(int)); //allocate memory on the GPU for the image

cudaMemcpy(d_image,image,x_size*y_size*sizeof(int),cudaMemcpyHostToDevice); //copy the image to GPU global memory

radialAverage<<<numBlocks,numThreads>>>(d_image,x_size,y_size,x_center,y_center); //Call CUDA kernel with device pointer to image data

这应该可以解决引用图像数据时的崩溃问题。其次是您索引图像的方式。如果您将图像作为 int* 传递,则必须将其作为一维数组访问。 CUDA 代码不知道图像的尺寸是多少。每当您想获取一些图像数据时,您都需要使用它(假设行主要顺序),

image[y*x_size + x];

第三是你的代码根本不是并行的。在计算过程中您永远不会引用“线程”的值,因此您基本上是在整个图像上并行多次执行相同的串行计算。我建议查看一些非常基本的 CUDA 代码以了解其工作原理。 UDACITY 有一个很棒的关于 CUDA 和并行编码的小型在线视频课程,我强烈推荐。 https://www.udacity.com/course/cs344

【讨论】:

  • 大多数有效点,但是由于 OP 提到了 matlab,大概使用 mex 或 PTX 接口,没有“主机代码”要检查。在调用提供的内核之前,Matlab 会在内部完成所有设置。
  • 是的,这是我的问题:/ 但我想我可以在重塑图像并做一维数组的事情时解决它:D
  • 我在做同样的计算是因为我想在添加实际并行部分(径向平均部分)之前测试代码到实际点...
猜你喜欢
  • 1970-01-01
  • 2014-03-06
  • 2014-10-06
  • 2021-05-31
  • 2019-09-24
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 2011-01-12
相关资源
最近更新 更多