OpenCL and MPI Termux Troubleshooting: Difference between revisions
Created page with "{{DISPLAYTITLE:OpenCL + MPI di Termux (Android/Adreno) — Troubleshooting Lengkap}} Halaman ini mendokumentasikan proses menjalankan '''OpenCL + MPI''' secara bersamaan di Termux pada perangkat Android yang sudah di-root, lengkap dengan '''semua error yang ditemui, penyebabnya, dan cara memperbaikinya'''. Hasil akhir: sebuah program C++ yang membagi vektor lewat MPI ke beberapa proses, lalu tiap proses menghitung bagiannya di GPU Adreno lewat OpenCL. == Lingkungan..." |
No edit summary |
||
| (One intermediate revision by the same user not shown) | |||
| Line 1: | Line 1: | ||
Dokumentasi proses menjalankan '''OpenCL + MPI''' secara bersamaan di [https://termux.dev/en/ Termux] pada perangkat Android yang sudah di-root, lengkap dengan '''semua error yang ditemui, penyebabnya, dan cara memperbaikinya'''. Hasil akhir: sebuah program C++ yang membagi vektor lewat MPI ke beberapa proses, lalu tiap proses menghitung bagiannya di GPU Adreno lewat OpenCL. | |||
== Lingkungan == | == Lingkungan == | ||
| Line 36: | Line 34: | ||
! # !! Gejala (error) !! Penyebab singkat !! Fix singkat | ! # !! Gejala (error) !! Penyebab singkat !! Fix singkat | ||
|- | |- | ||
| 1 || <code>clinfo</code>: Number of platforms = 0 || Loader ocl-icd tidak menemukan driver vendor || Daftarkan ICD / muat driver vendor langsung | | 1 || <code>clinfo</code>: Number of platforms = 0 || Loader ocl-icd tidak menemukan driver vendor || Daftarkan [[ICD]] / muat driver vendor langsung | ||
|- | |- | ||
| 2 || clang: <code>cannot locate symbol _ZNSt6__ndk1...</code> || <code>LD_LIBRARY_PATH</code> global menarik libc++ Android || Jangan set <code>LD_LIBRARY_PATH</code> global; pisah env build vs run | | 2 || clang: <code>cannot locate symbol _ZNSt6__ndk1...</code> || <code>LD_LIBRARY_PATH</code> global menarik libc++ Android || Jangan set <code>LD_LIBRARY_PATH</code> global; pisah env build vs run | ||
| Line 63: | Line 61: | ||
Loader <code>ocl-icd</code> terpasang, tetapi tidak ada driver vendor yang terdaftar. Loader mencari berkas <code>*.icd</code> di <code>$PREFIX/etc/OpenCL/vendors/</code>; kalau kosong, hasilnya 0 platform. | Loader <code>ocl-icd</code> terpasang, tetapi tidak ada driver vendor yang terdaftar. Loader mencari berkas <code>*.icd</code> di <code>$PREFIX/etc/OpenCL/vendors/</code>; kalau kosong, hasilnya 0 platform. | ||
'''Catatan penting:''' driver Adreno <code>/vendor/lib64/libOpenCL.so</code> ternyata '''bukan driver ICD yang patuh''' (tidak meng-export <code>clIcdGetPlatformIDsKHR</code>). Jadi mendaftarkannya ke loader saja '''tidak selalu cukup''' | '''Catatan penting:''' driver Adreno <code>/vendor/lib64/libOpenCL.so</code> ternyata '''bukan driver ICD yang patuh''' (tidak meng-export <code>clIcdGetPlatformIDsKHR</code>). Jadi mendaftarkannya ke loader saja '''tidak selalu cukup'''; lihat [[#Masalah 5: "No OpenCL platform" saat program C++ dijalankan|Masalah 5]] untuk gambaran lengkapnya. Cara paling andal adalah memuat driver vendor '''langsung'''. | ||
=== Solusi === | === Solusi === | ||
| Line 135: | Line 133: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
Jangan menaruh <code>export LD_LIBRARY_PATH=...</code> di <code>~/.bashrc</code>. Untuk compile, driver vendor '''tidak''' dibutuhkan | Jangan menaruh <code>export LD_LIBRARY_PATH=...</code> di <code>~/.bashrc</code>. Untuk compile, driver vendor '''tidak''' dibutuhkan; <code>-lOpenCL</code> hanya butuh loader ocl-icd di <code>$PREFIX/lib</code>; library vendor hanya perlu saat runtime. | ||
== Masalah 3: header C++ OpenCL tidak ada (use of undeclared identifier 'cl') == | == Masalah 3: header C++ OpenCL tidak ada (use of undeclared identifier 'cl') == | ||
| Line 154: | Line 152: | ||
Dua hal berbeda: | Dua hal berbeda: | ||
* <code><CL/cl.h></code> adalah header '''C''' | * <code><CL/cl.h></code> adalah header '''C'''; isinya fungsi <code>clGetPlatformIDs</code>, <code>clCreateContext</code>, dst. Header ini '''tidak punya namespace <code>cl::</code>''' sama sekali. Maka semua <code>cl::Platform</code>, <code>cl::Device</code>, dsb. menjadi "undeclared". | ||
* Class <code>cl::*</code> hanya ada di <code><CL/opencl.hpp></code> (OpenCL C++ bindings), yang merupakan header '''terpisah''' (paket <code>opencl-clhpp</code>) dan '''bukan''' bagian dari <code>opencl-headers</code>. Header ini sering belum terpasang di Termux. | * Class <code>cl::*</code> hanya ada di <code><CL/opencl.hpp></code> (OpenCL C++ bindings), yang merupakan header '''terpisah''' (paket <code>opencl-clhpp</code>) dan '''bukan''' bagian dari <code>opencl-headers</code>. Header ini sering belum terpasang di Termux. | ||
| Line 161: | Line 159: | ||
Dua pilihan: | Dua pilihan: | ||
'''A. Pakai OpenCL C API dari C++''' (paling andal | '''A. Pakai OpenCL C API dari C++''' (paling andal; hanya butuh <code><CL/cl.h></code> yang sudah ada). Tetap C++ (pakai <code>std::vector</code>, <code>std::string</code>, <code>iostream</code>), tapi panggil fungsi C: | ||
<syntaxhighlight lang="cpp"> | <syntaxhighlight lang="cpp"> | ||
| Line 199: | Line 197: | ||
Pemicunya: OpenMPI memakai '''hwloc''' untuk mengikat (binding) proses ke core CPU saat <code>MPI_Init</code>, dan binding itu memanggil syscall yang diblokir seccomp Android. Karena ini terjadi saat init (sebelum komunikasi), '''mengganti transport tidak menolong'''. | Pemicunya: OpenMPI memakai '''hwloc''' untuk mengikat (binding) proses ke core CPU saat <code>MPI_Init</code>, dan binding itu memanggil syscall yang diblokir seccomp Android. Karena ini terjadi saat init (sebelum komunikasi), '''mengganti transport tidak menolong'''. | ||
'''Yang TIDAK menyelesaikan''' (sudah dicoba): <code>--mca btl self,tcp</code> dan <code>--mca btl_vader_single_copy_mechanism none</code> | '''Yang TIDAK menyelesaikan''' (sudah dicoba): <code>--mca btl self,tcp</code> dan <code>--mca btl_vader_single_copy_mechanism none</code> ; keduanya tentang ''transport'', padahal masalahnya di ''binding''. | ||
=== Solusi === | === Solusi === | ||
| Line 238: | Line 236: | ||
Ini inti persoalannya. Demi libc++ (Masalah 2), program C++ menaruh <code>$PREFIX/lib</code> '''paling depan''' di <code>LD_LIBRARY_PATH</code>. Akibatnya <code>libOpenCL.so</code> yang termuat adalah '''loader ocl-icd''' (di <code>$PREFIX/lib</code>), bukan driver vendor. | Ini inti persoalannya. Demi libc++ (Masalah 2), program C++ menaruh <code>$PREFIX/lib</code> '''paling depan''' di <code>LD_LIBRARY_PATH</code>. Akibatnya <code>libOpenCL.so</code> yang termuat adalah '''loader ocl-icd''' (di <code>$PREFIX/lib</code>), bukan driver vendor. | ||
Masalahnya: driver Adreno <code>/vendor/lib64/libOpenCL.so</code> '''bukan driver ICD yang patuh''' | Masalahnya: driver Adreno <code>/vendor/lib64/libOpenCL.so</code> '''bukan driver ICD yang patuh'''; ia adalah implementasi OpenCL lengkap yang berdiri sendiri, tetapi '''tidak meng-export entry point ICD''' (<code>clIcdGetPlatformIDsKHR</code>) yang dipakai loader untuk meng-enumerasi platform. Maka: | ||
* Lewat '''loader''' (saat <code>$PREFIX/lib</code> di depan) → loader bisa memuat driver tapi '''tidak bisa enumerate''' → 0 platform. | * Lewat '''loader''' (saat <code>$PREFIX/lib</code> di depan) → loader bisa memuat driver tapi '''tidak bisa enumerate''' → 0 platform. | ||
| Line 299: | Line 297: | ||
Tiga prinsip kunci: | Tiga prinsip kunci: | ||
# '''Build pakai env bersih''' (<code>env -u LD_LIBRARY_PATH</code>), '''run pakai env vendor''' | # '''Build pakai env bersih''' (<code>env -u LD_LIBRARY_PATH</code>), '''run pakai env vendor'''; jangan dicampur, jangan di-global. | ||
# '''OpenCL''': muat driver vendor '''langsung''' (vendor-first), karena driver Adreno bukan ICD-compliant. | # '''OpenCL''': muat driver vendor '''langsung''' (vendor-first), karena driver Adreno bukan ICD-compliant. | ||
# '''C++ + vendor-first''': pakai <code>LD_PRELOAD</code> libc++ Termux supaya tidak bentrok namespace. | # '''C++ + vendor-first''': pakai <code>LD_PRELOAD</code> libc++ Termux supaya tidak bentrok namespace. | ||
| Line 305: | Line 303: | ||
== Catatan == | == Catatan == | ||
* '''"Max clock 1 MHz" dan "1 compute unit"''' yang dilaporkan device '''bukan error/bug kode''' | * '''"Max clock 1 MHz" dan "1 compute unit"''' yang dilaporkan device '''bukan error/bug kode'''; driver Adreno memang sering melaporkan <code>CL_DEVICE_MAX_CLOCK_FREQUENCY</code> dengan nilai placeholder, dan Adreno meng-expose 1 ''compute unit'' ke OpenCL (normal untuk arsitekturnya). Kernel tetap berjalan paralel di banyak ALU di dalamnya. | ||
* '''Paralelisme''': dengan hanya '''1 GPU''', menjalankan banyak rank MPI tidak mempercepat sisi GPU | * '''Paralelisme''': dengan hanya '''1 GPU''', menjalankan banyak rank MPI tidak mempercepat sisi GPU ; rangkaian kernel dari tiap rank di-''serialize'' oleh driver pada GPU yang sama. Sisi CPU (generate data, verifikasi, reduksi) tetap paralel. Paralelisme GPU nyata baru tercapai bila ada '''beberapa GPU''' (mis. cluster beberapa perangkat Android via MPI/TCP), satu rank per GPU. | ||
* <code>$PREFIX</code> Termux = <code>/data/data/com.termux/files/usr</code>. Variabel <code>$PREFIX</code> sudah otomatis ter-set di Termux. | * <code>$PREFIX</code> Termux = <code>/data/data/com.termux/files/usr</code>. Variabel <code>$PREFIX</code> sudah otomatis ter-set di Termux. | ||
== Lihat pula == | == Lihat pula == | ||
* [https://github.com/OCL-dev/ocl-icd ocl-icd] | * [https://github.com/OCL-dev/ocl-icd ocl-icd]; OpenCL ICD loader | ||
* [https://www.open-mpi.org/ Open MPI] | * [https://www.open-mpi.org/ Open MPI] | ||
* [https://github.com/KhronosGroup/OpenCL-CLHPP OpenCL-CLHPP] | * [https://github.com/KhronosGroup/OpenCL-CLHPP OpenCL-CLHPP]; C++ bindings | ||
* [https://registry.khronos.org/OpenCL/ Spesifikasi OpenCL (Khronos)] | * [https://registry.khronos.org/OpenCL/ Spesifikasi OpenCL (Khronos)] | ||
Latest revision as of 04:24, 15 June 2026
Dokumentasi proses menjalankan OpenCL + MPI secara bersamaan di Termux pada perangkat Android yang sudah di-root, lengkap dengan semua error yang ditemui, penyebabnya, dan cara memperbaikinya. Hasil akhir: sebuah program C++ yang membagi vektor lewat MPI ke beberapa proses, lalu tiap proses menghitung bagiannya di GPU Adreno lewat OpenCL.
Lingkungan
| Komponen | Keterangan |
|---|---|
| Perangkat | Redmi Note 12 4G (rooted) |
| SoC | Qualcomm Snapdragon 685 |
| GPU | Adreno 610 (OpenCL 2.0 device, driver melaporkan OpenCL 3.0) |
| Userland | Termux |
| ICD loader | ocl-icd ("OCL Icd free software")
|
| Driver OpenCL | /vendor/lib64/libOpenCL.so (milik vendor/Qualcomm)
|
| MPI | OpenMPI (paket openmpi Termux)
|
$PREFIX |
/data/data/com.termux/files/usr
|
Paket yang dibutuhkan:
pkg install clang make cmake openmpi opencl-headers ocl-icd clinfo
Ringkasan masalah
| # | Gejala (error) | Penyebab singkat | Fix singkat |
|---|---|---|---|
| 1 | clinfo: Number of platforms = 0 |
Loader ocl-icd tidak menemukan driver vendor | Daftarkan ICD / muat driver vendor langsung |
| 2 | clang: cannot locate symbol _ZNSt6__ndk1... |
LD_LIBRARY_PATH global menarik libc++ Android |
Jangan set LD_LIBRARY_PATH global; pisah env build vs run
|
| 3 | use of undeclared identifier 'cl' |
Header C++ <CL/opencl.hpp> tidak ada; <CL/cl.h> tidak punya namespace cl:: |
Pakai C API dari C++, atau pasang opencl-clhpp
|
| 4 | mpirun ... signal 31 (Bad system call) |
seccomp Android memblokir syscall binding hwloc saat MPI_Init |
--mca hwloc_base_binding_policy none
|
| 5 | Program C++: No OpenCL platform |
Driver Adreno bukan ICD-compliant → loader gagal enumerate | Muat driver vendor langsung (vendor-first) + LD_PRELOAD libc++ Termux
|
Masalah 1: clinfo melaporkan 0 platform
Gejala
Number of platforms 0
ICD loader Name OpenCL ICD Loader
ICD loader Vendor OCL Icd free software
Loader-nya kebaca, tapi tidak ada platform OpenCL sama sekali.
Penyebab
Loader ocl-icd terpasang, tetapi tidak ada driver vendor yang terdaftar. Loader mencari berkas *.icd di $PREFIX/etc/OpenCL/vendors/; kalau kosong, hasilnya 0 platform.
Catatan penting: driver Adreno /vendor/lib64/libOpenCL.so ternyata bukan driver ICD yang patuh (tidak meng-export clIcdGetPlatformIDsKHR). Jadi mendaftarkannya ke loader saja tidak selalu cukup; lihat Masalah 5 untuk gambaran lengkapnya. Cara paling andal adalah memuat driver vendor langsung.
Solusi
1. Cari lokasi driver:
ls -l /vendor/lib64/libOpenCL.so /system/vendor/lib64/libOpenCL.so 2>/dev/null
find /vendor /system -iname 'libOpenCL*.so' 2>/dev/null
2. (Opsional, untuk loader) daftarkan ICD:
mkdir -p $PREFIX/etc/OpenCL/vendors
echo /vendor/lib64/libOpenCL.so > $PREFIX/etc/OpenCL/vendors/adreno.icd
3. Saat menjalankan, arahkan loader ke library vendor:
export LD_LIBRARY_PATH=/vendor/lib64:/system/vendor/lib64:/system/lib64
clinfo
Dengan LD_LIBRARY_PATH vendor-first, libOpenCL.so yang dimuat adalah library vendor (driver Adreno) langsung, dan clinfo akan melihat platform "QUALCOMM Snapdragon" / "Adreno (TM) 610".
PERINGATAN: meng-export LD_LIBRARY_PATH secara global (mis. di ~/.bashrc) akan menimbulkan Masalah 2. Set hanya saat dibutuhkan.
Masalah 2: clang rusak (cannot locate symbol __ndk1)
Gejala
Setelah meng-export LD_LIBRARY_PATH untuk OpenCL, clang/clang++ berhenti bekerja:
CANNOT LINK EXECUTABLE "clang": cannot locate symbol
"_ZNSt6__ndk122__libcpp_verbose_abortEPKcz" referenced by ...
Simbol itu kalau di-demangle: std::__ndk1::__libcpp_verbose_abort(char const*, ...).
Penyebab
LD_LIBRARY_PATH=/vendor/lib64:/system/lib64 yang di-set global membuat Termux memuat libc++ milik Android dari /system/lib64 alih-alih libc++ milik Termux. Keduanya memakai inline namespace yang berbeda:
- libc++ Termux →
std::__ndk1 - libc++ Android →
std::__1
clang Termux dikompilasi terhadap __ndk1, sehingga ketika libc++ Android (__1) yang termuat, simbol __ndk1 hilang dan clang gagal jalan.
Solusi
Konfirmasi dulu:
unset LD_LIBRARY_PATH
clang --version # kalau jalan lagi, terbukti LD_LIBRARY_PATH penyebabnya
Prinsipnya: pisahkan environment untuk COMPILE dan RUN.
- Saat compile/cmake/make →
LD_LIBRARY_PATHharus kosong (biar libc++ Termux yang dipakai). Caranya pakaienv -u:
env -u LD_LIBRARY_PATH clang -lOpenCL main.c -o app
env -u LD_LIBRARY_PATH cmake --build build
- Saat run → baru set
LD_LIBRARY_PATHke library vendor, sebagai prefix satu perintah agar otomatis hilang setelahnya:
LD_LIBRARY_PATH=/vendor/lib64:/system/vendor/lib64:/system/lib64 ./app
Jangan menaruh export LD_LIBRARY_PATH=... di ~/.bashrc. Untuk compile, driver vendor tidak dibutuhkan; -lOpenCL hanya butuh loader ocl-icd di $PREFIX/lib; library vendor hanya perlu saat runtime.
Masalah 3: header C++ OpenCL tidak ada (use of undeclared identifier 'cl')
Gejala
Saat memakai OpenCL C++ bindings, <CL/opencl.hpp> tidak ditemukan. Lalu setelah diganti ke <CL/cl.h>, muncul:
error: use of undeclared identifier 'cl'
static cl::Device pick_gpu(...) { ... }
^
error: missing 'template' keyword prior to dependent template name 'getInfo'
Penyebab
Dua hal berbeda:
<CL/cl.h>adalah header C; isinya fungsiclGetPlatformIDs,clCreateContext, dst. Header ini tidak punya namespacecl::sama sekali. Maka semuacl::Platform,cl::Device, dsb. menjadi "undeclared".- Class
cl::*hanya ada di<CL/opencl.hpp>(OpenCL C++ bindings), yang merupakan header terpisah (paketopencl-clhpp) dan bukan bagian dariopencl-headers. Header ini sering belum terpasang di Termux.
Solusi
Dua pilihan:
A. Pakai OpenCL C API dari C++ (paling andal; hanya butuh <CL/cl.h> yang sudah ada). Tetap C++ (pakai std::vector, std::string, iostream), tapi panggil fungsi C:
#define CL_TARGET_OPENCL_VERSION 300
#include <CL/cl.h>
// cl_context ctx = clCreateContext(...); dst.
B. Sediakan header C++ bindings kalau memang ingin gaya cl:::
pkg install opencl-clhpp # kalau tersedia di repo
# atau ambil manual (header tunggal, hanya butuh cl.h):
mkdir -p CL
curl -L -o CL/opencl.hpp \
https://github.com/KhronosGroup/OpenCL-CLHPP/raw/main/include/CL/opencl.hpp
lalu tambahkan target_include_directories(... PRIVATE ${CMAKE_SOURCE_DIR}) di CMake.
Masalah 4: mpirun signal 31 (Bad system call / SIGSYS)
Gejala
mpirun: Forwarding signal 31 to job
mpirun noticed that process rank 3 with PID 0 on node localhost
exited on signal 31 (Bad system call).
Tidak ada output program sama sekali sebelum crash (mati di dalam MPI_Init).
Penyebab
Signal 31 = SIGSYS = "Bad system call". Kernel Android memasang filter seccomp yang memblokir syscall tertentu; saat proses memanggil syscall yang diblokir, proses langsung dibunuh dengan sinyal 31.
Pemicunya: OpenMPI memakai hwloc untuk mengikat (binding) proses ke core CPU saat MPI_Init, dan binding itu memanggil syscall yang diblokir seccomp Android. Karena ini terjadi saat init (sebelum komunikasi), mengganti transport tidak menolong.
Yang TIDAK menyelesaikan (sudah dicoba): --mca btl self,tcp dan --mca btl_vader_single_copy_mechanism none ; keduanya tentang transport, padahal masalahnya di binding.
Solusi
Matikan binding hwloc:
mpirun -np 4 --oversubscribe \
--mca hwloc_base_binding_policy none \
--mca btl tcp,self \
./app
--mca hwloc_base_binding_policy none→ kunci-nya; matikan binding yang memicu SIGSYS.--mca btl tcp,self→ komunikasi lewat TCP loopback (untuk demo ini datanya kecil, jadi tidak masalah).--oversubscribe→ izinkan proses lebih banyak daripada slot terdeteksi.
Verifikasi cepat dengan program "hello world" MPI minimal sebelum menggabungkan dengan OpenCL.
Masalah 5: "No OpenCL platform" saat program C++ dijalankan
Gejala
MPI sudah jalan (banner tampil, 4 rank start), tapi tiap rank gagal di OpenCL:
[rank 0] No OpenCL platform
[rank 1] No OpenCL platform
...
Anehnya:
clinfopolos (env shell vendor-first) → menemukan Adreno.clinfodengan$PREFIX/libdi depan → 0 platform.
Penyebab
Ini inti persoalannya. Demi libc++ (Masalah 2), program C++ menaruh $PREFIX/lib paling depan di LD_LIBRARY_PATH. Akibatnya libOpenCL.so yang termuat adalah loader ocl-icd (di $PREFIX/lib), bukan driver vendor.
Masalahnya: driver Adreno /vendor/lib64/libOpenCL.so bukan driver ICD yang patuh; ia adalah implementasi OpenCL lengkap yang berdiri sendiri, tetapi tidak meng-export entry point ICD (clIcdGetPlatformIDsKHR) yang dipakai loader untuk meng-enumerasi platform. Maka:
- Lewat loader (saat
$PREFIX/libdi depan) → loader bisa memuat driver tapi tidak bisa enumerate → 0 platform. - Dimuat langsung (saat
/vendor/lib64di depan) → berhasil, karena fungsiclGetPlatformIDsdipanggil langsung ke driver vendor.
Jadi driver model ini harus dimuat langsung, bukan lewat loader. Tetapi itu berbenturan dengan kebutuhan libc++ Termux yang menuntut $PREFIX/lib di depan.
Solusi
Muat driver vendor langsung (vendor-first) dan paksa libc++ Termux lewat LD_PRELOAD:
LD_LIBRARY_PATH=/vendor/lib64:/system/vendor/lib64:/system/lib64:$PREFIX/lib \
LD_PRELOAD=$PREFIX/lib/libc++_shared.so \
mpirun --oversubscribe --mca hwloc_base_binding_policy none --mca btl tcp,self \
-np 4 ./app
Cara kerjanya:
/vendor/lib64di depan →libOpenCL.somenyangkut ke driver Adreno langsung → platform ketemu.$PREFIX/libdi paling belakang → cadangan untuk library Termux lain (mis.libmpi.so), yang juga ditemukan lewat RUNPATH binary.LD_PRELOAD=$PREFIX/lib/libc++_shared.so→ memaksa libc++ Termux (__ndk1) dimuat lebih dulu, sehingga simbol C++ program ter-resolve dengan benar (mencegah crash__ndk1).
Catatan: cara ini bekerja selama driver vendor memakai libc++.so (platform, soname berbeda) dan/atau tidak meng-link libc++_shared.so secara dinamis. Untuk mengecek dependensi driver:
readelf -d /vendor/lib64/libOpenCL.so | grep NEEDED
Jika di sana muncul libc++_shared.so (akan bentrok dengan preload), alternatifnya adalah static-link libc++ ke binary (tambah -static-libstdc++ di kompilasi) sehingga binary tidak butuh libc++ shared sama sekali, lalu LD_PRELOAD bisa dilepas.
Konfigurasi runtime final
Ringkasan resep yang terbukti bekerja end-to-end:
Build (libc++ Termux, LD_LIBRARY_PATH dibuang):
env -u LD_LIBRARY_PATH cmake -S . -B build -DCMAKE_BUILD_TYPE=Release
env -u LD_LIBRARY_PATH cmake --build build -j
Cek GPU (driver vendor langsung):
LD_LIBRARY_PATH=/vendor/lib64:/system/vendor/lib64:/system/lib64:$PREFIX/lib \
clinfo | head -n 25
Run (driver vendor langsung + libc++ Termux + binding hwloc dimatikan):
LD_LIBRARY_PATH=/vendor/lib64:/system/vendor/lib64:/system/lib64:$PREFIX/lib \
LD_PRELOAD=$PREFIX/lib/libc++_shared.so \
TMPDIR=$PREFIX/tmp \
mpirun --oversubscribe --mca hwloc_base_binding_policy none --mca btl tcp,self \
-np 4 ./build/app <arg...>
Tiga prinsip kunci:
- Build pakai env bersih (
env -u LD_LIBRARY_PATH), run pakai env vendor; jangan dicampur, jangan di-global. - OpenCL: muat driver vendor langsung (vendor-first), karena driver Adreno bukan ICD-compliant.
- C++ + vendor-first: pakai
LD_PRELOADlibc++ Termux supaya tidak bentrok namespace.
Catatan
- "Max clock 1 MHz" dan "1 compute unit" yang dilaporkan device bukan error/bug kode; driver Adreno memang sering melaporkan
CL_DEVICE_MAX_CLOCK_FREQUENCYdengan nilai placeholder, dan Adreno meng-expose 1 compute unit ke OpenCL (normal untuk arsitekturnya). Kernel tetap berjalan paralel di banyak ALU di dalamnya. - Paralelisme: dengan hanya 1 GPU, menjalankan banyak rank MPI tidak mempercepat sisi GPU ; rangkaian kernel dari tiap rank di-serialize oleh driver pada GPU yang sama. Sisi CPU (generate data, verifikasi, reduksi) tetap paralel. Paralelisme GPU nyata baru tercapai bila ada beberapa GPU (mis. cluster beberapa perangkat Android via MPI/TCP), satu rank per GPU.
$PREFIXTermux =/data/data/com.termux/files/usr. Variabel$PREFIXsudah otomatis ter-set di Termux.
Lihat pula
- ocl-icd; OpenCL ICD loader
- Open MPI
- OpenCL-CLHPP; C++ bindings
- Spesifikasi OpenCL (Khronos)