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.
611 lines
34 KiB
611 lines
34 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.7 sun4u) [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: Query-Functon Examples</title>
|
||
|
|
||
|
</head>
|
||
|
<body bgcolor="#FFFFFF">
|
||
|
|
||
|
<div align=right><b><i><a href="ug.html">Zoltan User's Guide</a>
|
||
|
| <a href="ug_release.html">Next</a> | <a href="ug_examples_mig.html">Previous</a></i></b></div>
|
||
|
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<h2>
|
||
|
<a NAME="Query-Function Example"></a>Query-Function Examples</h2>
|
||
|
Examples of query functions provided by a simple application are included
|
||
|
below. The general-interface examples include a simple implementation
|
||
|
of <b><a href="ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN</a> </b>and <b><a href="ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN</a></b>
|
||
|
query functions and variants of the simple implementation that exploit
|
||
|
local identifiers and data pointers. Migration examples for packing
|
||
|
and unpacking objects are also included. Robust error checking
|
||
|
is not included in the routines; application developers should include
|
||
|
more explicit error checking in their query functions.
|
||
|
<ul><a href="#lb_query_example">General Interface Examples</a>
|
||
|
<ul><a href="#basic_query_example">Basic example</a>
|
||
|
<br><a href="#data_ptr_query_example">User-defined data pointer</a></ul>
|
||
|
<a href="#mig_query_example">Migration Examples</a>
|
||
|
<ul><a href="#mig_pack_example">Packing and unpacking functions</a></ul>
|
||
|
</ul>
|
||
|
All the examples use a mesh data structure consisting of nodes in the mesh.
|
||
|
these nodes are the objects passed to Zoltan. A node is described by
|
||
|
its 3D coordinates and a global ID number that is unique across all processors.
|
||
|
The type definitions for the mesh and node data structures used in the
|
||
|
examples are included <a href="#query example data types">below</a>.
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<br>
|
||
|
<center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE >
|
||
|
<tr>
|
||
|
<td><a NAME="query example data types"></a><tt>/*<i> Node data structure.</i>
|
||
|
*/</tt>
|
||
|
<br><tt>/* <i>A node consists of its 3D coordinates and</i> */</tt>
|
||
|
<br><tt>/* <i>an ID number that is unique across all processors.</i> */</tt>
|
||
|
<br><tt>struct Node_Type { </tt>
|
||
|
<br><tt> double Coordinates[3]; </tt>
|
||
|
<br><tt> int Global_ID_Num; </tt>
|
||
|
<br><tt>}; </tt>
|
||
|
<p><tt>/*<i> Mesh data structure.</i> */ </tt>
|
||
|
<br><tt>/* <i>Mesh consists of an array of nodes and</i> */</tt>
|
||
|
<br><tt>/* <i>the number of nodes owned by the processor.</i> */</tt>
|
||
|
<br><tt>struct Mesh_Type {</tt>
|
||
|
<br><tt> struct Node_Type Nodes[MAX_NODES]; </tt>
|
||
|
<br><tt> int Number_Owned; </tt>
|
||
|
<br><tt>};</tt></td>
|
||
|
</tr>
|
||
|
|
||
|
<caption ALIGN=BOTTOM><i>Data types for the query-function examples.</i></caption>
|
||
|
</table></center>
|
||
|
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<br>
|
||
|
<center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE >
|
||
|
<tr>
|
||
|
<td><a NAME="query example Fortran data types"></a><tt>!<i> Node data structure.</i></tt>
|
||
|
<br><tt>! <i>A node consists of its 3D coordinates and</i></tt>
|
||
|
<br><tt>! <i>an ID number that is unique across all processors.</i></tt>
|
||
|
<br><tt>type Node_Type </tt>
|
||
|
<br><tt> real(Zoltan_DOUBLE) :: Coordinates(3) </tt>
|
||
|
<br><tt> integer(Zoltan_INT) :: Global_ID_Num </tt>
|
||
|
<br><tt>end type Node_Type</tt>
|
||
|
<br><tt> </tt>
|
||
|
<p><tt>!<i> Mesh data structure.</i> </tt>
|
||
|
<br><tt>! <i>Mesh consists of an array of nodes and</i></tt>
|
||
|
<br><tt>! <i>the number of nodes owned by the processor.</i></tt>
|
||
|
<br><tt>type Mesh_Type </tt>
|
||
|
<br><tt> type(Node_Type) :: Nodes(MAX_NODES) </tt>
|
||
|
<br><tt> integer(Zoltan_INT) :: Number_Owned </tt>
|
||
|
<br><tt>end type Mesh_Type</tt>
|
||
|
<br> </td>
|
||
|
</tr>
|
||
|
|
||
|
<caption ALIGN=BOTTOM><i>Data types for the Fortran query-function examples.</i></caption>
|
||
|
</table></center>
|
||
|
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<h3>
|
||
|
<a NAME="lb_query_example"></a>General Interface Query Function Examples</h3>
|
||
|
In the following examples, <b><a href="ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN</a></b>
|
||
|
and <b><a href="ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN </a></b>query functions
|
||
|
are implemented for an application using the mesh and node data structures
|
||
|
described <a href="#query example data types">above</a>.
|
||
|
The nodes are the objects passed to Zoltan.
|
||
|
<p>Through a call to <b><a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a></b>,
|
||
|
the function <i>user_return_owned_nodes</i> is registered as the <b><a href="ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN</a></b>
|
||
|
query function. It returns global and local identifiers for
|
||
|
each node owned by a processor.
|
||
|
<p>The function <i>user_return_coords</i> is registered as a <b><a href="ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN</a></b>
|
||
|
query function. Given the global and local identifiers for a node,
|
||
|
this function returns the node's coordinates. All the examples exploit
|
||
|
the local identifier to quickly locate nodal data. If such an identifier
|
||
|
is not available in an application, a search using the global identifier
|
||
|
can be performed.
|
||
|
<p>The <a href="#basic_query_example">Basic Example</a> includes the simplest
|
||
|
implementation of the query routines. In the query routines, it uses
|
||
|
global application data structures and a local numbering scheme for the
|
||
|
local identifiers. The <a href="#data_ptr_query_example">User-Defined
|
||
|
Data Pointer Example</a> uses only local application data structures; this
|
||
|
model is useful if the application does not have global data structures
|
||
|
or if objects from more than one data structure are to be passed to Zoltan.
|
||
|
Differences between the latter example and the Basic Example are
|
||
|
shown in <font color="#FF0000">red</font>.
|
||
|
<h4>
|
||
|
<a NAME="basic_query_example"></a>Basic Example</h4>
|
||
|
In the simplest example, the query functions access the application data
|
||
|
through a global data structure (<i>Mesh</i>) representing the mesh.
|
||
|
In the calls to <b><a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a></b>,
|
||
|
no pointers to application data are registered with the query function
|
||
|
(i.e., the <i>data</i> pointer is not used). A node's local
|
||
|
identifier is an integer representing the index in the <i>Mesh.Nodes</i>
|
||
|
array of the node. The local identifier is set to the index's value
|
||
|
in<i> user_return_owned_nodes</i>. It is used to access the global
|
||
|
<i>Mesh.Nodes</i> array in <i>user_return_coords</i>.
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<br>
|
||
|
<center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE >
|
||
|
<tr>
|
||
|
<td><a NAME="query example one"></a><tt>/* <i>in application's program
|
||
|
file</i> */ </tt>
|
||
|
<br><tt>#include "zoltan.h"</tt>
|
||
|
<p><tt>/* <i>Declare a global Mesh data structure.</i> */</tt>
|
||
|
<br><tt>struct Mesh_Type Mesh;</tt>
|
||
|
<p><tt>main() </tt>
|
||
|
<br><tt>{ </tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt> /* <i>Indicate that local and global IDs are
|
||
|
one integer each. */</i></tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_GID_ENTRIES">NUM_GID_ENTRIES</a>", "1");</tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_LID_ENTRIES">NUM_LID_ENTRIES</a>", "1");</tt><tt></tt>
|
||
|
<p><tt> /* <i>Register query functions.</i>
|
||
|
*/</tt>
|
||
|
<br><tt> /* <i>Do not register a data pointer with the
|
||
|
functions;</i> */</tt>
|
||
|
<br><tt> /* <i>the global Mesh data structure will be
|
||
|
used.</i> */</tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN_TYPE</a>, </tt>
|
||
|
<br><tt>
|
||
|
(void (*)()) user_return_coords, NULL); </tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN_TYPE</a>, </tt>
|
||
|
<br><tt>
|
||
|
(void (*)()) user_return_owned_nodes, NULL); </tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt>} </tt>
|
||
|
<p><tt>void user_return_owned_nodes(void *data, </tt>
|
||
|
<br><tt> int num_gid_entries, int num_lid_entries,</tt>
|
||
|
<br><tt> <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> global_ids, <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> local_ids,</tt>
|
||
|
<br><tt> int wgt_dim, float *obj_wgts,</tt>
|
||
|
<br><tt> int *ierr) </tt>
|
||
|
<br><tt>{ </tt>
|
||
|
<br><tt>int i; </tt>
|
||
|
<br><tt> /* <i>return global node numbers as global_ids.</i>
|
||
|
*/ </tt>
|
||
|
<br><tt> /* <i>return index into Nodes array for local_ids.</i>
|
||
|
*/ </tt>
|
||
|
<br><tt> for (i = 0; i < Mesh.Number_Owned; i++){ </tt>
|
||
|
<br><tt> global_ids[i*num_gid_entries]
|
||
|
= Mesh.Nodes[i].Global_ID_Num; </tt>
|
||
|
<br><tt> local_ids[i*num_lid_entries]
|
||
|
= i; </tt>
|
||
|
<br><tt> } </tt>
|
||
|
<br><tt> *ierr = ZOLTAN_OK; </tt>
|
||
|
<br><tt>} </tt>
|
||
|
<p><tt>void user_return_coords(void *data, </tt>
|
||
|
<br><tt> int num_gid_entries, int num_lid_entries,</tt>
|
||
|
<br><tt> <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> global_id, <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> local_id, </tt>
|
||
|
<br><tt> double *geom_vec, int *ierr) </tt>
|
||
|
<br><tt>{ </tt>
|
||
|
<br><tt> /* <i>use local_id to index into the Nodes array.</i>
|
||
|
*/ </tt>
|
||
|
<br><tt> geom_vec[0] = Mesh.Nodes[local_id[0]].Coordinates[0]; </tt>
|
||
|
<br><tt> geom_vec[1] = Mesh.Nodes[local_id[0]].Coordinates[1]; </tt>
|
||
|
<br><tt> geom_vec[2] = Mesh.Nodes[local_id[0]].Coordinates[2]; </tt>
|
||
|
<br><tt> *ierr = ZOLTAN_OK; </tt>
|
||
|
<br><tt>}</tt></td>
|
||
|
</tr>
|
||
|
|
||
|
<caption ALIGN=BOTTOM><i>Example of general interface query functions (simplest
|
||
|
implementation).</i></caption>
|
||
|
</table></center>
|
||
|
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<br>
|
||
|
<center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE >
|
||
|
<tr>
|
||
|
<td><a NAME="query Fortran example one"></a><tt>! <i>in application's program
|
||
|
file</i> </tt>
|
||
|
<p><tt>module Global_Mesh_Data</tt>
|
||
|
<br><tt>! <i>Declare a global Mesh data structure.</i></tt>
|
||
|
<br><tt> type(Mesh_Type) :: Mesh</tt>
|
||
|
<br><tt>end module</tt>
|
||
|
<p><tt>program query_example_1 </tt>
|
||
|
<br><tt>use zoltan</tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt> ! <i>Indicate that local and global IDs are
|
||
|
one integer each. </i></tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_GID_ENTRIES">NUM_GID_ENTRIES</a>", "1");</tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_LID_ENTRIES">NUM_LID_ENTRIES</a>", "1");</tt><tt></tt>
|
||
|
<p><tt> ! <i>Register query functions.</i></tt>
|
||
|
<br><tt> ! <i>Do not register a data pointer with the
|
||
|
functions;</i></tt>
|
||
|
<br><tt> ! <i>the global Mesh data structure will be
|
||
|
used.</i></tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN_TYPE</a>,</tt>
|
||
|
|
||
|
<tt>user_return_coords) </tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN_TYPE</a>,</tt>
|
||
|
|
||
|
<tt>user_return_owned_nodes) </tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt>end program </tt>
|
||
|
<p><tt>subroutine user_return_owned_nodes(data, &</tt>
|
||
|
<br><tt> num_gid_entries, num_lid_entries, &</tt>
|
||
|
<br><tt> global_ids, local_ids, wgt_dim, obj_wgts, ierr) </tt>
|
||
|
<br><tt>use zoltan </tt>
|
||
|
<br><tt>use Global_Mesh_Data </tt>
|
||
|
<br><tt>integer(Zoltan_INT) :: data(1) ! dummy declaration, do not use</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: num_gid_entries, num_lid_entries</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(out) :: global_ids(*), local_ids(*)</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: wgt_dim</tt>
|
||
|
<br><tt>real(Zoltan_FLOAT), intent(out) :: obj_wgts(*)</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(out) :: ierr</tt>
|
||
|
<br><tt>integer i </tt>
|
||
|
<br><tt> ! <i>return global node numbers as global_ids.</i> </tt>
|
||
|
<br><tt> ! <i>return index into Nodes array for local_ids.</i> </tt>
|
||
|
<br><tt> do i = 1, Mesh%Number_Owned </tt>
|
||
|
<br><tt> global_ids(1+(i-1)*num_gid_entries) = &</tt>
|
||
|
<br><tt> Mesh%Nodes(i)%Global_ID_Num </tt>
|
||
|
<br><tt> local_ids(1+(i-1)*num_lid_entries)
|
||
|
= i </tt>
|
||
|
<br><tt> end do </tt>
|
||
|
<br><tt> ierr = ZOLTAN_OK </tt>
|
||
|
<br><tt>end subroutine </tt>
|
||
|
<p><tt>subroutine user_return_coords(data, num_gid_entries, num_lid_entries,
|
||
|
&</tt>
|
||
|
<br><tt> global_id, local_id, geom_vec, ierr) </tt>
|
||
|
<br><tt>use zoltan </tt>
|
||
|
<br><tt>use Global_Mesh_Data </tt>
|
||
|
<br><tt>integer(Zoltan_INT) :: data(1) ! dummy declaration, do not use</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: num_gid_entries, num_lid_entries</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: global_id(*), local_id(*)</tt>
|
||
|
<br><tt>real(Zoltan_DOUBLE), intent(out) :: geom_vec(*)</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(out) :: ierr</tt>
|
||
|
<br><tt> ! <i>use local_id to index into the Nodes array.</i> </tt>
|
||
|
<br><tt> geom_vec(1:3) = Mesh%Nodes(local_id(1))%Coordinates </tt>
|
||
|
<br><tt> ierr = ZOLTAN_OK </tt>
|
||
|
<br><tt>end subroutine</tt></td>
|
||
|
</tr>
|
||
|
|
||
|
<caption ALIGN=BOTTOM><i>Fortran example of general interface query functions
|
||
|
(simplest implementation).</i></caption>
|
||
|
</table></center>
|
||
|
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<h4>
|
||
|
<a NAME="data_ptr_query_example"></a>User-Defined Data Pointer Example</h4>
|
||
|
In this example, the address of a local mesh data structure is registered
|
||
|
with the query functions for use by those functions. This change
|
||
|
eliminates the need for a global mesh data structure in the application.
|
||
|
The address of the local data structure is included as an argument in calls
|
||
|
to <b><a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a></b>.
|
||
|
This address is then used in <i>user_return_owned_nodes</i> and <i>user_return_coords</i>
|
||
|
to provide data for these routines. It is cast to the <i><a href="#query example data types">Mesh_Type</a></i>
|
||
|
data type and accessed with local identifiers as in the <a href="#basic_query_example">Basic
|
||
|
Example</a>. Differences between this example and the <a href="#basic_query_example">Basic
|
||
|
Example</a> are shown in <font color="#FF0000">red</font>.
|
||
|
<p>This model is useful when the application does not have a global data
|
||
|
structure that can be accessed by the query functions. It can also
|
||
|
be used for operations on different data structures. For example,
|
||
|
if an application had more than one mesh, load balancing could be performed
|
||
|
separately on each mesh without having different query routines for each
|
||
|
mesh. Calls to <b><a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a></b>
|
||
|
would define which mesh should be balanced, and the query routines would
|
||
|
access the mesh currently designated by the <b><a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a></b>
|
||
|
calls.
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<br>
|
||
|
<center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE >
|
||
|
<tr>
|
||
|
<td><a NAME="query example three"></a><tt>/* <i>in application's program
|
||
|
file</i> */</tt>
|
||
|
<br><tt>#include "zoltan.h"</tt>
|
||
|
<p><tt>main()</tt>
|
||
|
<br><tt>{</tt>
|
||
|
<br><tt><font color="#FF0000">/* <i>declare a local mesh data structure.</i>
|
||
|
*/</font></tt>
|
||
|
<br><tt><font color="#FF0000">struct Mesh_Type mesh;</font></tt>
|
||
|
<br><tt>...</tt>
|
||
|
<br><tt> /* <i>Indicate that local and global IDs are
|
||
|
one integer each. */</i></tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_GID_ENTRIES">NUM_GID_ENTRIES</a>", "1");</tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_LID_ENTRIES">NUM_LID_ENTRIES</a>", "1");</tt><tt></tt>
|
||
|
<p><tt> /* <i>Register query functions.</i>
|
||
|
*/</tt>
|
||
|
<br><tt> /* <i><font color="#FF0000">Register the address
|
||
|
of mesh as the data pointer.</font></i> */</tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN_TYPE</a>,</tt>
|
||
|
<br><tt>
|
||
|
(void (*)()) user_return_coords, <font color="#FF0000">&mesh</font>); </tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN_TYPE</a>,</tt>
|
||
|
<br><tt>
|
||
|
(void (*)()) user_return_owned_nodes, <font color="#FF0000">&mesh</font>); </tt>
|
||
|
<br><tt>...</tt>
|
||
|
<br><tt>}</tt>
|
||
|
<p><tt>void user_return_owned_nodes(void *data,</tt>
|
||
|
<br><tt> int num_gid_entries, int num_lid_entries,</tt>
|
||
|
<br><tt> <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> global_ids, <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> local_ids,</tt>
|
||
|
<br><tt> int wgt_dim, float *obj_wgts,</tt>
|
||
|
<br><tt> int *ierr) </tt>
|
||
|
<br><tt>{</tt>
|
||
|
<br><tt>int i; </tt>
|
||
|
<br><tt><font color="#FF0000">/* <i>cast data pointer to type Mesh_Type.</i>
|
||
|
*/</font></tt>
|
||
|
<br><tt><font color="#FF0000">struct Mesh_Type *ptr = (struct Mesh_Type
|
||
|
*) data;</font></tt>
|
||
|
<p><tt> /* <i>return global node numbers as global_ids.</i>
|
||
|
*/</tt> <tt> </tt>
|
||
|
<br><tt> /* <i>return index into Nodes array for local_ids.</i>
|
||
|
*/</tt>
|
||
|
<br><tt> for (i = 0; i < ptr->Number_Owned; i++)
|
||
|
{</tt>
|
||
|
<br><tt> global_ids[i*num_gid_entries]
|
||
|
= <font color="#FF0000">ptr->Nodes[i].Global_ID_Num</font>;</tt>
|
||
|
<br><tt> local_ids[i*num_lid_entries]
|
||
|
= i;</tt>
|
||
|
<br><tt> }</tt>
|
||
|
<br><tt> *ierr = ZOLTAN_OK;</tt>
|
||
|
<br><tt>}</tt>
|
||
|
<p><tt>void user_return_coords(void *data, </tt>
|
||
|
<br><tt> int num_gid_entries, int num_lid_entries,</tt>
|
||
|
<br><tt> <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> global_id, <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> local_id, </tt>
|
||
|
<br><tt> double *geom_vec, int *ierr)</tt>
|
||
|
<br><tt>{</tt>
|
||
|
<p><tt><font color="#FF0000">/* <i>cast data pointer to type Mesh_Type.</i>
|
||
|
*/</font></tt>
|
||
|
<br><tt><font color="#FF0000">struct Mesh_Type *ptr = (struct Mesh_Type
|
||
|
*) data;</font></tt>
|
||
|
<p><tt> /* <i>use local_id to address the requested node.</i>
|
||
|
*/</tt>
|
||
|
<br><tt> geom_vec[0] = <font color="#FF0000">ptr->Nodes[local_id[0]].Coordinates[0]</font>;</tt>
|
||
|
<br><tt> geom_vec[1] = <font color="#FF0000">ptr->Nodes[local_id[0]].Coordinates[1]</font>;</tt>
|
||
|
<br><tt> geom_vec[2] = <font color="#FF0000">ptr->Nodes[local_id[0]].Coordinates[2]</font>;</tt>
|
||
|
<br><tt> *ierr = ZOLTAN_OK;</tt>
|
||
|
<br><tt>}</tt></td>
|
||
|
</tr>
|
||
|
|
||
|
<caption ALIGN=BOTTOM><i>Example of general interface query functions using
|
||
|
the application-defined data pointer.</i></caption>
|
||
|
</table></center>
|
||
|
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<br>
|
||
|
<center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE >
|
||
|
<tr>
|
||
|
<td><a NAME="query Fortran example three"></a><tt>/* <i>included in file
|
||
|
zoltan_user_data.f90</i> */</tt>
|
||
|
<br><tt><font color="#FF0000">! <i>User defined data type as wrapper for
|
||
|
Mesh</i></font></tt>
|
||
|
<br><tt><font color="#FF0000">type Zoltan_User_Data_1</font></tt>
|
||
|
<br><tt><font color="#FF0000"> type(Mesh_type), pointer ::
|
||
|
ptr</font></tt>
|
||
|
<br><tt><font color="#FF0000">end type Zoltan_User_Data_1</font></tt>
|
||
|
<p>
|
||
|
<hr WIDTH="100%"><tt>! <i>in application's program file</i> </tt>
|
||
|
<p><tt>program query_example_3 </tt>
|
||
|
<br><tt>use zoltan</tt>
|
||
|
<br><tt><font color="#FF0000">!<i> declare a local mesh data structure
|
||
|
and a User_Data to point to it.</i></font></tt>
|
||
|
<br><tt><font color="#FF0000">type(Mesh_Type), target :: mesh</font></tt>
|
||
|
<br><tt><font color="#FF0000">type(Zoltan_User_Data_1) data</font></tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt> ! <i>Indicate that local and global IDs are
|
||
|
one integer each. </i></tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_GID_ENTRIES">NUM_GID_ENTRIES</a>", "1");</tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Param">Zoltan_Set_Param</a>(zz,
|
||
|
"<a href="ug_param.html#NUM_LID_ENTRIES">NUM_LID_ENTRIES</a>", "1");</tt><tt></tt>
|
||
|
<p><tt> ! <i>Register query functions.</i></tt>
|
||
|
<br><tt><font color="#FF0000"> ! <i>Use the User_Data
|
||
|
variable to pass the mesh data
|
||
|
</i></font></tt>
|
||
|
<br><tt><font color="#FF0000"> data%ptr => mesh</font></tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN_TYPE</a>,</tt>
|
||
|
|
||
|
<tt>user_return_coords<font color="#FF0000">, data</font>) </tt>
|
||
|
<br><tt> ierr = <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN_TYPE</a>,</tt>
|
||
|
|
||
|
<br><tt>
|
||
|
user_return_owned_nodes<font color="#FF0000">, data</font>)</tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt>end program </tt>
|
||
|
<p><tt>subroutine user_return_owned_nodes(data, &</tt>
|
||
|
<br><tt> num_gid_entries, num_lid_entries, &</tt>
|
||
|
<br><tt> global_ids, local_ids, wgt_dim, obj_wgts, ierr) </tt>
|
||
|
<br><tt>use zoltan </tt>
|
||
|
<br><tt><font color="#FF0000">type(Zoltan_User_Data_1) :: data</font></tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: num_gid_entries, num_lid_entries</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(out) :: global_ids(*), local_ids(*)</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: wgt_dim</tt>
|
||
|
<br><tt>real(Zoltan_FLOAT), intent(out) :: obj_wgts(*)</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(out) :: ierr</tt>
|
||
|
<br><tt>integer i </tt>
|
||
|
<br><tt><font color="#FF0000">type(Mesh_Type), pointer :: Mesh</font></tt>
|
||
|
<p><tt><font color="#FF0000"> ! <i>extract the mesh from the
|
||
|
User_Data argument</i></font></tt>
|
||
|
<br><tt><font color="#FF0000"> Mesh => data%ptr</font></tt>
|
||
|
<p><tt> ! <i>return global node numbers as global_ids.</i> </tt>
|
||
|
<br><tt> ! <i>return index into Nodes array for local_ids.</i> </tt>
|
||
|
<br><tt> do i = 1, Mesh%Number_Owned </tt>
|
||
|
<br><tt> global_ids(1+(i-1)*num_gid_entries) = &</tt>
|
||
|
<br><tt> Mesh%Nodes(i)%Global_ID_Num </tt>
|
||
|
<br><tt> local_ids(1+(i-1)*num_lid_entries)
|
||
|
= i </tt>
|
||
|
<br><tt> end do </tt>
|
||
|
<br><tt> ierr = ZOLTAN_OK </tt>
|
||
|
<br><tt>end subroutine </tt>
|
||
|
<p><tt>subroutine user_return_coords(data, global_id, local_id, &</tt>
|
||
|
<br><tt> geom_vec, ierr) </tt>
|
||
|
<br><tt>use zoltan </tt>
|
||
|
<br><tt><font color="#FF0000">type(Zoltan_User_Data_1) :: data</font></tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: num_gid_entries, num_lid_entries</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(in) :: global_id(*), local_id(*)</tt>
|
||
|
<br><tt>real(Zoltan_DOUBLE), intent(out) :: geom_vec(*)</tt>
|
||
|
<br><tt>integer(Zoltan_INT), intent(out) :: ierr</tt>
|
||
|
<br><tt><font color="#FF0000">type(Mesh_Type), pointer :: Mesh</font></tt>
|
||
|
<p><tt><font color="#FF0000"> ! <i>extract the mesh from the
|
||
|
User_Data argument</i></font></tt>
|
||
|
<br><tt><font color="#FF0000"> Mesh => data%ptr</font></tt>
|
||
|
<p><tt> ! <i>use local_id to index into the Nodes array.</i> </tt>
|
||
|
<br><tt> geom_vec(1:3) = Mesh%Nodes(local_id(1))%Coordinates </tt>
|
||
|
<br><tt> ierr = ZOLTAN_OK </tt>
|
||
|
<br><tt>end subroutine</tt></td>
|
||
|
</tr>
|
||
|
|
||
|
<caption ALIGN=BOTTOM><i>Fortran example of general interface query functions
|
||
|
using the application-defined data pointer.</i></caption>
|
||
|
</table></center>
|
||
|
|
||
|
<!-------------------------------------------------------------------------->
|
||
|
<h3>
|
||
|
<a NAME="mig_query_example"></a>Migration Examples</h3>
|
||
|
|
||
|
<h4>
|
||
|
<a NAME="mig_pack_example"></a>Packing and Unpacking Data</h4>
|
||
|
Simple migration query functions for the <a href="#basic_query_example">Basic
|
||
|
Example</a> are included<a href="#query example four"> below</a>.
|
||
|
These functions are used by the migration tools to move nodes among the
|
||
|
processors. The functions <i>user_size_node</i>, <i>user_pack_node</i>,
|
||
|
and <i>user_unpack_node</i> are registered through calls to <b><a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a></b>.
|
||
|
Query function <i>user_size_node</i> returns the size (in bytes) of data
|
||
|
representing a single node. Query function <i>user_pack_node</i>
|
||
|
copies a given node's data into the communication buffer<i> buf</i>.
|
||
|
Query function <i>user_unpack_node</i> copies a data for one node from
|
||
|
the communication buffer <i>buf</i> into the <i>Mesh.Nodes</i> array on
|
||
|
its new processor.
|
||
|
<p>These query routines are simple because the application does not dynamically
|
||
|
allocate memory for each node. Such dynamic allocation would have
|
||
|
to be accounted for in the <a href="ug_query_mig.html#ZOLTAN_OBJ_SIZE_FN">ZOLTAN_OBJ_SIZE_FN</a>,
|
||
|
<a href="ug_query_mig.html#ZOLTAN_PACK_OBJ_FN">ZOLTAN_PACK_OBJ_FN</a>,
|
||
|
and <a href="ug_query_mig.html#ZOLTAN_UNPACK_OBJ_FN">ZOLTAN_UNPACK_OBJ_FN</a> routines.
|
||
|
<br>
|
||
|
<center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE >
|
||
|
<tr>
|
||
|
<td><a NAME="query example four"></a><tt>main() </tt>
|
||
|
<br><tt>{ </tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt> /* <i>Register migration query functions.</i>
|
||
|
*/</tt>
|
||
|
<br><tt> /* <i>Do not register a data pointer with the
|
||
|
functions;</i> */</tt>
|
||
|
<br><tt> /* <i>the global Mesh data structure will be
|
||
|
used.</i> */</tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_mig.html#ZOLTAN_OBJ_SIZE_FN">ZOLTAN_OBJ_SIZE_FN_TYPE</a>,</tt>
|
||
|
<br><tt>
|
||
|
(void (*)()) user_size_node, NULL); </tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_mig.html#ZOLTAN_PACK_OBJ_FN">ZOLTAN_PACK_OBJ_FN_TYPE</a>,</tt>
|
||
|
<br><tt>
|
||
|
(void (*)()) user_pack_node, NULL); </tt>
|
||
|
<br><tt> <a href="ug_interface_init.html#Zoltan_Set_Fn">Zoltan_Set_Fn</a>(zz,
|
||
|
<a href="ug_query_mig.html#ZOLTAN_UNPACK_OBJ_FN">ZOLTAN_UNPACK_OBJ_FN_TYPE</a>,</tt>
|
||
|
<br><tt>
|
||
|
(void (*)()) user_unpack_node, NULL); </tt>
|
||
|
<br><tt>... </tt>
|
||
|
<br><tt>} </tt>
|
||
|
<p><tt>int user_size_node(void *data, </tt>
|
||
|
<br><tt> int num_gid_entries, int num_lid_entries,</tt>
|
||
|
<br><tt> <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> global_id, <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> local_id, int *ierr)</tt>
|
||
|
<br><tt>{</tt>
|
||
|
<br><tt>/* <i>Return the size of data associated with one node.</i> */</tt>
|
||
|
<br><tt>/* <i>This case is simple because all nodes have the same size.</i> */</tt>
|
||
|
<br><tt> *ierr = ZOLTAN_OK;</tt>
|
||
|
<br><tt> return(sizeof(struct Node_Type));</tt>
|
||
|
<br><tt>}</tt>
|
||
|
<p><tt>void user_pack_node(void *data, </tt>
|
||
|
<br><tt>
|
||
|
int num_gid_entries, int num_lid_entries,</tt>
|
||
|
<br><tt>
|
||
|
<a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> global_id, <a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> local_id, </tt>
|
||
|
<br><tt>
|
||
|
int dest_proc, int size, char *buf, int *ierr) </tt>
|
||
|
<br><tt>{</tt>
|
||
|
<br><tt>/* Copy<i> the specified node's data into buffer buf.</i> */</tt>
|
||
|
<br><tt>struct Node_Type *node_buf = (struct Node_Type *) buf;</tt>
|
||
|
<p><tt> *ierr = ZOLTAN_OK;</tt>
|
||
|
<br><tt> node_buf->Coordinates[0] = Mesh.Nodes[local_id[0]].Coordinates[0];</tt>
|
||
|
<br><tt> node_buf->Coordinates[1] = Mesh.Nodes[local_id[0]].Coordinates[1];</tt>
|
||
|
<br><tt> node_buf->Coordinates[2] = Mesh.Nodes[local_id[0]].Coordinates[2];</tt>
|
||
|
<br><tt> node_buf->Global_ID_Num = Mesh.Nodes[local_id[0]].Global_ID_Num;</tt>
|
||
|
<br><tt>}</tt>
|
||
|
<p><tt>void user_unpack_node(void *data, int num_gid_entries,</tt>
|
||
|
<br><tt>
|
||
|
<a href="ug_usage.html#Data Types for Object IDs">ZOLTAN_ID_PTR</a> global_id, int size, </tt>
|
||
|
<br><tt>
|
||
|
char *buf, int *ierr)</tt>
|
||
|
<br><tt>{</tt>
|
||
|
<br><tt>/* <i>Copy the node data in buf into the Mesh data structure. </i>*/</tt>
|
||
|
<br><tt>int i;</tt>
|
||
|
<br><tt>struct Node_Type *node_buf = (struct Node_Type *) buf;</tt>
|
||
|
<p><tt> *ierr = ZOLTAN_OK;</tt>
|
||
|
<br><tt> i = Mesh.Number_Owned;</tt>
|
||
|
<br><tt> Mesh.Number_Owned = Mesh.Number_Owned + 1;</tt>
|
||
|
<br><tt> Mesh.Nodes[i].Coordinates[0] = node_buf->Coordinates[0];</tt>
|
||
|
<br><tt> Mesh.Nodes[i].Coordinates[1] = node_buf->Coordinates[1];</tt>
|
||
|
<br><tt> Mesh.Nodes[i].Coordinates[2] = node_buf->Coordinates[2];</tt>
|
||
|
<br><tt> Mesh.Nodes[i].Global_ID_Num = node_buf->Global_ID_Num;</tt>
|
||
|
<br><tt>}</tt></td>
|
||
|
</tr>
|
||
|
|
||
|
<caption ALIGN=BOTTOM><i>Example of migration query functions for the <a href="#basic_query_example">Basic
|
||
|
Example</a>.</i></caption>
|
||
|
</table></center>
|
||
|
|
||
|
<hr WIDTH="100%">[<a href="ug.html">Table of Contents</a> |
|
||
|
<a href="ug_release.html">Next:
|
||
|
Release Notes</a> | <a href="ug_examples_mig.html">Previous:
|
||
|
Migration Examples</a> | <a href="https://www.sandia.gov/general/privacy-security/index.html">Privacy and Security</a>]
|
||
|
</body>
|
||
|
</html>
|