clGetPlatformID的奇怪行为

时间:2018-12-26 07:54:48

标签: c opencl c-strings

我正在通过编写简单的opencl代码来测试opencl内核代码。 opencl有一个非常危险的问题。我使用GDB来检查代码,在“ clGetPlatformIDs”之后立即中断,但是在GDB内,“ bt”返回了许多其他函数,包括我自己的不应调用的函数。

我机器上的平台[0]和设备[0]是使用mesa驱动程序的AMD gpu。我几天前才刚刚学过opencl,然后仍然对这个问题一无所知。

main.c

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<CL/cl.h>
void print(float *a)
{
    printf("%f %f %f\n", a[0], a[1], a[2]);
}
char* read(char *filename)
{
    FILE *fp = fopen (filename , "rb" );
    if(!fp)
    {
        perror(filename);
        exit(1);
    }
    fseek(fp, 0L, SEEK_END);
    long filesize = ftell(fp);
    rewind(fp);
    char *buffer = malloc((filesize+1)*sizeof(char));
    if(!buffer)
    {   
        fclose(fp);
        fputs("memory alloc fails",stderr);
        exit(1);
    }
    if(1 != fread(buffer, filesize, 1, fp))
    {
        fclose(fp);
        free(buffer);
        fputs("entire read fails",stderr);
        exit(1);
    }
    buffer[filesize] = '\0';
    fclose(fp);
    printf("---------------------\n");
    printf("PROGRAM: size %d bytes\n", filesize);
    printf("---------------------\n");
    printf("%s\n", buffer);
    printf("---------------------\n");
    return buffer;
}
int main()
{
    const char *kernelSource = read("./fill.cl");
    const size_t kernelLength = strlen(kernelSource);
    cl_platform_id platform;
    clGetPlatformIDs(1, &platform, NULL);
    cl_device_id device;
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL);
    cl_context context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
    cl_command_queue_properties properties[] = {0};
    cl_command_queue queue = clCreateCommandQueueWithProperties(context, device, &(properties[0]), NULL);
    cl_program program = clCreateProgramWithSource(context, 1, (const char**) &kernelSource, &kernelLength, NULL);
    clBuildProgram(program, 1, &device, NULL, NULL, NULL);
    cl_kernel kernel = clCreateKernel(program, "fill", NULL);
    {
    unsigned int n = 3;
    float *h_a = malloc(n*sizeof(float));
    print(h_a);
    cl_mem d_a = clCreateBuffer(context, CL_MEM_READ_WRITE, n*sizeof(float), NULL, NULL);

    clEnqueueWriteBuffer(queue, d_a, CL_FALSE, 0, n*sizeof(float), h_a, 0, NULL, NULL);
    clSetKernelArg(kernel, 0, sizeof(cl_mem), &d_a);
    float X = 3.15;
    clSetKernelArg(kernel, 1, sizeof(float), &X);
    size_t global_dim = 3;
    size_t local_dim = 3;
    clEnqueueNDRangeKernel(queue, kernel, 1, NULL, &global_dim, &local_dim, 0, NULL, NULL);
    clEnqueueReadBuffer(queue, d_a, CL_FALSE, 0, n*sizeof(float), h_a, 0, NULL, NULL);
    clFinish(queue);
    print(h_a);
    clReleaseMemObject(d_a);
    free(h_a);
    }
    clReleaseKernel(kernel);
    clReleaseProgram(program);
    clReleaseCommandQueue(queue);
    clReleaseContext(context);
}

fill.cl

__kernel void fill(
        __global float *a, 
        __global const float x) 
{
    ulong i = get_global_id(0);
    a[i] = x;
    printf("%d\n", x);
}

来自GDB的日志

