Anda di halaman 1dari 290

Judul

Link: http://bit.ly/2R4ktSO

PEMROGRAMAN GPU
(Teori & Aplikasi)
“ CUDA/PyCUDA/OpenCL Nvidia/Intel/AMD/Intel Mac/etc”
Versi 1.01

Oleh:
Imam Cholissodin
Tusty Nadia Maghfira

PENGANTAR
Buku ini memberikan penjabaran dari konsep dasar sampai
tingkat lanjut, mulai dari bagaimana menggunakan teknik parallel ber-
basis GPU, lalu mengimplementasikan terkait beberapa kebutuhan
teknologi terkini, yang meliputi deep learning, self-driving cars, virtual
reality, game development, accelerated computing, design & visualiza-
tion, automous machines dan lainnya, dengan melakukan komputasi
secara cepat dan handal, serta membuat pengembang mampu
mengintegrasikan teknik parallel dengan teknologi saat ini maupun
untuk masa depan dengan mengambil potensi cara kerja proses
paralel GPU yang sangat cepat dalam pengolahan data untuk mem-
bantu meningkatkan hasil yang lebih akurat.

Imam Cholissodin
Dosen Pengampu MK Pemrograman GPU FILKOM UB

2017-2019
Kata Pengantar

Alhamdulillahhi robbil alamin, puji syukur kehadirat Allah SWT


atas segala rahmat dan karunia-Nya dengan terselesaikannya penu-
lisan buku ini dengan judul “Pemrograman GPU”. Buku ini memberikan
penjabaran dari konsep dasar sampai tingkat lanjut, mulai dari
bagaimana menggunakan teknik parallel berbasis GPU, lalu
mengimplementasikan terkait beberapa kebutuhan teknologi terkini,
yang meliputi deep learning, self-driving cars, virtual reality, game de-
velopment, accelerated computing, design & visualization, automous
machines dan lainnya, dengan melakukan komputasi secara cepat dan
handal, serta membuat pengembang mampu mengintegrasikan teknik
parallel dengan teknologi saat ini maupun untuk masa depan dengan
mengambil potensi cara kerja proses paralel GPU yang sangat cepat
dalam pengolahan data untuk membantu meningkatkan hasil yang
lebih akurat.
Penulis mengucapkan terimakasih yang sebesar-besarnya
kepada beberapa pihak terkait yang telah membantu baik secara
langsung maupun tidak langsung dalam menyediakan dan melengkapi
materi untuk penyelesaian buku ini:
1. Para penulis artikel tentang Pemrograman GPU di forum, web, blog
dan buku yang menjadi referensi buku ini untuk memberikan ma-
sukan yang sangat berharga sekali untuk perbaikan dan
penyelesaian buku ini.
2. Mbak Tusty Nadia Maghfira, yang telah banyak membantu penu-
lisan buku ini. Semoga kontribusinya menjadi ilmu yang barokah
dan bermanfaat. Aamiin. :)
3. Mahasiswa terbaik saya pada semester Genap 2016/2017 MK
Pemrograman GPU, yaitu Hilmi Ilyas Rizaldi, Firadi Surya
Pramana, Bariq Najmi R., Aditya Yudha A.N., Fathony Teguh
Irawan, M. Rizal Ma’rufi, Jeriko Hosea Julanto, M Hafidz Rahman,
Ardhan Maulana Z, Arvin Adam Dakhota, Faritz Nugroho,
Fathurrahman Annafabi, Reza Saputra, Wisnu Surya W., Herma-
wan Wijaya, Kevin Dwiki Saputra, Yoshua Aditya Kurnia.
Semoga kontribusi kalian menjadi ilmu yang barokah dan ber-
manfaat. Aamiin. :). Tidak ada gading yang tak retak, begitulah ungka-
pan yang tepat terkait dengan buku ini. Maka penulis memohon kritik
dan saran untuk perbaikan dan penyempurnaan buku ini.

ii
In Syaa Allah pada edisi berikutnya, kami akan memberikan
contoh implementasi maupun penerapan yang lebih banyak
menggunakan CUDA, jCUDA, pyCUDA, OpenCL, pyOpenCL,
OpenMP, OpenACC, Tensorflow, etc pada berbagai bidang dan multi-
disiplin keilmuan. Selamat membaca buku ini dan semoga bermanfaat.

Malang, 19 Juli 2017 – 22 Januari 2019

Penulis

iii
Daftar Isi

Judul ..................................................................................................... i
Kata Pengantar ................................................................................... ii
Daftar Isi ............................................................................................. iv
Daftar Gambar ................................................................................... viii
BAB 1 Konsep Pemrograman GPU ........................................... 1
1.1 Apa itu CPU vs GPU ....................................................... 1
1.2 Apa itu Pemrograman GPU............................................. 3
1.3 Macam-Macam CPU & GPU ........................................... 5
1.4 General Purpose Parallel Computing .............................. 6
1.5 Beberapa Teknik dari Tools Implementasi Paralel .......... 8
1.6 Tugas Kelompok ............................................................. 8
BAB 2 Introduction CUDA dan OpenCL .................................... 9
2.1 Instalasi CUDA ................................................................ 9
2.1.1 Install CUDA Toolkit 8.0 & Other ....................... 10
2.1.2 Compile dari command prompt (CMD) .............. 12
2.1.3 CUDA + VS 2017 .............................................. 19
2.1.4 CUDA + Python (PyCuda) ................................. 43
2.2 Instalasi OpenCL........................................................... 51
2.2.1 Apa itu OpenCL ................................................. 51
2.2.2 Install OpenCL NVidia ....................................... 51
2.2.3 Install OpenCL Intel ........................................... 63
2.2.4 Install OpenCL AMD.......................................... 81
2.3 Study Kasus Sederhana: CUDA dan OpenCL .............. 88
2.3.1 Hello World :D ................................................... 88
2.3.2 Single Instruction, Single Data (SISD)............... 90
2.3.3 Single Instruction, Multiple Data (SIMD) ............ 90
2.4 Tugas Kelompok ........................................................... 92
BAB 3 Cara Kerja Kernel Pada GPU....................................... 94
3.1 CUDA Grid Vs OpenCL NDRange ................................ 95

iv
3.2 Cara Kerja Kernel Pada CUDA ..................................... 98
3.3 Cara Kerja Kernel Pada OpenCL .................................. 99
3.4 Create Main Project (Compile dari Visual Studio) ....... 104
3.5 Study Kasus Dev.: CUDA............................................ 112
3.5.1 Operasi Paralel pada Vector ........................... 112
3.5.2 Operasi Paralel pada Matriks .......................... 118
3.6 Study Kasus Dev.: OpenCL ........................................ 121
3.6.1 Operasi Paralel pada Vector ........................... 121
3.6.2 Operasi Paralel pada Matriks .......................... 125
3.7 Tugas Kelompok ......................................................... 127
BAB 4 Race Conditions dan Atomic Function ........................ 135
4.1 Race Conditions .......................................................... 135
4.2 Atomic Function .......................................................... 137
4.3 Locks dan Mutex ......................................................... 139
4.4 Warps, Warps dan Locks ............................................ 141
4.5 Tugas Kelompok ......................................................... 143
BAB 5 Artificial Intelligence dengan GPU ............................... 145
5.1 Artificial Intelligence (AI) .............................................. 145
5.2 Machine Learning dan Teknik Optimasi ...................... 146
5.2.1 Clustering: K-Means ........................................ 147
5.2.2 Teknik Optimasi: Particle Swarm Optimization
(PSO) 149
5.3 Tugas Kelompok ......................................................... 158
BAB 6 OpenGL dengan GPU ................................................. 160
6.1 CUDA dan OpenGL .................................................... 160
6.1.1 Primitive Object (ex.: Segitiga) ........................ 161
6.1.2 Visualisasi Sine Wave ..................................... 162
6.1.3 Ray Tracing ..................................................... 176
6.1.4 Game Asteroid 2D ........................................... 177
6.1.5 Solusi Error CUDA + OpenGL ......................... 181
6.2 OpenCL dan OpenGL ................................................. 183
6.2.1 Visualisasi Sine Wave ..................................... 183

v
6.2.2 Marching Cubes OpenCL ................................ 185
6.3 Tugas Kelompok ......................................................... 186
BAB 7 Parallel Processing Pada Citra & Video ...................... 191
7.1 Tentang OpenCV, Citra dan Video.............................. 191
7.2 Install dan Konfigurasi OpenCV .................................. 194
7.3 Study Kasus: CUDA dan OpenCL............................... 196
7.3.1 Parallel Processing Pada Citra ........................ 196
7.3.2 Parallel Processing Pada Video ...................... 202
7.4 Tugas Kelompok ......................................................... 205
BAB 8 Create *.dll, *.lib pada GPU ......................................... 209
8.1 Apa itu *.dll, *.lib? ........................................................ 209
8.2 Create & Load *.dll, *.lib CUDA di Visual Studio ......... 210
8.2.1 Create *.dll ...................................................... 210
8.2.2 Load *.dll ......................................................... 215
8.2.3 Create *.lib ...................................................... 218
8.2.4 Load *.lib ......................................................... 223
8.3 Create Installer CUDA Project ..................................... 228
8.4 Tugas Kelompok ......................................................... 230
BAB 9 Pemrograman GPU Tingkat Lanjut ............................ 231
9.1 CUDA/OpenCL & Library, etc...................................... 231
9.2 Konfigurasi VS (CUDA dan Algoritma Yolo) ................ 232
9.3 Compile dan Run ........................................................ 238
9.4 Solusi Error saat Compile dan Run ............................. 243
9.5 Tugas Kelompok ......................................................... 246
BAB 10 Project Pilihan Pemrograman GPU ............................. 247
10.1 CUDA Pada Game 3D SandboxCraft ...................... 247
10.1.1 Dasar Teori ................................................... 248
10.1.2 Implementasi ................................................. 250
10.2 CUDA Pada Game 2D Asteroids ............................. 253
10.2.1 Dasar Teori ................................................... 254
10.2.2 Implementasi ................................................. 256

vi
10.3 CUDA Pada Game 2D Salmon Vs Turtles ............... 258
10.3.1 Dasar Teori ................................................... 259
10.3.2 Implementasi ................................................. 261
10.4 CUDA Pada Game Breakout ................................... 264
10.4.1 Dasar Teori ................................................... 265
10.4.2 Implementasi ................................................. 267
10.5 CUDA Pada Game 2D Pong .................................... 270
10.5.1 Dasar Teori ................................................... 270
10.5.2 Implementasi ................................................. 271
Daftar Pustaka................................................................................. 274
Biografi Penulis ............................................................................... 280

vii
Daftar Gambar

Gambar 1.1 Ilustrasi CPU vs GPU ...................................................... 1


Gambar 1.2 Spek Super Komputer vs Server ..................................... 2
Gambar 1.3 Contoh CPU, GPU, dan Core pada CPU vs GPU ........... 2
Gambar 1.4 Pemrograman GPU ......................................................... 3
Gambar 1.5 Serial Computing ............................................................. 4
Gambar 1.6 Parallel Computing .......................................................... 4
Gambar 1.7 Contoh GPU pada PC/Notebook dan mobile .................. 5
Gambar 1.8 Operasi Floating-Point per Detik pada CPU dan GPU .... 6
Gambar 1.9 Memory Bandwidth for the CPU dan GPU ...................... 6
Gambar 1.10 Contoh pada Machine Learning, etc .............................. 7
Gambar 1.11 Contoh pada Simulasi Fisika ......................................... 7
Gambar 2.1 Launch Visual Studio Installer ....................................... 10
Gambar 2.2 Launch Nvidia Display Driver Installer ........................... 10
Gambar 2.3 Pengecekan Compatibility Nvidia Display Driver ........... 11
Gambar 2.4 Launch CUDA Installer .................................................. 11
Gambar 2.5 Daftar Konten CUDA Samples ...................................... 12
Gambar 2.6 Cek di cmd dengan Windows+R ................................... 12
Gambar 2.7 pilih Path, klik Edit ......................................................... 13
Gambar 2.8 Set Folder bin dari VC ................................................... 13
Gambar 2.9 Cek kembali di cmd dengan Windows+R ...................... 14
Gambar 2.10 Download query.cu ...................................................... 14
Gambar 2.11 Ketikkan nvcc query.cu -o query.................................. 14
Gambar 2.12 Hasil nvcc query.cu -o query ....................................... 15
Gambar 2.13 Kernel execution timeout: Yes ..................................... 15
Gambar 2.14 Klik kanan pada Nsight ................................................ 15
Gambar 2.15 muncul “Modify Setting Error”, maka exit Nsight.......... 16
Gambar 2.16 Klik kanan pada Nsight, lalu klik Run as administrator 17
Gambar 2.17 now ready for CUDA .................................................... 17
Gambar 2.18 Buka Nsight, klik Allow access ................................... 18

viii
Gambar 2.19 Pilih CUDA Samples Sesuai Versi Visual Studio ......... 18
Gambar 2.20 Klik “Start Visual Studio” .............................................. 19
Gambar 2.21 GeForce Experience .................................................... 19
Gambar 2.22 Ekstrak, lalu install ....................................................... 20
Gambar 2.23 Nvidia Installer failed ................................................... 20
Gambar 2.24 Sukses install NVIDIA Display driver ........................... 20
Gambar 2.25 Klik Run anyway .......................................................... 21
Gambar 2.26 Klik OK......................................................................... 21
Gambar 2.27 Tunggu beberapa waktu .............................................. 21
Gambar 2.28 klik Next ....................................................................... 22
Gambar 2.29 Ketik “cl”....................................................................... 22
Gambar 2.30 Set bin folder VS .......................................................... 23
Gambar 2.31 Cek kembali di cmd dengan Windows+R .................... 23
Gambar 2.32 Download query.cu ...................................................... 24
Gambar 2.33 Ketikkan nvcc query.cu -o query.................................. 24
Gambar 2.34 Hasil nvcc query.cu -o query ....................................... 25
Gambar 2.35 Kernel execution timeout: Yes ..................................... 25
Gambar 2.36 Klik kanan pada Nsight ................................................ 25
Gambar 2.37 muncul “Modify Setting Error”, maka exit Nsight.......... 26
Gambar 2.38 Klik kanan pada Nsight, lalu klik Run as administrator 27
Gambar 2.39 now ready for CUDA .................................................... 27
Gambar 2.40 Install Nsight, klik Next ................................................ 28
Gambar 2.41 Enable syntax highlighting file CUDA *.cu ................... 28
Gambar 2.42 NumPy + Mamba = Numba ......................................... 43
Gambar 2.43 OpenCL dan Lainnya ................................................... 51
Gambar 3.1 Map CUDA dan OpenCL ............................................... 94
Gambar 3.2 Membuat Project NVIDIA CUDA ................................. 104
Gambar 3.3 Buat Solution Folder Baru Pada Solution VSCuda ...... 105
Gambar 3.4 Tampilan Project Aktif Pada Visual Studio .................. 110
Gambar 5.1 Ilustrasi Map AI dan ML, serta Transfer AI .................. 145
Gambar 5.2 Map cakupan dari Machine Learning ........................... 146

ix
Gambar 5.3 Map pengembangan produk App ................................ 146
Gambar 5.4 Konsep Non-Hierarchical Clustering ............................ 147
Gambar 5.5 Ilustrasi Pergerakan Partikel PSO ............................... 149
Gambar 5.6 Pseudocode Struktur Umum Algoritma PSO ............... 149
Gambar 5.7 Plotting 2D Contoh Fungsi ........................................... 150
Gambar 6.1 Ilustrasi Ray Tracing .................................................... 176
Gambar 6.2 Tampilan Game Asteroid 2D ....................................... 180
Gambar 6.3 Tampilan Sine Wave OpenCL ..................................... 184
Gambar 6.4 Cara Kerja Marching Cubes ........................................ 185
Gambar 8.1 File *.dll vs *.lib ............................................................ 209
Gambar 9.1 CUDA/OpenCL Library dan Lainnya ............................ 231
Gambar 9.2 CUDA + Yolo ............................................................... 232
Gambar 10.1 Nvidia CUDA ............................................................. 249
Gambar 10.2 Tampilan Game Craft ................................................ 250
Gambar 10.3 Hasil Running Game Asteroid 2D .............................. 256
Gambar 10.4 Hasil running Game 2D Salmon Vs Turtles ............... 263
Gambar 10.5 Main Screen Pada Game Breakout ........................... 269
Gambar 10.6 Setelah Dimodifikasi Game Pong .............................. 272

x
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 1 Konsep
Pemrograman GPU

1.1 Apa itu CPU vs GPU


Sebagai gambaran perbandingan antara CPU versus GPU,
adalah seperti ketika anda akan membajak sawah, manakah yang anda
pilih, menggunakan 2 lembu atau 1024 ayam atau dengan 10100
semut, atau misal saat anda bersepeda, manakah yang pilih bersepeda
sendirian atau bersama dengan sahabat atau keluarga.

Gambar 1.1 Ilustrasi CPU vs GPU


Atau sebagai ilustrasi lainnya, misalkan kita lebih memilih sewa
server dengan spek super komputer dan remote dari device atau
laptop yang biasa, atau beli laptop dengan spek tinggi dan tanpa harus
sewa server dengan spek mendekati super komputer.

1
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Gambar 1.2 Spek Super Komputer vs Server


Central Processing Unit (CPU) bisa disebut juga sebagai otak dari
komputer, atau disebut juga dengan prosessor. Tugas utama CPU yaitu
untuk mengolah data berdasarkan perintah dari keseluruhan software
pada komputer. Secara fisik, ditandai dengan adanya heatsink
(pendingin) dan kipas. Dan biasanya terpasang secara on-board, atau
terintegrasi dengan motherboard. Graphics Processing Unit (GPU)
adalah prossesor yang bertugas secara khusus mengolah tampilan
grafik. GPU saat ini semakin tinggi speknya, sehingga mendukung un-
tuk menampilkan grafik terbaik pada game-game 3D saat ini.

Gambar 1.3 Contoh CPU, GPU, dan Core pada CPU vs GPU

Pada Gambar 1.3 diatas dapat dilihat perbedaan CPU dan GPU
berdasarkan jumlah core yang ada di dalamnya.

2
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1.2 Apa itu Pemrograman GPU


Pemrograman GPU memiliki tujuan tidak hanya untuk mengolah
grafis melainkan juga dapat untuk tujuan umum, misal komputasi
ilmiah menggunakan machine learning dan rekayasa lainnya pada
game development, etc. dengan framework tertentu, misal CUDA
(Compute Unified Device Architecture). CUDA merupakan suatu frame-
work dari bahasa pemrograman C yang mampu berkomunikasi lang-
sung dengan GPU untuk multithreading parallel execution. OpenCL
(Open Computing Language) adalah mekanisme eksekusi program
pada Prosesor multi core dimana corenya memiliki platform berbeda
(heterogen) baik core pada CPU maupun GPU, dan GPU biasanya se-
bagai akselerator. OpenCL membagi beban kerja CPU dan GPU, se-
hingga Resource CPU lebih ringan. PhysX adalah Simulasi sesuai hukum
fisika Newton yang mana perhitunganya mampu menghasilkan efek
partikel cair, kain robek, dinamika tubuh, dll. PhysX biasanya ada pada
kartu grafis Nvidia. CUDA (Compute Unified Device Arcitecture) adalah
mekanisme komputasi paralel sekaligus API (Aplication Programing In-
terface) atau platform antarmuka pemrograman aplikasi dari NVidia.
CUDA hampir mirip dengan OpenCL untuk komputasi cepat, bedanya
CUDA dari vendor NVidia sedangkan OpenCL dipakai banyak Vendor.
Nvidia mengklaim bahwa CUDA lebih cepat dari OpenCL. Direct Com-
pute adalah API yang mendukung komputasi GPU pada Microsoft Win-
dows yang awalnya untuk pengolahan grafis menggunakan DirectX
10/11. Direct Compute sebagai pesaing, OpenCL dari Khronos Grup,
Shader untuk perhitungan dalam OpenGL, dan CUDA dari NVIDIA.

Gambar 1.4 Pemrograman GPU

3
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Konsep parallel computing adalah bentuk dari komputasi yang


dapat melakukan tugas secara paralel, yaitu secara banyak, serentak
dalam waktu yang bersamaan. Ilustrasi serial vs parallel computing
dapat dilihat pada Gambar 1.4 dan Gambar 1.5.
Multithreading adalah sekumpulan hyperthreading pada be-
berapa core. Hyperthreading yaitu sebuah teknologi yang membuat
satu processor dikenali sebagai dua processor secara virtual, yang bisa
menyalurkan dua aliran data (thread) sekaligus dalam satu waktu,
yang mana thread adalah sekumpulan instruksi (proses) yang
dieksekusi secara independen.

Gambar 1.5 Serial Computing

Gambar 1.6 Parallel Computing

4
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1.3 Macam-Macam CPU & GPU


Terdapat beberapa macam CPU dan GPU, di mana masing-mas-
ing CPU dan GPU dibedakan berdasarkan perangkat yang
menggunakannya yaitu PC/Notebook/etc dan mobile. Berikut ini ada-
lah macam-macam dari CPU:
 CPU pada PC/Notebook/etc:
- Intel Processor
- Advanced Micro Devices (AMD)
 CPU pada mobile:
- Qualcomm Snapdragon
- Mediatek
- Exynos (Samsung)
- Intel
Selain CPU, berikut ini merupakan macam-macam GPU yang ada
pada PC/Notebook dan mobile:
 GPU pada PC/Notebook/etc:
- NVIDIA
- AMD
- Intel
 GPU pada mobile
- ADRENO
- MALI
- PowerVR
- NVIDIA Tegra

Gambar 1.7 Contoh GPU pada PC/Notebook dan mobile

5
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1.4 General Purpose Parallel Computing


Berdasarkan permintaan pasar untuk pemrosesan realtime yang
lebih optimal (From Graphics Processing to General Purpose Parallel
Computing), kartu grafis pada GPU akhirnya berkembang menjadi san-
gat mendukung komputasi paralel, multithreaded, manycore prosesor
dengan kecepatan komputasi yang luar biasa dan bandwidth memori
yang sangat tinggi, seperti yang ditunjukkan pada Gambar di bawah
ini.

Gambar 1.8 Operasi Floating-Point per Detik pada CPU dan GPU

Gambar 1.9 Memory Bandwidth for the CPU dan GPU

6
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Single Precision (32 bit), Double Precision (64 bit), dan Clock
speed adalah ukuran dari seberapa besar kecepatan komputer
menyelesaikan perhitungan dasar dan operasi. 1 megahertz artinya
satu-juta siklus per detik, sementara gigahertz adalah satu-milyar
siklus per detik. Konsep Floating Point (bilangan titik mengambang),
adalah sebuah format bilangan yang dapat digunakan untuk merep-
resentasikan sebuah nilai yang sangat besar atau sangat kecil.
Bilangan ini direpresentasikan menjadi dua bagian, yakni bagian man-
tisa dan bagian eksponen (E). Contoh, bilangan 314600000 dan
0.0000451 dapat direpresentasikan dalam bentuk bilangan floating
point: 3146E5 dan 451E-7 (masing-masing artinya 3146 * 10 pangkat
5, dan 451 * 10 pangkat -7).
Berdasarkan hal tersebut, Parallel Computing saat ini banyak
digunakan pada berbagai operasi dalam PC dan mobile karena ke-
cepatan komputasi dan bandwidth memorinya yang tinggi. Berikut ini
beberapa contoh penggunaan Parallel Computing secara umum
beserta perusahaan yang menggunakannya:
 Machine Learning, Graphics & Game Dev.

Gambar 1.10 Contoh pada Machine Learning, etc

 Simulasi Fisika, etc

Gambar 1.11 Contoh pada Simulasi Fisika

7
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1.5 Beberapa Teknik dari Tools


Implementasi Paralel
Beberapa teknik dari tools untuk mengimplementasikan konsep
paralel dapat disesuaikan dengan ketersediaan hardware dan
kebutuhan. Berikut adalah pilihannya.
 CUDA (Compute Unified Device Architecture), hanya
support dengan GPU dari Nvidia.
 OpenCL (Open Computing Language), biasanya digunakan
untuk semua jenis GPU dari berbagai vendor.
 OpenACC (Open Accelerate), biasaya digunakan pada
multi-GPU.
 OpenMP (Open Multi Processing), biasanya juga digunakan
pada multi-GPU, sebagai alternatif untuk OpenACC.
 Dan lainnya

1.6 Tugas Kelompok


1. Jelaskan perbedaan peran CPU dan GPU!
2. Sebutkan macam-macam GPU pada PC/Notebook dan pada Mo-
bile, beserta karakteristiknya?
3. Download Visual Studio terbaru jika menggunakan OS Windows,
dan download Eclipse jika menggunakan Linux/Mac (Capture
bahwa VS sudah terdownload/terinstall, minimal di PC salah satu
anggota kelompok)
4. Lakukan register ke Nvidia, lalu download (Capture register atau
login di NVIDIA (minimal dari CUDA dan Nsight), minimal dari PC
salah satu anggota kelompok):
- CUDA untuk Windows/Linux/Mac
- Nsight untuk Windows, Linux/Mac
- DIGITS
5. Jelaskan perbedaan konsep GPU Programming untuk machine
learning, versus graphics & game!

8
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 2 Introduction CUDA


dan OpenCL

2.1 Instalasi CUDA


Compute Unified Device Architecture (CUDA) adalah sebuah
teknologi yang dikembangkan NVIDIA untuk mempermudah
penggunaan GPU untuk keperluan umum (non-grafis). Arsitektur
terpadu CUDA ini memudahkan pengembang perangkat lunak untuk
membuat aplikasi yang berjalan pada GPU buatan NVIDIA dengan syn-
tax yang mirip dengan syntax bahasa C yang sudah banyak dikenal. Se-
hingga, saat ini banyak developer dapat memanfaatkan kemampuan
prosesing GPU untuk mengakselerasi komputasi program mereka
dengan jauh lebih mudah. Lalu kenapa harus bersusah-susah
menggunakan GPU untuk menjalankan program? Berbeda dengan
CPU yang didesain lebih umum yang harus siap untuk menjalankan
berbagai instruksi program, GPU didesain khusus untuk menghitung
dan menyajikan pixel-pixel gambar yang akan ditampilkan. Karena satu
pixel tidak berhubungan dengan pixel yang lain, GPU dirancang untuk
melakukan banyak operasi secara paralel. Kemampuan eksekusi par-
alel secara masif inilah yang kemudian dapat dimanfaatkan dengan
CUDA.
Saat ini mulai banyak software yang mendukung akselerasi
dengan CUDA. Misal MATLAB dan beberapa plugin Adobe Photoshop.
Bila perangkat lunak ini mendeteksi ada hardware yang kompatibel
CUDA, maka proses komputasinya akan dilakukan dengan GPU. Se-
hingga, program dapat dieksekusi dengan lebih cepat. Program yang
akan diakselerasi adalah program yang dapat dipecah menjadi banyak
eksekusi paralel. Kenyataannya, banyak komputasi yang masuk pada
kategori tersebut. Misal Image dan Video Processing. Sehingga dapat
dikatakan bahwa teknologi CUDA telah merevolusi dunia High Perfor-
mance Computing.

9
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.1.1 Install CUDA Toolkit 8.0 & Other


Terdapat beberapa tahapan dalam proses instalasi yaitu:
a. Install Visual Studio
- Siapkan installer, ekstrak file “VS2013/2015/2017/.. *.iso”

Gambar 2.1 Launch Visual Studio Installer


- Cek “I agree..”, Klik Next, deselect all, klik INSTALL
- Tunggu beberapa waktu, klik “Restart Now”
- Jalankan “visual studio 2013”, klik “Not now, ..”, lalu Klik “Start
Visual Studio”
b. Install NVIDIA Display Driver
- Siapkan file “378.66-notebook-win10-64bit-international-
whql.exe”, lalu double klik, klik “Run anyway”, klik OK

Gambar 2.2 Launch Nvidia Display Driver Installer

10
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Setelah itu tunggu beberapa waktu untuk pengecekan system


compatibility seperti pada Gambar 2.3.

Gambar 2.3 Pengecekan Compatibility Nvidia Display Driver

- Klik “AGREE AND CONTINUE”, klik Next


- Klik CLOSE
- Klik GET Started

c. Install CUDA 8/9/..


- Siapkan file “cuda_8.0.61_win10.exe”, lalu double klik, lalu
klik Run anyway

Gambar 2.4 Launch CUDA Installer


- Klik OK
Setelah itu tunggu beberapa waktu untuk pengecekan apakah
komponen sistem telah siap untuk penginstalan CUDA seperti di-
tunjukkan pada Gambar 2.5.

11
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik “AGREE AND CONTINUE”, klik Next


- Klik Install, tunggu beberapa waktu, klik Next
- Klik CLOSE
- Lihat CUDA Samples

Gambar 2.5 Daftar Konten CUDA Samples

2.1.2 Compile dari command prompt (CMD)


- Cek di cmd dengan Windows+R, ketik “cl”

Gambar 2.6 Cek di cmd dengan Windows+R


- Jika muncul “cl” is not recognized ...., maka solusinya: masuk ke
Control Panel\System and Security\System

12
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik “Environment Variables..”, pilih Path, klik Edit

Gambar 2.7 pilih Path, klik Edit


- Klik New, copy paste “C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\bin”

Gambar 2.8 Set Folder bin dari VC

13
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik OK, OK, OK


- Cek kembali di cmd dengan Windows+R, ketik “cl”. Selesai.

Gambar 2.9 Cek kembali di cmd dengan Windows+R


