The unified diff between revisions [6327b022..] and [99a32020..] is displayed below. It can also be downloaded as a raw diff.

#
#
# add_file "aca319/lab9q1.c"
#  content [84c9892089e0d53521320499f9712eb8dacd7a61]
#
# patch "aca319/Makefile"
#  from [921c03d1193d872d536b97460b3b969fe41133c2]
#    to [49250753195fb97c9c84f38dad22c24c53b12abe]
#
============================================================
--- aca319/lab9q1.c	84c9892089e0d53521320499f9712eb8dacd7a61
+++ aca319/lab9q1.c	84c9892089e0d53521320499f9712eb8dacd7a61
@@ -0,0 +1,147 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <string.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "mpi.h"
+#include "mpe.h"
+
+#define		TRACK_SIZE		50
+
+#define		ACCELERATION_RATE	10
+#define		BREAK_RATE		10
+
+#define		SPEED_LIMIT		30
+
+#define		BREAK_DISTANCE		2
+#define		ACCELERATE_DISTANCE	5
+
+struct car {
+	int track_pos;
+	int speed;
+	int next_car_pos;
+};
+
+void
+drive(struct car *c, int rank, int size)
+{
+	MPI_Status status;
+	int distance;
+	int send_to;
+
+	/* firstly, we determine what our speed for this time
+	 * interval will be, based on our distance to the next
+	 * car on the track
+	 */
+	if (c->next_car_pos > c->track_pos) {
+		distance = c->next_car_pos - c->track_pos;
+	} else {
+		distance = (TRACK_SIZE - c->track_pos - 1) + c->next_car_pos;
+	}
+
+	if (rank == 0)
+		printf("[%d] (before) position=%d, speed=%d, distance=%d\n", rank, c->track_pos, c->speed, distance);
+	if (distance <= BREAK_DISTANCE) {
+		c->speed -= BREAK_RATE;
+	} else if (distance >= ACCELERATE_DISTANCE) {
+		c->speed += ACCELERATION_RATE;
+	}
+
+	/* no speeding! */
+	if (c->speed > SPEED_LIMIT)
+		c->speed = SPEED_LIMIT;
+	/* no going backwards, either */
+	if (c->speed < 0)
+		c->speed = 0;
+	/* ensure we don't overtake */
+	if (c->speed > distance - 1)
+		c->speed = distance - 1;
+
+	/* then we move
+	 */
+	c->track_pos = (c->track_pos + c->speed) % TRACK_SIZE;
+
+	if (rank == 0)
+		printf("[%d] (after) position=%d, speed=%d\n", rank, c->track_pos, c->speed);
+
+	/* then we send our position to the car behind us, and
+	 * receive the car in front's position
+	 */
+	send_to = rank - 1;
+	if (send_to < 0)
+		send_to = size - 1;
+	MPI_Sendrecv(&c->track_pos, 1, MPI_INT, send_to, 50,
+			&c->next_car_pos, 1, MPI_INT, (rank + 1) % size, 50, MPI_COMM_WORLD, &status);
+	//printf("%d: at %d, next car at %d\n", rank, c->track_pos, c->next_car_pos);
+}
+
+int
+main(int argc, char *argv[])
+{
+	int rank, size;
+	struct car this_car;
+	char *track;
+
+	MPI_Init(&argc, &argv);
+
+	MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+	MPI_Comm_size(MPI_COMM_WORLD, &size);
+
+	/* we're going to start 'size' cars.
+	 * they are evenly spaced around the track.
+	 */
+	this_car.track_pos = rank * (TRACK_SIZE / size);
+	this_car.next_car_pos = (rank + 1 % size) * (TRACK_SIZE / size);
+	this_car.speed = 0;
+
+	if (rank == 0) {
+		track = malloc(sizeof(char) * TRACK_SIZE);
+		if (!track) {
+			fprintf(stderr, "Unable to allocate track array.\n");
+			return -1;
+		}
+	}
+
+	for (;;) {
+		drive(&this_car, rank, size);
+		if (rank == 0) {
+			int i, position;
+			MPI_Status status;
+
+			memset(track, 0, TRACK_SIZE * sizeof(char));
+			track[this_car.track_pos] = '0';
+			for (i=1;i<size;i++) {
+				MPI_Recv(&position, 1, MPI_INT, i, 60, MPI_COMM_WORLD, &status);
+				if (i < 10) {
+					track[position] = 0x30 + i;
+				} else {
+					track[position] = 'A' + (i-10);
+				}
+			}
+			for (i=0;i<TRACK_SIZE;i++) {
+				if (track[i] != 0) {
+					printf("%c", track[i]);
+				} else {
+					printf("-");
+				}
+			}
+			fflush(stdout);
+			printf("\n\n");
+		} else {
+			MPI_Send(&this_car.track_pos, 1, MPI_INT, 0, 60, MPI_COMM_WORLD);
+		}
+		sleep(2);
+	}
+
+	if (rank == 0) {
+		free(track);
+	}
+
+	MPI_Finalize();
+
+	return 0;
+}
+
============================================================
--- aca319/Makefile	921c03d1193d872d536b97460b3b969fe41133c2
+++ aca319/Makefile	49250753195fb97c9c84f38dad22c24c53b12abe
@@ -1,7 +1,7 @@ LDFLAGS=-lpthread
 CC=gcc
 CFLAGS=-Wall -ggdb
 LDFLAGS=-lpthread
-PROGRAMS=lab1q1 lab1q2 lab2q1 lab2q2 lab3q1 lab3q2 lab3q3 lab4q1 lab4q1_up lab5q1 lab5q2 lab6q1 lab6q2 lab7q1 lab7q2 lab8q1 lab8q2
+PROGRAMS=lab1q1 lab1q2 lab2q1 lab2q2 lab3q1 lab3q2 lab3q3 lab4q1 lab4q1_up lab5q1 lab5q2 lab6q1 lab6q2 lab7q1 lab7q2 lab8q1 lab8q2 lab9q1

 all: $(PROGRAMS)

@@ -44,6 +44,9 @@ lab8q2: lab8q2.c
 lab8q2: lab8q2.c
 	mpicc $(CFLAGS) -lmpe -o lab8q2 lab8q2.c

+lab9q1: lab9q1.c
+	mpicc $(CFLAGS) -lmpe -o lab9q1 lab9q1.c
+
 lab4q1_up: lab4q1_up.o

 run_lab3q1:
@@ -73,6 +76,9 @@ run_lab8q2:
 run_lab8q2:
 	mpirun -machinefile machines -np 5 lab8q2

+run_lab9q1:
+	mpirun -machinefile machines -np 5 lab9q1
+
 clean:
 	rm -f *.o $(PROGRAMS)