我的OpenCL程序中的SIGSEGV

时间:2013-12-12 01:32:30

标签: c++ opencl sigsegv

实际上,问题是我的程序会显示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;
}

THX

1 个答案:

答案 0 :(得分:2)

你可以使用gdb。

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

来自终端运行的

gdb <your program>

然后在gdb shell中:

r <arguments>

现在等SIGSEGV类型:where或:bt

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