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

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

1. 概要

 前回および前々回 では、Coral EdgeTPU DevBoard 上で、TensorFlow Lite GPU Delegate の OpenGLES版 および OpenCL版 を試しました。

 OpenGLES, OpenCL とくれば、その次に気になるのは、Vulkan です。
 TensorFlow Lite のロードマップ にも、GPU Delegate のバックエンドとして、今後 Vulkan がサポートされることが列挙されています。
tflite_vulkan.png"

 幸い、EdgeTPU DevBoard の GPU は Vulkan にも対応している ので、うまくいけば、GPU Delegate Vulkan版 も動かせるかもしれません。
 (下記画像は DevBoard データシート画面のキャプチャ)
devboard_gpu.png

 そんなことを夢見ながら EdgeTPU DevBoard 上での Vulkan 環境について調べてみると、Vulkan 1.0 なら動かせそうだ ということが分かりました。
 本記事では、DevBoard での Vulkan 環境について確認できたことをまとめます。

(注)前回同様、EdgeTPU DevBoard 上で作業しますが、EdgeTPU アクセラレータは使いません。使うのはGPUです。

2. Vulkan 関連ファイルの確認

2.1 プリインストールファイル

 DevBoard 上で Vulkan を動かすために必要なライブラリは、DevBoard上に最初から存在しているようです。
 このライブラリとリンクすれば、Vulkan アプリを動かせそうです。

mendel@indigo-calf:~$ ls -l /usr/lib/vivante/
total 19000
lrwxrwxrwx 1 root root      14 Nov  8 21:45 libvulkan.so -> libvulkan.so.1
-rw-r--r-- 1 root root  571944 Nov  8 21:45 libvulkan.so.1
-rw-r--r-- 1 root root  380912 Nov  8 21:45 libSPIRV_viv.so
-rw-r--r-- 1 root root 5990448 Nov  8 21:45 libVSC.so
(以下略)

2.2 apt パッケージ

 さらに、DevBoard 上で Vulkan 関係のパッケージを apt 検索すると、いろいろ出てきます。
 なんかもう、apt install するだけで vulkan アプリ動かせそうな気になってきます。

mendel@indigo-calf:~$ apt search vulkan
Sorting... Done
Full Text Search... Done
dxvk/mendel-day 0.96+ds1-1 all
  Vulkan-based translation layer for Direct3D 10/11

libvkd3d-dev/mendel-day 1.1-3 arm64
  Direct3D 12 to Vulkan translation - development files

libvkd3d-utils1/mendel-day 1.1-3 arm64
  Direct3D 12 to Vulkan translation - utilities library

libvkd3d1/mendel-day 1.1-3 arm64
  Direct3D 12 to Vulkan translation - library

libvulkan-dev/mendel-day,now 1.1.97-2 arm64 [installed]
  Vulkan loader library -- development files

libvulkan1/mendel-day,now 1.1.97-2 arm64 [installed,automatic]
  Vulkan loader library

mesa-vulkan-drivers/mendel-day 18.3.6-2 arm64
  Mesa Vulkan graphics drivers

vkd3d-demos/mendel-day 1.1-3 arm64
  Direct3D 12 to Vulkan translation - demos

vulkan-tools/mendel-day,now 1.1.97+dfsg1-2 arm64 [installed]
  Miscellaneous Vulkan utilities

vulkan-utils/mendel-day 1.1.97+dfsg1-2 all
  transitional package

vulkan-validationlayers/mendel-day 1.1.97-2 arm64
  Vulkan validation layers

vulkan-validationlayers-dev/mendel-day 1.1.97-2 arm64
  Vulkan validation layers -- development files

3. vulkaninfo による Vulkan デバイスクエリ

 予想通り、apt を使って vulkaninfo ツールをインストールするだけで、いとも簡単に「DevBoard の GPU がどのようなVulkanデバイスとして見えるのか」を確認することができました。

mendel@indigo-calf:~$ sudo apt install vulkan-tools
mendel@indigo-calf:~$ vulkaninfo --html

 なお vulkaninfo は、引数に --html をつければ、ちょっとオシャレで見やすいhtml形式で出力してくれるので便利です。

vulkaninfo.png

 vulkaninfo 結果から、Vulkan 1.0 (device type = INTEGRATED_GPU) のデバイスとして、ちゃんと見えることが確認できました。

