Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

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

blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Databases A Beginners Guide

Authors: Andy Oppel

1st Edition

007160846X, 978-0071608466

More Books

Students also viewed these Databases questions