Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <mpi.h>
- #include <string.h>
- typedef struct buffers_s
- {
- double *buf1;
- double *buf2;
- int size;
- } Buffers;
- void BuffersMPI(Buffers *buf, MPI_Datatype *bufmpi)
- {
- int block_lengths[2]; // # of elt. in each block
- MPI_Aint displacements[2]; // displac.
- MPI_Datatype typelist[2]; // list of types
- MPI_Aint start_address, address; // use for calculating displac.
- MPI_Datatype myType;
- block_lengths[0] = buf->size;
- block_lengths[1] = buf->size;
- typelist[0] = MPI_DOUBLE;
- typelist[1] = MPI_DOUBLE;
- displacements[0] = 0;
- MPI_Address(buf->buf1, &start_address);
- MPI_Address(buf->buf2, &address);
- displacements[1] = address - start_address;
- MPI_Type_struct(2,block_lengths, displacements,typelist,bufmpi);
- MPI_Type_commit(bufmpi);
- }
- void buffersmpisum(Buffers *in, Buffers *out, int *len, MPI_Datatype *typeptr)
- {
- int i;
- for (i=0; i < *len; i++)
- {
- out->buf1[i] += in->buf1[i];
- out->buf2[i] += in->buf2[i];
- }
- }
- int main(int argc, char **argv)
- {
- Buffers buffers_1, buffers_2;
- double *pack, *unpack;
- double size;
- double start, end;
- int pos;
- int i;
- int rank;
- int cnt;
- int ierr;
- MPI_Datatype Buffers_mpi;
- MPI_Op buffersumop;
- MPI_Init(&argc, &argv);
- MPI_Comm_rank(MPI_COMM_WORLD, &rank);
- cnt = 100000;
- size = 10;
- buffers_1.buf1 = calloc(size, sizeof *buffers_1.buf1);
- buffers_1.buf2 = calloc(size, sizeof *buffers_1.buf2);
- buffers_2.buf1 = calloc(size, sizeof *buffers_2.buf1);
- buffers_2.buf2 = calloc(size, sizeof *buffers_2.buf2);
- pack = calloc(3*size, sizeof *pack);
- unpack = calloc(3*size, sizeof *unpack);
- for (i=0; i<size; i++)
- {
- buffers_1.buf1[i] = 2;
- buffers_1.buf2[i] = 4;
- }
- MPI_Barrier(MPI_COMM_WORLD);
- // ============================================================================
- // TWO CONSECUTIVE REDUCTIONS
- // ============================================================================
- start = MPI_Wtime();
- for (i=0; i< cnt; i++)
- {
- MPI_Reduce(buffers_1.buf1, // send buffer
- buffers_2.buf1, // reduced data goes here
- size, // size of the buffers
- MPI_DOUBLE, // type of the data
- MPI_SUM, // operation
- 0, // proc 0 only will recieve data
- MPI_COMM_WORLD); // all procs do the reduction
- MPI_Reduce(buffers_1.buf2, // send buffer
- buffers_2.buf2, // reduced data goes here
- size, // size of the buffers
- MPI_DOUBLE, // type of the data
- MPI_SUM, // operation
- 0, // proc 0 only will recieve data
- MPI_COMM_WORLD); // all procs do the reduction
- }
- end = MPI_Wtime();
- if(rank==0)
- {
- printf("%f seconds\n", end-start);
- }
- // empty bufffers_2
- memset(buffers_2.buf1, 0, size * sizeof *buffers_2.buf1);
- memset(buffers_2.buf2, 0, size * sizeof *buffers_2.buf2);
- // ============================================================================
- // PACK/UNPACK
- // ============================================================================
- MPI_Barrier(MPI_COMM_WORLD);
- start = MPI_Wtime();
- for(i=0; i < cnt; i++)
- {
- pos = 0; // start to pack at pack+0
- ierr = MPI_Pack(buffers_1.buf1, // data to be packed
- size, // size of buf1
- MPI_DOUBLE, // type of these elements
- pack, // start adress of the pack
- 2*size*sizeof *pack, // size of the pack buffer
- &pos, // pack+pos is the start position
- MPI_COMM_WORLD); // every proc will use 'pack'
- // pack the second buffer
- MPI_Pack(buffers_1.buf2, // data to be packed
- size, // size of buf1
- MPI_DOUBLE, // type of these elements
- pack, // start adress of the pack
- 2*size*sizeof *pack, // size of the pack buffer
- &pos, // pack+pos is the start position
- MPI_COMM_WORLD); // every proc will use 'pack'
- // now reduce the pack
- MPI_Reduce(pack, // send buffer
- unpack, // reduced data goes here
- 2*size, // size of the buffers
- MPI_DOUBLE, // type of the data
- MPI_SUM, // operation
- 0, // proc 0 only will recieve data
- MPI_COMM_WORLD); // all procs do the reduction
- }
- end = MPI_Wtime();
- if(rank==0)
- {
- printf("%f seconds\n", end-start);
- }
- if (rank == 0)
- {
- for (i=0; i<2*size; i++)
- {
- printf("unpack[%d] = %f\n",i,unpack[i]);
- }
- }
- // empty buffers_2
- memset(buffers_2.buf1, 0, size * sizeof *buffers_2.buf1);
- memset(buffers_2.buf2, 0, size * sizeof *buffers_2.buf2);
- // ============================================================================
- // MPI_Type_struct
- // ============================================================================
- MPI_Barrier(MPI_COMM_WORLD);
- start = MPI_Wtime();
- BuffersMPI(&buffers_1, &Buffers_mpi);
- ierr = MPI_Op_create((MPI_User_function *)buffersmpisum,1,&buffersumop);
- if (ierr == MPI_SUCCESS) printf("op create success\n");
- for (i=0; i<cnt; i++)
- {
- MPI_Reduce(&buffers_1, // send buffer
- &buffers_2, // reduced data goes here
- size, // size of the buffers
- Buffers_mpi, // type of the data
- buffersumop, // operation
- 0, // proc 0 only will recieve data
- MPI_COMM_WORLD); // all procs do the reduction
- }
- end = MPI_Wtime();
- if(rank==0)
- {
- printf("%f seconds\n", end-start);
- }
- if (rank == 0)
- {
- for (i=0; i< size; i++)
- {
- printf("buffers_2.buf1[%d] = %f \t buffers_2.buf2[%d] = %f\n",
- i,buffers_2.buf1[i], i, buffers_2.buf2[i]);
- }
- }
- free(buffers_1.buf1);
- free(buffers_1.buf2);
- free(buffers_2.buf1);
- free(buffers_2.buf2);
- free(pack);
- free(unpack);
- MPI_Finalize();
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement