gpt4 book ai didi

c++ - 我的 OpenCL 程序中的 SIGSEGV

转载 作者:行者123 更新时间:2023-11-28 03:02:05 25 4
gpt4 key购买 nike

实际上,问题是我的程序会显示 SIGSEGV 错误消息,但并非总是如此。这意味着它有时运行良好,但有时会出现故障。所以我想知道这可能是因为我的 C 程序正在使用大量内存资源?资源限制每次都在变化?希望得到您的回复,谢谢。

代码很长,很高兴收到您的来信,告诉您需要哪一部分。

但是我有一段调试信息,不知道对大家有没有帮助:

[New Thread 0x7ffff7e63700 (LWP 31256)]
[New Thread 0x7ffff393f700 (LWP 31257)]
[New Thread 0x7ffff312c700 (LWP 31258)]
[New Thread 0x7ffff2919700 (LWP 31260)]
[New Thread 0x7ffff2106700 (LWP 31261)]
Detaching after fork from child process 31265.
Detaching after fork from child process 31266.

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff708944a in _int_malloc () from /lib64/libc.so.6

如你所见,在构建了几个线程之后,malloc 面临问题。会不会是内存容量的问题?

这是我的一些代码:

#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>

#ifdef __APPLE__
#include <OpenCL/opencl.h>
#else
#include <CL/cl.h>
#endif

#include "compcol_double.h"
#include "comprow_double.h"
#include "coord_double.h"
#include "iohb_double.h"

#include "dehaze_set_opencl.h"
#include "default_set_opencl.h"
#include "load_image_opencl.h"

using namespace std;

//relative path is where program is executing
const char *kernel_path = "dehaze.cl";
const char *kernel_name = "dehaze";

const int ARRAY_SIZE = 100;

int main(int argc, char **argv){
//OpenCL program
cl_device_id device_id = NULL;
cl_context context = NULL;
cl_command_queue command_queue = NULL;
cl_program program = NULL;
cl_kernel kernel = NULL;
cl_platform_id platform_id = NULL;
cl_uint ret_num_devices;
cl_uint ret_num_platforms;
cl_int ret;
cl_int errNum;

//Image
cl_mem imageObjects[2] = {0,0};
cl_sampler sampler = NULL;

//Get Platform and Device Info
ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
ret = clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_DEFAULT, 1, &device_id, &ret_num_devices);

//Create OpenCL Context
context = clCreateContext(NULL, 1, &device_id, NULL, NULL, &ret);

//Create Command Queue
command_queue = clCreateCommandQueue(context, device_id, 0, &ret);

//Create Program
program = CreateProgram(context, device_id, kernel_path);
if (program == NULL) {
return 1;
}

// Make sure the device supports images, otherwise exit
cl_bool imageSupport = CL_FALSE;
clGetDeviceInfo(device_id, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool),
&imageSupport, NULL);
if (imageSupport != CL_TRUE)
{
std::cerr << "OpenCL device does not support images." << std::endl;
return 1;
}

// Now the Image Processor Kernel is loaded
// Load input image from file and load it into
// an OpenCL image object
int width, height;
imageObjects[0] = LoadImage(context, (char *) "./pic/Flowers.JPG", width, height);
if (imageObjects[0] == 0)
{
std::cerr << "Error loading: " << std::string(argv[1]) << std::endl;
return 1;
}

// Create ouput image object
cl_image_format clImageFormat;
clImageFormat.image_channel_order = CL_RGBA;
clImageFormat.image_channel_data_type = CL_UNORM_INT8;
imageObjects[1] = clCreateImage2D(context,
CL_MEM_WRITE_ONLY,
&clImageFormat,
width,
height,
0,
NULL,
&errNum);

if (errNum != CL_SUCCESS)
{
std::cerr << "Error creating CL output image object." << std::endl;
return 1;
}

// Create sampler for sampling image object
sampler = clCreateSampler(context,
CL_FALSE, // Non-normalized coordinates
CL_ADDRESS_CLAMP_TO_EDGE,
CL_FILTER_NEAREST,
&errNum);

if (errNum != CL_SUCCESS)
{
std::cerr << "Error creating CL sampler object." << std::endl;
return 1;
}

//Create OpenCL kernel

//Kernel1: calculate the t's value
//t is the mainly matrix in this algorithm
kernel = clCreateKernel(program, "get_t_mat", NULL);
if(kernel == NULL){
std::cerr<<"Failed to create kernel"<<std::endl;
return 1;
}

int t_size = width * height;
int img_size = width * height;
float t_mat[width * height];
memset( t_mat, 0, sizeof(t_mat));

cl_mem t_buffer = clCreateBuffer(context,
CL_MEM_READ_WRITE,
sizeof(float) * t_size,
NULL, NULL);

if(t_buffer == NULL){
std::cerr << "Error creating buffer" <<endl;
return 1;
}

// Set the kernel arguments
errNum = clSetKernelArg(kernel, 0, sizeof(cl_mem), &imageObjects[0]);
errNum |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &t_buffer);
errNum |= clSetKernelArg(kernel, 2, sizeof(cl_sampler), &sampler);
errNum |= clSetKernelArg(kernel, 3, sizeof(cl_int), &width);
errNum |= clSetKernelArg(kernel, 4, sizeof(cl_int), &height);
if (errNum != CL_SUCCESS)
{
std::cerr << "Error setting kernel arguments." << std::endl;
return 1;
}

size_t localWorkSize[2] = { 16, 16 };
size_t globalWorkSize[2] = { RoundUp(localWorkSize[0], width),
RoundUp(localWorkSize[1], height) };

// Queue the kernel up for execution
errNum = clEnqueueNDRangeKernel(command_queue, kernel, 2, NULL,
globalWorkSize, localWorkSize,
0, NULL, NULL);
if (errNum != CL_SUCCESS)
{
std::cerr << "Error queuing kernel for execution." << std::endl;
return 1;
}

errNum = clEnqueueReadBuffer(command_queue,
t_buffer,
CL_TRUE, 0,
t_size*sizeof(float),
t_mat,
0, NULL, NULL);

if( errNum!=CL_SUCCESS){
std::cerr << "Error write back buffer" <<endl;
return 1;
}

//Kernel2: calculate the win_b
kernel = clCreateKernel(program, "get_win_b", NULL);
if(kernel == NULL){
std::cerr<<"Failed to create kernel"<<std::endl;
return 1;
}

int win_b_size = width * height;
float win_b[width * height];
memset( win_b, 0, sizeof(win_b));

cl_mem win_b_buffer = clCreateBuffer(context,
CL_MEM_READ_WRITE,
sizeof(float) * t_size,
NULL, NULL);

if(win_b_buffer == NULL){
std::cerr << "Error creating buffer" <<endl;
return 1;
}

// Set the kernel arguments
errNum = clSetKernelArg(kernel, 0, sizeof(cl_mem), &t_buffer);
//errNum |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &imageObjects[1]);
errNum |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &win_b_buffer);
//errNum |= clSetKernelArg(kernel, 2, sizeof(cl_sampler), &sampler);
errNum |= clSetKernelArg(kernel, 2, sizeof(cl_int), &width);
errNum |= clSetKernelArg(kernel, 3, sizeof(cl_int), &height);
if (errNum != CL_SUCCESS)
{
std::cerr << "Error setting kernel arguments." << std::endl;
return 1;
}

// Queue the kernel up for execution
errNum = clEnqueueNDRangeKernel(command_queue, kernel, 2, NULL,
globalWorkSize, localWorkSize,
0, NULL, NULL);

if (errNum != CL_SUCCESS)
{
std::cerr << "Error queuing kernel for execution." << std::endl;
return 1;
}

errNum = clEnqueueReadBuffer(command_queue,
win_b_buffer,
CL_TRUE, 0,
win_b_size*sizeof(float),
win_b,
0, NULL, NULL);

if( errNum!=CL_SUCCESS){
std::cerr << "Error write back buffer" <<endl;
return 1;
}

cout << 1 << endl;

//Kernel 3: vals
int neb_size = 9;
kernel = clCreateKernel(program, "get_vals", NULL);
if(kernel == NULL){
std::cerr<<"Failed to create kernel"<<std::endl;
return 1;
}


long long tlen = width * height * neb_size * neb_size;
double *vals = new double[tlen];
int *row_inds = new int[tlen];
int *col_inds = new int[tlen];

memset(vals,0,sizeof(float)*tlen);
memset(row_inds,0,sizeof(int)*tlen);
memset(col_inds,0,sizeof(int)*tlen);

int indsM[width*height];
for(int i = 0; i<width*height; i++)
indsM[i] = i+1;

// int test_size = 0;

