blob: ebd70b5027e5631fbf26e531ba7efb26241a16fc [file] [log] [blame]
#include <stdbool.h>
#include "comm-schedule.h"
#ifdef DEBUG
static bool debug = true;
#else
static bool debug = false;
#endif
static void print_schedule(comm_schedule_t *schedule)
{
int global_self;
int self;
MPI_Aint lb;
MPI_Aint extent;
MPI_Comm_rank(MPI_COMM_WORLD, &global_self);
MPI_Comm_rank(schedule->comm, &self);
MPI_Type_get_extent(schedule->type, &lb, &extent);
fprintf(stderr,
"%d: schedule=%p, comm=%p, "
"type=%p(lb=%ld, extent=%ld), count=%d, %d %s %d\n",
global_self,
schedule,
(void *) schedule->comm,
(void *) schedule->type,
(long) lb,
(long) extent,
schedule->count,
self,
schedule->direction == COMM_SCHEDULE_SEND ? " -> " : " <- ",
schedule->peer);
}
comm_schedule_t *comm_schedule_append(comm_schedule_t *schedule,
MPI_Comm comm,
int peer,
int direction,
void *addr,
MPI_Datatype type,
int count)
{
comm_schedule_t *new_schedule;
new_schedule = (comm_schedule_t *) malloc(sizeof(comm_schedule_t));
if (!new_schedule) {
perror("out of memory");
}
new_schedule->next = NULL;
new_schedule->comm = comm;
new_schedule->peer = peer;
new_schedule->direction = direction;
new_schedule->addr = addr;
MPI_Type_dup(type, &new_schedule->type);
new_schedule->count = count;
new_schedule->req = MPI_REQUEST_NULL;
if (schedule == NULL) {
schedule = new_schedule;
} else {
comm_schedule_t *p = schedule;
while (p->next) {
p = p->next;
}
p->next = new_schedule;
}
return schedule;
}
comm_schedule_t *comm_schedule_prepend(comm_schedule_t *schedule,
MPI_Comm comm,
int peer,
int direction,
void *addr,
MPI_Datatype type,
int count)
{
comm_schedule_t *new_schedule;
new_schedule = (comm_schedule_t *) malloc(sizeof(comm_schedule_t));
if (!new_schedule) {
perror("out of memory");
}
new_schedule->next = schedule;
new_schedule->comm = comm;
new_schedule->peer = peer;
new_schedule->direction = direction;
new_schedule->addr = addr;
MPI_Type_dup(type, &new_schedule->type);
new_schedule->count = count;
new_schedule->req = MPI_REQUEST_NULL;
return new_schedule;
}
void comm_schedule_free(comm_schedule_t *schedule)
{
while (schedule) {
comm_schedule_t *s = schedule->next;
MPI_Type_free(&schedule->type);
free(schedule);
schedule = s;
}
}
void comm_schedule_start(comm_schedule_t *schedule)
{
for (comm_schedule_t *s = schedule; s; s = s->next) {
if (debug) {
print_schedule(s);
}
if (s->direction == COMM_SCHEDULE_SEND) {
MPI_Isend(s->addr, s->count, s->type, s->peer, 0, s->comm, &s->req);
} else if (s->direction == COMM_SCHEDULE_RECV) {
MPI_Irecv(s->addr, s->count, s->type, s->peer, 0, s->comm, &s->req);
} else {
perror("unknown direction in communication schedule");
}
}
}
void comm_schedule_progress(comm_schedule_t *schedule)
{
for (comm_schedule_t *s = schedule; s; s = s->next) {
int flag;
MPI_Test(&s->req, &flag, MPI_STATUS_IGNORE);
}
}
void comm_schedule_wait(comm_schedule_t *schedule)
{
MPI_Request array_of_requests[256];
int i;
i = 0;
for (comm_schedule_t *s = schedule; s; s = s->next) {
array_of_requests[i] = s -> req;
i = i + 1;
}
MPI_Waitall( i, array_of_requests, MPI_STATUSES_IGNORE );
//for (comm_schedule_t *s = schedule; s; s = s->next) {
// MPI_Wait(&s->req, MPI_STATUS_IGNORE);
//}
}
void comm_schedule_execute(comm_schedule_t *schedule)
{
comm_schedule_start(schedule);
comm_schedule_wait(schedule);
}