Laporan Grid NCC 1

21
LAPORAN KOMPUTASI GRID Cluster 1 NCC Kelompok Cluster NCC 1 : Rizky Septiandy W. Adhitya Bhawiyuga Pujianto Yogie Setiarko Dhanang Cindra Dosen F.X. Arunanto JURUSAN TEKNIK INFORMATIKA FAKULTAS TEKNOLOGI INFORMASI INSTITUT TEKNOLOGI SEPULUH NOPEMBER 2010

Transcript of Laporan Grid NCC 1

Page 1: Laporan Grid NCC 1

LAPORAN

KOMPUTASI GRID

Cluster 1 NCC

Kelompok Cluster NCC 1 :Rizky Septiandy W. Adhitya Bhawiyuga PujiantoYogie SetiarkoDhanang Cindra

DosenF.X. Arunanto

JURUSAN TEKNIK INFORMATIKAFAKULTAS TEKNOLOGI INFORMASI

INSTITUT TEKNOLOGI SEPULUH NOPEMBER

2010

Page 2: Laporan Grid NCC 1

Konfigurasi Cluster II Grid

Laboratorium Net Centric Computing

Topologi Jaringan

Topologi jaringan secara keseluruhan adalah :

Topologi pada cluster NCC adalah :

Rancangan Software

Untuk pengenmbangan sistem grid ini, dibutuhkan beberapa perangkat lunak. Perangkat lunak tersebut hampir kesemuanya bersifat gratis dan open source. Berikut kebutuhan perangkat lunak untuk sistem grid.

1. Sun Grid Engine Mengatur penjadwalan dan melakukan machines serta menjalankan perintah- perintah dalam unix.

2. Globus Toolkit

Gambar 1: Topologi Cluster ITS

Gambar 2 : Topologi Cluster NCC

Page 3: Laporan Grid NCC 1

Management Tools yang merupakan middleware antara antarmuka web dengan scheduler.

3. GridSphereAntarmuka web sebagai media user untuk mengirimkan job ke cluster grid.

4. MPICH Aplikasi untuk mengkompile dan menjalankan aplikasi berbasis MPI.

5. JD2SDK 1.5 +Framework java yang dipakai untuk menjalankan aplikasi berbasis java.

* sampai laporan dibuat, yang bertanda bintang sudah diinstall dan dikonfigurasi

Konfigurasi MPICH

Requirement

Sebuah alamat IP statis maupun dinamis (statis lebih disarankan). Pada kasus ini akan dibangun 3 buah node dalam satu cluster dengan nama dan IP sebagai berikut:

1. ncca1 dengan alamat 10.151.32.5 sebagai master2. ncca2 dengan alamat 10.151.32.26 sebagai slave3. ncca3 dengan alamat 10.151.32.23 sebagai slave

Setting IP

Untuk mensetting IP, kita edit file /etc/networking/interfaces pada tiap-tiap node di atas. Konfigurasi di tiap node adalah :

1. Pada ncca1 auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 10.151.32.5 netmask 255.255.255.0 broadcast 10.151.32.255 gateway 10.151.32.1

2. Pada ncca2 auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 10.151.32.26 netmask 255.255.255.0 broadcast 10.151.32.255

Page 4: Laporan Grid NCC 1

gateway 10.151.32.13. Pada ncca3

auto lo iface lo inet loopback auto eth0 iface eth0 inet static address 10.151.32.23 netmask 255.255.255.0 broadcast 10.151.32.255 gateway 10.151.32.1 Kemudian restart interface dengan printah /etc/init.d/networking restart.

Konfigurasi Hosts

Kita perlu memberikan nama domain untuk setiap node yang ada pada cluster. Kita dapat mengedit file /etc/hosts pada setiap node dengan nama dan IP semua node yang terlibat dalam cluster ini. Konfigurasi dalam setiap host harus sama untuk menghindari error seperti mpdboot_server (handle_mpd_output 407): failed to handshake with mpd on 10.0.0.2; recvd

output={}

Pada setiap node : 127.0.0.1 localhost 10.151.32.5 ncca1 10.151.32.26 ncca2 10.151.32.23 ncca3

