Добавил:
Tushkan
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:
#include "StdAfx.h"
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#include <mpi.h>
FILE *f_input, *f_matrix, *f_vector, *f_res, *f_time;
int procQuantity;
int procRank;
int* pProcInd;
int* pProcNum;
void ProcessInitialization (double* &pVector, double* &pResult, double* &pProcRows,
double* &pProcVector, double* &pProcResult, int &Size, int &RowNum)
{
int i,j;
MPI_Status Status;
if (procRank == 0)
{
f_input = fopen("C:\\Users\\main\\Documents\\Visual Studio 2010\\Projects\\lab1\\Debug\\Systems\\system1000.txt", "r");
fscanf(f_input, "%d\n", &Size);
f_vector = fopen("C:\\Users\\main\\Documents\\Visual Studio 2010\\Projects\\lab1\\Debug\\Systems\\vector1000.txt", "r");
fscanf(f_vector, "%d\n", &Size);
}
MPI_Bcast(&Size, 1, MPI_INT, 0, MPI_COMM_WORLD);
int missingRows = Size;
RowNum = Size/procQuantity;
bool fl = false;
missingRows = Size - RowNum * procQuantity;
j = 0;
if (missingRows != 0)
{
for (i = 0; i < procRank; i++)
{
missingRows--;
if (missingRows == 0)
{
fl = true;
j = i;
break;
}
}
if (fl == false)
RowNum++;
}
MPI_Bcast(&j, 1, MPI_INT, procQuantity-1, MPI_COMM_WORLD);
printf("%d \n", j);
pProcRows = (double*)malloc(RowNum*Size*sizeof(double));
pProcVector = new double [RowNum];
pProcResult = new double [RowNum];
pProcInd = new int [procQuantity];
pProcNum = new int [procQuantity];
if (procRank == 0)
{
pVector = new double [Size];
pResult = new double [Size];
for (i=0; i<Size; i++)
{
fscanf(f_vector, "%lg",pVector + i);
}
fclose(f_vector);
}
pProcInd[0] = 0;
pProcNum[0] = ceil((float)Size/procQuantity);
missingRows = Size/procQuantity;
for (i=1; i < procQuantity; i++)
{
if (i <= j)
pProcNum[i] = pProcNum[0];
else
pProcNum[i] = missingRows;
pProcInd[i] = pProcInd[i-1]+pProcNum[i-1];
}
if (procRank == 0)
{
int k = 0;
for (i = 0; i < Size; i++)
{
int destRank = i % procQuantity;
if (destRank == 0)
{
for (j = 0; j < Size; j++)
fscanf(f_input, "%lg", &pProcRows[(i / procQuantity) * Size+ j]);
pProcVector[k++] = pVector[i];
}
else
{
for (j = 0; j < Size; j++)
fscanf(f_input, "%lg", &pResult[j]);
MPI_Send(pResult, Size, MPI_DOUBLE, destRank, i / procQuantity, MPI_COMM_WORLD);
MPI_Send(&pVector[i], 1, MPI_DOUBLE, destRank, Size+1, MPI_COMM_WORLD);
}
}
fclose(f_input);
}
else
{
for (i = 0; i < pProcNum[procRank]; i++)
{
MPI_Recv(&pProcRows[i*Size], Size, MPI_DOUBLE, 0, i, MPI_COMM_WORLD, &Status);
MPI_Recv(&pProcVector[i],1, MPI_DOUBLE, 0, Size+1, MPI_COMM_WORLD, &Status);
}
}
printf("%d %d\n", procRank, pProcNum[procRank]);
}
void ColumnElimination(double* pProcRows, double* pProcVector, double* pRow, int Size, int RowNum, int Iter, int currentRowIndex)
{
double multiplier;
for (int i=currentRowIndex; i<RowNum; i++)
{
multiplier = pProcRows[i*Size+Iter] / pRow[Iter];
for (int j=Iter; j<Size; j++)
pProcRows[i*Size + j] -= pRow[j]*multiplier;
pProcVector[i] -= pRow[Size]*multiplier;
}
}
void GaussianElimination (double* pProcRows, double* pProcVector, int Size, int RowNum)
{
double* castedRow = new double [Size+1];
int pRowIndex, currentRank;
pRowIndex = 0;
currentRank = 0;
for (int i = 0; i < Size; i++)
{
if (procRank == currentRank)
{
for (int j=0; j<Size; j++)
{
castedRow[j] = pProcRows[pRowIndex*Size + j];
}
castedRow[Size] = pProcVector[pRowIndex];
pRowIndex++;
}
MPI_Bcast(castedRow, Size+1, MPI_DOUBLE, currentRank, MPI_COMM_WORLD);
ColumnElimination(pProcRows, pProcVector, castedRow, Size, RowNum, i, pRowIndex);
currentRank++;
if (currentRank == procQuantity)
currentRank = 0;
}
}
void BackSubstitution (double* pProcRows, double* pProcVector, double* pProcResult, int Size, int RowNum)
{
double IterResult;
double val;
int pRowIndex, currentRank;
pRowIndex = RowNum - 1;
currentRank = (Size - 1) % procQuantity;
for (int i = Size-1; i >= 0; i--)
{
if (procRank == currentRank)
{
IterResult = pProcVector[pRowIndex]/pProcRows[pRowIndex*Size+i];
pProcResult[pRowIndex] = IterResult;
pRowIndex--;
}
MPI_Bcast(&IterResult, 1, MPI_DOUBLE, currentRank, MPI_COMM_WORLD);
for (int j = 0; j < pRowIndex + 1; j++)
{
val = pProcRows[j*Size + i] * IterResult;
pProcVector[j] = pProcVector[j] - val;
}
currentRank--;
if (currentRank < 0)
currentRank = procQuantity - 1;
}
}
void ProcessTermination (double* pVector, double* pResult, double* pProcRows, double* pProcVector, double* pProcResult)
{
if (procRank == 0)
{
delete [] pVector;
delete [] pResult;
}
free(pProcRows);
delete [] pProcVector;
delete [] pProcResult;
delete [] pProcInd;
delete [] pProcNum;
}
int main(int argc, char* argv[])
{
double* pVector;
double* pResult;
int Size;
double *pProcRows;
double *pProcVector;
double *pProcResult;
int RowNum;
double start, finish, duration;
MPI_Init ( &argc, &argv );
MPI_Comm_rank ( MPI_COMM_WORLD, &procRank );
MPI_Comm_size ( MPI_COMM_WORLD, &procQuantity );
ProcessInitialization(pVector, pResult, pProcRows, pProcVector, pProcResult, Size, RowNum);
start = MPI_Wtime();
//GaussianElimination(pProcRows, pProcVector, Size, RowNum);
//BackSubstitution (pProcRows, pProcVector, pProcResult, Size, RowNum);
//MPI_Gatherv(pProcResult, pProcNum[procRank], MPI_DOUBLE, pResult, pProcNum, pProcInd, MPI_DOUBLE, 0, MPI_COMM_WORLD);
finish = MPI_Wtime();
duration = finish-start;
//if (procRank == 0)
//{
// f_res = fopen("C:\\Users\\main\\Documents\\Visual Studio 2010\\Projects\\lab1\\Debug\\Solutions\\result.txt", "w");
// int k = 0;
// int j =0;
// for (int i=0; i<Size; i++)
// {
// fprintf(f_res,"%7.4f ", pResult[k]);
// k += RowNum;
// if (k >= Size)
// {
// j++;
// k = j;
// }
// }
// fclose(f_res);
// f_time = fopen("C:\\Users\\main\\Documents\\Visual Studio 2010\\Projects\\lab1\\Debug\\Solutions\\Time.txt", "a+");
// fprintf(f_time, " Number of processors: %d\n Size of Matrix: %d\n Time of execution: %f\n\n", procQuantity, Size, duration);
// fclose(f_time);
//}
ProcessTermination(pVector, pResult, pProcRows, pProcVector, pProcResult);
MPI_Finalize();
return 0;
}