VELVETDETH
VELVETDETH

Reputation: 314

SIGSEGV in my OpenCL program

Actually, the problem is that my program will show the message of SIGSEGV fault, but not always. That means it sometimes runs well, but sometimes breaks down. So I wonder it is probably for my C program is using a lot of memory resource? And the resource limit changes every time? Hope for your reply, thanks.

The code is so long and I'll be glad to hear from you about what section that you need.

But I have a piece of the debug information and I dont know would it be helpful for you guys:

[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

As you can see, after the several threads are built, the malloc faces problems. Will it be the trouble of memory capacity?

And here is some of my codes:

#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

Upvotes: 0

Views: 780

Answers (1)

SHR
SHR

Reputation: 8313

you can use gdb.

compile all your source code with the -g flag.

from terminal run:

gdb <your program>

then in the gdb shell:

r <arguments>

now wait for SIGSEGV when it occur type: where or: bt

it will show you the exact place in your code it was when it crashed.

Upvotes: 2

Related Questions