- Download file cuda “query.cu” dari link (https://goo.gl/JCTKY8)
atau dengan ketikan:
bitsadmin /transfer myDownloadJob /download /priority nor-
mal https://raw.githubusercontent.com/sunbonilla/CUDA-
GPU-Device-Query/master/query.cu %cd%\query.cu

Gambar 2.10 Download query.cu


- Masuk ke directory yang berisi file cuda “query.cu”:
Ketikan: nvcc query.cu -o query

Gambar 2.11 Ketikkan nvcc query.cu -o query

14
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Gambar 2.12 Hasil nvcc query.cu -o query


- Cek Kernel execution timeout: Yes, ketikkan “query”

Gambar 2.13 Kernel execution timeout: Yes


- Ubah Kernel execution timeout: Yes menjadi No:

Klik kanan pada Nsight, lalu klik Options

Gambar 2.14 Klik kanan pada Nsight

15
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ubah Kernel execution timeout: Yes menjadi No:


Klik kanan pada Nsight, lalu klik Options,
Ubah WDDM TDR enabled True menjadi False

Ubah
Menjadi
False

- Ubah Kernel execution timeout: Yes menjadi No:


Klik kanan pada Nsight, lalu klik Options,
Ubah WDDM TDR enabled True menjadi False, Lalu Klik OK
Jika muncul “Modify Setting Error”, maka exit Nsight

Gambar 2.15 muncul “Modify Setting Error”, maka exit Nsight


- Ubah Kernel execution timeout: Yes menjadi No:
Coba Klik kanan pada Nsight, lalu klik Run as administrator,
Ubah WDDM TDR enabled True menjadi False, Lalu Klik OK
Sampai muncul “NVIDIA Nsight Monitor..”. Lalu Restart Komputer

16
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Gambar 2.16 Klik kanan pada Nsight, lalu klik Run as administrator
- Ubah Kernel execution timeout: No, ketikkan “query”

Your computer is now ready for CUDA


development.

Gambar 2.17 now ready for CUDA

17
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Install Nsight “NVIDIA_Nsight_Visual_Studio_Edition_Win64_5.2.0.16321.msi”

Gambar 2.18 Buka Nsight, klik Allow access

Setelah selesai menginstal tools yang dibutuhkan, kita dapat


mencoba untuk demo program dengan tahapan seperti berikut ini:
- C:\ProgramData\NVIDIA Corporation\CUDA Samples\v8.0:

Gambar 2.19 Pilih CUDA Samples Sesuai Versi Visual Studio

18
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.1.3 CUDA + VS 2017


Untuk memudahkan dalam membuat koding CUDA, maka kita
perlu sebuah IDE yang mampu bekerja dengan CUDA, salah satunya
adalah Visual Studio 2017. Sebagai contoh, ketika kita mendapati
terjadi error, maka IDE tersebut akan membantu kita dalam tracker
tempat error tersebut pada baris yang spesifik. Hal ini akan
memudahkan kita dalam mempercepat penyelesaian koding.
2.1.3.1 Install Visual Studio 2017
- Siapkan installer, ekstrak file “VS2017.zip (-+ 22GB)”, lalu double
file *.exe

Gambar 2.20 Klik “Start Visual Studio”


- Install terlebih dahulu “GeForce_Experience_v3.13.1.30.exe” dan
lakukan register, lalu Login.

Gambar 2.21 GeForce Experience

19
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Install Nvidia display driver, siapkan file “397.31-notebook-win10-


64bit-international-whql.exe”.

Gambar 2.22 Ekstrak, lalu install


- Jika muncul error

Gambar 2.23 Nvidia Installer failed


- Solusi, Install versi yang lebih rendah dari “397.31”, misal install
“391.35-notebook-win10-64bit-international-whql.exe”

Gambar 2.24 Sukses install NVIDIA Display driver


- Klik Close

20
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.1.3.2 Install CUDA Toolkit 9.0


- Siapkan file “cuda_9.0.176_win10.exe”, lalu double klik

Gambar 2.25 Klik Run anyway

- Klik OK

Gambar 2.26 Klik OK


- Tunggu beberaa waktu, lalu Klik “AGREE AND CONTINUE”, klik Next
- Tunggu beberapa waktu

Gambar 2.27 Tunggu beberapa waktu

21
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik Install, tunggu beberapa waktu

Gambar 2.28 klik Next


- Klik Close
- Cek di cmd dengan Windows+R, ketik “cl”

Gambar 2.29 Ketik “cl”

22
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Jika muncul “cl” is not recognized ...., maka solusinya: masuk ke


Control Panel\System and Security\System
- Klik “Environment Variables..”, pilih Path, klik Edit
- Klik New, copy paste “C:\Program Files (x86)\Microsoft Visual
Studio 12.0\VC\bin” atau dengan folder “bin” dari visual studio
yang digunakan dan support.

Gambar 2.30 Set bin folder VS


- Klik OK, OK, OK
- Cek kembali di cmd dengan Windows+R, ketik “cl”. Selesai.

Gambar 2.31 Cek kembali di cmd dengan Windows+R

23
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Download file cuda “query.cu” dari link (https://goo.gl/JCTKY8)


atau dengan ketikan:
bitsadmin /transfer myDownloadJob /download /priority nor-
mal https://raw.githubusercontent.com/sunbonilla/CUDA-
GPU-Device-Query/master/query.cu %cd%\query.cu

Gambar 2.32 Download query.cu


- Masuk ke directory yang berisi file cuda “query.cu”:
Ketikan: nvcc query.cu -o query

Gambar 2.33 Ketikkan nvcc query.cu -o query

24
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Gambar 2.34 Hasil nvcc query.cu -o query


- Cek Kernel execution timeout: Yes, ketikkan “query”

Gambar 2.35 Kernel execution timeout: Yes


- Ubah Kernel execution timeout: Yes menjadi No:

Klik kanan pada Nsight, lalu klik Options

Gambar 2.36 Klik kanan pada Nsight

25
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ubah Kernel execution timeout: Yes menjadi No:


Klik kanan pada Nsight, lalu klik Options,
Ubah WDDM TDR enabled True menjadi False

Ubah
Menjadi
False

- Ubah Kernel execution timeout: Yes menjadi No:


Klik kanan pada Nsight, lalu klik Options,
Ubah WDDM TDR enabled True menjadi False, Lalu Klik OK
Jika muncul “Modify Setting Error”, maka exit Nsight

Gambar 2.37 muncul “Modify Setting Error”, maka exit Nsight


- Ubah Kernel execution timeout: Yes menjadi No:
Coba Klik kanan pada Nsight, lalu klik Run as administrator,
Ubah WDDM TDR enabled True menjadi False, Lalu Klik OK
Sampai muncul “NVIDIA Nsight Monitor..”. Lalu Restart Komputer

26
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Gambar 2.38 Klik kanan pada Nsight, lalu klik Run as administrator
- Ubah Kernel execution timeout: No, ketikkan “query”

Your computer is now ready for CUDA


development.

Gambar 2.39 now ready for CUDA

27
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Install Nsight “NVIDIA_Nsight_Visual_Studio_Edition_Win64_5.5.0.18014.msi ”

Gambar 2.40 Install Nsight, klik Next


Nsight untuk meng-enable syntax highlighting file CUDA *.cu
pada Visual Studio seperti pada Gambar berikut.

Gambar 2.41 Enable syntax highlighting file CUDA *.cu

28
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.1.3.3 CUDA 8.0 + VS 2017


Pada kondisi default, VS 2017 tidak lagi mendukung CUDA 8,
namun ada beberapa teknik yang dapat digunakan untuk setting VS
2017 sehingga dapat support dengan CUDA 8. Berikut tahapannya
(Cara 1 of 3).
- Buka Visual Studio 2017, Klik File>New>Project

- Terlihat hanya ada “CUDA 9.0”

Kita akan mencoba merubah dari project “CUDA 9.0” menjadi


“CUDA 8.0” atau lainnya

29
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pastikan “CUDA 8.0” sudah terinstall


- Pastikan “VC++ 2015.3 v140 toolset” pada vs 2017, sudah terinstall.
Bisa di cek pada klik Tool>Get Tools and Features..., klik tab “Indi-
vidual components”, pastikan “VC++ 2015.3 v140 toolset” sudah
tercentang, jika belum, centang lalu klik tombol “Modify” utk install.

- Pastikan “.NET Framework 3.5” sudah terinstall, bisa dicek pada


“Control Panel\Programs\Programs and Features”, klik pada “Turn
Windows features on or off”, pastikan sudah terblok dengan warna
hitam, jika belum install.

Cara Install, klik Tool>Get Tools and Features..., klik tab “Individual
components”, pastikan ““.NET Framework 3.5 ..” sudah tercentang,
jika belum, centang lalu klik tombol “Modify” utk install.

30
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Copykan semua file dari folder “C:\Program Files\NVIDIA GPU Com-


puting
Toolkit\CUDA\v8.0\extras\visual_studio_integration\MSBuildExte
nsions” ke folder “C:\Program Files (x86)\Microsoft Visual Stu-
dio\2017\Community\Com-
mon7\IDE\VC\VCTargets\BuildCustomizations”

- Klik kanan project “02MyFirstGPU_SIMD”, klik Properties

- Ubah “Platform Toolset” menjadi “Visual Studio 2015 (v140)”, klik


Apply, klik OK

31
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Misal pada project “02MyFirstGPU_SIMD” di visual studio 2017,


jika dijalankan langsung tanpa setting file “*.vcxproj”, hasilnya:

Seperti code kernelnya tidak bisa dicompile


- Klik kanan pada project “02MyFirstGPU_SIMD”, klik “Unload Pro-
ject”

- Klik kanan pada project “02MyFirstGPU_SIMD”, klik “Edit ...*. vcx-


proj”

32
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ubah pada file “*. vcxproj”, lalu simpan

<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
9.0.props" />
</ImportGroup>

<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
9.0.targets" />
</ImportGroup>

menjadi

<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
8.0.props" />
</ImportGroup>

<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
8.0.targets" />
</ImportGroup>

- Klik kanan pada project “02MyFirstGPU_SIMD”, klik “Reload Pro-


ject”

33
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Coba build dan compile project “02MyFirstGPU_SIMD”, jika muncul


error. Solusinya: close visual studio 2017, buka lagi

- Coba build dan compile project “02MyFirstGPU_SIMD”, jika muncul


error

Solusi 1;
Copikan folder “bin” dan isinya dari link “http://bit.ly/2JFp62w” ke
folder “C:\Program Files (x86)\Microsoft Visual
Studio\2017\Community\VC”, sehingga menjadi seperti berikut

Solusi 2:
Lakukan konfigurasi pada Properti Project, set folder bin yang
sudah ada.

34
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- ubah “Code Generation” menjadi “compute_20,sm_20”, klik Apply,


klik OK

- Hasil run kode .cu pada visual studio 2017 dengan CUDA 8.0 yang
telah dikonfigurasi sebelumnya. Berhasil :D

Setelah kita mencoba Cara 1, untuk alternatif yang lain, berikut


tahapannya (Cara 2 of 3).
- Buka Visual Studio 2017, Klik File>New>Project
- Terlihat hanya ada “CUDA 9.0”

35
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Kita akan mencoba merubah dari project “CUDA 9.0” menjadi


support “CUDA 8.0” atau lainnya

- Pastikan “CUDA 8.0” sudah terinstall


- Pastikan “VC++ 2015.3 v140 toolset” pada vs 2017, sudah terinstall.
Bisa di cek pada klik Tool>Get Tools and Features..., klik tab “Indi-
vidual components”, pastikan “VC++ 2015.3 v140 toolset” sudah
tercentang, jika belum, centang lalu klik tombol “Modify” utk install.

- Pastikan “.NET Framework 3.5” sudah terinstall, bisa dicek pada


“Control Panel\Programs\Programs and Features”, klik pada “Turn
Windows features on or off”, pastikan sudah terblok dengan warna
hitam, jika belum install.

36
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Cara Install, klik Tool>Get Tools and Features..., klik tab “Individual
components”, pastikan ““.NET Framework 3.5 ..” sudah tercentang,
jika belum, centang lalu klik tombol “Modify” utk install.

- Copykan semua file dari folder “C:\Program Files\NVIDIA GPU Com-


puting
Toolkit\CUDA\v8.0\extras\visual_studio_integration\MSBuildExte
nsions” ke folder “C:\Program Files (x86)\MSBuild\Mi-
crosoft.Cpp\v4.0\V140\BuildCustomizations” (jika anda sudah in-
stall vs 2015 sebelumnya)

- Klik kanan project “02MyFirstGPU_SIMD”, klik Properties

37
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ubah “Platform Toolset” menjadi “Visual Studio 2015 (v140)”, klik


Apply, klik OK

- Misal pada project “02MyFirstGPU_SIMD” di visual studio 2017,


jika dijalankan langsung tanpa setting file “*.vcxproj”, hasilnya:

Seperti code kernelnya tidak bisa dicompile


- Klik kanan pada project “02MyFirstGPU_SIMD”, klik “Unload Pro-
ject”

38
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan pada project “02MyFirstGPU_SIMD”, klik “Edit ...*. vcx-


proj”

- Ubah pada file “*. vcxproj”, lalu simpan

<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
9.0.props" />
</ImportGroup>

<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
9.0.targets" />
</ImportGroup>

menjadi

<ImportGroup Label="ExtensionSettings">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
8.0.props" />
</ImportGroup>

<ImportGroup Label="ExtensionTargets">
<Import Project="$(VCTargetsPath)\BuildCustomizations\CUDA
8.0.targets" />
</ImportGroup>

39
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan pada project “02MyFirstGPU_SIMD”, klik “Reload Pro-


ject”

- ubah “Code Generation” menjadi “compute_20,sm_20”, klik Apply,


klik OK
- Hasil run kode .cu pada visual studio 2017 dengan CUDA 8.0 yang
telah dikonfigurasi sebelumnya. Berhasil :D

40
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Setelah kita mencoba Cara 1 atau Cara 2, untuk alternatif yang


lain, berikut tahapannya (Cara 3 of 3).
- Rename Folder “C:\Program Files\NVIDIA GPU Computing
Toolkit\CUDA\v9.0” menjadi “C:\Program Files\NVIDIA GPU
Computing Toolkit\CUDA\Temp-v9.0”
- Rename Folder “C:\Program Files\NVIDIA GPU Computing
Toolkit\CUDA\v8.0” menjadi Folder “C:\Program Files\NVIDIA GPU
Computing Toolkit\CUDA\v9.0”

- Pada project, ubah “Platform Toolset” menjadi “Visual Studio 2015


(v140)”, klik Apply, klik OK

41
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- ubah “Code Generation” menjadi “compute_20,sm_20”, klik Apply,


klik OK

42
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.1.4 CUDA + Python (PyCuda)


Casting CUDA dengan Python. CUDA adalah versi
original dari Nvidia dengan menggunakan bahasa
pemrograman C. Namun beberapa pengembanga
menggunakan seperti CUDACasts, etc. Numba
adalah High-Performance Python dengan CUDA
Acceleration (PyCUDA), dengan menggunakan
bahasa pemrograman Pyhon. Beberapa kelebihan
Numba yaitu High Productivity for High-Performance Computing
untuk operasi aritmatika, GPU-Accelerated Libraries untuk Python
(cuBLAS (dense linear algebra), cuFFT (Fast Fourier Transform), dan
cuRAND (random number generation) ), serta Massive Parallelism.

2.1.4.1 Apa itu Numba


Numba menyediakan CudaCast untuk Python, sehingga Python
dapat melakukan akselerasi GPU menggunakan kode CUDA yang
semakin canggih dengan sintaks yang simple dan sangat minim
(PyCUDA).

Gambar 2.42 NumPy + Mamba = Numba


Misal dengan membuat fungsi sederhana maupun kompleks untuk
mengkompilasi fungsi tertentu secara otomatis, menggunakan Library
CUDA dengan pyculib. Jika kita telah paham konsep pemrograman
paralel dan butuh untuk mengontrol secara fleksibel pada parallel
threads, maka CUDA sangat cocok untuk digunakan.

43
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.1.4.2 Install Anaconda


- Download Anaconda
- Double klik file master Anaconda, klik Next

- Klik Install

44
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik Finish, Install selesai :D

- Cek apakah python sudah aktif atau belum di Win OS, buka cmd
ketikkan “python” dan “conda”

Solusi jika python belum aktif, setting pada “Control Panel\System


and Security\System”, klik “Evironment Variable”, Pilih PATH, lalu
isikan, misal “E:\InstalledC\Anaconda3\Scripts” dan “E:\In-
stalledC\Anaconda3”.

45
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Buka cmd baru, Ketikkan “C:\Users\Imacho>conda update conda”


Lalu ketik “y”

Tunggu beberapa waktu, sampai update conda selesai.

- Ketikkan “C:\Users\Imacho>conda install numba”, lalu ketik “y”

46
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Tunggu beberapa waktu, sampai install numba selesai.

- Ketikkan “C:\Users\Imacho>conda install cudatoolkit”, lalu


ketikkan “y”

Tunggu beberapa waktu, sampai Cudatoolkit selesai di install

47
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ketik “C:\Users\Imacho>conda install numba cudatoolkit pyculib”,


ketik “y” tekan enter

Tunggu beberapa waktu, sampai Install pyculib selesai

2.1.4.3 Run PyCUDA


 Pertama: Run kode Program “VectorAdd.py”
- Buka cmd baru, lalu Ketikkan, misal “cd C:\Users\Imacho>cd
E:\Data Kuliah\!Genap 2017-2018\1. Pemrograman GPU\PyCUDA”
- Lalu ketikkan “python VectorAdd.py”

48
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Program “VectorAdd.py”


import numpy as np
import time
from numba import vectorize, cuda

@vectorize(['float32(float32, float32)'], target='cuda')


def VectorAdd(a, b):
return a + b

def main():
N = 100000

A = np.ones(N, dtype=np.float32)
B = np.ones(N, dtype=np.float32)

start = time.time()

# Add arrays on GPU


C = VectorAdd(A, B)
vector_add_time = time.time() - start

print ("C[:5] = " + str(C[:5]))


print ("C[-5:] = " + str(C[-5:]))

print ("VectorAdd took for %s seconds" % vector_add_time)

if __name__=='__main__':
main()

 Kedua: Run kode Program “mendel.py”


- ketikkan “python mendel.py”

49
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Program “mendel.py”


import numpy as np
from pylab import imshow, show
from timeit import default_timer as timer
from numba import autojit
from numba import cuda
from numba import *

#mandel_gpu = cuda.jit(device=True)(mandel)

@cuda.jit(device=True)
def mandel(x, y, max_iters):
"""
Given the real and imaginary parts of a complex number,
determine if it is a candidate for membership in the Mandelbrot
set given a fixed number of iterations.
"""
c = complex(x, y)
z = 0.0j
for i in range(max_iters):
z = z*z + c
if (z.real*z.real + z.imag*z.imag) >= 4:
return i

return max_iters

@cuda.jit
def mandel_kernel(min_x, max_x, min_y, max_y, image, iters):
height = image.shape[0]
width = image.shape[1]

pixel_size_x = (max_x - min_x) / width


pixel_size_y = (max_y - min_y) / height

startX = cuda.blockDim.x * cuda.blockIdx.x + cuda.threadIdx.x


startY = cuda.blockDim.y * cuda.blockIdx.y + cuda.threadIdx.y
gridX = cuda.gridDim.x * cuda.blockDim.x;
gridY = cuda.gridDim.y * cuda.blockDim.y;

for x in range(startX, width, gridX):


real = min_x + x * pixel_size_x
for y in range(startY, height, gridY):
imag = min_y + y * pixel_size_y
image[y, x] = mandel(real, imag, iters)

gimage = np.zeros((1024, 1536), dtype = np.uint8)


blockdim = (32, 8)
griddim = (32,16)

start = timer()
d_image = cuda.to_device(gimage)
mandel_kernel[griddim, blockdim](-2.0, 1.0, -1.0, 1.0, d_image, 20)
d_image.to_host()
dt = timer() - start

print ("Mandelbrot created on GPU in %f s" % dt)

imshow(gimage)
show()

50
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.2 Instalasi OpenCL


2.2.1 Apa itu OpenCL
OpenGL/AL/CL adalah versi Open Source dari DirectX, dimana
OpenGL = Direct3D, OpenAL = DirectSound3D, dan OpenCL mirip
dengan DirectCompute. OpenCL adalah framework untuk
pemrograman yang dikelola Khronos Grup, yang dapat
diimplementasikan pada heterogeneous platforms, terdiri dari Altera,
AMD, Apel, ARM Holdings, Creative Technology, IBM, Imagination
Technologies, Intel, Nvidia, Qualcomm, Samsung, Vivante, Xilinx, dan
ZiiLABS.
Open Source Computer Vision
Open Graphics Library

Open Audio Library


Open Computing Language

Gambar 2.43 OpenCL dan Lainnya


OpenCL adalah kerangka kerja untuk menulis program yang
mengeksekusi seluruh platform arsitektur silikon yang terdiri dari CPU
/ Prosesor dan unit pengolahan grafis / GPU, atau lainya. OpenCL
menyediakan antarmuka standar untuk komputasi paralel
menggunakan berbasis tugas dan paralelisme berbasis data. OpenCL
mengambil dan menggabungkan keunggulan dari tiap unit core,
contoh GPU memiliki keunggulan dalam komputasi FPU (Floating Point
Unit), dengan OpenCL CPU/ Prosesor tidak perlu menghitung bilangan
FPU, karena tugas untuk menghitung bilangan FPU telah dialihkan ke
GPU. Hal ini akan membuat kinerga CPU lebih ringan dan perhitungan
yang dilakukan bisa dilakukan lebih cepat.

2.2.2 Install OpenCL NVidia


- Pastikan anda telah melakukan tahapan instalasi Cuda sebagai
berikut:
o Install Visual Studio
o Install Nvidia display driver terbaru
o Install CUDA
o Install Nsight

51
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Lokasi OpenCL.lib untuk x64 dan Win32, search di PC anda, misal


ditemukan pada “C:\Program Files\NVIDIA GPU Computing
Toolkit\CUDA\v8.0\lib\x64”. Contoh koding OpenCL CUDA
“https://developer.nvidia.com/opencl”.

(Cara 1 of 2): Instalasi OpenCL CUDA


- Jalankan Visual Studio, buat folder solution utama atau global,
misal “VSOpenCL”, lalu buat folder solution “13_OpenCLIntro”, dan

pilih lokasi, lalu klik OK.


Misal lokasinya di “E:\Data Kuliah\!Genap 2016-2017\2.
Pemrograman GPU\VSOpenCL\13_OpenCLIntro\”

- Klik Next, Centang “Empty project”

52
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik Finish

- Masuk ke Control Panel\System and Security\System, lalu Klik


“Environment Variables..”, pada “Sys. Var.” klik New...

- Masukkan Var. name=“CUDA_INC_PATH” dan value “C:\Program


Files\NVIDIA GPU Computing Toolkit\CUDA\v8.0\include”. Klik OK

- Dan pada “Sys. Var.” klik New... lagi, masukkan Var.


name=“CUDA_LIB_PATH” dan value “C:\Program Files\NVIDIA GPU
Computing Toolkit\CUDA\v8.0\lib\x64” untuk 64 bit, “..\Win32”
untuk 32 bit. Klik OK, OK, OK, lalu restart komputer anda.

53
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada project “0OpenCLHello”, klik kanan pada “Source Files”, Add


New Item...

- Misal nama item “OpenCLHello.cpp”, lokasi di “E:\Data Kuliah\!Ge-


nap 2016-2017\2. Pemrograman
GPU\VSOpenCL\13_OpenCLIntro\0OpenCLHello\”, Klik Add

- Klik kanan pada project  Pilih Properties


- Pilih “All Configurations”

54
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ubah Active solution Platform dari “Active(Win32)” ke “Active(x64)”


jika komputer anda 64 bit. Klik “Configuration Manager” pada
“Active solution platform” klik, dan pilih x64

- Pada “Active solution platform” klik, dan pilih x64 (Jika belum ada
pilihan “x64”, klik “<New...>”. )

- Pada “New Solution platform”, pilih “x64”, pada “Copy setting


from”, pilih “Win32”. Klik OK

- Jika muncul, klik Yes

55
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik Close

- Klik OK

- Klik “Linker”, klik “Input”, pada “Additional Dependencies” klik


<Edit...>

56
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Masukkan “OpenCL.lib”, klik OK, Klik Apply

- Klik “Linker”, klik “General”, pada “Additional Library Directories”


klik <Edit...>

- Masukkan “$(CUDA_LIB_PATH)”, klik OK

57
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada file “OpenCLHello.cpp”, copy kode berikut (Link


https://goo.gl/AJMC2E ) atau dari link “https://goo.gl/8IAErm”:
#include <stdio.h>
#include <CL/cl.h>
int main(void){
cl_int err;
cl_uint numPlatforms;
err = clGetPlatformIDs(0, NULL, &numPlatforms);
if (CL_SUCCESS == err){
printf("\n Detected OpenCL platforms: %d", numPlatforms);
}
else{
printf("\n Error calling clGetPlatformIDs, Error code: %d", err);
}
getchar();
return 0;
}

- Compile Project:

- Klik kanan project, pilih “Set as StartUp Project”:

58
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Running

(Cara 2 of 2): Instalasi OpenCL CUDA


- Jalankan Visual Studio, dari folder solution global, misal “VSCuda”,
lalu buat folder solution “13_OpenCLIntro”, dan buat project,

lokasi, lalu klik OK.


Misal lokasinya di “E:\Data Kuliah\!Genap 2016-2017\2.
Pemrograman GPU\VSCuda\13_OpenCLIntro\”

59
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Hapus file “kernel.cu”, klik kanan klik “Remove”

- Klik “Delete”.

- Pada project “0OpenCLHello”, klik kanan pada project, Add New


Item...

60
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Misal nama item “OpenCLHello.cpp”, lokasi di “E:\Data


Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda\13_OpenCLIntro\0OpenCLHello\”, Klik Add

- Pada file “OpenCLHello.cpp”, copy kode berikut (Link


https://goo.gl/AJMC2E ) atau dari link “https://goo.gl/8IAErm”:
#include <stdio.h>
#include <CL/cl.h>
int main(void){
cl_int err;
cl_uint numPlatforms;
err = clGetPlatformIDs(0, NULL, &numPlatforms);
if (CL_SUCCESS == err){
printf("\n Detected OpenCL platforms: %d", numPlatforms);
}
else{
printf("\n Error calling clGetPlatformIDs, Error code: %d", err);
}
getchar();
return 0;
}

- File “OpenCLHello.cpp”, telah berisi kode:

61
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan pada project  Pilih Properties


- Klik “Linker”, klik “Input”, pada “Additional Dependencies” klik
<Edit...>

- Masukkan “OpenCL.lib”, klik OK, Klik Apply, Klik OK

- Compile Project, lalu


Debugging):

62
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.2.3 Install OpenCL Intel


(Instalasi Intel SDK for OpenCL 2017)
- Download file “intel_sdk_for_opencl_2017_7.0.0.2567.exe” dari ..,
atau yang terbaru dari web Intel:

- Tunggu beberapa waktu:

- Install selesai, lalu restart. :D

63
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

(Instalasi Intel SDK for OpenCL 2016)


- Download file “intel_sdk_for_opencl_setup_6.3.0.1904.exe” dari
https://goo.gl/khoqXk , atau yang terbaru dari web Intel:

- Double klik file “intel_sdk_for_opencl_setup_6.3.0.1904.exe”:

- Klik Next

64
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Centang “I accept ....”, klik Next

- Pilih Yes/No, klik Next

65
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik Install

- Proses Installasi

66
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Installasi Selesai, klik Finish, klik Yes/No, dan restart komputer anda.

- Link sampel kode OpenCL Intel: https://software.intel.com/en-


us/intel-opencl-support/code-samples
- Copy OpenCL.dll ke Sytem32 atau SysWOW64 (jika file OpenCL.dll
sudah ada di System32 atau SysWOW64, skip dan abaikan langkah
ini, jangan di replace)
C:\Pro\..\x64\OpenCL.dll should to be copied to
C:\Windows\SysWOW64

67
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

(Instalasi Intel SDK for OpenCL 2016: Create New Project)


- Buat folder solution utama, misal “VSIntelCL”, dengan cara klik File
 New  Project...

- Buat folder solution utama, misal “VSIntelCL”, dengan cara klik File
 New  Project..., lalu pilih Visual C++  OpenCL  CodeBuilder
Project for Windows. Isikan Name “OpenCLProject1”, dan Solution
name “VSIntelCL”, lalu klik OK

68
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Maka akan muncul “Code Builder Wizard ..”

- Maka akan muncul “Code Builder Wizard ..”, lalu klik Next

69
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik Finish, maka “OpenCLProject1” sudah terbuat

- Kemudian coba buat sub folder solution “01_IntroOCL”, dengan


cara klik kanan folder solution utama “VSIntelCL”, klik “New
Solution Folder”

70
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ubah “NewFolder..” menjadi “01_IntroOCL”, lalu tekan enter

- Pada Windows Explorer, buat folder baru didalamnya folder


“VSIntelCL”, dengan nama “01_IntroOCL” (sebaiknya nama dibuat
sama dengan yang ada di VS)

- Kemudian pada VS, didalamnya folder solution “01_IntroOCL” coba


buat project baru dengan nama “0HelloOCL”, dengan cara klik
kanan folder solution “01_IntroO

71
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

-
Name “0HelloOCL”, jangan di klik OK dulu

- Set Location, dengan cara klik Browse.., lalu pilih folder


“01_IntroOCL”, lalu klik “Select Folder”
Sehingga lokasinya berubah menjadi “E:\Data Kuliah\!Genap
2016-2017\2. Pemrograman GPU\VSIntelCL\01_IntroOCL\”, lalu
klik OK

72
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Setelah klik OK, jika muncul error “Adding a new OpenCL project to
existing solution is not supported”, klik OK

- Solusinya, coba cek pada Windows explorer, dari folder


“..\VSIntelCL\01_IntroCL”, project “0HelloOCL” muncul, tapi
didalamnya kosong karena gagal dibuat.

- Pada Windows explorer, copykan semua file dari folder


“..\VSIntelCL\OpenCLProject1” ke
“..\VSIntelCL\01_IntroCL\0HelloOCL”

73
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Setelah tercopy ke “..\VSIntelCL\01_IntroCL\0HelloOCL”

- Lalu rename file “OpenCLProject1.vcxproj” menjadi


“0HelloOCL.vcxproj”, dan “OpenCLProject1.vcxproj.filters” menjadi
“0HelloOCL.vcxproj.filters”

- Setelah itu, pada VS, didalamnya folder solution “01_IntroOCL”


coba klik kanan, pilih Add >> “Existing Project...”

74
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Setelah itu, masuk ke folder “E:\Data Kuliah\!Genap 2016-2017\2.


Pemrograman GPU\VSIntelCL\01_IntroOCL\0HelloOCL”, lalu pilih
file “0HelloOCL.vcxproj”

- Klik Open, project “0HelloOCL” berhasil dibuat.

- Hapus project “OpenCLProject1”, dengan cara klik kanan project,


lalu klik Remove, klik OK

75
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Project “OpenCLProject1” berhasil dihapus.

- Pada file “OpenCLProject1.cpp”, sebelum baris “return 0;”


sebaiknya di atasnya ditambahkan 1 baris dengan kode
“system("pause");”

- Klik kanan Project “0HelloOCL”, pilih “Set as StartUp Project”

76
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Compile Project “0HelloOCL”, klik kanan pilih Clean  Build.

- Build Project “0HelloOCL” berhasil

- Klik Debug  Start Without Debugging

77
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

(Konsep OpenCL: Tambahan)


- Suatu program atau aplikasi yang menggunakan OpenCL terdiri
dari:
o Kernel file (OpenCL-C/C++, misal transposeKernel.cl): problem
computation
o Host code(C/C++, misal mainOCL.cpp): kernel management

- Suatu program atau aplikasi yang menggunakan OpenCL terdiri


dari:
o Load dan Compile Kernel
o Copy data dari host ke device
o Mengeksekusi kernel
o Copy data dari device ke host
o Release kernel dan data dari device
memory

78
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Host code diprogram menggunakan OpenCL API


- API Calls, seperti berikut:
o clCreateProgramWithSource: Load kernel dari char*
o clBuildProgram: Compile kernel
o clSetKernelArgs: Set kernel arguments untuk device
o clEnqueueWriteBuffer/clEnqueueRead: Copy data vector ke
device
o clEnqueueNDRangerKernel: Launch kernel di dalam device
- API Types, seperti berikut:
o cl_mem: Pointer untuk device memory objects
o cl_program: Kernel object
o cl_float / cl_int / cl_uint: Redefinition dari C types
- Huge ecosystems for OpenCL, e.g. OpenACC

(Latihan Koding OpenCL: Operasi Matriks)


- Dalam folder solution utama kelompok, misal “VSCudaKel[..]” atau
di “VSIntelCLKel[..]”, buat folder solution “01_IntroOCLKel[..]”, dan
didalamnya buat project dengan nama
“5TransposeMatriksCLKel[..]”, link kode “https://goo.gl/Y0EIDE”
dengan file *.cl menjadi file tersendiri:

- Dalam folder solution utama kelompok, misal “VSCudaKel[..]” atau


di “VSIntelCLKel[..]”, buat folder solution “01_IntroOCLKel[..]”, dan
didalamnya buat project dengan nama
“7TransMatCLIncludeKel[..]”, link kode “https://goo.gl/l7wIo5”
dengan file *.cl menjadi char * dalam file *.cpp:

79
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

80
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.2.4 Install OpenCL AMD


- Download AMD APP SDK di alamat:
https://developer.amd.com/amd-accelerated-parallel-processing-app-sdk/
- Jalankan installer dan pilih “Install AMD APP SDK x.x now” jika tidak
ingin mendownload offline installer terlebih dahulu dan klik Install
lalu tunggu sampai proses installasi selesai.

Langkah – langkah konfigurasi project OpenCL


- Buat solution baru di Visual Studio dengan nama VSOpenCL

Pada gambar diatas dibuat sebuah solution/project dengan nama


VSOpenCL.

81
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Buat sebuah solution folder dengan nama 13_OpenCLIntro

Sebuah solution global dengan nama VSOpenCL telah dibuat dan


sebuah solution folder dengan nama 13_OpenCLIntro.

- Buat sebuah empty project pada folder solution 13_OpenCLIntro


dengan nama 0OpenCLHello

Gambar diatas menunjukkan bahwa project 0OpenCLHello telah


terbuat pada solution 13_OpenCLIntro

82
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Edit System Variable, buat system variable baru dengan nama


AMD_LIB_PATH yang mengandung PATH menuju direktori library
AMD APP SDK

- Buat system variable baru dengan nama AMD_INC_PATH yang


mengarah ke folder include dari AMD APP SDK

- Tampilan pada System variables

Gambar diatas menunjukkan bahwa variable AMD_INC_PATH dan


AMD_LIB_PATH telah dit-ambahkan dan berisi PATH sesuai dengan
direktori yang dibutuhkan.

83
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Buat sebuah file .cpp pada Source Files project 0OpenCLHello dan
beri nama OpenCLHello.cpp

- Klik kanan, pilih properties, pada “Configuration Manager”, ubah


jenis platform menjadi x64 apabila menggunakan sistem 64 bit

- Buka properties project 0OpenCLHello dan pilih “Linker” > “Input”


lalu edit Additional Dependencies dan set library OpenCL.lib

84
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Dibawah ini menunjukkan bahwa library OpenCL.lib telah


ditambahkan sehingga dapat digunakan dalam membangun
project.

- Akses menu “Linker” > “General” dan edit Additional Library


Directories untuk menambahkan library library yang ada pada
suatu direktori sehingga dapat digunakan dalam project. Gunakan
system variable yang berisi PATH menuju direktori library AMD APP
SDK yang telah dibuat sebelumnya.

85
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Gambar dibawah menunjukkan bahwa direktori yang di-tunjukkan


oleh variabl AMD_LIB_PATH telah disertakan dalam project.

- Akses menu “C/C++” > “General” dan edit Additional Include


Directories.

86
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Gambar dibawah ini menunjukkan bahwa direktori include AMD


APP SDK telah ditambahkan.

- Masukkan kode program kedalam file OpenCLHello.cpp

- Klik kanan pada project 0OpenCLHello dan pilih “Set as StartUp


Project”
- Klik “Debug” > “Start Without Debugging” untuk menjalankan
project.

Tampilan diatas menunjukkan output dari kode program pada file


OpenCLHello.cpp. Hal ini menandakan bahwa OpenCL telah dapat
digunakan pada project tersebut.

87
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.3 Study Kasus Sederhana: CUDA dan


OpenCL
2.3.1 Hello World :D
- Hello world dengan CUDA
__global__ void FnMyKernelGPU(){
}
int main(){
//byk block = 2, byk threads per block = 4
FnMyKernelGPU<<<2,4>>>();
printf(“Hello World, GPU CUDA \n”);
..
}

Prefixes pada CUDA


 __host__
o Berjalan hanya sekali per call pada CPU.
o Hanya dapat dipanggil dari CPU (misal, dari host function
lain).
o Semua functions tanpa explisit prefiks “__host__” adalah
host functions.
 __global__
o Akan dijalankan pada GPU dengan satu atau beberapa threads
secara simultan ketika dipanggil.
o Harus menggunakan return void
o Digunakan untuk membuat kernel tertentu atau spesifik
o Berjalan beberapa kali per call pada GPU (sesuai dengan
yang di-set pada <<<#,#>>>).
o Hanya dapat dipanggil dari CPU (misal, dari host function).
 __device__
o Berjalan hanya sekali per call pada GPU.
o Hanya dapat dipanggil dari GPU (misal, dari kernel atau
device function lain).

Contoh menggunakan prefiks __device__ dan __global__ dengan 2


blocks dan 4 threads per block.
__device__ int FnMydev1(){ printf(“Fn Dev1 \n”);
}
__device__ int FnMydev2(){ printf(“Fn Dev2 \n”);
}
__global__ void RunThis8Kali(){
FnMydev1(); FnMydev2();
}
int main(){
//byk block = 2, byk threads per block = 4
RunThis8Kali<<<2,4>>>();
printf(“Hello World, GPU CUDA \n”);
..
}

88
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Pipeline/ Skeleton/ Alur koding dengan CUDA


#include <stdio.h>
#include <stdlib.h>
#include "cuda_runtime.h"
#include "device_launch_parameters.h"

__global__ void satu_or_bbrp_kernel(..){..}


int main(){
// Deklarasi semua variabel
....
// Mengalokasikan memory host
....
// Mengalokasikan memory device secara dinamis untuk hasil GPU
....
// Write untuk memomy host
....
// Copy memory host ke memory device
....
// Menjalankan kernel pada device (GPU)
satu_or_bbrp_kernel<<<byk_blocks,byk_threads_per_block>>>(..);
// Write hasil GPU dalam memory device, lalu kembalikan ke
// memory host (copy memory device ke memory host), agar hasil
// dari GPU dapat diambil atau diproses lebih lanjut dalam
// host, misal untuk ditampilkan atau lainnya
....
// Free memory host
....
// Free memory device

system("pause");
return 0;
}

- Hello world dengan OpenCL


__kernel void FnMyKernelGPU(__global string
*string_device_hello){
//kirim string berikut ke host untuk di printf
*string_device_hello = “Hello World, GPU OpenCL”;
}

89
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.3.2 Single Instruction, Single Data (SISD)


- Single Instruction, Single Data (SISD), link kode
“http://bit.ly/2Cuvysi” dengan CUDA
__global__ void FnMyFirstGPU(float *device_a)
{
//Single Instruction, Single Data (SISD)
*device_a = 100;
}

- Single Instruction, Single Data (SISD), link kode


“https://goo.gl/EDjssk” dengan OpenCL
__kernel void IntroCL_SISD_FnMyFirstGPU(__global float
*device_a){
//Single Instruction, Single Data (SISD)
*device_a = 2;
}

2.3.3 Single Instruction, Multiple Data (SIMD)


- Single Instruction, Multiple Data (SIMD), link kode
“http://bit.ly/2BB4uGh” dengan CUDA
__global__ void FnMyFirstGPU(float *device_a)
{
//Single Instruction, Multiple Data (SIMD)
//Under this paradigm, the thread in a kernel call write to
//different memory spaces.
//When threads write to the same memory (SISD),
//problems can arise.

int tid1 = blockDim.x;


int tid2 = blockIdx.x;
int tid3 = threadIdx.x;

//printf("\n blockDim.x = %d", tid1);


//printf("\n blockIdx.x = %d", tid2);
//printf("\n threadIdx.x = %d", tid3);

int tid = blockDim.x*blockIdx.x + threadIdx.x;


printf("\n blockDim.x*blockIdx.x + threadIdx.x = %d*%d + %d =
%d", tid1, tid2, tid3, tid);

*device_a = blockDim.x*blockIdx.x + threadIdx.x;

//The output is unpredictable because the threads modify


//the same variable in an unpredictable order.
}

90
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Single Instruction, Multiple Data (SIMD), link kode


“https://goo.gl/fgkjhQ” dengan OpenCL
__kernel void IntroCL_SIMD_FnMyFirstGPU(__global int
*Host_A,__global int *device_tid) {
// Generate indeks untuk Thread
int blockDim_x = get_local_size(0); //blockDim.x;
int blockIdx_x = get_group_id(0); //blockIdx.x;
int threadIdx_x = get_local_id(0); //threadIdx.x;
// Single Instruction, Multiple Data (SIMD)
int tid = blockDim_x*blockIdx_x + threadIdx_x;
//int i = get_global_id(0);
// Do the operation
// get_local_size(0)*get_group_id(0) + get_local_id(0)
if (tid < 5){
device_tid[tid] = tid;
}else{
device_tid[tid] = -1;
}
*Host_A = get_local_size(0)*get_group_id(0) +
get_local_id(0);
}

91
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2.4 Tugas Kelompok


----------Instalasi CUDA/OpenCL/PyCUDA/OpenCV/etc----------
1. Lakukan instalasi dan konfigurasi dari beberapa master berikut,
seperti pada materi:
o Instalasi CUDA (Jika menggunakan Nvidia)
o Instalasi OpenCL (Jika menggunakan Nvidia/Intel/AMD atau
lainnya)
o Instalasi OpenCV
o Instalasi Anaconda (untuk PyCUDA atau PyOpenCL)
o Visual Studio terbaru atau IDE lainnya
Capture step by step proses instalasi dan konfigurasinya!
----------CUDA----------------
2. Buatkan Program untuk Operasi berikut menggunakan CUDA
a. SISD (Coba Compile dari CMD dan Visual Studio)
b. SIMD (Coba Compile dari CMD dan Visual Studio)
Di dalam koding SISD dan SIMD, tolong sisipkan kode berikut.

printf(“Koding GPU CUDA SISD/SIMD Kel-[..] Kelas-[..]...\n");

----------OpenCL----------------
3. Buatkan Program untuk Operasi berikut menggunakan OpenCL
a. SISD
b. SIMD
Di dalam koding SISD dan SIMD, tolong sisipkan kode berikut.

printf(“Koding GPU OpenCL SISD/SIMD Kel-[..] Kelas-[..]...\n");

92
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

----------PyCUDA----------------
4. Buatkan Program untuk Operasi berikut menggunakan PyCUDA
a. SISD
b. SIMD
Di dalam koding SISD dan SIMD, tolong sisipkan kode berikut.

printf(“Koding GPU PyCUDA SISD/SIMD Kel-[..] Kelas-[..]...\n");

93
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 3 Cara Kerja Kernel


Pada GPU

Tujuan utama dari pemrograman paralel adalah untuk


meningkatkan performa komputasi. Semakin banyak hal yang bisa
dikerjakan secara bersamaan (dalam waktu yang sama), semakin
banyak pekerjaan yang bisa diselesaikan. Contoh analoginya, misal
anda akan mencuci baju dan memasak nasi, maka anda dapat
menggunakan mesin cuci untuk mencuci baju, sambil menunggu
cucian bersih dan anda mulai memasak nasi dengan magic com,
sehingga waktu yang anda butuhkan akan lebih sedikit dibandingkan
bila anda mengerjakan hal tersebut secara berurutan (serial).

Gambar 3.1 Map CUDA dan OpenCL

94
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3.1 CUDA Grid Vs OpenCL NDRange


Perbandingan bentuk mapping kernel proses paralel pada
Pemrograman CUDA dan OpenCL.
CUDA Grid: "dim3 grid(3, 3, 1);" dan “dim3 block(3, 3, 1);”
OpenCL NDRange: "global_work_size[3]={ 3, 3, 0 };" dan “lo-
cal_work_size[3]={ 3, 3, 0 }; ”

clEnqueueNDRangeKernel(command_queue, kernel,
work_dim=2, NULL, global_work_size, lo-
cal_work_size, 0, NULL, NULL);

CUDA Grid Vs OpenCL NDRange


work_dim=2
local_id(0,0) local_id(1,0) local_id(2,0)
local_w ork_size.y

local_w ork_size.y

local_w ork_size.y

local_w ork_size.x local_w ork_size.x local_w ork_size.x


global_work_size.y

local_id(0,1) local_id(1,1) local_id(2,1)


local_w ork_size.y

local_w ork_size.y

local_w ork_size.y

local_w ork_size.x local_w ork_size.x local_w ork_size.x


local_id(0,2) local_id(1,2) local_id(2,2)
local_w ork_size.y

local_w ork_size.y

local_w ork_size.y

local_w ork_size.x local_w ork_size.x local_w ork_size.x

global_work_size.x

Pada saat membuat koding untuk penyelesaian suatu proses


komputasi, kita dapat menggunakan CUDA atau OpenCL yang masing-
masing memiliki keunikan tersendiri dalam memetakan data yang
diolah, sehingga bisa diproses secara paralel.

95
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Berikut contoh potongan kode program paralel CUDA pada


bagain kode kernel vectorAdd dengan blockIdx.x, dan Set grid, block
dan Fungsi untuk memanggilnya.

Jika dibuat kode lain dengan tujuan yang sama, maka contoh
kode vectorAdd dengan threadIdx.x, dan Set grid, block dan Fungsi
untuk memanggilnya adalah sebagai berikut.

Pemrograman paralel pada CUDA terdiri dari tiga core, yaitu


hirarki dari thread, shared memory, dan sinkronisasi. Threads pada
GPU dapat mempercepat perhitungan/komputasi dengan membagi-
bagi tugas perhitungan dan menyebarkannya ke thread-thread untuk
kemudian dilakukan komputasi oleh masing-masing thread tersebut.
Shared memory di setiap blok berfungsi untuk memudahkan
penggunaan resource oleh threads yang akan melakukan komputasi
sehingga tidak perlu keluar blok untuk mencari resource utama yang
berada di luar blok. Denan menggunakan Shared memory akan
mempercepat proses pengiriman dan penggunaan resource itu sendiri
sehingga akhirnya akan mengurangi waktu komputasi. Sinkronisasi
antar thread juga harus diimplementasikan pada proses komputasi,
sebab perhitungan yang dilakukan oleh threads nantinya akan
digabungkan ke dalam satu hasil perhitungan.

96
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

CUDA versus OpenCL jika dibandingkan dari segi terminologi


hardware (HW) dan Indexing pada Kernels.
- Terminologi Hardware

- Indexing pada Kernels


CUDA menggunakan threadIdx.x untuk mendapatkan id pada dimensi pertama
(1D), sedangkan OpenCL menggunakan get_local_id(0).

Di mana,
threadIdx.x  get_local_id(0), dan blockIdx.x  get_group_id(0)  Dim ke-1
threadIdx.y  get_local_id(1), dan blockIdx.y  get_group_id(1)  Dim ke-2
threadIdx.z  get_local_id(2), dan blockIdx.z  get_group_id(2)  Dim ke-3

- Qualifiers untuk Fungsi Kernel

- Kernels Synchronization dan API Calls

97
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3.2 Cara Kerja Kernel Pada CUDA


Global Thread ID (x-direction), pada komputasi paralel CUDA
yang melibatkan blockIdx.x, blockDim.x, dan threadIdx.x dan ilustrasi
Global Thread ID (tid) adalah berikut:

Pada Gambar di atas, diketahui gridDim.x = 2, blockDim.x = 5,


jumlah block = 2, dan jumlah thread (T) = 5. Jika dituliskan dalam
bentuk set ukuran grid dan block-nya menjadi seperti "dim3 grid(2, 1,
1);" dan “dim3 block(5, 1, 1);”, serta berikut kernel yang
memungkinkan untuk digunakan:
o FnvectAdd<<<1, N>>>
o FnvectAdd<<<(int)ceil(N/T),T>>>, terbaik untuk digunakan
o FnvectAdd<<<N, T>>>, atau lainnya
Global Thread ID (tid) dapat dihitung dengan “tid = blockIdx.x *
blockDim.x + threadIdx.x”. Jika Global Thread ID = 7, maka blockIdx.x
= 1, blockDim.x = 5, dan threadIdx.x = 2. Dan jika Global Thread ID = 4,
maka blockIdx.x = 0, blockDim.x = 5, dan threadIdx.x = 4. Penjelasan
set ukuran grid dan block adalah sebagai berikut:
////////////////////////////////
// set ukuran grid dan block //
////////////////////////////////
dim3 grid(3, 1, 1);
// Dari dim3 grid(3, 1, 1); dapat dijabarkan berikut:
//>> gridDim.x = 3, gridDim.y = 1, gridDim.z = 1
//>> banyakBlok = gridDim.x*gridDim.y*gridDim.z = 3
//>> blockIdx.x = {0,1,...,gridDim.x-1} = {0,1,...,3-1} yang diambilkan dari grid(3,..,..)
// blockIdx.x, memiliki anggota sebanyak 3
//>> blockIdx.y = {0} yang diambilkan dari grid(..,1,..)
// blockIdx.y, memiliki anggota sebanyak 1
//>> blockIdx.z = {0} yang diambilkan dari grid(..,..,1)
// blockIdx.z, memiliki anggota sebanyak 1

dim3 block(4, 1, 1);


// Dari dim3 block(4, 1, 1); dapat dijabarkan berikut:
//>> blockDim.x = 4, blockDim.y = 1, blockDim.z = 1
//>> banyakThread = blockDim.x*blockDim.y*blockDim.z = 4
//>> threadIdx.x = {0,1,...,blockDim.x-1} = {0,1,...,4-1} yang diambilkan dari block(4,..,..)
// threadIdx.x, memiliki anggota sebanyak 4
//>> threadIdx.y = {0} yang diambilkan dari block(..,1,..)
// threadIdx.y, memiliki anggota sebanyak 1
//>> threadIdx.z = {0} yang diambilkan dari block(..,..,1)
// threadIdx.z, memiliki anggota sebanyak 1

Di mana, Global Thread ID (tid) = blockIdx.x * blockDim.x + threadIdx.x

98
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3.3 Cara Kerja Kernel Pada OpenCL


Pada struktur kernel execution, terdapat cl_int
clEnqueueNDRangeKernel merupakan kernel pada OpenCL yang di
dalamnya terdapat beberapa argument yang utamanya adalah
digunakan untuk set nilai “work_dim” (set 1 atau 2 atau 3 dimensi),
global_work_size, dan local_work_size.
cl_int clEnqueueNDRangeKernel (cl_command_queue command_queue,
cl_kernel kernel,
cl_uint work_dim,
const size_t * global_work_offset,
const size_t * global_work_size,
const size_t * local_work_size,
cl_uint num_events_in_wait_list,
const cl_event *event_wait_list,
cl_event *event)

Workers, work dimension (work_dim) dan work sizes


(work_size), misal pada kasus VectorAdd, maka tiap workers
ditugaskan paling tidak mengambil 2 angka, lalu menjumlahkannya.
work_dim = 1: work_dim = 2:
for (int i = 0; i <= get_global_size(0); i++) for (int i = 0; i <= get_global_size(0); i++){
{ for (int j = 0; j <= get_global_size(1); j++){
i = get_global_id(0); i = get_global_id(0);
//Kernel code here j = get_global_id(1);
} // Kernel code here
}
}
work_dim = 3:
for (int i = 0; i <= get_global_size(0); i++){
for (int j = 0; j <= get_global_size(1); j++){
for (int k = 0; k <= get_global_size(2); k++)
{
i = get_global_id(0);
j = get_global_id(1);
k = get_global_id(2);
//Kernel code here
}
}
}

99
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ilustrasi Ke-1:
Workers, misal dalam 1 kelas terdapat 16 mahasiswa, dan
masing-masing mahasiswa diminta untuk membantu, dalam men
yelesaikan kasus menjumlahkan 2 vector. Misal vector A dan B yang
panjangnya masing-masing 16. Misal penyelesaiannya menggunakan
1D (work_dim=1), maka yang terisi hanya dimensi ke-1, sehingga
dimensi ke-2 dan ke-3 nya harus bernilai nol, dengan local_size(0)=4
(artinya, mhs tersebut dibentuk menjadi 4 kelompok).
global_work_size[3]={ 16, 0, 0 };
local_work_size[3]={ 4, 0, 0 };

Ket: //global_id() = group_id()*local_size() + local_id();


//int tid_x = blockIdx_x*blockDim_x + threadIdx_x;

// dimana “get_”, global_size(0)=16  jika diuraikan, maka


group_id(0) = {0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3}
// global_size(1)=0  group_id(1) = { }  himpunan kosong
// global_size(2)=0  group_id(2) = { }  himpunan kosong
// local_size(0)=4  jika diuraikan, maka local_id(0) =
{0,1,2,3,0,1,2,3,0,1,2,3,0,1,2,3}
// local_size(1)=0  local_id(1) = { }  himpunan kosong
// local_size(2)=0  local_id(2) = { }  himpunan kosong

Ket: global_id(0) = group_id*local_size + local_id;


= group_id(0)*local_size(0) + local_id(0);
= 0*4 + 0 = 0 = 2*4 + 0 = 8
= 0*4 + 1 = 1 = 2*4 + 1 = 9
= 0*4 + 2 = 2 = 2*4 + 2 = 10
= 0*4 + 3 = 3 = 2*4 + 3 = 11
= 1*4 + 0 = 4 = 3*4 + 0 = 12
= 1*4 + 1 = 5 = 3*4 + 1 = 13
= 1*4 + 2 = 6 = 3*4 + 2 = 14
= 1*4 + 3 = 7 = 3*4 + 3 = 15

clEnqueueNDRangeKernel(command_queue, kernel,
work_dim=1, NULL, global_work_size,
local_work_size, 0, NULL, NULL);

Tiap mahasiswa hanya ambil dan


menghitung 2 nilai pada indeks
tertentu, 1 nilai dari vektor
A, dan 1 nilai dari vektor B,
lalu menjumlahkannya, untuk di-
masukkan dalam vektor C

100
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ilustrasi Ke-2:
Workers, misal dalam 1 kelas terdapat 16 mahasiswa, dan
masing-masing mahasiswa diminta untuk membantu, dalam
menyelesaikan kasus menjumlahkan 2 vector. Misal vector A dan B
yang panjangnya masing-masing 16. Misal penyelesaiannya
menggunakan 1D (work_dim=1), maka yang terisi hanya dimensi ke-1,
sehingga dimensi ke-2 dan ke-3 nya harus bernilai nol, dengan
local_size(0)=1 (artinya, mhs tersebut dibentuk menjadi 1 kelompok).
global_work_size[3]={ 16, 0, 0 };
local_work_size[3]={ 1, 0, 0 };

Ket: //global_id() = group_id()*local_size() + local_id();


//int tid_x = blockIdx_x*blockDim_x + threadIdx_x;

// dimana “get_”, global_size(0)=16  jika diuraikan, maka


group_id(0) = {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
// global_size(1)=0  group_id(1) = { }  himpunan kosong
// global_size(2)=0  group_id(2) = { }  himpunan kosong
// local_size(0)=1  jika diuraikan, maka local_id(0) =
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}
// local_size(1)=0  local_id(1) = { }  himpunan kosong
// local_size(2)=0  local_id(2) = { }  himpunan kosong

Ket: global_id(0) = group_id*local_size + local_id;


= group_id(0)*local_size(0) + local_id(0);
= 0*1 + 0 = 0 = 8*1 + 0 = 8
= 1*1 + 0 = 1 = 9*1 + 0 = 9
= 2*1 + 0 = 2 = 10*1 + 0 = 10
= 3*1 + 0 = 3 = 11*1 + 0 = 11
= 4*1 + 0 = 4 = 12*1 + 0 = 12
= 5*1 + 0 = 5 = 13*1 + 0 = 13
= 6*1 + 0 = 6 = 14*1 + 0 = 14
= 7*1 + 0 = 7 = 15*1 + 0 = 15
clEnqueueNDRangeKernel(command_queue, kernel,
work_dim=1, NULL, global_work_size,
local_work_size, 0, NULL, NULL);

Tiap mahasiswa hanya ambil dan


menghitung 2 nilai pada indeks
tertentu, 1 nilai dari vektor
A, dan 1 nilai dari vektor B,
lalu menjumlahkannya, untuk di-
masukkan dalam vektor C

101
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ilustrasi Ke-3:
Misal menggunakan 2D (work_dim=2), maka yang terisi hanya
dimensi ke-1 dan dimensi ke-2, sehingga ke-3 nya harus bernilai nol,
dengan local_size(0)=4 (artinya, mhs tersebut dibentuk menjadi 4
kelompok) pada dimensi ke-1, local_size(1)=4 (artinya, mhs tersebut
dibentuk menjadi 4 kelompok) pada dimensi ke-2.
global_work_size[3]={ 4, 4, 0 };
local_work_size[3]={ 4, 4, 0 };

Ket: //global_id() = group_id()*local_size() + local_id();


//int tid_x = blockIdx_x*blockDim_x + threadIdx_x;

// dimana “get_”, global_size(0)=4  jika diuraikan, maka


group_id(0) = {0,0,0,0}
// global_size(1)=4  group_id(1) = { 0,0,0,0 }
// global_size(2)=0  group_id(2) = { }  himpunan kosong
// local_size(0)=4  jika diuraikan, maka local_id(0) = {0,1,2,3}
// local_size(1)=4  local_id(1) = { 0,1,2,3 }
// local_size(2)=0  local_id(2) = { }  himpunan kosong

Ket: global_id(0) = group_id*local_size + local_id;


= group_id(0)*local_size(0) + local_id(0);
= 0*4 + 0 = 0  global_id(1) = {0,1,2,3}
= 0*4 + 1 = 1  global_id(1) = {0,1,2,3}
= 0*4 + 2 = 2  global_id(1) = {0,1,2,3}
= 0*4 + 3 = 3  global_id(1) = {0,1,2,3}
 i = get_global_id(0); j = get_global_id(1);
 [i,j] = i*global_size(1)+j = 0*4 + 0 = 0  0*4 + 1 = 1  0*4 +
2 = 2  0*4 + 3 = 3  1*4 + 0 = 4  1*4 + 1 = 5  1*4 + 2 = 6 
1*4 + 3 = 7  2*4 + 0 = 8  2*4 + 1 = 9  2*4 + 2 = 10  2*4 + 3
= 11  3*4 + 0 = 12
 3*4 + 1 = 13  3*4 + 2 = 14  3*4 + 3 = 15

Ket: global_id(1) = group_id(1)*


local_size(1) +
local_id(1);
= 0*4 + 0 = 0
= 0*4 + 1 = 1
= 0*4 + 2 = 2
= 0*4 + 3 = 3

work_dim = 2:
for(int i=0; i<=get_global_size(0);i++){
for(int j=0; j<=get_global_size(1);j++){
i = get_global_id(0);
j = get_global_id(1);
// Kernel code here
}
}

clEnqueueNDRangeKernel(command_queue, kernel,
work_dim=2, NULL, global_work_size, local_work_size,
0, NULL, NULL);

102
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ilustrasi Ke-4:
Petunjuk: Pastikan global_work_sizes-nya merupakan
perkalian dari local_work_sizes. Artinya local_work_sizes harus
merupakan faktor dari global_work_sizes. Berikut contoh lainnya.
//set work dimension (work_dim)
int work_dim = 3; // 3D
//set global size dan local size
//seperti dim3 grid (..,..,..) size dan
//dim3 block(..,..,..) size pada CUDA
size_t global_work_size[3]={ 4, 10, 9 };
size_t local_work_size[3]={ 1, 2, 3 };
// atau bisa dgn { 2, 1, 3 }, atau lainnya
// dimana “get_”, global_size(0)=4,
// global_size(1)=10, global_size(2)=9
// local_size(0)=1, local_size(1)=2,
// local_size(2)=3

Ket: //global_id = group_id*local_size + local_id;


//int tid = blockIdx_x*blockDim_x + threadIdx_x;

//Menjalankan kernel pada device (“3" //mengindikasikan work


dengan 3-dim)
ret = clEnqueueNDRangeKernel(command_queue, kernel,
work_dim, NULL, global_work_size, local_work_size, 0, NULL,
NULL);

//File kernel.cl //Hasil output


__kernel void
kernelExample(
__global int * getglobalID0,
__global int * getglobalID1,
__global int * getglobalID2,
__global int * getlocalID0,
__global int * getlocalID1,
__global int * getlocalID2,
__global int * getgroupID0,
__global int * getgroupID1,
__global int * getgroupID2)
{
int i = get_global_id(0);
int j = get_global_id(1);
int k = get_global_id(2);
getglobalID0[i] = i;
getglobalID1[j] = j;
getglobalID2[k] = k;
getlocalID0[i] = get_local_id(0);
getlocalID1[j] = get_local_id(1);
getlocalID2[k] = get_local_id(2);
getgroupID0[i] = get_group_id(0);
getgroupID1[j] = get_group_id(1);
getgroupID2[k] = get_group_id(2);
}

103
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3.4 Create Main Project (Compile dari


Visual Studio)
Berikut ini merupakan tahapan dalam membuat dan konfigurasi
project serta demo program.
- Buka Visual Studio, dengan cara menekan tombol Windows,
ketikan “v”, klik “Visual Studio 2013”:

- Klik FileNewProject..:
- Klik NVIDIA  CUDA 8.0  CUDA 8.0 Runtime, lalu isikan nama
project, misal “VSCuda”:

Gambar 3.2 Membuat Project NVIDIA CUDA

104
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Blok project “VSCuda”, lalu klik kanan pilih remove, klik Yes:
(Menghapus Isi Project VSCuda)

- Solution “VSCuda”, masing kosong project:

- Solution “VSCuda”, masing kosong project, Buat Folder Solution


Kumpulan Project, dengan klik kanan solution “VSCuda”  Add 
New Solution Folder, misal “03_InstalasiCuda”:

Gambar 3.3 Buat Solution Folder Baru Pada Solution VSCuda

105
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Didalam folder Solution “VSCuda”, buat folder dengan nama


“03_InstalasiCuda”, dan hapus folder project “VSCuda” didalam
folder Solution “VSCuda”:

- Pada folder “03_InstalasiCuda”, klik kanan pilih Add  New


Project..:

106
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Lalu Pilih NVIDIA, klik CUDA 8.0  CUDA 8.0 Runtime, lalu
masukkan Name Project, misal “0matrixTambah” dan Pilih Lokasi
(misal, di “..Pemrograman GPU\VSCuda\03_InstalasiCuda\”, bukan
di “E:\Data Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda\”), Klik OK:

- Remove file *.cu, pada folder project “0matrixTambah”, klik


Remove:

107
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Buat file *.cu baru, pada folder project “0matrixTambah”, klik


kanan project  Add  New Item..:

- Lalu Pilih NVIDIA CUDA 8.0  CUDA C/C++ File, lalu masukkan
Name File, misal “0matrixTambah” dan Klik Add:

- Tampilan di project ketika File “0matrixTambah.cu” sudah


ditambahkan, siap untuk menulis koding di file tersebut:

108
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Tampilan Solution “VSCuda” dan beberapa project di dalamnya dari


Windows Explorer:

- Klik kanan pada Solution, lalu pilih Configuration Manager.., lalu


Pilih x64 (Sesuaikan dengan kodisi):

109
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan pada Project, lalu pilih Active(x64), klik Apply/OK:

- Preview Visual Studio:

Gambar 3.4 Tampilan Project Aktif Pada Visual Studio

110
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Running dari cmd:

- Running dari VS Klik kanan project, lalu Pilih Debug>Start new


instance (1 of 2):

111
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Running dari VS Klik kanan project, lalu Pilih Debug>Start new


instance (2 of 2):

3.5 Study Kasus Dev.: CUDA


3.5.1 Operasi Paralel pada Vector
Ilustrasi Proses Penjumlahan
- Perhatikan operasi vektor berikut:

1 baris banyak kolom, atau 1 kolom banyak baris

112
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Kernel dan Host, Kode Kernel adalah kode yang akan
dijalankan pada device atau GPU. Kode ini dijalankan pada thread
di device (kernel run).

Kode Host adalah kode yang dijalankan pada host atau CPU.
Inisialisasi memori yang akan diproses oleh device akan dilakukan
pada Kode Host (memory allocation, kernel launch, dan memory
deallocation).
- Kode Kernel Vs Host, link kode (CUDA):
o 101vectAddDgnblock_Timer: “https://goo.gl/A3kBYL”
o 102vectAddDgnblockIdx.x: “https://goo.gl/JBkoYS”
o 103vectAddDgnthreadIdx.x: “https://goo.gl/tCThJA”

113
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ilustrasi Proses pairwise Sum


- Perhatikan operasi pairwise Sum berikut:
d_A = (5, 2, -3, 1, 1, 8, 2, 6)
misal menggunakan jumlah block 1 dan jumlah threads 4

pairWiseSum<<<jmlBlock=1,threadPerBlock=4>>>(d_A);

- Step by Step proses pairwise Sum:

114
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Kernel pairwise Sum, link kode “https://goo.gl/3XJQ6u”


dengan CUDA:
// Pairwise-sum pada elemen dari vector a dan simpan hasil pada a[0].
// By: Nidos
__global__ void pairWiseSUm(float *a){
int t = threadIdx.x / 2;
int n = blockDim.x / 2 / 2;
int s = blockDim.x / 2 % 2;
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
a[t] += a[t + n];
a[t] += a[t + 2 * n];
}
else{
a[t] += a[t + n];
}
}
//dibutuhkan jika disini terdapat prior computations
dalam kernel
//sinkronisasi thread dalam blocks
__syncthreads();
s = n % 2;
n /= 2;
}
}

- Kode Lain Kernel pairwise Sum, link kode “https://goo.gl/a56FkA”


dengan CUDA:
// Pairwise-sum pada elemen dari vector v dan simpan hasil pada
v[0].
__global__ void pairWiseSum(float* v){
int t = threadIdx.x; // Thread index.
int n = blockDim.x; // nilai n merupakan setengah dari
panjang v.
while (n != 0) {
if (t < n)
v[t] += v[t + n];
__syncthreads();
n /= 2;
}
}

115
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ilustrasi Proses Min & Max


- Kode Kernel Min, refer ke pairwise Sum, link kode
“https://goo.gl/mUvaEg” dengan CUDA:
// membuat fungsi Min dengan GPU
__global__ void FnFindMinElementArray(float *a){
int t = threadIdx.x / 2;
int n = blockDim.x / 2 / 2;
int s = blockDim.x / 2 % 2;
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
a[t] = a[t] < a[t + n] ? a[t] : a[t +
n];
a[t] = a[t] < a[t + 2 * n] ? a[t] :
a[t + 2 * n];
}
else{
a[t] = a[t] < a[t + n] ? a[t] : a[t +
n];
}
}
//dibutuhkan jika disini terdapat prior computations
dalam kernel
//sinkronisasi thread dalam blocks
__syncthreads();
s = n % 2;
n /= 2;
}
}