Kebutuhan Paket

• libmpich1.0-dev - mpich static libraries dan development files

• libmpich-mpd1.0-dev - mpich static libraries dan development files

• libmpich-shmem1.0-dev - mpich static libraries dan development files

• mpich2 - Implementasi standar MPI Message Passing Interface.• mpich2-doc - Dokumentasi MPICH2

• openssh-server - secure shell (SSH) server• build-essentials - paket build-essential.

Lakukan proses instalasi pada setiap node di cluster dengan perintah :

grid@ncca1:~$ sudo apt-get install libmpich1.0-dev libmpich-mpd1.0-dev libmpich-shmem1.0-dev mpich2 mpich2-doc john openssh-server build-essentials

Page 5: Laporan Grid NCC 1

Konfigurasi User

Dalam cluster yang akan kita bangun, kita akan menggunakan user dengan nama yang sama pada setiap node. Dengan alasan keamanan, kita tidak akan menggunakan user root. Oleh karena itu, kita membuat user baru yaitu user grid pada setiap node dengan perintah:

grid@ncca1:~$ sudo useradd gridgrid@ncca1:~$ sudo passwd cluster

Enter new UNIX password:

Retype new UNIX password:

passwd: password updated successfully

Membuat NFS Server dan Client

NFS Server adalah sistem yang digunakan node-node dalam cluster ini berbagi resource file yang akan dikerjakan. Master akan menjadi NFS Server dimana nantinya suatu bagian dari filesystem pada node master akan dapat dimount oleh node slave sebagai NFS Client dan akhirnya master dan slave akan berbagi file yang akan dikerjakan oleh cluster tersebut. Setting pada setiap node adalah :

1. Master (ncca1) grid@ncca1:~$ sudo mkdir /mirror grid@ncca1:~$ chmod 777 /mirror grid@ncca1:~$ sudo apt-get install nfs-kernel-server grid@ncca1:~$ sudo echo /mirror *(rw,sync) >> /etc/exports

2. Slave (ncca2) grid@ncca2:~$ sudo mkdir /mirror grid@ncca2:~$ sudo chmod 777 /mirror grid@ncca2:~$ sudo apt-get install nfs-common grid@ncca2:~$ sudo mount ncca1:/mirror /mirror

3. Slave (ncca3) grid@ncca3:~$ sudo mkdir /mirror grid@ncca3:~$ sudo chmod 777 /mirror grid@ncca2:~$ sudo apt-get install nfs-common grid@ncca2:~$ sudo mount ncca1:/mirror /mirror

Konfigurasi SSH

Untuk berkomunikasi antar node dibutuhkan akses ssh pada user grid tanpa password. Untuk itu, pada setiap node harus saling disetting dengan node yang lain, dan sifatnya bolak-balik. Contoh, misal antara node ncca1 dan node ncca2.

Pada node ncca1 (master)grid@ncca1:~$ ssh-keygen -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (/home/grid/.ssh/id_rsa):

Page 6: Laporan Grid NCC 1

Created directory '/home/grid/.ssh'

Enter passpharse (empty for no passpharse):

Enter same passpharse again:

Your identification has been saved in /home/grid/.ssh/id_rsa.

Your public key has been saved in /home/grid/.ssh/id_rsa.pub.

The key fingerprint is:

0f:d7:c4:14:cf:06:11:d5:80:ec:1f:c3:f3:3b:7f:22 grid@ncca1The key's randomart image is:

[picture omitted]

grid@ncca1:~$ cat /home/grid/.ssh/id_rsa.pub | ssh grid@ncca2 'cat >> /home/grid/.ssh/authorized_keys'

Kosongkan passphrase yang diminta saat ssh-keygen, langsung tekan enter. Setelah langkah diatas maka sistem akan dapat melakukan SSH tanpa password, lakukan hal yang sama pada slave slave lain dengan target host SSH diganti dengan ncca1.

Konfigurasi MPICH

Pada setiap node, buat file konfigurasi untuk mpich sebagai berikut :• File ~/.mpd.conf

