KomputeKerangka Kerja Hitung GPU Tujuan Umum untuk Kartu Grafis Vendor Silang (AMD, Qualcomm, Nvidia & Friends) |
Bergabunglah dengan Panggilan Perselisihan & Komunitas? Dokumentasi Posting Blog ⌨ Contoh?
Di bawah ini Anda dapat menemukan contoh multiplikasi GPU menggunakan antarmuka Kompute C ++ dan Python.
Anda dapat bergabung dengan perselisihan untuk pertanyaan / diskusi, membuka masalah GitHub, atau membaca dokumentasinya.
Antarmuka C ++ menyediakan akses tingkat rendah ke komponen asli Kompute, memungkinkan untuk optimasi canggih serta perpanjangan komponen.
void kompute ( const std::string& shader) {
// 1. Create Kompute Manager with default settings (device 0, first queue and no extensions)
kp::Manager mgr;
// 2. Create and initialise Kompute Tensors through manager
// Default tensor constructor simplifies creation of float values
auto tensorInA = mgr. tensor ({ 2 ., 2 ., 2 . });
auto tensorInB = mgr. tensor ({ 1 ., 2 ., 3 . });
// Explicit type constructor supports uint32, int32, double, float and bool
auto tensorOutA = mgr. tensorT < uint32_t >({ 0 , 0 , 0 });
auto tensorOutB = mgr. tensorT < uint32_t >({ 0 , 0 , 0 });
std::vector<std::shared_ptr<kp::Memory>> params = {tensorInA, tensorInB, tensorOutA, tensorOutB};
// 3. Create algorithm based on shader (supports buffers & push/spec constants)
kp::Workgroup workgroup ({ 3 , 1 , 1 });
std::vector< float > specConsts ({ 2 });
std::vector< float > pushConstsA ({ 2.0 });
std::vector< float > pushConstsB ({ 3.0 });
auto algorithm = mgr. algorithm (params,
// See documentation shader section for compileSource
compileSource (shader),
workgroup,
specConsts,
pushConstsA);
// 4. Run operation synchronously using sequence
mgr. sequence ()
-> record <kp::OpSyncDevice>(params)
-> record <kp::OpAlgoDispatch>(algorithm) // Binds default push consts
-> eval () // Evaluates the two recorded operations
-> record <kp::OpAlgoDispatch>(algorithm, pushConstsB) // Overrides push consts
-> eval (); // Evaluates only last recorded operation
// 5. Sync results from the GPU asynchronously
auto sq = mgr. sequence ();
sq-> evalAsync <kp::OpSyncLocal>(params);
// ... Do other work asynchronously whilst GPU finishes
sq-> evalAwait ();
// Prints the first output which is: { 4, 8, 12 }
for ( const float & elem : tensorOutA-> vector ()) std::cout << elem << " " ;
// Prints the second output which is: { 10, 10, 10 }
for ( const float & elem : tensorOutB-> vector ()) std::cout << elem << " " ;
} // Manages / releases all CPU and GPU memory resources
int main () {
// Define a raw string shader (or use the Kompute tools to compile to SPIRV / C++ header
// files). This shader shows some of the main components including constants, buffers, etc
std::string shader = ( R"(
#version 450
layout (local_size_x = 1) in;
// The input tensors bind index is relative to index in parameter passed
layout(set = 0, binding = 0) buffer buf_in_a { float in_a[]; };
layout(set = 0, binding = 1) buffer buf_in_b { float in_b[]; };
layout(set = 0, binding = 2) buffer buf_out_a { uint out_a[]; };
layout(set = 0, binding = 3) buffer buf_out_b { uint out_b[]; };
// Kompute supports push constants updated on dispatch
layout(push_constant) uniform PushConstants {
float val;
} push_const;
// Kompute also supports spec constants on initalization
layout(constant_id = 0) const float const_one = 0;
void main() {
uint index = gl_GlobalInvocationID.x;
out_a[index] += uint( in_a[index] * in_b[index] );
out_b[index] += uint( const_one * push_const.val );
}
)" );
// Run the function declared above with our raw string shader
kompute (shader);
}
Paket Python menyediakan antarmuka interaktif tingkat tinggi yang memungkinkan untuk eksperimen sambil memastikan alur kerja pengembangan kinerja tinggi dan cepat.
from . utils import compile_source # using util function from python/test/utils
def kompute ( shader ):
# 1. Create Kompute Manager with default settings (device 0, first queue and no extensions)
mgr = kp . Manager ()
# 2. Create and initialise Kompute Tensors through manager
# Default tensor constructor simplifies creation of float values
tensor_in_a = mgr . tensor ([ 2 , 2 , 2 ])
tensor_in_b = mgr . tensor ([ 1 , 2 , 3 ])
# Explicit type constructor supports uint32, int32, double, float and bool
tensor_out_a = mgr . tensor_t ( np . array ([ 0 , 0 , 0 ], dtype = np . uint32 ))
tensor_out_b = mgr . tensor_t ( np . array ([ 0 , 0 , 0 ], dtype = np . uint32 ))
assert ( t_data . data_type () == kp . DataTypes . uint )
params = [ tensor_in_a , tensor_in_b , tensor_out_a , tensor_out_b ]
# 3. Create algorithm based on shader (supports buffers & push/spec constants)
workgroup = ( 3 , 1 , 1 )
spec_consts = [ 2 ]
push_consts_a = [ 2 ]
push_consts_b = [ 3 ]
# See documentation shader section for compile_source
spirv = compile_source ( shader )
algo = mgr . algorithm ( params , spirv , workgroup , spec_consts , push_consts_a )
# 4. Run operation synchronously using sequence
( mgr . sequence ()
. record ( kp . OpTensorSyncDevice ( params ))
. record ( kp . OpAlgoDispatch ( algo )) # Binds default push consts provided
. eval () # evaluates the two recorded ops
. record ( kp . OpAlgoDispatch ( algo , push_consts_b )) # Overrides push consts
. eval ()) # evaluates only the last recorded op
# 5. Sync results from the GPU asynchronously
sq = mgr . sequence ()
sq . eval_async ( kp . OpTensorSyncLocal ( params ))
# ... Do other work asynchronously whilst GPU finishes
sq . eval_await ()
# Prints the first output which is: { 4, 8, 12 }
print ( tensor_out_a )
# Prints the first output which is: { 10, 10, 10 }
print ( tensor_out_b )
if __name__ == "__main__" :
# Define a raw string shader (or use the Kompute tools to compile to SPIRV / C++ header
# files). This shader shows some of the main components including constants, buffers, etc
shader = """
#version 450
layout (local_size_x = 1) in;
// The input tensors bind index is relative to index in parameter passed
layout(set = 0, binding = 0) buffer buf_in_a { float in_a[]; };
layout(set = 0, binding = 1) buffer buf_in_b { float in_b[]; };
layout(set = 0, binding = 2) buffer buf_out_a { uint out_a[]; };
layout(set = 0, binding = 3) buffer buf_out_b { uint out_b[]; };
// Kompute supports push constants updated on dispatch
layout(push_constant) uniform PushConstants {
float val;
} push_const;
// Kompute also supports spec constants on initalization
layout(constant_id = 0) const float const_one = 0;
void main() {
uint index = gl_GlobalInvocationID.x;
out_a[index] += uint( in_a[index] * in_b[index] );
out_b[index] += uint( const_one * push_const.val );
}
"""
kompute ( shader )Anda dapat mencoba notebook Colab interaktif yang memungkinkan Anda menggunakan GPU gratis. Contoh yang tersedia adalah contoh Python dan C ++ di bawah ini:
Coba C ++ Colab interaktif dari posting blog | Coba Python Colab interaktif dari posting blog |
Anda juga dapat memeriksa dua pembicaraan berikut yang disajikan pada konferensi FOSDEM 2021.
Kedua video memiliki cap waktu yang akan memungkinkan Anda untuk melompat ke bagian yang paling relevan untuk Anda - intro & motivasi untuk keduanya hampir sama sehingga Anda dapat melompat ke konten yang lebih spesifik.
Tonton video untuk penggemar C ++ | Tonton Video untuk Python & Machine Learning Enthasasts |
Arsitektur inti Kompute mencakup yang berikut:
Untuk melihat rincian penuh, Anda dapat membaca lebih lanjut dalam referensi kelas C ++.
| Arsitektur penuh | Komponen kompute yang disederhanakan |
|---|---|
(Sangat kecil, periksa diagram referensi lengkap di dokumen untuk detailnya) |
Kompute memberikan fleksibilitas untuk menjalankan operasi dengan cara asynrchonous melalui VK :: pagar. Selain itu, Kompute memungkinkan alokasi antrian eksplisit, yang memungkinkan pelaksanaan operasi paralel di seluruh keluarga antrian.
Gambar di bawah ini memberikan intuisi tentang bagaimana sekuens kompute dapat dialokasikan untuk antrian yang berbeda untuk memungkinkan eksekusi paralel berdasarkan perangkat keras. Anda dapat melihat contoh tangan pada contoh, serta halaman dokumentasi terperinci yang menjelaskan cara kerjanya menggunakan NVIDIA 1650 sebagai contoh.
Kompute telah dioptimalkan untuk bekerja di lingkungan seluler. Sistem Build memungkinkan pemuatan dinamis dari perpustakaan bersama Vulkan untuk lingkungan Android, bersama dengan pembungkus NDK Android yang berfungsi untuk header CPP.
Untuk menyelam dalam, Anda dapat membaca posting blog "supercharging aplikasi seluler Anda dengan pembelajaran mesin yang dipercepat GPU di perangkat". Anda juga dapat mengakses kode contoh ujung ke ujung dalam repositori, yang dapat dijalankan menggunakan Android Studio. |
Selain C ++ Core SDK, Anda juga dapat menggunakan paket Python Kompute, yang memaparkan fungsionalitas inti yang sama, dan mendukung interoperabilitas dengan objek Python seperti daftar, array numpy, dll.
Satu -satunya dependensi adalah Python 3.5+ dan CMake 3.4.1+. Anda dapat menginstal kompute dari paket Python PYPI menggunakan perintah berikut.
pip install kp
Anda juga dapat menginstal dari Master Branch menggunakan:
pip install git+git://github.com/KomputeProject/kompute.git@master
Untuk perincian lebih lanjut, Anda dapat membaca dokumentasi paket Python atau dokumentasi referensi kelas Python.
Sistem build yang disediakan menggunakan cmake , yang memungkinkan untuk pembuatan lintas platform.
Makefile tingkat atas menyediakan serangkaian konfigurasi yang dioptimalkan untuk pengembangan serta pembuatan gambar Docker, tetapi Anda dapat memulai build dengan perintah berikut:
cmake -Bbuild
Anda juga dapat menambahkan kompute dalam repo Anda dengan add_subdirectory - file Android CMAKELIST.TXT menunjukkan bagaimana ini akan dilakukan.
Untuk ikhtisar yang lebih canggih dari konfigurasi build, periksa dokumentasi penyelaman sistem build.
Kami menghargai PR dan masalah. Jika Anda ingin berkontribusi, cobalah memeriksa tag "edisi pertama yang baik", tetapi bahkan menggunakan masalah kompute dan pelaporan adalah kontribusi besar!
Jika Anda ingin menjalankan dengan lapisan debug, Anda dapat menambahkannya dengan parameter KOMPUTE_ENV_DEBUG_LAYERS sebagai:
export KOMPUTE_ENV_DEBUG_LAYERS="VK_LAYER_LUNARG_api_dump"
Untuk memperbarui dokumentasi yang Anda perlukan:
make push_docs_to_ghpages Menjalankan tes unit telah disederhanakan secara signifikan untuk kontributor.
Tes dijalankan pada CPU, dan dapat dipicu menggunakan antarmuka baris perintah ACT (https://github.com/nektos/act) - Setelah Anda menginstal baris perintah (dan mulai daemon Docker) Anda hanya perlu mengetik:
$ act
[Python Tests/python-tests] Start image=axsauze/kompute-builder:0.2
[C++ Tests/cpp-tests ] Start image=axsauze/kompute-builder:0.2
[C++ Tests/cpp-tests ] ? docker run image=axsauze/kompute-builder:0.2 entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
[Python Tests/python-tests] ? docker run image=axsauze/kompute-builder:0.2 entrypoint=["/usr/bin/tail" "-f" "/dev/null"] cmd=[]
...
Repositori berisi tes unit untuk kode C ++ dan Python, dan dapat ditemukan di bawah folder test/ dan python/test .
Tes saat ini dijalankan melalui CI menggunakan tindakan GitHub. Menggunakan gambar yang ditemukan di docker-builders/ .
Untuk meminimalkan persyaratan perangkat keras, tes dapat berjalan tanpa GPU, langsung di CPU menggunakan Swiftshader.
Untuk informasi lebih lanjut tentang bagaimana CI dan tes diatur, Anda dapat pergi ke bagian CI, Docker dan Tes dalam dokumentasi.
Proyek ini dimulai setelah melihat bahwa banyak proyek ML & DL baru dan terkenal seperti Pytorch, TensorFlow, Alibaba DNN, Tencent NCNN - antara lain - telah mengintegrasikan atau mencari untuk mengintegrasikan SDK Vulkan untuk menambahkan dukungan GPU seluler (dan lintas -vendor).
Vulkan SDK menawarkan antarmuka tingkat rendah yang besar yang memungkinkan untuk optimasi yang sangat khusus - namun ia datang dengan biaya kode yang sangat bertele -tele yang membutuhkan 500-2000 baris kode untuk bahkan mulai menulis kode aplikasi. Ini telah menghasilkan masing-masing proyek ini harus mengimplementasikan garis dasar yang sama untuk mengabstraksikan fitur terkait non-komputasi dari SDK Vulkan. Sejumlah besar pelat boiler non-standar ini dapat menghasilkan transfer pengetahuan yang terbatas, kemungkinan lebih tinggi dari bug implementasi kerangka kerja unik yang diperkenalkan, dll.
Kami saat ini sedang mengembangkan Kompute untuk tidak menyembunyikan antarmuka Vulkan SDK (seperti yang dirancang dengan sangat baik) tetapi untuk menambahnya dengan fokus langsung pada kemampuan komputasi GPU Vulkan SDK. Artikel ini memberikan tinjauan tingkat tinggi tentang motivasi Kompute, bersama dengan serangkaian contoh langsung yang memperkenalkan komputasi GPU serta arsitektur inti kompute.