|
RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators
Version of the Day
|
00001 /* 00002 // @HEADER 00003 // *********************************************************************** 00004 // 00005 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization 00006 // Copyright (2003) Sandia Corporation 00007 // 00008 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive 00009 // license for use of this work by or on behalf of the U.S. Government. 00010 // 00011 // Redistribution and use in source and binary forms, with or without 00012 // modification, are permitted provided that the following conditions are 00013 // met: 00014 // 00015 // 1. Redistributions of source code must retain the above copyright 00016 // notice, this list of conditions and the following disclaimer. 00017 // 00018 // 2. Redistributions in binary form must reproduce the above copyright 00019 // notice, this list of conditions and the following disclaimer in the 00020 // documentation and/or other materials provided with the distribution. 00021 // 00022 // 3. Neither the name of the Corporation nor the names of the 00023 // contributors may be used to endorse or promote products derived from 00024 // this software without specific prior written permission. 00025 // 00026 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY 00027 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00028 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 00029 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE 00030 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 00031 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 00032 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 00033 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 00034 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 00035 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 00036 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00037 // 00038 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov) 00039 // 00040 // *********************************************************************** 00041 // @HEADER 00042 */ 00043 00044 #include <math.h> 00045 00046 #define max(a,b) ( (a) > (b) ? (a) : (b) ) 00047 #define min(a,b) ( (a) < (b) ? (a) : (b) ) 00048 00049 #include "RTOp_ROp_max_inequ_viol.h" 00050 #include "RTOp_obj_null_vtbl.h" 00051 #include "RTOp_obj_value_vtbl.h" 00052 #include "RTOp_obj_free_free.h" 00053 #include "RTOp_get_reduct_op.hpp" 00054 00055 #include <stdlib.h> 00056 00057 /* */ 00058 /* Implementation functions */ 00059 /* */ 00060 00061 /* Functions for the reduction target object */ 00062 00063 static int get_targ_type_num_entries( 00064 const struct RTOp_obj_type_vtbl_t* vtbl 00065 ,const void* obj_data 00066 ,int* num_values 00067 ,int* num_indexes 00068 ,int* num_chars 00069 ) 00070 { 00071 *num_values = 3; 00072 *num_indexes = 2; 00073 *num_chars = 0; 00074 return 0; 00075 } 00076 00077 static int targ_obj_reinit( 00078 const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data 00079 , RTOp_ReductTarget targ_obj ) 00080 { 00081 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00082 *targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj; 00083 targ->max_viol = 0.0; /* None violated yet! */ 00084 targ->v_i = 0.0; /* arbitrary */ 00085 targ->vLU_i = 0.0; /* arbitrary */ 00086 targ->max_viol_i = 0; /* None violated yet! */ 00087 targ->bnd_type = -2; /* Invalid type (just in case used by accident) */ 00088 return 0; 00089 } 00090 00091 static int targ_obj_create( 00092 const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data 00093 ,RTOp_ReductTarget* targ_obj 00094 ) 00095 { 00096 const int mem_size = sizeof(struct RTOp_ROp_max_inequ_viol_reduct_obj_t); 00097 *targ_obj = malloc( mem_size ); 00098 return targ_obj_reinit(vtbl,obj_data,*targ_obj); 00099 } 00100 00101 static int targ_extract_state( 00102 const struct RTOp_obj_type_vtbl_t* vtbl 00103 ,const void * obj_data 00104 ,void * reduct_obj 00105 ,int num_values 00106 ,RTOp_value_type value_data[] 00107 ,int num_indexes 00108 ,RTOp_index_type index_data[] 00109 ,int num_chars 00110 ,RTOp_char_type char_data[] 00111 ) 00112 { 00113 struct RTOp_ROp_max_inequ_viol_reduct_obj_t *targ = NULL; 00114 assert( reduct_obj ); 00115 assert( num_values == 3 ); 00116 assert( num_indexes == 3 ); 00117 assert( num_chars == 0 ); 00118 targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)reduct_obj; 00119 value_data[0] = targ->max_viol; 00120 value_data[1] = targ->v_i; 00121 value_data[2] = targ->vLU_i; 00122 index_data[0] = targ->max_viol_i; 00123 index_data[1] = targ->bnd_type; 00124 return 0; 00125 } 00126 00127 static int targ_load_state( 00128 const struct RTOp_obj_type_vtbl_t* vtbl 00129 ,const void* obj_data 00130 ,int num_values 00131 ,const RTOp_value_type value_data[] 00132 ,int num_indexes 00133 ,const RTOp_index_type index_data[] 00134 ,int num_chars 00135 ,const RTOp_char_type char_data[] 00136 ,void ** reduct_obj 00137 ) 00138 { 00139 struct RTOp_ROp_max_inequ_viol_reduct_obj_t *targ = NULL; 00140 assert( *reduct_obj ); 00141 assert( num_values == 3 ); 00142 assert( num_indexes == 2 ); 00143 assert( num_chars == 0 ); 00144 targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)*reduct_obj; 00145 targ->max_viol = value_data[0]; 00146 targ->v_i = value_data[1]; 00147 targ->vLU_i = value_data[2]; 00148 targ->max_viol_i = index_data[0]; 00149 targ->bnd_type = index_data[1]; 00150 return 0; 00151 } 00152 00153 static const struct RTOp_obj_type_vtbl_t targ_obj_vtbl = 00154 { 00155 get_targ_type_num_entries 00156 ,targ_obj_create 00157 ,targ_obj_reinit 00158 ,RTOp_obj_free_free 00159 ,targ_extract_state 00160 ,targ_load_state 00161 }; 00162 00163 /* Other functions */ 00164 00165 static int RTOp_ROp_max_inequ_viol_apply_op( 00166 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data 00167 ,const int num_vecs, const struct RTOp_SubVector vecs[] 00168 ,const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[] 00169 ,RTOp_ReductTarget targ_obj 00170 ) 00171 { 00172 /* */ 00173 /* Declare local variables */ 00174 /* */ 00175 00176 /* targ */ 00177 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00178 *targ = NULL; 00179 /* global_off */ 00180 size_t global_offset; 00181 /* sub_dim */ 00182 size_t sub_dim; 00183 /* v */ 00184 const RTOp_value_type *v_val = NULL; 00185 ptrdiff_t v_val_s; 00186 /* vL */ 00187 const RTOp_value_type *vL_val = NULL; 00188 ptrdiff_t vL_val_s; 00189 /* vU */ 00190 const RTOp_value_type *vU_val = NULL; 00191 ptrdiff_t vU_val_s; 00192 00193 register size_t k; 00194 RTOp_index_type i; 00195 RTOp_value_type v_scale; 00196 RTOp_value_type violL; 00197 RTOp_value_type violU; 00198 00199 /* */ 00200 /* Validate the input */ 00201 /* */ 00202 if( num_vecs != 3 ) 00203 return RTOp_ERR_INVALID_NUM_VECS; 00204 if( num_targ_vecs != 0 ) 00205 return RTOp_ERR_INVALID_NUM_TARG_VECS; 00206 if( vecs[0].global_offset != vecs[1].global_offset 00207 || vecs[0].sub_dim != vecs[1].sub_dim 00208 || vecs[0].global_offset != vecs[2].global_offset 00209 || vecs[0].sub_dim != vecs[2].sub_dim ) 00210 return RTOp_ERR_INCOMPATIBLE_VECS; 00211 00212 /* */ 00213 /* Get pointers to the data */ 00214 /* */ 00215 00216 /* targ */ 00217 targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj; 00218 /* global_off */ 00219 global_offset = vecs[0].global_offset; 00220 /* sub_dim */ 00221 sub_dim = vecs[0].sub_dim; 00222 /* v */ 00223 v_val = vecs[0].values; 00224 v_val_s = vecs[0].values_stride; 00225 /* vL */ 00226 vL_val = vecs[1].values; 00227 vL_val_s = vecs[1].values_stride; 00228 /* vU */ 00229 vU_val = vecs[2].values; 00230 vU_val_s = vecs[2].values_stride; 00231 00232 /* */ 00233 /* Perform the reduction operation. */ 00234 /* */ 00235 00236 i = global_offset + 1; 00237 for( k = 0; k < sub_dim; ++k, ++i, v_val += v_val_s, vL_val += vL_val_s, vU_val += vU_val_s ) { 00238 v_scale = 1.0 / (1.0 + fabs(*v_val)); 00239 /* (vL - v)*v_scale */ 00240 violL = (*vL_val - *v_val) * v_scale; 00241 /* (v - vU)*v_scale */ 00242 violU = (*v_val - *vU_val) * v_scale; 00243 /* Perform the reduction */ 00244 if( 00245 ( max(violL,violU) > targ->max_viol ) 00246 || 00247 ( max(violL,violU) == targ->max_viol && i < targ->max_viol_i ) 00248 ) 00249 { 00250 targ->bnd_type = ( violL > 0.0 00251 ? ( *vL_val == *vU_val 00252 ? 0 /* EQUALITY */ 00253 : -1 /* LOWER */ 00254 ) 00255 : +1 /* UPPER */ 00256 ); 00257 targ->max_viol = ( targ->bnd_type <= 0 ? violL : violU ); 00258 targ->v_i = *v_val; 00259 targ->vLU_i = ( targ->bnd_type <= 0 ? *vL_val : *vU_val ); 00260 targ->max_viol_i = i; 00261 } 00262 } 00263 00264 return 0; /* success? */ 00265 } 00266 00267 static int reduce_reduct_objs( 00268 const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data /* Can be NULL! */ 00269 , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj ) 00270 { 00271 const struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00272 *i_targ = (const struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)in_reduct_obj; 00273 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00274 *io_targ = (struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)inout_reduct_obj; 00275 00276 if( 00277 ( i_targ->max_viol > io_targ->max_viol ) 00278 || 00279 ( i_targ->max_viol == io_targ->max_viol && i_targ->max_viol_i < io_targ->max_viol_i ) 00280 ) 00281 { 00282 io_targ->max_viol = i_targ->max_viol; 00283 io_targ->v_i = i_targ->v_i; 00284 io_targ->vLU_i = i_targ->vLU_i; 00285 io_targ->max_viol_i = i_targ->max_viol_i; 00286 io_targ->bnd_type = i_targ->bnd_type; 00287 } 00288 return 0; 00289 } 00290 00291 INSERT_GET_REDUCT_OP_FUNCS( 00292 3,2,0,RTOp_ROp_max_inequ_viol_reduct_obj_t,reduce_reduct_objs 00293 ,targ_load_state,targ_extract_state 00294 ,external_reduct_op,get_reduct_op) 00295 00296 const struct RTOp_RTOp_vtbl_t RTOp_ROp_max_inequ_viol_vtbl = 00297 { 00298 &RTOp_obj_null_vtbl 00299 ,&targ_obj_vtbl 00300 ,"ROp_max_inequ_viol" 00301 ,NULL 00302 ,RTOp_ROp_max_inequ_viol_apply_op 00303 ,reduce_reduct_objs 00304 ,get_reduct_op 00305 }; 00306 00307 /* Class specific functions */ 00308 00309 int RTOp_ROp_max_inequ_viol_construct( struct RTOp_RTOp* op ) 00310 { 00311 op->vtbl = &RTOp_ROp_max_inequ_viol_vtbl; 00312 op->obj_data = NULL; 00313 return 0; /* success? */ 00314 } 00315 00316 int RTOp_ROp_max_inequ_viol_destroy( struct RTOp_RTOp* op ) 00317 { 00318 op->vtbl = NULL; 00319 op->obj_data = NULL; 00320 return 0; /* success? */ 00321 } 00322 00323 struct RTOp_ROp_max_inequ_viol_reduct_obj_t 00324 RTOp_ROp_max_inequ_viol_val(RTOp_ReductTarget targ_obj) 00325 { 00326 return *(struct RTOp_ROp_max_inequ_viol_reduct_obj_t*)targ_obj; 00327 }
1.7.6.1