File ini berisi konfigurasi secretword yang harus sama pada setiap node. Gunanya agar setiap node dapat berinteraksi dengan aman. Misal kita isi dengan secretword=grid. File ini harus memiliki permission 600 agar hanya dapat dibaca dan ditulis oleh user grid.

• File ~/mpd.hostsFile ini berisi nama host setiap node yang terlibat dalam cluster. Misal isi dari file tersebut.ncca1ncca2ncca3

Menjalankan Mesin

Untuk menjalankan mesin pada semua grid, dapat dilakukan dengan beberapa perintah yaitu :

• mpdboot – start the cluster

• mpdtrace - list all nodes in the cluster

• mpdallexit – shut down the cluster

Page 7: Laporan Grid NCC 1

Pada kasus ini, kita akan menjalankan mesin pada semua node, yaitu dengan perintah :grid@ncca1:~$ mpdboot -n 3

Kompilasi Source Code

Misal kita mempunyai code matrix.c yang terdapat di direktori ~/matrix.c, untuk melakukan kompilasi dan menjalankan code tersebut, dilakukan dengan perintah :

grid@ncca1:~$ mpic++ matrix.c -o /mirror/matrixgrid@ncca1:~$ mpiexec /mirror/matrix

Konfigurasi Sun Grid Engine

Konfigurasi pada Head Node / Master

1. Download paket-paket berikut dari situs http://gridengine.sunsource.net/downloads/61/download.html• ge-6.1u6-common.tar.gzPaket common Sun Grid Engine untuk semua platform• ge-6.1u6-bin-lx24-x86.tar.gzPaket Sun Grid Engine untuk Linux x86

2. Buat folder pada folder yang dapat di akses oleh semua node dalam satu cluster. Dalam konfigurasi ini, folder tersebut terletak di /mirror.mkdir /mirror/ge-common

3. Ekstrak dua file yang telah diunduh di atas dalam folder /mirror/ge-common dengan perintah.tar -xvzf ge-6.1u6-common.tar.gztar -xvzf ge-6.1u6-bin-lx24-x86.tar.gz

4. Setting path SGE_ROOT dengan lokasi kita mengekstrak dua file di atas yaitu di folder /mirror/ge-commonexport SGE_ROOT=/mirror/ge-common

5. Jalankan file instalasi dengan perintah./install_qmasterPada saat inistalasi akan diajukan beberapa pertanyaan. Pertanyaan tersebut dapat dijawab sesuai dengan konfigurasi dari node yang kita punya.

6. Untuk mengecek host yang terdaftar dalam lingkungan SGE, dapat dilakukan dengan perintah /bin/lx24-x86/qconf -sh

7. Jika host yang terdaftar masih kosong, dpaat ditambah dengan perintah /bin/lx24-x86/qconf -ah. Pada kasus cluster ini terdapat 3 host yaitu ncca1, ncca2, dan ncca3./bin/lx24-x86/qconf -ah ncca1/bin/lx24-x86/qconf -ah ncca2/bin/lx24-x86/qconf -ah ncca3

Page 8: Laporan Grid NCC 1

8. Konfigurasi SGE agar dapat mengenali MPICH yang sudah terlebih dahulu terinstall. Perintahyang dijalankan adalah

/bin/lx24-x86/qconf -ap mpich9. Setelah menjalankan perintah tersebut, akan muncul setting konfigurasi. Isikan setting

konfigurasi seperti berikutpe_name mpich slots 9999 user_lists NONE xuser_lists NONE start_proc_args /mirror/ge-common/mpi/startmpi.sh $pe_hostfile stop_proc_args /mirror/ge-common/mpi/stopmpi.sh allocation_rule $round_robin control_slaves FALSE job_is_first_task TRUE urgency_slots min pe_list make mpich

10. Simpan konfigurasi tersebut (konfigurasi tersebut diedit dengan editor default sistem anda, contoh vim).

Konfigurasi pada Worker Node / Slave

