Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CompMath2/my-hostfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
localhost slots=16
2 changes: 1 addition & 1 deletion CompMath2/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ for test_dir in $tests_dir/*; do
printf "\n[TEST $test]\n"
echo "mpiexec -np $proc $exe $test_dir/input.txt $build/$test.txt"
START=$(date +%s%N)
mpiexec -np $proc $exe $test_dir/input.txt $build/$test.txt
mpiexec -np $proc --hostfile my-hostfile $exe $test_dir/input.txt $build/$test.txt
END=$(date +%s%N)
DIFF=$((($END - $START)/1000000))
if [ ! $? -eq 0 ]; then
Expand Down
161 changes: 125 additions & 36 deletions CompMath2/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,148 @@
#include <unistd.h>
#include <cmath>

/**
* Функция, которая высчитывает границы
*/
void calcIterations( int* leftBorder, int* rightBorder, int rank, double sizeOfBlock, int length)
{
*leftBorder = rank * sizeOfBlock + 1;

/* Если справа хватает элементов, то проблем нет, просто выделяем их */
if ( (length - *leftBorder) >= sizeOfBlock)
{
*rightBorder = *leftBorder + sizeOfBlock - 1;
} else
/* Если справа не хватает элементов (например последний блок), то присваиваем правую границу */
{
*rightBorder = length - 1;
}
}

/**
* Функция для отладки. Печатаем фрейм
*/
void printFrame(double* frame, uint32_t ySize, uint32_t xSize)
{
for (uint32_t y = 0; y < ySize; y++)
{
for (uint32_t x = 0; x < xSize; x++)
{
printf("%f ", frame[y*xSize + x]);
}
printf("\n");
}
printf("\n");
}

