尝试创建自定义结构类型时,Cudamaloc不起作用
我正在尝试构建一个cuda程序来进行光线跟踪,下面有一些代码:尝试创建自定义结构类型时,Cudamaloc不起作用,cuda,Cuda,我正在尝试构建一个cuda程序来进行光线跟踪,下面有一些代码: void build_world(World *w, RGBAColor* buffer){ w->vp = (ViewPlane*) malloc(sizeof(ViewPlane)); w->vp->hres = 512; w->vp->vres = 512; w->vp->buffer = buffer; w->vp->s = 1; ViewPlane *viewp
void build_world(World *w, RGBAColor* buffer){
w->vp = (ViewPlane*) malloc(sizeof(ViewPlane));
w->vp->hres = 512;
w->vp->vres = 512;
w->vp->buffer = buffer;
w->vp->s = 1;
ViewPlane *viewplane;
cudaMalloc(&viewplane,sizeof(ViewPlane)); //return cudaSuccess but pointer still NULL
cudaMemcpy(viewplane,w->vp,sizeof(ViewPlane),cudaMemcpyHostToDevice);
free(w->vp);
w->vp = viewplane;
cudaMalloc(&(w->background_color),sizeof(RGBAColor)); //return cudaSuccess but pointer still NULL
*(w->background_color) = black; //Memory access error
cudaMalloc(&(w->sphere),sizeof(Sphere)); //return cudaSuccess but pointer still NULL
w->sphere->center = Point3D(0.0,0.0,0.0);
w->sphere->radius = 300;
}
World*w是一个静态全局指针,它位于全局内存中。
我的问题是,我不能在设备内存中分配内存,所有的“cudamaloc”调用在大多数时间都不起作用
我按照@RobertCrovella在评论中的建议做了如下工作:
void build_world(World *w, RGBAColor* buffer){
checkCudaErrors( cudaMalloc(&(w->vp),sizeof(ViewPlane)));
getLastCudaError("viewplane allocate failed");
w->vp->hres = 512; //memory access errors occurs here
w->vp->vres = 512;
w->vp->buffer = buffer;
w->vp->s = 1;
checkCudaErrors( cudaMalloc(&(w->background_color),sizeof(RGBAColor)));
getLastCudaError("background allocate failed");
*(w->background_color) = black;
checkCudaErrors( cudaMalloc(&(w->sphere),sizeof(Sphere)));
getLastCudaError("sphere allocate failed");
w->sphere->center = Point3D(0.0,0.0,0.0);
w->sphere->radius = 300;
}
而且它只工作一次…Cudamaloc API仍然返回“cudaSuccess”,而不是
以下是结构的定义:
typedef float3 Point3D;
typedef uchar4 RGBAColor;
struct Sphere{
Point3D center;
float radius;
};
struct ViewPlane{
public:
int hres;
int vres;
float s;
//float gamma;
//float inv_gamma;
RGBAColor *buffer;
};
struct World{
public:
ViewPlane *vp;
RGBAColor *background_color;
Sphere *sphere;
};
在考虑了@RobertCrovella在下面的回答中提到的问题后,下面是build_world的第三个版本:
struct World{
public:
ViewPlane *vp;
RGBAColor background_color;
Sphere *sphere;
};
void build_world(World *w, RGBAColor* buffer){
World *h_world;
h_world = (World*)malloc(sizeof(World));
ViewPlane *h_vp = (ViewPlane*)malloc(sizeof(ViewPlane));
h_vp->hres = 512;
h_vp->vres = 512;
h_vp->buffer = buffer;
h_vp->s = 1;
checkCudaErrors( cudaMalloc(&(h_world->vp),sizeof(ViewPlane)));
getLastCudaError("viewplane allocate failed");
checkCudaErrors( cudaMemcpy(h_world->vp,h_vp,sizeof(ViewPlane),cudaMemcpyHostToDevice));
getLastCudaError("viewplane memory copy failed");
h_world->background_color = black;
Sphere *h_sphere = (Sphere*)malloc(sizeof(Sphere));
h_sphere->center = Point3D(0.0,0.0,0.0);
h_sphere->radius = 300;
checkCudaErrors( cudaMalloc(&(h_world->sphere),sizeof(Sphere)));
getLastCudaError("sphere allocate failed");
checkCudaErrors( cudaMemcpy(h_world->sphere,h_sphere,sizeof(Sphere),cudaMemcpyHostToDevice));
getLastCudaError("sphere memory copy failed");
checkCudaErrors( cudaMalloc( &w , sizeof(World)));
getLastCudaError( "world allocate failed" );
checkCudaErrors( cudaMemcpy(w,h_world,sizeof(World),cudaMemcpyHostToDevice));
getLastCudaError("world memory copy failed");
free(h_world);free(h_vp);free(h_sphere);
}
这一次,所有
cudaMemcpy
调用都不起作用:当运行到此函数结束时,h_vp
和h_sphere
的值良好h_world->vp
和h_world->sphere
do指向设备力矩区域,但包含错误值w
没有正确的值,它包含的所有指针都是0x00000000…这个问题已经正式成为“一团乱”,因为您发布了两个不同版本的build\u world
,除了我要求您添加的错误检查之外,它们在重要方面有所不同。我会尽量解决一些问题,因为我看到他们,但我的理解是模糊的混乱,在您的张贴
- 如果您要传递到
的指针build\u world
已经是一个设备指针(即分配了*w
),它似乎就是您所说的,那么这一切都不起作用。在设备上创建数据结构(其中还包含指向设备上其他数据结构的指针)是一个有点不直观的过程。无法将指针传递到设备上已经存在的cudamaloc
(即,已经是使用cudamaloc
创建的区域的一部分。相反,需要在主机上创建一组并行指针,cudamaloc
分别创建这些指针,然后使用cudaMemcpy将指针值复制到设备数据结构中的适当区域。要查看我所指的另一个示例来,看一看cudamaloc
- 无法在主机代码中取消对设备指针的引用。例如:
如果w->vp->hres = 512;
或w
是使用w->vp
设置的指针,则上述操作无效。相反,需要在主机上创建并行数据结构,在那里设置值,然后从主机到设备设置cudamaloc
:cudaMemcpy
注意,在这个简化的描述中,我忽略了我在上面第一点中提到的问题h_vp->hres = 512; cudaMemcpy(d_vp, h_vp, sizeof(vp_struct), cudaMemcpyHostToDevice);
- 如果反复调用
,如果传递相同的build\u world
指针,则需要确保正确使用*w
cudaFree
build\u world
的额外发布,我选择创建一个示例代码,该示例代码应修复剩余问题:
#include <stdio.h>
#include <vector_functions.h>
#define black make_uchar4(4,3,2,1)
#define white make_uchar4(0,1,2,3)
#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)
typedef float3 Point3D;
typedef uchar4 RGBAColor;
struct Sphere{
Point3D center;
float radius;
};
struct ViewPlane{
public:
int hres;
int vres;
float s;
//float gamma;
//float inv_gamma;
RGBAColor *buffer;
};
struct World{
public:
ViewPlane *vp;
RGBAColor background_color;
Sphere *sphere;
};
__global__ void my_kernel(World *w){
printf("w->vp->hres = %d\n", w->vp->hres);
printf("w->background_color.y = %d\n", w->background_color.y);
printf("w->sphere->radius = %f\n", w->sphere->radius);
printf("w->vp->buffer->y = %d\n", w->vp->buffer->y);
}
void build_world(World **w, RGBAColor* buffer){
World *h_world;
h_world = (World*)malloc(sizeof(World));
ViewPlane *h_vp = (ViewPlane*)malloc(sizeof(ViewPlane));
h_vp->hres = 512;
h_vp->vres = 512;
h_vp->s = 1;
cudaMalloc((void **)&(h_vp->buffer), sizeof(RGBAColor));
cudaCheckErrors("viewplane RGBAColor allocate failed");
cudaMemcpy(h_vp->buffer, buffer, sizeof(RGBAColor), cudaMemcpyHostToDevice);
cudaCheckErrors("viewplane RGBAColor copy failed");
cudaMalloc((void **)&(h_world->vp),sizeof(ViewPlane));
cudaCheckErrors("viewplane allocate failed");
cudaMemcpy(h_world->vp,h_vp,sizeof(ViewPlane),cudaMemcpyHostToDevice);
cudaCheckErrors("viewplane memory copy failed");
h_world->background_color = black;
Sphere *h_sphere = (Sphere*)malloc(sizeof(Sphere));
h_sphere->center = (Point3D) make_float3(0.0,0.0,0.0);
h_sphere->radius = 300;
cudaMalloc((void **)&(h_world->sphere),sizeof(Sphere));
cudaCheckErrors("sphere allocate failed");
cudaMemcpy(h_world->sphere,h_sphere,sizeof(Sphere),cudaMemcpyHostToDevice);
cudaCheckErrors("sphere memory copy failed");
cudaMalloc((void **)w , sizeof(World));
cudaCheckErrors( "world allocate failed" );
cudaMemcpy(*w,h_world,sizeof(World),cudaMemcpyHostToDevice);
cudaCheckErrors("world memory copy failed");
free(h_world);free(h_vp);free(h_sphere);
}
int main(){
World *d_w;
RGBAColor my_buffer = white;
build_world(&d_w, &my_buffer);
my_kernel<<<1,1>>>(d_w);
cudaDeviceSynchronize();
cudaCheckErrors("kernel fail");
return 0;
}
1.对所有cuda调用和内核调用执行操作2.报告发生错误的特定行以及在该行执行cuda错误检查时显示的特定错误消息3.提供所有相关的结构/类定义,如本例中的
World
。当我对所有“库达马洛克",为什么?@RobertCrovella它只运行一次…除了我要求您添加的错误检查之外,您发布的两个版本的build\u world
在非常重要的方面有所不同。您在第二个代码发布中犯了第一个代码发布中没有的重大错误。因此,我开始尝试回答这个问题,但发现在我的回答中,请不要试图提及。此外,我需要了解您是如何调用build\u world
的,以及您传递给它的指针的实际分配。如果*w
是指向设备全局内存的指针,则所有这些都不会像写的那样工作。world*w
我认为指针本身在主机内存中,一个它应该指向设备内存的一个区域。我正在尝试为构建世界中的指针*w
分配设备内存,因此我必须为构建世界中的*w
调用cudamaloc
…我发布了一个新版本的构建世界,这带来了另一个问题…你的第三篇帖子build\u world的
几乎是正确的。我没有试图解释最后的问题,而是选择用一个工作示例代码更新我的答案,应该解决剩余的问题。
$ ./t98
w->vp->hres = 512
w->background_color.y = 3
w->sphere->radius = 300.000000
w->vp->buffer->y = 1
$