1. Pada tiap-tiap worker node / slave yang berada dalam cluster dan dapat mengakses NFS yang sudah kita buat sebelumnya, dilakukan instalasi daemon dengan perintah/mirror/ge-common/install_execdPada saat instalasi daemon akan ditanyakan beberapa pertanyaan yang harus dijawab sesuai dengan spesifikasi sistem.

Page 9: Laporan Grid NCC 1

Kode Pararel Programming

Matrix Vector Multiplication

Algoritma for i = 1 to n do Si : yi = 0; for j = 1 to n do yi = yi + ai,j * xj ; EndforEndfor

Pembagian proses komputasi dilakukan pada tiap row pada matrix, dimana proses komputasi hasil perkalian perbaris dibagi berdasarkan jumlah rank atau resource processor yang dijalankan

Source Code#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>#include "mpi.h"#define X 5#define Y 5#define Z 5#define ROW_MES_TAG 123#define MAT2_MES_TAG 1#define MAX_VALUE 10

int matrix1[X][Y];int matrix2[Y][Z];int result[X][Z];int therow[Y];int tmprow[Y];

//membuat matrix secara randomvoid generateRandomMatrix(){

int i,j;for(i=0;i<X;i++){

for(j=0;j<Y;j++)matrix1[i][j] = rand()%MAX_VALUE;

}

for(i=0;i<Y;i++){

for(j=0;j<Z;j++)matrix2[i][j] = rand()%MAX_VALUE;

}}//simpan ke temporaryvoid transfer(int rownum){

for(int i = 0; i < Y; i++){

tmprow[i] = matrix1[rownum][i];}

}

Page 10: Laporan Grid NCC 1

//mapping processorint proc_map(int rowNum, int size){ if((rowNum+1)%size==0) return size; else return (rowNum+1)%size;}

//komputasi satu barisvoid computeSingleRow(){

int i,j;for(j=0;j<Z;j++){

result[0][j] = 0;for(i=0;i<Y;i++){

result[0][j]+=therow[i]*matrix2[i][j];}

}}

int taskNumber(int therank, int size){

int hasil = floor(X/(size-1));if(therank<=X%(size-1)) hasil+=1;return hasil;

}

//cetak inputvoid writeMatrixInput(){

int i,j;printf("Matriks A\n====================\n");for(i=0;i<X;i++){

for(j=0;j<Y;j++){

printf("%d ",matrix1[i][j]);}printf("\n");

}printf("\nMatriks B\n====================\n");for(i=0;i<X;i++)

{ for(j=0;j<Y;j++) { printf("%d ",matrix2[i][j]); } printf("\n"); }

}

//cetakoutputvoid writeMatrixOutput(){

int i,j; printf("\n\n===HASIL PERKALIAN MATRIKS DAN MATRIKS===\n"); for(i=0;i<X;i++) { for(j=0;j<Z;j++)

Page 11: Laporan Grid NCC 1

{ printf("%d\t",result[i][j]); } printf("\n"); }}

bool adaSisa(int size, int CurrentRow){

if(X%(size-1)!=0 && CurrentRow==X-1)return true;

return false;}

int main (int argc, char **argv){

srand ( time(NULL) );

int rank; int size; int i,j,k; double time0, time1;

MPI_Status status;

MPI_Init(&argc, &argv);

MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if(rank==0){

generateRandomMatrix();writeMatrixInput();time0 = MPI_Wtime();for(i=1;i<size;i++)

MPI_Send(matrix2,Y*Z,MPI_INT,i,MAT2_MES_TAG,MPI_COMM_WORLD);k=0;for(i=0;i<X;i++){

transfer(i);MPI_Send(tmprow,Y,MPI_INT,proc_map(i,size-

1),ROW_MES_TAG,MPI_COMM_WORLD);//printf("\ni-nya>> %d", i);if((i+1)%(size-1)==0){

//printf("\nmasuk sini ketika i>> %d",i);for(j=1;j<=(size-1);j++){

MPI_Recv(result[k],Z,MPI_INT,j,ROW_MES_TAG,MPI_COMM_WORLD,&status);k+=1;

}}

if(adaSisa(size,i)){

for(j=1;j<=X%(size-1);j++) { MPI_Recv(result[k],Z,MPI_INT,j,ROW_MES_TAG,MPI_COMM_WORLD,&status); k+=1; }

}

Page 12: Laporan Grid NCC 1

} time1 = MPI_Wtime(); printf ("\nWaktu Total (Komputasi+Pengiriman) : [%f] seconds\n", time1 - time0);

