/*------------------------------------------------------------------*/ int main(int argc, char* argv[]) { long thread; pthread_t* thread_handles; double start, finish; if (argc != 4) Usage(argv[0]); thread_count = strtol(argv[1], NULL, 10); m = strtol(argv[2], NULL, 10); n = strtol(argv[3], NULL, 10); # ifdef DEBUG printf("thread_count = %d, m = %d, n = %d\n", thread_count, m, n); # endif thread_handles = malloc(thread_count*sizeof(pthread_t)); sem_init(&sem, 0, 1); /* Initial value is 1 */ A = malloc(m*n*sizeof(double)); x = malloc(n*sizeof(double)); y = malloc(m*sizeof(double)); srandom(1); Gen_matrix(A, m, n); # ifdef DEBUG Print_matrix("We generated", A, m, n); # endif Gen_vector(x, n); # ifdef DEBUG Print_vector("We generated", x, n); # endif GET_TIME(start); for (thread = 0; thread < thread_count; thread++) pthread_create(&thread_handles[thread], NULL, Pth_mat_vect, (void*) thread); for (thread = 0; thread < thread_count; thread++) pthread_join(thread_handles[thread], NULL); GET_TIME(finish); # ifdef DEBUG Print_vector("The product is", y, m); # endif printf("Elapsed time = %e seconds\n", finish - start); free(A); free(x); free(y); sem_destroy(&sem); free(thread_handles); return 0; } /* main */
/*------------------------------------------------------------------*/ int main(int argc, char* argv[]) { int thread_count; int m, n; double* A; double* x; double* y; Get_args(argc, argv, &thread_count, &m, &n); A = malloc(m*n*sizeof(double)); x = malloc(n*sizeof(double)); y = malloc(m*sizeof(double)); # ifdef DEBUG Read_matrix("Enter the matrix", A, m, n); Print_matrix("We read", A, m, n); Read_vector("Enter the vector", x, n); Print_vector("We read", x, n); # else Gen_matrix(A, m, n); /* Print_matrix("We generated", A, m, n); */ Gen_vector(x, n); /* Print_vector("We generated", x, n); */ # endif Omp_mat_vect(A, x, y, m, n, thread_count); # ifdef DEBUG Print_vector("The product is", y, m); # else /* Print_vector("The product is", y, m); */ # endif free(A); free(x); free(y); return 0; } /* main */
int main(int argc, char const *argv[]) { int matrixSize = strtol(argv[1], NULL, 10); int coreCount = omp_get_num_procs(); int threadCount = strtol(argv[2], NULL, 10); double startTime, finishTime; double **a_augmented, **a; // n x n Matrix as a 2D array double diagonalElement, bestElement, factor; int bestRowIndex = 0; // used in partial pivoting (index of row having greatest absolute value) int i, j, k; // for loop counters double *x; // Solutions double *b; printf("Matrix Size: %d\n", matrixSize); printf("Number of Cores: %d\n", coreCount); #pragma omp parallel num_threads(threadCount) { if (omp_get_thread_num() == 0) printf("Thread Count: %d\n", omp_get_num_threads()); } // Start Timer startTime = omp_get_wtime(); // Allocate memory // a_augmented will be the augmented matrix a_augmented = (double **) malloc(matrixSize * sizeof(double *)); // a will be the randomly generated matrix a = (double **) malloc(matrixSize * sizeof(double *)); x = (double *) malloc(matrixSize * sizeof(double)); b = (double *) malloc(matrixSize * sizeof(double)); if (DEBUG == 1) Read_matrix(&a, &a_augmented, matrixSize); else Gen_matrix(&a, &a_augmented, matrixSize, threadCount); // a will not be modified after this point // Only the a_augmented will be modified // Display generated matrix: displayMatrix(a, matrixSize); for (i = 0; i < matrixSize - 1; ++i) { // Partial Pivoting: // the algorithm selects the entry with largest absolute value from // the column of the matrix that is currently being considered as // the pivot element. // Diagonal Element diagonalElement = a_augmented[i][i]; // debug_printf("diagonalElement%d = %f\n", i, diagonalElement); // Find the best row (the one with the largest absolute value in the // column being worked on) bestRowIndex = i; bestElement = diagonalElement; for (j = i + 1; j < matrixSize; ++j) { if (fabs(a_augmented[j][i]) > fabs(bestElement)) { bestRowIndex = j; bestElement = a_augmented[j][i]; // debug_printf("bestElement = %f\n", a_augmented[j][i]); } } // Swap the rows if (i != bestRowIndex) { // debug_printf("Row %d needs to be swapped with Row %d\n", i, bestRowIndex ); swapRow(&a_augmented[i], &a_augmented[bestRowIndex]); // Update the diagonal element diagonalElement = a_augmented[i][i]; // debug_printf("diagonalElement%d = %f\n", i, diagonalElement); // displayMatrix(a_augmented, matrixSize); } // End of Partial Pivoting // To make the diagonal element 1, // divide the whole row with the diagonal element // debug_printf("Row %d = Row %d / %f\n", i, i, diagonalElement); for (j = 0; j < matrixSize + 1; ++j) { a_augmented[i][j] = a_augmented[i][j] / diagonalElement; } // Force the diagonal to be 1 (to avoid any roundoff errors in dividing above) a_augmented[i][i] = 1; diagonalElement = 1; // debug_printf("Annihilation of column %d...\n", i); // Annihilation: Zero all the elements in the column below the diagonal element #pragma omp parallel for num_threads(threadCount) \ default(none) private(j, factor, k) shared(i, matrixSize, a_augmented) for (j = i + 1; j < matrixSize; ++j) { // sleep(1); factor = a_augmented[j][i]; if (factor != 0) { // debug_printf("Row %d = Row %d - %f*Row %d\n", j, j, factor, i); for (k = i; k < matrixSize + 1; ++k) { a_augmented[j][k] = a_augmented[j][k] - factor * a_augmented[i][k]; } // displayAugmentedMatrix(a, matrixSize); } } } // Make the diagonal element of the last row 1 a_augmented[matrixSize-1][matrixSize] = a_augmented[matrixSize-1][matrixSize] / a_augmented[matrixSize-1][matrixSize-1]; a_augmented[matrixSize-1][matrixSize-1] = 1; // Display augmented matrix: displayMatrix(a_augmented, matrixSize); // Back substitution (parallelized) backSubstitution(&a_augmented, matrixSize, threadCount); // Record the finish time finishTime = omp_get_wtime(); displayMatrix(a_augmented, matrixSize); // Matrix X from augmented matrix // Vector b from matrix A for (i = 0; i < matrixSize; ++i) { x[i] = a_augmented[i][matrixSize]; b[i] = a[i][matrixSize]; } // Find I^2 norm iSquaredNorm(&a, x, b, matrixSize, threadCount); // Print the time taken printf("Time taken = %f\n", finishTime - startTime); // Free memory for (i = 0; i < matrixSize; ++i) { free(a[i]); free(a_augmented[i]); } free(a); free(a_augmented); free(x); free(b); return 0; }