(gdb) b 49
Breakpoint 1 at 0x401507: file main.c, line 49.
(gdb) r
Starting program: /home/khanh/programming/opencl/examples/c/run 
Missing separate debuginfos, use: dnf debuginfo-install glibc-2.28-26.fc29.x86_64
warning: Loadable section ".note.gnu.property" outside of ELF segments
---------------------
PROGRAM: size 133 bytes
---------------------
__kernel void fill(
        __global float *a, 
        __global const float x) 
{
    ulong i = get_global_id(0);
    a[i] = x;
    printf("%d\n", x);
}

---------------------

Breakpoint 1, main () at main.c:49
49      clGetPlatformIDs(1, &platform, NULL);
Missing separate debuginfos, use: dnf debuginfo-install ocl-icd-2.2.12-2.fc29.x86_64
(gdb) b 50
Breakpoint 2 at 0x40151d: file main.c, line 51.
(gdb) c
Continuing.
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
warning: Loadable section ".note.gnu.property" outside of ELF segments

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7e2dcb8 in perror_internal () from /lib64/libc.so.6
Missing separate debuginfos, use: dnf debuginfo-install clang-libs-7.0.0-2.fc29.x86_64 elfutils-libelf-0.174-5.fc29.x86_64 expat-2.2.6-1.fc29.x86_64 libdrm-2.4.96-2.fc29.x86_64 libedit-3.1-24.20170329cvs.fc29.x86_64 libffi-3.1-18.fc29.x86_64 libgcc-8.2.1-6.fc29.x86_64 libstdc++-8.2.1-6.fc29.x86_64 llvm-libs-7.0.0-2.fc29.x86_64 mesa-libOpenCL-18.2.6-3.fc29.x86_64 ncurses-libs-6.1-8.20180923.fc29.x86_64 zlib-1.2.11-14.fc29.x86_64
(gdb) bt
#0  0x00007ffff7e2dcb8 in perror_internal () from /lib64/libc.so.6
#1  0x00007ffff7e2ddb2 in perror () from /lib64/libc.so.6
#2  0x0000000000401394 in read (filename=0x4 <error: Cannot access memory at address 0x4>) at main.c:14
#3  0x00007ffff32da697 in ?? () from /lib64/libLLVM-7.so
#4  0x00007ffff32db78c in llvm::MemoryBuffer::getFileAsStream(llvm::Twine const&) () from /lib64/libLLVM-7.so
#5  0x00007ffff3327fe4 in ?? () from /lib64/libLLVM-7.so
#6  0x00007ffff3328805 in llvm::sys::getHostNumPhysicalCores() () from /lib64/libLLVM-7.so
#7  0x00007ffff333df0d in llvm::heavyweight_hardware_concurrency() () from /lib64/libLLVM-7.so
#8  0x00007ffff322d686 in ?? () from /lib64/libLLVM-7.so
#9  0x00007ffff7fe1e0a in call_init.part () from /lib64/ld-linux-x86-64.so.2
#10 0x00007ffff7fe1f0a in _dl_init () from /lib64/ld-linux-x86-64.so.2
#11 0x00007ffff7fe5eff in dl_open_worker () from /lib64/ld-linux-x86-64.so.2
#12 0x00007ffff7ef9137 in _dl_catch_exception () from /lib64/libc.so.6
#13 0x00007ffff7fe576e in _dl_open () from /lib64/ld-linux-x86-64.so.2
#14 0x00007ffff7dba39a in dlopen_doit () from /lib64/libdl.so.2
#15 0x00007ffff7ef9137 in _dl_catch_exception () from /lib64/libc.so.6
#16 0x00007ffff7ef91d3 in _dl_catch_error () from /lib64/libc.so.6
#17 0x00007ffff7dbab09 in _dlerror_run () from /lib64/libdl.so.2
#18 0x00007ffff7dba43a in dlopen@@GLIBC_2.2.5 () from /lib64/libdl.so.2
#19 0x00007ffff7f8ad11 in _initClIcd_real () from /lib64/libOpenCL.so.1
#20 0x00007ffff7f8d35c in clGetPlatformIDs () from /lib64/libOpenCL.so.1

0 个答案:

没有答案