Next: Completing a Thorn
Up: Cactus Application Interfaces
Previous: Interpolation Operators
Contents
Reduction Operators
A reduction operation can be defined as an operation on variables
distributed across multiple processor resulting in a single number.
Typical reduction operations are: sum, minimum/maximum value, and boolean
operations. A typical application is, for example,
finding the maximum reduction from processor local error estimates,
therefore, making the previous processor local error known to all processors.
The exchange of
information across processors needs the functionality of a
communication layer, e.g. CactusPUGH/PUGH. For this reason, the
reduction operation itself is not part of the flesh, instead, Cactus (again)
provides a registration mechanism for thorns to register routines they
provide as reduction operators. The different operators are
identified by their name and/or a unique number, called a handle.
The registration mechanism gives the advantage of a common
interface while hiding the individual communication calls in the
layer.
In Cactus, reduction operators can be applied to
grid functions, arrays and scalars, as well as to local arrays. Note that
different implementations of reduction operators may be limited in
the objects they can be applied to.
There is a fundamental difference between the reduction operation on
grid functions and quantities as arrays.
Currently the flesh supports the new and old reduction specification.
The old APIs will be deprecated in the next beta cycle in favour of the
new specification.
New Reduction Specification API documentation
In the new reduction specification, there are two different flesh APIs for reduction, depending
on whether the data arrays are Cactus grid arrays or processor-local,
programming language built-in arrays, and on what assumptions
are made about the topology and spacing of the grid (these descriptions
are for 3D, but the generalisations to other numbers of dimensions
should be obvious):
- CCTK_ReduceGridArrays()
- Reduces Cactus grid arrays, with the topology of the
grid implicitly specified by a Cactus coordinate system.
This API doesn't provide a reduction functionality itself,
it only takes care of the interprocessor communication
necessary when reducing distributed grid arrays, and invokes
the CCTK_ReduceLocalArrays() API on the each processor's
local patch of the data.
- CCTK_ReduceLocalArrays()
- Reduces processor-local arrays with various options including
offsets, strides and masks.
The flesh provides an API to register local reduction operators:
- CCTK_RegisterLocalArrayReductionOperator()
- Register a
CCTK_ReduceLocalArrays() interpolation operator
This is described in detail in the Reference Manual.
Each local reduction operator is registered under a character string name;
at registration, the name is mapped to a unique integer handle, which
may be used to refer to the operator. CCTK_LocalArrayReductionHandle()
is used to get the handle corresponding to a given character string
name.
Old Reduction Specification API Documentation
Obtaining the reduction handle
Before calling the routine which performs the reduction operation,
the handle, which identifies the operation, must be derived from its
registered name.
int CCTK_ReductionHandle(const char *reduction_name);
integer reduction_handle
character*(*) reduction_name
call CCTK_ReductionHandle(reduction_handle, reduction_name)
int CCTK_ReductionArrayHandle(const char *reduction_name);
integer reduction_handle
character*(*) reduction_name
call CCTK_ReductionArrayHandle(reduction_handle, reduction_name)
- reduction_handle
- in Fortran, the name of the variable will
contain the handle value after the call. In C, this value is the
function value.
- reduction_name
- is the name under which the operator has
been registered by the providing thorn. The only thorn in the standard
Computational Toolkit release, which provides reduction operators, is
CactusPUGH/PUGHReduce.
- error checking
- negative handle value indicates failure to
identify the correct operator.
Get a integer handle corresponding to a given reduction operator.
The operator is identified by the name it was registered with.
(Note that although it would appear to be far more convenient to
pass the name of the reduction operator directly to the following
function call to CCTK_Reduce this causes problems with the
translation of strings from Fortran to C with variable
argument lists).
The general reduction interface.
The main interfaces for reduction operations are quite powerful (and
hence rather complicated). To ease the use of these main interfaces, wrappers
designed for specific and more restricted use are described below. If
uncertain, you should use these.
int CCTK_Reduce( const cGH *GH,
int proc,
int operation_handle,
int num_out_vals,
int type_out_vals,
void *out_vals,
int num_in_fields,
...);
call CCTK_Reduce( int returnvalue,
cctkGH,
int processor,
int operation_handle,
int num_out_vals,
int type_out_vals,
out_vals,
int num_in_fields,
... )
int CCTK_ReduceArray( const cGH *GH,
int proc,
int operation_handle,
int num_out_vals,
int type_out_vals,
void *out_vals,
int num_dims,
int num_in_arrays,
int type_in_arrays,
... )
call CCTK_ReduceArray(int returnvalue,
cctkGH,
int processor,
int operation_handle,
int num_out_vals,
int type_out_arrays,
void out_vals,
int num_dims,
int num_in_arrays,
int type_in_arrays,
... )
- int returnvalue
- the return value of the operation. Negative
value indicates failure to perform reduction.
Zero indicates a successful operation.
- cctkGH
- in Fortran, the pointer to the grid hierarchy
structure. Can not be used within Fortran, but
can be used from within
C. Since this name is fixed, write it out as shown.
- cGH *GH
- in C, it is the pointer to the grid hierarchy.
- int processor
- the processor which collects the
information, a negative value (35#35) will distribute the data to all
processors.
- int operation_handle
- the number of the reduction operation
handle, needs to be found by calling CCTK_ReductionHandle or
CCTK_ReductionArrayHandle.
- int num_out_vals
- integer defining the number of output values.
- int type_out_arrays, type_in_arrays
- specifies the type of the gridfunction
you are communicating. Use the values as specified in Section
B10.8. Note: Do not mix data types, e.g. in
Fortran, do not declare a variable as integer and then specify
the type CCTK_VARIABLE_INT in the reduction command. These
types need not be the same on some architectures and will conflict.
- out_vals
- an array that will contain the output values.
- int num_in_fields
- specifies the number of input fields.
- ...
- indicates a variable argument list: specify the arrays which will be reduced, the number of
specified arrays must be the same as the value of the num_in_fields variable.
- error checking
- a return value, other than zero, indicates
failure to perform the operation.
Special reduction interfaces. The routines are designed for the purpose of reducing scalars, arrays
and grid functions. They hide many of the options of the generic
interface described above.
Reduction of local scalars across multiple processors. The result of
the reduction operation will be on the specified processor or on all processors.
int CCTK_ReduceLocScalar (const cGH *GH,
int processor,
int operation_handle,
void *in_scalar,
void *out_scalar,
int data_type)
call CCTK_ReduceLocScalar(int returnvalue,
cctkGH,
int processor,
int operation_handle,
in_scalar,
out_scalar,
int data_type)
- in_scalar
- the processor local variable with local value to be reduced
- out_scalar
- the reduction result: a processor local variable
with the global value (same on all processors), if processor has been
set to 35#35. Otherwise, processor will hold the reduction result.
- data_type
- specifies the type of the gridfunction
you are communicating. Use the values as specified in Section
B10.8.
Reduction of local 1d arrays to a local arrays. This reduction is carried
out element by element. The arrays need to have the same size on all
processors.
int CCTK_ReduceLocArrayToArray1D( const cGH *GH,
int processor,
int operation_handle,
void *in_array1d,
void *out_array1d,
int xsize,
int data_type)
call CCTK_ReduceLocArrayToArray1D(int returnvalue
cctkGH,
int processor,
int operation_handle,
in_array1d,
out_array1d,
int xsize,
int data_type)
- in_array1d
- one dimensional local arrays to be reduced across a
processors, element by element.
- out_array1d
- array holding the reduction result. out_array1d[1]
= Reduction(in_array[1]).
- xsize
- the size of the one dimensional array.
Reduction of local 2d arrays to a local 2d array. This reduction is carried
out element by element. The arrays need to have the same size on all
processors.
int CCTK_ReduceLocArrayToArray2D( const cGH *GH,
int processor,
int opertaion_handle,
in_array_2d,
out_array2d,
int xsize,
int ysize,
int data_type)
call CCTK_ReduceLocArrayToArray2D( int returnvalue
cctkGH,
int processor,
int operation_handle,
in_array2d,
out_array2d,
int xsize,
int ysize,
int data_type)
- in_array1d
- two dimensional local arrays, to be reduced across a
processors, element by element.
- out_array1d
- two dimensional array holding the reduction
result. out_array2d[i,j]= Reduction(in_array2d[i,j]).
- xsize
- the size of the one dimensional array in x direction.
- ysize
- the size of the one dimensional array in y direction.
Reduction of local 3D arrays to a local 3D array. This reduction is carried
out element by element. The arrays need to have the same size on all
processors.
int CCTK_ReduceLocArrayToArray3D(const cGH *GH,
int processor,
int opertaion_handle,
in_array_3d,
out_array3d,
int xsize,
int ysize,
int zsize,
int data_type)
call CCTK_ReduceLocArrayToArray3D(int returnvalue
cctkGH,
int processor,
int operation_handle,
in_array3d,
out_array3d,
int xsize,
int ysize,
int zsize,
int data_type)
- in_array3d
- two dimensional local arrays, to be reduced across a
processors, element by element.
- out_array3d
- two dimensional array holding the reduction
result. out_array3d[i,j,k]= Reduction(in_array3d[i,j,k]).
- xsize
- the size of the one dimensional array in x direction.
- ysize
- the size of the one dimensional array in y direction.
- ysize
- the size of the one dimensional array in z direction.
Some brief examples:
Reduction of a local scalars: a local error is reduced across all
processors with the maximum operation. The variable tmp will
hold the maximum of the error and is the same on all
processors. This quantity can then be reassigned to normerr.
CCTK_REAL normerr, tmp
integer ierr, reduction_handle
call CCTK_ReductionArrayHandle(reduction_handle,"maximum")
if (reduction_handle.lt.0) then
call CCTK_WARN(CCTK_WARN_ALERT, "Cannot get reduction handle for maximum operation.")
endif
call CCTK_ReduceLocScalar(ierr, cctkGH, -1,
. reduction_handle,
. normerr, tmp, CCTK_VARIABLE_REAL)
if (ierr.ne.0) then
call CCTK_WARN(CCTK_WARN_ALERT, "Reduction of norm failed!");
endif
normerr = tmp
Reduction of a local 2D array: a two dimensional array 36#36 is
reduced, reduction results (array of same size: bla_tmp) are seen
on all processors (35#35 entry as the third argument); also demonstrates
some simple error checking with the CCTKi_EXPECTOK macro.
CCTK_REAL bla(2,3),bla_tmp(2,3);
integer ierr, sum_handle
call CCTK_ReductionArrayHandle(sum_handle,"sum")
bla = 1.0d0
write (*,*) "BLA ",bla
call CCTK_ReduceLocArrayToArray2D(ierr, cctkGH, -1, sum_handle,
. bla, bla_tmp, 2, 3, CCTK_VARIABLE_REAL)
call CCTKi_EXPECTOK(ierr, 0, 1, "2D Reduction failed")
bla = bla_tmp
write (*,*) "BLA ",bla
Note that the memory for the returned values must be allocated before
the reduction call is made.
Next: Completing a Thorn
Up: Cactus Application Interfaces
Previous: Interpolation Operators
Contents
|