RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RTOp_ROp_max_abs_ele.c
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
6 // Copyright (2003) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 */
43 
44 #include <math.h>
45 
46 #include "RTOp_ROp_max_abs_ele.h"
47 #include "RTOp_obj_null_vtbl.h"
48 #include "RTOp_obj_value_vtbl.h"
49 #include "RTOp_obj_free_free.h"
50 #include "RTOp_get_reduct_op.hpp"
51 
52 /* */
53 /* Implementation functions */
54 /* */
55 
56 /* Selected functions that are used to implement exteral_reduct_op */
57 
58 static int CALL_API targ_extract_state(
59  const struct RTOp_obj_type_vtbl_t* vtbl
60  ,const void * instance_data
61  ,void * obj
62  ,int num_values
63  ,RTOp_value_type value_data[]
64  ,int num_indexes
65  ,RTOp_index_type index_data[]
66  ,int num_chars
67  ,RTOp_char_type char_data[]
68  )
69 {
70  struct RTOp_value_index_type* vi_obj;
71 #ifdef RTOp_DEBUG
72  assert( obj );
73  assert( num_values == 1 );
74  assert( num_indexes == 1 );
75  assert( num_chars == 0 );
76 #endif
77  vi_obj = (struct RTOp_value_index_type*)obj;
78  value_data[0] = vi_obj->value;
79  index_data[0] = vi_obj->index;
80  return 0;
81 }
82 
83 static int CALL_API targ_load_state(
84  const struct RTOp_obj_type_vtbl_t* vtbl
85  ,const void * instance_data
86  ,int num_values
87  ,const RTOp_value_type value_data[]
88  ,int num_indexes
89  ,const RTOp_index_type index_data[]
90  ,int num_chars
91  ,const RTOp_char_type char_data[]
92  ,void ** obj
93  )
94 {
95  struct RTOp_value_index_type* vi_obj;
96 #ifdef RTOp_DEBUG
97  assert( obj );
98  assert( *obj );
99  assert( num_values == 1 );
100  assert( num_indexes == 1 );
101  assert( num_chars == 0 );
102 #endif
103  vi_obj = (struct RTOp_value_index_type*)*obj;
104  vi_obj->value = value_data[0];
105  vi_obj->index = index_data[0];
106  return 0;
107 }
108 
109 /* Other functions */
110 
111 static int RTOp_ROp_max_abs_ele_apply_op(
112  const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
113  ,const int num_vecs, const struct RTOp_SubVector vecs[]
114  ,const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
115  ,RTOp_ReductTarget targ_obj
116  )
117 {
118  /* */
119  /* Declare local variables */
120  /* */
121 
122  /* targ */
123  struct RTOp_value_index_type
124  *targ = NULL;
125  /* global_off */
126  size_t global_offset;
127  /* sub_dim */
128  size_t sub_dim;
129  /* v */
130  const RTOp_value_type *v_val = NULL;
131  ptrdiff_t v_val_s;
132 
133  register size_t k;
134  RTOp_index_type i;
135  RTOp_value_type abs_v_i;
136 
137  /* */
138  /* Validate the input */
139  /* */
140  if( num_vecs != 1 )
141  return RTOp_ERR_INVALID_NUM_VECS;
142  if( num_targ_vecs != 0 )
143  return RTOp_ERR_INVALID_NUM_TARG_VECS;
144 
145  /* */
146  /* Get pointers to the data */
147  /* */
148 
149  /* targ */
150  targ = (struct RTOp_value_index_type*)targ_obj;
151  /* global_off */
152  global_offset = vecs[0].global_offset;
153  /* sub_dim */
154  sub_dim = vecs[0].sub_dim;
155  /* v */
156  v_val = vecs[0].values;
157  v_val_s = vecs[0].values_stride;
158 
159  /* */
160  /* Perform the reduction operation. */
161  /* */
162 
163  i = global_offset + 1;
164  for( k = 0; k < sub_dim; ++k, ++i, v_val += v_val_s ) {
165  abs_v_i = fabs(*v_val);
166  if( abs_v_i > targ->value || ( abs_v_i == targ->value && i < targ->index ) || targ->index == 0 ) {
167  targ->value = *v_val;
168  targ->index = i;
169  }
170  }
171 
172  return 0; /* success? */
173 }
174 
175 static int reduce_reduct_objs(
176  const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data /* Can be NULL! */
177  , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj )
178 {
179  const struct RTOp_value_index_type
180  *i_targ = (const struct RTOp_value_index_type*)in_reduct_obj;
181  struct RTOp_value_index_type
182  *io_targ = (struct RTOp_value_index_type*)inout_reduct_obj;
183  RTOp_value_type
184  i_abs_val = fabs(i_targ->value),
185  io_abs_val = fabs(io_targ->value);
186  if(
187  ( i_abs_val > io_abs_val )
188  ||
189  ( i_abs_val > io_abs_val && i_targ->index < io_targ->index )
190  )
191  {
192  io_targ->value = i_targ->value;
193  io_targ->index = i_targ->index;
194  }
195  return 0;
196 }
197 
198 INSERT_GET_REDUCT_OP_FUNCS(
199  1,1,0,RTOp_value_index_type,reduce_reduct_objs
200  ,targ_load_state,targ_extract_state
201  ,external_reduct_op,get_reduct_op)
202 
203 const struct RTOp_RTOp_vtbl_t RTOp_ROp_max_abs_ele_vtbl =
204 {
205  &RTOp_obj_null_vtbl
206  ,&RTOp_obj_value_index_vtbl
207  ,"ROp_max_abs_ele"
208  ,NULL
209  ,RTOp_ROp_max_abs_ele_apply_op
210  ,reduce_reduct_objs
211  ,get_reduct_op
212 };
213 
214 /* Class specific functions */
215 
216 int RTOp_ROp_max_abs_ele_construct( struct RTOp_RTOp* op )
217 {
218  op->vtbl = &RTOp_ROp_max_abs_ele_vtbl;
219  op->obj_data = NULL;
220  return 0; /* success? */
221 }
222 
223 int RTOp_ROp_max_abs_ele_destroy( struct RTOp_RTOp* op )
224 {
225  op->vtbl = NULL;
226  op->obj_data = NULL;
227  return 0; /* success? */
228 }
229 
230 struct RTOp_value_index_type
231 RTOp_ROp_max_abs_ele_val(RTOp_ReductTarget targ_obj)
232 {
233  return *(struct RTOp_value_index_type*)targ_obj;
234 }