Help us understand the problem. What is going on with this article?

Coral Edge TPU Dev Board の OpenCL 環境を確認

1. 概要

 前回記事 では、Coral EdgeTPU Dev Board 上で、TensorFlow Lite の GPU Delegate (OpenGLES版)を試しました。
 一方で、GPU Delegate には OpenCL版 もあり、かねてからこちらも試してみたいと思っていました。

 EdgeTPU DevBoard の GPU は、カタログスペック によれば、 OpenGLES3.1 に加えて OpenCL にも対応しているので、うまくやれば DevBoard 上で GPU Delegate (OpenCL版) を動かせるはずです。(前回同様、EdgeTPU DevBoard なのに EdgeTPU を使いません。)

 今回の記事では、その第一歩として、EdgeTPU DevBoard における OpenCL の動作環境構築までを書いてみます。

2. 必要ファイルの確認

 この作業に着手する前は、「そもそも DevBoard 上で OpenCL アプリをビルドするために必要なヘッダファイルやライブラリは、どこかに用意されてるのか?」という心配もあったのですが、あっけなく見つかりました。DevBoard 上に最初から存在しているようです。

■OpenCL ヘッダファイル

mendel@green-rabbit:~$ ls -l /usr/include/CL
total 188
-rw-r--r-- 1 root root 74542 Jun 14  2016 cl.h
-rw-r--r-- 1 root root 18168 Sep  8  2016 cl_ext.h
-rw-r--r-- 1 root root 43558 Sep  8  2016 cl_platform.h
-rw-r--r-- 1 root root  1993 Jun 14  2016 opencl.h
(以下略)

■OpenCL ライブラリ

mendel@green-rabbit:~$ ls -l /usr/lib/vivante/
total 17904
-rw-r--r-- 1 root root 2161664 Mar 20  2019 libCLC.so
-rw-r--r-- 1 root root 4322368 Mar 20  2019 libLLVM_viv.so
-rw-r--r-- 1 root root   26928 Mar 20  2019 libOpenCL.so
-rw-r--r-- 1 root root  372872 Mar 20  2019 libSPIRV_viv.so
-rw-r--r-- 1 root root  320440 Mar 20  2019 libVivanteOpenCL.so
(以下略)

 DevBoard 上で、上記ファイルを使ってネイティブビルドすれば、OpenCL アプリをビルドすることができそうです。

3. OpenCL デバイスクエリ

 とっかかりのOpenCLアプリとして、Dev Board の GPU がどのような OpenCL デバイスとして見えるのかを確認するQueryアプリを作りました。

3.1 Queryアプリの実装

 下記のように、OpenCL プラットフォーム および OpnCL デバイスに関する情報取得を行うAPIを一通り叩くようなコードを準備します。
 特に目新しいコードではありませんが、実際に私が使ったコードは、ここ で公開しています。

main.c
#include <CL/cl.h>

