Blame test/mpi/cxx/coll/alltoallw2x.cxx

Packit Service c5cf8c
/* -*- Mode: C++; c-basic-offset:4 ; -*- */
Packit Service c5cf8c
/*
Packit Service c5cf8c
 *  (C) 2001 by Argonne National Laboratory.
Packit Service c5cf8c
 *      See COPYRIGHT in top-level directory.
Packit Service c5cf8c
 */
Packit Service c5cf8c
#include "mpi.h"
Packit Service c5cf8c
#include "mpitestconf.h"
Packit Service c5cf8c
#ifdef HAVE_IOSTREAM
Packit Service c5cf8c
// Not all C++ compilers have iostream instead of iostream.h
Packit Service c5cf8c
#include <iostream>
Packit Service c5cf8c
#ifdef HAVE_NAMESPACE_STD
Packit Service c5cf8c
// Those that do often need the std namespace; otherwise, a bare "cout"
Packit Service c5cf8c
// is likely to fail to compile
Packit Service c5cf8c
using namespace std;
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#else
Packit Service c5cf8c
#include <iostream.h>
Packit Service c5cf8c
#endif
Packit Service c5cf8c
#include "mpitestcxx.h"
Packit Service c5cf8c
Packit Service c5cf8c
/*
Packit Service c5cf8c
  This program tests MPI_Alltoallw by having processor i send different
Packit Service c5cf8c
  amounts of data to each processor.  This is just the MPI_Alltoallv test,
Packit Service c5cf8c
  but with displacements in bytes rather than units of the datatype.
Packit Service c5cf8c
Packit Service c5cf8c
  Because there are separate send and receive types to alltoallw,
Packit Service c5cf8c
  there need to be tests to rearrange data on the fly.  Not done yet.
Packit Service c5cf8c
Packit Service c5cf8c
  The first test sends i items to processor i from all processors.
Packit Service c5cf8c
Packit Service c5cf8c
  Currently, the test uses only MPI_INT; this is adequate for testing systems
Packit Service c5cf8c
  that use point-to-point operations
Packit Service c5cf8c
 */
Packit Service c5cf8c
Packit Service c5cf8c
int main(int argc, char **argv)
Packit Service c5cf8c
{
Packit Service c5cf8c
    MPI::Intracomm comm;
Packit Service c5cf8c
    int *sbuf, *rbuf;
Packit Service c5cf8c
    int rank, size;
Packit Service c5cf8c
    int *sendcounts, *recvcounts, *rdispls, *sdispls;
Packit Service c5cf8c
    int i, j, *p, err;
Packit Service c5cf8c
    MPI::Datatype * sendtypes, *recvtypes;
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Init();
Packit Service c5cf8c
    err = 0;
Packit Service c5cf8c
Packit Service c5cf8c
    while (MTestGetIntracommGeneral(comm, 2, true)) {
Packit Service c5cf8c
        if (comm == MPI::COMM_NULL)
Packit Service c5cf8c
            continue;
Packit Service c5cf8c
Packit Service c5cf8c
        /* Create the buffer */
Packit Service c5cf8c
        size = comm.Get_size();
Packit Service c5cf8c
        rank = comm.Get_rank();
Packit Service c5cf8c
        sbuf = new int[size * size];
Packit Service c5cf8c
        rbuf = new int[size * size];
Packit Service c5cf8c
        if (!sbuf || !rbuf) {
Packit Service c5cf8c
            cout << "Could not allocate buffers!\n";
Packit Service c5cf8c
            comm.Abort(1);
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        /* Load up the buffers */
Packit Service c5cf8c
        for (i = 0; i < size * size; i++) {
Packit Service c5cf8c
            sbuf[i] = i + 100 * rank;
Packit Service c5cf8c
            rbuf[i] = -i;
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        /* Create and load the arguments to alltoallv */
Packit Service c5cf8c
        sendcounts = new int[size];
Packit Service c5cf8c
        recvcounts = new int[size];
Packit Service c5cf8c
        rdispls = new int[size];
Packit Service c5cf8c
        sdispls = new int[size];
Packit Service c5cf8c
        sendtypes = new MPI::Datatype[size];
Packit Service c5cf8c
        recvtypes = new MPI::Datatype[size];
Packit Service c5cf8c
        if (!sendcounts || !recvcounts || !rdispls || !sdispls || !sendtypes || !recvtypes) {
Packit Service c5cf8c
            cout << "Could not allocate arg items!\n";
Packit Service c5cf8c
            comm.Abort(1);
Packit Service c5cf8c
        }
Packit Service c5cf8c
        /* Note that process 0 sends no data (sendcounts[0] = 0) */
Packit Service c5cf8c
        for (i = 0; i < size; i++) {
Packit Service c5cf8c
            sendcounts[i] = i;
Packit Service c5cf8c
            recvcounts[i] = rank;
Packit Service c5cf8c
            rdispls[i] = i * rank * sizeof(int);
Packit Service c5cf8c
            sdispls[i] = (((i + 1) * (i)) / 2) * sizeof(int);
Packit Service c5cf8c
            sendtypes[i] = recvtypes[i] = MPI::INT;
Packit Service c5cf8c
        }
Packit Service c5cf8c
        comm.Alltoallw(sbuf, sendcounts, sdispls, sendtypes, rbuf, recvcounts, rdispls, recvtypes);
Packit Service c5cf8c
Packit Service c5cf8c
        /* Check rbuf */
Packit Service c5cf8c
        for (i = 0; i < size; i++) {
Packit Service c5cf8c
            p = rbuf + rdispls[i] / sizeof(int);
Packit Service c5cf8c
            for (j = 0; j < rank; j++) {
Packit Service c5cf8c
                if (p[j] != i * 100 + (rank * (rank + 1)) / 2 + j) {
Packit Service c5cf8c
                    cout << "[" << rank << "] got " << p[j] << " expected " <<
Packit Service c5cf8c
                        (i * (i + 1)) / 2 + j << " for " << j << "th\n";
Packit Service c5cf8c
                    err++;
Packit Service c5cf8c
                }
Packit Service c5cf8c
            }
Packit Service c5cf8c
        }
Packit Service c5cf8c
Packit Service c5cf8c
        delete[]sendtypes;
Packit Service c5cf8c
        delete[]recvtypes;
Packit Service c5cf8c
        delete[]sdispls;
Packit Service c5cf8c
        delete[]rdispls;
Packit Service c5cf8c
        delete[]recvcounts;
Packit Service c5cf8c
        delete[]sendcounts;
Packit Service c5cf8c
        delete[]rbuf;
Packit Service c5cf8c
        delete[]sbuf;
Packit Service c5cf8c
        MTestFreeComm(comm);
Packit Service c5cf8c
    }
Packit Service c5cf8c
Packit Service c5cf8c
    MTest_Finalize(err);
Packit Service c5cf8c
    return 0;
Packit Service c5cf8c
}