void calc(double* frame, uint32_t ySize, uint32_t xSize, double delta, int rank, int size)
{
if (rank == 0 && size > 0)
{
double diff = 0;
double* tmpFrame = new double[ySize * xSize];
double* tmpFrame = new double[ySize * xSize]();

/* Приходится создать ещё один, так как
* MPI_Reduce не поддерживает send = recv
*/
double* recvFrame = new double[ySize * xSize]();

double diff = 100;
double diff_part = 0;

if (rank != 0)
{
frame = new double[ySize * xSize]();
}

MPI_Bcast(frame, xSize*ySize, MPI_DOUBLE, 0, MPI_COMM_WORLD);

// Prepare tmpFrame
for (uint32_t y = 0; y < ySize; y++)
{
tmpFrame[y*xSize] = frame[y*xSize];
tmpFrame[y*xSize + xSize - 1] = frame[y*xSize + xSize - 1];
tmpFrame[y*xSize] = frame[y*xSize];
tmpFrame[y*xSize + xSize - 1] = frame[y*xSize + xSize - 1];
}
for (uint32_t x = 1; x < xSize - 1; x++)
{
tmpFrame[x] = frame[x];
tmpFrame[(ySize - 1)*xSize + x] = frame[(ySize - 1)*xSize + x];
}
// Calculate first iteration
for (uint32_t y = 1; y < ySize - 1; y++)
{
for (uint32_t x = 1; x < xSize - 1; x++)
{
tmpFrame[y*xSize + x] = (frame[(y + 1)*xSize + x] + frame[(y - 1)*xSize + x] +\
frame[y*xSize + x + 1] + frame[y*xSize + x - 1])/4.0;
diff += std::abs(tmpFrame[y*xSize + x] - frame[y*xSize + x]);
}
tmpFrame[x] = frame[x];
tmpFrame[(ySize - 1)*xSize + x] = frame[(ySize - 1)*xSize + x];
}

/* Для каждого процесса расчитаем его "область действия" */
/* Найдем границы для каждого процесса */
int xLeftBorder = 0,
xRightBorder = 0;

int xSizeOfBlock = (int)ceil( (float)(xSize - 2) / size);

calcIterations( &xLeftBorder, &xRightBorder, rank, xSizeOfBlock, xSize - 1);

double* currFrame = tmpFrame;
double* nextFrame = frame;

uint32_t iteration = 1;

// Calculate frames
while (diff > delta)
{
diff = 0;
for (uint32_t y = 1; y < ySize - 1; y++)
{
for (uint32_t x = 1; x < xSize - 1; x++)
{
nextFrame[y*xSize + x] = (currFrame[(y + 1)*xSize + x] + currFrame[(y - 1)*xSize + x] +\
diff = 0;
diff_part = 0;

std::fill(nextFrame, nextFrame + ySize*xSize, 0);
std::fill(recvFrame, recvFrame + ySize*xSize, 0);

for (uint32_t y = 0; y < ySize; y++)
{
nextFrame[y*xSize] = currFrame[y*xSize];
nextFrame[y*xSize + xSize - 1] = currFrame[y*xSize + xSize - 1];
}

for (uint32_t x = 1; x < xSize - 1; x++)
{
nextFrame[x] = currFrame[x];
nextFrame[(ySize - 1)*xSize + x] = currFrame[(ySize - 1)*xSize + x];
}

for (uint32_t y = 1; y < ySize - 1; y++)
{
for (int x = xLeftBorder; x <= xRightBorder; x++)
{
nextFrame[y*xSize + x] = (currFrame[(y + 1)*xSize + x] + currFrame[(y - 1)*xSize + x] +\
currFrame[y*xSize + x + 1] + currFrame[y*xSize + x - 1])/4.0;
diff += std::abs(nextFrame[y*xSize + x] - currFrame[y*xSize + x]);
}
}
std::swap(currFrame, nextFrame);
iteration++;
diff_part += std::abs(nextFrame[y*xSize + x] - currFrame[y*xSize + x]);
}
}

MPI_Allreduce( nextFrame, recvFrame, xSize * ySize, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);
MPI_Allreduce( &diff_part, &diff, 1, MPI_DOUBLE, MPI_SUM, MPI_COMM_WORLD);

for (uint32_t y = 0; y < ySize; y++)
{
recvFrame[y*xSize] = currFrame[y*xSize];
recvFrame[y*xSize + xSize - 1] = currFrame[y*xSize + xSize - 1];
}

for (uint32_t x = 1; x < xSize - 1; x++)
{
recvFrame[x] = currFrame[x];
recvFrame[(ySize - 1)*xSize + x] = currFrame[(ySize - 1)*xSize + x];
}

memcpy(currFrame, recvFrame, xSize*ySize*sizeof(double));
iteration++;
}

// Copy result from tmp
if (iteration % 2 == 1)
if( rank == 0)
{
for (uint32_t i = 0; i < xSize*ySize; i++)
{
frame[i] = tmpFrame[i];
}
memcpy(frame, recvFrame, xSize*ySize*sizeof(double));
}

delete tmpFrame;
}
delete recvFrame;
if (rank != 0)
{
delete frame;
}


}

int main(int argc, char** argv)
Expand Down Expand Up @@ -119,6 +203,11 @@ int main(int argc, char** argv)
}
}

/* Разошлём всем процессам xSize, ySize и zSize*/
MPI_Bcast( &xSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast( &ySize, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast( &delta, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD);

calc(frame, ySize, xSize, delta, rank, size);

if (rank == 0)
Expand Down
1 change: 1 addition & 0 deletions Loop1/my-hostfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
localhost slots=16
2 changes: 1 addition & 1 deletion Loop1/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ for test_dir in $tests_dir/*; do
printf "\n[TEST $test]\n"
echo "mpiexec -np $proc $exe $test_dir/input.txt $build/$test.txt"
START=$(date +%s%N)
mpiexec -np $proc $exe $test_dir/input.txt $build/$test.txt
mpiexec -np $proc --hostfile my-hostfile $exe $test_dir/input.txt $build/$test.txt
END=$(date +%s%N)
DIFF=$((($END - $START)/1000000))
if [ ! $? -eq 0 ]; then
Expand Down
72 changes: 64 additions & 8 deletions Loop1/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,30 +5,82 @@
#include <unistd.h>
#include <cmath>


/**
* Функция, которая высчитывает границы
*/
void calcIterations( int* leftBorder, int* rightBorder, int rank, double sizeOfBlock, int length)
{
*leftBorder = rank * sizeOfBlock;

/* Если справа хватает элементов, то проблем нет, просто выделяем их */
if ( (length - *leftBorder) >= sizeOfBlock)
{
*rightBorder = *leftBorder + sizeOfBlock - 1;
} else
/* Если справа не хватает элементов (например последний блок), то присваиваем правую границу */
{
*rightBorder = length - 1;
}
}

/* Вектор зависимости (0, 0), нам без разницы как разбивать. Разобьем на size блоков по столбцам или строкам */
void calc(double* arr, uint32_t ySize, uint32_t xSize, int rank, int size)
{
if (rank == 0 && size > 0)
{
for (uint32_t y = 0; y < ySize; y++)
if ( rank != 0)
{
for (uint32_t x = 0; x < xSize; x++)
{
arr[y*xSize + x] = sin(0.00001*arr[y*xSize + x]);
}
arr = new double[ySize * xSize];
}
}

double* bufArr = new double[ySize * xSize]();
double* reduceArr = new double[ySize * xSize]();

/* Передадим всем процессам изначальный массив arr */
MPI_Bcast( arr, xSize * ySize, MPI_DOUBLE, 0, MPI_COMM_WORLD);

/* Найдем границы для каждого процесса */
int yLeftBorder = 0,
yRightBorder = 0;

int ySizeOfBlock = (int)ceil( (float)ySize / size);

calcIterations( &yLeftBorder, &yRightBorder, rank, ySizeOfBlock, (int)ySize);

for (int y = yLeftBorder; y <= yRightBorder; y++)
{
for (uint32_t x = 0; x < xSize; x++)
{
bufArr[y*xSize + x] = sin(0.00001*arr[y*xSize + x]);
}
}

/* В каждой области имеем посчитанное значение, теперь надо их просто сложить в 0 процессе */
MPI_Reduce( bufArr, reduceArr, (int)(xSize * ySize), MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD);

if( rank == 0)
{
memcpy( arr, reduceArr, sizeof(double) * xSize * ySize);
}

delete bufArr;
delete reduceArr;

}

int main(int argc, char** argv)
{

int rank = 0, size = 0, buf = 0;
uint32_t ySize = 0, xSize = 0;
double* arr = 0;

MPI_Init(&argc, &argv);

MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);



if (rank == 0)
{
// Check arguments
Expand Down Expand Up @@ -72,6 +124,10 @@ int main(int argc, char** argv)
}
}

/* Разошлём всем процессам xSize и ySize */
MPI_Bcast( &xSize, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast( &ySize, 1, MPI_INT, 0, MPI_COMM_WORLD);

calc(arr, ySize, xSize, rank, size);

if (rank == 0)
Expand Down
1 change: 1 addition & 0 deletions Loop2/my-hostfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
localhost slots=16
2 changes: 1 addition & 1 deletion Loop2/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ for test_dir in $tests_dir/*; do
printf "\n[TEST $test]\n"
echo "mpiexec -np $proc $exe $test_dir/input.txt $build/$test.txt"
START=$(date +%s%N)
mpiexec -np $proc $exe $test_dir/input.txt $build/$test.txt
mpiexec -np $proc --hostfile my-hostfile $exe $test_dir/input.txt $build/$test.txt
END=$(date +%s%N)
DIFF=$((($END - $START)/1000000))
if [ ! $? -eq 0 ]; then
Expand Down
Loading