4. デバイス Query アプリの自前ビルド

 ここまで1行もソースを書かずビルドもせず Vulkan 環境の確認をしてきましたが、ここからは、自分で Vulkan アプリをビルド、動作確認してみます。
 動かすアプリは、上記 vulkaninfo のソース を参考に、デバイスQueryに必要な最小限を切り出した自前アプリとします。

4.1 Vulkan ヘッダファイルのインストール

 DevBoard 上には、Vulkan アプリのビルドに必要な vulkan.h がプリインストールされていないようなので、apt install libvulkan-dev でインストールします。

 なお、この作業により、 /usr/lib/aarch64-linux-gpu/libvulkan.so もおまけでインストールされますが、このライブラリは DevBoard 上で動作しません。ファイル名が libvulkan.so.1.1.97 なので、「ひょっとして Vulkan 1.1 が使えるのかも」、と淡い期待をもって実験してみましたが、残念ながら、Vulkan 初期化時に呼び出す vkCreateInstance() 関数が VK_ERROR_INCOMPATIBLE_DRIVER エラーを返すため、使えませんでした。

 アプリビルド時・実行時は、DevBoard にプレインストールされている /usr/lib/vivante/libvulkan.so を使いましょう。

# Vulkan ヘッダファイルのインストール
mendel@indigo-calf:~$ sudo apt install libvulkan-dev

# インストールされたヘッダファイル確認
mendel@indigo-calf:~$ ll /usr/include/vulkan/
total 2800
-rw-r--r--  1 root root    1580 Jan 13  2019 vulkan.h
(以下略)

# おまけでインストールされる vulkan ライブラリ。このライブラリは vulkanインタンス初期化でエラー
mendel@indigo-calf:~$ ll /usr/lib/aarch64-linux-gnu/
lrwxrwxrwx  1 root root       14 Jan 23  2019 libvulkan.so -> libvulkan.so.1
lrwxrwxrwx  1 root root       19 Jan 23  2019 libvulkan.so.1 -> libvulkan.so.1.1.97
-rw-r--r--  1 root root   350808 Jan 23  2019 libvulkan.so.1.1.97
(以下略)

4.2 Query アプリの実装

 上記 vulkaninfo のソース を参考に、デバイスQueryに必要な最小限を切り出します。
 下記はその一部分抜粋です。とくに目新しいコードではありませんが、ご参考までに、私が実験したソースコード全体は、ここ で公開しています。

main.c
#include <vulkan/vulkan.h>