writeMatrixOutput();}

if(rank!=0){

MPI_Recv(matrix2,Y*Z,MPI_INT,0,MAT2_MES_TAG,MPI_COMM_WORLD,&status);int flag = taskNumber(rank,size);//printf("\nflag = %d",flag);for(int i=0;i < flag;i++){

MPI_Recv(therow,Y,MPI_INT,0,ROW_MES_TAG,MPI_COMM_WORLD,&status);time0 = MPI_Wtime();

computeSingleRow();time1 = MPI_Wtime();

printf ("\nWaktu Komputasi ke-%d : [%f] seconds\n",i, time1 - time0);

MPI_Send(result[0],Z,MPI_INT,0,ROW_MES_TAG,MPI_COMM_WORLD);}

}

MPI_Finalize();

return 0;}

Dokumentasi

Page 13: Laporan Grid NCC 1

Matrix Matrix Multiplication

Algoritmafor i = 1 to n do Ti : for j = 1 to n do sum = 0; for k = 1 to n do sum = sum + a(i,k) * b (k,j); Endfor c(i,j) = sum; EndforEndfor

Source Code#include <stdio.h>#include <stdlib.h>#include <math.h>#include <time.h>

Page 14: Laporan Grid NCC 1

#include "mpi.h"#define X 5#define Y 5#define Z 5#define ROW_MES_TAG 123#define MAT2_MES_TAG 1#define MAX_VALUE 10

int matrix1[X][Y];int matrix2[Y][Z];int result[X][Z];int therow[Y];int tmprow[Y];

//membuat matrix secara randomvoid generateRandomMatrix(){

int i,j;for(i=0;i<X;i++){

for(j=0;j<Y;j++)matrix1[i][j] = rand()%MAX_VALUE;

}

for(i=0;i<Y;i++){

for(j=0;j<Z;j++)matrix2[i][j] = rand()%MAX_VALUE;

}}//simpan ke temporaryvoid transfer(int rownum){

for(int i = 0; i < Y; i++){

tmprow[i] = matrix1[rownum][i];}

}

//mapping processorint proc_map(int rowNum, int size){ if((rowNum+1)%size==0) return size; else return (rowNum+1)%size;}

//komputasi satu barisvoid computeSingleRow(){

int i,j;for(j=0;j<Z;j++){

result[0][j] = 0;for(i=0;i<Y;i++){

result[0][j]+=therow[i]*matrix2[i][j];}

}}

int taskNumber(int therank, int size){

Page 15: Laporan Grid NCC 1

int hasil = floor(X/(size-1));if(therank<=X%(size-1)) hasil+=1;return hasil;

}

//cetak inputvoid writeMatrixInput(){

int i,j;printf("Matriks A\n====================\n");for(i=0;i<X;i++){

for(j=0;j<Y;j++){

printf("%d ",matrix1[i][j]);}printf("\n");

}printf("\nMatriks B\n====================\n");for(i=0;i<X;i++)

{ for(j=0;j<Y;j++) { printf("%d ",matrix2[i][j]); } printf("\n"); }

}

//cetakoutputvoid writeMatrixOutput(){

int i,j; printf("\n\n===HASIL PERKALIAN MATRIKS DAN MATRIKS===\n"); for(i=0;i<X;i++) { for(j=0;j<Z;j++) { printf("%d\t",result[i][j]); } printf("\n"); }}

bool adaSisa(int size, int CurrentRow){

if(X%(size-1)!=0 && CurrentRow==X-1)return true;

return false;}

