0

私は OpenCL を学習しようとしています。これは非常に興味深いですが、学習曲線が急勾配です (少なくとも私にとっては)。

本に続いて: OpenCl in Action

私が持っているopenclデバイスに関する情報を提供する簡単なプログラムを書きましたが、まだコンテキストもカーネルも何もありません。

2 つの構造体を定義しました (オンラインのブログからのアイデア)。

:ファイルの最後にある通知にジャンプしてください

デバイスの説明

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;

PlatformDesc

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

} PlatformDesc;

また、2つの列挙型を定義しました

ピン情報

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);
    }


}

私はこれがたくさんあることを知っていますが、コメントで ==> とマークされたコードの部分に到達するまで、私のプログラムは正常に実行されます。ここがメインです

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.

2 番目のタヒチが特定されない場合があります。とにかく、私は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