0

我正在尝试学习 OpenCL,这很有趣,但学习曲线陡峭(至少对我而言)。

跟随本书:OpenCl in Action

我编写了一个简单的程序,它可以为我提供有关我拥有的 opencl 设备的信息,但仍然没有上下文,没有内核,什么都没有。

我定义了两个结构(来自一些在线博客的想法):

注意:请跳转到文件末尾的通知

设备描述

typedef struct DeviceDesc{
    cl_device_id    deviceID;
    cl_device_type  Type;
    char*           TypeString;
    char*           Name;
    char*           Ext;
    cl_bool         Available;
    cl_ulong        GlobalMemSize;
    cl_ulong        LocalMemSize;
    cl_uint         Clock;
    cl_uint         ComputeUnits;

} DeviceDesc;

平台描述

typedef struct PlatformDesc{
    cl_platform_id  pID;
    char*           pName;
    char*           pExt;
    char*           pVersion;
    char*           pVendor;

} PlatformDesc;

我还定义了两个枚举

PINFO

enum pINFO{
    name = 0,
    vendor = 1,
    ext = 2,
    profile = 3,
    version = 4,


}pINFO;

DINFO

enum dINFO{
    dname = 0,   //char*
    davail = 1, //clbool
    dext = 2,  //char*
    dgmemsize = 3, //ulong
    dlmemsize = 4, //ulong
    dmaxclock = 5, //uint
    dcompunits = 6,//uint

}dINFO;

我还定义了这些函数

void cl_error_check(cl_int err,char* msg) {
    if (!err==CL_SUCCESS) {
        printf("%s\n",msg);
        exit(1);
    }
}


