На прошлой неделе был рассмотрен Ubuntu 18.04 на плате ODROID-XU4, протестированы большинство заявленных функций. Однако, были оставлены без внимания функции, перечисленные в списке изменений:
Аппаратное ускорение GPU с помощью OpenGL ES 3.1 и драйверов OpenCL 1.2 для графического процессора Mali T628MP6
Хотя тестировался OpenGL ES с помощью таких инструментов, как glmark2-es2 и es2gears, а также было представлена демонстрация WebGL в Chromium, не тестировался OpenCL, так как нам о нем мало что известно, кроме того, что он используется для GPGPU (GPU общего назначения) для ускорения таких как задач, как обработка изображений и звука. Это хороший предлог, чтобы узнать немного больше, попробовать его на плате и написать краткое руководство, как начать работу с OpenGL на оборудовании с помощью Arm Mali GPU. Цель этого обзора – показать, как запустить OpenCL, и утилиту OpenCL, не вдаваясь в нюансы кода OpenCL. Если вы хотите узнать больше о кодировании OpenCL на Arm, один из способов – проверить исходный код предоставленных образцов.
Вычиcлительная библиотека Arm и OpenCL
Поскольку мы не знали, с чего начать, перейдем на форум, где показано, как использовать Arm Compute Library для тестирования OpenCL на плате.
Соответствующий пост датирован январем 2018 года и основан на Compute Library 17.12, но вы можете проверить последнюю версию и документацию на https://arm-software.github.io/ComputeLibrary/latest/. Последняя версия – 18.03, актуальная на момент написания этого обзора, поэтому загрузим ее и попытаемся установить ее в соответствии с инструкциями:
1 2 3 4 5 |
wget https://github.com/ARM-software/ComputeLibrary/archive/v18.03.tar.gz tar xvf v18.03.tar.gz cd ComputeLibrary-18.03/ sudo apt install scons scons Werror=1 -j8 debug=0 neon=1 opencl=1 embed_kernels=1 os=linux arch=armv7a build=native |
Однако, неудача.
1 |
g++: internal compiler error: Killed (program cc1plus) |
Взглянув на kernel log с dmesg, стало ясно, что на плате закончилась память: «Недостаточно памяти: Завершить процесс 4984 (cc1plus). Недостаточно памяти: Завершить процесс 4984 (cc1plus)». Поэтому нам пришлось настроить swap файл (1 Гб):
1 2 3 4 5 |
sudo dd if=/dev/zero of=/swapfile bs=1024 count=1M sudo chown root.root /swapfile sudo chmod 0600 /swapfile sudo mkswap /swapfile sudo swapon /swapfile |
… появилось больше памяти…
1 2 3 4 |
free -m total used free shared buff/cache available Mem: 1994 336 520 34 1137 1568 Swap: 1023 0 1023 |
перед перезапуском сборки с поддержкой NEON и OpenCL:
1 |
scons Werror=1 -j8 debug=0 neon=1 opencl=1 embed_kernels=1 os=linux arch=armv7a build=native |
и на этот раз процесс может быть завершен:
1 |
scons: done building targets. |
И мы можем скопировать библиотеки в /usr/lib:
1 |
sudo cp build/*.so /usr/lib/ |
Имеется ряд образцов, рассмотрим их:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
ls examples/ SConscript graph_mobilenet_qasymm8.cpp cl_convolution.cpp graph_resnet50.cpp cl_events.cpp graph_squeezenet.cpp cl_sgemm.cpp graph_squeezenet_v1_1.cpp gc_absdiff.cpp graph_vgg16.cpp gc_dc.cpp graph_vgg19.cpp graph_alexnet.cpp neon_cartoon_effect.cpp graph_googlenet.cpp neon_cnn.cpp graph_inception_v3.cpp neon_convolution.cpp graph_inception_v4.cpp neon_copy_objects.cpp graph_lenet.cpp neon_scale.cpp graph_mobilenet.cpp neoncl_scale_median_gaussian.cpp |
Обратите внимание, что некоторые из них относятся только к NEON и не используют OpenCL, а префикс объясняет тип образца:
- cl_*.cpp –> OpenCL examples
- gc_*.cpp –> GLES compute shaders examples
- graph_*.cpp –> Graph examples
- neoncl_*.cpp –> NEON / OpenCL interoperability examples
- neon_*.cpp –> NEON examples
Все образцы также были созданы и могут быть найдены в каталоге build/examples. Запускаем cl_convolution после генерации образа Raw ppm с использованием Gimp:
1 2 3 4 5 6 7 8 9 10 |
time ./cl_convolution ~/ODROID-XU4Q-Large.ppm ./cl_convolution Test passed real 0m5.814s user 0m4.893s sys 0m0.758s |
Он может обрабатывать фотографию (5184 x 3456) менее чем за 6 секунд. Если мы посмотрим на полученное изображение, мы увидим, что обработка OpenCL преобразует изображение в оттенки серого.
Оригинальное изображение (Слева) vs После обработки OpenCL (справа)
Повторим аналогичную операцию с convert, которое было скомпилировано без поддержки OpenCL, поэтому использует только программное обеспечение:
1 2 3 4 5 |
time convert ODROID-XU4Q-Large.ppm -colorspace Gray ODROID-XU4Q-Large-Grayscale.ppm real 0m10.475s user 0m0.724s sys 0m2.957s |
Это заняло чуть более 10 секунд, это почти в два раза больше времени, используемого OpenCL. Файлы изображений PPM, однако, превышают 50 Мб, поэтому часть времени используется для чтения и сохранения файла с флэш-памяти eMMC. Повторение тестов дает аналогичную производительность (~ 6 секунд против ~ 11 секунд), что незначительно.
Конечная версия convert показывает, что OpenCL не является частью доступных функций в ImageMagick:
1 2 3 4 5 6 |
convert -version Version: ImageMagick 6.9.7-4 Q16 arm 20170114 http://www.imagemagick.org Copyright: © 1999-2017 ImageMagick Studio LLC License: http://www.imagemagick.org/script/license.php Features: Cipher DPC Modules OpenMP Delegates (built-in): bzlib djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png tiff wmf x xml zlib |
Попробуем другой образец:
1 2 3 4 5 6 7 8 9 10 |
time ./cl_events ~/ODROID-XU4Q-Large.ppm ./cl_events Test passed real 0m3.068s user 0m2.527s sys 0m0.369s |
Что было сделано? Открываем файл, он выглядит так же, как и первый образец (изображение в оттенках серого), но на самом деле изображение масштабировано (50% в ширину, 50% по высоте)
1 2 |
file ~/ODROID-XU4Q-Large.ppm_out.ppm /home/odroid/ODROID-XU4Q-Large.ppm_out.ppm: Netpbm image data, size = 2592 x 1728, rawbits, pixmap |
Последний образец cl_sgemm управляет матрицами. Основная цель трех OpenCL (cl_xxx_ samples) заключается в том, чтобы показать, как использовать OpenCL Convolution, Events и SGEMM (Single-precision Matrix Multiple), используя вычислительную библиотеку.
Вы также можете рассмотреть другие образцы для NEON и OpenGL ES, а Arm Community опубликовала сообщение в блоге, в котором объясняется, как запустить neon_cartoon_effect на Raspberry Pi, и подробно объясняется исходный код. На самом деле вам не нужна плата RPi, так как любая Arm Board с процессором, поддерживает NEON.
clinfo Utility
clinfo – это утилита, которая выводит информацию о платформах и устройствах OpenCL в системе. Поэтому устанавливаем ее на плату
1 |
sudo apt install clinfo |
Но запуск программы не дает никакой полезной информации
1 2 |
clinfo Number of platforms 0 |
Совсем не то, что ожидалось. К счастью, как настроить clinfo объясняется в ODROID Magazine,, поэтому давайте попробуем. Нам нужен драйвер фреймбуфера Mali:
1 |
sudo apt install mali-fbdev |
и настраиваем vendor ICD file:
1 2 |
sudo mkdir -p /etc/OpenCL/vendors sudo sh -c 'echo "/usr/lib/arm-linux-gnueabihf/mali-egl/libOpenCL.so" > /etc/OpenCL/vendors/armocl.icd' |
Теперь мы можем запустить clinfo:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
clinfo Number of platforms 1 Platform Name ARM Platform Platform Vendor ARM Platform Version OpenCL 1.2 v1.r12p0-04rel0.03af15950392f3702b248717f4938b82 Platform Profile FULL_PROFILE Platform Extensions 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_byte_addressable_store cl_khr_3d_image_writes cl_khr_fp64 cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_fp16 cl_khr_gl_sharing cl_khr_icd cl_khr_egl_event cl_khr_egl_image cl_arm_core_id cl_arm_printf cl_arm_thread_limit_hint cl_arm_non_uniform_work_group_size cl_arm_import_memory Platform Extensions function suffix ARM Platform Name ARM Platform Number of devices 2 Device Name Mali-T628 Device Vendor ARM Device Vendor ID 0x6200010 Device Version OpenCL 1.2 v1.r12p0-04rel0.03af15950392f3702b248717f4938b82 Driver Version 1.2 Device OpenCL C Version OpenCL C 1.2 v1.r12p0-04rel0.03af15950392f3702b248717f4938b82 Device Type GPU Device Profile FULL_PROFILE Device Available Yes Compiler Available Yes Linker Available Yes Max compute units 4 Max clock frequency 600MHz Device Partition (core) Max number of sub-devices 0 Supported partition types None Max work item dimensions 3 Max work item sizes 256x256x256 Max work group size 256 Preferred work group size multiple 4 Preferred / native vector sizes char 16 / 16 short 8 / 8 int 4 / 4 long 2 / 2 half 8 / 8 (cl_khr_fp16) float 4 / 4 double 2 / 2 (cl_khr_fp64) Half-precision Floating-point support (cl_khr_fp16) Denormals Yes Infinity and NANs Yes Round to nearest Yes Round to zero Yes Round to infinity Yes IEEE754-2008 fused multiply-add Yes Support is emulated in software No Single-precision Floating-point support (core) Denormals Yes Infinity and NANs Yes Round to nearest Yes Round to zero Yes Round to infinity Yes IEEE754-2008 fused multiply-add Yes Support is emulated in software No Correctly-rounded divide and sqrt operations No Double-precision Floating-point support (cl_khr_fp64) Denormals Yes Infinity and NANs Yes Round to nearest Yes Round to zero Yes Round to infinity Yes IEEE754-2008 fused multiply-add Yes Support is emulated in software No Address bits 64, Little-Endian Global memory size 2090397696 (1.947GiB) Error Correction support No Max memory allocation 522599424 (498.4MiB) Unified memory for Host and Device Yes Minimum alignment for any data type 128 bytes Alignment of base address 1024 bits (128 bytes) Global Memory cache type Read/Write Global Memory cache size 131072 (128KiB) Global Memory cache line size 64 bytes Image support Yes Max number of samplers per kernel 16 Max size for 1D images from buffer 65536 pixels Max 1D or 2D image array size 2048 images Max 2D image size 65536x65536 pixels Max 3D image size 65536x65536x65536 pixels Max number of read image args 128 Max number of write image args 8 Local memory type Global Local memory size 32768 (32KiB) Max number of constant args 8 Max constant buffer size 65536 (64KiB) Max size of kernel argument 1024 Queue properties Out-of-order execution Yes Profiling Yes Prefer user sync for interop No Profiling timer resolution 1000ns Execution capabilities Run OpenCL kernels Yes Run native kernels No printf() buffer size 1048576 (1024KiB) Built-in kernels Device Extensions 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_byte_addressable_store cl_khr_3d_image_writes cl_khr_fp64 cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_fp16 cl_khr_gl_sharing cl_khr_icd cl_khr_egl_event cl_khr_egl_image cl_arm_core_id cl_arm_printf cl_arm_thread_limit_hint cl_arm_non_uniform_work_group_size cl_arm_import_memory Device Name Mali-T628 Device Vendor ARM Device Vendor ID 0x6200010 Device Version OpenCL 1.2 v1.r12p0-04rel0.03af15950392f3702b248717f4938b82 Driver Version 1.2 Device OpenCL C Version OpenCL C 1.2 v1.r12p0-04rel0.03af15950392f3702b248717f4938b82 Device Type GPU Device Profile FULL_PROFILE Device Available Yes Compiler Available Yes Linker Available Yes Max compute units 2 Max clock frequency 600MHz Device Partition (core) Max number of sub-devices 0 Supported partition types None Max work item dimensions 3 Max work item sizes 256x256x256 Max work group size 256 Preferred work group size multiple 4 Preferred / native vector sizes char 16 / 16 short 8 / 8 int 4 / 4 long 2 / 2 half 8 / 8 (cl_khr_fp16) float 4 / 4 double 2 / 2 (cl_khr_fp64) Half-precision Floating-point support (cl_khr_fp16) Denormals Yes Infinity and NANs Yes Round to nearest Yes Round to zero Yes Round to infinity Yes IEEE754-2008 fused multiply-add Yes Support is emulated in software No Single-precision Floating-point support (core) Denormals Yes Infinity and NANs Yes Round to nearest Yes Round to zero Yes Round to infinity Yes IEEE754-2008 fused multiply-add Yes Support is emulated in software No Correctly-rounded divide and sqrt operations No Double-precision Floating-point support (cl_khr_fp64) Denormals Yes Infinity and NANs Yes Round to nearest Yes Round to zero Yes Round to infinity Yes IEEE754-2008 fused multiply-add Yes Support is emulated in software No Address bits 64, Little-Endian Global memory size 2090397696 (1.947GiB) Error Correction support No Max memory allocation 522599424 (498.4MiB) Unified memory for Host and Device Yes Minimum alignment for any data type 128 bytes Alignment of base address 1024 bits (128 bytes) Global Memory cache type Read/Write Global Memory cache size 131072 (128KiB) Global Memory cache line size 64 bytes Image support Yes Max number of samplers per kernel 16 Max size for 1D images from buffer 65536 pixels Max 1D or 2D image array size 2048 images Max 2D image size 65536x65536 pixels Max 3D image size 65536x65536x65536 pixels Max number of read image args 128 Max number of write image args 8 Local memory type Global Local memory size 32768 (32KiB) Max number of constant args 8 Max constant buffer size 65536 (64KiB) Max size of kernel argument 1024 Queue properties Out-of-order execution Yes Profiling Yes Prefer user sync for interop No Profiling timer resolution 1000ns Execution capabilities Run OpenCL kernels Yes Run native kernels No printf() buffer size 1048576 (1024KiB) Built-in kernels Device Extensions 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_byte_addressable_store cl_khr_3d_image_writes cl_khr_fp64 cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_fp16 cl_khr_gl_sharing cl_khr_icd cl_khr_egl_event cl_khr_egl_image cl_arm_core_id cl_arm_printf cl_arm_thread_limit_hint cl_arm_non_uniform_work_group_size cl_arm_import_memory NULL platform behavior clGetPlatformInfo(NULL, CL_PLATFORM_NAME, ...) ARM Platform clGetDeviceIDs(NULL, CL_DEVICE_TYPE_ALL, ...) Success [ARM] clCreateContext(NULL, ...) [default] Success [ARM] clCreateContextFromType(NULL, CL_DEVICE_TYPE_DEFAULT) Success (1) Platform Name ARM Platform Device Name Mali-T628 clCreateContextFromType(NULL, CL_DEVICE_TYPE_CPU) No devices found in platform clCreateContextFromType(NULL, CL_DEVICE_TYPE_GPU) Success (2) Platform Name ARM Platform Device Name Mali-T628 Device Name Mali-T628 clCreateContextFromType(NULL, CL_DEVICE_TYPE_ACCELERATOR) No devices found in platform clCreateContextFromType(NULL, CL_DEVICE_TYPE_CUSTOM) No devices found in platform clCreateContextFromType(NULL, CL_DEVICE_TYPE_ALL) Success (2) Platform Name ARM Platform Device Name Mali-T628 Device Name Mali-T628 ICD loader properties ICD loader Name OpenCL ICD Loader ICD loader Vendor OCL Icd free software ICD loader Version 2.2.11 ICD loader Profile OpenCL 2.1 |
Достаточно много информации, показывающей одну платформу с двумя устройствами OpenCL (и Mali-T628), поддерживающими OpenCL 1.2.
Это все для этого небольшого руководства по началу работы. Если вы действительно хотите что-то сделать с помощью OpenCL, пришло время прочитать документацию вычислительной библиотеки Arm и другие Интернет-ресурсы.
Благодарим сайт cnx-software.com за предоставленную информацию.
Оригинал статьи опубликован здесь