cl_mem vals_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(float) * tlen, NULL, NULL);
cl_mem row_inds_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(int) * tlen, NULL, NULL);
cl_mem col_inds_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(int) * tlen, NULL, NULL);
cl_mem indsM_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
sizeof(int)*width*height, NULL, NULL);
//cl_mem test_buffer = clCreateBuffer(context, CL_MEM_READ_WRITE,
// sizeof(float)*test_size, NULL, NULL);

if(vals_buffer == NULL || row_inds_buffer == NULL
|| col_inds_buffer == NULL || indsM_buffer == NULL ){
std::cerr << "Error creating buffer" <<endl;
return 1;
}

errNum = clEnqueueWriteBuffer( command_queue, indsM_buffer, CL_FALSE, 0,
width*height, indsM, 0, NULL, NULL);
if(errNum != CL_SUCCESS){
cerr<<"Error writing buffer"<<endl;
exit(1);
}

// Set the kernel arguments
// Needs to be repaired
errNum = clSetKernelArg(kernel, 0, sizeof(cl_mem), &imageObjects[0]);
errNum |= clSetKernelArg(kernel, 1, sizeof(cl_mem), &indsM_buffer);
errNum |= clSetKernelArg(kernel, 2, sizeof(cl_sampler), &sampler);
errNum |= clSetKernelArg(kernel, 3, sizeof(cl_mem), &vals_buffer);
errNum |= clSetKernelArg(kernel, 4, sizeof(cl_mem), &row_inds_buffer);
errNum |= clSetKernelArg(kernel, 5, sizeof(cl_mem), &col_inds_buffer);
errNum |= clSetKernelArg(kernel, 6, sizeof(cl_int), &width);
errNum |= clSetKernelArg(kernel, 7, sizeof(cl_int), &height);
if (errNum != CL_SUCCESS)
{
std::cerr << "Error setting kernel arguments." << std::endl;
return 1;
}

// Queue the kernel up for execution
size_t t_localWorkSize[2] = { 1, 1 };
size_t t_globalWorkSize[2] = { RoundUp(localWorkSize[0], width),
RoundUp(localWorkSize[1], height) };

errNum = clEnqueueNDRangeKernel(command_queue, kernel, 2, NULL,
t_globalWorkSize, t_localWorkSize,
0, NULL, NULL);

if (errNum != CL_SUCCESS)
{
std::cerr << "Error queuing kernel for execution." << std::endl;
return 1;
}

errNum = clEnqueueReadBuffer(command_queue, vals_buffer, CL_TRUE, 0,
tlen*sizeof(float), vals, 0, NULL, NULL);
errNum |= clEnqueueReadBuffer(command_queue, row_inds_buffer, CL_TRUE, 0,
tlen*sizeof(float), row_inds, 0, NULL, NULL);
errNum |= clEnqueueReadBuffer(command_queue, col_inds_buffer, CL_TRUE, 0,
tlen*sizeof(float), col_inds, 0, NULL, NULL);
// cout << 1 << endl;

if( errNum!=CL_SUCCESS){
std::cerr << "Error write back buffer" <<endl;
return 1;
}

Coord_Mat_double SparseMat(width,height,tlen,vals,row_inds,col_inds);
cout << SparseMat.dim(0) << endl;
cout << width << endl;

// Read the output buffer back to the Host
/*
char *buffer = new char [width * height * 4];
size_t origin[3] = { 0, 0, 0 };
size_t region[3] = { width, height, 1};
errNum = clEnqueueReadImage(command_queue, imageObjects[1], CL_TRUE,
origin, region, 0, 0, buffer,
0, NULL, NULL);
if (errNum != CL_SUCCESS)
{
std::cerr << "Error reading result buffer." << std::endl;
return 1;
}
*/

//std::cout << std::endl;
std::cout << "Executed program succesfully." << std::endl;


//memset(buffer, 0xff, width * height * 4);
// Save the image out to disk
/*
if (!SaveImage((char *) "out2.png", buffer, width, height))
{
std::cerr << "Error writing output image" << std::endl;
delete [] buffer;
return 1;
}

delete [] buffer;
*/
return 0;
}

感谢

最佳答案

你可以使用 gdb。

使用 -g 标志编译所有源代码。

从终端运行:

gdb <your program>

然后在 gdb shell 中:

r <arguments>

现在等待SIGSEGV发生时键入:where或:bt

它会向您显示崩溃时代码中的确切位置。

关于c++ - 我的 OpenCL 程序中的 SIGSEGV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20533402/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com