- Kode Kernel Max, refer ke pairwise Sum, link kode


“https://goo.gl/Zx9GYL” dengan CUDA:
// membuat fungsi Max dengan GPU
__global__ void FnFindMaxElementArray(float *a){
int t = threadIdx.x / 2;
int n = blockDim.x / 2 / 2;
int s = blockDim.x / 2 % 2;
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
a[t] = a[t] > a[t + n] ? a[t] : a[t +
n];
a[t] = a[t] > a[t + 2 * n] ? a[t] :
a[t + 2 * n];
}
else{
a[t] = a[t] > a[t + n] ? a[t] : a[t +
n];
}
}
//dibutuhkan jika disini terdapat prior computations
dalam kernel
//sinkronisasi thread dalam blocks
__syncthreads();
s = n % 2;
n /= 2;
}
}

116
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ilustrasi Proses dot Product


- Perhatikan operasi vektor dot Product ( • ) berikut:
dot Product = VectorMultiply  PairWise Sum

- Proses parallel vektor dot Product

- Kode Kernel, link kode lengkap “https://goo.gl/bp7VFn” dengan


CUDA (1 of 2):
//set parameter kernel, untuk kode program ini hanya menggunakan 1 block, Alokasi
dengan 1 block berisi (2*N) threads
int jumlahBlock = 1;
ukuran
dim3 threadPerBlock(2 * N, 1); block dan
Vector_Dot_Product << <jumlahBlock, threadPerBlock >> > (V1_D, V2_D, V3_D); Thread

117
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Kernel, link kode lengkap “https://goo.gl/bp7VFn” dengan


CUDA (2 of 2):
__global__ void Vector_Dot_Product(const float *V1, const float *V2, float Kode Ker-
*a){ nel pada
int t = threadIdx.x / 2;
int n = blockDim.x / 2 / 2; Device un-
int s = blockDim.x / 2 % 2; tuk Operasi
int tid1 = blockDim.x; int tid2 = blockIdx.x; int tid3 =
threadIdx.x;
dot Product
unsigned int tid = blockDim.x * blockIdx.x + threadIdx.x;
//mengoperasikan Hadamard Product (Misal, 2 Vector dengan
operasi perkalian pada posisi yg sama)
if (tid < N){
printf("\n blockDim.x*blockIdx.x + threadIdx.x =
%d*%d + %d = %d", tid1, tid2, tid3, tid);
a[tid] = V1[tid] * V2[tid];
}
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
a[t] += a[t + n];
a[t] += a[t + 2 * n];
}
else{
a[t] += a[t + n];
}
}
//dibutuhkan jika disini terdapat prior
computations dalam kernel
//sinkronisasi thread dalam blocks
__syncthreads();
s = n % 2;
n /= 2;
}
}

3.5.2 Operasi Paralel pada Matriks


Koding Penjumlahan Matriks
- Kode Kernel, link kode “https://goo.gl/T2wRom” dengan CUDA:
// membuat fungsi penjumlahan dengan CPU, untuk kroscek
void fnMatrixPlusCPU(float *A, float *B, float *Hasil, int
jumlahData){
for (int i = 0; i < jumlahData; i+=1)
{
Hasil[i] = A[i] + B[i];
}
}

Alokasi ukuran block dan Thread:

//set parameter kernel, untuk kode program ini hanya menggunakan


//1 block,dengan 1 block berisi (N * N) threads
int jumlahBlock = 1;
dim3 threadPerBlock(N, N);

Kode Kernel pada Device untuk Operasi Penjumlahan Matriks:

__global__ void fnMatrixPlusGPU(float *A, float *B, float *Hasil,


int ordoMat){
//thread ID
int tid = (threadIdx.y * ordoMat) + threadIdx.x; // This
gives every thread a unique ID.
//perhatikan disini tidak menggunakan loop sama sekali
Hasil[tid] = A[tid] + B[tid];
}

118
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Koding Transpose Matriks


- Kode Kernel, link kode lengkap “https://goo.gl/GqyTVi” dengan
CUDA:
// membuat fungsi transpose dengan CPU, untuk kroscek
void fnMatrixTransCPU(float *A, float *Hasil, int jumlahData)
{
for (int i = 0; i < Baris; i++){
for (int j = 0; j < Kolom; j++){
Hasil[(j*Kolom)+i] = A[(i*Kolom)+j];
}
}
}

Alokasi ukuran block dan Thread:

//set parameter kernel, untuk kode program ini hanya menggunakan


//1 block,dengan 1 block berisi (Baris * Kolom) threads
int jumlahBlock = 1;
dim3 threadPerBlock(Baris, Kolom);

Kode Kernel pada Device untuk Operasi Transpose Matriks:

__global__ void fnMatrixTransGPU(float *A, float *Hasil){


int baris_i = threadIdx.y;
int kolom_j = threadIdx.x;

//membuat thread ID unik dari A


int tid_A = (baris_i * Kolom) + kolom_j;
//thread ID dari Hasil
int tid_H = (kolom_j * Kolom) + baris_i;
printf("tidA %d, tidH %d\n", tid_A, tid_H);

//perhatikan disini tidak menggunakan loop sama sekali


Hasil[tid_H] = A[tid_A];
}

Koding Perkalian Matriks


- Kode Kernel, link kode lengkap “https://goo.gl/ckDhxN” dengan
CUDA:
// membuat fungsi perkalian matriks dengan CPU, untuk kroscek
void fnMatrixMulCPU(float *A, float *B, float *Hasil, int
jumlahData){
for i  0 to n-1 do
for j  0 to n-1 do
Hasil[i,j]  0,0
for k  0 to n-1 do
Hasil[i,j]  Hasil[i,j] + A[i,k]* B[k,j]
}

119
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Alokasi ukuran block dan Thread:

dim3 blocks(1, 1);


dim3 threads(N, N);

// menghitung perkalian matrik dengan GPU


MatMul << <blocks, threads >> > (dev_a, dev_b, dev_c);

Kode Kernel pada Device untuk Operasi Perkalian Matriks:

__global__ void fnMatrixMulGPU(float *d_a, float *d_b, float


*d_c){
int kolom = threadIdx.x;
int baris = threadIdx.y;
float c = 0;
for (int k = 0; k<N; k++){
c += d_a[baris*N + k] * d_b[k*N + kolom];
}
d_c[baris*N + kolom] = c;
}

Running dari VS Klik kanan project, lalu Pilih Debug>Start new


instance:

120
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3.6 Study Kasus Dev.: OpenCL


3.6.1 Operasi Paralel pada Vector
Ilustrasi Proses Penjumlahan
- Perhatikan operasi vektor berikut:

1 baris banyak kolom, atau 1 kolom banyak baris

- Kode Kernel dan Host, Kode Kernel adalah kode yang akan
dijalankan pada device atau GPU. Kode ini dijalankan pada thread
di device (kernel run).

Kode Host adalah kode yang dijalankan pada host atau CPU.
Inisialisasi memori yang akan diproses oleh device akan dilakukan
pada Kode Host (memory allocation, kernel launch, dan memory
deallocation).

121
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Kernel Vs Host, link kode (OpenCL) “https://goo.gl/889Zi2”


Kode Kernel di GPU

// Koding Kernel untuk Penjumlahan Vector di GPU dengan


// OpenCL
__kernel void vector_add(__global const float *A,
__global const float *B, __global float *C) {

// Generate Thread index


int blockDim_x = get_local_size(0); //blockDim.x;
int blockIdx_x = get_group_id(0); //blockIdx.x;
int threadIdx_x = get_local_id(0); //threadIdx.x;

int tid = blockDim_x*blockIdx_x + threadIdx_x;


//int i = get_global_id(0);

// Melakukan operasi penjumlahan Vector secara paralel


C[tid] = A[tid] + B[tid];
}

Ilustrasi Proses pairwise Sum


- Perhatikan operasi pairwise Sum berikut:
d_A = (5, 2, -3, 1, 1, 8, 2, 6)

// Set 2 arguments untuk kernel


ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&a_mem_obj);
ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&device_tid_mem_obj);
ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&myblockDim_x_mem_obj);

// Set Ukuran OpenCL kernel


size_t global_item_size = 2*LIST_SIZE; // Process the entire lists
size_t local_item_size = 1; // Divide work items into groups sebanyak, misal 1
// atau 64 atau lainnya

// Builds a 1D, 2D or 3D ND-range descriptor.


ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size,
&local_item_size, 0, NULL, NULL);

- Step by Step proses pairwise Sum:

122
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Kernel pairwise Sum, link kode “https://goo.gl/HsvFMk”


dengan OpenCL:
// Pairwise-sum pada elemen dari vector a dan simpan hasil pada a[0].
__kernel void vector_pairwisesum(__global float *A, __global int
*device_tid, __global int *myblockDim_x) {
// Generate Thread indeks
int blockDim_x = get_local_size(0); //blockDim.x;
int blockIdx_x = get_group_id(0); //blockIdx.x;
int threadIdx_x = get_local_id(0); //threadIdx.x;
int tid = blockDim_x*blockIdx_x + threadIdx_x; device_tid[tid] =
tid;
int t = tid / 2; //int t = threadIdx_x / 2;
int n = *myblockDim_x / 2 / 2; //int n = blockDim_x / 2 / 2;
int s = *myblockDim_x / 2 % 2; //int s = blockDim_x / 2 % 2;
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
A[t] += A[t + n];
A[t] += A[t + 2 * n];
}
else{
A[t] += A[t + n];
}
}
//sinkronisasi semua work-items (seperti threads dlm
block) utk selesaikan iterasi sebelumnya
barrier(CLK_LOCAL_MEM_FENCE);
s = n % 2;
n /= 2;
}
}

Ilustrasi Proses Min & Max


- Kode Kernel Min, refer ke pairwise Sum, dengan bagian kodenya
sebagai berikut
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
a[t] = a[t] < a[t + n] ? a[t] : a[t +
n];
a[t] = a[t] < a[t + 2 * n] ? a[t] :
a[t + 2 * n];
}
else{
a[t] = a[t] < a[t + n] ? a[t] : a[t +
n];
}
}
//sinkronisasi semua work-items (seperti threads dlm
block) utk selesaikan iterasi sebelumnya
barrier(CLK_LOCAL_MEM_FENCE);
s = n % 2;
n /= 2;
}

123
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Kernel Max, refer ke pairwise Sum, dengan bagian kodenya


sebagai berikut
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
a[t] = a[t] > a[t + n] ? a[t] : a[t +
n];
a[t] = a[t] > a[t + 2 * n] ? a[t] :
a[t + 2 * n];
}
else{
a[t] = a[t] > a[t + n] ? a[t] : a[t +
n];
}
}
//sinkronisasi semua work-items (seperti threads dlm
block) utk selesaikan iterasi sebelumnya
barrier(CLK_LOCAL_MEM_FENCE);
s = n % 2;
n /= 2;
}

Ilustrasi Proses dot Product


- Perhatikan operasi vektor dot Product ( • ) berikut:
dot Product = VectorMultiply  PairWise Sum

- Proses parallel vektor dot Product

124
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Kode Kernel Vector dot Product, refer ke pairwise Sum, dengan


