Commit 35f6694d authored by Taddeüs Kroes's avatar Taddeüs Kroes

ModSim ass4 taddeus: Finished part 1 and made a least squares data fitting script.

parent c27c9f03
#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>
double data[1] = {.0};
void initialize_ring(int tasks) {
double received;
MPI_Status status;
printf("Sending first data...");
MPI_Send(data, 1, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);
puts("sent");
MPI_Recv(&received, 1, MPI_DOUBLE, tasks - 1, MPI_ANY_TAG, MPI_COMM_WORLD,
&status);
if( received != *data )
printf("Received data does not match (sent: %f, received: %f)\n",
*data, received);
else
puts("Data received succesfully");
}
void pass_data(int tasks, int rank) {
double received;
MPI_Status status;
int target = (rank + 1) % tasks, source = (rank - 1 + tasks) % tasks;
MPI_Recv(&received, 1, MPI_DOUBLE, source, MPI_ANY_TAG, MPI_COMM_WORLD,
&status);
printf("Task %d received data from %d, sending to %d...", rank, source,
target);
MPI_Send(data, 1, MPI_DOUBLE, target, 0, MPI_COMM_WORLD);
puts("sent");
}
int main(int argc, char **argv) {
int tasks, rank, error;
if( (error = MPI_Init(&argc, &argv)) != MPI_SUCCESS ) {
printf("MPI_init failed (error %d)\n", error);
MPI_Abort(MPI_COMM_WORLD, error);
}
MPI_Comm_size(MPI_COMM_WORLD, &tasks);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if( !rank )
initialize_ring(tasks);
else
pass_data(tasks, rank);
MPI_Finalize();
}
#!/usr/bin/env python
from sys import argv, stdin
from pylab import array, matrix, ones, dot, plot, legend, show, savefig
# Collect data
data = []
for line in stdin.readlines():
data.append(map(float, line.split(',', 1)))
# Least squares data fit
A = matrix(ones((len(data), 2)))
data = array(data)
A.T[1] = data.T[0]
b = data.T[1].T
start, slope = tuple(list(dot((A.T * A).I * A.T, b).tolist()[0]))
# Plot and optionally save data
data = data.T
plot(data[0], data[1], 'x-', label='original data')
plot([0, data[0][-1]], [start, data[0][-1] * slope + start], '-',
label='linear fit y = %ex + %e' % (slope, start))
if len(argv) == 2:
savefig(argv[1])
legend()
show()
#include <stdlib.h>
#include <stdio.h>
#include <mpi.h>
//#define DEBUG
#define LOOP 100
#define STRIDE 10000
#define REPEAT 7
const int data_size = LOOP * STRIDE;
/*
* The master task measures the time between the sending and receiving of data.
*/
void master(int tasks) {
double *received = malloc(data_size * sizeof(double)),
*sent = malloc(data_size * sizeof(double)),
avg_time, start_time, time;
MPI_Status status;
int i, size, measurement, failures;
// generate data to send
for( i = 0; i < data_size; i++ )
sent[i] = .0;
// Increase the message length with a fixed STRIDE
for( size = STRIDE; size <= data_size; size += STRIDE ) {
// Repeat the measurement and average the results
avg_time = .0;
for( measurement = 1; measurement <= REPEAT; measurement++ ) {
#ifdef DEBUG
printf("Measurement %d: ", measurement);
#endif
start_time = MPI_Wtime();
//printf("0");
MPI_Send(sent, size, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);
//printf("...");
MPI_Recv(received, size, MPI_DOUBLE, tasks - 1, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
time = MPI_Wtime() - start_time;
for( i = failures = 0; i < size; i++ )
if( received[i] != sent[i] )
failures++;
//printf("0, %fs (%d failures)\n", time, failures);
#ifdef DEBUG
printf("%fs (%d failures)\n", time, failures);
#endif
avg_time += time;
}
avg_time /= REPEAT;
#ifdef DEBUG
printf("Average time for size %d: %fs\n", size, avg_time);
#else
printf("%d,%f\n", size, avg_time);
#endif
}
free(received);
free(sent);
}
/*
* A slave task passes the data to the next task in the ring.
*/
void slave(int tasks, int rank) {
double *data = malloc(data_size * sizeof(double));
MPI_Status status;
int size, measurement,
source = (rank - 1 + tasks) % tasks, target = (rank + 1) % tasks;
// Increase the message length with a fixed STRIDE
for( size = STRIDE; size <= data_size; size += STRIDE ) {
// Repeat the measurement
for( measurement = 1; measurement <= REPEAT; measurement++ ) {
MPI_Recv(data, size, MPI_DOUBLE, source, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
//printf("%d", rank);
MPI_Send(data, size, MPI_DOUBLE, target, 0, MPI_COMM_WORLD);
//printf("...");
}
}
free(data);
}
int main(int argc, char **argv) {
int tasks, rank, error;
if( (error = MPI_Init(&argc, &argv)) != MPI_SUCCESS ) {
printf("MPI_init failed (error %d)\n", error);
MPI_Abort(MPI_COMM_WORLD, error);
return EXIT_FAILURE;
}
MPI_Comm_size(MPI_COMM_WORLD, &tasks);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if( !rank )
master(tasks);
else
slave(tasks, rank);
MPI_Finalize();
return EXIT_SUCCESS;
}
......@@ -40,6 +40,7 @@ int main(int argc, char **argv) {
if( (error = MPI_Init(&argc, &argv)) != MPI_SUCCESS ) {
printf("MPI_init failed (error %d)\n", error);
MPI_Abort(MPI_COMM_WORLD, error);
return EXIT_FAILURE;
}
MPI_Comm_size(MPI_COMM_WORLD, &tasks);
......@@ -51,4 +52,6 @@ int main(int argc, char **argv) {
pass_data(tasks, rank);
MPI_Finalize();
return EXIT_SUCCESS;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment