Query functions return information about only on-processor data. They can be called by Zoltan with individual objects or lists of objects. Each processor may call a given query function zero, one or more than one time. Thus, most query functions should NOT contain interprocessor communication, as such communication can cause processors to hang while waiting for messages that were never sent. (The only exceptions to this rule are certain migration query functions.)
Two categories of query functions are used by the library:
General Zoltan Query FunctionsIn each category, a variety of query functions can be registered by the user. The query functions have a function type, describing their purpose. Functions can be registered with a Zoltan structure in two ways: through calls to Zoltan_Set_Fn or through calls to query-function-specific functions Zoltan_Set_<zoltan_fn_type>_Fn. When a function is registered through a call to Zoltan_Set_Fn, its function type is passed in the fn_type argument. When Zoltan_Set_<zoltan_fn_type>_Fn is used to register functions, the type of the function is implicit in the fn_ptr argument. Each function description below includes both its function type and function prototype.
Migration Query Functions
Query functions that return information about data objects owned by a processor come in two forms: list-based functions that return information about a list of objects, and iterator functions that return information about a single object. Users can provide either version of the query function; they need not provide both. Zoltan calls the list-based functions with the IDs of all objects needed; this approach often provides faster performance as it eliminates the overhead of multiple function calls. List-based functions have the word "MULTI" in their function-type name. If, instead, the application provides iterator functions, Zoltan calls the iterator function once for each object whose data is needed. This approach, while slower, allows Zoltan to use less memory for some data.
Some algorithms in Zoltan require that certain query functions be registered by the application; for example, geometric partitioning algorithms such as Recursive Coordinate Bisection (RCB) require that either a ZOLTAN_GEOM_FN or a ZOLTAN_GEOM_MULTI_FN be registered. When a default value is specified below, the query function type is optional; if a function of that type is not registered, the default values are used. Details of which query functions are required by particular algorithms are included in the Algorithms section.
Many of the functions have both global and local object identifiers (IDs) in their argument lists. The global IDs provided by the application must be unique across all processors; they are used for identification within Zoltan. The local IDs are not used by Zoltan; they are provided for the convenience of the application and can be anything the application desires. The local IDs can be used by application query routines to enable direct access to application data. For example, the object with global ID "3295" may be stored by the application in location "15" of an array in the processor's local memory. Both global ID "3295" and local ID "15" can be used by the application to describe the object. Then, rather than searching the array for global ID "3295," the application query routines can subsequently use the local ID to index directly into the local storage array. See Data Types for Object IDs for a description of global and local IDs. All of the functions have, as their first argument, a pointer to data that is passed to Zoltan through Zoltan_Set_Fn or Zoltan_Set_<zoltan_fn_type>_Fn. This data is not used by Zoltan. A different set of data can be supplied for each registered function. For example, if the local ID is an index into an array of data structures, then the data pointer might point to the head of the data structure array.
As their last argument, all functions have an error code that should be set and returned by the registered function.
If you are calling the Zoltan library from a C++ application, you may
set the query function to be any class static function
or any function
defined outside of a class definition. However, it is possible you
will wish to set the query function to be an object method.
In that case, you should
write a query function that takes a pointer to the object as its
data field. The query function can then call the object