Cloned SEACAS for EXODUS library with extra build files for internal package management.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1266 lines
40 KiB

2 years ago
<!-------- @HEADER
!
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! Zoltan Toolkit for Load-balancing, Partitioning, Ordering and Coloring
! Copyright 2012 Sandia Corporation
!
! Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
! the U.S. Government retains certain rights in this software.
!
! Redistribution and use in source and binary forms, with or without
! modification, are permitted provided that the following conditions are
! met:
!
! 1. Redistributions of source code must retain the above copyright
! notice, this list of conditions and the following disclaimer.
!
! 2. Redistributions in binary form must reproduce the above copyright
! notice, this list of conditions and the following disclaimer in the
! documentation and/or other materials provided with the distribution.
!
! 3. Neither the name of the Corporation nor the names of the
! contributors may be used to endorse or promote products derived from
! this software without specific prior written permission.
!
! THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
! EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
! IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
! PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
! CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
! EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
! PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
! PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
! LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
! NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
! SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
!
! Questions? Contact Karen Devine kddevin@sandia.gov
! Erik Boman egboman@sandia.gov
!
! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!
! @HEADER
------->
<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<meta name="GENERATOR" content="Mozilla/4.7 [en] (X11; U; SunOS 5.6 sun4m) [Netscape]">
<meta name="sandia.approval_type" content="formal">
<meta name="sandia.approved" content="SAND2007-4748W">
<meta name="author" content="Zoltan PI">
<title> Zoltan User's Guide: Communication Utilities</title>
</head>
<body bgcolor="#FFFFFF">
<div align=right><b><i><a href="ug.html">&nbsp;Zoltan User's Guide</a>&nbsp;
|&nbsp; <a href="ug_util_dd.html">Next</a>&nbsp; |&nbsp; <a href="ug_util_mem.html">Previous</a></i></b></div>
<!------------------------------------------------------------------------->
<h2>
Unstructured Communication Utilities</h2>
The unstructured communication package provides a simple interface for
doing complicated patterns of point-to-point communication, such as those
associated with data remapping. This package consists of a few simple functions
which create or modify communication <i>plans</i>, perform communication,
and destroy communication plans upon completion. The package is descended
from software first developed by Steve Plimpton and Bruce Hendrickson,
and has proved useful in a variety of different applications. For this
reason, it is maintained as a separate library and can be used independently
from Zoltan.
<p>In a prototypical usage of the unstructured communication package each
processor has some objects to send to other processors, but no processor
knows what messages it will receive. A call to
<b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>
produces a data structure called a communication <i>plan</i> which encapsulates
the basic information about the communication operation. The plan does
not know anything about the types of objects being transferred, only the
number of them. So the same plan can be used repeatedly to transfer different
types of data as long as the number of objects in the transfers remains
the same. The actual size of objects isn't specified until the call to
<b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>
which performs the data transfer.
<p>The plan which is produced by
<b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>
assumes that all the objects are of the same size. If this is not true,
then a call to <b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize</a></b> can
specify the actual size of each object, and the plan is augmented appropriately.
<b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize</a></b>
can be invoked repeatedly on the same plan to specify varying sizes for
different data transfer operations.
<p>Although a friendlier interface may be added in the future, for now
the data to be sent must be passed to
<b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>
as a packed buffer in which the objects are stored consecutively. This
probably requires the application to pull the data out of native data structures
and place in into the buffer. The destination of each object is specified
by the <i>proclist</i> argument to <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.
Some flexibility is supported by allowing <i>proclist</i> to contain negative
values, indicating that the corresponding objects are not to be sent. The
communication operations allow for any object to be sent to any destination
processor. However, if the objects are grouped in such a way that all those
being sent to a particular processor are consecutive, the time and
memory of an additional copy is avoided.
<p> Function
<b><a href="#Zoltan_Comm_Do_Reverse">Zoltan_Comm_Do_Reverse</a></b>
reverses the communication plan to send back messages to the originators.
<p> To allow overlap between communication and processing, POST and WAIT
variants of
<b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>
and
<b><a href="#Zoltan_Comm_Do_Reverse">Zoltan_Comm_Do_Reverse</a></b>
are provided. Communication is initiated by the POST function
(<b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do_Post</a></b> or
<b><a href="#Zoltan_Comm_Do_Reverse">Zoltan_Comm_Do_Reverse_Post</a></b>);
incoming messages are posted and outgoing messages are sent.
Then the user can continue processing.
After the processing is complete, the corresponding WAIT function
(<b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do_Wait</a></b> or
<b><a href="#Zoltan_Comm_Do_Reverse">Zoltan_Comm_Do_Reverse_Wait</a></b>)
is called to wait for all incoming messages to be received.
For convenience,
these functions use the same calling
arguments as
<b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b> and
<b><a href="#Zoltan_Comm_Do_Reverse">Zoltan_Comm_Do_Reverse</a></b>.
<p>All the functions in the unstructured communication library return integer
<a href="../ug_html/ug_interface.html#Error Codes">error codes</a> identical to
those used by Zoltan.
<p>
The C++ interface to the unstructured communication utility is found
in the <I>zoltan_comm_cpp.h</I> header file which defines the
<B>Zoltan_Comm</B> class.
<p>
A Fortran90 interface is not yet available.
<p>
<hr>
<table>
<tr VALIGN=TOP>
<td WIDTH="50%"><b>Source code location:</b></td>
<td WIDTH="50%"><i>Utilities/Communication</i></td>
</tr>
<tr VALIGN=TOP>
<td><b>C Function prototypes file:</b></td>
<td><i>Utilities/Communication/zoltan_comm.h</i>
</td>
</tr>
<tr VALIGN=TOP>
<td><b>C++ class definition:</b></td>
<td><i>Utilities/Communication/zoltan_comm_cpp.h</i>
</td>
</tr>
<tr VALIGN=TOP>
<td><b>Library name:</b></td>
<td>libzoltan_comm.a</td>
</tr>
<tr VALIGN=TOP>
<td><b>Other libraries used by this library:</b></td>
<td>libmpi.a, <a href="ug_util_mem.html">libzoltan_mem.a</a>.</td>
</tr>
<tr VALIGN=TOP>
<td COLSPAN="2"><b>High Level Routines:</b>
<blockquote><b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a>:&nbsp; </b>computes
a communication plan for sending objects to destination processors.
<br><b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a>:&nbsp; </b>uses a communication
plan to send data objects to destination processors.&nbsp; The POST and WAIT variants
are
<br>&nbsp;&nbsp;&nbsp;&nbsp;<b><a href="#Zoltan_Comm_Do_Post">Zoltan_Comm_Do_Post</a></b> and
<br>&nbsp;&nbsp;&nbsp;&nbsp;<b><a href="#Zoltan_Comm_Do_Wait">Zoltan_Comm_Do_Wait</a>. </b>
<br><b><a href="#Zoltan_Comm_Do_Reverse">Zoltan_Comm_Do_Reverse</a>:&nbsp;</b>
performs the reverse (opposite) communication of <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>.
&nbsp;The POST and WAIT variants are
<br>&nbsp;&nbsp;&nbsp;&nbsp;<b><a href="#Zoltan_Comm_Do_Reverse_Post">Zoltan_Comm_Do_Reverse_Post</a></b> and
<br>&nbsp;&nbsp;&nbsp;&nbsp;<b><a href="#Zoltan_Comm_Do_Reverse_Wait">Zoltan_Comm_Do_Reverse_Wait</a>.</b>
<br><b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize</a>:&nbsp; </b>augments
the plan to allow objects to be of variable sizes.&nbsp;
<br><b><a href="#Zoltan_Comm_Copy">Zoltan_Comm_Copy</a>:</b>&nbsp; create a new
communication plan and copy an existing one to it.&nbsp;
<br><b><a href="#Zoltan_Comm_Copy_To">Zoltan_Comm_Copy_To</a>:</b>&nbsp; copy
one existing communication plan to another.&nbsp;
<br><b><a href="#Zoltan_Comm_Destroy">Zoltan_Comm_Destroy</a>:</b>&nbsp; free memory
associated with a communication plan.&nbsp;</blockquote>
<b>Low Level Routines:</b>
<blockquote><b><a href="#Zoltan_Comm_Exchange_Sizes">Zoltan_Comm_Exchange_Sizes</a>:
</b>updates the sizes of the messages each processor will receive.
<br><b><a href="#Zoltan_Comm_Invert_Map">Zoltan_Comm_Invert_Map</a>:&nbsp; </b>given
a set of messages each processor wants to send, determines the set of messages
each processor needs to receive.
<br><b><a href="#Zoltan_Comm_Sort_Ints">Zoltan_Comm_Sort_Ints</a>:&nbsp; </b>sorts
an array of integer values.&nbsp;
<br><b><a href="#Zoltan_Comm_Info">Zoltan_Comm_Info</a>:&nbsp; </b>returns information about a communication plan.
<br><b><a href="#Zoltan_Comm_Invert_Plan">Zoltan_Comm_Invert_Plan</a>:&nbsp; </b>given a communication plan, converts the plan into a plan for the reverse communication.
</blockquote>
</td>
</tr>
<tr VALIGN=TOP>
<td COLSPAN="2"><b>Use in Zoltan:</b>
<blockquote>The Zoltan library uses the unstructured communication package
in its migration tools and in some of the load-balancing algorithms. For
example, in <b><a href="../ug_html/ug_interface_mig.html#Zoltan_Migrate">Zoltan_Migrate</a></b>,
<b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>
is used to develop a communication map for sending objects to be exported
to their new destination processors. The sizes of the exported objects are
obtained and the communication map is augmented with a call to
<a href="#Zoltan_Comm_Resize"><b>Zoltan_Comm_Resize</b></a>.
The data for the objects is packed
into a communication buffer and sent to the other processors through a
call to <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>. After the received
objects are unpacked, the communication plan is no longer needed, and it
is deallocated by a call to
<b><a href="#Zoltan_Comm_Destroy">Zoltan_Comm_Destroy</a></b>.
Zoltan developers use the package whenever possible, as improvements made
to the package (for example, support for heterogeneous architectures)
automatically propagate to the algorithms.&nbsp;</blockquote>
</td>
</tr>
</table>
<!------------------------------------------------------------------------->
<hr> <hr>
<b>C:</b><br>
<a NAME="Zoltan_Comm_Create"></a>
int <b>Zoltan_Comm_Create</b>(
struct Zoltan_Comm_Obj **<i>plan</i>,
int <i>nsend</i>,
int *<i>proclist</i>,
MPI_Comm <i>comm</i>,
int <i>tag</i>,
int *<i>nreturn</i>);
<br>
<b>C++:</b><br>
<b>Zoltan_Comm</b>(
const int & <i>nsend</i>,
int *<i>proclist</i>,
const MPI_Comm & <i>comm</i>,
const int & <i>tag</i>,
int *<i>nreturn</i>);
<br>
&nbsp;&nbsp;&nbsp;or
<br>
<b>Zoltan_Comm</b>();
<br>
<b>Zoltan_Comm::Create</b>(
const int & <i>nsend</i>,
int *<i>proclist</i>,
const MPI_Comm & <i>comm</i>,
const int & <i>tag</i>,
int *<i>nreturn</i>);
<hr>The <b>Zoltan_Comm_Create</b> function sets up the communication plan in
the unstructured communication package. Its input is a count of objects
to be sent to other processors, a list of the processors to which the objects
should be sent (repetitions are allowed), and an MPI communicator and tag.
It allocates and builds a communication plan that describes to which processors
data will be sent and from which processors data will be received. It also
computes the amount of data to be sent to and received from each processor.
It returns the number of objects to be received by the processor and a
pointer to the communication plan it created. The communication
plan is then used by calls to <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>
to perform the actual communication.
<br>&nbsp;
<table WIDTH="100%" NOSAVE >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; <i>plan</i></td>
<td>A pointer to the communication plan created by <b>Zoltan_Comm_Create</b>.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nsend</i></td>
<td>The number of objects to be sent to other processors.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; proclist</i></td>
<td>An array of size <i>nsend</i> of destination processor numbers for
each of the objects to be sent.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; comm</i></td>
<td>The MPI communicator for the unstructured communication.</td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; <i>tag</i></td>
<td>A tag for MPI communication.</td>
</tr>
<tr>
<td VALIGN=TOP>&nbsp;&nbsp;&nbsp; <i>nreturn</i></td>
<td>Upon return, the number of objects to be received by the processor.</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td VALIGN=TOP>&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<p>
In the C++ interface to the communication utility, the communication plan
is represented by a <B>Zoltan_Comm</B> object. It is created when the
<B>Zoltan_Comm</B> constructor executes. There are two constructors. The
first one listed above uses parameters to initialize the plan. The
second constructor does not, but the plan can subsequently be initialized
with a call to <B>Zoltan_Comm::Create()</B>.
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Do"></a>
<a NAME="Zoltan_Comm_Do_Post"></a>
<a NAME="Zoltan_Comm_Do_Wait"></a>
<hr>
<b>C:</b><br>
int <b>Zoltan_Comm_Do</b>(struct Zoltan_Comm_Obj *<i>plan</i>,
int <i>tag</i>, char *<i>send_data</i>, int <i>nbytes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm_Do_Post</b>(struct Zoltan_Comm_Obj *<i>plan</i>,
int <i>tag</i>, char *<i>send_data</i>, int <i>nbytes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm_Do_Wait</b>(struct Zoltan_Comm_Obj *<i>plan</i>,
int <i>tag</i>, char *<i>send_data</i>, int <i>nbytes</i>, char *<i>recvbuf</i>);&nbsp;
<br><b>C++:</b><br>
int <b>Zoltan_Comm::Do</b>(const int & <i>tag</i>, char *<i>send_data</i>, const int & <i>nbytes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm::Do_Post</b>(const int & <i>tag</i>, char *<i>send_data</i>, const int & <i>nbytes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm::Do_Wait</b>(const int & <i>tag</i>, char *<i>send_data</i>, const int & <i>nbytes</i>, char *<i>recvbuf</i>);&nbsp;
<hr>The <b>Zoltan_Comm_Do</b> function performs the communication described
in a communication plan built by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.
Using the plan, it takes a buffer of object data to be sent and the size
(in bytes) of each object's data in that buffer and sends the data to other
processors.
<b>Zoltan_Comm_Do</b> also receives object data from
other processors and stores it in a receive buffer.
The receive buffer must be allocated by the code
calling <b>Zoltan_Comm_Do</b> using the number of received objects returned
by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b> or <b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize</a></b>.
If the objects have variable sizes, then <b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize</a></b>
must be called before <b>Zoltan_Comm_Do</b>.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; plan</i></td>
<td>A pointer to a communication plan built by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.</td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; <i>tag</i></td>
<td>An MPI message tag.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; send_data</i></td>
<td>A buffer filled with object data to be sent to other processors.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nbytes</i></td>
<td>The size (in bytes) of the data for one object, or the scale factor
if the objects have variable sizes. (See <b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize
</a></b>for
more details.)</td>
</tr>
<tr>
<td VALIGN=TOP>&nbsp;&nbsp;&nbsp; <i>recvbuf</i></td>
<td>Upon return, a buffer filled with object data received from other processors.</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Do_Reverse"></a>
<a NAME="Zoltan_Comm_Do_Reverse_Post"></a>
<a NAME="Zoltan_Comm_Do_Reverse_Wait"></a>
<hr>
<b>C:</b><br>
int <b>Zoltan_Comm_Do_Reverse</b>(
struct Zoltan_Comm_Obj *<i>plan</i>, int <i>tag</i>, char *<i>send_data</i>, int <i>nbytes</i>,
int *<i>sizes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm_Do_Reverse_Post</b>(
struct Zoltan_Comm_Obj *<i>plan</i>, int <i>tag</i>, char *<i>send_data</i>, int <i>nbytes</i>,
int *<i>sizes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm_Do_Reverse_Wait</b>(
struct Zoltan_Comm_Obj *<i>plan</i>, int <i>tag</i>, char *<i>send_data</i>, int <i>nbytes</i>,
int *<i>sizes</i>, char *<i>recvbuf</i>);&nbsp;
<br><b>C++:</b><br>
int <b>Zoltan_Comm::Do_Reverse</b>(
const int & <i>tag</i>, char *<i>send_data</i>, const int & <i>nbytes</i>,
int *<i>sizes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm::Do_Reverse_Post</b>(
const int & <i>tag</i>, char *<i>send_data</i>, const int & <i>nbytes</i>,
int *<i>sizes</i>, char *<i>recvbuf</i>);&nbsp;
<br>
int <b>Zoltan_Comm::Do_Reverse_Wait</b>(
const int & <i>tag</i>, char *<i>send_data</i>, const int & <i>nbytes</i>,
int *<i>sizes</i>, char *<i>recvbuf</i>);&nbsp;
<hr>The <b>Zoltan_Comm_Do_Reverse</b> function performs communication based
on a communication plan built by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.
But unlike <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>, this routine performs
the reverse of the communication pattern. Specifically, all sends in the
plan are treated as receives and vice versa. <b>Zoltan_Comm_Do_Reverse</b>
is particularly well suited to return updated data objects to their originating
processors when the objects were initially transferred via
<b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; plan</i></td>
<td>A pointer to a communication plan built by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.</td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; <i>tag</i></td>
<td>An MPI message tag to be used by this routine.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; send_data</i></td>
<td>A buffer filled with object data to be sent to other processors.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nbytes</i></td>
<td>The size (in bytes) of the data associated with an object, or the scale
factor if the objects have variable sizes.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; sizes</i></td>
<td>If not NULL, this input array specifies the size of all the data objects
being transferred. This argument is passed directly to <b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize</a></b>.
This array has length equal to the <i>nsend</i> value passed to
<b>Zoltan_Comm_Create</b>.
But note that for <b>Zoltan_Comm_Do_Reverse</b> this array describes the sizes
of the values being received, not sent.</td>
</tr>
<tr>
<td VALIGN=TOP>&nbsp;&nbsp;&nbsp; <i>recvbuf</i></td>
<td>Upon return, a buffer filled with object data received from other processors.</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Resize"></a>
<hr>
<b>C:</b><br>
int <b>Zoltan_Comm_Resize</b>(
struct Zoltan_Comm_Obj *<i>plan</i>,
int *<i>sizes</i>, int <i>tag</i> , int *<i>total_recv_size</i>);&nbsp;
<br><b>C++:</b><br>
int <b>Zoltan_Comm::Resize</b>(
int *<i>sizes</i>, const int & <i>tag</i> , int *<i>total_recv_size</i>);&nbsp;
<hr>If the objects being communicated are of variable sizes, then the plan
produced by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b> is incomplete.
This routine allows the plan to be augmented to allow for variable sizes.
<b>Zoltan_Comm_Resize</b>
can be invoked repeatedly on the same plan to specify different object
sizes associated with different data transfers.
<br>&nbsp;
<table WIDTH="100%" NOSAVE >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; plan</i></td>
<td>A communication plan built by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; sizes</i></td>
<td>An input array of length equal to the <i>nsend</i> argument in the
call to <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b> which generated
the <i>plan</i>. Each entry in the array is the size of the corresponding
object to be sent. If <i>sizes</i> is <i>NULL </i>(on all processors),
the objects are considered to be the same size. Note that the true
size of a message will be scaled by the <i>nbytes</i> argument to <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>.&nbsp;</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; tag</i></td>
<td>A message tag to be used for communication within this routine, based
upon the communicator in <i>plan</i>.</td>
</tr>
<tr VALIGN=TOP NOSAVE>
<td>&nbsp;&nbsp;&nbsp; <i>total_recv_size</i></td>
<td NOSAVE>Sum of the sizes of the incoming messages. To get the actual
size (in bytes), you need to scale by the <i>nbytes</i> argument to <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>.&nbsp;</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Copy"></a>
<hr>
<b>C:</b>&nbsp; struct Zoltan_Comm_Obj *<b>Zoltan_Comm_Copy</b>(
struct Zoltan_Comm_Obj *<i>plan</i>);&nbsp;
<br><b>C++:</b>&nbsp; <b>Zoltan_Comm(const Zoltan_Comm &plan);</b>
<hr><b>Zoltan_Comm_Copy</b> creates a new Zoltan_Comm_Obj structure
and copies the existing <I>plan</I> to it.
The corresponding C++ method is the <b>Zoltan_Comm</b> copy
constructor.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; plan</i></td>
<td>A pointer to the communication plan to be copied to the new
Zoltan_Comm_Obj structure. &nbsp;</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; struct Zoltan_Comm_Obj *</td>
<td>the newly created plan, or NULL on error.</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Copy_To"></a>
<hr>
<b>C:</b>&nbsp; int <b>Zoltan_Comm_Copy_To</b>(
struct Zoltan_Comm_Obj **<i>to</i>,&nbsp;
struct Zoltan_Comm_Obj *<i>from</i>);&nbsp;
<br><b>C++:</b>&nbsp; Zoltan_Comm & &nbsp;<b>operator= </b>(const Zoltan_Comm &plan);</b>
<hr><b>Zoltan_Comm_Copy_To</b> copies one existing communication plan
to another.
The corresponding C++ method is the <b>Zoltan_Comm</b> copy operator.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; to</i></td>
<td>A pointer to a pointer to the communication plan that will
be copied to. We destroy the plan first, and set the pointer to
the plan to NULL, before proceeding with the copy.
&nbsp;</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; from</i></td>
<td>A pointer the communication plan that we will make a copy of.
&nbsp;</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Destroy"></a>
<hr>
<b>C:</b>&nbsp; int <b>Zoltan_Comm_Destroy</b>(
struct Zoltan_Comm_Obj **<i>plan</i>);&nbsp;
<br><b>C++:</b>&nbsp; <b>~Zoltan_Comm();</b>
<hr>The <b>Zoltan_Comm_Destroy</b> function frees all memory associated with
a communication plan created by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.
The C++ <b>Zoltan_Comm</b> object does not have an explicit <b>Destroy</b> method.
It is deallocated when its destructor is called.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; plan</i></td>
<td>A pointer to a communication plan built by <b><a href="#Zoltan_Comm_Create">Zoltan_Comm_Create</a></b>.&nbsp;
Upon return, <i>plan</i> is set to NULL.&nbsp;</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Exchange_Sizes"></a>
<hr>
<b>C:</b><br>
int <b>Zoltan_Comm_Exchange_Sizes</b>(
int *<i>sizes_to</i>, int *<i>procs_to</i>, int <i>nsends</i>, int <i>self_msg</i>,
int *<i>sizes_from</i>, int *<i>procs_from</i>, int <i>nrecvs</i>, int
*<i>total_recv_size</i>, int <i>my_proc</i>, int <i>tag</i>, MPI_Comm <i>comm</i>
);&nbsp;
<br><b>C++:</b><br>
static int <b>Zoltan_Comm::Exchange_Sizes</b>(
int *<i>sizes_to</i>, int *<i>procs_to</i>,
const int & <i>nsends</i>, const int & <i>self_msg</i>,
int *<i>sizes_from</i>, int *<i>procs_from</i>, const int & <i>nrecvs</i>,
int *<i>total_recv_size</i>, const int & <i>my_proc</i>,
const int & <i>tag</i>, const MPI_Comm & <i>comm</i>
);&nbsp;
<hr>This routine is used by <b><a href="#Zoltan_Comm_Resize">Zoltan_Comm_Resize</a></b>
to update the sizes of the messages each processor is expecting to receive.
The processors already know who will send them messages, but if variable
sized objects are being communicated, then the sizes of the messages are
recomputed and exchanged via this routine.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; sizes_to</i></td>
<td>Input array with the size of each message to be sent. Note
that the actual number of bytes in the message is the product of this value
and the <i>nbytes</i> argument to <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; procs_to</i></td>
<td>Input array with the destination processor for each of the messages
to be sent.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nsends</i></td>
<td>Input argument with the number of messages to be sent. (Length
of the <i>procs_to</i> array.)</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; self_msg</i></td>
<td>Input argument indicating whether a processor has data for itself (=1) or not
(=0) within the <i>procs_to</i> and <i>lengths_to</i> arrays.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; sizes_from</i></td>
<td>Returned array with the size of each message that will be received. Note
that the actual number of bytes in the message is the product of this value
and the <i>nbytes</i> argument to <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; procs_from</i></td>
<td>Returned array of processors from which data will be received.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nrecvs</i></td>
<td>Returned value with number of messages to be received. (length of <i>procs_from</i>
array.)</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; total_recv_size</i></td>
<td>The total size of all the messages to be received. As above, the actual
number of bytes will be scaled by the <i>nbytes</i> argument to <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b>.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; my_proc</i></td>
<td>The processor's ID in the <i>comm</i> communicator.&nbsp;</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; tag</i></td>
<td>A message tag which can be used by this routine.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; comm</i></td>
<td>MPI Communicator for the processor numbering in the <i>procs</i> arrays.</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Invert_Map"></a>
<hr>
<b>C:</b><br>
int <b>Zoltan_Comm_Invert_Map</b>( int
*<i>lengths_to</i>, int *<i> procs_to</i>, int <i>nsends</i>, int <i>self_msg</i>,
int **<i> lengths_from</i>, int **<i> procs_from</i>, int *<i> nrecvs</i>,
int <i>my_proc</i>, int <i>nprocs</i>, int <i>out_of_mem</i>, int <i>tag</i>,
MPI_Comm <i>comm</i> );&nbsp;
<br><b>C++:</b><br>
static int <b>Zoltan_Comm::Invert_Map</b>( int
*<i>lengths_to</i>, int *<i> procs_to</i>,
const int & <i>nsends</i>, const int & <i>self_msg</i>,
int * &<i> lengths_from</i>, int * &<i> procs_from</i>, int &<i> nrecvs</i>,
const int & <i>my_proc</i>, const int & <i>nprocs</i>,
const int & <i>out_of_mem</i>, const int & <i>tag</i>,
const MPI_Comm & <i>comm</i> );&nbsp;
<hr>The <b>Zoltan_Comm_Invert_Map</b> function is a low level communication
routine. It is useful when a processor knows to whom it needs to send data,
but not from whom it needs to receive data. Each processor provides to this
routine a set of lengths and destinations for the messages it wants to
send. The routine then returns the set of lengths and origins for the messages
a processor will receive. Note that by inverting the interpretation
of
<i>to</i> and <i>from</i> in these arguments, the routine can be used
to do the opposite: knowing how much data to receive and from which processors, it can
compute how much data to send and to which processors.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; lengths_to</i></td>
<td>Input array with the number of values in each of the messages to be sent.
Note that the actual size of each value is not specified until
the <b><a href="#Zoltan_Comm_Do">Zoltan_Comm_Do</a></b> routine is invoked.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; procs_to</i></td>
<td>Input array with the destination processor for each of the messages
to be sent.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nsends</i></td>
<td>Input argument with the number of messages to be sent. (Length
of the <i>lengths_to</i> and <i>procs_to</i> arrays.)</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; self_msg</i></td>
<td>Input argument indicating whether a processor has data for itself (=1) or not
(=0) within the <i>procs_to</i> and <i>lengths_to</i> arrays.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; lengths_from</i></td>
<td>Returned array with lengths of messages to be received.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; procs_from</i></td>
<td>Returned array of processors from which data will be received.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nrecvs</i></td>
<td>Returned value with number of messages to be received (lengths of
<i>lengths_from</i>
and <i>procs_from</i> arrays).</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; my_proc</i></td>
<td>The processor's ID in the <i>comm</i> communicator.&nbsp;</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nprocs</i></td>
<td>Number of processors in the <i>comm</i> communicator.&nbsp;</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; out_of_mem</i></td>
<td>Since it has a barrier operation, this routine is a convenient time
to tell all the processors that one of them is out of memory. This input
argument is 0 if the processor is OK, and 1 if the processor has failed
in a malloc call. All the processors will return with a code of <b>COMM_MEMERR</b>
if any of them is out of memory.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; tag</i></td>
<td>A message tag which can be used by this routine.</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; comm</i></td>
<td>MPI Communicator for the processor numbering in the <i>procs</i> arrays.</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<p>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Sort_Ints"></a>
<hr>
int <b>Zoltan_Comm_Sort_Ints</b>( int *<i>vals_sort</i>,
int *<i>vals_other</i>, int <i>nvals</i>);&nbsp;
<hr>As its name suggests, the <b>Zoltan_Comm_Sort_Ints</b> function sorts a
set of integers via the quicksort algorithm. The integers are reordered
from lowest to highest, and a second array of integers is reordered in
the same fashion. This second array can be used to return the permutation
associated with the sort operation. There is no C++ interface to this
function. You can use the C function instead.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; vals_sort</i></td>
<td>The array of integers to be sorted. This array is permuted into sorted
order.&nbsp;</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; vals_other</i></td>
<td>Another array of integers which is permuted identically to <i>vals_sort</i>.&nbsp;</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nvals</i></td>
<td>The number of values in the two integer arrays.&nbsp;</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Info"></a>
<hr>
<b>C:</b><br>
int <b>Zoltan_Comm_Info</b>(
struct Zoltan_Comm_Obj *<i>plan</i>,
int *<i>nsends</i>,
int *<i>send_procs</i>,
int *<i>send_lengths</i>,
int *<i>send_nvals</i>,
int *<i>send_max_size</i>,
int *<i>send_list</i>,
int *<i>nrecvs</i>,
int *<i>recv_procs</i>,
int *<i>recv_lengths</i>,
int *<i>recv_nvals</i>,
int *<i>recv_total_size</i>,
int *<i>recv_list</i>,
int *<i>self_msg</i>);
<br><b>C++:</b><br>
int <b>Zoltan_Comm::Info</b>(
int *<i>nsends</i>,
int *<i>send_procs</i>,
int *<i>send_lengths</i>,
int *<i>send_nvals</i>,
int *<i>send_max_size</i>,
int *<i>send_list</i>,
int *<i>nrecvs</i>,
int *<i>recv_procs</i>,
int *<i>recv_lengths</i>,
int *<i>recv_nvals</i>,
int *<i>recv_total_size</i>,
int *<i>recv_list</i>,
int *<i>self_msg</i>) const;
<hr><b>Zoltan_Comm_Info</b> returns information about a communication plan.
All arguments, except the <i>plan</i> itself, may be NULL; values are
returned only for non-NULL arguments.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp;
plan</i></td>
<td VALIGN=TOP>
Communication data structure created by
<a href="#Zoltan_Comm_Create"><b>Zoltan_Comm_Create</b></a>.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nsends</i></td>
<td VALIGN=TOP>
Upon return, the number of processors to which messages are sent;
does not include self-messages.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; send_procs</i></td>
<td VALIGN=TOP>
Upon return, a list of processors to which messages are sent;
self-messages are included.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; send_lengths</i></td>
<td VALIGN=TOP>
Upon return, the number of values to be sent to each processor
in <i>send_procs</i>.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; send_nvals</i></td>
<td VALIGN=TOP>
Upon return, the total number of values to send.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; send_max_size</i></td>
<td VALIGN=TOP>
Upon return, the maximum size of a message to be sent; does not
include self-messages.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; send_list</i></td>
<td VALIGN=TOP>
Upon return, the processor assignment of each value to be sent.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; nrecvs</i></td>
<td VALIGN=TOP>
Upon return, the number of processors from which to receive messages;
does not include self-messages.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; recv_procs</i></td>
<td VALIGN=TOP>
Upon return, a list of processors from which messages are
received; includes self-messages.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; recv_lengths</i></td>
<td VALIGN=TOP>
Upon return, the number of values to be received from each
processor in <i>recv_procs</i>.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; recv_nvals</i></td>
<td VALIGN=TOP>
Upon return, the total number of values to receive.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; recv_total_size</i></td>
<td VALIGN=TOP>
Upon return, the total size of items to be received.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; recv_list</i></td>
<td VALIGN=TOP>
Upon return, the processor assignments of each value to be received.
</td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp; self_msg</i></td>
<td VALIGN=TOP>
Upon return, the number of self-messages.
</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<!------------------------------------------------------------------------->
<hr>
<a NAME="Zoltan_Comm_Invert_Plan"></a>
<hr>
<b>C:</b>&nbsp; int <b>Zoltan_Comm_Invert_Plan</b>(
struct Zoltan_Comm_Obj **<i>plan</i>
);
<br><b>C++:</b>&nbsp; int <b>Zoltan_Comm::Invert_Plan</b>();
<hr>Given a communication plan, <b>Zoltan_Comm_Invert_Plan</b>
alters the plan to make it the plan for the reverse communication.
Information in the input plan is replaced by information for the
reverse-communication plan. All receives in the reverse-communication
plan are blocked; thus, using the inverted plan does not produce the
same results as
<a href="#Zoltan_Comm_Do_Reverse"><b>Zoltan_Comm_Do_Reverse</b></a>.
If an error occurs within <b>Zoltan_Comm_Invert_Plan</b>, the original plan
is returned unaltered.
<br>&nbsp;
<table WIDTH="100%" >
<tr VALIGN=TOP>
<td VALIGN=TOP WIDTH="20%"><b>Arguments:</b></td>
<td WIDTH="80%"></td>
</tr>
<tr>
<td VALIGN=TOP><i>&nbsp;&nbsp;&nbsp;
plan</i></td>
<td VALIGN=TOP>
Communication data structure created by
<a href="#Zoltan_Comm_Create"><b>Zoltan_Comm_Create</b></a>; the contents
of this plan are irretrievably modified by <b>Zoltan_Comm_Invert_Plan</b>.
</td>
</tr>
<tr>
<td><b>Returned Value:</b></td>
<td></td>
</tr>
<tr>
<td>&nbsp;&nbsp;&nbsp; int</td>
<td>Error code.</td>
</tr>
</table>
<!------------------------------------------------------------------------->
<hr>
<br>[<a href="ug.html">Table of Contents</a>&nbsp; |&nbsp; <a href="ug_util_dd.html">Next:&nbsp;
Distributed Directory Utility</a>&nbsp; |&nbsp; <a href="ug_util_mem.html">Previous:&nbsp;
Memory Management Utilities</a>&nbsp; |&nbsp; <a href="https://www.sandia.gov/general/privacy-security/index.html">Privacy and Security</a>]
</body>
</html>