#define PRINT_PLATFORM_INFO_STR(pf_id, param_name)              \
    do                                                          \
    {                                                           \
        char strbuf[1024];                                      \
        clGetPlatformInfo (pf_id, param_name, sizeof(strbuf), strbuf, NULL); \
        fprintf (stderr, " %-24s: %s\n", #param_name, strbuf);  \
    } while (0)

opencl_device_query () 
{
    cl_platform_id* pf_ids;
    cl_uint i, j, num_platforms;

    /* OpenCL プラットフォーム数を取得し、全てのプラットフォームID を取得 */
    clGetPlatformIDs (0, NULL, &num_platforms);

    pf_ids = (cl_platform_id*)malloc (num_platforms * sizeof (cl_platform_id));
    clGetPlatformIDs (num_platforms, pf_ids, NULL);

    /* i 番目のプラットフォームに関する Query */
    for (i = 0; i < num_platforms; i++)
    {
        cl_platform_id pf_id = pf_ids[i];
        cl_uint      num_devices;
        cl_device_id *devices;

        PRINT_PLATFORM_INFO_STR(pf_id, CL_PLATFORM_NAME);
        PRINT_PLATFORM_INFO_STR(pf_id, CL_PLATFORM_VENDOR);
        PRINT_PLATFORM_INFO_STR(pf_id, CL_PLATFORM_VERSION);
        PRINT_PLATFORM_INFO_STR(pf_id, CL_PLATFORM_PROFILE);
        PRINT_PLATFORM_INFO_STR(pf_id, CL_PLATFORM_EXTENSIONS);

        /* i 番目のプラットフォームに属する全てのデバイスIDを取得 */
        clGetDeviceIDs (pf_id, CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);

        devices = (cl_device_id *)malloc (sizeof(cl_device_id) * num_devices);
        clGetDeviceIDs (pf_id, CL_DEVICE_TYPE_ALL, num_devices, devices, &num_devices);

        for (j = 0; j < num_devices; j++)
        {
            query_cldev (devices[j]);
        }
    }
}

3.2 Queryアプリのビルド

 上記ソースコードは、DevBoard 上でネイティブビルドすれば、至ってシンプルにビルドすることができました。

mendel@green-rabbit:~$ gcc -L/usr/lib/vivante -lOpenCL main.c
mendel@green-rabbit:~$ ls -l a.out
-rwxr-xr-x 1 mendel mendel 18008 Nov  3 12:58 a.out*

3.3 Queryアプリ実行結果

 上記アプリを DevBoard 上で実行すると、下記のようなQuery結果が表示されます。
 OpenCL 1.2 Full Profile (DEVICE_TYPE=GPU) のデバイスとして、ちゃんと見えているようです。

--------------------------------------------------------
 OpenCL Platform [0/1]
--------------------------------------------------------
 CL_PLATFORM_NAME        : Vivante OpenCL Platform
 CL_PLATFORM_VENDOR      : Vivante Corporation
 CL_PLATFORM_VERSION     : OpenCL 1.2 V6.2.4.p2.163672
 CL_PLATFORM_PROFILE     : FULL_PROFILE
 CL_PLATFORM_EXTENSIONS  : cl_khr_icd

 ----------------------------------
  CL Device [0/1]
 ----------------------------------
  CL_DEVICE_NAME                          : Vivante OpenCL Device GC7000L.6214.0000
  CL_DEVICE_VENDOR                        : Vivante Corporation
  CL_DRIVER_VERSION                       : OpenCL 1.2 V6.2.4.p2.163672
  CL_DEVICE_OPENCL_C_VERSION              : OpenCL C 1.2
  CL_DEVICE_PROFILE                       : FULL_PROFILE
  CL_DEVICE_AVAILABLE                     : true
  CL_DEVICE_COMPILER_AVAILABLE            : true
  CL_DEVICE_TYPE                          : CL_DEVICE_TYPE_GPU
  CL_DEVICE_EXTENSIONS                    : cl_khr_byte_addressable_store cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_gl_sharing
  CL_DEVICE_VENDOR_ID                     : 5654870
  CL_DEVICE_MAX_COMPUTE_UNITS             : 1
  CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS      : 3
  CL_DEVICE_MAX_WORK_ITEM_SIZES           : 1024 / 1024 / 1024
  CL_DEVICE_MAX_WORK_GROUP_SIZE           : 1024
  CL_DEVICE_MAX_CLOCK_FREQUENCY           : 800 MHz
  CL_DEVICE_ADDRESS_BITS                  : 32
  CL_DEVICE_MAX_MEM_ALLOC_SIZE            : 128 MByte
  CL_DEVICE_GLOBAL_MEM_SIZE               : 256 MByte
  CL_DEVICE_ENDIAN_LITTLE                 : true
  CL_DEVICE_HOST_UNIFIED_MEMORY           : true
  CL_DEVICE_ERROR_CORRECTION_SUPPORT      : true
  CL_DEVICE_LOCAL_MEM_TYPE                : global
  CL_DEVICE_LOCAL_MEM_SIZE                : 32 KByte
  CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE      : 64 KByte
  CL_DEVICE_QUEUE_PROPERTIES              : CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE
  CL_DEVICE_QUEUE_PROPERTIES              : CL_QUEUE_PROFILING_ENABLE
  CL_DEVICE_IMAGE_SUPPORT                 : true
  CL_DEVICE_MAX_READ_IMAGE_ARGS           : 128
  CL_DEVICE_MAX_WRITE_IMAGE_ARGS          : 8
  CL_DEVICE_IMAGE2D_MAX_WIDTH             : 8192
  CL_DEVICE_IMAGE2D_MAX_HEIGHT            : 8192
  CL_DEVICE_IMAGE3D_MAX_WIDTH             : 8192
  CL_DEVICE_IMAGE3D_MAX_HEIGHT            : 8192
  CL_DEVICE_IMAGE3D_MAX_DEPTH             : 8192
  CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR   : 4
  CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT  : 4
  CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT    : 4
  CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG   : 4
  CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT  : 4
  CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE : 0
  CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF   : 0
  CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR      : 4
  CL_DEVICE_NATIVE_VECTOR_WIDTH_SHORT     : 4
  CL_DEVICE_NATIVE_VECTOR_WIDTH_INT       : 4
  CL_DEVICE_NATIVE_VECTOR_WIDTH_LONG      : 4
  CL_DEVICE_NATIVE_VECTOR_WIDTH_FLOAT     : 4
  CL_DEVICE_NATIVE_VECTOR_WIDTH_DOUBLE    : 0
  CL_DEVICE_NATIVE_VECTOR_WIDTH_HALF      : 0

4. 最後に

 EdgeTPU DevBoard 上で、OpenCL デバイスクエリに成功しました。
 (まだ CLカーネルは1つも動かしてませんが、)EdgeTPU DevBoard 上で OpenCL は動きそうな感じがしてきたので、引き続き、TensorFlow Lite (OpenCL版) に挑戦したいと思います。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした