Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.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
C++ CUDA:使用不同大小的阵列_C++_Arrays_Memory_Cuda - Fatal编程技术网

C++ CUDA:使用不同大小的阵列

C++ CUDA:使用不同大小的阵列,c++,arrays,memory,cuda,C++,Arrays,Memory,Cuda,在本例中,我尝试使用10x9数组中的值创建10x8数组。看起来我访问内存不正确,但我不确定我的错误在哪里 < C++中的代码将是类似于的代码。 for (int h = 0; h < height; h++){ for (int i = 0; i < (width-2); i++) dd[h*(width-2)+i] = hi[h*(width-1)+i] + hi[h*(width-1)+i+1]; } for(int h=0;h

在本例中,我尝试使用10x9数组中的值创建10x8数组。看起来我访问内存不正确,但我不确定我的错误在哪里

< C++中的代码将是类似于

的代码。
for (int h = 0; h < height; h++){
    for (int i = 0; i < (width-2); i++)
        dd[h*(width-2)+i] = hi[h*(width-1)+i] + hi[h*(width-1)+i+1];
}
for(int h=0;h
这就是我在CUDA的尝试:

#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <stdint.h>

#include <iostream>

#define TILE_WIDTH 4

using namespace std;

__global__ void cudaOffsetArray(int height, int width, float *HI, float *DD){

    int             x                   =   blockIdx.x * blockDim.x + threadIdx.x; // Col // width
    int             y                   =   blockIdx.y * blockDim.y + threadIdx.y; // Row // height
    int             grid_width          =   gridDim.x  * blockDim.x;
  //int             index               =   y * grid_width + x;

    if ((x < (width - 2)) && (y < (height)))
        DD[y * (grid_width - 2) + x] = (HI[y * (grid_width - 1) + x] + HI[y * (grid_width - 1) + x + 1]);
}

int main(){

    int height  = 10;
    int width   = 10;

    float *HI = new float [height * (width - 1)];
    for (int i = 0; i < height; i++){
        for (int j = 0; j < (width - 1); j++)
            HI[i * (width - 1) + j] = 1;
    }

    float   *gpu_HI;
    float   *gpu_DD;
    cudaMalloc((void **)&gpu_HI, (height * (width - 1) * sizeof(float)));
    cudaMalloc((void **)&gpu_DD, (height * (width - 2) * sizeof(float)));

    cudaMemcpy(gpu_HI, HI, (height * (width - 1) * sizeof(float)), cudaMemcpyHostToDevice);

    dim3            dimGrid((width - 1) / TILE_WIDTH + 1, (height - 1)/TILE_WIDTH + 1, 1);
    dim3            dimBlock(TILE_WIDTH, TILE_WIDTH, 1);

    cudaOffsetArray<<<dimGrid,dimBlock>>>(height, width, gpu_HI, gpu_DD);

    float *result   = new float[height * (width - 2)];
    cudaMemcpy(result, gpu_DD,  (height * (width - 2) * sizeof(float)), cudaMemcpyDeviceToHost);

    for (int i = 0; i < height; i++){
        for (int j = 0; j < (width - 2); j++)
            cout << result[i * (width - 2) + j] << " ";
        cout << endl;
    }

    cudaFree(gpu_HI);
    cudaFree(gpu_DD);
    delete[] result;
    delete[] HI;

    system("pause");
}
#包括“cuda_runtime.h”
#包括“设备启动参数.h”
#包括
#包括
#包括
#定义平铺宽度4
使用名称空间std;
__全局无效cudaOffsetArray(整数高度、整数宽度、浮点*HI、浮点*DD){
int x=blockIdx.x*blockDim.x+threadIdx.x;//列//宽度
int y=blockIdx.y*blockDim.y+threadIdx.y;//行//高度
int grid_width=gridDim.x*blockDim.x;
//int index=y*网格宽度+x;
如果((x<(宽度-2))和((y<(高度)))
DD[y*(网格宽度-2)+x]=(HI[y*(网格宽度-1)+x]+HI[y*(网格宽度-1)+x+1]);
}
int main(){
整数高度=10;
整数宽度=10;
浮动*高=新浮动[高度*(宽度-1)];
对于(int i=0;igrid\u width
的每次使用更改为
width

    DD[y * (grid_width - 2) + x] = (HI[y * (grid_width - 1) + x] + HI[y * (grid_width - 1) + x + 1]);
if ((x < (width - 2)) && (y < (height)))
像这样:

    DD[y * (width - 2) + x] = (HI[y * (width - 1) + x] + HI[y * (width - 1) + x + 1]);
说明:

您的
网格宽度

dim3            dimGrid((width * 2 - 1) / TILE_WIDTH + 1, (height - 1)/TILE_WIDTH + 1, 1);
dim3            dimBlock(TILE_WIDTH, TILE_WIDTH, 1);
实际上与数组大小(10x10、10x9或10x8)不对应。我不确定为什么要在x维中启动
2*width
线程,但这意味着线程数组比数据数组大得多

因此,当您在内核中使用
grid\u width
时:

    DD[y * (grid_width - 2) + x] = (HI[y * (grid_width - 1) + x] + HI[y * (grid_width - 1) + x + 1]);
索引将是一个问题。如果您将上面的
grid\u width
的每个实例改为仅
width
(对应于数据数组的实际宽度),我认为您将获得更好的索引。通常启动“额外线程”不是问题,因为您的内核中有一个线程检查行:

    DD[y * (grid_width - 2) + x] = (HI[y * (grid_width - 1) + x] + HI[y * (grid_width - 1) + x + 1]);
if ((x < (width - 2)) && (y < (height)))
if((x<(宽度-2))和&(y<(高度)))

但是当你启动额外的线程时,它会使你的网格变大,因此你不能使用网格维度来正确地索引到你的数据数组中。

使用向量,它会告诉你什么时候你会越界。@NeilKirk你的意思是使用推力库吗?我只是读到了那些只在主机端可用,你不能在设备函数中使用它们。我这是错误的,或者你能给我任何额外的信息吗?我不知道什么是Cuda。我指的是std::vector
std::vector
在Cuda设备代码中不方便使用。
推力::设备\设备向量
在Cuda设备代码中也不方便使用。对不起,(宽度*2)是一个复制粘贴错误。我编辑了文章,但修复了这个错误后,我的代码仍然不正确。我想如果没有*2,我将在x和3(4x4)中获得3(4x4)个平铺在y中平铺,这是我想要的,因为代码中的数组将是大小的混合。另外,我使用的10x10作为示例,实际数组将更大。请重新阅读我的答案。我不建议更改
宽度*2
条目。只需将内核中的
网格宽度
更改为
宽度
,如我所示(只需在使用它的一行内核代码中的3个位置进行更改,正如我在回答中所发布的那样),您的代码将被“修复”"。这就是我所做的,而且似乎有效。这是一个完整的示例。抱歉,我误解了,它似乎与该更改一起工作。非常感谢!如果我理解正确,在示例中,grid_width=12,这就是索引错误的原因。在您发布的原始代码中,以及我的,
grid_width
=20中包含的内容。您可以验证这可以通过在内核代码中添加
printf
语句轻松实现。但是,是的,当
grid\u width
width
不同时,索引到
width
大小数据数组将不正确。如果在普通C代码中这样做,它也不会正常工作。