bagian kodenya sebagai berikut:
Kode Ker-
// Generate Thread indeks nel pada
int blockDim_x = get_local_size(0); //blockDim.x;
int blockIdx_x = get_group_id(0); //blockIdx.x; Device un-
int threadIdx_x = get_local_id(0); //threadIdx.x; tuk Operasi
unsigned int tid = blockDim_x * blockIdx_x + threadIdx_x;
dot Product
//mengoperasikan Hadamard Product (Misal, 2 Vector dengan
operasi perkalian pada posisi yg sama)
if (tid < N){
a[tid] = V1[tid] * V2[tid];
}
while (n != 0){
if (t < n){
if (t == 0 && s == 1){
a[t] += a[t + n];
a[t] += a[t + 2 * n];
}
else{
a[t] += a[t + n];
}
}
//sinkronisasi semua work-items (seperti threads
dlm block) utk selesaikan iterasi sebelumnya
barrier(CLK_LOCAL_MEM_FENCE);
s = n % 2;
n /= 2;
}

3.6.2 Operasi Paralel pada Matriks


Koding Penjumlahan Matriks
- Kode Kernel Penjumlahan Matriks, refer ke Vector Add, dengan
bagian kodenya sebagai berikut:
// membuat fungsi penjumlahan dengan CPU, untuk kroscek
void fnMatrixPlusCPU(float *A, float *B, float *Hasil, int
jumlahData){
for (int i = 0; i < jumlahData; i+=1)
{
Hasil[i] = A[i] + B[i];
}
}

Bagian Kode Kernel pada Device untuk Operasi Penjumlahan Matriks:

//perhatikan disini tidak menggunakan loop sama sekali


Hasil[tid] = A[tid] + B[tid];

Koding Transpose Matriks


- Kode Kernel, link kode lengkap “https://goo.gl/Y0EIDE” dan
“https://goo.gl/l7wIo5” dengan OpenCL:
// membuat fungsi transpose dengan CPU, untuk kroscek
void fnMatrixTransCPU(float *A, float *Hasil, int jumlahData)
{
for (int i = 0; i < Baris; i++){
for (int j = 0; j < Kolom; j++){
Hasil[(j*Kolom)+i] = A[(i*Kolom)+j];
}
}
}

125
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Bagian Kode Kernel pada Device untuk Operasi Transpose Matriks:

..

//membuat thread ID unik dari A


int tid_A = (baris_i * Kolom) + kolom_j;
//thread ID dari Hasil
int tid_H = (kolom_j * Kolom) + baris_i;

//perhatikan disini tidak menggunakan loop sama sekali


Hasil[tid_H] = A[tid_A];
..

Koding Perkalian Matriks


- Kode Kernel Perkalian Matriks dengan OpenCL, refer ke kode
Perkalian Matriks dengan CUDA:
// membuat fungsi perkalian matriks dengan CPU, untuk kroscek
void fnMatrixMulCPU(float *A, float *B, float *Hasil, int
jumlahData){
for i  0 to n-1 do
for j  0 to n-1 do
Hasil[i,j]  0,0
for k  0 to n-1 do
Hasil[i,j]  Hasil[i,j] + A[i,k]* B[k,j]
}

Bagian Kode Kernel pada Device untuk Operasi Perkalian Matriks:

..
int threadIdx_x = get_local_id(0);
int threadIdx_y = get_local_id(1);
int kolom = threadIdx_x;
int baris = threadIdx_y;
float c = 0;
for (int k = 0; k<N; k++){
c += d_a[baris*N + k] * d_b[k*N + kolom];
}
d_c[baris*N + kolom] = c;
..

126
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3.7 Tugas Kelompok


----------dengan CUDA----------
1. Buatlah main project dengan nama “VSCudaKel-[..]-Kelas-[..]”, lalu
didalam project terdapat folder, misal “03_Vector_n_Ma-
trixCuda”, yang didalamnya terdapat beberapa project yang terdiri
dari:
– 01findMinArray
– 02findMaxArray
Dan capture hasil hasil running programnya masing-masing dari
VS!

Petunjuk: Buatlah project “01findMinArray dan 02findMaxArray”


tersebut dengan memodifikasi dari kode program “PairWise Sum”
2. Jelaskan konsep thread (tid) pada bagian kode MyFirst-
GPU_SIMD.cu berikut:
__global__ void FnMyFirstGPU(float *device_a)
{
//Single Instruction, Multiple Data (SIMD)
//Under this paradigm, the thread in a kernel call write to
//different memory spaces.
//When threads write to the same memory (SISD),
//problems can arise.

int tid1 = blockDim.x;


int tid2 = blockIdx.x;
int tid3 = threadIdx.x;

//printf("\n blockDim.x = %d", tid1);


//printf("\n blockIdx.x = %d", tid2);
//printf("\n threadIdx.x = %d", tid3);

int tid = blockDim.x*blockIdx.x + threadIdx.x;


printf("\n blockDim.x*blockIdx.x + threadIdx.x = %d*%d + %d = %d", tid1, tid2, tid3, tid);

*device_a = blockDim.x*blockIdx.x + threadIdx.x;

//The output is unpredictable because the threads modify


//the same variable in an unpredictable order.
}

Dan apakah setiap kali dijalankan hasil “printf("\n\nHasil host_a


Setelah Masuk di FnMyFirstGPU = %.2f", host_a);” selalu sama
atau berbeda? Kenapa?

127
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3. Jika pada bagian kode MyFirstGPU_SIMD.cu diubah menjadi beri-


kut:
Pada
int tid = blockDim.x*blockIdx.x + threadIdx.x;
printf("\n blockDim.x*blockIdx.x + threadIdx.x = %d*%d + %d = %d", tid1, tid2, tid3, tid);

Jika diubah menjadi:

int tid = blockDim.x*blockIdx.x + threadIdx.x;


If (tid <5) {
printf("\n blockDim.x*blockIdx.x + threadIdx.x = %d*%d + %d = %d", tid1, tid2, tid3, tid);
}

Bagaimana hasil yang didapatkan? Jelaskan!


4. Jika pada bagian kode MyFirstGPU_SIMD.cu diubah menjadi beri-
kut:
Pada
//printf("\n blockDim.x = %d", tid1);
//printf("\n blockIdx.x = %d", tid2);
//printf("\n threadIdx.x = %d", tid3);
Jika diubah menjadi:

printf("\n blockDim.x = %d", tid1);


printf("\n blockIdx.x = %d", tid2);
printf("\n threadIdx.x = %d", tid3);

Bagaimana hasil yang didapatkan? Jelaskan!

5. Buatlah main project dengan nama “VSCudaKelompok[..]”, lalu


didalam project terdapat folder, misal “03_InstalasiCuda”, yang
didalamnya terdapat beberapa project kecil sekaligus, minimal
project kecil tersebut terdiri dari:
– Penjumlahan Matriks
– Perkalian Matriks
– Transpose Matriks
– Invers Matriks
Dan capture hasil hasil running programnya masing-masing dari
VS! Contoh,

128
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6. Uraikan alur kerja indeks thread yang diadopsi dari alur kerja suatu
fungsi pada CPU dari bagian kode program GPU berikut, misal
dengan ordoMat=3:
a. Thread pada penjumlahan matriks
__global__ void fnMatrixPlusGPU(float *A, float *B, float *Hasil, int ordoMat)
{
//thread ID
int tid = (threadIdx.y * ordoMat) + threadIdx.x; // This gives every thread a unique ID.

//perhatikan disini tidak menggunakan loop sama sekali


Hasil[tid] = A[tid] + B[tid];
}

b. Thread pada perkalian matriks


// dev_a, dev_b, dev_c masing-masing adalah matrik a, b, c
__global__ void MatMul(float *dev_a,float *dev_b ,float *dev_c,int ordoMat){ // dev adalah device
int kolom=threadIdx.x; // threadIdx adalah thread Index
int baris=threadIdx.y;
float c=0;
for(int k=0;k<ordoMat;k++){
c+=dev_a[baris*ordoMat +k]*dev_b[k*ordoMat+kolom];
}
dev_c[baris*ordoMat+kolom]=c;
}

c. Thread pada transpose matriks


----------dengan OpenCL----------
7. Buatlah main project dengan nama “VSCudaKel-[..]-Kelas-[..]”, lalu
di dalam project buat folder, misal “03_Vector_n_MatrixCL”, yang
di dalamnya terdapat project dengan nama, misal yaitu “11In-
troCL_SIMD_FnMyFirstGPU”. Dan capture hasil-hasil running pro-
gramnya masing-masing dari VS!

129
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

8. Buatlah main project dengan nama “VSCudaKel-[..]-Kelas-[..]”, lalu


didalam project terdapat folder, misal “03_Vector_n_MatrixCL”,
yang didalamnya terdapat beberapa project yang terdiri dari:
– 01findMinArrayCL
– 02findMaxArrayCL
Dan capture hasil hasil running programnya masing-masing dari
VS! Petunjuk: Buatlah project “01findMinArrayCL dan
02findMaxArrayCL” tersebut dengan memodifikasi dari kode
program “Pairwise Sum” dengan OpenCL.
9. Jelaskan konsep thread (tid) pada bagian kode MyFirstGPU_SIMD
__kernel void IntroCL_SIMD_FnMyFirstGPU(__global int *Host_A,__global int *device_tid) {
// Get the index of the current element to be processed
int blockDim_x = get_local_size(0); //blockDim.x;
int blockIdx_x = get_group_id(0); //blockIdx.x;
int threadIdx_x = get_local_id(0); //threadIdx.x;

int tid = blockDim_x*blockIdx_x + threadIdx_x; // = get_global_id(0);


//int i = get_global_id(0);

// Do the operation
// get_local_size(0)*get_group_id(0) + get_local_id(0)
if (tid < 3){
device_tid[tid] = tid;
}else{
device_tid[tid] = -1;
}
*Host_A = get_local_size(0)*get_group_id(0) + get_local_id(0);
}

Dan apakah setiap kali dijalankan hasil “printf("\n Hasil Host_A


Setelah Masuk di FnMyFirstGPU = %d \n", Host_A); ” selalu sama
atau berbeda? Kenapa?
10. Jika pada bagian kode MyFirstGPU_SIMD OpenCL diubah menjadi
berikut:
Pada OpenCLFile.cl
device_tid[tid] = tid;

Jika diubah menjadi:

if (tid < 5){


device_tid[tid] = tid;
}else{
device_tid[tid] = -1;
}

Bagaimana hasil yang didapatkan? Jelaskan!


11. Jika pada bagian kode MyFirstGPU_SIMD OpenCL diubah menjadi
berikut:
Pada
printf("\n tid = %d", device_tid[i]);

Jika diubah menjadi:

if (device_tid[i]>=0){
printf("\n tid = %d", device_tid[i]);
}

Bagaimana hasil yang didapatkan? Jelaskan!

130
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

12. Buatlah main project dengan nama “VSCudaKel-[..]-Kelas-[..]”,


lalu di dalamnya project terdapat folder, misal dengan nama
“03_Vector_n_MatrixCL”, yang didalamnya terdapat beberapa
project kecil sekaligus, minimal project tersebut terdiri dari:
- Penjumlahan Matriks
- Perkalian Matriks
- Transpose Matriks
- Invers Matriks
Dan capture hasil running programnya masing-masing dari VS!
----------dengan CUDA atau dengan OpenCL----------
13. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk
mendapatkan hasil manipulasi pada matriks berikut:

Ketika k=3, maka lakukan penambahan tepian matrik sebanyak


floor(k/2) = 1, dengan nilai tepian yang direplika, dimana nilai k
bilangan ganjil ≥ 3
14. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk
mendapatkan hasil manipulasi pada matriks berikut:

Ketika k=5, maka lakukan penambahan tepian matrik sebanyak


floor(k/2) = 2, dengan nilai tepian yang direplika, dimana nilai k
bilangan ganjil ≥ 3

131
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

15. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk


mendapatkan hasil manipulasi pada matriks berikut:

Pada hasil manipulasi dengan k=3 diatas, lakukan penghitungan


rata-rata disekeliling nilai elemen matriks yang berwarna merah
12 , dengan ketentuan seperti berikut:

16. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk


mendapatkan hasil manipulasi pada matriks berikut:

Pada hasil manipulasi dengan k=5 diatas, lakukan penghitungan


rata-rata disekeliling nilai elemen matriks yang berwarna merah
12 , dengan ketentuan seperti berikut:

132
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

17. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk


mendapatkan hasil transpose pada matriks yang bukan persegi
dgn ordo 5x3 berikut:

18. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk


mendapatkan hasil perkalian pada matriks yang bukan persegi dgn
ordo A5x2 dengan B2x3:

19. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk


mendapatkan hasil sorting pada array A dan B berikut:

20. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk


mendapatkan hasil frekuensi (kemunculan data) dari array atau
matriks A dan B berikut:
float A[N]={15, 2, 0, 1, 1, 8, 2, 6, 0, 15, 1, 2, 0, 0};
float B[N-1]={15, 2, 0, 1, 1, 8, 2, 6, 0, 15, 1, 2, 8};

a. Buat koding di GPU untuk mendapatkan uniqueElement-nya,


lalu Sorting, lalu
b. Buat koding counter di GPU untuk menghitung frekuensi/
kemunculan elemen dari Array
21. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk
mendapatkan hasil distance pada vector A dan B berikut, dengan
Manhattan atau Euclidean Distance:

133
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

22. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk


mendapatkan hasil titik terdekat (closest pair) dari data point (x,y)
random bebas, dengan Euclidean Dist.:

----------dengan PyCUDA atau dengan PyOpenCL----------


23. Buatkan Program untuk Operasi Vector berikut
a. Penjumlahan
b. Pairwise Sum
c. dot Product
d. Fin Min
e. Fin Max
24. Buatkan Program untuk Operasi matrik berikut
a. Penjumlahan
b. Transpose
c. Perkalian
d. Invers

134
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 4 Race Conditions dan


Atomic Function

4.1 Race Conditions


Race condition terjadi ketika 2 atau lebih thread mencoba men-
gubah nilai pada alamat di shared atau global memori secara bersama-
sama pada waktu yang bersamaan. Misal terdapat dua thread, A dan
B, yang ingin di-increment nilainya pada alamat memori M dengan
menambahkan angka 1. Misal M sudah mengandung nilai 7. Karena
algoritma penjadwalan thread dapat bertukar antar untaian secara
acak, urutan di mana thread akan mencoba mengakses M tidak
diketahui oleh pemrogram.
Jika A dan B keduanya ingin meng-increment nilai pada M secara
bersamaan, maka setiap thread akan membaca nilai sebagai langkah
pertama (A dan B membaca nilai 7). Setelah itu ditambahkan nilai 1,
kedua thread akan menulis 8 ke dalam alamat memori M, yang
akhirnya mengarah pada hasil yang tidak benar.
Karena dijalankan paralel (dalam waktu yang bersamaan)
thread A = 7 + 1
kedua thread akan menulis 8 ke dalam M
thread B = 7 + 1
Seharusnya (serial, dari thread A lalu thread B atau sebaliknya)
thread A = 7 + 1 = 8  tulis ke M, lalu M dibaca thread B = 8 + 1 = 9 tulis ke M

karena nilai 7, seharusnya telah ditingkatkan dua kali (sekali


oleh setiap thread), tetapi ternyata hanya meningkat sekali. Dengan
kata lain, hasil dari perubahan data tergantung pada algoritma
penjadwalan thread, yaitu kedua thread tersebut “berlomba” untuk
mengakses dan mengubah data dalam waktu yang sama.
Race condition adalah komputasi yang berisiko melakukan
kesalahan atau kecerobohan dalam perhitungan karena terlalu cepat
dan singkatnya waktu yang dialokasikan dalam melakukan proses
perhitungan. Sehingga justru malah berisiko karena menghasilkan
kesalahan dalam solusi akhirnya, kondisi tersebut muncul ketika hasil
program bergantung pada waktu kejadian yang tidak dapat
dikendalikan, seperti urutan atau untaian eksekusi yang semuanya
seolah-olah sudah dilalui namun hanya sebagian yang benar-benar
diekseksi dengan sempurna. Solusi: Operasi Atomic dan locks adalah

135
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

metode brute force yang digunakan untuk mem-fix-kan race


conditions sehingga hasil akhirnya bisa sesuai. Misal int *x diset
sebagai global memory. Maka jika dilakukan eksekusi terhadap *x++
yang terjadi adalah 3 step berikut:
- Read nilai dalam *x untuk dimasukkan ke dalam suatu register
- Add 1 ke nilai yang telah dibaca (Read) dari langkah ke-1
- Write hasil, kembali ke *x
Jika kita ingin parallelkan threads A dan B, keduanya melakukan
increment *x, maka kita butuh proses, misal seperti berikut:
- Thread A reads nilai 7 dari *x
- Thread A add 1 terhadap nilai 7 tadi, sehingga menjadi 8
- Thread A write nilai 8 tersebut, lalu return ke *x
- Thread B reads nilai 8 dari *x
- Thread B add 1 terhadap nilai 8 tadi, sehingga menjadi 9
- Thread B write nilai 9 tersebut, lalu return ke *x
Link kode Race Conditions, silahkan download dari link
“https://drive.google.com/file/d/1Agf2yuCK9CEM33W4WgZeUKb0Ra
pUut5c/view?usp=sharing”

136
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

4.2 Atomic Function


AtomicAdd Function
- Link kode Race Condition:
“https://drive.google.com/file/d/1ZvSaCrZnTjM75y96veB5T3Zgcw
rU9ZoM/view?usp=sharing”
__global__ void FnMyRaceConditionGPU(float *device_a)
{
int tid1 = blockDim.x;
int tid2 = blockIdx.x;
int tid3 = threadIdx.x;
//printf("\n blockDim.x = %d", tid1);
//printf("\n blockIdx.x = %d", tid2);
//printf("\n threadIdx.x = %d", tid3);
//int tid = blockDim.x*blockIdx.x + threadIdx.x;
//printf("\n blockDim.x*blockIdx.x + threadIdx.x = %d*%d + %d =
%d", tid1, tid2, tid3, tid);
int tid = blockDim.x*blockIdx.x + threadIdx.x;
printf("\n blockDim.x*blockIdx.x + threadIdx.x = %d*%d + %d =
%d", tid1, tid2, tid3, tid);
// d...ds.dsa..saf.saf.as
*device_a += 1;
}

Pada kode di atas, coba ubah baris kode


“ *device_a += 1; ” menjadi
“ atomicAdd(device_a, 1); “ untuk mem-fix-kan Race
Condition pada kode race_condition.cu

Hasil Running:

Dari kode di atas, kita mendapatkan jawaban yang benar, tetapi


waktu eksekusinya lebih lambat karena memaksa thread untuk
mengeksekusi secara berurutan dengan atomicAdd.

137
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Dengan versi CUDA 2.0 atau yang lebih tinggi, kita bisa
menggunakan:
o old = atomicAdd(&addr, value); // old = *addr; *addr += value
o old = atomicSub(&addr, value); // old = *addr; *addr –= value
o old = atomicExch(&addr, value); // old = *addr; *addr = value
o old = atomicMin(&addr, value); // old = *addr; *addr = min( old, value )
o old = atomicMax(&addr, value); // old = *addr; *addr = max( old, value )
// Increment naikkan sampai ke nilai value, kemudian reset menjadi 0
// Decrement turunkan sampai ke nilai 0, kemudian reset menjadi value
o old = atomicInc(&addr, value); // old = *addr; *addr = ((old >= value) ? 0 :
old+1 )
o old = atomicDec(&addr, value); // old = *addr; *addr = ((old == 0) or (old >
val) ? val : old–1)
o old = atomicAnd(&addr, value); // old = *addr; *addr &= value
o old = atomicOr(&addr, value); // old = *addr; *addr |= value
o old = atomicXor(&addr, value); // old = *addr; *addr ^= value
// Compare-And-Store atau Compare-And-Swap
o old = atomicCAS(&addr, compare, value); // old = *addr; *addr = ((old ==
compare) ? value : old)

- Beberapa hasil Running dari project Atomic pada VS dengan cara


Klik kanan project, lalu Pilih Debug>Start new instance:

138
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Berikut adalah contoh beberapa Atomic yang dikembangkan untuk


melakukan komputasi pada hal lain yang lebih luas:
o atomicAddToHistogram, link kode
“https://drive.google.com/file/d/1sUkEAPYf6oMPnAdPqS7j-
R9fvzrQ6WlB/view?usp=sharing”
Contoh (sebagai ilustrasi konsep Histogram):

(a) Data matriks (b) Histogram (Kemunculan data matriks)

o dot product dengan operasi Atomic, project “030AtomicDotProductBuiltIn” link


kode “https://drive.google.com/drive/folders/1wU3sjAyCX4dlVop-
9U2uqb9WQiqRveV8?usp=sharing”
(Contoh ilustrasi konsep dot product ada di materi sebelumnya)

4.3 Locks dan Mutex


Lock adalah suatu mekanisme dalam komputasi paralel yang
memaksa keseluruhan segmen kode untuk dijalankan secara Atomic.
Sedangkan Mutex atau “Mutual Exclusion” merupakan prinsip dibalik
konsep Lock, artinya selama thread menjalankan kode di dalam Lock,
maka itu akan menutup semua thread-thread lainnya keluar dari Lock.
Contoh bagian kodenya:
__global__ void FnMyKernelGPU(void){
Lock myLock;

//kode paralel
myLock.lock();
//kode sequential
myLock.unlock();
//kode paralel
}

139
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ilustrasi tentang konsep Lock dan UnLock:

Link kode Lock dan UnLock dan blockCounter1:


“https://drive.google.com/drive/folders/1VMxEjtQnAsE_Ep0pYwI
bAk3rQL02X0gn?usp=sharing”

Link kode Lock dan UnLock dan blockCounter2:


“https://drive.google.com/drive/folders/1V8Yez0md9ssojE81daL
qz67VXvI8B1da?usp=sharing”

140
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Dengan kernel blockCounter2 berikut, tidak dapat berhenti, kira"


kenapa? ini karena Warps
__global__ void blockCounter2(Lock lock, float *nblocks){
lock.lock();
if (threadIdx.x == 0){ // masuk pada proses sequential
*nblocks = *nblocks + 1; // masuk pada proses sequential
} // masuk pada proses sequential
lock.unlock();
}

Kernel di atas akan menghasilkan kondisi divergen (tidak dapat


berhenti atau keluar dari kernel), jangan menggunakan kernel
tersebut.

4.4 Warps, Warps dan Locks


Warps adalah suatu group dari "32 threads" di block yang sama
yang dijalankan dengan konsep Lock pada setiap langkahnya
(lockstep).
o Artinya, mereka melakukan sinkronisasi setelah setiap
langkah (seperti syncthreads() yang dipanggil dengan
sesering mungkin).
o Dan semua block dipartisi ke dalam warps.
- Ilustrasi Thread-Thread dalam warp yang sama:

141
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Ilustrasi Thread-Thread dalam warp-warp yang berbeda (1 of 2):

- Ilustrasi Thread-Thread dalam warp-warp yang berbeda (2 of 2):

- Ilustrasi Thread-Thread dalam warp yang sama:

142
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

4.5 Tugas Kelompok


----------dengan CUDA atau dengan OpenCL----------
1. Buatlah koding di GPU (dengan CUDA atau OpenCL) untuk
mendapatkan hasil sorting pada array A dan B berikut dengan me-
manfaatkan AtomicMin atau AtomicMax Function!

2. Pada kode program “030AtomicDotProductBuiltIn”, modifikasi


bagian baris kode
for (int i = 0; i<N; i++) {
a[i] = i;
b[i] = i * 2;
}

menjadi

srand(time(NULL));
float Batas_Bawah = 10.0, Batas_Atas = 100.0;
for (int i = 0; i < N; i++){
// random fix 0 angka dibelakang koma dengan nilai
[0,1,2,..,9]
a[i] = (float)(((int)(((float)rand() /
(float)RAND_MAX) * 10)) / 1.0);
b[i] = (float)(((int)(((float)rand() /
(float)RAND_MAX) * 10)) / 1.0);
}

Dan ubah “#define sum_squares(x) (x*(x+1)*(2*x+1)/6) ” menjadi


fungsi di CPU untuk menghitung dot Product.

143
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3. Pada kode program “030AtomicDotProductBuiltIn”, lakukan


tracking bagian baris kode berikut
__global__ void dot(float *a, float *b, float *c) {
__shared__ float cache[threadsPerBlock];
int tid = threadIdx.x + blockIdx.x * blockDim.x;
int cacheIndex = threadIdx.x;
float temp = 0;
while (tid < N) {
temp += a[tid] * b[tid];
tid += blockDim.x * gridDim.x;
}
// men-set cache values
cache[cacheIndex] = temp;
// synchronize threads dalam block ini
__syncthreads();
// untuk melakukan reduksi, threadsPerBlock harus merupakan
pangkat dari 2
// karena mengikuti kode berikut
int i = blockDim.x / 2;
while (i != 0) {
if (cacheIndex < i)
cache[cacheIndex] += cache[cacheIndex + i];
__syncthreads();
i /= 2;
}
// disini kita menggunakan atomic addition:
if (cacheIndex == 0) {
atomicAdd(c, cache[0]);
}
}

dengan “printf” untuk mengetahui detail setiap prosesnya, cap-


ture lalu jelaskan!
4. Pada kode “Lock dan UnLock dan blockCounter2”, jelaskan setiap
baris kode pada kernel berikut
__global__ void blockCounter2(Lock lock, float *nblocks){
lock.lock();
if (threadIdx.x == 0){ // masuk pada proses sequential
*nblocks = *nblocks + 1; // masuk pada proses sequential
} // masuk pada proses sequential
lock.unlock();
}

Kernel di atas akan menghasilkan kondisi divergen (tidak dapat


berhenti atau keluar dari kernel). Jelaskan kenapa bisa terjadi hal
demikian (jelaskan secara detail dengan menghubungkan ter-
hadap konsep Warps)!

144
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 5 Artificial Intelligence


dengan GPU

5.1 Artificial Intelligence (AI)


Artificial Intelligent (AI) atau Kecerdasan Buatan adalah teknik
yang menjadikan komputer dapat berpikir secerdas atau melampaui
kecerdasan manusia. Tujuannya agar komputer memiliki kemampuan
berperilaku, berpikir, dan mengambil keputusan layaknya manusia.
Berikut beberapa pengertian dari AI dari berbagai sumber.
o Otomasi aktivitas yang berhubungan dengan proses berpikir,
pemecahan masalah dan pembelajaran
(Bellman, 1978).
o Studi tentang kemampuan mengindera dengan menggunakan
model komputasi (Charniak & McDermott, 1985).
o Studi bagaimana cara melakukan sesuatu sehingga menjadi lebih
baik (Rich & Knight, 1991)
o Cabang dari ilmu komputer yang fokus pada otomasi perilaku yang
cerdas (Luger & Stubblefield,1993).

Copy kecerdasan dengan koding,


misal pakai CUDA/OpenCL/etc

manusia mesin
(a) Map AI dan ML
(b) Transfer kecerdasan Manusia ke Mesin

Gambar 5.1 Ilustrasi Map AI dan ML, serta Transfer AI

145
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

5.2 Machine Learning dan Teknik


Optimasi
Machine Learning (ML) atau Mesin Pembelajar adalah cabang
dari AI yang fokus belajar dari data (learn from data), yaitu fokus pada
pengembangan sistem yang mampu belajar secara “mandiri" tanpa
harus berulang kali diprogram manusia. ML membutuhkan Data yang
valid sebagai bahan belajar (ketika proses training) sebelum digunakan
ketika testing untuk hasil output yang optimal.

Gambar 5.2 Map cakupan dari Machine Learning


Hasil pengembangan produk bernasis AI (Machine Learning dan
Teknik Optimasi, etc) ini harapnnya dapat lebih memberikan
kemudahan dan langsung dapat diterapkan di masyarakat luas atau
bahkan masuk ke industri dalam skala nasional dan internasional.
Berikut ilustrasi Map produk untuk apply ke masyarakat.

Gambar 5.3 Map pengembangan produk App

146
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

5.2.1 Clustering: K-Means


Ketika orang berpikir tentang algoritme K-means, mereka
biasanya memikirkan algoritme yang biasanya dikaitkan dengan Lloyd
dari sebuah dokumen pada tahun 1957, meskipun tidak dipublikasikan
sampai tahun 1982. K-means clustering merupakan metode
pengolahan data clustering non-hirarki yang mengelompokan data
dalam bentuk satu atau lebih cluster (kelompok) berdasarkan
karakteristik yang sama atau mirip dikelompokan dalam satu cluster
dan jika berbeda akan masuk pada kelompok yang berbeda.

Gambar 5.4 Konsep Non-Hierarchical Clustering


Langkah-langkah melakukan clustering dengan metode k-means
adalah sebagai berikut:
1. Tentukan jumlah cluster k.
2. Inisialisasi k pusat cluster ini bisa dilakukan dengan berbagai
cara. Namun yang paling sering dilakukan adalah dengan cara
random (acak).
3. Alokasikan semua data atau obyek ke cluster terdekat
berdasarkan jarak kedua obyek tersebut (jarak Euclidean) yang
ditunjukan oleh persamaan 3.1 berikut:

D xi , x j   x  x j1   xi 2  x j 2   ..  xid  x jd 


2 2 2
i1

4. Hitung kembali pusat cluster dengan keanggotaan cluster yang


sekarang menggunakan persamaan 3.2 berikut:

147
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

mi mi
1 1
Ci1 
mi
 x j1 ....... Cid 
j 1 mi
x
j 1
jd

5. Jika pusat cluster tidak berubah lagi maka proses clustering


selesai atau kembali ke langkah nomor 3 sampai pusat cluster
tidak berubah.
Kode program algoritme K-means dengan menggunakan CUDA
dapat di-download dari link “http://bit.ly/2JoNYw9” atau dari
“https://drive.google.com/drive/folders/1EQgE8OlvKFgyD5tONxqWaTc5POi9FfXk?usp=sharing”.
- Spesifikasi kode program di atas
Di dalam file dari link di atas terdapat 2 macam kode program, yaitu menggunakan CPU
(tanpa proses komputasi paralel) dan GPU CUDA (dengan proses komputasi paralel).

File kmeans.c merupakan koding di CPU, dengan K=3:


Clustering data 2-dimensi (x,y) yang bersifat naive (diasumsikan antar fitur data tidak
saling berhubungan atau berkorelasi signifikan), dengan algoritma Lloyd's K-means

File koding K-Means CUDA dengan K=3: gpu_kmeans.cu: Implementasi algoritma diatas
dgn komputasi paralel

File titik data (x,y) yang digunakan: x.txt: koordinat x sebagai fitur ke-1, dan y.txt:
koordinat y sebagai fitur ke-2

File titik pusat cluster awal sebagai inisialisasi (mu_x,mu_y)={(-10,10), (0,0 ), (10,-10)}:
mu_x.txt: pusat cluster awal dari x, dan mu_y.txt: pusat cluster awal dari y

File titik pusat cluster awal sebagai inisialisasi (mu_x_out, mu_y_out):


mu_x_out.txt: pusat cluster akhir dari x, dan mu_y_out.txt: pusat cluster akhir dari y

File group_out.txt, menampung id keanggotaan cluster

- Tampilan visualisasi data

148
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

5.2.2 Teknik Optimasi: Particle Swarm


Optimization (PSO)
Teknik Optimasi adalah cara menyelesaiakan permasalahan
yang sulit sekali untuk dimodelkan dalam bentuk matematika, dan jika
dibuat model persamaan matematikanya akan membutuhkan waktu
yang lama. Beberapa keilmuan dalam teknik optimasi:
- Swarm Intelligence (misal PSO)
- Algoritma Evolusi (misal GA)

Gambar 5.5 Ilustrasi Pergerakan Partikel PSO


Sistem alami merupakan segala mekanisme baik implisit
maupun eksplisit yang berhubungan dengan swarm dan secara natural
ada, sedangakan sistem buatan adalah membuat sintesis atau
penyederhanaan yang bisa jadi menjadi cukup kompleks dalam bentuk
model matematika untuk mengenali tingkah laku dari swarm
intelligence dari mekanisme yang ada di alam yang lebih banyak ke
arah eksplisitnya (Cholissodin dan Riyandani, 2016).

procedure AlgoritmaPSO
begin
t = 0
𝑡 𝑡 𝑡 𝑡
inisialisasi posisi partikel(𝑥𝑖,𝑗 ), kecepatan(𝑣𝑖,𝑗 ), 𝑃𝑏𝑒𝑠𝑡𝑖,𝑗 = 𝑥𝑖,𝑗 ,
𝑡
hitung fitness tiap partikel, dan 𝐺𝑏𝑒𝑠𝑡𝑔,𝑗
do
t = t + 1
update kecepatan v (t)
i,j
update posisi x (t)
i,j
hitung fitness tiap partikel
update Pbest (t) dan Gbest (t)
i,j g,j
while (bukan kondisi berhenti)
end

Gambar 5.6 Pseudocode Struktur Umum Algoritma PSO

149
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Untuk memperjelas pemahaman tentang PSO, maka diberikan


contoh sederhana masalah maksimasi (yaitu mencari nilai x1 dan x2
yang optimal sehingga bisa memaksimalkan nilai f(x1,x2)) dari sebuah
fungsi sebagai berikut:
max, f(x1,x2) = 19 + x1sin(x1π) + (10 – x2) sin(x2π),
-5,0 ≤ x1 ≤ 9,8 0,0 ≤ x2 ≤ 7,3
Plotting dua dimensi dari fungsi diatas ditunjukkan pada Gambar
dibawah ini. Warna putih menunjukkan nilai fungsi yang lebih besar.
Perhatikan bahwa fungsi ini mempunyai banyak nilai maksimum lokal.

Gambar 5.7 Plotting 2D Contoh Fungsi

5.2.2.1 Representasi Partikel


Dalam kasus ini variabel keputusan (x1 dan x2) langsung menjadi
dimensi pada partikel, sehingga panjang dimensi partikel adalah 2. Da-
lam siklus Real-Code algoritma Particle Swarm Optimization terdapat
beberapa proses sebagai berikut:
1. Inisialisasi
- Inisialisasi Kecepatan Awal
- Inisialisasi Posisi awal Partikel
- Inisialisasi Pbest dan Gbest
2. Update Kecepatan
3. Update Posisi dan Hitung Fitness (Seperti pada algoritma evolusi,
fungsi objektif mengukur seberapa dekat solusi dengan optimum,
contohnya fungsi objektif mengukur performansi atau kualitas
partikel, dalam hal ini adalah f(x1,x2))
4. Update Pbest dan Gbest

150
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

5.2.2.2 Inisialisasi
1. Inisialisasi Kecepatan Awal Partikel
Pada iterasi ke-0 (t=0), dapat dipastikan bahwa nilai kecepatan
awal semua partikel di (vi,j(t)=0) dan misal kecepatan partikelnya
sebagai berikut:
popSize=10, max, f(x1,x2) = 19 + x1sin(x1π) + (10 – x2) sin(x2π),
-5,0 ≤ x1 ≤ 9,8 0,0 ≤ x2 ≤ 7,3

2. Inisialisasi Posisi awal Partikel


Partikel inisial, yaitu pada iterasi ke-0 (t=0) dibangkitkan secara
random dengan persamaan. x = xmin + rand[0,1]*(xmax-xmin), dan
misal dihasilkan populasi sebagai berikut:
popSize=10, max, f(x1,x2) = 19 + x1sin(x1π) + (10 – x2) sin(x2π),
-5,0 ≤ x1 ≤ 9,8 0,0 ≤ x2 ≤ 7,3

3. Inisialisasi Pbest dan Gbest


Pbest, karena masih iterasi ke-0 (t=0), maka nilai Pbest akan
disamakan dengan nilai posisi awal partikel, yaitu (Pbesti,j(t)=xi,j(t))
dan misal Pbest-nya sebagai berikut:

151
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

popSize=10, max, f(x1,x2) = 19 + x1sin(x1π) + (10 – x2) sin(x2π),


-5,0 ≤ x1 ≤ 9,8 0,0 ≤ x2 ≤ 7,3