void cl_PFINFO(PlatformDesc* platform,enum pINFO itype,int i) {
    size_t datasize;
    char*  data;
    cl_int err;

    //name = 0,   //char*
    //avail = 1, //clbool
    //ext = 2,  //char*
    //gmemsize = 3, //ulong
    //lmemsize = 4, //ulong
    //maxclock = 5, //uint
    //compunits = 6,//uint
    switch(itype) {
    case 0: //name
        err = clGetPlatformInfo(platform[i].pID,CL_PLATFORM_NAME,0,NULL,&datasize);
        cl_error_check(err,"Couldn't Obtain Plaform Name!");
        data = (char*)malloc(sizeof(datasize));
        clGetPlatformInfo(platform[i].pID,CL_PLATFORM_NAME,datasize,data,NULL);
        platform[i].pName = data;
        break;
    case 1: //avail
        err = clGetPlatformInfo(platform[i].pID,CL_PLATFORM_VENDOR,0,NULL,&datasize);
        cl_error_check(err,"Couldn't Obtain Plaform Vendor!");
        data = (char*)malloc(sizeof(datasize));
        clGetPlatformInfo(platform[i].pID,CL_PLATFORM_VENDOR,datasize,data,NULL);
        platform[i].pVendor = data;
        break;
    case 2: //ext
        err = clGetPlatformInfo(platform[i].pID,CL_PLATFORM_EXTENSIONS,0,NULL,&datasize);
        cl_error_check(err,"Couldn't Obtain Plaform Extensions!");
        data = (char*)malloc(sizeof(datasize));
        clGetPlatformInfo(platform[i].pID,CL_PLATFORM_EXTENSIONS,datasize,data,NULL);
        platform[i].pExt = data;
        break;
    case 3: //globalmemorysize

        break;
    case 4: //localmemorysize
        err = clGetPlatformInfo(platform[i].pID,CL_PLATFORM_VERSION,0,NULL,&datasize);
        cl_error_check(err,"Couldn't Obtain Plaform Version!");
        data = (char*)malloc(sizeof(datasize));
        clGetPlatformInfo(platform[i].pID,CL_PLATFORM_VERSION,datasize,data,NULL);
        platform[i].pVersion = data;
        break;

        break;
    default:
        printf("Unknown Platform Info Type! %d",itype);
        exit(1);
    }


}
void cl_DVINFO(DeviceDesc* dev,enum dINFO itype,int i) {
    size_t datasize;
    char*  data;
    cl_bool av;
    cl_int err;

    cl_ulong gm,lm;
    cl_uint  clock,units;
     //name = 0,   //char*
    //avail = 1, //clbool
    //ext = 2,  //char*
    //gmemsize = 3, //ulong
    //lmemsize = 4, //ulong
    //maxclock = 5, //uint
    //compunits = 6,//uint

    switch(itype) {
    case 0: //name
        err = clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_NAME,0,NULL,&datasize);
        cl_error_check(err,"Couldn't Obtain Device Name!");
        data = (char*)malloc(sizeof(datasize));
        clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_NAME,datasize,data,NULL);
        dev[i].Name = data;
        printf("\nDevice Name: %s",dev[i].Name);
        break;
    case 1: //avail
        err = clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_AVAILABLE,sizeof(cl_bool),&av,NULL);
        cl_error_check(err,"Couldn't Obtain Device Availability!");
        dev[i].Available = av;
        printf("\nDevice Available: %d",dev[i].Available);
        break;
    case 2: //ext
        err = clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_EXTENSIONS,0,NULL,&datasize);
        cl_error_check(err,"Couldn't Obtain Device Extensions!");
        data = (char*)malloc(sizeof(datasize));
        clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_EXTENSIONS,datasize,data,NULL);
        dev[i].Ext = data;
        break;
    case 3: //globalmemorysize
        err = clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_GLOBAL_MEM_SIZE,sizeof(cl_ulong),&gm,NULL);
        cl_error_check(err,"Couldn't Obtain Device Global Memory Size!");
        dev[i].GlobalMemSize = gm;
        printf("\nDevice Global Memory Size: %lu",dev[i].GlobalMemSize);
        break;
    case 4: //localmemorysize
        err = clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_LOCAL_MEM_SIZE,sizeof(cl_ulong),&lm,NULL);
        cl_error_check(err,"Couldn't Obtain Device Local Memory Size!");
        dev[i].LocalMemSize = lm;
        printf("\nDevice Local Memory Size: %lu",dev[i].LocalMemSize);
        break;
    case 5: //Max Clock
        err = clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_MAX_CLOCK_FREQUENCY,sizeof(cl_uint),&clock,NULL);
        cl_error_check(err,"Couldn't Obtain info on Device Max Clock Frequency!");
        dev[i].Clock = clock;
        printf("\nDevice Clock: %u",dev[i].Clock);
        break;
    case 6://Max Compte
        err = clGetDeviceInfo(dev[i].deviceID,CL_DEVICE_MAX_COMPUTE_UNITS,sizeof(cl_uint),&units,NULL);
        cl_error_check(err,"Couldn't Obtain info on Device Max Computing Units!");
        dev[i].ComputeUnits = units;
        printf("\nDevice Compute Units: %u",dev[i].ComputeUnits);
        break;
    default:
        printf("Unknown Device Info Type! %d",itype);
        exit(1);
    }


}

我知道这很多,但是我的程序运行良好,直到我到达注释中标有 ==> 的代码部分,问题是有时,代码运行良好,有时在识别第二个 GPU 后崩溃,这是主要的

