parent
9520b45851
commit
f95dd2452b
@ -1,46 +0,0 @@ |
||||
#include <mpi.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
int main(int argc, char **argv) { |
||||
int size, rank; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &size); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
int *globaldata=NULL; |
||||
int localdata; |
||||
|
||||
if (rank == 0) { |
||||
globaldata = malloc(size * sizeof(int) ); |
||||
for (int i=0; i<size; i++) |
||||
globaldata[i] = 2*i+1; |
||||
|
||||
printf("Processor %d has data: ", rank); |
||||
for (int i=0; i<size; i++) |
||||
printf("%d ", globaldata[i]); |
||||
printf("\n"); |
||||
} |
||||
|
||||
MPI_Scatter(globaldata, 1, MPI_INT, &localdata, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
printf("Processor %d has data %d\n", rank, localdata); |
||||
localdata *= 2; |
||||
printf("Processor %d doubling the data, now has %d\n", rank, localdata); |
||||
|
||||
MPI_Gather(&localdata, 1, MPI_INT, globaldata, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
if (rank == 0) { |
||||
printf("Processor %d has data: ", rank); |
||||
for (int i=0; i<size; i++) |
||||
printf("%d ", globaldata[i]); |
||||
printf("\n"); |
||||
} |
||||
|
||||
if (rank == 0) |
||||
free(globaldata); |
||||
|
||||
MPI_Finalize(); |
||||
return 0; |
||||
} |
@ -1,69 +0,0 @@ |
||||
#include <mpi.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
//#include <math.h>
|
||||
|
||||
#define SIZE 4 |
||||
|
||||
int main(int argc, char *argv[]) |
||||
{ |
||||
int rank, size; // for storing this process' rank, and the number of processes
|
||||
int *sendcounts; // array describing how many elements to send to each process
|
||||
int *displs; // array describing the displacements where each segment begins
|
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &size); |
||||
|
||||
int rem = (SIZE*SIZE)%size; // elements remaining after division among processes
|
||||
int sum = 0; // Sum of counts. Used to calculate displacements
|
||||
char rec_buf[100]; // buffer where the received data should be stored
|
||||
|
||||
// the data to be distributed
|
||||
char data[SIZE][SIZE] = { |
||||
{'a', 'b', 'c', 'd'}, |
||||
{'e', 'f', 'g', 'h'}, |
||||
{'i', 'j', 'k', 'l'}, |
||||
{'m', 'n', 'o', 'p'} |
||||
//{'q', 'r', 's'}
|
||||
}; |
||||
|
||||
sendcounts = malloc(sizeof(int)*size); |
||||
displs = malloc(sizeof(int)*size); |
||||
|
||||
// calculate send counts and displacements
|
||||
for (int i = 0; i < size; i++) { |
||||
sendcounts[i] = (SIZE*SIZE)/size; |
||||
if (rem > 0) { |
||||
sendcounts[i]++; |
||||
rem--; |
||||
} |
||||
|
||||
displs[i] = sum; |
||||
sum += sendcounts[i]; |
||||
} |
||||
|
||||
// print calculated send counts and displacements for each process
|
||||
if (0 == rank) { |
||||
for (int i = 0; i < size; i++) { |
||||
printf("sendcounts[%d] = %d\tdispls[%d] = %d\n", i, sendcounts[i], i, displs[i]); |
||||
} |
||||
} |
||||
|
||||
// divide the data among processes as described by sendcounts and displs
|
||||
MPI_Scatterv(&data, sendcounts, displs, MPI_CHAR, &rec_buf, 100, MPI_CHAR, 0, MPI_COMM_WORLD); |
||||
|
||||
// print what each process received
|
||||
printf("%d: ", rank); |
||||
for (int i = 0; i < sendcounts[rank]; i++) { |
||||
printf("%c\t", rec_buf[i]); |
||||
} |
||||
printf("\n"); |
||||
|
||||
MPI_Finalize(); |
||||
|
||||
free(sendcounts); |
||||
free(displs); |
||||
|
||||
return 0; |
||||
} |
@ -1,28 +0,0 @@ |
||||
#include <mpi.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
int main(int argc, char** argv) { |
||||
int rank; |
||||
int *buf;
|
||||
const int root=0; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
if(rank == root) { |
||||
buf = (int *)malloc(2*sizeof(int)); |
||||
buf[0] = 0; |
||||
buf[1] = 1; |
||||
} |
||||
|
||||
//printf("[%d]: Before Bcast, buf is %d\n", rank, buf);
|
||||
|
||||
/* everyone calls bcast, data is taken from root and ends up in everyone's buf */ |
||||
MPI_Bcast(buf, 2, MPI_INT, root, MPI_COMM_WORLD); |
||||
|
||||
printf("[%d]: %d %d\n", rank, buf[0], buf[1]); |
||||
|
||||
MPI_Finalize(); |
||||
return 0; |
||||
} |
@ -1,18 +1,21 @@ |
||||
#ifndef COMMON_H |
||||
#define COMMON_H |
||||
|
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <limits.h> |
||||
#include <mpi.h> |
||||
|
||||
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
|
||||
#define INIT_BUFFER_SIZE 8 |
||||
#define INIT_BUFFER_SIZE 20 |
||||
// Optimal exponential buffer growth factor, 2 is sometimes used to
|
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
// Macro for counting the lenght of an array
|
||||
//#define COUNT(x) ((int) (sizeof(x) / sizeof(x[0])))
|
||||
|
||||
// Maximum length of the file that will be read (not applicable to z1)
|
||||
#define MAX_LINE_LENGTH 8192 |
||||
|
||||
void *my_malloc(size_t size); |
||||
void *my_calloc(size_t nitems, size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
#endif |
@ -1,34 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <mpi.h> |
||||
|
||||
int main(int argc, char** argv) { |
||||
int n, i, *ptr, rank;
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
n = 4; |
||||
ptr = (int*)malloc(n * sizeof(int)); //memory allocated using malloc
|
||||
|
||||
if(ptr == NULL) { |
||||
printf("Error! memory not allocated.");
|
||||
exit(0);
|
||||
} |
||||
|
||||
if (rank == 0) { |
||||
for(i = 0; i < n; i++) { |
||||
ptr[i] = i * 10;
|
||||
} |
||||
} |
||||
|
||||
|
||||
MPI_Bcast(ptr, n, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
for(i = 0; i < n; i++) { |
||||
printf("%d: i[%d] = %d\n", rank, i, ptr[i]); |
||||
} |
||||
|
||||
free(ptr);
|
||||
MPI_Finalize(); |
||||
return 0;
|
||||
} |
@ -1,51 +0,0 @@ |
||||
#include <mpi.h> |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
int main(int argc, char** argv) { |
||||
int rank; |
||||
int rows = 4, columns = 4; |
||||
int **array;
|
||||
const int root=0; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
if (rank == root) { |
||||
array = (int**) malloc(rows * sizeof(int*)); |
||||
if (array == NULL) exit (-1); |
||||
|
||||
array[0] = (int*) malloc (rows * columns * sizeof(int)); |
||||
if (array[0] == NULL) exit (-1); |
||||
|
||||
for (int i = 1; i < rows; i++) |
||||
array[i] = array[0] + i * columns; |
||||
|
||||
//array[0] = 0;
|
||||
//array[1] = 1;
|
||||
} |
||||
|
||||
//printf("[%d]: Before Bcast, array is %d\n", rank, array);
|
||||
|
||||
/* everyone calls bcast, data is taken from root and ends up in everyone's array */ |
||||
MPI_Bcast(array[0], rows * columns, MPI_INT, root, MPI_COMM_WORLD); |
||||
//MPI_Bcast(array, 2, MPI_INT, root, MPI_COMM_WORLD);
|
||||
|
||||
//printf("[%d]: %d %d\n", rank, array[0], array[1]);
|
||||
|
||||
MPI_Finalize(); |
||||
return 0; |
||||
|
||||
|
||||
//int **array;
|
||||
//array = (int**) malloc (rows * sizeof(int*));
|
||||
//if (array == NULL) exit (-1);
|
||||
|
||||
//array[0] = (int*) malloc (rows * columns * sizeof(int));
|
||||
//if (array[0] == NULL) exit (-1);
|
||||
|
||||
//for (i=1; i<rows; i++)
|
||||
//array[i] = array[0] + i * columns;
|
||||
|
||||
|
||||
} |
@ -1,84 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <mpi.h> |
||||
|
||||
#define INPUTFILE "sample1_e.in" |
||||
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
|
||||
#define INIT_COUNT 8 |
||||
// Optimal exponential buffer growth factor, 2 is sometimes used to
|
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
void *my_malloc(size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
int main(int argc, char *argv[]){ |
||||
|
||||
int i = 0, rank, number, *numbers, count = 0, max = INIT_COUNT; |
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
if (rank == 0) { |
||||
count = 0; |
||||
// Allocate enough memory for INIT_COUNT numbers
|
||||
numbers = my_malloc(max * sizeof(int)); |
||||
FILE *file = my_fopen(INPUTFILE, "r"); |
||||
|
||||
// Read lines of numbers until an EOF or a character is read
|
||||
while (fscanf(file, "%d", &number) == 1) { |
||||
// Buffer space check
|
||||
if (max == count) { |
||||
// Grow buffer exponentially
|
||||
max *= GROWTH_FACTOR; |
||||
numbers = my_realloc(numbers, max * sizeof(int)); |
||||
}
|
||||
|
||||
// Store the read number to the array in memory
|
||||
numbers[count++] = number; |
||||
} |
||||
} |
||||
|
||||
|
||||
MPI_Bcast(&count, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
MPI_Bcast(numbers, count, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
//printf("count: %d, max: %d\n", count, max);
|
||||
for (i = 0; i < count; i++) { |
||||
printf("%d ", numbers[i]); |
||||
} |
||||
printf("\n"); |
||||
|
||||
MPI_Finalize(); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
void *my_malloc(size_t size) { |
||||
void *p = malloc(size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
|
||||
void *my_realloc(void *p, size_t size) { |
||||
void *temp = realloc(p, size); |
||||
if (temp == NULL) { |
||||
printf("Insufficient memory; can't add more items.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return temp; |
||||
} |
||||
|
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
@ -1,71 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
#define INPUTFILE "sample1_e.in" |
||||
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
|
||||
#define INIT_COUNT 8 |
||||
// Optimal exponential buffer growth factor, 2 is sometimes used to
|
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
void *my_malloc(size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
int main(int argc, char *argv[]){ |
||||
|
||||
int number, count = 0, max = INIT_COUNT; |
||||
// Allocate enough memory for INIT_COUNT numbers
|
||||
int *numbers = my_malloc(max * sizeof(int)); |
||||
FILE *file = my_fopen(INPUTFILE, "r"); |
||||
|
||||
// Read lines of numbers until an EOF or a character is read
|
||||
while (fscanf(file, "%d", &number) == 1) { |
||||
// Buffer space check
|
||||
if (max == count) { |
||||
// Grow buffer exponentially
|
||||
max *= GROWTH_FACTOR; |
||||
numbers = my_realloc(numbers, max * sizeof(int)); |
||||
}
|
||||
|
||||
// Store the read number to the array in memory
|
||||
numbers[count++] = number; |
||||
} |
||||
|
||||
//printf("count: %d, max: %d\n", count, max);
|
||||
int i; |
||||
for (i = 0; i < count; i++) { |
||||
printf("%d ", numbers[i]); |
||||
} |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
void *my_malloc(size_t size) { |
||||
void *p = malloc(size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
|
||||
void *my_realloc(void *p, size_t size) { |
||||
void *temp = realloc(p, size); |
||||
if (temp == NULL) { |
||||
printf("Insufficient memory; can't add more items.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return temp; |
||||
} |
||||
|
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
@ -1,79 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <mpi.h> |
||||
|
||||
#define BUFSIZE 10 |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
int size, rank; |
||||
int slave; |
||||
int buf[BUFSIZE]; |
||||
int n, value; |
||||
float rval; |
||||
MPI_Status status; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &size); |
||||
if (size == 3) { |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
if (rank == 0) { |
||||
buf[0] = 5; |
||||
buf[1] = 1; |
||||
buf[2] = 8; |
||||
buf[3] = 7; |
||||
buf[4] = 6; |
||||
buf[5] = 5; |
||||
buf[6] = 4; |
||||
buf[7] = 2; |
||||
buf[8] = 3; |
||||
buf[9] = 1; |
||||
printf("\n Sending the values {5,1,8,7,6,5,4,2,3,1}"); |
||||
printf("\n -----------------------------"); |
||||
for (slave = 1; slave < size; slave++) { |
||||
printf("\n from master %d to slave %d", rank, slave); |
||||
MPI_Send(buf, 10, MPI_INT, slave, 1, MPI_COMM_WORLD); |
||||
} |
||||
printf("\n\n Receiving the results from slaves"); |
||||
printf("\n ---------------------------------"); |
||||
MPI_Recv(&value, 1, MPI_INT, 1, 11, MPI_COMM_WORLD, &status); |
||||
printf("\n Minimum %4d from slave 1", value); |
||||
MPI_Recv(&value, 1, MPI_INT, 2, 21, MPI_COMM_WORLD, &status); |
||||
printf("\n Sum\t %4d from slave 2", value); |
||||
MPI_Recv(&value, 1, MPI_INT, 1, 12, MPI_COMM_WORLD, &status); |
||||
printf("\n Maximum %4d from slave 1", value); |
||||
MPI_Recv(&rval, 1, MPI_FLOAT, 2, 22, MPI_COMM_WORLD, &status); |
||||
printf("\n Average %4.2f from slave 2\n", rval); |
||||
}
|
||||
else { |
||||
if (rank == 1) { |
||||
MPI_Recv(buf, 10, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
value = 100; |
||||
for (n = 0; n < BUFSIZE; n++) { |
||||
if (value > buf[n]) { |
||||
value = buf[n]; |
||||
} |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 11, MPI_COMM_WORLD); |
||||
value = 0; |
||||
for (n = 0; n < BUFSIZE; n++) { |
||||
if (value < buf[n]) { |
||||
value = buf[n]; |
||||
} |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 12, MPI_COMM_WORLD); |
||||
}
|
||||
else { |
||||
MPI_Recv(buf, 10, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
value = 0; |
||||
for (n = 0; n < BUFSIZE; n++) { |
||||
value = value + buf[n]; |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 21, MPI_COMM_WORLD); |
||||
rval = (float) value / BUFSIZE; |
||||
MPI_Send(&rval, 1, MPI_FLOAT, 0, 22, MPI_COMM_WORLD); |
||||
} |
||||
} |
||||
} |
||||
MPI_Finalize(); |
||||
return (0); |
||||
} |
@ -1,111 +0,0 @@ |
||||
#include "library.h" |
||||
|
||||
#define INPUTFILE "sample1_e.in" |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
int size, rank, slave, i, n, value, count = 0; |
||||
float fvalue; |
||||
|
||||
MPI_Status status; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &size); |
||||
|
||||
if (size == 4) { |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
|
||||
if (rank == 0) { |
||||
|
||||
int number, max = INIT_COUNT; |
||||
// Allocate enough memory for INIT_COUNT numbers
|
||||
int *numbers = my_malloc(max * sizeof(int *)); |
||||
//int num[10];
|
||||
FILE *file = my_fopen(INPUTFILE, "r"); |
||||
|
||||
// Read lines of numbers until an EOF or a character is read
|
||||
while (fscanf(file, "%d", &number) == 1) { |
||||
// Buffer space check
|
||||
if (max == count) { |
||||
// Grow buffer exponentially
|
||||
max *= GROWTH_FACTOR; |
||||
numbers = my_realloc(numbers, max * sizeof(int *)); |
||||
}
|
||||
|
||||
// Store the read number to the array in memory
|
||||
numbers[count++] = number; |
||||
} |
||||
|
||||
printf(" Sending numbers: "); |
||||
for (i = 0; i < count; i++) |
||||
printf("%d ", numbers[i]); |
||||
|
||||
|
||||
printf("\n -----------------------------"); |
||||
for (slave = 1; slave < size; slave++) { |
||||
printf("\n from master %d to slave %d", rank, slave); |
||||
MPI_Send(numbers, count, MPI_INT, slave, 1, MPI_COMM_WORLD); |
||||
} |
||||
printf("\n\n Receiving the results from slaves"); |
||||
printf("\n ---------------------------------"); |
||||
MPI_Recv(&value, 1, MPI_INT, 1, 11, MPI_COMM_WORLD, &status); |
||||
printf("\n Minimum %4d from slave 1", value); |
||||
MPI_Recv(&value, 1, MPI_INT, 2, 21, MPI_COMM_WORLD, &status); |
||||
printf("\n Sum\t %4d from slave 2", value); |
||||
MPI_Recv(&value, 1, MPI_INT, 1, 12, MPI_COMM_WORLD, &status); |
||||
printf("\n Maximum %4d from slave 1", value); |
||||
MPI_Recv(&fvalue, 1, MPI_FLOAT, 2, 22, MPI_COMM_WORLD, &status); |
||||
printf("\n Average %4.2f from slave 2", fvalue); |
||||
MPI_Recv(&fvalue, 1, MPI_FLOAT, 3, 31, MPI_COMM_WORLD, &status); |
||||
printf("\n H. mean %4.2f from slave 3\n", fvalue);
|
||||
}
|
||||
else { |
||||
MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &status); |
||||
MPI_Get_count(&status, MPI_INT, &n); |
||||
|
||||
is_mpi_defined(n); |
||||
int numbers[n]; |
||||
count = COUNT(numbers);
|
||||
|
||||
if (rank == 1) { |
||||
MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
//MPI_Recv(numbers, n, MPI_INT, status.MPI_SOURCE, status.MPI_TAG, MPI_COMM_WORLD, &status);
|
||||
value = INT_MAX; |
||||
for (i = 0; i < count; i++) { |
||||
if (value > numbers[i]) { |
||||
value = numbers[i]; |
||||
} |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 11, MPI_COMM_WORLD); |
||||
value = 0; |
||||
for (i = 0; i < count; i++) { |
||||
if (value < numbers[i]) { |
||||
value = numbers[i]; |
||||
} |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 12, MPI_COMM_WORLD); |
||||
}
|
||||
else if (rank == 2) { |
||||
MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
value = 0; |
||||
for (i = 0; i < count; i++) { |
||||
value = value + numbers[i]; |
||||
} |
||||
MPI_Send(&value, 1, MPI_INT, 0, 21, MPI_COMM_WORLD); |
||||
fvalue = (float) value / count; |
||||
MPI_Send(&fvalue, 1, MPI_FLOAT, 0, 22, MPI_COMM_WORLD); |
||||
} |
||||
else { |
||||
MPI_Recv(numbers, n, MPI_INT, 0, 1, MPI_COMM_WORLD, &status); |
||||
fvalue = 0.0; |
||||
for (i = 0; i < count; i++) { |
||||
fvalue += 1.0 / numbers[i]; |
||||
} |
||||
fvalue = (float) count / fvalue; |
||||
MPI_Send(&fvalue, 1, MPI_FLOAT, 0, 31, MPI_COMM_WORLD);
|
||||
} |
||||
} |
||||
} |
||||
MPI_Finalize(); |
||||
return (0); |
||||
} |
||||
|
@ -1,10 +0,0 @@ |
||||
5 |
||||
1 |
||||
8 |
||||
7 |
||||
6 |
||||
5 |
||||
4 |
||||
3 |
||||
2 |
||||
1 |
@ -1,28 +0,0 @@ |
||||
#include <mpi.h> |
||||
#include <stdio.h> |
||||
|
||||
int main(int argc, char **argv) { |
||||
int rank, size, root_process; |
||||
|
||||
MPI_Status status; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
|
||||
MPI_Comm_rank(MPI_COMM_WORLD, &rank); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &size); |
||||
|
||||
if( rank == 0 ) { |
||||
printf("I am the first process\n"); |
||||
} |
||||
else if( rank == 1 ) { |
||||
printf("I am the second process\n"); |
||||
} |
||||
else if( rank == 2 ) { |
||||
printf("I am the third process\n"); |
||||
}
|
||||
else { |
||||
printf("I am a remaning process\n"); |
||||
} |
||||
|
||||
MPI_Finalize(); |
||||
} |
@ -1,237 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <limits.h> |
||||
#include <mpi.h> |
||||
|
||||
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
|
||||
#define INIT_BUFFER_SIZE 8 |
||||
// Optimal exponential buffer growth factor, 2 is sometimes used to
|
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
#define INPUTFILE "zadanie1.in" |
||||
//#define MIN_PORTION 2
|
||||
|
||||
int maximum(int n, int *arrNumbers); |
||||
int *array_slice(int n, int *arrNumbers, int start, int count); |
||||
void *my_malloc(size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
int numProcesses, numRank; |
||||
//MPI_Status mpiStatus;
|
||||
|
||||
int *arrNumbers = NULL; |
||||
int *arrBlockIndices = NULL; |
||||
int *arrBlockSizes = NULL; |
||||
|
||||
// The address of this need not change
|
||||
static int numBlockSize = 0; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &numRank); |
||||
|
||||
if (numRank == 0) { |
||||
int numNumber, numCount = 0; |
||||
// To avoid aggresive buffer growth at the beggining of the sequence
|
||||
int numBufferSize = INIT_BUFFER_SIZE; |
||||
// Allocate enough memory for initial buffer
|
||||
arrNumbers = my_malloc(numBufferSize * sizeof(int)); |
||||
//int num[10];
|
||||
FILE *ptrFile = my_fopen(INPUTFILE, "r"); |
||||
|
||||
// Read lines of numbers until an EOF or a character is read
|
||||
while (fscanf(ptrFile, "%d", &numNumber) == 1) { |
||||
// Incorporate space for storing results received from slaves at the end of array
|
||||
int numBufferUsed = numCount + numProcesses - 1; |
||||
|
||||
if (numBufferSize == numBufferUsed) { |
||||
// Grow buffer exponentially
|
||||
numBufferSize *= GROWTH_FACTOR; |
||||
arrNumbers = my_realloc(arrNumbers, numBufferSize * sizeof(int)); |
||||
}
|
||||
|
||||
arrNumbers[numCount++] = numNumber; |
||||
} |
||||
//printf("count: %d, buffer: %d\n", numCount, numBufferSize);
|
||||
|
||||
int numBlockIndex = 0; |
||||
int numRemainder = numCount % numProcesses; |
||||
|
||||
arrBlockIndices = my_malloc(numProcesses * sizeof(int)); |
||||
arrBlockSizes = my_malloc(numProcesses * sizeof(int)); |
||||
|
||||
for (int ii = 0; ii < numProcesses; ii++) { |
||||
arrBlockSizes[ii] = numCount / numProcesses; |
||||
if (numRemainder > 0) { |
||||
arrBlockSizes[ii]++; |
||||
numRemainder--; |
||||
} |
||||
|
||||
arrBlockIndices[ii] = numBlockIndex; |
||||
numBlockIndex += arrBlockSizes[ii]; |
||||
} |
||||
for (int jj = 0; jj < numProcesses; jj++) { |
||||
printf("size[%d] = %d\tindex[%d] = %d\n", jj, arrBlockSizes[jj], jj, arrBlockIndices[jj]); |
||||
} |
||||
numBlockSize = arrBlockSizes[0]; |
||||
} |
||||
|
||||
//int *numBlockSize = &arrBlockSizes[numRank];
|
||||
//printf("r: %d, nbs %d\n", numRank, *numBlockSize);
|
||||
|
||||
// If there is just the one root process, all the numbers must be passed to the final stage
|
||||
//if (numRank == 0 && numProcesses != 1)
|
||||
if (numRank == 0 && numProcesses != 1) |
||||
numBlockSize = numProcesses; |
||||
|
||||
MPI_Bcast(&arrBlockSizes, numProcesses, MPI_INT, 0, MPI_COMM_WORLD); |
||||
for (int i = 0; i < numProcesses; i++) |
||||
printf("rank %d, nproc %d, abs[%i] = %d\n", numRank, numProcesses, i, arrBlockSizes[i]); |
||||
printf("%d %d\n", arrBlockSizes[0], arrBlockSizes[1]); |
||||
|
||||
|
||||
//int *arrMaximums = my_malloc(numBlockSize[numRank] * sizeof(int));
|
||||
int *arrMaximums = my_malloc(numBlockSize * sizeof(int)); |
||||
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, &arrMaximums, numBlockSize, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
//print what each process received
|
||||
//for (int i = 0; i < numRank; i++) {
|
||||
//printf("rank %d, nproc %d, m[%d] = %d\t", numRank, numProcesses, i, arrMaximums[i]);
|
||||
//arrMaximums[i] *= 10;
|
||||
//printf("\n");
|
||||
//}
|
||||
|
||||
//int *arrMaximums = my_malloc(numBlockSize * sizeof(int));
|
||||
//arrMaximums[numRank] = numRank * 10 + 5;
|
||||
|
||||
//MPI_Gatherv(arrMaximums, 1, MPI_INT, arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
|
||||
//if (numRank == 0) {
|
||||
//printf("root received:\n");
|
||||
//for (int i = 0; i < numBlockSize; i++) {
|
||||
//printf("m[%d] = %d\t", i, arrMaximums[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//} */
|
||||
|
||||
|
||||
MPI_Finalize(); |
||||
return (0); |
||||
} |
||||
|
||||
int maximum(int n, int *arrNumbers) { |
||||
int value = 0;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (value < arrNumbers[i]) { |
||||
value = arrNumbers[i];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
} |
||||
|
||||
int *array_slice(int n, int *arrNumbers, int start, int count) { |
||||
int *slice = my_malloc(count * sizeof(int)); |
||||
for (int i = 0; i < count && i < n; i++)
|
||||
slice[i] = arrNumbers[start + i];
|
||||
|
||||
return slice; |
||||
} |
||||
|
||||
void *my_malloc(size_t size) { |
||||
void *p = malloc(size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
|
||||
void *my_realloc(void *p, size_t size) { |
||||
void *temp = realloc(p, size); |
||||
if (temp == NULL) { |
||||
printf("Insufficient memory; can't add more items.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return temp; |
||||
} |
||||
|
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
|
||||
/*
|
||||
//print what each process received
|
||||
//printf("%d: ", numRank);
|
||||
for (int i = 0; i < arrBlockSizes[numRank]; i++) { |
||||
//printf("m[%d] = %d\t", i, arrMaximums[i]);
|
||||
arrMaximums[i] *= 10; |
||||
}
|
||||
//printf("\n");
|
||||
*/ |
||||
|
||||
|
||||
|
||||
|
||||
//printf("size = %d, remainder = %d\n\n", numBlockSize, numRemainder);
|
||||
|
||||
// This is a slave process
|
||||
//else {
|
||||
//int numCount, numValue;
|
||||
//MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &mpiStatus);
|
||||
//MPI_Get_count(&mpiStatus, MPI_INT, &numCount);
|
||||
|
||||
//if (numCount != MPI_UNDEFINED) {
|
||||
//int *arrNumbers = my_malloc(numCount * sizeof(int));
|
||||
|
||||
////printf("address before: %p\n", arrNumbers);
|
||||
//MPI_Recv(arrNumbers, numCount, MPI_INT, 0, 1, MPI_COMM_WORLD, &mpiStatus);
|
||||
////printf("address after: %p\n", arrNumbers);
|
||||
//numValue = maximum(numCount, arrNumbers);
|
||||
//MPI_Send(&numValue, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// If there are no slave processes, just find the maximum of the numbers from the file
|
||||
//int numUse = numCount, numStart = 0;
|
||||
//int numPortion = numCount;
|
||||
|
||||
//if (numProcesses > 1) {
|
||||
|
||||
////int numSlaves = numProcesses - 1;
|
||||
//numPortion = numCount / numProcesses;
|
||||
|
||||
//// Send at least 2 numbers to compare to slave process, no less
|
||||
//numPortion = numPortion >= 2 ? numPortion : 2;
|
||||
|
||||
//// Do the loop for every slave process
|
||||
//for (int numSlave = 1; numProcesses > numSlave; numSlave++) {
|
||||
//printf("> sending %d to %d\n", numPortion, numSlave);
|
||||
//MPI_Send(&arrNumbers[numStart], numPortion, MPI_INT, numSlave, 1, MPI_COMM_WORLD);
|
||||
//numStart += numPortion;
|
||||
//numUse -= numPortion;
|
||||
//}
|
||||
|
||||
|
||||
//}
|
||||
|
||||
//int max = maximum(numUse, &arrNumbers[numStart]);
|
||||
//int max = maximum(numCount, arrNumbers);
|
||||
//printf("processes: %d, buffer: %d, count: %d, portion: %d \n",
|
||||
//numProcesses, numBufferSize, numCount, numPortion);
|
||||
|
||||
//printf("start: %d, use: %d, max: %d\n", numStart, numUse, max);
|
Binary file not shown.
@ -1,289 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <limits.h> |
||||
#include <mpi.h> |
||||
|
||||
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
|
||||
#define INIT_BUFFER_SIZE 8 |
||||
// Optimal exponential buffer growth factor, 2 is sometimes used to
|
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
#define INPUTFILE "zadanie1.in" |
||||
//#define MIN_PORTION 2
|
||||
|
||||
int maximum(int n, int *arrNumbers); |
||||
int *array_slice(int n, int *arrNumbers, int start, int count); |
||||
void *my_malloc(size_t size); |
||||
void *my_calloc(size_t nitems, size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
int numProcesses, numRank; |
||||
//MPI_Status mpiStatus;
|
||||
|
||||
int *arrNumbers; |
||||
int *arrBlockIndices; |
||||
int *arrBlockSizes; |
||||
|
||||
size_t sizeBufferTotal; |
||||
MPI_Status status; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &numRank); |
||||
|
||||
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];
|
||||
FILE *ptrFile = my_fopen(INPUTFILE, "r"); |
||||
|
||||
// Read lines of numbers until an EOF or a character is read
|
||||
while (fscanf(ptrFile, "%d", &numNumber) == 1) { |
||||
// Incorporate space for storing results received from slaves at the end of array
|
||||
// TODO: remove this incorporation
|
||||
size_t sizeBufferUsed = numCount + numProcesses - 1; |
||||
|
||||
if (sizeBufferTotal == sizeBufferUsed) { |
||||
// Grow buffer exponentially
|
||||
sizeBufferTotal *= GROWTH_FACTOR; |
||||
arrNumbers = my_realloc(arrNumbers, sizeBufferTotal * sizeof(int)); |
||||
}
|
||||
|
||||
arrNumbers[numCount++] = 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);
|
||||
|
||||
int numBlockIndex = 0; |
||||
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] = numCount / 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]);
|
||||
//}
|
||||
|
||||
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++) {
|
||||
//printf("rank %d: m[%d] = %d\n", numRank, i, arrSlice[i]);
|
||||
//}
|
||||
|
||||
int numMaximum = maximum(numCount, arrSlice); |
||||
//printf("max in %d is %d\n", numRank, numMaximum);
|
||||
int *arrMaximums; |
||||
if (numRank == 0) { |
||||
arrMaximums = my_malloc(numProcesses * sizeof(int)); |
||||
} |
||||
|
||||
MPI_Gather(&numMaximum, 1, MPI_INT, arrMaximums, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
MPI_Barrier(MPI_COMM_WORLD); |
||||
if (numRank == 0) { |
||||
//for (int i = 0; i < numProcesses; i++) {
|
||||
//printf("arrMaximums[%d] = %d\n", i, arrMaximums[i]);
|
||||
//}
|
||||
printf("The maximum from file %s is %d.\n", INPUTFILE, maximum(numProcesses, arrMaximums)); |
||||
} |
||||
|
||||
|
||||
MPI_Finalize(); |
||||
return (0); |
||||
} |
||||
|
||||
int maximum(int n, int *arrNumbers) { |
||||
int value = INT_MIN;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (value < arrNumbers[i]) { |
||||
value = arrNumbers[i];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
} |
||||
|
||||
int *array_slice(int n, int *arrNumbers, int start, int count) { |
||||
int *slice = my_malloc(count * sizeof(int)); |
||||
for (int i = 0; i < count && i < n; i++)
|
||||
slice[i] = arrNumbers[start + i];
|
||||
|
||||
return slice; |
||||
} |
||||
|
||||
void *my_malloc(size_t size) { |
||||
void *p = malloc(size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
void *my_calloc(size_t nitems, size_t size) { |
||||
void *p = calloc(nitems, size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation with initialisation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
|
||||
void *my_realloc(void *p, size_t size) { |
||||
void *temp = realloc(p, size); |
||||
if (temp == NULL) { |
||||
printf("Insufficient memory; can't add more items.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return temp; |
||||
} |
||||
|
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
//int *numBlockSize = &arrBlockSizes[numRank];
|
||||
//printf("r: %d, nbs %d\n", numRank, *numBlockSize);
|
||||
|
||||
// If there is just the one root process, all the numbers must be passed to the final stage
|
||||
//if (numRank == 0 && numProcesses != 1)
|
||||
//if (numRank == 0 && numProcesses != 1)
|
||||
//numBlockSize = numProcesses;
|
||||
//int BlS = arrBlockSizes;
|
||||
//MPI_Bcast(arrBlockciwSizes, numProcesses, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
//for (int i = 0; i < numProcesses; i++)
|
||||
//printf("rank %d, nproc %d, abs[%i] = %d\n", numRank, numProcesses, i, arrBlockSizes[i]);
|
||||
//printf("%d %d\n", arrBlockSizes[0], arrBlockSizes[1]);
|
||||
//printf("%d: ", numRank);
|
||||
//for (int i = 0; i < numProcesses; i++) {
|
||||
//printf("%d ", arrBlockSizes[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//int num = numProcesses + 100;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//int *arrSlice = my_malloc(numBlockSize * sizeof(int));
|
||||
//arrSlice[numRank] = numRank * 10 + 5;
|
||||
|
||||
|
||||
//if (numRank == 0) {
|
||||
//printf("root received:\n");
|
||||
//for (int i = 0; i < numBlockSize; i++) {
|
||||
//printf("m[%d] = %d\t", i, arrSlice[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//} */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//print what each process received
|
||||
//printf("%d: ", numRank);
|
||||
for (int i = 0; i < arrBlockSizes[numRank]; i++) { |
||||
//printf("m[%d] = %d\t", i, arrSlice[i]);
|
||||
arrSlice[i] *= 10; |
||||
}
|
||||
//printf("\n");
|
||||
*/ |
||||
|
||||
|
||||
|
||||
|
||||
//printf("size = %d, remainder = %d\n\n", numBlockSize, numRemainder);
|
||||
|
||||
// This is a slave process
|
||||
//else {
|
||||
//int numCount, numValue;
|
||||
//MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &mpiStatus);
|
||||
//MPI_Get_count(&mpiStatus, MPI_INT, &numCount);
|
||||
|
||||
//if (numCount != MPI_UNDEFINED) {
|
||||
//int *arrNumbers = my_malloc(numCount * sizeof(int));
|
||||
|
||||
////printf("address before: %p\n", arrNumbers);
|
||||
//MPI_Recv(arrNumbers, numCount, MPI_INT, 0, 1, MPI_COMM_WORLD, &mpiStatus);
|
||||
////printf("address after: %p\n", arrNumbers);
|
||||
//numValue = maximum(numCount, arrNumbers);
|
||||
//MPI_Send(&numValue, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// If there are no slave processes, just find the maximum of the numbers from the file
|
||||
//int numUse = numCount, numStart = 0;
|
||||
//int numPortion = numCount;
|
||||
|
||||
//if (numProcesses > 1) {
|
||||
|
||||
////int numSlaves = numProcesses - 1;
|
||||
//numPortion = numCount / numProcesses;
|
||||
|
||||
//// Send at least 2 numbers to compare to slave process, no less
|
||||
//numPortion = numPortion >= 2 ? numPortion : 2;
|
||||
|
||||
//// Do the loop for every slave process
|
||||
//for (int numSlave = 1; numProcesses > numSlave; numSlave++) {
|
||||
//printf("> sending %d to %d\n", numPortion, numSlave);
|
||||
//MPI_Send(&arrNumbers[numStart], numPortion, MPI_INT, numSlave, 1, MPI_COMM_WORLD);
|
||||
//numStart += numPortion;
|
||||
//numUse -= numPortion;
|
||||
//}
|
||||
|
||||
|
||||
//}
|
||||
|
||||
//int max = maximum(numUse, &arrNumbers[numStart]);
|
||||
//int max = maximum(numCount, arrNumbers);
|
||||
//printf("processes: %d, buffer: %d, count: %d, portion: %d \n",
|
||||
//numProcesses, sizeBufferTotal, numCount, numPortion);
|
||||
|
||||
//printf("start: %d, use: %d, max: %d\n", numStart, numUse, max);
|
@ -1,127 +1,125 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include "common.h" |
||||
|
||||
#define INPUTFILE "zadanie2.in" |
||||
#define MAX_LINE_LENGTH 8192 |
||||
#define INIT_BUFFER_SIZE 20 |
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
void *my_malloc(size_t size); |
||||
void *my_calloc(size_t nitems, size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
|
||||
int main(void) { |
||||
char strBuffer[MAX_LINE_LENGTH]; |
||||
char *ptrBuffer; |
||||
int numValue; |
||||
|
||||
FILE *ptrFile = my_fopen(INPUTFILE, "r"); |
||||
|
||||
size_t sizeBufferUsed = 0, sizeBufferTotal = INIT_BUFFER_SIZE; |
||||
int *arrNumbers; |
||||
arrNumbers = my_malloc(sizeBufferTotal * sizeof(int)); |
||||
|
||||
int cols; |
||||
|
||||
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)); |
||||
int main(int argc, char *argv[]) { |
||||
int numProcesses, numRank; |
||||
//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; |
||||
|
||||
if (numRank == 0) { |
||||
|
||||
char *ptrBuffer, strBuffer[MAX_LINE_LENGTH]; |
||||
FILE *ptrFile = my_fopen(INPUTFILE, "r"); |
||||
sizeBufferTotal = INIT_BUFFER_SIZE; |
||||
arrNumbers = my_malloc(sizeBufferTotal * sizeof(int)); |
||||
|
||||
// Read line by line until the end of file
|
||||
// TODO: remove the MAX_LINE_LENGTH limitation of strBuffer
|
||||
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') { |
||||
// Convert string to base 10
|
||||
numValue = strtol(ptrBuffer, &ptrBuffer, 10); |
||||
// Store the number read in memory
|
||||
arrNumbers[sizeBufferUsed++] = numValue; |
||||
cols++; |
||||
} |
||||
} |
||||
|
||||
// store the pointer
|
||||
ptrBuffer = strBuffer; |
||||
cols = 0; |
||||
// Read untill newline
|
||||
while (*ptrBuffer != '\n') { |
||||
// Convert string to base 10
|
||||
numValue = strtol(ptrBuffer, &ptrBuffer, 10); |
||||
// Store the number read in memory
|
||||
arrNumbers[sizeBufferUsed++] = 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);
|
||||
|
||||
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]);
|
||||
//}
|
||||
} |
||||
|
||||
printf("original matrix: \n"); |
||||
MPI_Bcast(&sizeBufferTotal, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
printf("total %d in %d\n", sizeBufferTotal, numRank); |
||||
|
||||
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++) { |
||||
// Only the indices are transposed
|
||||
int index = ((rows * i) / (cols * rows)) + ((rows * i) % (cols * rows)); |
||||
arrIndices[index] = i; |
||||
} |
||||
|
||||
printf("trasnposed matrix:"); |
||||
printf("transposed matrix:"); |
||||
for (int i = 0; i < sizeBufferUsed; i++) { |
||||
if (i % rows == 0) |
||||
printf("\n"); |
||||
printf("%d ", arrNumbers[arrIndices[i]]); |
||||
} |
||||
|
||||
printf("\n"); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
|
||||
void *my_malloc(size_t size) { |
||||
void *p = malloc(size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
void *my_calloc(size_t nitems, size_t size) { |
||||
void *p = calloc(nitems, size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation with initialisation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
}*/ |
||||
|
||||
|
||||
void *my_realloc(void *p, size_t size) { |
||||
void *temp = realloc(p, size); |
||||
if (temp == NULL) { |
||||
printf("Insufficient memory; can't add more items.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return temp; |
||||
//printf("\n");
|
||||
MPI_Finalize(); |
||||
return 0; |
||||
} |
||||
|
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
//printf("trasnposed matrix:");
|
||||
//for (int i = 0; i < sizeBufferUsed; i++) {
|
||||
//if (i % rows == 0)
|
||||
//printf("\n");
|
||||
//printf("%d ", arrTrans[i]);
|
||||
//}
|
||||
//printf("trasnposed matrix:");
|
||||
//for (int i = 0; i < sizeBufferUsed; i++) {
|
||||
//if (i % rows == 0)
|
||||
//printf("\n");
|
||||
//printf("%d ", arrTrans[i]);
|
||||
//}
|
||||
|
||||
/* for (int i = 0; i < sizeBufferUsed; i++) {*/ |
||||
//if (i % rows == 0)
|
||||
//printf("\n");
|
||||
//printf("%2d[%2d]\t", i, arrIndices[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", sizeBufferUsed / cols, cols);
|
||||
|
@ -1,289 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <limits.h> |
||||
#include <mpi.h> |
||||
|
||||
// Avoids aggresive memory reallocation at the beginning of buffer growth sequence
|
||||
#define INIT_BUFFER_SIZE 8 |
||||
// Optimal exponential buffer growth factor, 2 is sometimes used to
|
||||
#define GROWTH_FACTOR 1.5 |
||||
|
||||
#define INPUTFILE1 "zadanie1.in1" |
||||
#define INPUTFILE2 "zadanie1.in2" |
||||
//#define MIN_PORTION 2
|
||||
|
||||
int maximum(int n, int *arrNumbers); |
||||
int *array_slice(int n, int *arrNumbers, int start, int count); |
||||
void *my_malloc(size_t size); |
||||
void *my_calloc(size_t nitems, size_t size); |
||||
void *my_realloc(void *p, size_t size); |
||||
FILE *my_fopen(const char *filename, const char *mode); |
||||
|
||||
int main(int argc, char *argv[]) { |
||||
int numProcesses, numRank; |
||||
//MPI_Status mpiStatus;
|
||||
|
||||
int *arrNumbers; |
||||
int *arrBlockIndices; |
||||
int *arrBlockSizes; |
||||
|
||||
int numBufferSize; |
||||
MPI_Status status; |
||||
|
||||
MPI_Init(&argc, &argv); |
||||
MPI_Comm_size(MPI_COMM_WORLD, &numProcesses); |
||||
MPI_Comm_rank(MPI_COMM_WORLD, &numRank); |
||||
|
||||
if (numRank == 0) { |
||||
int numNumber, numCount = 0; |
||||
// To avoid aggresive buffer growth at the beggining of the sequence
|
||||
numBufferSize = INIT_BUFFER_SIZE; |
||||
// Allocate enough memory for initial buffer
|
||||
arrNumbers = my_malloc(numBufferSize * sizeof(int)); |
||||
//int num[10];
|
||||
FILE *ptrFile = my_fopen(INPUTFILE, "r"); |
||||
|
||||
// Read lines of numbers until an EOF or a character is read
|
||||
while (fscanf(ptrFile, "%d", &numNumber) == 1) { |
||||
// Incorporate space for storing results received from slaves at the end of array
|
||||
int numBufferUsed = numCount + numProcesses - 1; |
||||
|
||||
if (numBufferSize == numBufferUsed) { |
||||
// Grow buffer exponentially
|
||||
numBufferSize *= GROWTH_FACTOR; |
||||
arrNumbers = my_realloc(arrNumbers, numBufferSize * sizeof(int)); |
||||
}
|
||||
|
||||
arrNumbers[numCount++] = 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, numBufferSize);
|
||||
|
||||
int numBlockIndex = 0; |
||||
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] = numCount / 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]);
|
||||
//}
|
||||
|
||||
for (int i = 0; i < numProcesses; i++) { |
||||
MPI_Send(&arrBlockSizes[i], 1, MPI_INT, i, 1, MPI_COMM_WORLD);
|
||||
} |
||||
} |
||||
|
||||
MPI_Bcast(&numBufferSize, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
int *arrSlice = my_malloc(numBufferSize * sizeof(int)); |
||||
MPI_Scatterv(arrNumbers, arrBlockSizes, arrBlockIndices, MPI_INT, arrSlice, numBufferSize, 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++) {
|
||||
//printf("rank %d: m[%d] = %d\n", numRank, i, arrSlice[i]);
|
||||
//}
|
||||
|
||||
int numMaximum = maximum(numCount, arrSlice); |
||||
//printf("max in %d is %d\n", numRank, numMaximum);
|
||||
int *arrMaximums; |
||||
if (numRank == 0) { |
||||
arrMaximums = my_malloc(numProcesses * sizeof(int)); |
||||
} |
||||
|
||||
MPI_Gather(&numMaximum, 1, MPI_INT, arrMaximums, 1, MPI_INT, 0, MPI_COMM_WORLD); |
||||
|
||||
MPI_Barrier(MPI_COMM_WORLD); |
||||
if (numRank == 0) { |
||||
//for (int i = 0; i < numProcesses; i++) {
|
||||
//printf("arrMaximums[%d] = %d\n", i, arrMaximums[i]);
|
||||
//}
|
||||
printf("The maximum from file %s is %d.\n", INPUTFILE, maximum(numProcesses, arrMaximums)); |
||||
} |
||||
|
||||
|
||||
MPI_Finalize(); |
||||
return (0); |
||||
} |
||||
|
||||
int maximum(int n, int *arrNumbers) { |
||||
int value = INT_MIN;
|
||||
for (int i = 0; i < n; i++) {
|
||||
if (value < arrNumbers[i]) { |
||||
value = arrNumbers[i];
|
||||
}
|
||||
}
|
||||
return value;
|
||||
} |
||||
|
||||
int *array_slice(int n, int *arrNumbers, int start, int count) { |
||||
int *slice = my_malloc(count * sizeof(int)); |
||||
for (int i = 0; i < count && i < n; i++)
|
||||
slice[i] = arrNumbers[start + i];
|
||||
|
||||
return slice; |
||||
} |
||||
|
||||
void *my_malloc(size_t size) { |
||||
void *p = malloc(size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
void *my_calloc(size_t nitems, size_t size) { |
||||
void *p = calloc(nitems, size); |
||||
if (p == NULL) { |
||||
printf("Memory allocation with initialisation unsuccessful.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return p; |
||||
} |
||||
|
||||
|
||||
void *my_realloc(void *p, size_t size) { |
||||
void *temp = realloc(p, size); |
||||
if (temp == NULL) { |
||||
printf("Insufficient memory; can't add more items.\n"); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return temp; |
||||
} |
||||
|
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
|
||||
|
||||
|
||||
//int *numBlockSize = &arrBlockSizes[numRank];
|
||||
//printf("r: %d, nbs %d\n", numRank, *numBlockSize);
|
||||
|
||||
// If there is just the one root process, all the numbers must be passed to the final stage
|
||||
//if (numRank == 0 && numProcesses != 1)
|
||||
//if (numRank == 0 && numProcesses != 1)
|
||||
//numBlockSize = numProcesses;
|
||||
//int BlS = arrBlockSizes;
|
||||
//MPI_Bcast(arrBlockciwSizes, numProcesses, MPI_INT, 0, MPI_COMM_WORLD);
|
||||
//for (int i = 0; i < numProcesses; i++)
|
||||
//printf("rank %d, nproc %d, abs[%i] = %d\n", numRank, numProcesses, i, arrBlockSizes[i]);
|
||||
//printf("%d %d\n", arrBlockSizes[0], arrBlockSizes[1]);
|
||||
//printf("%d: ", numRank);
|
||||
//for (int i = 0; i < numProcesses; i++) {
|
||||
//printf("%d ", arrBlockSizes[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//int num = numProcesses + 100;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//int *arrSlice = my_malloc(numBlockSize * sizeof(int));
|
||||
//arrSlice[numRank] = numRank * 10 + 5;
|
||||
|
||||
|
||||
//if (numRank == 0) {
|
||||
//printf("root received:\n");
|
||||
//for (int i = 0; i < numBlockSize; i++) {
|
||||
//printf("m[%d] = %d\t", i, arrSlice[i]);
|
||||
//}
|
||||
//printf("\n");
|
||||
//} */
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
//print what each process received
|
||||
//printf("%d: ", numRank);
|
||||
for (int i = 0; i < arrBlockSizes[numRank]; i++) { |
||||
//printf("m[%d] = %d\t", i, arrSlice[i]);
|
||||
arrSlice[i] *= 10; |
||||
}
|
||||
//printf("\n");
|
||||
*/ |
||||
|
||||
|
||||
|
||||
|
||||
//printf("size = %d, remainder = %d\n\n", numBlockSize, numRemainder);
|
||||
|
||||
// This is a slave process
|
||||
//else {
|
||||
//int numCount, numValue;
|
||||
//MPI_Probe(MPI_ANY_SOURCE, MPI_ANY_TAG, MPI_COMM_WORLD, &mpiStatus);
|
||||
//MPI_Get_count(&mpiStatus, MPI_INT, &numCount);
|
||||
|
||||
//if (numCount != MPI_UNDEFINED) {
|
||||
//int *arrNumbers = my_malloc(numCount * sizeof(int));
|
||||
|
||||
////printf("address before: %p\n", arrNumbers);
|
||||
//MPI_Recv(arrNumbers, numCount, MPI_INT, 0, 1, MPI_COMM_WORLD, &mpiStatus);
|
||||
////printf("address after: %p\n", arrNumbers);
|
||||
//numValue = maximum(numCount, arrNumbers);
|
||||
//MPI_Send(&numValue, 1, MPI_INT, 0, 1, MPI_COMM_WORLD);
|
||||
//}
|
||||
//}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// If there are no slave processes, just find the maximum of the numbers from the file
|
||||
//int numUse = numCount, numStart = 0;
|
||||
//int numPortion = numCount;
|
||||
|
||||
//if (numProcesses > 1) {
|
||||
|
||||
////int numSlaves = numProcesses - 1;
|
||||
//numPortion = numCount / numProcesses;
|
||||
|
||||
//// Send at least 2 numbers to compare to slave process, no less
|
||||
//numPortion = numPortion >= 2 ? numPortion : 2;
|
||||
|
||||
//// Do the loop for every slave process
|
||||
//for (int numSlave = 1; numProcesses > numSlave; numSlave++) {
|
||||
//printf("> sending %d to %d\n", numPortion, numSlave);
|
||||
//MPI_Send(&arrNumbers[numStart], numPortion, MPI_INT, numSlave, 1, MPI_COMM_WORLD);
|
||||
//numStart += numPortion;
|
||||
//numUse -= numPortion;
|
||||
//}
|
||||
|
||||
|
||||
//}
|
||||
|
||||
//int max = maximum(numUse, &arrNumbers[numStart]);
|
||||
//int max = maximum(numCount, arrNumbers);
|
||||
//printf("processes: %d, buffer: %d, count: %d, portion: %d \n",
|
||||
//numProcesses, numBufferSize, numCount, numPortion);
|
||||
|
||||
//printf("start: %d, use: %d, max: %d\n", numStart, numUse, max);
|
@ -1,2 +0,0 @@ |
||||
1 2 3 |
||||
4 5 6 |
@ -1,3 +0,0 @@ |
||||
7 8 |
||||
9 10 |
||||
11 12 |
@ -1,36 +0,0 @@ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
|
||||
#define MAX_LINE_LENGTH 8192 |
||||
|
||||
#define INPUTFILE1 "zadanie3.in1" |
||||
#define INPUTFILE2 "zadanie3.in2" |
||||
|
||||
FILE *my_fopen(const char *filename, const char *mode) { |
||||
FILE *file = fopen(filename, mode); |
||||
if (file == NULL) { |
||||
printf("File %s could not be opened.\n", filename); |
||||
exit(EXIT_FAILURE); |
||||
} |
||||
return file; |
||||
} |
||||
|
||||
|
||||
int main(void) { |
||||
char strBuffer[MAX_LINE_LENGTH]; |
||||
char *ptrBuffer; |
||||
int numValue; |
||||
|
||||
FILE *ptrFile = my_fopen(INPUTFILE2, "r"); |
||||
|
||||
while (fgets(strBuffer, sizeof strBuffer, ptrFile) != 0) { |
||||
//printf("Line contains ");
|
||||
ptrBuffer = strBuffer; |
||||
while (*ptrBuffer != '\n') { |
||||
numValue = strtol(ptrBuffer, &ptrBuffer, 10); |
||||
printf("%d ", numValue); |
||||
} |
||||
printf("\n"); |
||||
} |
||||
return 0; |
||||
} |
Loading…
Reference in new issue