Gbest, memilih satu Pbest yang fitness-nya tertinggi, (k=argMaxi {


fitnessPbesti,j(t) }=2), maka Gbestg=1,j(t=0)=Pbestk=2,j(t=0).
Masuk pada iterasi ke-1, (t = t +1 = 0 + 1 = 1)

5.2.2.3 Update Kecepatan


Dalam implementasi PSO, terkadang ditemukan bahwa ke-
cepatan partikel bergerak ke nilai yang besar dengan cepat, terutama
untuk posisi partikel yang jauh dari posisi tetangga dan individu ter-
baik. Akibatnya, partikel tersebut memiliki kecenderungan untuk
meninggalkan (keluar) dari ruang batas pencarian atau posisi baru
partikel berada di luar range solusi. Oleh karena itu, untuk mengontrol
eksplorasi global partikel, perlu adanya pembatasan kecepatan mini-
mum dan maksimum. Teknik pembatasan ini disebut velocity clamping
untuk mencegah partikel bergerak terlalu jauh melampaui ruang pen-
cariannya.
Batasan lower dan upper kecepatan yang digunakan dalam
proses ini berdasarkan nilai minimum dan maksimum pada setiap
dimensi dari representasi solusi partikel ( xmind dan xmaxd ), dimana d
menyatakan dimensi, atau bisa dituliskan xi,j=[xminj ; xmaxj]
Diketahui nilai lower dan upper pada x1, maka jika dibentuk
intervalnya menjadi xi,j=1=[xmin1 ; xmax1]=[-5 ; 9,8], xi,2=[xmin2 ;
xmax2]=[0 ; 7,3], dimana vminj=-vmaxj dan

v max j  k
x max j  x min j 
k  0,1 (Marini & Walczak, 2015)
2

152
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

misal k= 0,6 maka

v max j 1  0,6
9,8   5  4,44 v max 2  0,6
7,3  0  2,19
2 2
sehingga untuk vi,j=1=[vmin1 ; vmax1] = [-4,44 ; 4,44] dan
vi,j=2=[vmin2 ; vmax2] = [-2,19 ; 2,19]
Dalam menentukan interval pada langkah sebelumnya, baik
untuk posisi maupun kecepatan partikel untuk setiap dimensi,
sebaiknya dilakukan pada proses inisialisai. Batasan kecepatan atau
threshold yang digunakan adalah sebagai berikut (Marini & Walczak,
2015):
jika vijt 1  v max j maka vijt 1  v max j
jika vijt 1  v max j maka vijt 1  v max j

Jika diketahui xi,1 = [xmin1 ; xmax1] = [-5 ; 9,8], xi,2 = [xmin2 ; xmax2] = [0
; 7,3], serta telah didapatkan vi,1 = [-4,44 ; 4,44] dan vi,2 = [-2,19 ; 2,19]
dan misalkan diketahui w = 0.5, c1 = 1, c2 = 1, r1 = rand[0,1], dan r2 =
rand[0,1]. Dimana r1 dan r2 adalah bilangan acak dalam interval [0, 1].
Maka untuk mendapatkan hasil update kecepatannya dihitung sebagai
berikut, misal menghitung v1,1(1).

  
vit,j1  w.vit, j  c1.r1 Pbestit, j  xit, j  c2 .r2 Gbestgt , j  xit, j 

  
v10,11  w.v10,1  c1.r1 Pbest10,1  x10,1  c2 .r2 Gbest10,1  x10,1 
 0.50   10.11.4898  1.4898   10.4 8.4917  1.4898 
 0  0  2.8001  2.8001

Berikut keseluruhan hasil update kecepatannya:


  
v10,11  w.v10,1  c1.r1 Pbest10,1  x10,1  c2 .r2 Gbest10,1  x10,1 
 0.50   10.11.4898  1.4898   10.4 8.4917  1.4898 
 0  0  2.8001  2.8001

153
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

5.2.2.4 Update Posisi dan Hitung Fitness


1. Update posisi dihitung sebagai berikut, misal hitung x1,1(1).

xit,j1  xit, j  vit,j1


x10,11  x10,1  v10,11  1.4898  2.80076  4.2906

x = [xmin ; xmax ] = [-5 ; 9,8]


i,1 1 1
x = [xmin ; xmax ] = [0 ; 7,3]
i,2 2 2

2. Berikut keseluruhan hasil update posisinya:

partikel

j=1 j=2 f(x1,x2)

4.2906 2.2868 28.4696


x1(1)
8.4917 2.5754 34.7023
x2(1)
4.2399 4.8123 24.7773
x3(1)
6.8835 4.0769 22.8537
x4(1)
2.2890 2.0560 22.2186
x5(1)
5.8090 3.6915 10.5710
x6(1)
3.2986 2.8146 20.2634
x7(1)

154
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.5612 1.4611 16.9525


x8(1)
9.0591 5.0453 16.4912
x9(1)
-0.1175 1.1309 15.4854
x10(1)

5.2.2.5 Update Pbest dan Gbest


1. Update Pbest, disini kita harus membandingkan antara Pbest
pada iterasi sebelumnya dengan hasil dari Update Posisi.

Pbest partikel

j=1 j=2 f(x1,x2) j=1 j= j=2 f(x1,x2)

Pbest1(0) 1,4898 2,0944 19,8206 x1(1) 4.2906 2.2868 28.4696

Pbest2(0) 8,4917 2,5754 34,7058 x2(1) 8.4917 2.5754 34.7023

Pbest3(0) 1,4054 6,3035 20,6707 x3(1) 4.2399 4.8123 24.7773

Pbest4(0) 5,8114 5,0779 14,5624 x4(1) 6.8835 4.0769 22.8537

Pbest5(0) -1,8461 1,7097 11,5858 x5(1) 2.2890 2.0560 22.2186

Pbest6(0) 4,0206 4,4355 24,7106 x6(1) 5.8090 3.6915 10.5710

Pbest7(0) -0,1634 2,974 19,653 x7(1) 3.2986 2.8146 20.2634

Pbest8(0) 5,2742 0,7183 22,1813 x8(1) 6.5612 1.4611 16.9525

Pbest9(0) 9,4374 6,6919 12,4694 x9(1) 9.0591 5.0453 16.4912

Pbest10(0) -4,5575 0,1679 28,4324 x10(1) -0.1175 1.1309 15.4854

2. Dari 2 tabel di atas, cek dari urutan baris yang sama, kemudian
dibandingkan fitness-nya, manakah yang lebih tinggi nilainya
akan menjadi Pbest terbaru.

Pbest

j=1 j=2 f(x1,x2)

Pbest1(1) 4.2906 2.2868 28.4696

155
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Pbest2(1) 8,4917 2,5754 34,7058

Pbest3(1) 4.2399 4.8123 24.7773

Pbest4(1) 6.8835 4.0769 22.8537

Pbest5(1) 2.2890 2.0560 22.2186

Pbest6(1) 4,0206 4,4355 24,7106

Pbest7(1) 3.2986 2.8146 20.2634

Pbest8(1) 5,2742 0,7183 22,1813

Pbest9(1) 9.0591 5.0453 16.4912

Pbest10(1) -4,5575 0,1679 28,4324

3. Dan Pbest terbaru dengan nilai fitness tertinggi akan menjadi


Gbest.

Gbest

j=1 j=2 f(x1,x2)

Gbest1(1) 8,4917 2,5754 34,7058

4. Dan Pbest terbaru dengan nilai fitness tertinggi akan menjadi


Gbest.

Gbest

j=1 j=2 f(x1,x2)

Gbest1(1) 8,4917 2,5754 34,7058

5. Kemudian, jika dilanjutkan iterasi berikutnya (t = t + 1), maka


langkah di bawah ini akan diulang terus-menerus sampai iterasi
Maksimum atau telah mencapai konvergen.
1. Update Kecepatan
2. Update Posisi dan Hitung Fitness
3. Update Pbest dan Gbest

156
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Kode program algoritme PSO dengan menggunakan CUDA


dapat di-download dari link “http://bit.ly/2Jv2ceL”.
- Spesifikasi kode program di atas
File main.cpp merupakan kode utama untuk menjalankan semua fungsi yang ada, baik PSO
CPU maupun PSO GPU untuk perbandingan kinerja Koding CUDA dan CPU untuk PSO
pada fungsi Retribusi (Levy function) 3 dimensi, untuk mencari nilai optimal (x1, x2, x3)
sebagai test case (d=3), dgn xi = [xmin=-5.12f;xmax=5.12f]
------------- penulisan (x1, x 2, x3) kalau dikoding indeksnya dimulai dari 0, sehingga menjadi
 (x0, x1, x2)

File koding PSO CUDA, dgn nama mykernel.cu: Implementasi PSO yang dijalankan secara
paralel dengan CUDA

File koding PSO CPU, dgn nama mykernel.cpp: Implementasi PSO yang dijalankan secara
iteratif tanpa CUDA

File header dgn nama mykernel.h: digunakan untuk set parameter PSO, juga untuk me-
manggil fungsi cuda_pso dari file mykernel.cu dan fungsi pso dari file mykernel.cpp

Link kode alternatif:


https://drive.google.com/drive/folders/1LMYnKf_fKNQaPrCHZ3eR_ChlJ-fkJthB

- Case Study yang digunakan adalah Levy function (ref:


https://www.sfu.ca/~ssurjano/levy.html), Minimalkan nilai
f(X={x1,x2,...xd}), d menyatakan banyaknya dimensi, xi = [xmin=-
10;xmax=10].

- Tampilan hasil running kode PSO (CPU & CUDA)

157
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

5.3 Tugas Kelompok


1. Dalam main project kelompok anda, misal “VSCudaCLKel-[..]-
Kelas-[..]”, didalamnya buat folder, misal
“009_MachineLearn_n_OptimasiCUKel[..]”, yang didalamnya
minimal terdapat project “01KmeansCU[..]” dengan set parameter
nreps atau iterasi = 100. Dan capture step by step hasil running
programnya dari VS, seperti pada contoh di slide, dan sertakan
kode programnya dalam tabel.
2. Dari soal no. 1, didalam folder
“009_MachineLearn_n_OptimasiCUKel[..]”, buat project dengan
nama “01KManhattanCUKel[..]”, “01KMaxCUKel[..]” dan
“01KaVgCUKel[..]”, ubah koding pada:
// deklarasi menghitung jarak euclidean pada GPU tanpa akar
__global__ void get_dst(float *dst, float *x, float *y,
float *mu_x, float *mu_y){
int i = blockIdx.x;
int j = threadIdx.x;

dst[I(i, j, blockDim.x)] = (x[i] - mu_x[j]) * (x[i] - mu_x[j]);


dst[I(i, j, blockDim.x)] += (y[i] - mu_y[j]) * (y[i] -
mu_y[j]);
}

menjadi koding menggunakan 2 rumus jarak berikut:


o Manhattan Distance
d
d m an ( x, y )   x j  y j
j 1

o Maximum Distance
d max ( x, y)  max x j  y j
j 1..d

o Average Distance
1
1 d 2
d ave ( x, y )    x j  y j  
2

 d j 1 
Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di-slide, dan sertakan kode programnya dalam tabel.

158
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3. Didalam folder “009_MachineLearn_n_OptimasiCUKel[..]”, buat


project dengan nama “10PSOCUKel[..]”, yang mengacu pada
koding PSO-CUDA, lalu ubah koding pada nilai
“NUM_OF_DIMENSIONS=2”, dan ubah “float
host_fitness_function(float x[])” dari file “mykernel.cpp” dan
“__device__ float fitness_function(float x[])” dari file
“mykernel.cu” menggunakan fungsi berikut berikut:
Maksimalkan nilai f(x1,x2)) dari sebuah fungsi
max, f(x1,x2) = 19 + x1sin(x1π) + (10 – x2) sin(x2π),
-5,12 ≤ x1 ≤ 5,12 dan -5,12 ≤ x2 ≤ 5,12

Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di-slide, dan sertakan kode programnya dalam tabel.

4. Dari soal no. 3, ubah juga pada koding x1min, x1max, x2min, x2max tiap
dimensinya, dimensi ke-1 (x1), dimensi ke-2 (x2). Dengan batas
berikut:
Maksimalkan nilai f(x1,x2)) dari sebuah fungsi
max, f(x1,x2) = 19 + x1sin(x1π) + (10 – x2) sin(x2π),
-5,0 ≤ x1 ≤ 9,8 dan 0,0 ≤ x2 ≤ 7,3

Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di-slide, dan sertakan kode programnya dalam tabel.

159
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 6 OpenGL dengan GPU

6.1 CUDA dan OpenGL


CUDA digunakan untuk calculation, data generation, image
manipulation. Sedangkan OpenGL digunakan untuk draw pixels atau
vertices pada screen. Interop is very fast! yaitu mampu melakukan
share data melalui common memory di dalam framebuffer. CUDA C
menggunakan familiar C memory management techniques (malloc,
pointers). OpenGL menyimpan data dalam abstract generic buffers
yang disebut dengan buffer objects. CUDA/ OpenGL interop
menggunakan konsep sederhana, yaitu Map/Unmap, suatu OpenGL
buffer di dalam memory space-nya CUDA. Berikut beberapa langkah
menggunakan Cuda OpenGL pada Cuda Kernel:
1. Membuat Vertex Buffer Object (VBO) kosong
2. Register VBO dengan Cuda
3. Map VBO selama writing dari Cuda
4. Jalankan Cuda kernel untuk memodifikasi posisi vertex
5. Unmap VBO
6. Render hasil menggunakan OpenGL

VBO adalah suatu memory buffer dengan high speed memory


dari video card yang didesain untuk meng-handle informasi tentang
vertices. Pada contoh VBOs, terdapat bagian yang mendeskripsikan
coordinate dari vertices dan atau plus color yang dihubungkan dengan
setiap vertex (Khronos, 2014).

160
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.1.1 Primitive Object (ex.: Segitiga)


- VBO membuat segitigacuda standar link “https://goo.gl/Oa7ELq”:
o Membuat fungsi “void createVBO”
void createVBO(GLuint *vbo, struct cudaGraphicsResource **vbo_res,
unsigned int vbo_res_flags)
{
assert(vbo);
// .. Vertices dari triangle
// .. Create buffer object
// .. Initialize buffer object
// .. Register buffer object dengan CUDA
checkCudaErrors(cudaGraphicsGLRegisterBuffer(vbo_res, *vbo,
vbo_res_flags));
SDK_CHECK_ERROR_GL();
}

assert(vbo) digunakan membantu mencetak bahwa program


telah berjalan dengan benar, dengan ekspresi yang hanya
mengevaluasi benar jika tidak terdapat kesalahan. Kita tidak
perlu menghapus statemen assert() dari kode sumber program
bila program telah dibetulkan.
o Membuat fungsi “void createVBO”  Vertices dari triangle
GLfloat data[] = {
0.0f, 1.0f, 0.0f, 1.0f,
-1.0f, -1.0f, 0.0f, 1.0f,
1.0f, -1.0f, 0.0f, 1.0f
};

Note:
GLint = int, dan GLuint = unsigned int
o Membuat fungsi “void createVBO”  Create buffer object
..
// Membuat new VBO dengan variable id untuk menyimpan VBO id
glGenBuffers(1, vbo);

// Membuat new VBO aktif


glBindBuffer(GL_ARRAY_BUFFER, *vbo); ..

o Initialize buffer object


..
// 3 menyatakan banyaknya titik, 4 banyak dimensi satu titik
unsigned int size = 3 * 4 * sizeof(float);

// Upload vertex data ke video device


glBufferData(GL_ARRAY_BUFFER, size, data, GL_STATIC_DRAW);

// Menggunakan buffer yang dibuat sebelumnya sebagai yang aktif


VBO.glBindBuffer(GL_ARRAY_BUFFER, *vbo); ..

161
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

o Initialize buffer object, pada “glBufferData(GL_ARRAY_BUFFER,


size, data, GL_STATIC_DRAW);”, Kapan menggunakan;
 GL_STATIC_DRAW: ketika isi data yang disimpan akan diubah sekali
dan digunakan berkali-kali.
 GL_DYNAMIC_DRAW: ketika isi data yang disimpan akan diubah
berulang kali dan digunakan berkali-kali.
 GL_STREAM_DRAW: ketika isi data yang disimpan akan diubah sekali
dan digunakan di hanya beberapa kali.

- VBO membuat segitigacuda gradasi (“3segitigaGradasiCuda”), link


“https://drive.google.com/drive/folders/1fwZ55KHZkvCMHrJycZWWEkVXEZVIzfKg?usp=sharing”
atau “http://bit.ly/2H2ElEM”.

6.1.2 Visualisasi Sine Wave


6.1.2.1 Konfigurasi CUDA + OpenGL
- Buat Folder Solution dengan nama “06_CudaOpenGL” dan di
dalamnya buat project NVIDIA CUDA dengan nama “0transObject”:

Location, misal di “E:\Data Kuliah\!Genap 2016-2017\2. Pemrograman


GPU\VSCuda\06_CudaOpenGL\”.

162
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Tampilan project NVIDIA CUDA dengan nama “0transObject”:

- Klik kanan project “0transObject”, Add New Item:

- Berikan nama file *.cu, misal “transObject”, lalu klik Add:

163
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Copykan isi file dari link “https://goo.gl/BDXXbD”, ke dalam file


“transObject.cu”:

- Klik kanan project “0transObject”, lalu pilih “Properties”:

164
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pastikan Platform “Active(x64)”, jika belum diset, klik


“Configuration Manager”:

- Pastikan Platform “Active(x64)”, jika belum diset, klik


“Configuration Manager”, Pilih x64:

165
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada Code Generation, klik , lalu klik <Edit...>:

- Isi Code Generation, Klik OK, Klik Apply:

compute_20,sm_20
compute_30,sm_30
compute_35,sm_35
compute_37,sm_37
compute_50,sm_50
compute_52,sm_52
compute_60,sm_60

- Pada Additi..Dep.., Klik , lalu klik <Edit...>:

166
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Replace isi pada Additi..Dep.., Klik OK, Klik Apply:

glew64.lib
cudart_static.lib
freeglut.lib
kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib

