Pada artikel ini, saya akan mengulas salah satu fase dari pemrograman komputasi pararel menggunakan CUDA API, yaitu Inisialisasi Divais CUDA. Fase ini umumnya dijalankan aplikasi di awal – awal sebelum aplikasi mengeksekusi kernel – kernel CUDA ( Misal di baris – baris awal implementasi method main ). Tujuannya adalah untuk mendeteksi ada/tidaknya divais yang mendukung CUDA ( VGA/GPU Nvidia GeForce 8xxx keatas ) serta memilih divais CUDA yang akan digunakan oleh API CUDA. CUDA API memiliki 2 cita rasa , yaitu Driver API & CUDA C. Mengingat kompleksnya ( low level )Driver API & motivasi saya yang ingin memberdaya gunakan pengetahuan bahasa C saya, maka di tutorial ini ( & yang akan datang ), saya memilih menggunakan CUDA C sebagai API di kode tutorial ini.
Prasyarat
- Pengetahuan pemrograman C dasar ( forward declaration, method, pointer, passing method parameter by reference, header & source file, #include directive, dsb )
- Visual Studio 2008 SP1 ( atau/dan Visual Studio 2010) dengan Visual C++ terinstall di dalamnya.
- CUDA Toolkit versi 3.2 atau lebih tinggi. Untuk tutorial instalasi nya dapat di simak di artikel ini.
Mari kita mulai
- Method InitializeCudaDevice
Kita akan mendefinisikan kode ini sebagai method C global, dengan nama InitializeCudaDevice. Berikut adalah deklarasi method ini:
// Forward declarations bool InitializeCudaDevice( int* numberDevices );
Tulis kode di atas pada file header baru (.h), beri nama sembarang ( misal: CudaUtility.h ). Method ini mengembalikan nilai boolean true bila inisialisasi divais CUDA berhasil lalu memilih divais pertama sebagai divais yang akan di gunakan CUDA API. Parameter pass-by-reference ( pointer integer ) numberDevices akan di isi jumlah divais CUDA yang terdeteksi bila inisialisasi berhasil ( misal : *numberDevices = 2 bila terdeteksi 2 GPU GeForce terinstal ).
Berikut adalah pseudocode dari implementasi method ini:
1. Dapatkan jumlah CUDA devices, bila tidak ada CUDA Devices yang terpasang/gagal maka kembalikan nilai false.
2. Set device CUDA pertama untuk di gunakan kernel CUDA, bila gagal kembalikan nilai false.
3. Kembalikan nilai true, sampai disini dapat di nyatakan bahwa inisialisasi divais CUDA telah berhasil.
Pertama kali, tambahkan file source code C++ baru (.cpp ), beri nama sembarang ( misal: CudaUtility.cpp ). Tulis kode deklarasi penggunaan file header kita di atas dan CUDA runtime API (<cuda_runtime_api.h>). Tulis juga kerangka implementasi method InitializeCudaDevice ini.
#include <cuda_runtime_api.h>
#include "CudaUtility.h";
///
/// Initialize CUDA
/// Returns TRUE if initialization is success, otherwise FALSE.
///
bool InitializeCudaDevice( int* numberDevices ){
// Get number of CUDA Supported device
// Set device 0 to be used as current GPU's execution
// Initialization is success.
return true;
};
Di dalam method ini, tulis kode untuk mendapatkan jumlah divais CUDA yg terpasang dengan memanggil method CUDA API cudaError_t cudaGetDeviceCount(int* numberDevices). Method ini akan mengembalikan nilai enumerasi cudaSuccess bila berhasil dan parameter pass-by-reference numberDevices akan terisi jumlah divais CUDA yang dapat dikenali. Pada baris ini, kita akan check apakah pemanggilan method cudaGetDeviceCount berhasil/tidak dan apakah jumlah divais CUDA yg dapat dikenali lebih dari 0 / sebaliknya. Bila 2 kondisi ini tidak terpenuhi, maka dapat kita nyatakan inisialisasi gagal.
// Get number of CUDA Supported device
if ( ( cudaGetDeviceCount(numberDevices) != cudaSuccess ) || ( *numberDevices < 1) ){
// If there is no CUDA Supported device presents, return FALSE from here.
return false;
}
Langkah selanjutnya adalah memanggil CUDA API (cudaError_t cudaSetDevice( int deviceId )) untuk memilih divais CUDA pertama ( divais 0 ) sebagai divais yang akan di gunakan oleh CUDA API dan kernel – kernel CUDA di dalam aplikasi kita nantinya. Bila pemanggilan method ini mengembalikan nilai yang selain cudaSuccess, dapat kita nyatakan inisialisasi gagal.
// Set device 0 to be used as current GPU's execution
if ( cudaSetDevice(0) != cudaSuccess ){
// Unable to use 1st CUDA Device
return false;
}
Berikut implementasi lengkap method inisialisasi divais CUDA ini
#include <cuda_runtime_api.h>
#include "CudaUtility.h";
///
/// Initialize CUDA
/// Returns TRUE if initialization is success, otherwise FALSE.
///
bool InitializeCudaDevice( int* numberDevices ){
// Get number of CUDA Supported device
if ( ( cudaGetDeviceCount(numberDevices) != cudaSuccess ) || ( *numberDevices < 1) ){
// If there is no CUDA Supported device presents, return FALSE from here.
return false;
}
// Set device 0 to be used as current GPU's execution
if ( cudaSetDevice(0) != cudaSuccess ){
// Unable to use 1st CUDA Device
return false;
}
// Initialization is success.
return true;
};
- Contoh penggunaan – Aplikasi .NET Command Line
Buatlah sebuah project baru di dalam visual studio .NET, pilih : Visual C++ -> CLR -> Console Application di dalam dialog new project. Set CUDA’s Customization Build, runtime library dan setting lainnya pada project ini ( di ulas di artikel ini). Buat file .h & .cpp baru dan tulis implementasi kode di atas ke dalam project ini. Berikut adalah kode contoh penggunaannya di dalam file main.cpp :
#include "stdafx.h"
#include "CudaUtility.h"
using namespace System;
using namespace System::Text;
int main(array ^args)
{
// Initialize Cuda
int numberOfDevices = 0;
StringBuilder^ stringBuilder = gcnew StringBuilder();
if ( InitializeCudaDevice(&numberOfDevices) ){
// If success , display the number of initialized devices to screen and success message
stringBuilder->Append( L"CUDA Devices initialization is SUCCESS\n" );
stringBuilder->Append( String::Format( L"Number of detected devices : {0}", numberOfDevices ) );
}
else{
// otherwise display failed initialization's message
stringBuilder->Append( L"Initialization is FAILED" );
}
stringBuilder->Append( L"\n\nPress enter to exit..." );
Console::Write( stringBuilder-&gt;ToString() );
Console::ReadLine();
return 0;
}
Kode keseluruhan yg di ulas dalam artikel ini dapat di ambil dari url Subversion berikut ini : http://saint.xtremecodes.asia:8080/svn/tutorial_cuda/Initialization. Selamat mencoba 🙂









