char *
avtSamplePointCommunicator::CommunicateMessages(char **sendmessages,
                                                int   *sendcount,
                                                char **recvmessages,
                                                int   *recvcount)
{
#ifdef PARALLEL
    //
    // Figure out how much each processor needs to send/receive.
    //
    MPI_Alltoall(sendcount, 1, MPI_INT, recvcount, 1, MPI_INT, VISIT_MPI_COMM);

    //
    // Create a buffer we can receive into.
    //
    char *recvConcatList = CreateMessageStrings(recvmessages, recvcount,
                                                numProcs);
    
    //
    // Calculate the displacement lists.
    //
    int *senddisp = new int[numProcs];
    int *recvdisp = new int[numProcs];
    senddisp[0] = 0;
    recvdisp[0] = 0;
    for (int i = 1 ; i < numProcs ; i++)
    {
        senddisp[i] = senddisp[i-1] + sendcount[i-1];
        recvdisp[i] = recvdisp[i-1] + recvcount[i-1];
    }

    //
    // Do the actual transfer of sample points.   The messages arrays are
    // actually indexes into one big array.  Since MPI expects that big
    // array, give that (which is at location 0).
    //
    MPI_Alltoallv(sendmessages[0], sendcount, senddisp, MPI_CHAR,
                  recvmessages[0], recvcount, recvdisp, MPI_CHAR,
                  VISIT_MPI_COMM);

    delete [] senddisp;
    delete [] recvdisp;

    //
    // We need to return this buffer so the calling function can delete it.
    //
    return recvConcatList;
#else
    return 0;
#endif
}
Example #2
0
char *
avtCellList::ConstructMessages(avtImagePartition *part, char **msgs, int *lens)
{
    int  numPartitions = part->GetNumPartitions();

    int storageForCoord = 3;
    const int bytesPerNode = (storageForCoord+nVars)*sizeof(double); 
    int storageForBBox = 6;
    const int bytesForCellThatIsAPt = (storageForBBox+nVars)*sizeof(double);

    //
    // Set up memory to put our messages into.
    //
    for (long long i = 0 ; i < numPartitions ; ++i)
    {
        lens[i] = 0;
    }
    int *partitions = new int[numPartitions];
    for (long long i = 0 ; i < celllistI ; ++i)
    {
        //
        // PartitionList will make a list of the partitions that this cell
        // needs to be sent to.  It will place that list in `partitions'.
        //
        int numParts = part->PartitionList(celllist[i]->minx,celllist[i]->maxx,
                                           celllist[i]->miny,celllist[i]->maxy,
                                           partitions);
        int size = sizeof(int);
        if (celllist[i]->size > 1)
            size += bytesPerNode*celllist[i]->size;
        else
            size += bytesForCellThatIsAPt;
        for (int j = 0 ; j < numParts ; j++)
        {
            lens[partitions[j]] += size;
        }
    }
    char *rv = CreateMessageStrings(msgs, lens, numPartitions);
    char **msgstemp = new char*[numPartitions];
    for (long long i = 0 ; i < numPartitions ; ++i)
    {
        msgstemp[i] = msgs[i];
    }

    //
    // Go through our cell list and add each cell to the appropriate message.
    //
    for (long long i = 0 ; i < celllistI ; ++i)
    {
        int numParts = part->PartitionList(celllist[i]->minx,celllist[i]->maxx,
                                           celllist[i]->miny,celllist[i]->maxy,
                                           partitions);
        for (int j = 0 ; j < numParts ; j++)
        {
            int p = partitions[j];
            InlineCopy(msgstemp[p], (char *)&(celllist[i]->size), sizeof(int));
            int size;
            if (celllist[i]->size > 1)
                size = bytesPerNode*celllist[i]->size;
            else
                size = bytesForCellThatIsAPt;

            InlineCopy(msgstemp[p], celllist[i]->cell, size);
        }
    }

    delete [] msgstemp;
    delete [] partitions;

    return rv;
}