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