zadanie2 working in parallel

master
Peter Babič 9 years ago
parent 4d4d9d935e
commit 87ad365293
  1. 57
      common.c
  2. 8
      common.h
  3. BIN
      zadanie1
  4. 58
      zadanie1.c
  5. BIN
      zadanie2
  6. 179
      zadanie2.c
  7. 13
      zadanie2.in

@ -1,26 +1,26 @@
#include "common.h"
void *my_malloc(size_t size) {
void *p = malloc(size);
if (p == NULL) {
void *ptr = malloc(size);
if (ptr == NULL) {
printf("Memory allocation unsuccessful.\n");
exit(EXIT_FAILURE);
}
return p;
return ptr;
}
void *my_calloc(size_t nitems, size_t size) {
void *p = calloc(nitems, size);
if (p == NULL) {
void *ptr = calloc(nitems, size);
if (ptr == NULL) {
printf("Memory allocation with initialisation unsuccessful.\n");
exit(EXIT_FAILURE);
}
return p;
return ptr;
}
void *my_realloc(void *p, size_t size) {
void *temp = realloc(p, size);
void *my_realloc(void *ptr, size_t size) {
void *temp = realloc(ptr, size);
if (temp == NULL) {
printf("Insufficient memory; can't add more items.\n");
exit(EXIT_FAILURE);
@ -38,3 +38,44 @@ FILE *my_fopen(const char *filename, const char *mode) {
return file;
}
void *buffer_grow(void *ptr, int sizeBufferUsed, int *sizeBufferTotal) {
// Grow the buffer exponentially when needed
if (sizeBufferUsed == *sizeBufferTotal) {
*sizeBufferTotal *= GROWTH_FACTOR;
ptr = my_realloc(ptr, *sizeBufferTotal * sizeof(int));
}
return ptr;
}
bool checkParallelWorth(int numProcesses, int sizeBufferUsed) {
if (numProcesses > sizeBufferUsed / 2) {
//printf("*********************************************************************************\n");
printf("The number of processes if greater than number of parallel computations required!\n");
//printf("*********************************************************************************\n\n");
exit(EXIT_FAILURE);
}
return true;
}
void spread_evenly(int numProcesses, int sizeBufferUsed, int **arrBlockIndices, int **arrBlockSizes) {
int numBlockIndex = 0;
int numRemainder = sizeBufferUsed % numProcesses;
*arrBlockIndices = my_malloc(numProcesses * sizeof(int));
*arrBlockSizes = my_malloc(numProcesses * sizeof(int));
for (int i = 0; i < numProcesses; i++) {
(*arrBlockSizes)[i] = sizeBufferUsed / numProcesses;
if (numRemainder > 0) {
(*arrBlockSizes)[i]++;
numRemainder--;
}
(*arrBlockIndices)[i] = numBlockIndex;
numBlockIndex += *arrBlockSizes[i];
}
//for (int i = 0; i < numProcesses; i++) {
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrBlockSizes[i], i, arrBlockIndices[i]);
//}
}

@ -4,10 +4,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <stdbool.h>
#include <mpi.h>
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
#define INIT_BUFFER_SIZE 20
#define INIT_BUFFER_SIZE 16
// Optimal exponential buffer growth factor, 2 is sometimes used to
#define GROWTH_FACTOR 1.5
// Maximum length of the file that will be read (not applicable to z1)
@ -15,7 +16,10 @@
void *my_malloc(size_t size);
void *my_calloc(size_t nitems, size_t size);
void *my_realloc(void *p, size_t size);
void *my_realloc(void *ptr, size_t size);
FILE *my_fopen(const char *filename, const char *mode);
void *buffer_grow(void *ptr, int sizeBufferUsed, int *sizeBufferTotal);
bool checkParallelWorth(int numProcesses, int sizeBufferUsed);
void spread_evenly(int numProcesses, int sizeBufferUsed, int **arrBlockIndices, int **arrBlockSizes);
#endif

Binary file not shown.

@ -6,59 +6,43 @@ int maximum(int n, int *arrNumbers);
int main(int argc, char *argv[]) {
int numProcesses, numRank;
//MPI_Status mpiStatus;
int *arrNumbers;
int *arrBlockIndices;
int *arrBlockSizes;
int sizeBufferTotal;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
MPI_Comm_rank(MPI_COMM_WORLD, &numRank);
int *arrNumbers, *arrBlockIndices, *arrBlockSizes;
int sizeBufferTotal, sizeBufferUsed = 0;
if (numRank == 0) {
int numNumber, numCount = 0;
// To avoid aggresive buffer growth at the beggining of the sequence
sizeBufferTotal = INIT_BUFFER_SIZE;
// Allocate enough memory for initial buffer
arrNumbers = my_malloc(sizeBufferTotal * sizeof(int));
//int num[10];
// Open the file with input data
FILE *ptrFile = my_fopen(INPUTFILE, "r");
// Read lines of numbers until an EOF or a character is read
int numNumber;
while (fscanf(ptrFile, "%d", &numNumber) == 1) {
// Incorporate space for storing results received from slaves at the end of array
// TODO: remove this incorporation
int sizeBufferUsed = numCount + numProcesses - 1;
if (sizeBufferTotal == sizeBufferUsed) {
// Grow buffer exponentially
sizeBufferTotal *= GROWTH_FACTOR;
arrNumbers = my_realloc(arrNumbers, sizeBufferTotal * sizeof(int));
}
arrNumbers[numCount++] = numNumber;
// Grow buffer when needed
arrNumbers = buffer_grow(arrNumbers, sizeBufferUsed, &sizeBufferTotal);
// Store the number in memory
arrNumbers[sizeBufferUsed++] = numNumber;
}
if (numProcesses > numCount / 2) {
printf("*********************************************************************************\n");
printf("The number of processes if greater than number of parallel computations required!\n");
printf("*********************************************************************************\n\n");
exit(EXIT_FAILURE);
}
//printf("count: %d, buffer: %d\n", numCount, sizeBufferTotal);
checkParallelWorth(numProcesses, sizeBufferUsed);
int numBlockIndex = 0;
int numRemainder = numCount % numProcesses;
int numRemainder = sizeBufferUsed % numProcesses;
arrBlockIndices = my_malloc(numProcesses * sizeof(int));
arrBlockSizes = my_malloc(numProcesses * sizeof(int));
for (int i = 0; i < numProcesses; i++) {
arrBlockSizes[i] = numCount / numProcesses;
arrBlockSizes[i] = sizeBufferUsed / numProcesses;
if (numRemainder > 0) {
arrBlockSizes[i]++;
numRemainder--;
@ -66,28 +50,30 @@ int main(int argc, char *argv[]) {
arrBlockIndices[i] = numBlockIndex;
numBlockIndex += arrBlockSizes[i];
// Send block size to every process
MPI_Send(&arrBlockSizes[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
}
//for (int i = 0; i < numProcesses; i++) {
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrBlockSizes[i], i, arrBlockIndices[i]);
//}
for (int i = 0; i < numProcesses; i++) {
MPI_Send(&arrBlockSizes[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
}
//for (int i = 0; i < numProcesses; i++) {
//MPI_Send(&arrBlockSizes[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
//}
}
MPI_Bcast(&sizeBufferTotal, 1, MPI_INT, 0, MPI_COMM_WORLD);
int *arrSlice = my_malloc(sizeBufferTotal * sizeof(int));
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice, sizeBufferTotal, MPI_INT, 0, MPI_COMM_WORLD);
int numCount;
MPI_Recv(&numCount, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
//for (int i = 0; i < numCount; i++) {
int numBlockSize;
MPI_Recv(&numBlockSize, 1, MPI_INT, 0, 1, MPI_COMM_WORLD, &status);
//for (int i = 0; i < numBlockSize; i++) {
//printf("rank %d: m[%d] = %d\n", numRank, i, arrSlice[i]);
//}
int numMaximum = maximum(numCount, arrSlice);
int numMaximum = maximum(numBlockSize, arrSlice);
//printf("max in %d is %d\n", numRank, numMaximum);
int *arrMaximums;
if (numRank == 0) {

Binary file not shown.

@ -2,62 +2,65 @@
#define INPUTFILE "zadanie2.in"
// TODO: define custom structure for this probably
#define CODE_SIZE 0
#define CODE_INDEX 1
//#define CODE_COLS 0
//#define CODE_COUNT 1
#define NUM_CODES 2
int transpose_index(int index, int rows, int cols);
int main(int argc, char *argv[]) {
int numProcesses, numRank;
//MPI_Status status;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses);
MPI_Comm_rank(MPI_COMM_WORLD, &numRank);
int sizeBufferUsed = 0, sizeBufferTotal;
int *arrNumbers, *arrBlockSizes, *arrBlockIndices, cols;
int *arrNumbers, *arrBlockSizes, *arrBlockIndices;
int cols = 0, numCount = 0;
if (numRank == 0) {
char *ptrBuffer, strBuffer[MAX_LINE_LENGTH];
FILE *ptrFile = my_fopen(INPUTFILE, "r");
sizeBufferTotal = INIT_BUFFER_SIZE;
// To avoid aggresive buffer growth at the beggining of the sequence
int sizeBufferTotal = INIT_BUFFER_SIZE;
// Allocate enough memory for initial buffer
arrNumbers = my_malloc(sizeBufferTotal * sizeof(int));
// Open the file with input data
FILE *ptrFile = my_fopen(INPUTFILE, "r");
// Read line by line until the end of file
// TODO: remove the MAX_LINE_LENGTH limitation of strBuffer
char *ptrBuffer, strBuffer[MAX_LINE_LENGTH];
while (fgets(strBuffer, sizeof strBuffer, ptrFile) != 0) {
// Grow the buffer when needed
if (sizeBufferUsed == sizeBufferTotal) {
sizeBufferTotal *= GROWTH_FACTOR;
arrNumbers = my_realloc(arrNumbers, sizeBufferTotal * sizeof(int));
}
// Store the pointer
ptrBuffer = strBuffer;
cols = 0;
int numValue;
// Read untill newline
while (*ptrBuffer != '\n') {
// Grow buffer when needed
arrNumbers = buffer_grow(arrNumbers, numCount, &sizeBufferTotal);
// Convert string to base 10
numValue = strtol(ptrBuffer, &ptrBuffer, 10);
// Store the number read in memory
arrNumbers[sizeBufferUsed++] = numValue;
arrNumbers[numCount++] = numValue;
cols++;
}
}
if (numProcesses > sizeBufferUsed / 2) {
printf("*********************************************************************************\n");
printf("The number of processes if greater than number of parallel computations required!\n");
printf("*********************************************************************************\n\n");
exit(EXIT_FAILURE);
}
//printf("count: %d, buffer: %d\n", sizeBufferUsed, sizeBufferTotal);
checkParallelWorth(numProcesses, numCount);
int numBlockIndex = 0;
int numRemainder = sizeBufferUsed % numProcesses;
int numRemainder = numCount % numProcesses;
arrBlockIndices = my_malloc(numProcesses * sizeof(int));
arrBlockSizes = my_malloc(numProcesses * sizeof(int));
for (int i = 0; i < numProcesses; i++) {
arrBlockSizes[i] = sizeBufferUsed / numProcesses;
arrBlockSizes[i] = numCount / numProcesses;
if (numRemainder > 0) {
arrBlockSizes[i]++;
numRemainder--;
@ -65,61 +68,139 @@ int main(int argc, char *argv[]) {
arrBlockIndices[i] = numBlockIndex;
numBlockIndex += arrBlockSizes[i];
int arrTransp[NUM_CODES];
arrTransp[CODE_SIZE] = arrBlockSizes[i];
arrTransp[CODE_INDEX] = arrBlockIndices[i];
// Send every process starting index of 1D represented matrix and number of
// succeding indices to calculate transposition
MPI_Send(arrTransp, NUM_CODES, MPI_INT, i, NUM_CODES, MPI_COMM_WORLD);
}
//for (int i = 0; i < numProcesses; i++) {
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrBlockSizes[i], i, arrBlockIndices[i]);
//}
}
MPI_Bcast(&sizeBufferTotal, 1, MPI_INT, 0, MPI_COMM_WORLD);
printf("total %d in %d\n", sizeBufferTotal, numRank);
//int packet[NUM_CODES];
//MPI_Scatter(arrPackets, NUM_CODES, MPI_INT, packet, NUM_CODES, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&numCount, 1, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Bcast(&cols, 1, MPI_INT, 0, MPI_COMM_WORLD);
//printf("size %2d, index %2d, buffer %2d, rank %d\n", packet[0], packet[1], packet[CODE_COUNT], numRank);
//int *arrSlice = my_malloc(sizeBufferTotal * sizeof(int));
//MPI_Scatterv(arrNumbers, arrPackets, arrPackets, MPI_INT, arrSlice, sizeBufferTotal, MPI_INT, 0, MPI_COMM_WORLD);
int *arrSlice = my_malloc(sizeBufferTotal * sizeof(int));
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice, sizeBufferTotal, MPI_INT, 0, MPI_COMM_WORLD);
/*printf("original matrix: \n");
for (int i = 0; i < sizeBufferUsed; i++) {
printf("%d ", arrNumbers[i]);
if ((i + 1) % cols == 0)
printf("\n");
}
printf("\n");
// We can calculate rows * cols = sizeBufferused
int rows = sizeBufferUsed / cols;
int *arrIndices = my_malloc(sizeBufferUsed * sizeof(int));
for (int i = 0; i < sizeBufferUsed; i++) {
//if (numRank == 0 ) {
//printf("original matrix: \n");
//for (int i = 0; i < numCount; i++) {
//printf("%d ", arrNumbers[i]);
//if ((i + 1) % cols == 0)
//printf("\n");
//}
//printf("\n");
//}
int arrTransp[NUM_CODES];
MPI_Recv(arrTransp, NUM_CODES, MPI_INT, 0, NUM_CODES, MPI_COMM_WORLD, &status);
//for (int i = 0; i < numCount; i++) {
//printf("rank %d: m[%d] = %d\n", numRank, i, arrSlice[i]);
//}
//We can calculate rows * cols = numCount
int rows = numCount / cols;
int *arrIndices = my_malloc(numCount * sizeof(int));
//for (int i = arrTransp[CODE_INDEX]; i < (arrTransp[CODE_SIZE] + arrTransp[CODE_INDEX]); i++) {
for (int i = 0; i < arrTransp[CODE_SIZE]; i++) {
//if (i % rows == 0)
//printf("\n");
// Only the indices are transposed
int index = ((rows * i) / (cols * rows)) + ((rows * i) % (cols * rows));
arrIndices[index] = i;
int index = transpose_index(i + arrTransp[CODE_INDEX], rows, cols);
arrIndices[i] = index;
//printf("%2d[%2d](%d)\n", i, index, numRank);
//arrIndices[index] = i;
//printf("%2d[%2d](%d)\n", index, i, numRank);
}
//printf("\n");
printf("transposed matrix:");
for (int i = 0; i < sizeBufferUsed; i++) {
if (i % rows == 0)
printf("\n");
printf("%d ", arrNumbers[arrIndices[i]]);
}*/
//printf("rank %d, rows %d, cols %d, count %d, index %2d, size %2d\n", numRank, rows, cols, numCount,
//arrTransp[CODE_INDEX], arrTransp[CODE_SIZE]);
int *arrMatrix;
if (numRank == 0)
arrMatrix = my_malloc(numCount * sizeof(int));
MPI_Gatherv(arrIndices, arrTransp[CODE_SIZE], MPI_INT, arrMatrix, arrBlockSizes, arrBlockIndices, MPI_INT, 0, MPI_COMM_WORLD);
if (numRank == 0) {
//for (int i = 0; i < numCount; i++) {
//printf("arrMatrix[%2d] = %2d\n", i, arrMatrix[i]);
//}
printf("transposed matrix:");
for (int i = 0; i < numCount; i++) {
if (i % rows == 0)
printf("\n");
printf("%d ", arrNumbers[arrMatrix[i]]);
}
printf("\n");
}
//printf("\n");
MPI_Finalize();
return 0;
}
int transpose_index(int index, int rows, int cols) {
//return ((rows * index) / (cols * rows)) + ((rows * index) % (colss * rows));
//return (index / cols) + rows * (index % cols);
return (index / rows) + cols * (index % rows);
}
//printf("trasnposed matrix:");
//for (int i = 0; i < sizeBufferUsed; i++) {
//for (int i = 0; i < numCount; i++) {
//if (i % rows == 0)
//printf("\n");
//printf("%d ", arrTrans[i]);
//}
/* for (int i = 0; i < sizeBufferUsed; i++) {*/
/* for (int i = 0; i < numCount; i++) {*/
//if (i % rows == 0)
//printf("\n");
//printf("%2d[%2d]\t", i, arrIndices[i]);
/*}*/
//printf("rows: %zu, cols: %d\n", sizeBufferUsed / cols, cols);
//printf("rows: %zu, cols: %d\n", numCount / cols, cols);
/*
int numBlockIndex = 0;
int numRemainder = numCount % numProcesses;
arrBlockIndices = my_malloc(numProcesses * sizeof(int));
arrBlockSizes = my_malloc(numProcesses * sizeof(int));
int numPackets = numProcesses * NUM_CODES;
arrPackets = my_malloc(numPackets * sizeof(int));
for (int i = 0; i < numPackets; i += NUM_CODES) {
arrBlockSizes[i] = arrPackets[i + CODE_SIZE] = numCount / numProcesses;
if (numRemainder > 0) {
arrPackets[i]++;
numRemainder--;
}
arrBlockIndices[i] = arrPackets[i + CODE_INDEX] = numBlockIndex;
numBlockIndex += arrPackets[i];
arrPackets[i + CODE_COLS] = cols;
arrPackets[i + CODE_COUNT] = numCount;
}*/
//for (int i = 0; i < numPackets; i += 2) {
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrPackets[i], i + 1, arrPackets[i + 1]);
//}
//for (int i = 0; i < numProcesses; i++) {
//printf("size[%d] = %d\tindex[%d] = %d\n", i, arrPackets[i], i, arrPackets[i + 1]);
//}
//for (int i = 0; i < numProcesses; i++) {
//MPI_Send(&arrPackets[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
//}

@ -1,6 +1,7 @@
1 1 1 1
2 2 2 2
3 3 3 3
4 4 4 4
5 5 5 5
6 6 6 6
1 1 1 1 1
2 2 2 2 2
3 3 3 3 3
4 4 4 4 4
5 5 5 5 5
6 6 6 6 6
7 7 7 7 7

Loading…
Cancel
Save