From 8795ba4f274a9f6ca44ddb9de44638054395364e Mon Sep 17 00:00:00 2001 From: mfikrin <muhammad.fikrin1729@gmail.com> Date: Sun, 6 Mar 2022 18:58:43 +0700 Subject: [PATCH] feat : tc spek passed --- src/par | Bin 21944 -> 22016 bytes src/parallel.c | 234 ++++++++++++++++++------ src/parallel2.c | 476 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 658 insertions(+), 52 deletions(-) create mode 100644 src/parallel2.c diff --git a/src/par b/src/par index 8bf4ea24047dd88c1e67dfcc6830ff4f8b2f82c4..ffafc83fe9e030b3ca6386844af9bd6f87ef3bf2 100644 GIT binary patch delta 5872 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 NQ`7^W1bw?K`G1DK#^V40 delta 4436 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 diff --git a/src/parallel.c b/src/parallel.c index ebf4562..2f3cec5 100644 --- a/src/parallel.c +++ b/src/parallel.c @@ -289,6 +289,8 @@ int main() { // 10 / 4 = 2 2 2 (10-6) int kernel_row, kernel_col, target_row, target_col, num_targets; + int counter_distribute = 0; + int counter_receiver = 0; // reads kernel's row and column and initalize kernel matrix from input scanf("%d %d", &kernel_row, &kernel_col); @@ -299,7 +301,7 @@ int main() { // initialize array of matrices and array of data ranges (int) scanf("%d %d %d", &num_targets, &target_row, &target_col); Matrix* arr_mat = (Matrix*)malloc(num_targets * sizeof(Matrix)); - Matrix* arr_mat2 = (Matrix*)malloc(num_targets * sizeof(Matrix)); + int arr_range[num_targets]; @@ -310,8 +312,7 @@ int main() { print_matrix(&kernel); - int counter_distribute = 0; - int counter_receiver = 0; + printf("HELLO OPEN MPI\n"); @@ -354,77 +355,206 @@ int main() { 6 7 8 - 9 + 9 10 11 */ - int root = 0; + int root = 0; + int divide = num_targets/(world_size-1); + + if (world_rank == root){ + // Divide input + int i; + int j = 0; + // int k = 0; + int sisa = num_targets % (world_size-1); + for (int rank = 0; rank < world_size; rank++) { + printf("I = %d\n", rank); + if (rank != world_rank) { + int jumlah_diambil = divide; + printf("jumlah diambil pre-sisa: %d\n", jumlah_diambil); + if (sisa != 0){ + jumlah_diambil += 1; + sisa -= 1; + } + printf("jumlah diambil post-sisa: %d\n", jumlah_diambil); + + MPI_Send(&kernel, 1, mat_MPI, rank, 0, MPI_COMM_WORLD); + MPI_Send(&jumlah_diambil, 1, MPI_INT, rank, 1, MPI_COMM_WORLD); + + for (int k=0; k < jumlah_diambil; k++){ + MPI_Send(&arr_mat[j], 1, mat_MPI, rank, 2+k, MPI_COMM_WORLD); + j++; + } + + printf("Checkpoint A\n"); + } + } + + + printf("BACK TO PROCESS 0"); + // Now receive the message with the allocated buffer + int idxArrRange = 0; + for (int i = 0; i < world_size; i++ ){ + if (i != root){ + MPI_Status status; + // Probe for an incoming message from process zero + MPI_Probe(i, 0, MPI_COMM_WORLD, &status); + // When probe returns, the status object has the size and other + // attributes of the incoming message. Get the message size + int number_amount; + MPI_Get_count(&status, MPI_INT, &number_amount); + // Allocate a buffer to hold the incoming numbers + int* number_buf = (int*)malloc(sizeof(int) * number_amount); - while (counter_distribute < PING_PONG_LIMIT){ - // distribute(arr_mat[counter_distribute],1,mat_MPI,0, MPI_COMM_WORLD) - printf("Counter dis %d \n", counter_distribute); - if (world_rank == root) { - // If we are the root process, send our data to every process - int i; - for (i = 0; i < world_size; i++) { - if (i != world_rank) { - MPI_Send(&arr_mat[counter_distribute], 1, mat_MPI, i, 1, MPI_COMM_WORLD); - MPI_Send(&kernel, 1, mat_MPI, i, 0, MPI_COMM_WORLD); - counter_distribute++; - } + + MPI_Recv(number_buf, number_amount, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + printf("\nPROCESS 0 IN RECEIVING\n"); + print_array(number_buf,number_amount); + //[3] + //[46] + //[22] + + for (int j=0; j<number_amount; j++){ + arr_range[idxArrRange] = number_buf[j]; + idxArrRange++; + } } + } + } else { + Matrix kernel_recv; + MPI_Recv(&kernel_recv, 1, mat_MPI, root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + int totalData; + MPI_Recv(&totalData, 1, MPI_INT, root, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + printf("Total datanya %d \n", totalData); + + print_matrix(&kernel_recv); + + Matrix* arr_mat2 = (Matrix*)malloc(totalData * sizeof(Matrix)); + + for (int i=0; i<totalData; i++){ + Matrix mat_recv; + MPI_Recv(&mat_recv, 1, mat_MPI, root, i+2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + printf("Hasil passing\n"); + print_matrix(&mat_recv); + + arr_mat2[i] = convolution(&kernel_recv, &mat_recv); + + print_matrix(&arr_mat2[i]); + arr_range[i] = get_matrix_datarange(&arr_mat2[i]); + } + + printf("HASILLL RANGE\n"); + merge_sort(arr_range, 0, totalData-1); + print_array(arr_range,totalData); + + MPI_Send(&arr_range, totalData, MPI_INT, 0, 0, MPI_COMM_WORLD); + } + + + // if (world_rank == 0){ + // printf("BACK TO PROCESS 0"); + // // Now receive the message with the allocated buffer + // for (int i = 0; i < world_size; i++ ){ + // if (i != root){ + // MPI_Status status; + // // Probe for an incoming message from process zero + // MPI_Probe(i, 0, MPI_COMM_WORLD, &status); + + // // When probe returns, the status object has the size and other + // // attributes of the incoming message. Get the message size + // int number_amount; + // MPI_Get_count(&status, MPI_INT, &number_amount); + + // // Allocate a buffer to hold the incoming numbers + // int* number_buf = (int*)malloc(sizeof(int) * number_amount); + + + // MPI_Recv(number_buf, number_amount, MPI_INT, i, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // printf("PROCESS 0 IN RECEIVING"); + // print_array(number_buf,number_amount); + // } + // } + // } + + + // while (counter_distribute < PING_PONG_LIMIT){ + // // distribute(arr_mat[counter_distribute],1,mat_MPI,0, MPI_COMM_WORLD) + // printf("Counter dis %d \n", counter_distribute); + // if (world_rank == root) { + // // If we are the root process, send our data to every process + // int i; + // for (i = 0; i < world_size; i++) { + // if (i != world_rank) { + // MPI_Send(&arr_mat[counter_distribute], 1, mat_MPI, i, 1, MPI_COMM_WORLD); + // MPI_Send(&kernel, 1, mat_MPI, i, 0, MPI_COMM_WORLD); + + // counter_distribute++; + + // MPI_Send(&counter_distribute, 1, MPI_INT, i, 2, MPI_COMM_WORLD); + // } + // } - } else { - // If we are a receiver process, receive the data from the root - Matrix recv_data; - MPI_Recv(&recv_data, 1, mat_MPI, root, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - Matrix kernel_recv; - MPI_Recv(&kernel_recv, 1, mat_MPI, root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); - print_matrix(&recv_data); - print_matrix(&kernel_recv); - - printf("HASILLL\n"); - arr_mat2[counter_receiver] = convolution(&kernel_recv, &recv_data); + // } else { + // // If we are a receiver process, receive the data from the root + // Matrix recv_data; + // MPI_Recv(&recv_data, 1, mat_MPI, root, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // Matrix kernel_recv; + // MPI_Recv(&kernel_recv, 1, mat_MPI, root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // print_matrix(&recv_data); + // print_matrix(&kernel_recv); + // MPI_Recv(&counter_distribute, 1, mat_MPI, root, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + // printf("HASILLL\n"); + // arr_mat2[counter_receiver] = convolution(&kernel_recv, &recv_data); - print_matrix(&arr_mat2[counter_receiver]); - arr_range[counter_receiver] = get_matrix_datarange(&arr_mat2[counter_receiver]); + // print_matrix(&arr_mat2[counter_receiver]); + // arr_range[counter_receiver] = get_matrix_datarange(&arr_mat2[counter_receiver]); + // counter_distribute = counter_distribute; + // printf("Counter reciver now %d \n", counter_distribute); + // printf("Counter disribute now %d \n", counter_distribute); + + // counter_receiver++; + // } + // } - counter_receiver++; - } - } + printf("HOOOOOOOOOOOOOOO\n"); + - MPI_Finalize(); - + MPI_Finalize(); - // // Print hasil + // print_array(arr_range,num_targets); + // Print hasil // for (int i = 0; i < num_targets; i++) { // printf("\nMATRIX CONV %d",i); // print_matrix(arr_mat2); // } - // // sort the data range array - // printf("\n"); - // print_array(arr_range,num_targets); - // merge_sort(arr_range, 0, num_targets - 1); + // sort the data range array + printf("BAWAHNYA PRINT ARRAY\n"); + print_array(arr_range,num_targets); + merge_sort(arr_range, 0, num_targets - 1); + + + printf("AFTER SORT\n"); + print_array(arr_range,num_targets); - // int median = get_median(arr_range, num_targets); - // int floored_mean = get_floored_mean(arr_range, num_targets); + int median = get_median(arr_range, num_targets); + int floored_mean = get_floored_mean(arr_range, num_targets); - // // print the min, max, median, and floored mean of data range array - // printf("%d\n%d\n%d\n%d\n", - // arr_range[0], - // arr_range[num_targets - 1], - // median, - // floored_mean); + // print the min, max, median, and floored mean of data range array + printf("HASIL FINALLLL\n"); + printf("MIN : %d\nMAX : %d\nMedian : %d\nRata-Rata : %d\n", + arr_range[0], + arr_range[num_targets - 1], + median, + floored_mean); - // START OPEN MP - - - + // START OPEN MP return 0; } diff --git a/src/parallel2.c b/src/parallel2.c new file mode 100644 index 0000000..f4ecd9b --- /dev/null +++ b/src/parallel2.c @@ -0,0 +1,476 @@ +// serial.c + +#include <stdio.h> +#include <stdlib.h> +#include <mpi.h> + +#define NMAX 100 +#define DATAMAX 1000 +#define DATAMIN -1000 + +/* + * Struct Matrix + * + * Matrix representation consists of matrix data + * and effective dimensions + * */ +typedef struct Matrix { + int mat[NMAX][NMAX]; // Matrix cells + int row_eff; // Matrix effective row + int col_eff; // Matrix effective column +} Matrix; + + +/* + * Procedure init_matrix + * + * Initializing newly allocated matrix + * Setting all data to 0 and effective dimensions according + * to nrow and ncol + * */ +void init_matrix(Matrix *m, int nrow, int ncol) { + m->row_eff = nrow; + m->col_eff = ncol; + + for (int i = 0; i < m->row_eff; i++) { + for (int j = 0; j < m->col_eff; j++) { + m->mat[i][j] = 0; + } + } +} + + +/* + * Function input_matrix + * + * Returns a matrix with values from stdin input + * */ +Matrix input_matrix(int nrow, int ncol) { + Matrix input; + init_matrix(&input, nrow, ncol); + + for (int i = 0; i < nrow; i++) { + for (int j = 0; j < ncol; j++) { + scanf("%d", &input.mat[i][j]); + } + } + + return input; +} + + +/* + * Procedure print_matrix + * + * Print matrix data + * */ +void print_matrix(Matrix *m) { + for (int i = 0; i < m->row_eff; i++) { + for (int j = 0; j < m->col_eff; j++) { + printf("%d ", m->mat[i][j]); + } + printf("\n"); + } +} + + +/* + * Function get_matrix_datarange + * + * Returns the range between maximum and minimum + * element of a matrix + * */ +int get_matrix_datarange(Matrix *m) { + int max = DATAMIN; + int min = DATAMAX; + for (int i = 0; i < m->row_eff; i++) { + for (int j = 0; j < m->col_eff; j++) { + int el = m->mat[i][j]; + if (el > max) max = el; + if (el < min) min = el; + } + } + + return max - min; +} + + +/* + * Function supression_op + * + * Returns the sum of intermediate value of special multiplication + * operation where kernel[0][0] corresponds to target[row][col] + * */ +int supression_op(Matrix *kernel, Matrix *target, int row, int col) { + int intermediate_sum = 0; + for (int i = 0; i < kernel->row_eff; i++) { + for (int j = 0; j < kernel->col_eff; j++) { + intermediate_sum += kernel->mat[i][j] * target->mat[row + i][col + j]; + } + } + + return intermediate_sum; +} + + +/* + * Function convolution + * + * Return the output matrix of convolution operation + * between kernel and target + * */ +Matrix convolution(Matrix *kernel, Matrix *target) { + Matrix out; + int out_row_eff = target->row_eff - kernel->row_eff + 1; + int out_col_eff = target->col_eff - kernel->col_eff + 1; + + // printf("kernel row %d",kernel->row_eff); + // printf("kernel col %d",kernel->col_eff); + + // printf("out_row_eff %d %d",out_row_eff,out_col_eff); + + init_matrix(&out, out_row_eff, out_col_eff); + + for (int i = 0; i < out.row_eff; i++) { + for (int j = 0; j < out.col_eff; j++) { + out.mat[i][j] = supression_op(kernel, target, i, j); + } + } + + return out; +} + + +/* + * Procedure merge_array + * + * Merges two subarrays of n with n[left..mid] and n[mid+1..right] + * to n itself, with n now ordered ascendingly + * */ +void merge_array(int *n, int left, int mid, int right) { + int n_left = mid - left + 1; + int n_right = right - mid; + int iter_left = 0, iter_right = 0, iter_merged = left; + int arr_left[n_left], arr_right[n_right]; + + for (int i = 0; i < n_left; i++) { + arr_left[i] = n[i + left]; + } + + for (int i = 0; i < n_right; i++) { + arr_right[i] = n[i + mid + 1]; + } + + while (iter_left < n_left && iter_right < n_right) { + if (arr_left[iter_left] <= arr_right[iter_right]) { + n[iter_merged] = arr_left[iter_left++]; + } else { + n[iter_merged] = arr_right[iter_right++]; + } + iter_merged++; + } + + while (iter_left < n_left) { + n[iter_merged++] = arr_left[iter_left++]; + } + while (iter_right < n_right) { + n[iter_merged++] = arr_right[iter_right++]; + } +} + + +/* + * Procedure merge_sort + * + * Sorts array n with merge sort algorithm + * */ +void merge_sort(int *n, int left, int right) { + if (left < right) { + int mid = left + (right - left) / 2; + + merge_sort(n, left, mid); + merge_sort(n, mid + 1, right); + + merge_array(n, left, mid, right); + } +} + + +/* + * Procedure print_array + * + * Prints all elements of array n of size to stdout + * */ +void print_array(int *n, int size) { + for (int i = 0; i < size; i++ ) printf("%d ", n[i]); + printf("\n"); +} + + +/* + * Function get_median + * + * Returns median of array n of length + * */ +int get_median(int *n, int length) { + int mid = length / 2; + if (length & 1) return n[mid]; + + return (n[mid - 1] + n[mid]) / 2; +} + + +/* + * Function get_floored_mean + * + * Returns floored mean from an array of integers + * */ +long get_floored_mean(int *n, int length) { + long sum = 0; + for (int i = 0; i < length; i++) { + sum += n[i]; + } + + return sum / length; +} + + +void distribute(void* data, int count, MPI_Datatype datatype, int root, + MPI_Comm communicator) { + int world_rank; + MPI_Comm_rank(communicator, &world_rank); + int world_size; + MPI_Comm_size(communicator, &world_size); + + // Procecss 0 --> Kirim matriks inputan 1,2,3 ke prcess 1,2,3 + // process 1,2,3 -> receive + // prcess 0 --> kirim matriks input 4,5,6, ke process 1,2,3 + + if (world_rank == root) { + // If we are the root process, send our data to every process + int i; + for (i = 0; i < world_size; i++) { + if (i != world_rank) { + MPI_Send(data, count, datatype, i, 0, communicator); + } + } + } else { + // If we are a receiver process, receive the data from the root + MPI_Recv(data, count, datatype, root, 0, communicator, + MPI_STATUS_IGNORE); + + + // Ngitung con sama data range + } +} + +// void init_matrix_kernel() { +// m->row_eff = 2; +// m->col_eff = 2; + +// m->mat[0][0] = 1; +// m->mat[0][1] = 0; +// m->mat[1][0] = 0; +// m->mat[1][1] = -1; +// } + +// main() driver +int main() { + // OPEN MPI + MPI_Init(NULL, NULL); + + int world_rank; + MPI_Comm_rank(MPI_COMM_WORLD, &world_rank); + int world_size; + MPI_Comm_size(MPI_COMM_WORLD, &world_size); + + const int PING_PONG_LIMIT = 3; + printf("HELLO WORLD\n"); + + // 10 / 4 = 2 2 2 (10-6) + int kernel_row, kernel_col, target_row, target_col, num_targets; + int counter_distribute = 0; + int counter_receiver = 0; + + // reads kernel's row and column and initalize kernel matrix from input + scanf("%d %d", &kernel_row, &kernel_col); + // Matrix* kernel = (Matrix*)malloc(num_targets * sizeof(Matrix)); + Matrix kernel = input_matrix(kernel_row, kernel_col); + + // reads number of target matrices and their dimensions. + // initialize array of matrices and array of data ranges (int) + scanf("%d %d %d", &num_targets, &target_row, &target_col); + Matrix* arr_mat = (Matrix*)malloc(num_targets * sizeof(Matrix)); + Matrix* arr_mat2 = (Matrix*)malloc(num_targets * sizeof(Matrix)); + int arr_range[num_targets]; + + + // read each target matrix, compute their convolution matrices, and compute their data ranges + for (int i = 0; i < num_targets; i++) { + arr_mat[i] = input_matrix(target_row, target_col); + } + + print_matrix(&kernel); + + + + printf("HELLO OPEN MPI\n"); + + + + // --------------------------- Create the datatype ----------------------------- // + MPI_Datatype mat_MPI; + int lengths[3] = { NMAX * NMAX, 1, 1 }; + + // Calculate displacements + // In C, by default padding can be inserted between fields. MPI_Get_address will allow + // to get the address of each struct field and calculate the corresponding displacement + // relative to that struct base address. The displacements thus calculated will therefore + // include padding if any. + MPI_Aint displacements[3]; + Matrix dummy_matrix; + MPI_Aint base_address; + MPI_Get_address(&dummy_matrix, &base_address); + MPI_Get_address(&dummy_matrix.mat, &displacements[0]); + MPI_Get_address(&dummy_matrix.row_eff, &displacements[1]); + MPI_Get_address(&dummy_matrix.col_eff, &displacements[2]); + displacements[0] = MPI_Aint_diff(displacements[0], base_address); + displacements[1] = MPI_Aint_diff(displacements[1], base_address); + displacements[2] = MPI_Aint_diff(displacements[2], base_address); + + MPI_Datatype types[3] = { MPI_INT, MPI_INT, MPI_INT }; + MPI_Type_create_struct(3, lengths, displacements, types, &mat_MPI); + MPI_Type_commit(&mat_MPI); + + // --------------------------- End Create the datatype ----------------------------- // + + // Distribusi matriks input ke process-process + + /* + 0 1 2 3 4 5 6 7 8 9 + + 0 1 2 + + 3 4 5 + + 6 7 8 + + 9 10 11 + + */ + + int root = 0; + int divide = num_targets/(world_size-1); + int divideInput[world_size-1]] = { NMAX * NMAX, 1, 1 }; + + // [[1,2,3], [4,5,6], [7,8,9],[10]] + + if (world_rank == root){ + // Divide input + int i; + int sisa = num_targets % (world_size-1) + for (i = 1; i < world_size; i++) { + int jumlah_diambil = divide + if (sisa != 0){ + jumlah_diambil += 1; + sisa -= 1; + } + + + if (i != world_rank) { + MPI_Send(&kernel, 1, mat_MPI, i, 0, MPI_COMM_WORLD); + for (int j=0; j<divide; j++){ + MPI_Send(&arr_mat[j], 1, mat_MPI, i, 1, MPI_COMM_WORLD); + } + } + } + } else { + Matrix recv_data; + MPI_Recv(&recv_data, 1, mat_MPI, root, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + Matrix kernel_recv; + MPI_Recv(&kernel_recv, 1, mat_MPI, root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + + + + } + + + + + + + while (counter_distribute < PING_PONG_LIMIT){ + // distribute(arr_mat[counter_distribute],1,mat_MPI,0, MPI_COMM_WORLD) + printf("Counter dis %d \n", counter_distribute); + if (world_rank == root) { + // If we are the root process, send our data to every process + int i; + for (i = 0; i < world_size; i++) { + if (i != world_rank) { + MPI_Send(&arr_mat[counter_distribute], 1, mat_MPI, i, 1, MPI_COMM_WORLD); + MPI_Send(&kernel, 1, mat_MPI, i, 0, MPI_COMM_WORLD); + + counter_distribute++; + + MPI_Send(&counter_distribute, 1, MPI_INT, i, 2, MPI_COMM_WORLD); + } + } + + } else { + // If we are a receiver process, receive the data from the root + Matrix recv_data; + MPI_Recv(&recv_data, 1, mat_MPI, root, 1, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + Matrix kernel_recv; + MPI_Recv(&kernel_recv, 1, mat_MPI, root, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + print_matrix(&recv_data); + print_matrix(&kernel_recv); + MPI_Recv(&counter_distribute, 1, mat_MPI, root, 2, MPI_COMM_WORLD, MPI_STATUS_IGNORE); + printf("HASILLL\n"); + arr_mat2[counter_receiver] = convolution(&kernel_recv, &recv_data); + + print_matrix(&arr_mat2[counter_receiver]); + arr_range[counter_receiver] = get_matrix_datarange(&arr_mat2[counter_receiver]); + counter_distribute = counter_distribute; + printf("Counter reciver now %d \n", counter_distribute); + printf("Counter disribute now %d \n", counter_distribute); + + counter_receiver++; + } + } + + printf("HOOOOOOOOOOOOOOO"); + + + MPI_Finalize(); + + print_array(arr_range,num_targets); + // Print hasil + for (int i = 0; i < num_targets; i++) { + printf("\nMATRIX CONV %d",i); + print_matrix(arr_mat2); + } + + // sort the data range array + printf("\n"); + print_array(arr_range,num_targets); + merge_sort(arr_range, 0, num_targets - 1); + + int median = get_median(arr_range, num_targets); + int floored_mean = get_floored_mean(arr_range, num_targets); + + // print the min, max, median, and floored mean of data range array + printf("%d\n%d\n%d\n%d\n", + arr_range[0], + arr_range[num_targets - 1], + median, + floored_mean); + + + + // START OPEN MP + + + + + return 0; +} -- GitLab