Commit 6ffd29cc authored by Taddeüs Kroes's avatar Taddeüs Kroes

ModSim ass4 taddeus: Worked on vibrating string MPI part.

parent 186e1e12
from sys import argv, exit
def combine(numfiles):
files = range(int(numfiles))
lines = [open('out%d.txt' % i).readlines() for i in files]
return [' '.join([lines[j][i][:-1] for j in files]) for i in
range(len(lines[0]))]
if __name__ == '__main__':
if len(argv) < 2:
print 'Usage: python %s TASKS' % argv[0]
exit()
print '\n'.join(combine(argv[1]))
#!/usr/bin/env python
from sys import stdin
from sys import stdin, argv, exit
from pylab import figure, plot, axis, draw, ion, clf
from time import sleep
from sys import argv, exit
from combine import combine
if len(argv) < 2:
print 'Usage: python %s TIME_STEP [ DELAY ]' % argv[0]
if len(argv) < 3:
print 'Usage: python %s TASKS TIME_STEP [ DELAY ]' % argv[0]
exit()
stride = int(argv[1])
delay = .1 if len(argv) < 3 else float(argv[2])
# tasks = 0 means sequential, above means parallel and having to combine the
# different output files
lines = combine(int(argv[1])) if int(argv[1]) else stdin.readlines()
stride = int(argv[2])
delay = .1 if len(argv) < 4 else float(argv[3])
# Collect data
y = []
lines = stdin.readlines()
x = map(float, lines[0].split(' '))
for line in lines[1::stride]:
y += [map(float, line.split(' '))]
......@@ -30,4 +33,4 @@ for i in range(len(y)):
plot(x, y[i], '-')
axis(ranges)
draw()
sleep(delay)
i and sleep(delay)
......@@ -4,51 +4,50 @@
#include <math.h>
#include <mpi.h>
double **y = NULL, dx;
int steps, time, start, rank, tasks;
static inline int first_node() {
return !rank;
}
static inline int last_node() {
return rank == tasks - 1;
}
double **y = NULL;
int tasks, rank, steps, start;
FILE *file;
/*
* Connect the string at both ends by sending the calculated border values and
* receiving the outer borders calculated by the adjacent nodes
*/
void connect(int state) {
double send[2], recv[2];
int source = (rank - 1 + tasks) % tasks, target = (rank + 1) % tasks;
void interact(int state) {
int prev = (rank - 1 + tasks) % tasks, next = (rank + 1) % tasks;
MPI_Status status;
send[0] = y[state][1];
send[1] = y[state][steps];
MPI_Sendrecv(send, 2, MPI_DOUBLE, target, MPI_ANY_TAG, recv, 2, MPI_DOUBLE,
source, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
// Left border
if( rank ) {
MPI_Sendrecv(&y[state][1], 1, MPI_DOUBLE, prev, 0, &y[state][0], 1,
MPI_DOUBLE, prev, MPI_ANY_TAG, MPI_COMM_WORLD, &status);
}
y[state][0] = recv[0];
y[state][steps + 1] = recv[1];
// Right border
if( rank < tasks - 1 ) {
MPI_Sendrecv(&y[state][steps], 1, MPI_DOUBLE, next, 0,
&y[state][steps + 1], 1, MPI_DOUBLE, next, MPI_ANY_TAG,
MPI_COMM_WORLD, &status);
}
}
static inline void init_borders() {
void init_borders() {
// The string is attached at both ends
if( first_node() )
if( !rank )
y[2][1] = y[1][1] = y[0][1];
else if( last_node() )
else if( rank == tasks - 1 )
y[2][steps] = y[1][steps] = y[0][steps];
connect(0);
//interact(0);
}
/*
* Fill the assigned string section with a sinus shape
*/
void init_sinus(double l, double n) {
for( int i = 0; i < steps; i++ )
void init_sinus(double l, double dx, double n) {
int i;
printf("start: %d\n", start);
for( i = 0; i < steps; i++ )
y[0][i + 1] = sin(n * M_PI * (i + start) * dx / l);
init_borders();
......@@ -57,10 +56,11 @@ void init_sinus(double l, double n) {
/*
* Fill the assigned string section with a plucked shape
*/
void init_plucked(double l, double xp) {
void init_plucked(double l, double dx, double xp) {
double x;
int i;
for( int i = 0; i < steps; i++ ) {
for( i = 0; i < steps; i++ ) {
x = (i + start) * dx;
y[0][i + 1] = x < xp ? x / xp : (l - x) / (l - xp);
}
......@@ -75,23 +75,20 @@ void init_plucked(double l, double xp) {
void print(int index) {
for( int i = 0; i < steps; i++ ) {
if( i || rank )
printf(" ");
if( i )
fprintf(file, " ");
printf(PRINT_FORMAT, y[index][i]);
fprintf(file, PRINT_FORMAT, y[index][i]);
}
if( last_node() )
puts("");
fflush(stdout);
fprintf(file, "\n");
}
#endif
/*
*
*/
void calculate_steps(int time, double tau) {
void calculate_steps(int time, double dx, double tau) {
double x;
int i, t, prev = 0, current = 1, next = 2;
......@@ -107,13 +104,12 @@ void calculate_steps(int time, double tau) {
// Print x values (which are the same for every y-series)
for( i = 0; i < steps; i++ ) {
if( i )
printf(" ");
fprintf(file, " ");
printf(PRINT_FORMAT, (i + start) * dx);
fprintf(file, PRINT_FORMAT, (i + start) * dx);
}
puts("");
fflush(stdout);
fprintf(file, "\n");
// Print init states
print(prev);
......@@ -135,28 +131,19 @@ void calculate_steps(int time, double tau) {
current = next;
next = (next + 1) % 3;
connect(next);
interact(next);
}
}
int main(int argc, char **argv) {
int error, time, i, total_steps;
void (*init_method)(double, double);
double l, tau, constant;
// Initialize and setup MPI
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);
void (*init_method)(double, double, double);
double l, tau, constant, dx;
char filename[9];
// Parse arguments
if( argc < 7 ) {
printf("Usage: %s INIT_METHOD CALCULATION_STEPS LENGTH DX TAU N|XP\n",
printf("Usage: %s INIT_METHOD TIME_STEPS LENGTH DX TAU N|XP\n",
argv[0]);
return EXIT_FAILURE;
}
......@@ -176,6 +163,20 @@ int main(int argc, char **argv) {
tau = atof(argv[5]);
constant = atof(argv[6]);
// Initialize and setup MPI
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);
// Open file for output
sprintf(filename, "out%d.txt", rank);
file = fopen(filename, "w");
// Calculate the indices of the string to calculate
total_steps = (int)ceil(l / dx);
steps = total_steps / tasks;
......@@ -195,19 +196,18 @@ int main(int argc, char **argv) {
for( i = 0; i < 3; i++ )
y[i] = (double *)malloc((steps + 2) * sizeof(double));
// Initialize the string values (sinus/plucked)
(*init_method)(l, constant);
// Calculate the specified number of steps
calculate_steps(time, tau);
// Initialize the string values (sinus/plucked) and calculate the specified
// number of steps
(*init_method)(l, dx, constant);
calculate_steps(time, dx, tau);
// Free allocated memory
// Cleanup
for( i = 0; i < 3; i++ )
free(y[i]);
free(y);
// Finalize MPI
fclose(file);
MPI_Finalize();
return EXIT_SUCCESS;
......
#!/bin/sh
NUM_PROCESSES=${1-4} # Default: 4 processes
#RSH_AGENT=rsh
#MPI_HOSTFILE=~/.mpirun.machines
PROGRAM_EXEC=par
RSH_AGENT=rsh
MPI_HOSTFILE=~/.mpirun.machines
PROGRAM_EXEC=./par
ARGS=sinus 1001 1 .01 1 1
mpirun -np $NUM_PROCESSES $PROGRAM_EXEC $@
#mpirun -np $NUM_PROCESSES ./par sinus 100 1 .01 1 1
mpirun -np $NUM_PROCESSES ./par sinus 3 1 .01 1 1
#mpirun -np $NUM_PROCESSES $PROGRAM_EXEC $ARGS
#mpirun -np $NUM_PROCESSES --mca pls_rsh_agent $RSH_AGENT \
# --hostfile $MPI_HOSTFILE $PROGRAM_EXEC
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