Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 1
IMPLEMENTASI ALJABAR LINEAR (IDENTIFIKASI VARIABEL SISTEM PERSAMAAN
LINIER MENGGUNAKAN MATRIKS) DENGAN OPEN MP-CUDA
Rahmat Muttaqin (13210027) Dita Amalia (13210105) Anissa Sachi Hatami (13210123)
EL4127-Arsitektur dan Komputasi Paralel
Sekolah Teknik Elektro dan Informatika ITB
Abstrak
Pada tugas besar ini, dilakukan implementasi aljabar linear
berupa identifikasi variabel sistem persamaan linier
menggunakan matriks orde 3x3 dengan program Open MP
dan CUDA. Program Open MP (Open Multi-Processing)
adalah sebuah antarmuka pemrograman aplikasi (API)
yang mendukung multi processing shared memory
pemrograman di C, C++ dan Fortran pada berbagai
arsitektur yang terdiri dari satu set perintah kompiler,
perpustakaan rutinitas, dan variabel lingkungan yang
mempengaruhi run-time. Program CUDA merupakan
platform komputasi paralel dan model pemrograman yang
dibuat oleh NVIDIA dan implementasinya menggunakan
GPU( Graphic Processing Unit). CUDA memberikan
akses langsung pada set instruksi virtual dan memori dari
elemen komputasi paralel pada GPU CUDA. Secara
keseluruhan hasil yang didapat berupa perbandingan
performa antara Open Mp dan CUDA.
Kata kunci : Open MP, CUDA, Persamaan Linier,
Matriks.
1. S
TUDIP
USTAKA1.1
O
PENMP
(O
PENM
ULTIP
ROCESSING)
OpenMP adalah sebuah antarmuka pemrograman aplikasi (API) yang mendukung multi processing shared memory pemrograman di C, C++ dan Fortran pada berbagai arsitektur, termasuk Unix dan Microsoft Windows platform. OpenMP Terdiri dari satu set perintah kompiler,perpustakaan rutinitas, dan variabel lingkungan yang mempengaruhi run-time. Banyak Aplikasi dibangun dengan model hibrida pemrograman paralel dapat dijalankan pada komputer cluster dengan menggunakan OpenMP dan Message Passing Interface (MPI), atau lebih transparan dengan menggunakan ekstensi OpenMP non-shared memory systems.
OpenMP mengimplementasi multithreading. Bagian kode yang akan dijalankan secara parallel ditandai sesuai dengan Preprocessor directif sehingga akan membuat thread-thread sebelum dijalnkan. Setiap thread memiliki id yang di buat mengunakan fungsi ( omp_get_thread_num() pada C/C++ dan OMP_GET_THREAD_NUM() pada Fortran). Secara default, setiap thread mengeksekusi kode secara parallel dan independent. "Work-sharing constructs" dapat dapat digunakan untuk membagi tugas antar thread sehingga setiap thread menjalankan sesuai bagian alokasi kodenya. Fungsi OpenMP berada pada file header yang berlabel “omp.h” di C / C++.
Unsur inti OpenMP adalah pembuatan konstruksi thread, distribusi beban kerja (pembagian kerja), pengelolaan data-environment, thread sinkronisasi, bagian user-level runtime dan variabel environment.
1.2
CUDA
(C
OMPUTEU
NIFIEDD
EVICEA
RCHITECTURE)
Secara sederhana, CUDA adalah kumpulan program-program yang menerjemahkan teks dalam bentuk bahasa komputer (computer language) berupa source language/source code, ke dalam bentuk bahasa komputer yang lain (target language/object code).
NVIDIA CUDA technology merupakan suatu lingkup bahasa pemrograman “C” yang membuka akses kekuatan prosesing dari GPU, untuk memecahkan hampir seluruh tantangan intensif dari komputasi / perhitungan yang kompleks dari proses GPU tersebut. Diawali dari seri Geforce 8000 series merupakan GPU yang sudah suport arsitektur CUDA.
Arsitektur CUDA memungkinkan GPU (yang telah support CUDA) menjadi arsitektur terbuka seperti layaknya CPU (Central Processing Unit a.k.a Processor). Hanya, tidak seperti CPU, GPU
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 2 memiliki arsitektur banyak-inti yang pararel.
Setiap inti memiliki kemampuan untuk menjalankan ribuan “thread” secara simultan. Jika aplikasi yang dijalankan sesuai dengan arsitektur ini, GPU dapat menyediakan keuntungan yang lebih besar dari segi performa proses aplikasi tersebut.
1.3
P
ERKALIANM
ATRIKSJika matriks Am x n dan matriks Bp x q dikalikan, maka Banyaknya kolom matriks A harus sama dengan banyaknya kolom matriks B, sehingga n =
p
matriks dengan ordo m x q
hasil kali setiap elemen baris matriks A dengan setiap elemen kolom matriks B yang sesuai
1.4
I
NVERSM
ATRIKSDapat ditentukan menggunakan rumus
1.4.1
D
ETERMINANM
ATRIKSUntuk matriks berukuran 3x3, maka determinan matriks dapat dicari dengan aturan Sarrus sebagai berikut
1.4.2
A
DJOINM
ATRIKSAdjoin Matriks A adalah transpose dari kofaktor-kofaktor matriks tersebut
1.4.2.1
M
INOR DANK
OFAKTORM
ATRIKSYang dimaksud dengan MINOR unsur aij adalah determinan yang berasal dari determinan orde ke-n tadi dikurake-ngi deke-ngake-n baris ke-i dake-n kolom ke-j yang dinotasikan dengan Mij. Contoh Minor dari elemen a₁₁
Minor-minor dari Matrik A (ordo 3x3) antara lain
Kofaktor dan minor hanya berbeda tanda. kofaktor dari baris ke-i dan kolom ke-j dituliskan dengan
Contoh
1.4.2.2
T
RANSPOSEM
ATRIKS Matriks transpose adalah matriks yang mengalami pertukaran elemen dari baris menjadi kolom dan sebaliknya1.5
I
DENTIFIKASIV
ARIABELS
ISTEMP
ERSAMAANL
INIERMisal menentukan nilai p, q, dan r dari persamaan linier berikut :
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 3 2p +2q -3r = -25
4p +5q -6r = -37 2p -3q +4r = 33
Sistim persamaan linier 3 variabel di atas, dapat dituliskan dalam bentuk matriks berikut:
Bentuk matriks di atas, terlebih dahulu dianalogikan dengan sebuah persamaan, maka diperoleh persamaan yang baru yaitu : A*X = B. Untuk mendapatkan nilai X, bentuk persamaan harus dirubah menjadi :
1.6
M
ICROSOFTV
ISUALS
TUDIOMicrosoft Visual Studio merupakan environment dari microsoft yang dapat digunakan untuk membantu pemrograman berbagai bahasa, dalam percobaan ini digunakan C/C++ dengan implementasi CUDA dengan menggunakan CUDA Runtime 5.5.
2. H
ASIL DANA
NALISISPada percobaan ini dilakukan pembuatan program yang berkaitan dengan aljabar linier menggunakan OpenMP dan CUDA. Kasus aljabar linier yang diambil pada percobaan ini adalah identifikasi variabel dari tiga buah persamaan linier yang mengandung variabel x, y, dan z. Penentuan variabel ini menggunakan perkalian dua buah matriks dengan melakukan invers terhadap matriks pertama.
Hasil perkalian dua buah matriks ini berupa sebuah matriks yang elemennya adalah nilai variabel x, y, dan z pada persamaan linier.
Pada percobaan ini digunakan environment Microsoft Visual Studio 2010 karena memiliki environment yang mudah untuk digunakan, serta
lebih praktis jika di bandingkan dengan menggunakan command prompt
Pada step ini di gunakan #include<cuda.h> untuk memasukkan library cuda dan #include<omp>.h digunakan untuk library openmp.
Pada bagian inti program, matriks harus memiliki orde 3. Dengan Matriks A yang berisi koefisien dari variabel persamaan linier. Pengisian nilai Matriks diimplementasikan pada iterasi (i=0; i<n; i++) kemudian (j=0; j<n; j++) sehingga terjadi pengisian nilai matriks.
Matriks B yang berisi hasil dari variabel persamaan linier. Pengisian nilai Matriks diimplementasikan pada iterasi (i=0; i<3; i++) kemudian (j=0; j<3; j++) sehingga terjadi pengisian nilai matriks.
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 4 Bagian program ini menampilkan persamaan
linier, isi Matriks A, serta isi Matriks B .
Spesifikasi thread, kernel dari perkalian matriks. Penambahan __global__ sebelum fungsi pada baris program ini, berguna untuk memerintah compiler untuk mengeksekusi fungsi ini di GPU yang di panggil dari host, sehingga program akan berkerja secara paralel di banyak thread.
Pvalue memasukan elemen yang telah di komputasi oleh thread float Pvalue=0
Pada bagian ini dilakukan konfigurasi eksekusi setup dan menjalankan device thread komputasi. Setelah inisialisasi data, cudaMemcpy meng-copy data dari destination ke source dan parameter baru cudaMemcpyHostToDevice untuk
menunjukkan arah data berjalan. Kemudian data dikembalikan lagi dari destination ke source namun dengan arah yang berbeda pada cudaMemcpyDeviceToHost. Selain itu, memori juga dialokasikan ke GPU dengan cudaMalloc yang mengambil address/alamat ke pointer. Perintah cudaMemcpyDeviceToHost, mentransfer P dari device ke host, lalu mengosongkan nilai matriks.
.Pada program diatas merupakan fungsi determinan.
Pada bagian diatas dilakukan proses pembuatan invers matriks dengan menggunakan openmp. Pada bagian pragma omp parallel seluruh proses dishare ke seluruh thread kecuali yang bagian
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 5 private, yaitu j dilakukan oleh masing-masing
thread.
Menampilkan invers dari Matriks A.
Pada bagian ini dilakukan perkalian Matriks invers A (A-1) dan Matriks B dengan cara
memanggil fungsi MatrixMultiplication, sehingga didapat variabel x, y, dan z serta menampilkan hasilnya ke layar.
Hasil yang didapat:
Hasil yang didapat menunjukkan bahwa program berjalan sesuai dengan harapan. Dapat dilihat seluruh isi matriks berukuran 3x3. Untuk menentukan nilai variabel x, y, dan z dari persamaan linier maka koefisien akan ditampung pada matriks A sedangkan hasil persamaan akan ditampung pada matriks B.
Kemudian, berdasarkan rumus
Jika dikalkulasikan, maka didapat matriks dengan elemen adalah nilai variabel x=2, y=3, dan z=4. Hasil diatas menunjukkan bahwa program berjalan dengan baik.
3. K
ESIMPULANKesimpulan yang diperoleh dari Tugas Besar, antara lain :
Cara kerja program CUDA adalah data di copy dari CPU ke GPU, lalu menjalankan kernel Matrix Multiplication pada GPU setelah itu resultan data di copy dari GPU ke CPU, yang dikerjakan oleh GPU secara paralel dengan menggunakan banyak thread. Pemrograman paralel dengan melibatkan cuda dengan sebagian open mp dapat dilakukan. Pada bagian openmp dilakukan proses kompilasi di CPU, sedangkan CUDA dilakukan di GPU.
4. D
AFTARP
USTAKA[1]
Jackstar H. S., Panduan Penulisan Laporan, Jacks
Publishing, Bandung, 2008.
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 6
LAMPIRAN
SOURCE CODE
3.1 Perkalian Matriks /* Inverse of a n by n matrix */ #include<stdio.h> #include<conio.h> #include<math.h> #include<stdlib.h> #include<omp.h> int main() {void MatrixMultiplication(float *, float *, float *, int); void arg(int *,int *, int *,int ,int );
int det(int *,int *);
int a[10][10],b[10][10],c[10][10],n,i,j,m,d; float inv[10][10],z[10][10],out[10][10]; printf("Enter the order of the matrix\n"); scanf("%d",&n);
if (n!=3) {
printf("Orde harus 3 untuk persamaan ini"); } else { FILE *inputA; inputA=fopen("matriksA","r"); for(i=0;i<n;i++) { for(j=0;j<n;j++) fscanf(inputA,"%d",&a[i][j]); } fclose(inputA); FILE *inputB; inputB=fopen("matriksB","r");
if (inputB == NULL) { //jika file tidak ada
printf("Can't open input file \"data!\"\n"); } for(i=0;i<3;i++) { for(j=0;j<3;j++) { fscanf(inputB,"%f",&z[i][j]); } } fclose(inputB);
printf("Diketahui persamaan linear dibawah : \n");
printf("Tentukan nilai x y dan z dengan cara invers matriks \n"); printf("%dx + %dy + %dz\t= %.f\n",a[0][0],a[0][1],a[0][2],z[0][0]); printf("%dx + %dy + %dz\t= %.f\n",a[1][0],a[1][1],a[1][2],z[1][0]); printf("%dx + %dy + %dz\t= %.f\n",a[2][0],a[2][1],a[2][2],z[2][0]); printf("\n"); printf("jawab : \n"); printf("Matriks A :\n"); for(i=0;i<n;i++) { for(j=0;j<n;j++)
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 7 printf("%d\t",a[i][j]); printf("\n"); } printf("\n"); printf("Matriks B(Hasil) :\n"); for(i=0;i<n;i++) { printf("%.f\t",z[i][0]); printf("\n"); } printf("\n"); if(n==2) { c[0][0]=a[1][1]; c[1][1]=a[0][0]; c[0][1]=-a[0][1]; c[1][0]=-a[1][0]; d=a[0][0]*a[1][1]-a[0][1]*a[1][0]; printf("Determinant is:%d\n",d); printf("Matrix inversnya(A-1) : "); if(d==0) { getch(); exit (d-'0'); } for(i=0;i<n;i++) { printf("\n"); for(j=0;j<n;j++) printf(" %f",c[i][j]/(float)d); } } else {
#pragma omp parallel for default(shared) private (j) m=n; for(i=0;i<m;i++) { for(j=0;j<m;j++) { n=m; arg(&a[0][0],&b[0][0],&n,i,j); c[j][i]=pow(-1,(i+j))*det(&b[0][0],&n); } } n=m; d=det(&a[0][0],&n); printf("Determinant is :%d\n",d); printf("Matrix inversnya(A-1) : "); if(d==0) {
printf("INVERSE DOES NOT EXIST"); getch(); exit(d-'0'); } for(i=0;i<m;i++) { printf("\n"); for(j=0;j<m;j++) { inv[i][j] = c[i][j]/(float)d; printf(" %10.2f",inv[i][j]);
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 8 }
} }
MatrixMultiplication(&inv[n][n], &z[n][n], &out[n][n], n); printf("\nnilai x y dan z adalah :\n");
for (i=0;i<3;i++) { j=0; { printf(" %10.2f",out[i][j]); } printf("\n"); } } } return 0; }
__global__ void MatrixMulKernel(float *invd, float *zd, float *outd, int n) { //2D Thread ID int tx = threadIdx.x;
int ty = threadIdx.y;
//Pvalue stores the outd element that is computed by the thread float Pvalue = 0;
if((tx>=n)||(tx>=n))return; for(int k = 0; k < n ; ++k) {
float invdelement = invd[ty*n + k]; float zdelement = zd[k*n + tx]; Pvalue += (invdelement*zdelement); }
outd[ty*n + tx] = Pvalue; }
void MatrixMultiplication(float *inv, float *z, float *out, int n) { int size = n*n*sizeof(float);
float *invd, *zd, *outd;
//Transfer inv azd z to device memory cudaMalloc((void**)&invd, size);
cudaMemcpy(invd,inv,size,cudaMemcpyHostToDevice); cudaMalloc((void**)&zd, size);
cudaMemcpy(zd,z,size,cudaMemcpyHostToDevice); //Allocate out on the device
cudaMalloc((void**)&outd,size); //Setup the execution configuration dim3 dimBlock(10,10);
dim3 dimGrid(1,1);
//Launch the device computation threads!
MatrixMulKernel<<<dimGrid,dimBlock>>>(invd,zd,outd,n); //Transfer P from device to host
cudaMemcpy(out,outd,size,cudaMemcpyDeviceToHost); //Free device matrices
cudaFree(invd); cudaFree(zd); cudaFree(outd); }
void arg(int *a,int *b,int *n,int x,int y) {
Laporan Praktikum - Laboratorium Dasar Teknik Elektro – STEI ITB 9 #pragma omp parallel for default(shared) private (j)
for(i=0,k=0;i<*n;i++,k++) { for(j=0,l=0;j<*n;j++,l++) { if(i==x) i++; if(j==y) j++; *(b+10*k+l)=*(a+10*i+j); } } *n=*n-1; }
int det(int *p,int *n) { int d[10][10],i,j,m,sum=0; m=*n; if(*n==2) return(*p**(p+11)-*(p+1)**(p+10)); for(i=0,j=0;j<m;j++) { *n=m; arg(p,&d[0][0],n,i,j); sum=sum+*(p+10*i+j)*pow(-1,(i+j))*det(&d[0][0],n); } return(sum); }