int main (int argc, char **argv){

srand ( time(NULL) );

int rank; int size; int i,j,k; double time0, time1;

MPI_Status status;

MPI_Init(&argc, &argv);

Page 16: Laporan Grid NCC 1

MPI_Comm_size(MPI_COMM_WORLD, &size); MPI_Comm_rank(MPI_COMM_WORLD, &rank);

if(rank==0){

generateRandomMatrix();writeMatrixInput();time0 = MPI_Wtime();for(i=1;i<size;i++)

MPI_Send(matrix2,Y*Z,MPI_INT,i,MAT2_MES_TAG,MPI_COMM_WORLD);k=0;for(i=0;i<X;i++){

transfer(i);MPI_Send(tmprow,Y,MPI_INT,proc_map(i,size-

1),ROW_MES_TAG,MPI_COMM_WORLD);//printf("\ni-nya>> %d", i);if((i+1)%(size-1)==0){

//printf("\nmasuk sini ketika i>> %d",i);for(j=1;j<=(size-1);j++){

MPI_Recv(result[k],Z,MPI_INT,j,ROW_MES_TAG,MPI_COMM_WORLD,&status);k+=1;

}}

if(adaSisa(size,i)){

for(j=1;j<=X%(size-1);j++) { MPI_Recv(result[k],Z,MPI_INT,j,ROW_MES_TAG,MPI_COMM_WORLD,&status); k+=1; }

}}

time1 = MPI_Wtime(); printf ("\nWaktu Total (Komputasi+Pengiriman) : [%f] seconds\n", time1 - time0);

writeMatrixOutput();}

if(rank!=0){

MPI_Recv(matrix2,Y*Z,MPI_INT,0,MAT2_MES_TAG,MPI_COMM_WORLD,&status);int flag = taskNumber(rank,size);//printf("\nflag = %d",flag);for(int i=0;i < flag;i++){

MPI_Recv(therow,Y,MPI_INT,0,ROW_MES_TAG,MPI_COMM_WORLD,&status);time0 = MPI_Wtime();

computeSingleRow();time1 = MPI_Wtime();

printf ("\nWaktu Komputasi ke-%d : [%f] seconds\n",i, time1 - time0);

MPI_Send(result[0],Z,MPI_INT,0,ROW_MES_TAG,MPI_COMM_WORLD);}

}

MPI_Finalize();

Page 17: Laporan Grid NCC 1

return 0;}

Dokumentasi

Page 18: Laporan Grid NCC 1

LAPORAN METODE GAUSS

Penjelasan Source Code :

Pertama kita menginputkan jumlah persamaan di proses master dan membroadcastnyaif (pid == 0) { printf("Enter size of matrix: "); scanf("%d",jumlahPersamaan); } MPI_Bcast(jumlahPersamaan, 1, MPI_INT, 0, MPI_COMM_WORLD);

Kemudian kita menginputkan matrix yang merupakan koefisien-koefisien persamaan linear.void inputMatrix(int n, int jumlahProsesor, float var[]){ float input[UKURAN*(UKURAN+1)], cyclic[UKURAN*(UKURAN+1)]; int i,j,count,no_rows; int sizes[jumlahProsesor], displs[jumlahProsesor];

if (pid == 0) { count = 0; printf("Enter the elements of the matrix.\n"); printf("All floats please.\n"); for (i=1; i<=n; i++)

{ for (j=1;j<=n; j++) { printf("Enter a[%d][%d]: ", i, j); scanf("%f", &input[count]); count++; } count++;}

for (i=1; i<=n; i++){ printf("Enter b[%d]: ", i); scanf("%f", &input[i*n+i-1]); }

buatCyclicMatrix(input, cyclic); }

for (i=0;i<n%jumlahProsesor;i++) sizes[i] = (n/jumlahProsesor + 1)*(n+1); for (i=n%jumlahProsesor;i<jumlahProsesor;i++) sizes[i] = (n/jumlahProsesor)*(n+1);

Page 19: Laporan Grid NCC 1

displs[0] = 0; for (i=1;i<jumlahProsesor;i++) displs[i] = displs[i-1] + sizes[i-1];

MPI_Scatterv(cyclic, sizes, displs, MPI_FLOAT, var, UKURAN*UKURAN, MPI_FLOAT, 0, MPI_COMM_WORLD);}

