Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <mpi.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
- struct Vector_clock {
- int rank;
- int nprocs;
- int *vc_mas;
- MPI_Comm comm;
- };
- struct Vector_clock *vc_create(MPI_Comm comm)
- {
- struct Vector_clock *vc = malloc(sizeof(*Vector_clock));
- if (!vc) return NULL;
- vc->comm = comm;
- MPI_Comm_size(comm, &vc->nprocs);
- MPI_Comm_rank(comm, &vc->rank);
- vc->vc_mas = malloc(sizeof(*(vc->vc_mas)) * vc->nprocs);
- if (!vc->vc_mas) {
- free(vc);
- return NULL;
- }
- for (int i = 0; i < vc->nprocs; i++)
- vc->vc_mas[i] = 0;
- return vc;
- }
- void vc_free(struct Vector_clock *vc)
- {
- free(vc->vc_mas);
- free(vc);
- }
- void vc_print_clock(Vector_clock *vc)
- {
- printf("\nrank %d clock: ", vc->rank);
- for (int i = 0; i < vc->vc_mas[i]; i++) printf("%d ", vc->vc_mas[i]);
- printf("\n");
- }
- void vc_event(Vector_clock *vc, char *event)
- {
- vc->vc_mas[vc->rank]++;
- printf("rank %d event '%s' time %d\n", vc->rank, event, vc->vc_mas[vc->rank]);
- }
- int ds_send(Vector_clock *vc, void *buf, int count, MPI_Datatype datatype, int dest, int tag)
- {
- int userbuf_size, clockbuf_size, packbuf_size;
- MPI_Pack_size(count, datatype, vc->comm, &userbuf_size);
- MPI_Pack_size(vc->nprocs, MPI_INT, vc->comm, &clockbuf_size);
- packbuf_size = userbuf_size + clockbuf_size;
- char *outbuf = malloc(sizeof(*buf) * packbuf_size);
- if (NULL == outbuf) {
- fprintf(stderr, "error: no enough memory\n");
- MPI_Abort(ds->comm, EXIT_FAILURE);
- }
- int position = 0;
- MPI_Pack(buf, count, datatype, outbuf, packbuf_size, &position, ds->comm);
- MPI_Pack(ds->vc_mas, ds->nprocs, MPI_INT, outbuf, packbuf_size, &position, ds->comm);
- MPI_Send(outbuf, position, MPI_PACKED, dest, tag, ds->comm);
- free(outbuf);
- }
- int ds_recv(ds_t *ds, void *buf, int count, MPI_Datatype datatype, int src, int tag)
- {
- int userbuf_size, clockbuf_size, packbuf_size, comm_size;
- MPI_Pack_size(count, datatype, ds->comm, &userbuf_size);
- MPI_Pack_size(ds->nprocs, MPI_INT, ds->comm, &clockbuf_size);
- packbuf_size = userbuf_size + clockbuf_size;
- char *inbuf = malloc(sizeof(*buf) * packbuf_size);
- int *vc = malloc(sizeof(*vc) * ds->nprocs);
- if (NULL == inbuf || NULL == vc) {
- fprintf(stderr, "error: no enough memory\n");
- MPI_Abort(ds->comm, EXIT_FAILURE);
- }
- MPI_Recv(inbuf, packbuf_size, MPI_PACKED, src, tag, ds->comm, MPI_STATUS_IGNORE);
- int position = 0;
- MPI_Unpack(inbuf, packbuf_size, &position, buf, count, datatype, ds->comm);
- MPI_Unpack(inbuf, packbuf_size, &position, vc, ds->nprocs, MPI_INT, ds->comm);
- free(inbuf);
- for (int i = 0; i < ds->nprocs; i++) {
- ds->vc_mas[i] = vc[i] > ds->vc_mas[i] ? vc[i] : ds->vc_mas[i];
- }
- ds->vc_mas[ds->rank]++;
- free(vc);
- }
- int main(int argc, char **argv)
- {
- MPI_Comm comm = MPI_COMM_WORLD;
- int rank, buf;
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(comm, &rank);
- ds_t *ds = ds_create(comm);
- if (rank != 0)
- ds_recv(ds, &buf, 1, MPI_INT, (rank - 1)/2, 0)
- else
- buf = rank;
- ds_event(ds, "event1");
- ds_event(ds, "event2");
- ds_event(ds, "event3");
- if (ds->nprocs > rank * 2 + 1) ds_send(ds, &buf, 1, MPI_INT, rank * 2 + 1, 0);
- if (ds->nprocs > rank * 2 + 2) ds_send(ds, &buf, 1, MPI_INT, rank * 2 + 2, 0);
- ds_free(ds);
- MPI_Finalize();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement