/*@@ @file Reduction.c @date Thu Apr 3 11:54:53 1997 @author Thomas Radke, Paul Walker @desc Various MPI reduction operators. @enddesc @version $Id$ @@*/ #include #include "local_reductions.h" static const char *rcsid = "$Header$"; CCTK_FILEVERSION(CCTDevelopment_LocalReduce_Reduction_c); /******************************************************************** ********************* Local Routine Prototypes ********************* ********************************************************************/ static int copy_real_to_outtype (int num_elems, CCTK_REAL inarray [/* num_elems */], int outtype, void *outarray /* [num_elems] */); /******************************************************************** ********************* External Routines ********************** ********************************************************************/ /*@@ @routine LocalReduce_Reduce @author Thomas Radke, Yaakoub El Khamra @date @desc Wrapper to reduce a list of arrays. Just calls the appropriate reduction operator and does the type conversion of the results. @enddesc @history @endhistory @var N_dims @vdesc number of dimensions in the *reduction* @vtype int @vio in @endvar @var operator_handle @vdesc operator handle specificies the type of reduction we will perform @vtype int @vio in @endvar @var param_table_handle @vdesc handle to "parameter table", a key-value table @vtype int @vio in @endvar @var N_input_arrays @vdesc number of input arrays @vtype int @vio in @endvar @var input_array_dims @vdesc array of input array dimensions (common to all input arrays) @vtype const CCTK_INT @vio in @endvar @var input_array_type_codes @vdesc array of CCTK_VARIABLE_* codes giving data types of input arrays @vtype const CCTK_INT @vio in @endvar @var input_arrays @vdesc array of pointers to input arrays @vtype const void *const @vio in @endvar @var M_output_numbers @vdesc @vtype int @vio in @endvar @var output_number_type_codes @vdesc array of CCTK_VARIABLE_* codes giving data types of output numbers @vtype const CCTK_INT @vio in @endvar @var output_numbers @vdesc array[M_output_numbers] of pointers to output numbers[M_reduce_numbers] @vtype void *const @vio in @endvar @@*/ int LocalReduce_Reduce (int N_dims, int operator_handle, int param_table_handle, int N_input_arrays, const CCTK_INT input_array_dims[], const CCTK_INT input_array_type_codes[], const void *const input_arrays[], int M_output_numbers, const CCTK_INT output_number_type_codes[], void *const output_numbers[], reduction_fn_t reduction_fn) { int i, num_points, retval; int from[1], to[1], iterator[1], points_per_dim[1]; int *intypes; CCTK_REAL *buffer; points_per_dim[0] = 1; from[0] = 0; to[0] = input_array_dims[0]; /* get the total number of array elements */ for (i = 1; i < N_dims; i++) { to[0] *= input_array_dims[i]; } /* check for zero-sized arrays */ if (to[0] <= 0) { CCTK_WARN (2, "LocalReduce_Reduce: Cannot reduce zero-sized arrays"); return (-1); } if (M_output_numbers != 1) { if (M_output_numbers != to[0]) { CCTK_VWarn (1, __LINE__, __FILE__, CCTK_THORNSTRING, "LocalLocalReduce_Reduce: Don't know how to reduce " "a %d-dimensional array with %d elements " "to an output array of %d elements", N_dims, to[0], M_output_numbers); return (-2); } to[0] = 1; } num_points = to[0]; /* set the array types to intype */ /* FIXME: could allow to pass in arrays of different types now !!! */ intypes = malloc (N_input_arrays * sizeof (int)); for (i = 0; i < N_input_arrays; i++) { intypes[i] = input_array_type_codes[i]; } buffer = malloc (M_output_numbers * sizeof (CCTK_REAL)); /* do the reduction on the input arrays */ retval = reduction_fn (N_dims, from, to, iterator, points_per_dim, num_points, 1, N_input_arrays, intypes, input_arrays, M_output_numbers, buffer); if (retval == 0 ) { /* type-cast the result to the requested datatype */ /* retval = copy_real_to_outtype (N_input_arrays * M_output_numbers, buffer, output_number_type_codes, output_numbers);*/ } free (intypes); free (buffer); return (retval); } /*@@ @routine copy_real_to_outtype @author Thomas Radke @date 19 Aug 1999 @desc Does the type conversion from CCTK_REAL into the requested datatype. @enddesc @calls CCTK_VarTypeSize CCTK_GroupTypeFromVarI ReductionScalar copy_real_to_outtype @var num_elems @vdesc number of elements to convert @vtype int @vio in @endvar @var inarray @vdesc input array with results of reductions @vtype CCTK_REAL * @vio in @endvar @var outtype @vdesc requested output datatype @vtype int @vio in @endvar @var outarray @vdesc pointer to output buffer to store the converted results @vtype void * @vio out @endvar @returntype int @returndesc 0 for success, or
-1 if conversion into target datatype is not supported. @endreturndesc @@*/ static int copy_real_to_outtype (int num_elems, CCTK_REAL inarray[/* num_elems */], int outtype, void *outarray /* [num_elems] */) { int i, retval; retval = 0; if (outtype == CCTK_VARIABLE_CHAR) { CCTK_BYTE *_outarray = (CCTK_CHAR *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_BYTE) inarray[i]; } } else if (outtype == CCTK_VARIABLE_INT) { CCTK_INT *_outarray = (CCTK_INT *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_INT) inarray[i]; } } #ifdef CCTK_INT1 else if (outtype == CCTK_VARIABLE_INT1) { CCTK_INT1 *_outarray = (CCTK_INT1 *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_INT1) inarray[i]; } } #endif #ifdef CCTK_INT2 else if (outtype == CCTK_VARIABLE_INT2) { CCTK_INT2 *_outarray = (CCTK_INT2 *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_INT2) inarray[i]; } } #endif #ifdef CCTK_INT4 else if (outtype == CCTK_VARIABLE_INT4) { CCTK_INT4 *_outarray = (CCTK_INT4 *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_INT4) inarray[i]; } } #endif #ifdef CCTK_INT8 else if (outtype == CCTK_VARIABLE_INT8) { CCTK_INT8 *_outarray = (CCTK_INT8 *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_INT8) inarray[i]; } } #endif else if (outtype == CCTK_VARIABLE_REAL) { CCTK_REAL *_outarray = (CCTK_REAL *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_REAL) inarray[i]; } } #ifdef CCTK_REAL4 else if (outtype == CCTK_VARIABLE_REAL4) { CCTK_REAL4 *_outarray = (CCTK_REAL4 *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_REAL4) inarray[i]; } } #endif #ifdef CCTK_REAL8 else if (outtype == CCTK_VARIABLE_REAL8) { CCTK_REAL8 *_outarray = (CCTK_REAL8 *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_REAL8) inarray[i]; } } #endif #ifdef CCTK_REAL16 else if (outtype == CCTK_VARIABLE_REAL16) { CCTK_REAL16 *_outarray = (CCTK_REAL16 *) outarray; for (i = 0; i < num_elems; i++) { _outarray[i] = (CCTK_REAL16) inarray[i]; } } #endif else { CCTK_WARN (1, "copy_real_to_outtype: Unsupported output type"); retval = -1; } return (retval); }