Question
Need to convert the following code from MPI to SSE using only SSE commands: #include #include #include #include #include mpi.h #define N 64 #define MIN_RAND
Need to convert the following code from MPI to SSE using only SSE commands:
#include
#include
#include
#include
#include "mpi.h"
#define N 64
#define MIN_RAND 0
#define MAX_RAND 10
int cpu, numcpus;
/////////////////////////////Cramer's Rule Algorithm////////////////////////////////////
typedef struct {
int n;
double **elems;
} SquareMatrix;
struct timeval start, end;
void starttime() {
gettimeofday( &start, 0 );
}
void endtime(const char* c) {
gettimeofday( &end, 0 );
double elapsed = ( end.tv_sec - start.tv_sec ) * 1000.0 + ( end.tv_usec - start.tv_usec ) / 1000.0;
printf("%s: %f ms ", c, elapsed);
}
SquareMatrix init_square_matrix(int n, double elems[N][N]) {
SquareMatrix A = {
.n = n,
.elems = (double **) malloc(n * sizeof(double *))
};
int i = 0;
for (i = 0; i < n; ++i) {
A.elems[i] = (double *) malloc(n * sizeof(double));
int j = 0;
for (j = 0; j < n; ++j)
A.elems[i][j] = elems[i][j];
}
return A;
}
SquareMatrix copy_square_matrix(SquareMatrix src) {
SquareMatrix dest;
dest.n = src.n;
dest.elems = (double **) malloc(dest.n * sizeof(double *));
int i = 0;
for (i = 0; i < dest.n; ++i) {
dest.elems[i] = (double *) malloc(dest.n * sizeof(double));
int j = 0;
for (j = 0; j < dest.n; ++j)
dest.elems[i][j] = src.elems[i][j];
}
return dest;
}
double det(SquareMatrix A) {
double det = 1;
int j = 0;
for (j = 0; j < A.n; ++j) {
int i_max = j;
int i = 0;
for (i = j; i < A.n; ++i)
if (A.elems[i][j] > A.elems[i_max][j])
i_max = i;
if (i_max != j) {
int k = 0;
for (k = 0; k < A.n; ++k) {
double tmp = A.elems[i_max][k];
A.elems[i_max][k] = A.elems[j][k];
A.elems[j][k] = tmp;
}
det *= -1;
}
for (i = j + 1; i < A.n; ++i) {
double mult = -A.elems[i][j] / A.elems[j][j];
int k = 0;
for (k = 0; k < A.n; ++k)
A.elems[i][k] += mult * A.elems[j][k];
}
}
int i = 0;
for (i = 0; i < A.n; ++i)
det *= A.elems[i][i];
return det;
}
void deinit_square_matrix(SquareMatrix A) {
int i = 0;
for (i = 0; i < A.n; ++i)
free(A.elems[i]);
free(A.elems);
}
double cramer_solve(SquareMatrix A, double det_A, double *b, int var) {
SquareMatrix tmp = copy_square_matrix(A);
int i = 0;
for (i = 0; i < tmp.n; ++i)
tmp.elems[i][var] = b[i];
double det_tmp = det(tmp);
deinit_square_matrix(tmp);
return det_tmp / det_A;
}
////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////New Functions/////////////////////////////////////////////
/**
* Creates a new SquareMatrix with random values.
* Param size: The size of the matrix.
*/
SquareMatrix init_rand_square_matrix(int size) {
SquareMatrix matrix = {
.n = size,
.elems = (double **) malloc(size * sizeof(double *))
};
int row, col;
for (row = 0; row < size; ++row) {
matrix.elems[row] = (double *) malloc(size * sizeof(double));
for (col = 0; col < size; ++col)
matrix.elems[row][col] = rand() % (MAX_RAND + 1 - MIN_RAND) + MIN_RAND;
}
return matrix;
}
/**
* Prints a SquareMatrix.
* Param matrix: The matrix to be printed.
*/
void print_matrix(SquareMatrix matrix) {
int row, col;
for (row = 0; row < matrix.n; row++) {
for (col = 0; col < matrix.n; col++)
printf("%f\t", matrix.elems[row][col]);
printf(" ");
}
}
/**
* Calculates a matrix's determinants sequentially.
* Param matrix: The matrix to calculate.
* Param det: The determinant of the matrix.
* Param answers: An array containing the constants of each equation.
*/
void normal(SquareMatrix matrix, double det, double *answers) {
printf("***************** %s ********************** ", "Normal");
starttime();
int i = 0;
for (i = 0; i < matrix.n; ++i) {
cramer_solve(matrix, det, answers, i);
}
endtime("Normal");
printf("*************************************************** ");
}
/**
* Calculates a matrix's determinants using the multi-core parallelism technique.
* Param matrix: The matrix to calculate.
* Param det: The determinant of the matrix.
* Param answers: An array containing the constants of each equation.
*/
void mpi(SquareMatrix matrix, double det, double *answers) {
int i, j, slave, det_index;
MPI_Status status;
int numeach = ceil((N / 1.0)/numcpus);
////////////////////////////////////////////////////////////////////////////////////////
// I AM THE MASTER
if (cpu == 0) {
double data[matrix.n];
for (slave = 1; slave < numcpus; slave++) {
MPI_Send(&matrix.n, 1, MPI_INT, slave, 1, MPI_COMM_WORLD);
for (i = 0; i < matrix.n; i++) {
MPI_Send(&matrix.elems[i][0], matrix.n, MPI_DOUBLE, slave, 1, MPI_COMM_WORLD);
}
MPI_Send(&det, 1, MPI_DOUBLE, slave, 1, MPI_COMM_WORLD);
MPI_Send(answers, matrix.n, MPI_DOUBLE, slave, 1, MPI_COMM_WORLD);
MPI_Send(&data[numeach*slave], numeach, MPI_FLOAT, slave, 1, MPI_COMM_WORLD);
}
for (i = 0; i < numeach; i++) {
data[i] = cramer_solve(matrix, det, answers, i);
}
for (slave = 1; slave < numcpus; slave++)
MPI_Recv(&data[numeach * slave], numeach, MPI_DOUBLE, slave, 2, MPI_COMM_WORLD, &status);
}
/////////////////////////////////////////////////////////////////////////////////////////
// I AM A SLAVE
else {
double data[numeach];
int n = 0;
MPI_Recv(&n, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
matrix = init_rand_square_matrix(n);
for (i = 0; i < matrix.n; i++) {
MPI_Recv(&matrix.elems[i][0], matrix.n, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
}
MPI_Recv(&det, 1, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
MPI_Recv(answers, matrix.n, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
MPI_Recv(&data[0], numeach, MPI_DOUBLE, 0, 1, MPI_COMM_WORLD, &status);
for (i = numeach * cpu; i < numeach * (cpu + 1) && i < matrix.n; i++) {
data[i - numeach * cpu] = cramer_solve(matrix, det, answers, i);
}
MPI_Send(&data[0], numeach, MPI_DOUBLE, 0, 2, MPI_COMM_WORLD);
}
/////////////////////////////////////////////////////////////////////////////////////////
}
/**
* Program entry point.
* Param argc: The number of arguments passed to this program.
* Param argv: The list of arguments passed to this program.
*/
int main(int argc, char **argv)
{
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &cpu);
MPI_Comm_size(MPI_COMM_WORLD, &numcpus);
SquareMatrix A;
double* b = (double *) malloc(N * sizeof(double));
double det_A;
if (cpu == 0)
{
srand((unsigned) time(NULL));
A = init_rand_square_matrix(N);
int i = 0;
for (i = 0; i < N; ++i)
b[i] = rand() % 10;
SquareMatrix tmp = copy_square_matrix(A);
det_A = det(tmp);
deinit_square_matrix(tmp);
normal(A, det_A, b);
printf("***************** %s ********************** ", "MPI");
starttime();
}
mpi(A, det_A, b);
if (cpu == 0)
{
deinit_square_matrix(A);
free(b);
endtime("MPI");
printf("*************************************************** ");
}
MPI_Finalize();
return EXIT_SUCCESS;
}
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started