- Pada System, klik “Console (....” , ubah menjadi “Windows (...”,


Klik Apply, Klik OK:

167
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada bagian kode program di file “transObject.cu”, pada “#include


<GL/glew.h>”, setelah tanda “/” tekan tombol Control+Spasi
sampai muncul dir, misal “C:\Program Files(x86)\Windows
Kits\8.1\Include\um\gl”

- Copy semua isi file dari link “https://goo.gl/fbQjEy” ke “C:\Program


Files (x86)\Windows Kits\8.1\Include\um\gl”

168
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Copy semua isi file dari link “https://goo.gl/tMqNoV” ke


“C:\Program Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x64”

- Copy semua isi file dari link “https://goo.gl/xXZ5jP” ke “C:\Program


Files (x86)\Windows Kits\8.1\Lib\winv6.3\um\x86”

169
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Copy semua isi file dari link “https://goo.gl/O3tFxk” ke Pada folder


Debug, misal terdapat pada “..\VSCuda\x64\Debug” yang
menampung hasil compile setiap project menjadi file *.exe.

- Untuk 64bit: Copy semua isi file dari link “https://goo.gl/DSWJJS”


ke “C:\Windows\SysWOW64”

- Untuk 32bit: Copy semua isi file dari link “https://goo.gl/hnQg0d”


ke “C:\Windows\System32”

170
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Preview Visual Studio:

- Compile dari VS Klik kanan project, lalu Pilih Build:

- Tampilan hasil Build, jika sukses:

171
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Compile dari VS Klik kanan project, lalu Pilih Debug>Start new


instance:

- Hasil running transobject OpenGL dan CUDA

- Tampilan di folder Debug:

172
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.1.2.2 Set Icon CUDA + OpenGL


- Perhatikan, icon pada hasil compile belum diset:

- Berikut langkah-langkah untuk set icon pada hasil compile:


o Siapkan file *.ico, copykan pada folder project “0transObject”

o Misal nama file tersebut “favicon.ico”, lalu Klik kanan pada


folder project “0transObject”, klik New Item

173
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

o Buat file *.rc, misal “transObject.rc”. Klik Add

o Klik “Solution Explorer”

o Klik kanan file “transObject.rc”, klik “View Code”, klik Yes, hapus
semua kode di dalam file “transObject.rc”

Ketikkan: “GLUT_ICON ICON favicon.ico”,


Lalu simpan file tersebut

174
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Lakukan Rebuild lagi

- Compile dari VS Klik kanan project, lalu Pilih Debug>Start new


instance. Perhatikan, icon pada hasil compile sudah diset:

175
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.1.3 Ray Tracing


Ray tracing adalah suatu metode rendering untuk menghasilkan
efek gambar yang dibuat dalam lingkungan komputer 3D. Cara
kerjanya mengikuti jejak (tracing) suatu sinar (ray) dari suatu mata
imajiner setiap pixel di layar virtual dan mengakumulasi kontribusi
setiap sinar dalam scene di pixel tersebut. Intinya saat rendering,
komputer akan mencari informasi warna apa yang perlu dimunculkan
di suatu titik di layar (satu pixel) berdasarkan posisi kamera, objek, dan
sumber cahaya di scene 3D yang bersangkutan.

Gambar 6.1 Ilustrasi Ray Tracing


Berikut 2 contoh kode program Ray Tracing menggunakan
CUDA dan tampilan hasil running-nya.
- Ray Tracing 1 (0GPUPathTracing) Link: https://goo.gl/zp0gqt

- Ray Tracing 2 (1rayTracCudaTwo) Link: https://goo.gl/m24YkU

176
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.1.4 Game Asteroid 2D


- Koding dengan CPU, ke-1:
/* Update debu untuk tiap frame, terhadap kerlipan dan panjangnya.*/
// Koding dengan CPU
// -------------------------start Koding Update debu dengan CPU------------
---------------------
//for (int i = 0; i < MAX_DUST; i++) {
//if (dust[i].active) {
//if (dust[i].drawThisFrame) {
//dust[i].drawThisFrame = 0;
//dust[i].dustTimer = dust[i].dustTimer + 1;
//}
//else {
//dust[i].drawThisFrame = 1;
//dust[i].dustTimer = dust[i].dustTimer + 1;
//}
//if (dust[i].dustTimer > 6) {
//dust[i].active = 0;
//}
//}
//}
// -------------------------end Koding Update debu dengan CPU--------------
-------------------

- Koding dengan GPU, ke-1:


// Koding dengan CUDA
// -------------------------start Koding Update debu dengan GPU------------
---------------------
// copy host memory ke cuda memory
cudaMemcpy(cudaDust, dust, sizeof (Asteroid)* MAX_DUST,
cudaMemcpyHostToDevice);
int gridDust = 1;
dim3 blockDust(MAX_DUST);
updateDustGPU << <gridDust, blockDust >> > (cudaDust, xMax, yMax);
cudaDeviceSynchronize();
cudaMemcpy(dust, cudaDust, sizeof (Dust)* MAX_DUST,
cudaMemcpyDeviceToHost);
// -------------------------end Koding Update debu dengan GPU--------------
-------------------

__global__ void updateDustGPU(Dust * dust, int xMax, int yMax){


int i = threadIdx.x;
if (dust[i].active) {
if (dust[i].drawThisFrame) {
Dust[i].drawThisFrame = 0;
dust[i].dustTimer = dust[i].dustTimer + 1;
}
else{
dust[i].drawThisFrame = 1;
dust[i].dustTimer = dust[i].dustTimer + 1;
}
if (dust[i].dustTimer > 6) {
dust[i].active = 0;
}
}
}

177
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Koding dengan CPU, ke-2:


/* update posisi tembakan laser foton, hilangkan mereka jika telah melewati
batas windows-nya*/
// -------------------------start Koding Eliminasi Laser foton dengan CPU--
-------------------------------
/*for (int i = 0; i < MAX_PHOTONS; i++) {
if (photons[i].active == 1) {
photons[i].x = photons[i].x + (photons[i].dx);
photons[i].y = photons[i].y + (photons[i].dy);
if (photons[i].x > xMax || photons[i].x < 0 || photons[i].y < 0 ||
photons[i].y > yMax) {
photons[i].active = 0;
}
}
}*/
// -------------------------end Koding Eliminasi Laser foton dengan CPU----
-----------------------------

- Koding dengan GPU, ke-2:


// Koding dengan CUDA
// -------------------------start Koding Eliminasi Laser foton dengan GPU--
-------------------------------
// copy host memory ke cuda memory
cudaMemcpy(cudaPhotons, photons, sizeof (Photon)* MAX_PHOTONS,
cudaMemcpyHostToDevice);
int gridPhotons = 1;
dim3 blockPhotons(MAX_DUST);
updatePhotonGPU << <gridPhotons, blockPhotons >> > (cudaPhotons, xMax,
yMax);
cudaDeviceSynchronize();
cudaMemcpy(photons, cudaPhotons, sizeof (Photon)* MAX_PHOTONS,
cudaMemcpyDeviceToHost);
// -------------------------end Koding Eliminasi Laser foton dengan GPU----
-----------------------------

__global__ void updatePhotonGPU(Photon * photons, int xMax, int yMax){


int i = threadIdx.x;
if (photons[i].active == 1) {
photons[i].x = photons[i].x + (photons[i].dx);
photons[i].y = photons[i].y + (photons[i].dy);
if (photons[i].x > xMax || photons[i].x < 0 || photons[i].y < 0 ||
photons[i].y > yMax) {
photons[i].active = 0;
}
}
}

178
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Koding dengan CPU, ke-3:


/* Update posisi asteroid dan rotasinya*/
// Koding dengan CPU
// ----start Koding Update posisi asteroid dan rotasinya dengan CPU--------
/*for (int i = 0; i < MAX_ASTEROIDS; i++) {
if (asteroids[i].active == 1) {
asteroids[i].x = asteroids[i].x + (asteroids[i].dx);
asteroids[i].y = asteroids[i].y + (asteroids[i].dy);
asteroids[i].dx = (
asteroids[i].phi = asteroids[i].phi + asteroids[i].dphi;
if (asteroids[i].x < 0) {
asteroids[i].x = xMax;
}
else if (asteroids[i].x > xMax) {
asteroids[i].x = 0;
}
else if (asteroids[i].y < 0) {
asteroids[i].y = yMax;
}
else if (asteroids[i].y > yMax) {
asteroids[i].y = 0;
}
}
}*/
// --------end Koding Update posisi asteroid dan rotasinya dengan CPU------

- Koding dengan GPU, ke-3:


// Koding dengan CUDA
// --start Koding Update posisi asteroid dan rotasinya dengan GPU--
// copy host memory ke cuda memory
cudaMemcpy(cudaAsteroids, asteroids, sizeof (Asteroid)* MAX_ASTEROIDS,
cudaMemcpyHostToDevice);
int gridAsteroid = 1;
dim3 blockAsteroid(MAX_ASTEROIDS);
updateAsteroidsGPU << <gridAsteroid, blockAsteroid >> > (cudaAsteroids, xMax, yMax);
cudaDeviceSynchronize();
cudaMemcpy(asteroids, cudaAsteroids, sizeof (Asteroid)* MAX_ASTEROIDS,
cudaMemcpyDeviceToHost);
// --end Koding Update posisi asteroid dan rotasinya dengan GPU--

__global__ void updateAsteroidsGPU(Asteroid * asteroids, int xMax, int


yMax){
int i = threadIdx.x;
if (asteroids[i].active == 1) {
asteroids[i].x = asteroids[i].x + (asteroids[i].dx);
asteroids[i].y = asteroids[i].y + (asteroids[i].dy);
asteroids[i].phi = asteroids[i].phi + asteroids[i].dphi;
if (asteroids[i].x < 0) {
asteroids[i].x = xMax;
}
else if (asteroids[i].x > xMax) {
asteroids[i].x = 0;
}
else if (asteroids[i].y < 0) {
asteroids[i].y = yMax;
}
else if (asteroids[i].y > yMax) {
asteroids[i].y = 0;
}
}
}

179
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Link kode lengkap Game Asteroid2D CUDA dapat di-download dari


“https://drive.google.com/drive/folders/17-mK8lzJbFOmXmouQO97P0KL2fAqFaqP?usp=sharing”
atau “http://bit.ly/2ICLLMr”

Gambar 6.2 Tampilan Game Asteroid 2D

180
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.1.5 Solusi Error CUDA + OpenGL


- Jika terdapat error “..warning : Access to the path
‘..\x64\debug\..exe' is denied” atau “..error LNK1104: cannot open
file ‘..\x64\Debug\...exe‘..”

- Solusi, jika terdapat error “..warning : Access to the path


‘..\x64\debug\..exe' is denied” atau “..error LNK1104: cannot open
file ‘..\x64\Debug\...exe‘ ..”

1. Buka Task Manager


2. Cari pada kolom Name nama file
*.exe hasil compile
3. Klik kanan, lalu klik End task
4. Selesai

181
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Jika “Access is Denied” maka solusinya:

1. Buka Task Manager


2. Cari pada kolom Name nama file *.exe
hasil compile
3. Cek PID, “4052”
4. Buka PowerShell as Administrator
5. Ketikkan “kill -d 4052”, tanpa quote, lalu
tekan enter
6. Masukkan,Y
7. Tekan enter, selesai

182
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.2 OpenCL dan OpenGL


OpenCL digunakan untuk calculation, data generation, image
manipulation. Sedangkan OpenGL digunakan untuk draw pixels atau
vertices pada screen. Interop is very fast! yaitu mampu melakukan
share data melalui common memory di dalam framebuffer.
1. Membuat Vertex Buffer Object (VBO) kosong
2. Register VBO dengan OpenCL
3. Map VBO selama writing dari OpenCL
4. Jalankan OpenCL kernel untuk memodifikasi posisi vertex
5. Unmap VBO
6. Render hasil menggunakan OpenGL
6.2.1 Visualisasi Sine Wave
- Kode Program “00TransObjectSineWaveCL”:
o Link kode program: “http://bit.ly/2HqWGLW” atau
“https://drive.google.com/drive/folders/1gdPU52QBiqRJpwDbfu-aoOmV4ShWXwzb”
o Hasil compile program:

o Kode Kernel Sine Wave OpenCL (sinewave.cl):


__kernel void sinewave(__global float4* pos, unsigned int width, unsigned int
height, float time, __global uchar4* color){
unsigned int x = get_global_id(0);
unsigned int y = get_global_id(1);
// calculate uv coordinates
float u = x / (float)width;
float v = y / (float)height;
u = u*2.0f - 1.0f;
v = v*2.0f - 1.0f;
// calculate simple sine wave pattern
float freq = 4.0f;
float w = sin(u*freq + time) * cos(v*freq + time) * 0.5f;
// write output vertex
pos[y*width + x] = (float4)(u, w, v, 1.0f);
color[y*width + x] = (uchar4)(
(uchar) 255.f *0.5f*(1.f + sin(w + (float)x)),
(uchar) 255.f *0.5f*(1.f + sin((float)x)*cos((float)y)),
(uchar) 255.f *0.5f*(1.f + sin(w + time / 10.f)), 0);
}

183
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

o Visualisasi hasil running Sine Wave OpenCL

Gambar 6.3 Tampilan Sine Wave OpenCL

184
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6.2.2 Marching Cubes OpenCL


Marching Cubes (MC) adalah algoritma yang diperkenalkan
Lorensen dan Cline (1987) untuk ekstraksi permukaan dataset 3D
melalui kubus yang diambil bagian tertentu dalam bentuk segitiga. Cara
kerjanya dengan membagi seluruh dataset ke dalam grid kubus,
kemudian dibuat segitiga di setiap kubus dengan menentukan posisi
tertentu, menggunakan 3 titik sudut tertentu dalam kubus.

Gambar 6.4 Cara Kerja Marching Cubes


- Ilustrasi Marching Cubes (MC):
o Misal, kita akan membuat suatu segi (facet) dalam bentuk
bidang dari segitiga yang memotong melalui sisi (edge) 2, 3, dan
11.
o Dari kumpulan banyak segi, digunakan untuk membentuk
permukaan (surface) 3D, berikut contohnya:

185
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Link kode lengkap Marching Cubes dapat di-download dari


“https://drive.google.com/drive/folders/1gE9dchA_-m8H0p8bKngJ8BlupwpRNgSo?usp=sharing”
atau “http://bit.ly/2qBwsMi”

6.3 Tugas Kelompok


----------dengan CUDA----------
1. Dalam main project kelompok anda, misal “VSCudaCLKel-[..]-
Kelas-[..]”, didalamnya buat folder, misal “09_CudaOpelGLKel[..]”,
yang didalamnya minimal terdapat project “0transObjectKel[..]”.
Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di slide, dan sertakan kode programnya dalam tabel.

Dalam main project kelompok anda, misal “VSCudaCLKel-[..]-


Kelas-[..]”, didalam folder “009_OpenGLCUKel[..]”, buat project
dengan nama “1primObjectKel[..]”, buat beberapa primitive
object (masukkan dalam vbo), tambahkan proses transformasi
(rotasi/translasi/scaling) dari semua object berikut:
 SegiEmpat
 Lingkaran
 Kubus
 Polygon
yang mana mengacu pada project “3segitigaGradasiCuda”, link
kode “http://bit.ly/2H2ElEM”. Dan capture step by step hasil
running programnya dari VS, seperti pada contoh di-slide, dan
sertakan kode programnya dalam tabel.

186
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2. Didalam folder “09_CudaOpelGLKel[..]”, buat project dengan


nama “3segitigaGradasiCudaKel[..]”, buat beberapa primitive
object (masukkan dalam vbo), tambahkan proses transformasi
(rotasi/translasi/scaling) dari satu atau untuk semua object, yaitu
Segitiga, SegiEmpat, Lingkaran, Polygon, harus dapat dikontrol
dengan tombol dikeyboard:
 ‘s’ untuk stop objek
 ‘r’ untuk menjalankan objek
 ‘↑’ untuk mempercepat, misal perputaran objek
 ‘↓’ untuk memperlambat perputaran objek
Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di-slide, dan sertakan kode programnya dalam tabel.
3. Dalam main project kelompok, misal “VSCudaCLKel-[..]-Kelas-[..]”,
didalamnya buat folder, misal “9_RayTracingNdCudaKel[..]”, yang
didalamnya minimal terdapat project “0GPUPathTracingKel[..]”.
Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di slide, dan sertakan kode programnya dalam tabel.
4. Didalam folder “9_RayTracingNdCudaKel[..]”, buat project dengan
nama “1rayTracCudaTwoKel[..]”. Dan capture step by step hasil
running programnya dari VS, seperti pada contoh di slide, dan
sertakan kode programnya dalam tabel.
5. Didalam folder “09_CudaOpelGLKel[..]”, buat project dengan
nama “00Asteroid2DGameCUDAKel[..]”, yang mengacu pada
contoh project “Game Asteroid2D CUDA”, lalu ubah kode host
berikut:
// Collision diantara ship dan suatu asteroid.
for (int j = 0; j < SHIP_VERTICES; j++) {
for (int i = 0; i < MAX_ASTEROIDS; i++) {
if (asteroids[i].active == 1 && shipExplosion.active == 0) {
if (ShipCollision(&ship.coords[j], &asteroids[i])) {
activateExplosion(0, 0);
lives = lives - 1;
j = SHIP_VERTICES + 1;
i = MAX_ASTEROIDS + 1;
}
}
}
}

Menjadi kode device dengan kernel CUDA.

187
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

----------dengan OpenCL----------
1. Dalam main project kelompok anda, misal “VSCudaCLKel-[..]-Kelas-
[..]”, didalamnya buat folder, misal “09_OpelGLCLKel[..]”, yang
didalamnya minimal terdapat project “00TransObjectCLKel[..]”.
Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di slide, dan sertakan kode programnya dalam tabel.

2. Dari project no. 1, dalam main project kelompok anda, didalam


folder “09_OpelGLCLKel[..]”, buat project dengan nama
“1primObjectCLKel[..]”, buat beberapa primitive object (masukkan
dalam vbo), tambahkan proses transformasi
(rotasi/translasi/scaling) dari satu atau untuk semua object:
o Segitiga
o SegiEmpat
o Lingkaran
o Kubus
o Polygon
Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di-slide, dan sertakan kode programnya dalam tabel.
3. Didalam folder “09_OpelGLCLKel[..]”, buat project dengan nama
“3segitigaGradasiCLKel[..]”, buat beberapa primitive object
(masukkan dalam vbo), tambahkan proses transformasi
(rotasi/translasi/scaling) dari satu atau untuk semua object, yaitu
Segitiga, SegiEmpat, Lingkaran, Polygon, harus dapat dikontrol
dengan tombol dikeyboard:
o ‘s’ untuk stop objek
o ‘r’ untuk menjalankan objek
o ‘↑’ untuk mempercepat, misal perputaran objek
o ‘↓’ untuk memperlambat perputaran objek
Dan capture step by step hasil running programnya dari VS, seperti
pada contoh di-slide, dan sertakan kode programnya dalam tabel.

188
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

4. Dalam main project kelompok, misal “VSCudaCLKel-[..]-Kelas-[..]”,


didalamnya folder solution, misal “001_CitraAudioVideoCLKel[..]”,
buat didalamnya project “032MarchingCubesCLKel[..]”, kodingnya
dari link “https://drive.google.com/drive/folders/1gE9dchA_-
m8H0p8bKngJ8BlupwpRNgSo?usp=sharing” atau
“http://bit.ly/2qBwsMi”. Dan capture step by step hasil running
programnya dari VS, seperti pada contoh di slide, dan sertakan
kode programnya dalam tabel.

Ganti file skull.raw dengan yang lain, misal dengan

----------Petunjuk untuk soal no. 5 sampai no. 7----------


Copy file *.dll dari link “https://goo.gl/86LZo3” ke folder Debug
di Windows Explorer, misal di “E:\Data Kuliah\!Genap 2016-
2017\2. Pemrograman GPU\VSIntelCL\x64\Debug”
5. Buat folder solution “03_RayTracingKel[..]”, dan didalamnya buat
project dengan nama “0RayCLKel[..]”, link kode
“https://goo.gl/PzUxVA”:

189
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Note: Klik kanan pada project “0RayCL” >> Pilih


Properties, lalu Klik “Linker”,
klik “Input”, pada “Additional Dependencies” klik
<Edit...>
Masukkan “OpenCL.lib, freeglut.lib, glew32.lib”, klik
OK, Klik Apply, Klik OK

6. Pada folder solution “03_RayTracingKel[..]”, dan didalamnya buat


project dengan nama “1RayCLKel[..]”, link kode
“https://goo.gl/uDkC6H”:

7. Pada folder solution “03_RayTracingKel[..]”, dan didalamnya buat


project dengan nama “2RayCLKel[..]”, link kode
“https://goo.gl/Ew7OKK”:

190
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 7 Parallel Processing Pada


Citra & Video

7.1 Tentang OpenCV, Citra dan Video


OpenCV (Open Source Computer Vision Library) dirilis dengan
lisensi BSD sehingga gratis untuk penggunaan akademis maupun
komersial. OpenCV memiliki antarmuka C++, C, Python dan Java dan
mendukung Windows, Linux, Mac OS, iOS dan Android.

OpenCV dirancang untuk komputasi yang efisien dengan fokus


pada aplikasi real-time dan handal. OpenCV ditulis di C/C++ yang
dioptimalkan, dapat memanfaatkan pemrosesan multi-core. Dan
dapat pula diaktifkan dengan OpenCL sebagai alternatif CUDA,
sehingga dapat memanfaatkan akselerasi perangkat keras dari
platform penghitungan heterogen yang mendasarinya. Sebelum kita
melakukan pengolahan citra digital menggunakan CUDA atau OpenCL,
terlebih dahulu pada bagian ini akan diberikan beberapa pembahasan
singkat mengenai konsep dasar dan beberapa teknik untuk melakukan
pengolahan citra digital sebagai acuan untuk dibuat secara parallel
menggunakan CUDA atau dengan OpenCL.
 Pertama: Konsep Tingkat Kecerahan (Intensitas)
- Citra Berwarna: 0 sampai 255 (Terdapat 256 warna, dengan 3 sam-
pai 4 lapisan)

Harus ada min. 3 dan max. 4 lapisan. [ (lapisan R dan G dan B)


dan/atau A) ]. Red (lapisan/channel merah), Green (lapisan hijau),
Blue (lapisan biru), Alpha (lapisan Transparan).

191
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Citra Grayscale: 0 sampai 255 (Terdapat 256 warna, dengan 1


lapisan)

- Citra Biner: 0 dan 1 (Terdapat 2 warna, dengan 1 lapisan)

 Kedua: Konversi RedGreenBlue ke Graylevel


- Lightness Method
Gray = (max(R, G, B) + min(R, G, B)) / 2
- Average Method
Gray = (R + G + B) / 3
- Citra Biner: 0 dan 1 (Terdapat 2 warna, dengan 1 lapisan)
Gray = 0.2126 R + 0.7152 G + 0.0722 B

Contoh: Diketahui Channel Matrix Warna dari Citra Digital adalah


sebagai berikut dengan Average Method.

192
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

 Ketiga: Smoothing filters (Image Filtering)


- Lowpass filter (linear filter, mengambil nilai rata-rata)

- Median filter (non-linear filter, mengambil median dari setiap jen-


dela ketetanggan)
3 x 3 Median filter [42 42 42 42 42 231 231 231 231] = 42
3 x 3 Max filter [42 42 42 42 42 231 231 231 231] = 231
3 x 3 Min filter [42 42 42 42 42 231 231 231 231] = 42

 Keempat: Sharpening filters (Image Filtering)


- Roberts, Sobel (edge detection)

f’(0,0) = |4-1| + |5-2| = 6

- Highpass filter

193
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

 Kelima: Object Tracking


- Background Subtraction, cek dari link “https://goo.gl/JVjiSv”

- Surf (Speed Up Robust Features), SIFT (Scale Invariant Feature


Transform) dan lainnya

7.2 Install dan Konfigurasi OpenCV


- Pastikan anda sudah install CUDA Toolkit atau Installer/lib OpenCL
dari Nvidia/Intel/AMD/etc
- Download misal OpenCV 2.4+, lalu ekstak, misal di “drive E:”
- Hasil Ekstrak di “drive E:”

194
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Setting PATH dengan masuk ke Control Panel\System and Secu-


rity\System, Klik “Environment Variables..”. Pada System variables,
pilih Path.

- klik Edit, Klik New, copy paste misal “E:\opencv\build\x64\vc12\bin”

195
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

7.3 Study Kasus: CUDA dan OpenCL


7.3.1 Parallel Processing Pada Citra
Contoh Proses Pengolahan Citra dengan CUDA
- Buat new project di Visual Studio, misal “2RGB2GrayCUDAOpenCV”,
link kode “https://goo.gl/MUFG2v”

- Pada Project “2RGB2GrayCUDAOpenCV”, Pada “VC++ Directories”,


lalu set “Executable Directories” dengan
“E:\opencv\build\x64\vc12\bin”

196
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada “VC++ Directories”, Lalu set “Include Directories” dengan


“E:\opencv\build\include”

- Pada “VC++ Directories”, Lalu set “Library Directories” dengan


“E:\opencv\build\x64\vc12\lib”

- Pada “CUDA C/C++”, Lalu set “Additional Include Directories”


dengan “E:\opencv\build\include”

- Pada “Linker” >> “General”, Lalu set “Additional Library Directories”


dengan “E:\opencv\build\x64\vc12\lib”

197
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada “CUDA Linker”, Lalu set “Additional Library Directories”


dengan “E:\opencv\build\x64\vc12\lib”

-
dengan “E:\opencv\build\x64\vc12\bin”

- Pada “Linker -> Input -> Additional Dependencies”, Tambahkan:


opencv_core2412d.lib
opencv_imgproc2412d.lib
opencv_highgui2412d.lib
opencv_ml2412d.lib
opencv_video2412d.lib
opencv_features2d2412d.lib
opencv_calib3d2412d.lib
opencv_objdetect2412d.lib
opencv_contrib2412d.lib
opencv_legacy2412d.lib
opencv_flann2412d.lib

198
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Compile project “” berhasil

- Jalankan file *exe hasil compile project

- Tampilan project

199
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Show atau hanya Display Image + Cimg


Link kode program: https://goo.gl/Q7JALn

- Kode Program Utama Display Image:


o #include "CImg.h“
 header CImg.h v1.6.9 dapat digunakan untuk
memanipulasi file citra (*.bmp) dengan mudah. Petunjuk
lengkap menggunakan ada pada link http://cimg.eu
o Kernel
__global__ void gpu_task(unsigned char * d_in, unsigned char * d_out, int img_width, int
img_height){

unsigned long scale = img_width*img_height; // = 640*480 = 220800


unsigned long r = blockIdx.x * blockDim.x + threadIdx.x; // { 0,1,2,3,4, ....,
//(220800-1) }

unsigned long g = r + scale; // { 0,1,2,3,4, ...., (220800-1) } + 220800


unsigned long b = g + scale; // { 0,1,2,3,4, ...., (220800-1) } + 2*220800

//copy the input image to the output image, sebenarnya d_out ini hanya array 1
//dimensi
//dengan indeks {0,1,.., (220800-1)} untuk lapisan red (r)
//dengan indeks {220800,220801,.., (2*220800-1)} untuk lapisan green (g)
//dengan indeks {2*220800, (2*220800 + 1),.., (3*220800-1)} untuk lapisan blue (b)
d_out[r] = d_in[r];
d_out[b] = d_in[b];
d_out[g] = d_in[g];

//printf("%d\t%d\t%d\n",r,g,b);
}

200
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Contoh Proses Pengolahan Citra dengan OpenCL


- Show atau hanya Display Image + Cimg
Link kode program: http://bit.ly/2HkU1DN
atau dari link berikut:
https://drive.google.com/drive/folders/1gcJUn0QzN-gGKMyZOA3xvpLliga_gTuU?usp=sharing

- Kode Program Utama Display Image:


o #include "CImg.h“
 header CImg.h v1.6.9 dapat digunakan untuk
memanipulasi file citra (*.bmp) dengan mudah. Petunjuk
lengkap menggunakan ada pada link http://cimg.eu
o Kernel
kernel void XYY_XYZ(global const float* red_input, global const float* green_input, global const
float* blue_input, global float *red_output, global float *green_output, global float
*blue_output, const int w){
int baseX = get_global_id(0);
int baseY = get_global_id(1);

global const float *rsrcPixel = red_input + (baseY * w) + baseX;


global const float *gsrcPixel = green_input + (baseY * w) + baseX;
global const float *bsrcPixel = blue_input + (baseY * w) + baseX;

global float *rdstPixel = red_output + (baseY * w) + baseX;


global float *gdstPixel = green_output + (baseY * w) + baseX;
global float *bdstPixel = blue_output + (baseY * w) + baseX;

*rdstPixel = *rsrcPixel / (*rsrcPixel + *gsrcPixel + *bsrcPixel);


*gdstPixel = *gsrcPixel / (*rsrcPixel + *gsrcPixel + *bsrcPixel);
*bdstPixel = *gsrcPixel / 2;
}

201
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

7.3.2 Parallel Processing Pada Video


Contoh Proses Video Realtime dengan CUDA
- Tampilan hasil pengolahan
Link kode program: http://bit.ly/2qylng1
atau dari link berikut:
https://drive.google.com/drive/folders/18TWKo5ur28gu7ZTVIMKnWxM4fvRfCsR4

202
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Contoh Proses Video Realtime dengan OpenCL


- Tampilan hasil build
Link kode program: http://bit.ly/2qB7A7s
atau dari link berikut:
https://drive.google.com/drive/folders/18_Tql46nQlcVwLWzw2xYqLjLz0Exhd9m?usp=sharing

- Tampilan hasil pengolahan


Contoh running ke-1:

Contoh running ke-2:

203
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Konfigurasi Visual Studio untuk OpenCV (CUDA dan OpenCL)


- Setelah download kode programnya CUDA dan OpenCL, konfigurasi
seperti pada tahapan berikut, Klik kanan project, misal
“01WebCamProsesCUDAOpenCV”, klik “Properties”

- Klik “CUDA C/C++”  Klik “Host”  Klik pada bagian anak panah
“Preprocessor Definitions”, lalu klik “<Edit...>”

- Copykan isikan dengan teks “_ITERATOR_DEBUG_LEVEL=0”, klik OK,


klik Apply, klik OK. Selesai. :D

204
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

7.4 Tugas Kelompok


----------CUDA + OpenCV ----------------
1. Dalam folder solution utama kelompok, misal “VSCudaKel[..]”,
buat folder solution “001_ImageProcessingKel[..]”, dan dida-
lamnya buat project dengan nama “0DisplayRGBKel[..]”, link
kode “https://goo.gl/Q7JALn” dari demo program “Display Im-
age + Cimg”
a. Compile di Visual Studio, sampai
b. Hasil running-nya, dan setiap kelompok harus mengubah ba-
ris kode:
CImgDisplay main_disp(img_out, "After Processing");
Menjadi
CImgDisplay main_disp(img_out, "After Processing Kel-[..] Kelas-[..]");

2. Dari soal no. 1 di atas, ganti file citra "flower.bmp“ dengan citra
foto selfie kelompok (1 file citra ada semua anggota), misal
dengan nama “selfiekel[..]kelas[..].bmp”:
CImg<unsigned char> img("flower.bmp");

Menjadi, misal
CImg<unsigned char> img("selfiekel[..]kelas[..].bmp");

Compile di Visual Studio, dan capture hasil running-nya, contoh


seperti citra berikut!

205
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3. Modif dari soal no. 1, dalam folder solution utama kelompok,


misal “VSCudaKel[..]”, dalam folder solution “001_ImagePro-
cessingKel[..]”, buat project dengan nama “1RGB2GrayKel[..]”,
link kode “https://goo.gl/Q7JALn” dari demo program “Display
Image + Cimg”
//copy the input image to the output image
d_out[r] = d_in[r];
d_out[b] = d_in[b];
d_out[g] = d_in[g];
Ubah menjadi, misal dengan rumus Luminosity Method
I = 0.2126 * R + 0.7152 * G + 0.0722 * B
// I menyatakan Intensitas Warna Gray (abu-abu)

Compile di Visual Studio, dan capture hasil running-nya!


4. Modif soal no. 3 di atas, dalam folder solution utama kelompok,
misal “VSCudaKel[..]”, dalam folder solution “001_ImagePro-
cessingKel[..]”, buat project dengan nama “10RGB2GrayKel[..]”,
link kode “https://goo.gl/Q7JALn” dari demo program “Display
Image + Cimg”
//copy the input image to the output image
d_out[r] = d_in[r];
d_out[b] = d_in[b];
d_out[g] = d_in[g];

Ubah menjadi, misal dengan rumus (pilih salah satu)


Lightness Method: Gray = (max(R, G, B) + min(R, G, B)) / 2
Atau Average Method: Gray = (R + G + B) / 3

Compile di Visual Studio, dan capture hasil running-nya!


5. Modif soal no. 4 di atas, dalam folder solution utama kelompok,
misal “VSCudaKel[..]”, dalam folder solution “001_ImagePro-
cessingKel[..]”, buat project dengan nama “11RGB2BinerKel[..]”,
link kode “https://goo.gl/Q7JALn” dari demo program “Display
Image + Cimg”
//copy the input image to the output image
d_out[r] = d_in[r];
d_out[b] = d_in[b];
d_out[g] = d_in[g];

Ubah menjadi, misal dengan rumus konversi citra warna ke biner


If R atau G atau B > 128, return 0, else 255

Compile di Visual Studio, dan capture hasil running-nya!

206
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

6. Modif dari contoh project pengolahan citra, dalam folder solu-


tion utama kelompok, misal “VSCudaCLKel-[..]-Kelas-[..]”, buat
folder solution “001_ImageProcessingKel[..]”, buat project
dengan nama “1RGB2NegKel[..]”, link kode contoh
“https://goo.gl/Q7JALn” dari demo program “Display Image +
Cimg”
//copy the input image to the output image
d_out[r] = d_in[r];
d_out[b] = d_in[b];
d_out[g] = d_in[g];

Misal untuk RBG-nya dengan rumus Luminosity Method


I = 0.2126 * R + 0.7152 * G + 0.0722 * B // I menyatakan Intensitas Warna
Gray (abu-abu)

RGB2Neg: 255 - I

Compile di Visual Studio, dan capture hasil running-nya!


7. Dalam main project kelompok, misal “VSCudaCLKel-[..]-Kelas-
[..]”, didalamnya buat folder solution, misal
“001_CitraAudioVideoCUKel[..]”, yang didalamnya minimal
terdapat project “01WebCamProsesCUDAOpenCVKel[..]”. Dan
capture step by step hasil running programnya dari VS, seperti
pada contoh di slide, dan sertakan kode programnya dalam
tabel.

----------OpenCL + OpenCV ----------------


1. Modif dari contoh project pengolahan citra
“01RGB2XYZchromaticity”, dalam folder solution utama ke-
lompok, misal “VSCudaCLKel-[..]-Kelas-[..]”, buat folder solution
“001_ImageProcessingCLKel[..]”, buat project dengan nama
“02RGB2XYZchromaticityKel[..]”, link kode contoh
“http://bit.ly/2HkU1DN” dari demo program “Display Image +
Cimg”. Compile di Visual Studio, dan capture hasil running-nya!
2. Modif dari soal no. 1, dalam folder solution utama kelompok,
misal “VSCudaCLKel[..]”, dalam folder solution
“001_ImageProcessingCLKel[..]”, buat project dengan nama
“1RGB2GrayCLKel[..]”, dengan ketentuan sebagai berikut

Buat RBG-nya dengan rumus Luminosity Method


I = 0.2126 * R + 0.7152 * G + 0.0722 * B // I menyatakan Intensitas Warna
Gray (abu-abu)

207
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3. Modif dari soal no. 2, dalam folder solution utama kelompok,


misal “VSCudaCLKel[..]”, dalam folder solution
“001_ImageProcessingCLKel[..]”, buat project dengan nama
“1RGB2NegCLKel[..]”, dengan ketentuan sebagai berikut
Misal untuk RBG-nya dengan rumus Luminosity Method
I = 0.2126 * R + 0.7152 * G + 0.0722 * B // I menyatakan Intensitas Warna
Gray (abu-abu)

RGB2Neg: 255 - I

4. Buatlah main project dengan nama “VSCudaCLKel-[..]-Kelas-[..]”,


lalu didalamnya buat folder solution, misal
“001_CitraAudioVideoCLKel[..]”, yang didalamnya minimal
terdapat project “02CannyWebCamCLKel[..]”. Dan capture step
by step hasil running programnya dari VS, seperti pada contoh
di slide, dan tambahkan kode programnya untuk menampilkan
hasil Grayscale. (modif dari kode dari link:
“http://bit.ly/2qB7A7s”).

Ubah file “.\kernels\gpu\sobel_kernel.cl”


__constant int sobx[3][3] = { {-1, 0, 1},
{-2, 0, 2},
{-1, 0, 1} };
__constant int soby[3][3] = { {-1,-2,-1},
{ 0, 0, 0},
{ 1, 2, 1} };

__constant float sobx[3][3] = { {1/9, 1/9, 1/9},


{1/9, 1/9, 1/9},
{1/9, 1/9, 1/9} };
__constant float soby[3][3] = { {1/9, 1/9, 1/9},
{1/9, 1/9, 1/9},
{1/9, 1/9, 1/9} };

208
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 8 Create *.dll, *.lib pada GPU

8.1 Apa itu *.dll, *.lib?


Dynamic library (*.dll) dapat disebut juga sebagai shared library,
terdiri dari rutinitas yang dimuat ke dalam aplikasi pada waktu dijalan-
kan. Ketika anda mengkompilasi sebuah program yang menggunakan
dynamic library, library tidak menjadi bagian dari eksekusi, tetap
sebagai unit terpisah. Dynamic library dapat diilustrasikan ketika anda
datang ke perpustakaan, melihat ada buku apa saja & tahu dimana
posisinya. Suatu saat ada yang bertanya pada anda tentang isi buku
tersebut, anda cukup menuju ke posisi rak mana, dimana buku
disimpan, kemudian ambil, anda bisa baca buku terlebih dahulu untuk
menjawab pertanyaan. Pada sistem operasi Windows, dynamic library
biasanya memiliki ekstensi .dll (dynamic link library) sedangkan pada
Linux memiliki ekstensi .so (shared object). Keuntungan dari dynamic
library adalah banyak program dapat berbagi satu salinan, dan
menghemat ruang, serta dapat diperbarui ke versi yang lebih baru
tanpa mengganti semua executable yang menggunakannya. Berikut
beberapa cara untuk load file *.dll (dynamic link library) pada C++ atau
C++ CUDA:
 Memodifikasi working directory dari executable file utama.
 Meletakkan DLL files ke dalam Windows root.
 Memodifikasi PATH environment variable.

Static library Static library


(*.lib) (*.lib)
File Static linking
menyatu dengan Program
setelah di-compile

Shared library
(*.dll) File Dynamic linking
tidak menyatu dengan Program
setelah di-compile

Gambar 8.1 File *.dll vs *.lib


Static library (*.lib) dapat dikenal juga sebagai archive, terdiri
dari rutinitas yang disusun dan dihubungkan langsung ke program
anda. Ketika anda mengkompilasi sebuah program yang menggunakan
static library, semua fungsi dari static library menjadi bagian dari

209
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

eksekusi. Static library dapat diilustrasikan ketika anda datang ke per-


pustakaan, dan harus membaca dan hafal semua isi buku apa saja yang
ada disana. Sehingga ketika ada yang bertanya ke anda tentang isi
buku tertentu, anda langsung bisa menjawab pertanyaan. Pada sistem
operasi Windows, static library biasanya memiliki ekstensi .lib se-
dangkan pada Linux, biasanya memiliki ekstensi .a (archive).
Keuntungan dari static library adalah anda cukup mendistribusikan
executable file ke pengguna untuk menjalankan program. Karena
library menjadi bagian dari program anda, ini memastikan bahwa versi
yang tepat dari library selalu digunakan dengan program anda. Selain
itu anda dapat menggunakannya sama seperti fungsi yang sudah anda
tulis untuk program anda sendiri. Pada sisi negatifnya, karena salinan
library menjadi bagian dari setiap executable, maka ini dapat
menyebabkan banyak ruang terbuang. Static library juga tidak dapat
diperbarui dengan mudah, untuk memperbarui library, seluruh
executable perlu diganti dengan di-compile ulang.

8.2 Create & Load *.dll, *.lib CUDA di


Visual Studio
8.2.1 Create *.dll
- Create *.dll, buat folder solution, misal “14_CreateUseLIBDLL”, dan
di dalam folder tersebut buat project dengan nama
“0createhelloDLL”
- Dan pastikan di Win. Explorer sudah dibuat folder, misal “E:\Data
Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda\14_CreateUseLIBDLL\”, yang nantinya di-browse
sebagai lokasi penyimpanan project diatas

210
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Dalam project “0createhelloDLL”, remove file “kernel.cu”, klik


Delete.

- Download file “icshello.cu dan icshello.h” dari link


“https://goo.gl/cS37AC”, lalu copy di project “0createhelloDLL”.
- Klik kanan project “0createhelloDLL”, lalu klik Add  Existing
Item...

- Klik Add

211
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Tampilan project “0createhelloDLL”, setelah ditambahkan file


“icshello.cu dan icshello.h”

- Klik kanan project “0createhelloDLL”, lalu pilih “Properties”


- Klik General  Configuration Type, klik pilih “Dynamic Library
(.dll)”. Klik Apply, Klik OK

- Klik kanan Project “0createhelloDLL”, pilih “Set as StartUp Project”.

212
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Compile Project “0createhelloDLL”, klik kanan pilih Clean  Build.

- Build Project “0createhelloDLL” berhasil

- Cek folder “Debug” di Windows Explorer, misal di “E:\Data


Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda\x64\Debug”. File “0createhelloDLL.dll” berhasil
dibuat.

213
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada Windows Explorer, pada folder solution utama, misal di


“E:\Data Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda”, didalamnya folder “VSCuda” buat folder baru
dengan nama “common”, lalu didalam folder “common” buat
folder baru dengan nama “dll”, lalu didalam folder “dll“, buat folder
baru dengan nama “x64”.

- Copy file “0createhelloDLL.dll” tersebut ke folder, misal di folder


“E:\Data Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda\common\dll\x64”, untuk di-backup
- Tampilan setelah dicopy:

214
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

8.2.2 Load *.dll


- Using/Load *.dll, pada folder solution, “14_CreateUseLIBDLL”, di
dalam folder tersebut buat project baru dengan nama
“1Use0helloDLLCara1”, Location, misal di “E:\Data Kuliah\!Genap
2016-2017\2. Pemrograman GPU\VSCuda\14_CreateUseLIBDLL\”

- Dalam project “1Use0helloDLLCara1”, remove file “kernel.cu”, klik


Delete.

- Download file “use0helloDLL.cu” dari link “https://goo.gl/Q6cpJb”,


lalu copykan di project “1Use0helloDLLCara1”.

215
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan project “1Use0helloDLLCara1”, lalu klik Add  Existing


Item...

- Klik Add
- Tampilan project “1Use0helloDLLCara1”, setelah ditambahkan file
“use0helloDLL.cu”

Pada bagian yang merah, ganti menjadi:


auto myDLL = LoadLibrary("..\\..\\common\\dll\\x64\\0createhelloDLL.dll");

216
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan Project “1Use0helloDLLCara1”, pilih “Set as StartUp


Project”.

- Compile Project “1Use0helloDLLCara1”, klik kanan pilih Clean 


Build.

- Build Project “1Use0helloDLLCara1” berhasil

217
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Running Project (Klik Debug  Start Without Debugging):

8.2.3 Create *.lib


- Create *.lib, pada folder solution, “14_CreateUseLIBDLL”, di dalam
folder tersebut buat project baru dengan nama, misal
“2createhelloLIB”, Location, misal di “E:\Data Kuliah\!Genap 2016-
2017\2. Pemrograman GPU\VSCuda\14_CreateUseLIBDLL\”

218
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Dalam project “2createhelloLIB”, remove file “kernel.cu”, klik


Delete.

- Download file “icshello.cu dan icshello.h” dari link


“https://goo.gl/cS37AC”, lalu copy di project “2createhelloLIB”.
- Klik kanan project “2createhelloLIB”, lalu klik Add  Existing Item...

- Klik Add

219
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Tampilan project “2createhelloLIB”, setelah ditambahkan file


“icshello.cu dan icshello.h”

- Klik kanan project “2createhelloLIB”, lalu pilih “Properties”


- Klik General  Configuration Type, klik pilih “StaticLibrary (.lib)”.
Klik Apply, Klik OK

- Klik kanan Project “2createhelloLIB”, pilih “Set as StartUp Project”.

220
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Compile Project “2createhelloLIB”, klik kanan pilih Clean  Build.

- Build Project “2createhelloLIB” berhasil

- Cek folder “Debug” di Windows Explorer, misal di “E:\Data


Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda\x64\Debug”. File “2createhelloLIB.lib” berhasil
dibuat.

221
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada Windows Explorer, pada folder solution utama, misal di


“E:\Data Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda”, didalamnya folder “VSCuda” buat folder baru
dengan nama “common” (abaikan jika sudah ada), lalu di dalam
folder “common” buat folder baru dengan nama “lib”, lalu didalam
folder “lib“, buat folder baru dengan nama “x64”.

- Copy file “2createhelloLIB.lib” tersebut ke folder, misal di folder


“E:\Data Kuliah\!Genap 2016-2017\2. Pemrograman
GPU\VSCuda\common\lib\x64”, untuk di-backup
- Tampilan setelah dicopy:

222
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

8.2.4 Load *.lib


- Using/Load *.lib, pada folder solution, “14_CreateUseLIBDLL”,
didalam folder tersebut buat project baru dengan nama
“4Use0helloLIB”, Location, misal di “E:\Data Kuliah\!Genap 2016-
2017\2. Pemrograman GPU\VSCuda\14_CreateUseLIBDLL\”

- Dalam project “4Use0helloLIB”, remove file “kernel.cu”, klik Delete.

223
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Download file “use0helloLIB.cu” dari link “https://goo.gl/Ko3oyp”,


lalu copy di project “4Use0helloLIB”.
- Klik kanan project “4Use0helloLIB”, lalu klik Add  Existing Item...

- Klik Add
- Tampilan project “4Use0helloLIB”, setelah ditambahkan file
“use0helloLIB.cu”

224
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan Project “4Use0helloLIB”, pilih “Set as StartUp Project”.

- Klik kanan project “4Use0helloLIB”, pilih properties

- Klik “VC++ Directories”, klik “Library Directories”, klik “<Edit...>”

225
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Masukkan “..\..\common\lib\x64”, yang merupakan lokasi lib


“2createhelloLIB.lib”, klik OK

- Klik “Linker”, klik “Input”, pada “Additional Dependencies” klik


<Edit...>

- Masukkan “2createhelloLIB.lib”, klik OK, klik Apply, klik OK

226
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Compile Project “4Use0helloLIB”, klik kanan pilih Clean  Build.

- Build Project “4Use0helloLIB” berhasil

- Running Project (Klik Debug  Start Without Debugging):

227
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

8.3 Create Installer CUDA Project


- Download InstallShield Limited Edition for Visual Studio di
“https://goo.gl/vyqDyT”, atau cek di web
http://learn.flexerasoftware.com/content/IS-EVAL-InstallShield-
Limited-Edition-Visual-Studio, Lengkapi biodata (Note: *Visual
Studio Community Edition is not supported).

- Klik Download Now

228
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik Download, klik Save File

- Close Visual Studio anda, lalu double klik


“InstallShield2015LimitedEdition.exe”

- Setelah instalasi selesai, untuk cara build MSI installation project,


hanya dalam beberapa menit dengan InstallShield Limited Edition,
lihat petunjuk dari link “https://goo.gl/TMWcYQ”.
- Untuk alternatif software create Installer lainnya, gunakan “Inno
Setup” www.jrsoftware.org/isdl.php atau lainnya.

229
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

8.4 Tugas Kelompok


1. Dalam main project kelompok, misal “VSCudaKel[..]”, didalamnya
buat folder, misal “14_CreateUseLIBDLLKel[..]”, yang didalamnya
terdapat project (lihat di slide sebelumnya):
a. “0createhelloDLLKel[..]”.
b. “1Use0helloDLLCara1Kel[..]”
c. “2createhelloLIBKel[..]”
d. “4Use0helloLIB”
Note: Capture step by step hasil running programnya dari VS,
seperti pada contoh di slide, dan sertakan kode programnya
dalam tabel.
2. Dari soal no. 1, didalamnya folder “14_CreateUseLIBDLLKel[..]”,
buat project baru dengan nama “5Use0helloDLLCara2Kel[..]”,
download kodenya dari link “https://goo.gl/0YI9uy”
Note: capture step by step hasil running programnya dari VS,
seperti pada contoh di slide, dan sertakan kode programnya
dalam tabel.

230
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 9 Pemrograman GPU


Tingkat Lanjut

9.1 CUDA/OpenCL & Library, etc


Beberapa library untuk pemrograman GPU telah tersedia cukup
banyak dan dapat langsung digunakan tanpa harus koding mulai dari
nol. Hal ini sangat berguna ketita pengembang membutuhkan waktu
lebih singkat dalam membuat suatu aplikasi dalam bentuk
implementasi komputasi parallel. Berikut beberapa library
CUDA/OpenCL yang dapat digunakan sebagai pilihan modul instan
dalam membuat sebagian kecil atau besar dalam membangun aplikasi.
 CUDA: curand, thrust, cublas, cudnn, etc
 OpenCL: CLBlast (https://github.com/CNugteren/CLBlast), etc
Beberapa tool lainnya untuk memudahkan pembuatan atau
pengembangan program diantaranya dengan casting code CUDA
maupun OpenCL menggunakan Python (PyCUDA dan PyOpenCL) atau
bahasa pemrograman lainnya yang anda familiar dengannya. Dan
dapat juga dikombinasikan dengan beberapa library lain, misal
TensorFlow, maupun dikembangkan dalam lingkungan virtualisasi
menggunakan konsep container seperti docker. Salah satu algoritma
yang nantinya akan dijelaskan detail dalam bagian ini dengan
menggunakan cudnn atau tanpa menggunakan library CUDA, yaitu
algoritma You Only Look Once (Yolo) Darknet yang merupakan salah
satu contoh dari penerapan algoritma Deep Learning sebagai AI-nya.

Gambar 9.1 CUDA/OpenCL Library dan Lainnya

231
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

9.2 Konfigurasi VS (CUDA dan Algoritma


Yolo)
You Only Look Once (Yolo)-Darknet adalah sebuah state-of-the-
art terpadu (unified) untuk sistem deteksi objek secara real-time. Yolo-
Darknet mendukung cross-platform Windows dan Linux, dalam
bentuk open framework neural network yang ditulis dalam bahasa C
dan CUDA, sangat cepat, mudah untuk di-install, dan supports penuh
untuk komputasi melalui CPU dan GPU.

Gambar 9.2 CUDA + Yolo

- Create project CUDA, misal “01darknetY2CU8” untuk compile,


membuat file 01darknetY2CU8.exe

232
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Klik kanan pada project “01darknetY2CU8”, klik properties, setting


“Include Directories”, klik Edit

- Pada “Include Directories”, masukkan lokasi “build\include” dari


opencv anda, misal di “E:\opencv\build\include”, klik OK

- Lalu pada “Library Directories”, Klik Edit

- Pada “Library Directories”, masukkan lokasi “build\x64\vc12\lib”


dari opencv anda, misal di “E:\opencv\build\x64\vc12\lib”, klik Ok,
klik Apply

233
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada “C/C++”  “General”, setting seperti berikut, klik OK, klik


Apply, klik OK

- Pada “Linker”  “Additional Library Directories”, setting seperti


berikut, klik OK, klik Apply, klik OK

- Download cudnn dari “https://developer.nvidia.com/cudnn”:

234
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pilih cudnn yang sesuai dgn versi CUDA anda

- Ektraks cudnn, misal di “E:\cuda”

- Konfigurasi cudnn ke project “darknet”, Setting pada “Include


Directories”, klik Edit

235
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Pada “Include Directories”, masukkan lokasi “include” dari cudnn


anda, misal di “E:\cuda\include”, klik OK

- Lalu pada “Library Directories”, Klik Edit

- Pada “Library Directories”, masukkan lokasi “lib” dari cudnn anda,


misal di “E:\cuda\lib”, klik Ok, klik Apply

236
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Masuk ke Control Panel\System and Security\System, Klik “Envi-


ronment Variables..”. Pada System variables, klik “New”, Isikan
“Variable name” dgn “cudnn”, misal “Variable value”-nya adalah
“E:\cuda”, sebagai folder cudnn diekstrak. Klik OK, Klik OK, klik OK

- Pada “System Variables”, pada “Path”, klik “New”, Isikan misal


“bin”-nya adalah “E:\cuda\bin”, lalu Klik OK, Klik OK, klik OK

- Pada “Additional Dependencies”, klik Edit

237
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Tambahkan “cudnn.lib”, klik OK, klik Apply, klik OK

9.3 Compile dan Run


- Compile tanpa cudNN, set pada bagian berikut

- Compile dengan cudNN, set pada bagian berikut:

238
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Running dari cmd (utk deteksi objek dari multi citra) ke-1:
Ketikkan di cmd: 01darknetY2CU8.exe detector test data/coco.data
yolo.cfg yolo.weights -i 0 -thresh 0.3

- Running dari cmd (utk deteksi objek dari multi citra) ke-2:
Ketikkan di cmd: 01darknetY2CU8.exe detector test data/coco.data
yolo.cfg yolo.weights -i 0 -thresh 0.3

Note: Pada sebagian bentuk ellips diidentifikasi sebagai frisbee (piring terbang) :D

239
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Log hasil running 1 dan 2:


E:\Data Kuliah\!Genap 2017-2018\1. Pemrograman
GPU\CUDAvs2015\012_CreateUse_libdll_CU\01darknetY2CU8\test>01darknetY2CU8.exe detector
test data/coco.data yolo.cfg yolo.weights -i 0 -thresh 0.3
layer filters size input output
0 conv 32 3 x 3 / 1 416 x 416 x 3 -> 416 x 416 x 32
1 max 2 x 2 / 2 416 x 416 x 32 -> 208 x 208 x 32
2 conv 64 3 x 3 / 1 208 x 208 x 32 -> 208 x 208 x 64
3 max 2 x 2 / 2 208 x 208 x 64 -> 104 x 104 x 64
4 conv 128 3 x 3 / 1 104 x 104 x 64 -> 104 x 104 x 128
5 conv 64 1 x 1 / 1 104 x 104 x 128 -> 104 x 104 x 64
6 conv 128 3 x 3 / 1 104 x 104 x 64 -> 104 x 104 x 128
7 max 2 x 2 / 2 104 x 104 x 128 -> 52 x 52 x 128
8 conv 256 3 x 3 / 1 52 x 52 x 128 -> 52 x 52 x 256
9 conv 128 1 x 1 / 1 52 x 52 x 256 -> 52 x 52 x 128
10 conv 256 3 x 3 / 1 52 x 52 x 128 -> 52 x 52 x 256
11 max 2 x 2 / 2 52 x 52 x 256 -> 26 x 26 x 256
12 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512
13 conv 256 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 256
14 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512
15 conv 256 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 256
16 conv 512 3 x 3 / 1 26 x 26 x 256 -> 26 x 26 x 512
17 max 2 x 2 / 2 26 x 26 x 512 -> 13 x 13 x 512
18 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024
19 conv 512 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 512
20 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024
21 conv 512 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 512
22 conv 1024 3 x 3 / 1 13 x 13 x 512 -> 13 x 13 x1024
23 conv 1024 3 x 3 / 1 13 x 13 x1024 -> 13 x 13 x1024
24 conv 1024 3 x 3 / 1 13 x 13 x1024 -> 13 x 13 x1024
25 route 16
26 conv 64 1 x 1 / 1 26 x 26 x 512 -> 26 x 26 x 64
27 reorg / 2 26 x 26 x 64 -> 13 x 13 x 256
28 route 27 24
29 conv 1024 3 x 3 / 1 13 x 13 x1280 -> 13 x 13 x1024
30 conv 425 1 x 1 / 1 13 x 13 x1024 -> 13 x 13 x 425
31 detection
Loading weights from yolo.weights...Done!
Enter Image Path: data/horses.jpg
data/horses.jpg: Predicted in 0.761000 seconds.
horse: 72%
horse: 90%
horse: 69%
horse: 85%

SRC output_video = 0000000000000000

cvCreateVideoWriter, DST output_video = 0000022F9A347700

cvWriteFrame
Enter Image Path: data/1.jpg
data/1.jpg: Predicted in 0.593000 seconds.
person: 31%
person: 64%
person: 37%
person: 59%
person: 79%
person: 84%
frisbee: 58%
person: 82%
person: 87%
person: 85%
frisbee: 60%
person: 79%
person: 62%
person: 73%
person: 79%
horse: 36%

cvWriteFrame

240
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Running dari cmd (utk deteksi objek dari multi citra) ke-3:
Ketikkan di cmd: 01darknetY2CU8.exe detector test data/coco.data
yolo.cfg yolo.weights -i 0 -thresh 0.3

Note: Bagus juga pada citra dengan sedikit atau banyak cahaya :D

- Running dari cmd (utk deteksi objek dari multi citra) ke-4:
Ketikkan di cmd: 01darknetY2CU8.exe detector test data/coco.data
yolo.cfg yolo.weights -i 0 -thresh 0.3

Note: Pada sebagian belum teridentifikasi, misal monas, person yang ukurannya kecil (perlu
dilakukan training dengan menambah, misal 1 kelas, misal monas dan mengoptimalkan
parameter yang digunakan untuk mengenali person yang terlihat kecil) :D

241
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Running dari cmd (utk deteksi objek dari video):


Ketikkan di cmd: 01darknetY2CU8.exe detector demo data/voc.data
tiny-yolo-voc.cfg tiny-yolo-voc.weights test.mp4 -i 0

- Project “01darknetY2CU8” dengan kode program yolo-darknet


dapat di-download dari link “http://bit.ly/2I0fDWd”

- Setelah Download project dari link “http://bit.ly/2I0fDWd”.


Ekstraks file di atas, jika menggunakan OpenCV dan CUDA
9.0/9.1/9.2 atau lainnya, maka sebelum menjalankan project, maka
setting terlebih dahulu file “01darknetY2CU8.vcxproj”
o Sesuaikan letak folder opencv-nya
o Sesuaikan letak CUDA-nya

242
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Cari dan Ubah, misal seperti berikut:


o BuildCustomizations\CUDA 8.0.props 
BuildCustomizations\CUDA 9.0.props
o BuildCustomizations\CUDA 8.0.targets 
BuildCustomizations\CUDA 9.0.targets
- Simpan, lalu “Reload All”. Jika tidak bisa, coba dengan Close Visual
Studio anda, lalu open lagi “darknet.sln”

9.4 Solusi Error saat Compile dan Run


- Jika muncul error “Failed to createproject”:
The template path ‘C:\ProgramData\NVIDIA GPU Computing
Toolkit\v9.0\extras\visual_studio_integration\CudaProjectVsWizard
s\Templates\Projects\CUDA\CudaRuntime\...’

Solusi, copykan 1 file “...” ke “...”

243
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

- Jika muncul error “CUDA error: invalid device function”:


CUDA error: invalid device function

Solusi 1 of 2: ubah “Code Generation” anda, cek dari arsitektur GPU


NVIDIA anda, termasuk “fermi”, “kepler” atau lainnya, cek dari link
berikut “http://bit.ly/2r8C9BL”, misal kartu GPU NVIDIA anda
“Geforce GT 635M 2GB”, cltr+f, ketikkan “635M”, tekan enter
maka akan muncul tipe micro-arsitekturnya, yaitu “fermi” dan code
generation-nya “2.0” atau “2.1” (dalam visual studio ditulis:
“compute_20,sm_20; compute_21,sm_21” )

244
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Solusi 2 of 2: ubah “Code Generation” anda, misal dari


“compute_30,sm_30;compute_52,sm_52” menjadi
“compute_20,sm_20; compute_21,sm_21” atau cukup dengan
“compute_20,sm_20”

Klik OK

245
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

9.5 Tugas Kelompok


1. Jalankan kembali contoh project “01darknetY2CU8” pada slide
sebelumnya, dalam folder solution utama kelompok, misal
“VSCudaCLKel-[..]-Kelas-[..]”, buat folder solution
“012_CreateUse_libdll_CUKel[..]”, buat project dengan nama
“01darknetY2CUKel[..]”, link kode contoh
“http://bit.ly/2I0fDWd”. Compile di Visual Studio, dan capture
hasil running-nya!
2. Modif dari no. 1, dalam folder solution utama kelompok, misal
“VSCudaCLKel[..]-Kelas-[..]”, dalam folder solution
“012_CreateUse_libdll_CUKel[..]”, buat project dengan nama
“02darknetY2CUKel[..]”, dengan ketentuan sebagai berikut
o Lakukan pengolahan minimal 4 citra dari foto selfi kelompok,
dan berikan analisis hasilnya
o Lakukan pengolahan minimal 1 video kelompok, dan berikan
analisis hasilnya

246
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

BAB 10 Project Pilihan


Pemrograman GPU

10.1 CUDA Pada Game 3D SandboxCraft


CPU dapat disebut juga sebagai Central Processing Unit yang
dipakai untuk melakukan suatu fungsi yang dibutuhkan untuk
menjalankan sebuah proses. CPU mengeksekusi suatu proses seperti
perhitungan aritmatika, kalkukasi di Excel dan operasi yang
berhubungan dengan matematis lainnya. Video games membutuhkan
CPU untuk melakukan proses yang berfungsi menentukan kalkulasi
khusus untuk game.
GPU (Graphical Processing Unit) adalah suatu komponen yang
mempunyai hubungan dengan proses dari segi tampilan. Komputer
dapat berfungsi atau berjalan tanpa GPU (Nvidia, 2017), namun yang
sering terjadi adalah pada ketidakmampuan menampilkan apapun di
layar atau monitor. GPU sendiri tersedia dalam berbagai jenis, bentuk,
maupun ukuran serta berbentuk lempengan atau yang biasanya pada
umumnya sering disebut dengan card dan dapat dicolokkan ke dalam
slot PCI-Express pada motherboard di desktop, hingga bentuk yang lain
yaitu chip onboard yang tertanam di dalam motherboard secara
langsung disebut dengan integrated graphic chip. Perbedaan yang
jelas diantara CPU dan GPU adalah kegunaan GPU yang khusus untuk
melakukan pemrosesan grafis dan mempunyai kemampuan untuk
melakukan perhitungan hingga banyak kalkulasi per detik. Jumlah
banyaknya core yang terdapat di dalam perangkat GPU itu sendiri
tergantung dari masing-masing vendor di market. Hingga sekarang
nVidia memiliki spesifikasi yang cukup tinggi pada setiap graphic chip
yang mereka tawarkan meski jumlahnya tidak banyak, sementara itu
graphic chip dari pabrikan lain yang menjadi penantang dari nVidia
yaitu AMD (Advanced Micro Devices) memiliki banyak chip yang
tertanam di dalam kartu grafisnya untuk meningkatkan performa dari
pengolahan grafis. Kartu grafis sendiri memiliki kelas masing-masing,
tipe high-end biasanya memiliki 68 core yang tertanam untuk nVidia,
sementara AMD memiliki jumlah hingga 1500 core.
Video game memiliki berbagai jenis maupun tipe permaianan
yang ditawarkan. Jenis sandbox adalah game yang membebaskan

247
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

pemain untuk melakukan apapun dan menjelajahi dunia dalam game


tersebut sesuka hati. (Adams dan Ernest, 2010) Seperti pada game
Minecraft, terdapat blok-blok yang disusun secara rapi untuk
membentuk dunia dari game tersebut. Sama layaknya pada game The
Elder Scroll Skyrim. Pemain dihadapkan dengan dunia masa
lalu/medieval dimana pemain dapat menelusuri game tersebut tanpa
ada batas. Melalui pengamatan dari game-game tersebut, kita dapat
mengambil kata kunci dari game berjenis sandbox yaitu dunia atau
dalam kata lain game environment.
Game environment adalah dunia yang dikembangkan dalam
game untuk dijelajahi. Hal ini merupakan gabungan dari banyak
elemen yang saling bekerja sama untuk dapat membangun sebuah
kedalaman desain serta perasaan bahwa dunia ini layaknya nyata.
Komponen tersebut antara lain desain environment, proyeksi cahaya,
bayangan, tekstur teraplikasi, partikel, serta material dari objek dalam
environment. Dari kebuntuan ini, CPU mengalami kesulitan dalam
mengelola semua komponen di atas. Dibutuhkannya kerja sama antar
CPU dengan perangkat pada GPU sehingga kerja pada CPU dalam
pertukaran data dapat lebih mudah. Namun, desain game
environment yang semakin hari semakin luas dan semakin detail
berdampak kepada performa dari game tersebut apakah game
memiliki loading dunia yang cepat atau lambat.
Game berjenis sandbox memiliki tipikal dengan rendering
dunia/environment yang luas serta detail. Maka dari itu, dibutuhkan
sebuah optimasi agar rendering dapat melakukan proses yang lebih
cepat dan terasa real-time. Namun, untuk mendapatkan kecepatan
render, dibutuhkan kerjasama antar CPU dan GPU dalam prosesnya.
Oleh karena itu, perlu dilakukan simulasi untuk render dengan CPU dan
CPU bersama GPU. Simulasi dilakukan dalam platform C++ dan NVIDIA
CUDA dengan bantuan OpenGL serta library yang mendukung
pengerjaan.
10.1.1 Dasar Teori
o Tentang OpenGL
OpenGL adalah API tingkat rendah (Application Programming
Interface), yang memungkinkan programmer, memakai antarmuka
untuk perangkat keras grafis (GPU) . OpenGL tidak menyediakan
fungsionalitas tingkat tinggi seperti pada fungsi antarmuka untuk
perangkat keras lainnya. OpenGL hanya menangani grafis. Keuntungan

248
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

utama yang dimiliki OpenGL di atas API grafis lainnya adalah platform
berjalan pada berbagai platform. OpenGL dapat berjalan di Windows,
Linux, Mac OSX.
Konsep awal dari game loop adalah memproses input dari user
tapi tidak menunggu dan selalu melakukan loop secara terus menerus.
Hal tersebut membuat sebuah CPU menjadi lebih berat. Pada gambar
1 terdapat icon waktu yang menandakan sleep untuk menahan ke-
cepatan loop agar sesuai pada tiap framenya. Menahan kecepatan
loop tersebut nantinya akan di proses menjadi sebuah fps.
o Pemrograman GPU
Pemrograman GPU memiliki tujuan tidak hanya untuk mengolah
grafis melainkan juga dapat untuk tujuan umum, misal komputasi
ilmiah menggunakan machine learning dan rekayasa lainnya pada
game development, etc. dengan framework tertentu, misal CUDA.

Gambar 10.1 Nvidia CUDA


CUDA adalah sebuah API yang dikembangkan oleh Nvidia yang
digunakan untuk melakukan suatu komputasi yang dapat berjalan
secara paralel atau dengan kata lain secara bersama-samaan. Para de-
veloper dapat menggunakan CUDA untuk pemrosesan tujuan umum
atau disebut dengan pendekatan GPGPU (komputasi General-purpose
on GPU). Platform CUDA merupakan lapisan akses pada perangkat lu-
nak atau software yang memberikan langsung ke set instruksi virtual
GPU untuk kernel pelaksanaan penghitungan.
Platform CUDA dirancang untuk bekerja dengan bahasa pem-
rograman seperti C, C ++, dan Fortran. Aksesibilitas ini memudahkan
para spesialis dalam pemrograman paralel untuk menggunakan sum-
ber daya GPU, berbeda dengan API sebelumnya seperti Direct3D dan
OpenGL, yang memerlukan keterampilan lanjutan dalam pem-
rograman grafis. Selain itu, CUDA mendukung framework pem-
rograman seperti OpenACC dan OpenCL. Ketika pertama kali diperke-
nalkan oleh Nvidia, nama CUDA adalah akronim dari Compute Unified
Device Architecture, namun Nvidia kemudian menjatuhkan
penggunaan akronim tersebut.

249
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

o Grid, Block, dan Thread


Dalam sebuah grid terdapat block-block. Dan pada masing-mas-
ing block terdapat thread-thread. Grid sendiri ialah sebuah grup dari
block-block. Yang dimana block-block tersebut tidak terjadi sebuah
proses synkronisasi antar block. Block adalah sebuah grup dari thread.
Thread-thread ini dapat berjalan concurrent atau pun secara seri
dengan urutan yang tidak pasti. Dengan menggunakan fungsi __sync-
threads() dapat membuat sebuah thread dapat berhenti pada titik ter-
tentu di dalam kernel sampai proses lainnya juga sampai pada titik
yang sama tersebut. Thread adalah sebuah eksekusi dari kernel
dengan sebuah index yang diberikan/ditentukan. Setiap thread akan
menggunakan index tersebut untuk mengakses element di dalam array
seperti koleksi-koleksi dari semua thread yang bekerja sama pada
semua data set.
10.1.2 Implementasi
Dikarenakan game ini 3D dan menggunakan banyak matrix dan
vector. Dibuatnya sebuah class matrix untuk menghandle fungsi-fungsi
penggunaan matrix pada umumnya, dimana pada c++ menggunakan
array 1 dimensi dan membutuhkan banyak pengulangan. Terdapat se-
buah proses perkalian matrix mat_multiply pada Game craft yang
digunakan untuk perkalian matrix untuk perhitungan penyimpanan
matrix 3d pada game di method set_matrix_3d pada matrix.c yang
masih menggunakan CPU.

Gambar 10.2 Tampilan Game Craft

250
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1 void mat_vec_multiply(float *vector, float *a, float *b) {


2 float result[4];
3 for (int i = 0; i < 4; i++) {
4 float total = 0;
5 for (int j = 0; j < 4; j++) {
6 int p = j * 4 + i;
7 int q = j;
8 total += a[p] * b[q];
9 }
10 result[i] = total;
11 }
12 for (int i = 0; i < 4; i++) {
13 vector[i] = result[i];
14 }
15 }

Kode di atas dapat dirubah menjadi menggunakan GPU


dengan menggunakan perhitungan konsep parralel programming di-
mana akan menggunakan thread pada GPU untuk perhitungan setiap
result jadi perkalian akan di handle oleh thread sehingga tidak perlu
menggunakan banyak pengulangan dan penggunaan CPU akan men-
jadi lebih rendah dari CPU.Penggunaan jumlah Grid 1,Blok 1, dan
Thread 2x2; pada Kode program di bawah ini.
1 __global__ void mat_vec_multiply(float *vector, float *a,
2 float *b) {
3 int kolom = threadIdx.x; // threadIdx adalah thread Index
4 int baris = threadIdx.y;
5 float c = 0;
6 int ordoMat = 4;
7 for (int k = 0; k < ordoMat; k++) {
8 c += a[baris*ordoMat + k] * b[k*ordoMat + kolom];
9 }
10 vector[baris*ordoMat + kolom] = c;
11 }

Penjelasan dari Kode Program di atas:


1. Baris 1-2 merupakan deklarasi fungsi kernel mat_vec_multiply
2. Baris 3 deklarasi kolom mengunakan threadIdx.x dan baris
menggunakan threadIdx.y untuk perhitungan matrix.
3. Baris 4 deklarasi c sebagai penyimpan hasil perhitungan se-
mentara.
4. Baris 5 deklarasi hasil dari perkalian ordo matrix dimana game
menggunakan ordo 2 x 2 yaitu 4.
5. Baris 6-8 proses perhitungan dengan thread GPU yang di loop-
ing agar hasil dari perkalian dapat dijumlahakan sebagai hasil.
6. Baris 11 proses memasukan hasil perkalian ke dalam pointer
vector yang nantinya akan dipakai pada perhitungan selanjut-
nya pada game

251
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Lalu, untuk menjalankan kode tersebut dibutuhkan perpindahan vari-


able pada memori CPU ke GPU menggunakan cudaMemCpy agar
dapat di proses pada method kernel. Kode program di bawah ini.
1 int jumlahBlock = 1;
2 dim3 threadPerBlock(2, 2);
3 ……………………
4 cudaMemcpy(d_A, h_A, sizeof(float) * jumlahElemen,
5 cudaMemcpyHostToDevice);
6 cudaMemcpy(d_B, h_B, sizeof(float) * jumlahElemen,
7 cudaMemcpyHostToDevice);
8 mat_vec_multiply << < jumlahBlock, threadPerBlock >> >
9 (d_HasilPerkalian, d_A, d_B);
10 cudaThreadSynchronize();
11 cudaMemcpy(h_HasilRef, d_HasilPerkalian, sizeof(float) *
jumlahElemen, cudaMemcpyDeviceToHost);

Penjelasan dari Kode Program di atas:


1. Baris 1-2 merupakan deklarasi grid, blok, dan thread. grid
1,blok 1 , dan thread 2 x 2.
2. Baris 4-5 copy variabel pada host ke device.
3. Baris 7-8 pemanggilan method device.
4. Baris 6 deklarasi hasil dari perkalian ordo matrix dimana game
menggunakan ordo 2 x 2 yaitu 4.
5. Baris 9 mengsinkronkan thread pada device agar selesai ber-
barengan.
6. Baris 10 copy variabel hasil pada device ke host

252
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

10.2 CUDA Pada Game 2D Asteroids


Zaman Modern ini banyak sekali hiburan yang bisa dilakukan
disaat senggang untuk menghilangkan penat. Salah satu cara yang
paling praktis, populer, dan hampir bisa dilakukan dimana saja serta
tersedia di hampir semua platform seperti mobile, desktop, laptop dan
console, adalah video game. Video game sangat diminati oleh
masyarakat, hal ini disebabkan karena game dapat menyuguhkan
cerita, baik secara visual maupun audio, dan user dapat melakukan
interaksi langsung ke dalam cerita. Tidak sedikit pemain video game
yang hanya bermain untuk mendapatkan kesenangan semata atau
menghabiskan waktu luang, hal ini dibuktikan dengan meningkatnya
kebutuhan video game dari tahun ke tahun dengan jumlah pemain
video game yang mencapai pada angka 1,3 miliar.
Di pihak produsen game sendiri, ini merupakan perilaku yang
menguntungkan bagi mereka, yaitu dengan memperluas pasar
penjualan video game. Namun, kondisi ini tentunya harus diimbangi
dengan peningkatan kualitas produksi video game oleh pihak industri,
salah satunya ialah dengan cara memanfaatkan kemampuan
perangkat keras yang tersedia sehingga performa dari video game
yang dimainkan dapat dijalankan oleh pemain dengan selancar mung-
kin. Dengan semakin optimalnya sebuah video game, maka dapat
dipastikan luas pasar yang dapat dijangkau semakin besar.
Salah satu cara untuk meningkatkan kualitas hasil dari video game
sehingga optimal adalah dengan menggunakan parallel processing.
Parallel processing digunakan agar dapat melakukan komputasi secara
paralel sehingga dapat meningkatkan jumlah frame yang diproses da-
lam satu detik sehingga meningkatkan performa video game secara
signifikan.
Pemrogramn GPU mencakup konsep dasar GPU Programming,
pembahasan lebih mendalam mengenai pemrograman menggunakan
teknik paralel berbasis GPU, implementasi terkait beberapa
kebutuhan teknologi terkini, yang meliputi deep learning, self-driving
cars, virtual reality, game development, accelerated computing, design
& visualization, automous machines, dengan melakukan komputasi
secara cepat dan tepat, serta dapat mengintegrasikan teknik parallel
terhadap kebutuhan teknologi masa depan dengan mengambil
potensi dari pengolahan data yang cepat untuk membantu
meningkatkan hasil yang lebih akurat.

253
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Tujuan diadakannya penelitian yang menjadikan video game


Asteroids sebagai objek penelitiannya adalah untuk meningkatkan
performa video game secara umum. Proses peningkatan performa dari
video game adalah dengan memanfaatkan interoperability dari CUDA
dan OpenGL. Hasil dari penelitian ini adalah perbedaan performa
antara video game yang memanfaatkan interoperability CUDA dan
OpenGL dibandingkan dengan video game tanpa memanfaatkan
interoperability dari CUDA dan OpenGL.

10.2.1 Dasar Teori


o Konsep Game Loop
Game loop merupakan central point dari sebuah game. Pada
tahap ini, program akan menerima input dari user, yang kemudian
akan diproses sebagai input untuk mengubah environment game dan
perubahan visual akan ditampilkan sebagai output. Sehingga terjadi
interaksi dari player. Proses ini akan dilakukan berulang dan terus
menerus sampai program dihentikan. Pada Gambar 1 merupakan
gambaran game loop berupa diagram.

o Konsep Pemrograman GPU


GPU (Graphics Processing Unit) merupakan sebuah hardware
yang dimaksudkan untuk memproses gambar pada komputer. Pada ta-
hun 2001, GPU mulai dimanfaatkan untuk keperluan komputing
umum atau non-grafis. Kelebihan utama dari GPU dibandingkan
dengan CPU adalah core GPU yang berjumlah sampai ribuan buah. Hal
ini membuat waktu proses menjadi lebih singkat dan efisien dengan

254
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

memanfaatkan banyaknya core untuk membagi dan memproses data


secara bersamaan dalam satu waktu.
Untuk dapat meng-utilisasi kemampuan dari GPU harus ada
jembatan untuk menghubungkan program dengan hardware GPU.
Setidaknya ada 3 API untuk memanfaatkan GPU, yakni CUDA dari
Nvidia, OpenCL dari Khronos, dan DirectCompute dari Microsoft. Da-
lam paper ini, API yang digunakan adalah Nvidia CUDA.

o CUDA
CUDA merupakan sebuah platform dan programming untuk
komputasi paralel yang dikembangkan oleh Nvidia. CUDA difokuskan
untuk mengambil keuntungan sepenuhnya dari GPU Nvidia. Berbeda
dengan OpenCL yang mampu memanfaatkan GPU non-Nvidia (AMD,
Intel, Mali, dsb). CUDA memungkinkan kita untuk melakukan parallel
computing menggunakan GPU untuk keperluan non grafis.
CUDA sendiri didesain untuk diprogram pada bahasa pem-
rograman C, C++, dan Fortan. Selain itu, CUDA juga mendukung API
seperti OpenCL, hal ini memungkingkan kita untuk menggunakan API
CUDA jika pada platform yang menggunakan GPU Nvidia, dan
menggunakan API OpenCL pada platform non Nvidia seperti AMD, In-
tel, Mali, dan PowerVR.

255
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

10.2.2 Implementasi
Game yang dilakukan proses improvement adalah game 2D As-
teroids dimana player dapat berjalan pada layar game. Di dalam se-
buah game pasti memiliki main loop. Pada main loop tersebut, sebuah
proses pasti dilakukan secara berulang. Pada game loop yang terdapat
pada game Asteroids diatas, terdapat beberapa method untuk
melakukan update objek yang terdapat pada game. Salah satunya
yaitu melakukan update pada array asteroids. Update yang dilakukan
yaitu berupa update posisi dan rotasi dari asteroids. Code for-loop
yang menggunakan CPU untuk melakukan update rotasi dan posisi as-
teroids ada pada file Asteroids.c.

Gambar 10.3 Hasil Running Game Asteroid 2D

1 /* advance asteroids and update their rotation */


2 for (int i = 0; i < MAX_ASTEROIDS; i++) {
3 if (asteroids[i].active == 1) {
4 asteroids[i].x = asteroids[i].x + (asteroids[i].dx);
5 asteroids[i].y = asteroids[i].y + (asteroids[i].dy);
6 asteroids[i].phi = asteroids[i].phi +
7 asteroids[i].dphi;
8
9 if (asteroids[i].x < 0) {
10 asteroids[i].x = xMax;
11 } else if (asteroids[i].x > xMax) {
12 asteroids[i].x = 0;
13 } else if (asteroids[i].y < 0) {
14 asteroids[i].y = yMax;
15 } else if (asteroids[i].y > yMax) {
16 asteroids[i].y = 0;
17 }
18 }
19 }

Penjelasan dari kode CPU diatas adalah sebagai berikut:


1. Baris 2 for-loop untuk mengakses seluruh asteroid
2. Baris 3 seleksi untuk hanya merubah asteroids yang memiliki
status aktif adalah true

256
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

3. Baris 4 dan baris 5 untuk melakukan update posisi asteroids


bersadarkan secepatan masing-masing asteroids
4. Baris 6 untuk melakukan update rotasi dari asteroids
5. Baris 7-17 melakukan seleksi apabila asteroids keluar dari bor-
der, maka akan dipindahkan diseberangnya
Kode di atas dapat diubah agar dapat menggunakan GPU untuk
melakukan update dari asteroids yang terdapat pada game. Dalam ka-
sus ini for-loop akan dihilangkan dan akan diproses oleh masing-mas-
ing thread yang terdapat pada GPU. Hasil perubahan dari kode CPU
diatas terdapat pada Kode Program di bawah ini.
1 __global__ void updateAsteroidsGPU (Asteroid * asteroids, int
2 xMax, int yMax) {
3 int i = threadIdx.x;
4 if (asteroids[i].active == 1) {
5 asteroids[i].x = asteroids[i].x + (asteroids[i].dx);
6 asteroids[i].y = asteroids[i].y + (asteroids[i].dy);
7 asteroids[i].phi = asteroids[i].phi +
8 asteroids[i].dphi;
9
10 if (asteroids[i].x < 0) {
11 asteroids[i].x = xMax;
12 } else if (asteroids[i].x > xMax) {
13 asteroids[i].x = 0;
14 } else if (asteroids[i].y < 0) {
15 asteroids[i].y = yMax;
16 } else if (asteroids[i].y > yMax) {
17 asteroids[i].y = 0;
18 }
19 }
}

Penjelasan dari kode program CUDA ke-1:


1. Baris 1 mendeklarasikan method kernel updateAsteroidsGPU
2. Baris 2 mendapatkan threadIdx.x kemudian dimasukkan ke
variable i
3. Baris 3-13 merupakan hasil copy-paste dari kode CPU yang di
dalam loop

257
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

10.3 CUDA Pada Game 2D Salmon Vs


Turtles
Game ini berlatar belakang Opengl, sehingga semua fungsi-
fungsi dalam Game ini seperti rendering objek, texture maping,
controller input ditangani semua menggunakan opengl yang diproses
dalam CPU, sehingga dalam optimalisasinya rendah karena tidak
menggunakan GPU yang notabene mampu melakukan proses
rendering atau texture maping yang cepat dan ringan karena jumlah
core yang banyak. Melakukan texture maping menggunakan CPU
tergolong berat karena jumlah core CPU yang terbatas, berbeda
dengan jumlah core GPU yang banyak.
Permasalahan yang sedang diteliti adalah sebuah game, di
mana permasalahan pada game-game saat ini adalah kurangnya
optimisasi pada permainan. Kebanyakan game-game saat ini
menggunakan CPU dan GPU untuk memproses suatu objek dalam
game, seperti memproses sebuah karakter dalam game, ataupun
dunia dalam game tersebut. Maka muncul sebuah solusi dari
perusahaan grafis yang terkenal di dunia yaitu Nvidia mengembangkan
sebuah SDK salah satunya CUDA. CUDA adalah sebuah SDK yang
memungkinkan sebuah objek di dalam game langsung diproses
menuju GPU. Dan juga CUDA dapat digunakan sebagai parallel
programming. Dikarenakan CUDA menggunakan GPU untuk
memproses sebuah data, maka dalam permasalahan dalam
pengembangan game dapat teratasi menggunakan CUDA.
Dikarenakan prosesor hanya memiliki beberapa core saja. Jumlahnya
sebuah core pada CPU tidak sampai 10. Maka untuk pemrosesan
sebuah game, CPU cukup terbebani dengan pemrosesan sebuah
algoritma dalam game. Maka solusinya adalah menggunakan GPU.
Dikarenakan GPU memiliki jumlah core yang jumlahnya ratusan. Maka
untuk memproses sebuah algoritma dapat teratasi.
Metode yang akan digunakan dalam Game ini adalah metode
texture maping menggunakan CUDA/ Texture maping yang
menggunakan CUDA ini akan menggunakan GPU dalam proses texture
maping sehingga proses komputasinya cenderung lebih cepat
daripada menggunakan CPU. Karena Game ini menggunakan OpenGL
1.0, di akhir nanti kita akan analisis apakah optimasi ini dapat
berpengaruh jika diterapkan dalam Game ini.

258
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

10.3.1 Dasar Teori


o General Purpose Computing
Dahulu GPU hanya digunakan untuk memproses sebuah grafik.
GPU memiliki dua fitur yaitu ratusan core yang dapat digunakan untuk
paralel programming seperti pada Gambar di bawah ini. Dan bandwith
memory yang lebar disediakan oleh GPU untuk kualitas pengiriman
data lebih baik. Ketika performa komputasi yang tinggi dilakukan maka
munculah konsep GPGPU (General Purpose On Graphic Processing
Unit) dari Nvidia.

Baru-baru ini kapasitas komputasi dari GPU meningkat secara


exponen. Didasari dari sebuah struktur Single-instruction Multiple
Data (SIMD), GPU cocok untuk komputasi yang berjalan secara insentif
dan mampu berjalan di samping komputasi grafik, mengenali sebuah
nilai dari GPGPU, vendor GPU menambah dukungan driver dan
perangkat keras untuk digunakan perangkat keras paralel yang tinggi
dari GPU tanpa membutuhkan komputasi yang lama untuk
memproses beberapa graphic pipeline (transform, vertice, rasteriza-
tion, etc) dan tanpa membutuhkan API 3D apapun.

o CUDA
CUDA adalah sebuah arsitektur komputer paralel yang dikem-
bangkan oleh perusahan besar yang memiliki basis Graphic Card, yaitu
NVIDIA dan diluncurkan pada tahun 2007. Tujuan dari CUDA adalah
menyediakan arsitektur yang mudah digunakan untuk pemrosesan
secara paralel. Yang hanya dapat dijalankan oleh GPU NVIDIA. Periset
dan pengembang dapat menggunakan GPU yang bertenaga dengan
hanya menggunakan bahasa pemrograman yang sederhana dan syn-
tax tambahan CUDA. CUDA menyediaan dua jenis API, termasuk

259
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Runtime API dan Driver API. CUDA juga merupakan extensi minimal
dari bahasa pemrograman C dan C++. Programmer menulis program
secara seri yang dapat memanggil kernel paralel, yang dapat berupa
fungsi sederhana atau program yang utuh.
Arsitektur GPU yang mendukung CUDA meningkat perkem-
banganya dari arsitektur Tesla (Compute Capability 1.0) menuju gen-
erasi Fermi (Compute Capability 2.0). GPU basis Fermi mendukung
presisi ganda, mekanisme caching dan concurrent kernel execution.
Pada tahun 2012, arsitektur kepler(Compute Capability 3) Diluncurkan
dan menjadi batu loncatan dalam pemrograman GPU yang mendkung
beberapa fitur baru yang diimplementasi, yaitu dynamic parallelism
dan bindless texture object.
o OpenGL
OpenGL pada masa sekarang pengembanganya bagus untuk
perangkat lunak pencitraan tiga dimensi, yang dikembangkan oleh SGI
yang pengembanganya menyasar workstation berperforma tinggi, in-
tinya grafik dan interface perangkat lunak terdiri dari lebih dari 100
fungsi graphic, diantaranya pemodelan, transformasi, pemrosesan ca-
haya, pemrosesan warna, animasi dan texture mapping yang lebih
baik, fungsi motion blur pada objek, pengembang dapat menggunakan
fungsi tersebut untuk membuat model tiga dimensi dan interaksi tiga
dimensi secara nyata. Grafik tiga dimensi pada openGL menjadi
standar universal dan openGL juga dapat dijalankan pada sistem
operasi windows.

Para pengembang library OpenGL sesungguhnya biasanya ada-


lah perakit kartu grafis. Setiap kartu grafis yang anda beli mendukung
versi spesifik dari openGL dimana setiap versi di kembangkan opengl
dikhususkan untuk seri kartu grafis. Ketika menggunakan system Apple
maka library OpenGL dirawat oleh Apple sendiri dan dibawah Linux
ada kombinasi antara pemasok grafis dan penghobi yang mengadap-
tasi library-nya. Ini berarti apabila OpenGL menampilkan perlakuan
aneh atau yang tidak seharusnya, kebanyakan kesalahan perakit kartu
grafis untuk pengembangan/perawatan library. Banyak metode untuk

260
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

mengintegrasikan OpenGL pada pengembangan program untuk sis-


tem operasi seperti Windows atau linux. Metode yang digunakan ada-
lah OpenGL utility toolkit(GLUT). GLUT adalah sistem pengatur jendela
independen untuk menulis program OpenGL.

10.3.2 Implementasi
Gambar berikut adalah tampilan in-game Salmon Vs Turtles
ketika pada awal game dan ketika salmon bertabrakan dengan turtle,
bagian tertentu dari objek yang akan dioptimasi prosesnya.

Proses ini merupakan proses membuat objek lingkaran pada


mata objek salmon pada game. Pada cara awal sebelum optimasi, un-
tuk membuat lingkaran pada mata salmon menggunakan for seperti
dibawah.
1 glBegin(GL_POLYGON);
2 for (int i = 0; i <=360; i++)
3 {
4 float degInRad = i*DEG2RAD;
5 glVertex2f(cos(degInRad)*5, sin(degInRad)*5);
6 }
7 glEnd();

Penjelasan dari kode program di atas:


1. Baris 1 Merupakan insialisasi pembuatan lingkaran dari poly-
gon menggunakan glBegin
2. Baris 2-6 merupakan set koordinat masing-masing vertex pem-
bentuk lingkaran menggunakan for
3. Baris 7 merupakan penutupan pembuatan lingkaran dari poly-
gon menggunakan glEnd
Method Global yang berada di file cuda digunakan untuk men-
goptimasi game untuk pembuatan objek lingkaran.

261
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1 __global__ void mykernelx(float2 *A, int r) {


2 int tid = (threadIdx.y * 20) + threadIdx.x;
3
4 A[tid] = make_float2(cos(tid*3.14159 / 180) * r,
5 sin(tid*3.14159 / 180) * r);
6
7 }

Penjelasan dari kode program di atas:


1. Baris 1, nama method Global yang digunakan adalah myker-
nelx dengan parameter float2 *A yang akan diisi dengan vertex
penyusun lingkaran dan int r merupakan jari-jari lingkaran
2. Baris 2 merupakan set id dari masing-masing thread yang ber-
beda
3. Baris 4 pengisian vertex penyusun lingkaran pada array A di
masing-masing thread

Method yang nantinya akan dipanggil oleh file cpp dan


mengembalikan array vertex ke file CPP adalah method berikut:
1 float2 * vertices_kernelx(int r) {
2
3
4 unsigned int jumlahElemen = N * N;
5 float2 *h_Hasilx; // h --> host
6 float2 *d_Hasilx; // d --> device
7
8 h_Hasilx = (float2 *)malloc(sizeof(float2)*
9 jumlahElemen); //hasil hitungan GPU
10
11 cudaMalloc((void **)&d_Hasilx, sizeof(float2)*
12 jumlahElemen);
13
14 int jumlahBlock = 1;
15 dim3 threadPerBlock(N, N);
16 mykernelx << <jumlahBlock, threadPerBlock >>
17 >(d_Hasilx,r);
18 cudaDeviceSynchronize();
19
20
21 cudaMemcpy(h_Hasilx, d_Hasilx, sizeof(float2)*
22 jumlahElemen, cudaMemcpyDeviceToHost);
23 return h_Hasilx;
24 }

Penjelasan dari kode program di atas:


1. Baris 1, nama method yang digunakan adalah vertices_kernelx
dengan parameter int r merupakan jari-jari lingkaran

262
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

2. Baris 4-11 variabel jumlah elemen array vertex yang ingin


dibuat sebanyak 20x20=400 vertex dan float2 *d_Hasilx dan
h_Hasilx merupakan array vector2 vertex.
3. Baris 13-17 memanggil method kernel mykernelx dengan block
1 dan thread perblock 20x20 lalu melakukan sinkroniasasi
CUDA
4. Baris 20-22 melakukan copy dari variabel Device d_Hasilx ke
variabel Host h_Hasilx dan mengembalikan nilai h_Hasilx

Gambar 10.4 Hasil running Game 2D Salmon Vs Turtles

263
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

10.4 CUDA Pada Game Breakout


Breakout adalah game untuk platform arcade yang diluncurkan
pada tahun 1972 oleh perusahaan ternama Atari. Didasari dan
terinspirasi dari game pertama yang dibuat manusia di computer, Pong,
game ini memiliki kesamaan dimana player menggerakkan sebuah
garis lurus seperti pipa yang mengharuskan player untuk tidak
membiarkan bola yang terpantul ke dinding untuk jatuh dari platform.
Tujuan lainnya adalah untuk menghancurkan tiap dinding yang
tersedia untuk memenangkan permainan. Permainan ini sungguh
sangat terkenal pada jamannya, yang mana hampir 1.1 juta kopi game
arcade breakout terjual pada tahun 1978, nomor dua dari game space
invaders yang terjual 2.6 juta kopi pada tahun tersebut.
Game Breakout sendiri bertemakan pelolosan diri dari penjara,
yaitu dengan cara menghancurkan tiap dinding yang ada untuk
meloloskan diri. Namun seiring waktu, orang-orang yang memainkan
game ini tidak lagi mengetahui apa sebenarnya tema permainan yang
mereka mainkan, walaupun, tidak mengurangi user experience yang
mereka dapatkan dari permainan ini.
Seiring perkembangan jaman, game breakout terus menerus
dibuat perkembangannya juga untuk platform-platform yang lain
seperti Gameboy, NES, PC dan lain sebagainya hingga kini. Dan yang
terbaru adalah dari google, ketika anda mengetikkan game breakout
di google, anda juga dapat memainkannya dari komputer anda.
CUDA adalah parallel computing dan platform API yang dibuat
oleh Nvidia untuk kepentingan software development dengan
menggunakan GPU. CUDA didesain agar dapat mengkalkulasi
permasalahan grafis dimana dengan alokasi proses sekarang yang
masih multi-core, diharapkan dengan GPU yang memilii ribuan core
dapat membantu pekerjaan daripada CPU sehingga dapat
meringankan kerja CPU.
Pada penelitian ini dilakukan percobaan untuk mengubah iterasi
daripada proses dalam game Breakout yang telah ada untuk dijalankan
dengan menggunakan CUDA OpenGL, untuk mengetahui apakah
dengan menggunakan CUDA dapat meringankan dan mempercepat
laju proses serta tidak membebani CPU.

264
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

10.4.1 Dasar Teori


o Konsep Game Loop game Breakout
Breakout adalah sebuah game arcade yang dikembangkan dan
di terbitkan oleh Atari, Inc. bermula dari munculnya konsep oleh Nolan
Bushnell dan Steve Bristow yang juga dipengaruhi oleh game arcade
sebelumnya yaitu Pong, dan dibangun oleh Steve Wozniak dibantu
oleh Steve Jobs. Permainan ini dimainkan di banyak platform saat ini.
Dalam permainan ini terdapat beberapa lapisan batu bata yang
menutupi hampir sepertiga bagian atas layar. Sebuah bola yang
memantul ketika mengenai dinding samping maupun atas dan juga
papan di bagian bawah layer yang dapat digerakkan ke samping kanan
maupun kiri yang digunakan untuk memantulkan bola agar tidak jatuh
ke bawah. Saat batu bata terpukul bola akan memantul dan batu bata
akan hancur, pemain akan mendapatkan point ketika menghancurkan
batu bata tersebut. Permainan berakhir ketika bola jatuh ke bawah,
untuk mencegah hal ini, pemain harus menggerakkan papan ke
samping kiri ataupun kanan supaya bola tetap memantul ke atas.
Sehingga, dapat disimpulkan game loop pada breakout adalah seperti
terlihat pada Gambar 10.18.

o Konsep Pemrograman GPU


Graphic Processing Unit (GPU) merupakan sbeuah kartu atau
chip yang dirancang secara khusus untuk meningkatkan performa ap-
likasi komputer yang khusus menangani grafis pada komputer. Sesuai

265
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

dengan fungsi utamanya yang mengolah grafis pada computer, pada


awalnya GPU ini hanya digunakan untuk menjalankan aplikasi yang
membutuhkan komputasi grafis yang tinggi seperti halnya perangkat
lunak Computer Aided Design (CAD) dan menjalankan game. Namun
pada saat ini yang meningkatnya kebutuhan pengolah grafis pada ap-
likasi, perkembangan performa GPU juga semakin meningkat. Arsi-
tektur GPU kemudian berevolusi menjadi multiprosesor yang mampu
menjalankan sebuah program secara parallel. Dimana juga, GPU mem-
iliki ribuan core yang sangat berbeda jauh dari CPU yang hanya multi-
core.

o OpenGL
OpenGL adalah API yang dikeluarkan oleh perusahaan Silicon
Graphic Pada tahun 1992 untuk tujuan grafis. Dimana dengan OpenGL
kita dapat membuat dan me render gambar 2D maupun 3D dengan
menggunakan buffer yang telah disediakan. OpenGL melakukan ren-
dering objek 2D maupun 3D dari susunan vertex-vertex atau pixel ke
dalam frame buffer. OpenGL tidaklah menyediakan fungsi-fungsi dasar
seperti membuat windows dan sebagainya karena bergantung pada
sistemnya itu sendiri. Tetapi, ada helper seperti GLUT, SDL, dan lain
sebagainya yang dapat membantu kita untuk membuat fungsi-fungsi
dasar maupun lanjutan yang tidak disediakan oleh OpenGL. Berikut
contoh Penerapan OpenGL pada Google Sketchup

o CUDA
Compute Unified Device Architecture (CUDA) adalah sebuah
pengembangan teknologi yang dikembangkan oleh NVIDIA untuk
mempermudah penggunaan GPU untuk keperluan umum (non-grafis).
Berawal dari penelitian yang dilakukan oleh NVIDIA tentang GPGPU
(General-Purpose Computing on Graphics processing Unit) lahirlah
teknologi yang bernama CUDA. Arsitektur pada CUDA itu sendiri dil-
akukan secara parallel yang diimplementasikan ke dalam GPU besutan

266
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

NVIDIA, pada seri GPU Tesla, GeForce maupun Quadro. Saat ini CUDA
mengalami banyak perkembangan yang sangat pesat. Itu dapat dibuk-
tuikan dari banyaknya penelitian yang dilakukan, dan juga banyaknya
CUDA SDK yang diunduh dalam beberapa tahun terakhir ini.

10.4.2 Implementasi
JIka objek bola terkena objek lain, maka secara otomatis akan
mengkalkulasi akibat daripada collision tersebut, kemudian
mengupdate game objek apabila ada perubahan pada objek ketika ter-
jadi collision. Setelah itu, window direfresh dan di update sehingga se-
tiap perubahan yang terjadi pada game langsung diperlihatkan.
Setelah itu jika tidak ada kejadian lain, masuk ke sleep hingga ada ke-
jadian lain yang menimbulkan update daripada game.
Proses ini merupakan proses membuat fungsi transpose matrik
GPU yang akan digunakan dalam sistem. Diawali dengan sintaks
__global__ void fnMatrixTransGPU(float *A, float *Hasil), kemudian
membuat ID Threads unik dari threadIdx.y dan threadIdx.x. Kese-
luruhan proses tersebut ditunjukkan dari potongan kode program
berikut.
1 untuk CPU
2 for(int j = 0; j < CIRCLE_SEGMENTS; j++) {
3 float const theta = 2.0f * 3.1415926f * (float)j /
4 (float)CIRCLE_SEGMENTS;
5 float const xx = scale * 16.0f * sinf(theta) *
6 sinf(theta) * sinf(theta);
7 float const yy = -1 * scale * (13.0f * cosf(theta) -
8 5.0f * cosf(2.0f * theta) - 2 * cosf(3.0f * theta) - cosf(4.0f
9 * theta));
10 glVertex2f(x + xx, y + yy);
11 }

Penjelasan dari Kode Program di atas:


1. Baris 2-9 merupakan perulangan yang dilakukan untuk meng-
gambarkan tiap-tiap vertex x dan y. Menggunakan rumus yang
dikutip dari Mathworld Wolfram (http://mathworld.wolf-
ram.com/HeartCurve.html).
2. Baris 10 merupakan perintah untuk menggambarkan titik ver-
tex berdimensi 2 yang nilainya diambil dari variabel x + xx, y +
yy. Dimana variabel-variabel tersebut telah dihitung sebe-
lumnya.

267
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1 untuk GPU
2
3 pada method drawLife(float x, float y)
4 float *xx, *yy;
5 xx = (float*)malloc(sizeof(float)*CIRCLE_SEGMENTS);
6 yy = (float*)malloc(sizeof(float)*CIRCLE_SEGMENTS);
7
8 float *xx_d, *yy_d;
9 cudaMalloc((void**)&xx_d, sizeof(float)*CIRCLE_SEGMENTS);
10 cudaMalloc((void**)&yy_d, sizeof(float)*CIRCLE_SEGMENTS);
11
12 kernel_wrapper(CIRCLE_SEGMENTS, xx_d, yy_d);
13
14 cudaMemcpy(xx, xx_d, sizeof(float)*CIRCLE_SEGMENTS,
15 cudaMemcpyDeviceToHost);
16 cudaMemcpy(yy, yy_d, sizeof(float)*CIRCLE_SEGMENTS,
17 cudaMemcpyDeviceToHost);
18
19 for (int j = 0; j < CIRCLE_SEGMENTS; j++) {
20
21 glVertex2f(x + xx[j], y + yy[j]);
22 }
23
24 glEnd();
25 cudaFree(xx_d);
26 cudaFree(yy_d);
27 free(xx);
28 free(yy);
29
30
31 pada kernel
32 __global__ void drawlife(int CIRCLE_SEGMENTS, float *x, float
33 *y) {
34 float const scale = 0.5f;
35 int i = threadIdx.y * CIRCLE_SEGMENTS + threadIdx.x;
36 float const theta = 2.0f * 3.1415926f * (float)i /
37 (float)CIRCLE_SEGMENTS;
38 x[i] = 0.5f * 16.0f * sinf(2.0f * 3.1415926f * (float)i /
39 (float)CIRCLE_SEGMENTS) * sinf(2.0f * 3.1415926f * (float)i /
40 (float)CIRCLE_SEGMENTS) * sinf(2.0f * 3.1415926f * (float)i /
41 (float)CIRCLE_SEGMENTS);
42 y[i] = -1 * 0.5f * (13.0f * cosf(2.0f * 3.1415926f * (float)i
43 / (float)CIRCLE_SEGMENTS) - 5.0f * cosf(2.0f * 2.0f *
44 3.1415926f * (float)i / (float)CIRCLE_SEGMENTS) - 2 *
45 cosf(3.0f * 2.0f * 3.1415926f * (float)i /
46 (float)CIRCLE_SEGMENTS) - cosf(4.0f * 2.0f * 3.1415926f *
47 (float)i / (float)CIRCLE_SEGMENTS));
48 }
49
50 void kernel_wrapper(int CIRCLE_SEGMENTS, float *x, float *y) {
51 drawlife << <1, CIRCLE_SEGMENTS >> > (CIRCLE_SEGMENTS, x, y);
52 }

268
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Penjelasan dari Kode Program di atas:


1. Baris 3-12 merupakan fungsi untuk menggambarkan primitif
hati. Dengan mengalokasikan memori untuk setiap variabel
xx,yy, xx_d, dan yy_d. Variabel ini nantinya digunakan dalam
menggambarkan titik vertex dan akan dikalkulasikan didalam
kernel secara paralel.
2. Baris 14 memanggil trans_wrapper yang dimana fungsi terse-
but menjembatani antara kernel dengan program.
3. Baris 16-19 setelah dilakukan perhitungan pada kernel maka
selanjutnya nilai akan dicopy dari device menuju host.
4. 21-24 perulangan untuk membangun primitif menggunakan
titik vertex x++xx[j], dan y+yy[j].
5. 26-30 Menghentikan pembuatan primitif untuk hati dan mem-
bersihkan memori.
6. 33-47 Fungsi kernel untuk menggambarkan drawlife
menggunakan CUDA. Perhitungan dilakukan secara paralel
menggunakan thread ID dengan isi indeksnya threadIdx.y *
CIRCLE_SEGMENTS + threadIdx.x.
7. 49-53 Wrapper untuk memanggil method kernel drawlife agar
dapat dijalankan pada program

Gambar 10.5 Main Screen Pada Game Breakout

269
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

10.5 CUDA Pada Game 2D Pong


Permainan Pong merupakan permainan klasik yang sangat
menarik untuk dipelajari dari masa ke masa. Pong merupakan salah
satu permainan terkuno pada perangkat arcade yang bergenre sports.
Konsep dari permainan ini mensimulasikan permainan olahraga tenis
meja ke dalam grafis 2 dimensi sederhana. Game besutan Atari pada
1972 ini mencapai popularitas yang tinggi di masyarakat, melebihi
game komputer sebelumnya seperti Computer Space. Pong diciptakan
oleh Allan Alcorn sebagai latihan yang diberikan oleh co-founder Atari,
Nolan Bushnell. Bushnel mendapat ide permainan ini berdasarkan
game ping – pong yang sudah ada pada konsol Magnafox Odyssey,
yang kemudian menyebabkan Atari dijerat hukum. Karena kagum
dengan kualitas pekerjaan Alcorn, Bushnell dan co-founder Atari Ted
Dabney memutuskan untuk memproduksi permainan ini.
Pong memiliki gameplay yang cukup sederhana. Player dapat
menggerakan papan ke atas dan ke bawah sampai ke batas layar. Bola
akan terus dipantulkan apabila bola menabrak tembok atau menabrak
papan Player. Bola yang berhasil lolos ke sisi kiri melewati papan Player
1 akan memberikan skor ke Player 2, dan sebaliknya bola yang berhasil
lolos ke sisi kanan melewati papan Player 2 akan memberikan skor ke
Player 1.
Permainan sederhana ini pada umumnya hanya menggunakan
CPU untuk menjalankannya. Sangat sulit menemukan referensi
permainan ini yang menggunakan GPU, terutama NVIDIA CUDA, dalam
implementasinya. Penelitian ini ingin mengetahui bagaimana yang
terjadi dan hasil apa yang didapat jika permainan ini diimplemetasikan
dengan menggunakan pemrograman CUDA, apakah memakan
resource yang lebih banyak atau tidak. Dalam implementasi penelitian
ini akan dilakukan eksperimen dengan menambahkan jumlah bola
yang terdapat dalam permainan Pong ini.

10.5.1 Dasar Teori


o Konsep Game Loop Pong
Pada saat aplikasi dijalankan, akan terjadi proses inisialisasi
untuk posisi papan, bola, dan skor. Lalu masuk pada game loop, selama
user tidak keluar atau mematikan aplikasi game loop akan terus
diulang. Game menerima input dari user dalam hal menggerakan

270
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

papan. Saat update terjadi perhitungan perubahan posisi dari bola


yang jalan sendiri dan papan yang digerakkan user, lalu dicek juga
apakah bola menyentuh papan atau menembus ke pojok layar. Lalu
pada proses output hasil perhitungan dari update akan ditampilkan di
layar melalui proses rendering.
o CUDA
Compute Unified Device Architecture (CUDA) ialah suatu
teknologi yang dikembangkan oleh NVIDIA guna mempermudah
penggunaan GPU untuk keperluan umum atau non-grafis. Arsitektur
terpadu CUDA ini memudahkan pengembang perangkat lunak untuk
merancang aplikasi yang berjalan pada GPU buatan NVIDIA dengan
menggunakan sintaks yang mirip dengan sintaks bahasa C yang sudah
umum ditemui. Sehingga, saat ini banyak developer mampu me-
manfaatkan kemampuan prosesing GPU untuk meningkatkan kinerja
komputasi program mereka dengan jauh lebih mudah.
Apabila perangkat lunak ini mendeteksi ada hardware yang
kompatibel CUDA, maka proses komputasinya akan dilakukan dengan
GPU. Sehingga, program dapat dijalankan dengan lebih cepat. Program
yang akan diakselerasi adalah program yang dapat dipecah menjadi
banyak eksekusi paralel. Kenyataannya, banyak komputasi yang masuk
pada kategori tersebut. Misal Image dan Video Processing. Sehingga
dapat dikatakan bahwa teknologi CUDA telah melakukan revolusi pada
dunia High Performance Computing.

10.5.2 Implementasi
Pada game ini, dilakukan eksperimen dengan membuat jumlah
bola menjadi sangat banyak, targetnya 10.000 bola. Hal ini dilakukan
untuk menguji seberapa besar kerja CPU dan GPU saat program dijal-
ankan dalam visual studio. Untuk CPU, program akan menggunakan
for untuk membuat objek bola yang akan dibuat classnya supaya lebih
mudah, sebanyak 10.000 kali pembuatannya. Lalu untuk merender se-
luruh bola tersebut menggunakan OpenGL dengan syntax glBegin dan
glEnd, karena merupakan kode asli dari sumbernya. Untuk GPU, imple-
mentasi mirip dengan CPU, namun karena terdapat berbagai fungsi
yang tidak bisa dipanggil pada kernel, maka simulasi yang dilakukan
pada GPU hanya memperbanyak jumlah bola saja, tidak ada
mekanisme pantulan papan dan skor. Rendering untuk objek pada
GPU menggunakan OpenGL CUDA interop yaitu penggunaan VBO yang

271
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

diregister pada CUDA, setelah dimapping titik-titik pada VBO akan


dirubah satu per satu pada fungsi kernel. Hasil VBO yang sudah dirubah
akan digambarkan ke layar dengan glDrawArrays dengan bentuk
quads. Proses ini merupakan proses membuat fungsi merubah titik
pada VBO. Variabel pos digunakan sebagai tempat VBO. Hasil proses
ketika running project ketika dijalankan pada Visual Studio dapat
dilihat pada gambar berikut.

Gambar 10.6 Setelah Dimodifikasi Game Pong

272
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

1 __global__ void simple_vbo_kernel(float4 *pos, unsigned int


2 width, unsigned int height, float time)
3 {
4 unsigned int x = blockIdx.x*blockDim.x + threadIdx.x;
5 unsigned int y = blockIdx.y*blockDim.y + threadIdx.y;
6 // calculate uv coordinates float u = x / (float)width; float
7 v = y / (float)height; u = u*2.0f - 1.0f;
8 v = v*2.0f - 1.0f;
9
10 float x_aksen = cos(u * 22.0f /
11 7.0f);
12 float y_aksen = sin(u * 22.0f /
13 7.0f);
14
15 // calculate simple sine wave
16 pattern
17 float freq = 4.0f;
18 float w = sinf(u*freq + time) * cosf(v*freq + time) * 0.5f;
19 int checkID = (y*width + x) %
20 4;
21 float total_aksenX = time*x_aksen*v;
22 //batesi daerah ilang X
23 //if (total_aksenX > 1.0f)total_aksenX -= (int)total_aksenX;
24 //else if(total_aksenX < - 1.0f)total_aksenX -=
25 (int)total_aksenX;
26 float total_aksenY = time*y_aksen*v;
27 //batesi daerah ilang Y

Method GPU ini digunakan untuk mengatur posisi titik pada


VBO. Supaya bola bisa menyebar digunakan sin dan cos karena nilainya
yang berkisar antara -1 dan 1. Supaya bola dapat bergerak digunakan
variable time yang ditambahkan setiap mainloop. Hasil perkalian dari
variable sebelumnya dimasukkan ke posisi titik pada array pos yang
merupakan perwakilan dari VBO. Setiap thread mengatur satu titik,
diperlukan empat titik untuk menggambar persegi, sehingga
pembagian titik pada thread dibagi menjadi satu benda empat
thread(titik).

273
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Daftar Pustaka

Abdellah Marwan., Eldeib Ayman., Owis I, Mohammed., 2015


GPU Acceleration for Digitally Reconstructed
Radiographs using Bindless Texture Objects and
CUDA/OpenGL Interoperability. IEEE EMBS
Abi Chahla, Fedy. 2008. “Nvidia’s CUDA: The End of the
CPU?”. Tom’s Hardware
Adams, Ernest, 2010. Fundamentals of Game Design. New
Riders. pp. 161, 268.
Aghaei Pour, Payam; Gulrez, Tauseef; AlZoubi, Omar;
Gargiuolo, Gaetano and A. Calvo, Rafael, “Brain-
Computer Interface: Next Generation Thought
Controlled Distributed Video Game Development
Platform”, 2008 IEEE Symposium on Computational
Intelligence and Games (CIG’08)
Asano, Shuichi; Maruyama, Tsutomu; Yamaguchi, Yoshiki.
“Performance Comparison of FPGA, GPU and CPU
Image Processing”. Ten-ou-dai Tsukuba Ibaraki
Bakhoda, A., Yuan, G. L., Fung, W. L., Wong, H., Aamodt, T.
M., 2009, Analyzing CUDA Workloads Using a Detailed
GPU Simulator. University of British Columbia.
Barney, B. 2009. Parallel Image Processing Based on Cuda.
China: Polytechnical University.
Basuki, A. 2005. Pengolahan Citra Digital Menggunakan
Visual Basic 6, Yogyakarta.
Che Shuai., Boyer Michael., Meng Jiayuan, Tarjan David.,
W.Sheaffer Jeremy., Skadron Kevin. 2008. A
Performance Study of General-Purpose Applications on
Graphics Processors Using CUDA. University of Virgina,
Department of Computer Science. USA
Che, B., Boyer, M., Meng, J., Tarjan, D., Sheaffer, J. W.,
SKADRON., K., 2008, A Performance Study of General-
Purpose Applications on Graphics Processors Using
CUDA, Parallel and Distributed Computing

274
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Ching-Lung Su., Po-Yu Chen., Chun-Chieh Lan., Long-Sheng


Huang., & Kuo-Hsuan Wu. 2014. Overview and
Comparison of OpenCL and CUDA
Cholissodin, I., Riyandani, E., 2016, Swarm Intelligence,
Fakultas Ilmu Komputer, Universitas Brawijaya, Malang.
Christanti, R., Cholissodin, I., Sutrisno. 2016. Implementasi
Blob Analysis Untuk Vehicle Counting Pada Video Lalu
Lintas. DORO: Repository Jurnal Mahasiswa PTIIK
Universitas Brawijaya, vol. 7, no. 13
CMSoft. 2016. Kernel Execution Structure.
http://www.cmsoft.com.br/opencl-tutorial/kernel-
execution-structure/
Demir Veysel., Elsherbeni Z, Atef. 2011. Utilization Of CUDA-
OpenGL Interoperability to Display Electromagnetic
Fields Calculated by FDTD. Northern Illnois Univerity
and University of Mississippi, USA
Eriksmistad, https://www.eriksmistad.no/marching-cubes-
implementation-using-opencl-and-opengl/
Fogleman, M. 2017. Minecraft clone for Windows, Mac OS X
and Linux. Sumber dapat diakses dari
https://github.com/fogleman/Craft
Fung, J. dan Mann, S. 2008. Using Graphics Devices in
Reverse: GPU-Based Image Processing and Computer
Vision, Nvidia Corporation, USA.
Gonzalez, RC., Woods RE. 2018. Digital Image Processing,
4Th Edition.
Green, Simon. 2013. Particle Simulation Using CUDA.
NVIDIA Corporation
Hapsani, A.G., Cholissodin, I., Supianto, A.A. 2014.
Implementasi Metode Scale Invariant Feature Transform
(SIFT) Untuk Multiple Object Tracking Pada Video
CCTV. DORO: Repository Jurnal Mahasiswa PTIIK
Universitas Brawijaya, vol. 4, no. 2
Irawan, F. T., Ma’rufi, M. R., Cholissodin, I. 2017. Optimasi
Rendering Game 2D Asteroids Menggunakan

275
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Pemrograman CUDA. Jurnal Teknologi Informasi dan


Ilmu Komputer (JTIIK) Vol. 4 No. 4 2017.
Keckler, S. W., Dally, W.J., Khailany, B., Garland, M., Glasco.
D., 2011, GPUs and The Future of Parallel Computing.
IEEE Computer Society, 7-17.
Kent, Steven. 2001. "And Then There Was Pong". Ultimate
History of Video Games. Three Rivers Press.
Kristiadi, A., sumber https://github.com/wiseodd/cuda-pso
diakses Juni 2017.
Kurniawan, B., Noor A. S., Teguh B. A. 2015. Analisis
Perbandingan Komputasi GPU dengan CUDA dan
Komputasi CPU untuk Image dan Video Processing.
Seminar Nasional Aplikasi Teknologi Informasi (SNATi)
2015. 6 Juni, Yogyakarta.
Landau, W., 2013. GPU. Diambil dari
https://wlandau.github.io/gpu/talks.html
Lee, J. H., Clarke, R. I., Karlova, N., Thornton, K., & Perti, A.
2014. Facet Analysis of Video Game Genres.
iConference 2014, 131.
Lewis, N. 2015. Image Processing using CUDA. Sumber
dapat diakses dari
https://github.com/Teknoman117/cuda
Lixin, L. & Zhen, P. 2011 The method of three-dimensional
scene modeling and implementation using VC++ and
OpenGL, School Of Optoelectronicds, ChangChun
University of Science And Technology, China
Mivule, K., Harvey, B., Cobb, C., Sayed, H. E., 2014, A Review
of CUDA, MapReduce, and Pthreads Parallel Computing
Models. Bowie State University.
Mukhlis, Y., Harmanto, L. 2007. Metode Sorting Bitonic pada
GPU. 2 Februari.
Nickolls John., Buck Ian., Garland Michael., Nvidia., Skadron
Kevin. 2008. Scalable Parallel Programming., University
of Virginia. USA
Nickolls, J., Dally, W. J., 2010, The GPU Computing Era. IEEE
Computer Society, 56-69.

276
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Nvidia, 2017. Graphics Processing Unit (GPU).


http://www.nvidia.com/object/gpu.html (Diakses tanggal
6 Juni 2017).
Nvidia, 2017. What is CUDA?.
http://www.nvidia.com/object/cuda_home_new.html
(Diakses tanggal 7 Juni 2017).
Phillips, J.M. 2013. Sumber dapat diakses dari
https://www.cs.utah.edu/~jeffp/teaching/cs5955/L10-
kmeans.pdf
Prahara, A. 2015. Deteksi Kebakaran pada Video Berbasis
Pengolahan Citra dengan Dukungan GPU. . Seminar
Nasional Aplikasi Teknologi Informasi (SNATi). 6 Juni,
Yogyakarta.
Prato, G. D., Feijoo, C., & Simon, J.-P. 2014. Innovations in
the Video Game Industry: Changing Global Markets.
Digiworld Economic Journal, 17-18.
Redmon, J., Divvala, S., Girshick, R., Farhadi, A. 2016. You
Only Look Once: Unified, Real-Time Object Detection.
Ridgesolutions. 2016. OpenCV Display window title corrupted
and multiple windows show. Sumber dapat diakses dari
http://www.ridgesolutions.ie/index.php/2013/09/26/open
cv-display-window-title-corrupted-and-multiple-
windows-show/
Rizaldi, H. I., Pramana, F. S., R., B. N., A.N., A. Y.,
Cholissodin, I. 2017. Optimasi Proses Rendering Objek
Game 3D Menggunakan Pemrograman CUDA Pada
Game Sandbox Craft. Jurnal Teknologi Informasi dan
Ilmu Komputer (JTIIK) Vol. 4 No. 3 2017.
Ruggill, J.E., Mcallister, K.S., 2011. Gaming Matters: Art,
Science, Magic, and the Computer Game Medium.
University Alabama Press; 1st Edition edition.
RyGuyM. 2013. Game Asteroids 2D build in C and using
OpenGL. Sumber dapat diakses dari
https://github.com/RyGuyM/Asteroids
Ryoo, Shane, Rodrigues, Christopher I., Baghsorkhi, Sara S.,
Stone, Sam S., Kirk, David B., Hwu, Wen-Mei W.,
Optimization Principles and Application Performance

277
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Evaluation of a Multithreaded GPU Using CUDA, PPoPP


'08 Proceedings of the 13th ACM SIGPLAN Symposium
on Principles and practice of parallel programming, 73-
82.
Sellers, John. 2001 . "Pong". Arcade Fever: The Fan's Guide
to The Golden Age of Video Games. Running Press.
Sharcnet. 2016. Porting CUDA to OpenCL. Diambil dari
https://www.sharcnet.ca/help/index.php/Porting_CUDA
_to_OpenCL. Powered by MediaWiki.
Shen Whenfeng., Wei Daming., Xu Weimin., Zhu Xin., Yuan
Shizhong. 2010. Parallelized computation for computer
simulation of electrocardiograms using personal
computers with multi-core CPU and general-purpose
GPU. Biomedical Information Technology Lab, The
University of Aizu, Japan
Sutrisno, Cholissodin, I, Christanti, R., Dewi, C., Hidayat, N.
2015. Segmentasi Kendaraan Menggunakan Improve
Blob Analysis (BA) Pada Video Lalu Lintas. Jurnal
Teknologi Informasi dan Ilmu Komputer (JTIIK) Vol. 2
No. 1 2015.
Tarjan, D., K. Skadron, & P. Micikevicius, 2009. The art of
performance tuning for CUDA and many core
architectures. Birds-of-a-feather session di SC'09.
Technology for GPGPU. Department Of Electronic
Engineering National Yunlin University Of Science And
Technology., Taiwan, ROC.
Tutsplus. 2011. Understanding the Game Loop-Basix.
Diakses 20 Juni 2017, dari
https://code.tutsplus.com/tutorials/understanding-the-
game-loop-basix--active-8510
University Of Virginia, Engineering, Computer Science, 2017.
CUDA Optimization Techniques.
http://www.cs.virginia.edu/~mwb7w/cuda_support/optim
ization_techniques.html (Diakses tanggal 5 juni 2017).
Unsky. 2017. yolo-for-windows-v2. GitHub.
https://github.com/unsky/yolo-for-windows-v2. Web.
diakses 30 April 2018.

278
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Vries, D, J. 2015 Learn OpenGL: An Offline Transcript of


learnopengl.com. learnopengl.com
Werkhoven, B. V., Maassen, J., Seinstra, F. J., 2011,
Optimizing Convolution Operations in CUDA with
Adaptive Tiling. VU University.
Whitehead, Nathan; Fit-Florea, Alex. “Precision &
Performance: Floating Point and IEEE 754 Compliance
for Nvidia GPUs”. Nvidia.
Willhalm, T., Dementiev, R., Fay P., 2017. Intel® Performance
Counter Monitor - A better way to measure CPU
utilization. software.intel.com.
William E. Lorensen, Harvey E. Cline, 1987. Marching cubes:
A high resolution 3D surface construction algorithm.
Yusnita R., Norbaya F., dan Basharuddin N. 2012. Intelligent
Parking Space Detection System Based on Image
Processing. International Journal of Innovation,
Management and Technology, Vol. 3, No. 3, June 2012.
Zhang L., Li X., Huang J., Shen Y., dan Wang D. 2018. Vision-
Based Parking-Slot Detection: A Benchmark and A
Learning-Based Approach. Symmetry 2018, 10, 64;
doi:10.3390/sym10030064.

279
Cholissodin, I., Maghfira, T. N., 2017, Pemrograman GPU, Fakultas Ilmu Komputer,
Universitas Brawijaya, Malang.

Biografi Penulis

Imam Cholissodin, lahir di Lamongan pada


tanggal 19 Juli 1985, telah menyelesaikan
pendidikan S2 di Teknik Informatika FTIF ITS
Surabaya pada Tahun 2011. Sejak Tahun 2012
telah aktif sebagai dosen pengajar di jurusan
Teknik Informatika Program Teknologi dan Ilmu
Komputer (PTIIK), dan Alhamdulillah mulai tahun
2016 telah menjadi Fakultas Ilmu Komputer
(FILKOM) Universitas Brawijaya (UB) Malang
pada beberapa mata kuliah, seperti Information Retrieval, Pengolahan
Citra Digital, Probabilitas dan Statatistika, Grafika Komputer, Decision
Support System, Kecerdasan Buatan, Data Mining, Analisis Big Data,
Pemrograman GPU, Algoritma Evolusi, Swarm Intelligence dan
Pengenalan Pola. Di samping mengajar, peneliti juga aktif dalam Riset
Group Sistem Cerdas dan Riset Group Media, Game & Mobile
Technology (MGM) di dalam Laboratorium Riset. Selain itu peneliti juga
telah melakukan beberapa publikasi pada seminar maupun jurnal
nasional dan internasional (IEEE, Scopus, etc). Riset pada tahun 2015-
2018 yang sedang dilakukan sekarang bersama dengan beberapa tim
dosen dan mahasiswa semester akhir adalah berfokus pada bidang
Information Retrieval, teknik optimasi untuk melakukan analisis
dokumen lembaga pemerintahan secara Real-time, yaitu dengan tema
“Pengembangan Sistem Audit Dokumen Lembaga Pemerintahan
Menggunakan Stream Deep Learning Untuk Mendukung Smart
Governance” yang merupakan kombinasi dari beberapa multi-disiplin
keilmuan antara Decision Support System (DSS), Teknik Optimasi, Big
Data, Machine Learning, Ilmu Administrasi Pemerintahan serta
Information Retrieval (IR).
Motto: “We Are A Code, We Are The Best Code Of God”.

Tusty Nadia Maghfira, lahir di Malang pada


tanggal 29 November tahun 1995, telah berhasil
menyelesaikan studi S1 Teknik Informatika,
Fakultas Ilmu Komputer, Universitas Brawijaya
Malang dengan tugas akhir yang berjudul
“Deteksi Kesalahan Ejaan dan Penentuan
Rekomendasi Koreksi Kata yang Tepat Pada
Dokumen Jurnal JTIIK Menggunakan Dictionary
Lookup dan Damerau-Levenshtein Distance”.

280

Anda mungkin juga menyukai