9.1. コマンドキュー

9.1.1. clCreateCommandQueue

clCreateCommandQueue関数はコマンドキューを生成。

注記

詳しくは「表:clCreateCommandQueue」(表B.23「表:clCreateCommandQueue」)と「表:cl_command_queue_properties」(表B.24「表:cl_command_queue_properties」)を参照ください。

cl_command_queue org.jocl.CL.clCreateCommandQueue(
    cl_context context, //(1)
    cl_device_id device, //(2)
    long properties, //(3)
    int[] errcode_ret) //(4)

(1)

有効なOpenCLコンテキストを指定。

(2)

対象とするOpenCLデバイスを指定。

(3)

コマンドキューのプロパティのリストを指定するビットフィールド。

(4)

適切なエラーコードを戻します。

では実際のコードを見てみましょう。以下が例となります。

cl_command_queue queue;
queue = clCreateCommandQueue(
    context,
    device,
    CL_QUEUE_PROFILING_ENABLE, //(1)
    null);

(1)

プロファイルを有効にします。

プロパティを入れない場合は、0と入力すれば、フィールドは無視されます。

9.1.2. cl_command_queue_properties

注記

詳しくは「表:clCreateCommandQueue」(表B.23「表:clCreateCommandQueue」)と「表:cl_command_queue_properties」(表B.24「表:cl_command_queue_properties」)を参照ください。

9.1.3. clRetainCommandQueue

clRetainCommandQueue関数はcommand_queueの参照カウントをインクリメント。

注記

詳しくは「表:clRetainCommandQueue」(表B.25「表:clRetainCommandQueue」)を参照ください。

cl_int clRetainCommandQueue (
    cl_command_queue command_queue //(1)
)

(1)

コマンドキューを指定。

9.1.4. clReleaseCommandQueue

clReleaseCommandQueue関数はコマンドキューの参照カウントをデクリメントします。

注記

詳しくは「表:clReleaseCommandQueue」(表B.26「表:clReleaseCommandQueue」)を参照ください。

cl_int clReleaseCommandQueue (
    cl_command_queue command_queue //(1)
)

(1)

コマンドキューを指定。

clGetCommandQueueInfo

clGetCommandQueueInfo関数はコマンドキューについての情報を取得します。

注記

詳しくは「表:clGetCommandQueueInfo」(表B.27「表:clGetCommandQueueInfo」)と「表:cl_command_queue_info」(表B.28「表:cl_command_queue_info」)を参照ください。

cl_int clGetCommandQueueInfo (
    cl_command_queue command_queue, //(1)
    cl_command_queue_info param_name, //(2)
    size_t param_value_size, //(3)
    void *param_value, //(4)
    size_t *param_value_size_ret //(5)
)

(1)

情報を取得するコマンドキューを指定。

(2)

取得する情報を指定。

(3)

param_nameで指定した情報についての値が戻るメモリ空間へのポインタ。

(4)

param_valueが指すメモリの(バイトで表す)サイズを指定。

(5)

param_valueが取得するデータの実際の(バイトで表す)サイズを戻す。

ではコード例を見てみましょう。以下のコードでは、コマンドキューに関連付けられたデバイスを取得しています。

err = clGetCommandQueueInfo(
    queue,
    CL_QUEUE_DEVICE,
    sizeof(cl_device_id),
    &dev,
    NULL);
if(err < 0) {
    perror("Failed to get a command queue information on queue1");
    exit(1);
};

実装例

#ifndef HELLO_H
#define HELLO_H

#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#ifdef __APPLE__
#include <OpenCL/cl.h>
#else
#include <CL/cl.h>
#endif

#define PROGRAM_FILE "kernel_helloworld.cl"
#define FUNC "helloworld"

int main(int argc, char **argv)
{
        int err;

    /* OpenCL APIの変数 */
        cl_device_id device;
        cl_context context;
        cl_command_queue queue1;
        cl_command_queue queue2;
        cl_platform_id platform;

        /*
         * OpenCLデバイスのプラットフォームの特定
         * 最初に見つけたプラットフォームを使用します。
         * */
        err = clGetPlatformIDs(1, &platform, NULL);
        if(err < 0) {
          perror("Failed to identify a platform");
          exit(1);
        }

        /*
         * CPU/GPUデバイスの情報取得をします。
         * */
        err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 1, &device, NULL);
        if(err == CL_DEVICE_NOT_FOUND) {
          err = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 1, &device, NULL);
        }
        if(err < 0) {
          perror("Failed to access the devices on the platform");
          exit(1);
        }

        /* コンテキストの生成をします。 */
        context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
        if(err < 0) {
          perror("Unable to create a context");
          exit(1);
        }

        /* コマンドキューを生成します */
        queue1 = clCreateCommandQueue(context,
                        device,
                        0,
                        &err);
        if(err < 0) {
          perror("Failed to create a command queue 1");
          exit(1);
        };

        queue2 = clCreateCommandQueue(context,
                        device,
                        CL_QUEUE_PROFILING_ENABLE,
                        &err);
        if(err < 0) {
          perror("Failed to create a command queue 2");
          exit(1);
        };

        cl_device_id dev;
        cl_command_queue_properties cpro;

        err = clGetCommandQueueInfo(queue1, CL_QUEUE_DEVICE, sizeof(cl_device_id), &dev, NULL);
        if(err < 0) {
          perror("Failed to get a command queue information on queue1");
          exit(1);
        };
        err |= clGetCommandQueueInfo(queue2, CL_QUEUE_PROPERTIES, sizeof(cl_command_queue_properties), &cpro, NULL);
        if(err < 0) {
          perror("Failed to get a command queue information on queue2");
          exit(1);
        };

        size_t size = 0;
        err = clGetDeviceInfo(dev, CL_DEVICE_MAX_WORK_GROUP_SIZE, sizeof(size), &size, NULL);
        if(err < 0) {
                printf("errorcode: %d\n",err);
                perror("Failed to get a device information");
                exit(1);
        };
        printf("CL_DEVICE_MAX_WORK_GROUP_SIZE: %lu\n", size);

        if(cpro & CL_QUEUE_PROFILING_ENABLE) {
                printf("CL_QUEUE_PROFILING_ENABLE: on\n");
        }
        if(cpro & CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE) {
                printf("CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE: on\n");
        }

        /* OpenCL APIで割り当てたメモリーを解放します */
    clReleaseCommandQueue(queue1);
    clReleaseCommandQueue(queue2);
    clReleaseContext(context);

}

#endif //HELLO_H

出力. 

CL_DEVICE_MAX_WORK_GROUP_SIZE: 512
CL_QUEUE_PROFILING_ENABLE: on

9.1.5. cl_command_queue_info

注記

詳しくは「表:clGetCommandQueueInfo」(表B.27「表:clGetCommandQueueInfo」)と「表:cl_command_queue_info」(表B.28「表:cl_command_queue_info」)を参照ください。

Copyright 2018-2019, by Masaki Komatsu