int main(int argc, char** argv) {
    /*
            OPEN CL INIT AND STUFF
    */
    cl_platform_id      platformID;
    cl_device_id        *CPUID,*GPUID;
    cl_uint             num_devices,addr_data,num_platforms = 1;
    cl_uint             num_CPU,num_GPU;
    cl_int              err, i;

    char                dname_data[48],dext_data[4096];
    int                 k;

    PlatformDesc*       platform = (PlatformDesc*)malloc(sizeof(PlatformDesc));
    DeviceDesc*         CPUS = NULL;
    DeviceDesc*         GPUS = NULL;


    err = clGetPlatformIDs(num_platforms,&platformID,NULL);
    cl_error_check(err,"Couldn't find any platforms!");
    platform[0].pID = platformID;
    //Get CPUs
    err = clGetDeviceIDs(platform[0].pID,CL_DEVICE_TYPE_CPU,NULL,NULL,&num_CPU);
    cl_error_check(err,"Error in finding CPUS!");

    CPUS = (DeviceDesc*)malloc(num_CPU*sizeof(DeviceDesc));
    CPUID = (cl_device_id*)malloc(num_CPU*sizeof(cl_device_id));

    err = clGetDeviceIDs(platform[0].pID,CL_DEVICE_TYPE_CPU,num_CPU,CPUID,NULL);\
    cl_error_check(err,"Error in Getting CPUS!");

    for (k = 0;k<num_CPU;k++) {
        CPUS[k].deviceID = CPUID[k];
        CPUS[k].Type = CL_DEVICE_TYPE_CPU;
        CPUS[k].TypeString = "CPU";
        //get device info
        int l;
        for (l=0;l<7;l++)
        cl_DVINFO(CPUS,l,k);
    }
    //Get GPUs
    err = clGetDeviceIDs(platform[0].pID,CL_DEVICE_TYPE_GPU,NULL,NULL,&num_GPU);
    cl_error_check(err,"Error in finding GPUS!");

    GPUS = (DeviceDesc*)malloc(num_GPU*sizeof(DeviceDesc));
    GPUID = (cl_device_id*)malloc(num_GPU*sizeof(cl_device_id));

    err = clGetDeviceIDs(platform[0].pID,CL_DEVICE_TYPE_GPU,num_GPU,GPUID,NULL);\
    cl_error_check(err,"Error in Getting GPUS!");

    for (k = 0;k<num_GPU;k++) {
            //==> Most of the crashing occurs here... if they occur
        GPUS[k].deviceID = GPUID[k];
        GPUS[k].Type = CL_DEVICE_TYPE_GPU;
        GPUS[k].TypeString = "GPU";
        int l;
        for (l=0;l<7;l++)
        cl_DVINFO(GPUS,l,k); //Here, i am getting the info "L" for the GPU K
    }

    //Ok Now get Platform info
    cl_PFINFO(platform,name,0);
    cl_PFINFO(platform,vendor,0);
    cl_PFINFO(platform,ext,0);
    cl_PFINFO(platform,version,0);
    scanf("%d",&k); //THIS SCANF is just to see if it reaches this part or not, useless
    //CLEANUP

    free(GPUID);
    free(CPUID);
    free(CPUS);
    free(GPUS);
    return 0;

}

这是我从我的机器获得的示例输出

Device Name: AMD FX(tm)-8120 Eight-Core Processor
Device Available: 1
Device Global Memory Size: 2147483648
Device Local Memory Size: 32768
Device Clock: 4100
Device Compute Units: 8
Device Name: Tahiti
Device Available: 1
Device Global Memory Size: 2147483648
Device Local Memory Size: 32768
Device Clock: 950
Device Compute Units: 28
Device Name: Tahiti
Device Available: 1
Device Global Memory Size: 2147483648
Device Local Memory Size: 32768
Device Clock: 950
Device Compute Units: 28
Process returned -1073741819 (0xC0000005)   execution time : 2.206 s
Press any key to continue.

有时没有确定第二个大溪地。无论如何,我得到一个 0xC0000005 (我认为这是访问冲突,又名与指针有关)

我的问题是,我哪里出错了:)。我的意思是如果我不能这样做,我将如何处理内核:P

注意

由于请求,我将发布代码失败的部分:

代码在这里失败

for (k = 0;k<num_CPU;k++) {
    CPUS[k].deviceID = CPUID[k];
    CPUS[k].Type = CL_DEVICE_TYPE_CPU;
    CPUS[k].TypeString = "CPU";
    //get device info
    int l;
    for (l=0;l<7;l++)
    cl_DVINFO(CPUS,l,k);
}
4

0 回答 0