<!-------- @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.approved" content="SAND99-1376"> <meta name="author" content="karen devine, kddevin@sandia.gov"> <title> Zoltan Developer's Guide: Adding Data Structures</title> </head> <body bgcolor="#FFFFFF"> <div align=right><b><i><a href="dev.html">Zoltan Developer's Guide</a> | <a href="dev_add_memory.html">Next</a> | <a href="dev_add_lb.html">Previous</a></i></b></div> <h2> <a NAME="new_data_structs"></a>Data Structures</h2> The main data structures for the algorithm should be pointed to by the <i>LB.Data_Structure</i> field of the <b><a href="dev_lb_structs.html#Zoltan_Struct">Zoltan_Struct</a></b>. This requirement allows reuse of data structures from one invocation of the new load-balancing algorithm to the next. It also prevents the use of global data structures for the algorithm so that multiple instances of the algorithm may be used (i.e., the same algorithm can be used for multiple <b><a href="dev_lb_structs.html#Zoltan_Struct">Zoltan_Struct</a></b> structures). An example showing the construction of data structures for the <a href="../ug_html/ug_alg_rcb.html">Recursive Coordinate Bisection (RCB)</a> algorithm is included in the <a href="#RCB_example">figure</a> below. <center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE > <tr> <td><a NAME="RCB_example"></a> <tt> <br>/* Allocate RCB data structure for this Zoltan structure. <br> * If the previous data structure still exists, free the Dots first; <br> * the other fields can be reused. <br> */ <br>if (zz->LB.Data_Structure == NULL) { <br> rcb = (RCB_STRUCT *) <a href="../ug_html/ug_util_mem.html#Zoltan_Malloc">ZOLTAN_MALLOC</a>(sizeof(RCB_STRUCT)); <br> zz->LB.Data_Structure = (void *) rcb; <br> rcb->Tree_Ptr = (struct rcb_tree *) <br> <a href="../ug_html/ug_util_mem.html#Zoltan_Malloc">ZOLTAN_MALLOC</a>(zz->Num_Proc*sizeof(struct rcb_tree)); <br> rcb->Box = (struct rcb_box *) <a href="../ug_html/ug_util_mem.html#Zoltan_Malloc">ZOLTAN_MALLOC</a>(sizeof(struct rcb_box)); <br>} <br>else { <br> rcb = (RCB_STRUCT *) zz->LB.Data_Structure; <br> <a href="../ug_html/ug_util_mem.html#Zoltan_Free">ZOLTAN_FREE</a>(&(rcb->Dots)); <br>} </tt> </td> </tr> <caption ALIGN=BOTTOM><i>Example demonstrating allocation of data structures for the RCB algorithm. (Taken from rcb/rcb_util.c.)</i></caption> </table></center> <p>The data needed for the algorithm is collected through calls to the query functions registered by the application. Algorithms should test the query function pointers for NULL and report errors when needed functions are not registered. The appropriate query functions can be called to build the algorithm's data structures up front, or they can be called during the algorithm's execution to gather data only as it is needed. The <a href="#query_example">figure</a> below shows how the <i>Dots</i> data structure needed by RCB is built. The call to <i>zz->Get_Num_Obj</i> invokes an <b><a href="../ug_html/ug_query_lb.html#ZOLTAN_NUM_OBJ_FN">ZOLTAN_NUM_OBJ_FN</a></b> query function to determine the number of objects on the processor. Space for the <i>Dots</i> data structure is allocated through calls to <b><a href="../ug_html/ug_util_mem.html#Zoltan_Malloc">ZOLTAN_MALLOC</a></b>, <a href="dev_lb_types.html#ID alloc"><b>ZOLTAN_MALLOC_GID_ARRAY</b></a>, and <a href="dev_lb_types.html#ID alloc"><b>ZOLTAN_MALLOC_LID_ARRAY</b></a>. The <i>Dots</i> information is obtained through a call to the Zoltan service function <b><a href="dev_services_objlist.html">Zoltan_Get_Obj_List</a></b>; this function calls either an <b><a href="../ug_html/ug_query_lb.html#ZOLTAN_OBJ_LIST_FN">ZOLTAN_OBJ_LIST_FN</a></b> or an <b><a href="../ug_html/ug_query_lb.html#ZOLTAN_FIRST_OBJ_FN">ZOLTAN_FIRST_OBJ_FN</a></b>/<b><a href="../ug_html/ug_query_lb.html#ZOLTAN_NEXT_OBJ_FN">ZOLTAN_NEXT_OBJ_FN</a></b> pair to get the object IDs and weights. The data for each <i>Dot</i> is set in the function <i>initialize_dot</i>, which includes calls to<i> zz->Get_Geom</i>, an <b><a href="../ug_html/ug_query_lb.html#ZOLTAN_GEOM_FN">ZOLTAN_GEOM_FN</a></b> query function. <br> <br> <center><table BORDER=2 COLS=1 WIDTH="90%" NOSAVE > <tr> <td><a NAME="query_example"></a> <tt> <br>/* <br> * Allocate space for objects. Allow extra space <br> * for objects that are imported to the processor. <br> */ <p>*num_obj = zz->Get_Num_Obj(zz->Get_Num_Obj_Data, &ierr); <br>if (ierr) { <br> <a href="dev_intro_coding.html#ZOLTAN_PRINT">ZOLTAN_PRINT_ERROR</a>(zz->Proc, yo, <br> "Error returned from Get_Num_Obj."); <br> return(ierr); <br>} <p>*max_obj = (int)(1.5 * *num_obj) + 1; <br>*global_ids = <a href="dev_lb_types.html#ID alloc">ZOLTAN_MALLOC_GID_ARRAY</a>(zz, (*max_obj)); <br>*local_ids = <a href="dev_lb_types.html#ID alloc">ZOLTAN_MALLOC_LID_ARRAY</a>(zz, (*max_obj)); <br>*dots = (struct Dot_Struct *) <br> <a href="../ug_html/ug_util_mem.html#Zoltan_Malloc">ZOLTAN_MALLOC</a>((*max_obj)*sizeof(struct Dot_Struct)); <p>if (!(*global_ids) || (zz->Num_LID && !(*local_ids)) || !(*dots)) { <br> <a href="dev_intro_coding.html#ZOLTAN_PRINT">ZOLTAN_PRINT_ERROR</a>(zz->Proc, yo, "Insufficient memory."); <br> return(<a href="../ug_html/ug_interface.html#Error Codes">ZOLTAN_MEMERR</a>); <br>} <p>if (*num_obj > 0) { <p> if (wgtflag) { <p> /* <br> * Allocate space for object weights. <br> */ <p> objs_wgt = (float *) <a href="../ug_html/ug_util_mem.html#Zoltan_Malloc">ZOLTAN_MALLOC</a>((*num_obj)*sizeof(float)); <br> if (!objs_wgt) { <br> <a href="dev_intro_coding.html#ZOLTAN_PRINT">ZOLTAN_PRINT_ERROR</a>(zz->Proc, yo, "Insufficient memory."); <br> return(<a href="../ug_html/ug_interface.html#Error Codes">ZOLTAN_MEMERR</a>); <br> } <br> for (i = 0; i < *num_obj; i++) objs_wgt[i] = 0.; <br> } <p> /* <br> * Get list of objects' IDs and weights. <br> */ <p> <a href="dev_services_objlist.html">Zoltan_Get_Obj_List</a>(zz, *global_ids, *local_ids, wgtflag, <br> objs_wgt, &ierr); <br> if (ierr) { <br> <a href="dev_intro_coding.html#ZOLTAN_PRINT">ZOLTAN_PRINT_ERROR</a>(zz->Proc, yo, <br> "Error returned from Zoltan_Get_Obj_List."); <br> <a href="../ug_html/ug_util_mem.html#Zoltan_Free">ZOLTAN_FREE</a>(&objs_wgt); <br> return(ierr); <br> } <p> ierr = initialize_dot(zz, *global_ids, *local_ids, *dots, <br> *num_obj, wgtflag, objs_wgt); <br> if (ierr == ZOLTAN_FATAL || ierr == ZOLTAN_MEMERR) { <br> <a href="dev_intro_coding.html#ZOLTAN_PRINT">ZOLTAN_PRINT_ERROR</a>(zz->Proc, yo, <br> "Error returned from initialize_dot."); <br> <a href="../ug_html/ug_util_mem.html#Zoltan_Free">ZOLTAN_FREE</a>(&objs_wgt); <br> return(ierr); <br> } <p> <a href="../ug_html/ug_util_mem.html#Zoltan_Free">ZOLTAN_FREE</a>(&objs_wgt); <br>} </tt> </td> </tr> <caption ALIGN=BOTTOM><i>Example demonstrating how data structures are built for the RCB algorithm. (Taken from rcb/shared.c.)</i></caption> </table></center> <p> The data structures pointed to by <i>zz->LB.Data_Structure</i> will be freed at some point, and may be copied. <p>A function that frees these structures and resets <i>zz->LB.Data_Structure</i> to NULL should be written. The function should be called when the load-balancing algorithm exits, either normally or due to an error condition. The function <b>Zoltan_RCB_Free_Structure</b> in <i>rcb/rcb_util.c</i> may be used as an example. <A NAME="Copy"></A> <p>If your algorithm uses the <a href="../ug_html/ug_alg_rcb.html">KEEP_CUTS</a> parameter, a function that copies one <i>zz->LB.Data_Structure</i> to another is required. This is particularly important for C++, which may create temporary objects at runtime by invoking a copy operator (which will call your copy function). It is a convenience for C applications, which may wish to copy one Zoltan_Struct to another. See the function <b>Zoltan_RCB_Copy_Structure</b> in <i>rcb/rcb_util.c</i> for an example. <hr WIDTH="100%"> <br>[<a href="dev.html">Table of Contents</a> | <a href="dev_add_memory.html">Next: Memory Management</a> | <a href="dev_add_lb.html">Previous: Load-Balancing Function Implementation</a> | <a href="https://www.sandia.gov/general/privacy-security/index.html">Privacy and Security</a>] <br> </body> </html>