Kemudian tahap selanjutnya kita melakukan eliminasi Gauss atau yang dinamakan Forward Elimination. Di dalam fungsi eliminasi Gauss ini juga dipanggil fungsi pipeline untuk Backward Substitution nya.void eliminasiGauss(float m[], float x[]){ int j;

for (j=1; j<jumlahPersamaan; j++) dealBarisKeJ(m, j);

pipeline(pecahkanPersamaanKeI_init, pecahkanPersamaanKeI_g, pecahkanPersamaanKeI_h, m, x);}void pipeline (void (*init) (float *, float *),void (*g) (int, float *, float *, float),void (*h) (int, float *, float *),float local_vals[], float res[]){ float tmp, sum; int startelt, endelt, no_seen, no_to_receive; float accum[jumlahPersamaan]; MPI_Status status; int n = jumlahPersamaan; int x, i, j;

if (pid==(n-1)%jumlahProsesor) { (*init)(&sum, &local_vals[((n-1)/jumlahProsesor)*(n+1)]); (*h)(n-1, &sum, &local_vals[((n-1)/jumlahProsesor)*(n+1)]); res[(n-1)/jumlahProsesor] = sum; MPI_Send(&sum, 1, MPI_FLOAT, mod(pid-1,jumlahProsesor), 0, MPI_COMM_WORLD); accum[0] = sum; no_seen = 1; } else no_seen = 0;

if (n<jumlahProsesor) { if (pid < n-1) startelt = 0; else startelt = -1; } else if (n%jumlahProsesor == 0) {

Page 20: Laporan Grid NCC 1

if (pid < (n-1)%jumlahProsesor)startelt = n/jumlahProsesor - 1;

elsestartelt = n/jumlahProsesor - 2;

} else if (pid > n%jumlahProsesor - 2) startelt = n/jumlahProsesor - 1; else startelt = n/jumlahProsesor;

if (pid>0) endelt = 0; else endelt = 1;

for (x=startelt; x>=endelt; x--) { (*init)(&sum, &local_vals[x*(n+1)]);

for (i=0; i<no_seen; i++) (*g)(i+1, &sum, &local_vals[x*(n+1)], accum[i]);

if (no_seen==0) no_to_receive = (n-pid-1)%jumlahProsesor; else no_to_receive = jumlahProsesor-1;

for (j=0; j<no_to_receive; j++) { MPI_Recv(&tmp, 1, MPI_FLOAT, (pid+1)%jumlahProsesor, 0, MPI_COMM_WORLD, &status);

if ((j==0) && ((no_seen>0)||((no_seen==0)&&(pid==n%jumlahProsesor)))) ; else MPI_Send (&tmp, 1, MPI_FLOAT, mod(pid-1,jumlahProsesor), 0,

MPI_COMM_WORLD);

no_seen++; accum[no_seen-1] = tmp; (*g)(no_seen, &sum, &local_vals[x*(n+1)], tmp); }

(*h)(pid+jumlahProsesor*x, &sum, &local_vals[x*(n+1)]); res[x] = sum; MPI_Send(&sum, 1, MPI_FLOAT, mod(pid-1,jumlahProsesor), 0, MPI_COMM_WORLD);

no_seen++; accum[no_seen-1] = sum; }

if (pid==0)

Page 21: Laporan Grid NCC 1

{ (*init)(&sum, &local_vals[0]);

for (i=0; i<no_seen; i++)(*g)(i+1, &sum, &local_vals[0], accum[i]);

if (no_seen==0) no_to_receive = (n-pid-1)%jumlahProsesor; else no_to_receive = jumlahProsesor-1;

for (j=0; j<no_to_receive; j++) { MPI_Recv(&tmp, 1, MPI_FLOAT, 1, 0, MPI_COMM_WORLD, &status); no_seen++; (*g)(no_seen, &sum, &local_vals[0], tmp); }

(*h)(0, &sum, &local_vals[0]); res[0] = sum; }}Contoh :

Setelah tahap Forward Elimination menjadi

Dan setelah dilakukan Backward Substitution menjadi