VkPhysicalDevice
query_vulkan_device(VkInstance vk_instance)
{
    VkResult err;
    uint32_t gpu_count, i, j;
    VkPhysicalDevice phydev, *phydev_array;

    err = vkEnumeratePhysicalDevices(vk_instance, &gpu_count, NULL);
    assert(err == VK_SUCCESS);

    fprintf(stderr, "\n");
    fprintf(stderr, "-----------------------------------------------------\n");
    fprintf(stderr, " Physical Devices count : %d\n", gpu_count);
    fprintf(stderr, "-----------------------------------------------------\n");

    if (gpu_count == 0)
    {
        fprintf(stderr, "vkEnumeratePhysicalDevices() returned no devices.\n");
        return NULL;
    }

    phydev_array = malloc(sizeof(VkPhysicalDevice) * gpu_count);

    err = vkEnumeratePhysicalDevices(vk_instance, &gpu_count, phydev_array);
    assert(err == VK_SUCCESS);

    for (i = 0; i < gpu_count; i ++)
    {
        fprintf(stderr, " \n");
        fprintf(stderr, " ##### Device[%d/%d] #####\n", i, gpu_count);

        /* ------------------------------------ *
         * PhysicalDeviceProperties
         * ------------------------------------ */
        phydev = phydev_array[i];
        VkPhysicalDeviceProperties  dev_props;

        vkGetPhysicalDeviceProperties(phydev, &dev_props);

        fprintf(stderr, " \n");
        fprintf(stderr, " ------ PhysicalDeviceProperties\n");
        fprintf(stderr, " deviceName   : %s\n",   dev_props.deviceName);
        fprintf(stderr, " deviceType   : %s\n", get_vkdevtype(dev_props.deviceType));
        fprintf(stderr, " apiVersion   : %d.%d.%d\n",
                VK_VERSION_MAJOR(dev_props.apiVersion),
                VK_VERSION_MINOR(dev_props.apiVersion),
                VK_VERSION_PATCH(dev_props.apiVersion));
        fprintf(stderr, " driverVersion: 0x%x\n", dev_props.driverVersion);
        fprintf(stderr, " vendorID     : 0x%x\n", dev_props.vendorID);
        fprintf(stderr, " deviceID     : 0x%x\n", dev_props.deviceID);
(以下略)

4.3 Queryアプリのビルド

 上記ソースコードは、DevBoard 上でネイティブビルドすれば、至ってシンプルにビルドすることができます。
 念のため、ライブラリパスを明記して、プリイントール版の libvulkan.so を使うようにしています。

# Queryアプリのビルド
mendel@indigo-calf:~/work/VulkanSample/query_vk_devices$ gcc -L/usr/lib/vivante main.c -lvulkan

# ビルド生成物
mendel@indigo-calf:~/work/VulkanSample/query_vk_devices$ ls -l a.out
-rwxr-xr-x 1 mendel mendel 27528 Nov 23 05:30 a.out*

# 念のため依存ライブラリを確認
mendel@indigo-calf:~/work/VulkanSample/query_vk_devices$ ldd ./a.out
        linux-vdso.so.1 (0x0000ffffa66bc000)
        libvulkan.so.1 => /usr/lib/vivante/libvulkan.so.1 (0x0000ffffa65dc000)
        libstdc++.so.6 => /usr/lib/aarch64-linux-gnu/libstdc++.so.6 (0x0000ffffa6451000)
        libm.so.6 => /lib/aarch64-linux-gnu/libm.so.6 (0x0000ffffa6394000)
        libgcc_s.so.1 => /lib/aarch64-linux-gnu/libgcc_s.so.1 (0x0000ffffa6370000)
        libc.so.6 => /lib/aarch64-linux-gnu/libc.so.6 (0x0000ffffa61fe000)
        libGAL.so => /usr/lib/vivante/libGAL.so (0x0000ffffa610a000)
        libSPIRV_viv.so => /usr/lib/vivante/libSPIRV_viv.so (0x0000ffffa609e000)
        libVSC.so => /usr/lib/vivante/libVSC.so (0x0000ffffa5b24000)
        libGLSLC.so => /usr/lib/vivante/libGLSLC.so (0x0000ffffa5a26000)
        libwayland-client.so.0 => /usr/lib/aarch64-linux-gnu/libwayland-client.so.0 (0x0000ffffa5a07000)
        /lib/ld-linux-aarch64.so.1 (0x0000ffffa668e000)
        libdl.so.2 => /lib/aarch64-linux-gnu/libdl.so.2 (0x0000ffffa59f3000)
        librt.so.1 => /lib/aarch64-linux-gnu/librt.so.1 (0x0000ffffa59db000)
        libpthread.so.0 => /lib/aarch64-linux-gnu/libpthread.so.0 (0x0000ffffa59ac000)
        libffi.so.6 => /usr/lib/aarch64-linux-gnu/libffi.so.6 (0x0000ffffa5994000)

4.4 queryアプリ実行結果

 上記アプリを DevBoard 上で実行すると、下記のようなQuery結果が表示されます。
 自前ビルドしたアプリでも、apt でインストールした vulkaninfo と同様、Vulkan 1.0 (device type = INTEGRATED_GPU) のデバイスとして、ちゃんと見えることが確認できました。

Vulkan Instance Version = 1.0.0

-----------------------------------------------------
 Instance Extension (GLOBAL) count : 5
-----------------------------------------------------
  VK_EXT_debug_report                      ver: 8
  VK_KHR_get_physical_device_properties2   ver: 1
  VK_KHR_surface                           ver:25
  VK_KHR_display                           ver:21
  VK_KHR_wayland_surface                   ver: 6

-----------------------------------------------------
 Instance Layer count : 0
-----------------------------------------------------

-----------------------------------------------------
 Physical Devices count : 1
-----------------------------------------------------

 ##### Device[0/1] #####

 ------ PhysicalDeviceProperties
 deviceName   : VeriSilicon
 deviceType   : INTEGRATED_GPU
 apiVersion   : 1.0.59
 driverVersion: 0x1802004
 vendorID     : 0x10002
 deviceID     : 0x70006214
 limits.maxImageDimension1D:   8192
 limits.maxImageDimension2D:   8192
 limits.maxImageDimension3D:   512
 limits.maxImageDimensionCube: 8192
 (snipped)
 sparseProp.residencyStandard2DBlockShape           : 0
 sparseProp.residencyStandard2DMultisampleBlockShape: 0
 sparseProp.residencyStandard3DBlockShape           : 0
 sparseProp.residencyAlignedMipSize                 : 0
 sparseProp.residencyNonResidentStrict              : 0

 ------ ExtensionProperties count = 2
 VK_KHR_maintenance1 (ver:1)
 VK_KHR_swapchain (ver:68)

 ------ QueueFamilyProperties count = 1
 QueueFamily[0/1]
   queueFlags            : GRAPHICS, COMPUTE, TRANSFER,
   queueCount            : 1
   timestampValidBits    : 0
   minImgTransGranularity: (1, 1, 1)

 ------ PhysicalDeviceFeatures
 robustBufferAccess    : 1
 fullDrawIndexUint32   : 0
 imageCubeArray        : 1
 independentBlend      : 1
 geometryShader        : 0
 tessellationShader    : 0
 sampleRateShading     : 0
 shaderFloat64         : 0
 shaderInt64           : 0
 shaderInt16           : 0
 (snipped)

 ------ PhysicalDeviceMemoryProperties
 memoryTypeCount = 1
 memoryType[0/1]
   heapIndex    : 0
   propertyFlags: 0x00000007
        DEVICE_LOCAL_BIT
        HOST_VISIBLE_BIT
        HOST_COHERENT_BIT
 memoryHeapCount = 1
 memoryHeap[0/1]
   size         : 768 [MB]
   flags        : 0x00000001
        DEVICE_LOCAL_BIT

 ------ PhysicalDeviceFormatProperties
 [VK_FORMAT_R8G8B8A8_UINT]
   linearTilingFeatures : 0x0000cc87
        VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
        VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
        VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
        VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
        VK_FORMAT_FEATURE_BLIT_SRC_BIT
        VK_FORMAT_FEATURE_BLIT_DST_BIT
        VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
        VK_FORMAT_FEATURE_TRANSFER_DST_BIT
   optimalTilingFeatures: 0x0000cc87
        VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
        VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
        VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
        VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
        VK_FORMAT_FEATURE_BLIT_SRC_BIT
        VK_FORMAT_FEATURE_BLIT_DST_BIT
        VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
        VK_FORMAT_FEATURE_TRANSFER_DST_BIT
   bufferFeatures       : 0x00000078
        VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
        VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
        VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
        VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
 [VK_FORMAT_R8G8B8A8_UNORM]
   linearTilingFeatures : 0x00000000
   optimalTilingFeatures: 0x0000dd87
        VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
        VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
        VK_FORMAT_FEATURE_STORAGE_IMAGE_ATOMIC_BIT
        VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BIT
        VK_FORMAT_FEATURE_COLOR_ATTACHMENT_BLEND_BIT
        VK_FORMAT_FEATURE_BLIT_SRC_BIT
        VK_FORMAT_FEATURE_BLIT_DST_BIT
        VK_FORMAT_FEATURE_SAMPLED_IMAGE_FILTER_LINEAR_BIT
        VK_FORMAT_FEATURE_TRANSFER_SRC_BIT
        VK_FORMAT_FEATURE_TRANSFER_DST_BIT
   bufferFeatures       : 0x00000078
        VK_FORMAT_FEATURE_UNIFORM_TEXEL_BUFFER_BIT
        VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_BIT
        VK_FORMAT_FEATURE_STORAGE_TEXEL_BUFFER_ATOMIC_BIT
        VK_FORMAT_FEATURE_VERTEX_BUFFER_BIT
  (snipped)

5.最後に

 EdgeTPU DevBoard上で、Vulkan デバイスクエリができました。

 サポートしている Vulkan バージョンが 1.0 と少し古いのが気になりますが、
 もし、TensorFlow Lite GPU Delegate が要求する Vulkan バージョンが 1.0 なら、DevBoard 上での動作に挑戦したいと思います。
 
 そして、GPU Delegate のバックエンド3兄弟 (OpenGLES/OpenCL/Vulkan) でガチンコ勝負できればいいなと思っています。

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
ユーザーは見つかりませんでした