|
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 <stdio.h> 00045 #include <assert.h> 00046 #include <string.h> 00047 00048 #include "RTOp.h" 00049 00050 /* Misc. */ 00051 00052 void RTOp_sub_vector( 00053 RTOp_index_type global_offset, RTOp_index_type sub_dim 00054 ,const RTOp_value_type values[], ptrdiff_t values_stride 00055 ,struct RTOp_SubVector *sub_vec 00056 ) 00057 { 00058 /* Validate input */ 00059 #ifdef RTOp_DEBUG 00060 assert( values != NULL ); 00061 #endif 00062 /* Set members */ 00063 sub_vec->global_offset = global_offset; 00064 sub_vec->sub_dim = sub_dim; 00065 sub_vec->values = values; 00066 sub_vec->values_stride = values_stride; 00067 } 00068 00069 void RTOp_sub_vector_null( struct RTOp_SubVector *sub_vec ) 00070 { 00071 sub_vec->global_offset = 0; 00072 sub_vec->sub_dim = 0; 00073 sub_vec->values = NULL; 00074 sub_vec->values_stride = 0; 00075 } 00076 00077 void RTOp_mutable_sub_vector( 00078 RTOp_index_type global_offset, RTOp_index_type sub_dim 00079 ,RTOp_value_type values[], ptrdiff_t values_stride 00080 ,struct RTOp_MutableSubVector *sub_vec 00081 ) 00082 { 00083 /* Validate input */ 00084 #ifdef RTOp_DEBUG 00085 assert( sub_vec ); 00086 assert( values != NULL ); 00087 #endif 00088 /* Set members */ 00089 sub_vec->global_offset = global_offset; 00090 sub_vec->sub_dim = sub_dim; 00091 sub_vec->values = values; 00092 sub_vec->values_stride = values_stride; 00093 } 00094 00095 void RTOp_mutable_sub_vector_null( struct RTOp_MutableSubVector *sub_vec ) 00096 { 00097 #ifdef RTOp_DEBUG 00098 assert( sub_vec ); 00099 #endif 00100 sub_vec->global_offset = 0; 00101 sub_vec->sub_dim = 0; 00102 sub_vec->values = NULL; 00103 sub_vec->values_stride = 0; 00104 } 00105 00106 /* RTOp_RTOp */ 00107 00108 int RTOp_get_op_name( 00109 const struct RTOp_RTOp* op 00110 ,const char** op_name 00111 ) 00112 { 00113 #ifdef RTOp_DEBUG 00114 assert( op ); 00115 assert( op->vtbl ); 00116 assert( op->vtbl->op_name ); 00117 assert( op_name ); 00118 #endif 00119 *op_name = op->vtbl->op_name; 00120 return 0; 00121 } 00122 00123 int RTOp_get_op_type_num_entries( 00124 const struct RTOp_RTOp* op 00125 ,int* num_values 00126 ,int* num_indexes 00127 ,int* num_chars 00128 ) 00129 { 00130 #ifdef RTOp_DEBUG 00131 assert( op ); 00132 assert( op->vtbl ); 00133 assert( op->vtbl->obj_data_vtbl ); 00134 assert( op->vtbl->obj_data_vtbl->get_obj_type_num_entries ); 00135 assert( num_values ); 00136 assert( num_indexes ); 00137 assert( num_chars ); 00138 #endif 00139 return op->vtbl->obj_data_vtbl->get_obj_type_num_entries( 00140 op->vtbl->obj_data_vtbl,op->obj_data 00141 , num_values, num_indexes, num_chars ); 00142 } 00143 00144 int RTOp_extract_op_state( 00145 const struct RTOp_RTOp* op 00146 ,int num_values 00147 ,RTOp_value_type value_data[] 00148 ,int num_indexes 00149 ,RTOp_index_type index_data[] 00150 ,int num_chars 00151 ,RTOp_char_type char_data[] 00152 ) 00153 { 00154 #ifdef RTOp_DEBUG 00155 assert( op ); 00156 assert( op->vtbl ); 00157 assert( op->vtbl->obj_data_vtbl ); 00158 assert( op->vtbl->obj_data_vtbl->extract_state ); 00159 if(num_values) assert( value_data ); 00160 if(num_indexes) assert( index_data ); 00161 if(num_chars) assert( char_data ); 00162 #endif 00163 return op->vtbl->obj_data_vtbl->extract_state( 00164 op->vtbl->obj_data_vtbl, NULL, op->obj_data 00165 , num_values, value_data 00166 , num_indexes, index_data 00167 , num_chars, char_data ); 00168 } 00169 00170 int RTOp_load_op_state( 00171 int num_values 00172 ,const RTOp_value_type value_data[] 00173 ,int num_indexes 00174 ,const RTOp_index_type index_data[] 00175 ,int num_chars 00176 ,const RTOp_char_type char_data[] 00177 ,struct RTOp_RTOp* op 00178 ) 00179 { 00180 #ifdef RTOp_DEBUG 00181 assert( op ); 00182 assert( op->vtbl ); 00183 assert( op->vtbl->obj_data_vtbl ); 00184 assert( op->vtbl->obj_data_vtbl->load_state ); 00185 if(num_values) assert( value_data ); 00186 if(num_indexes) assert( index_data ); 00187 if(num_chars) assert( char_data ); 00188 #endif 00189 return op->vtbl->obj_data_vtbl->load_state( 00190 op->vtbl->obj_data_vtbl, NULL 00191 ,num_values, value_data 00192 ,num_indexes, index_data 00193 ,num_chars, char_data 00194 , &op->obj_data ); 00195 } 00196 00197 int RTOp_free_op( struct RTOp_RTOp* op ) 00198 { 00199 #ifdef RTOp_DEBUG 00200 assert( op ); 00201 assert( op->vtbl ); 00202 assert( op->vtbl->obj_data_vtbl ); 00203 assert( op->vtbl->obj_data_vtbl->obj_free ); 00204 #endif 00205 return op->vtbl->obj_data_vtbl->obj_free( 00206 op->vtbl->obj_data_vtbl,NULL,&op->obj_data ); 00207 } 00208 00209 int RTOp_get_reduct_type_num_entries( 00210 const struct RTOp_RTOp* op 00211 ,int* num_values 00212 ,int* num_indexes 00213 ,int* num_chars 00214 ) 00215 { 00216 #ifdef RTOp_DEBUG 00217 assert( op ); 00218 assert( op->vtbl ); 00219 assert( op->vtbl->reduct_vtbl ); 00220 assert( op->vtbl->reduct_vtbl->get_obj_type_num_entries ); 00221 assert( num_values ); 00222 assert( num_indexes ); 00223 assert( num_chars ); 00224 #endif 00225 return op->vtbl->reduct_vtbl->get_obj_type_num_entries( 00226 op->vtbl->reduct_vtbl, op->obj_data 00227 , num_values, num_indexes, num_chars ); 00228 } 00229 00230 int RTOp_reduct_obj_create( const struct RTOp_RTOp* op 00231 , RTOp_ReductTarget* reduct_obj ) 00232 { 00233 int err = 0; 00234 #ifdef RTOp_DEBUG 00235 assert( op ); 00236 assert( op->vtbl ); 00237 assert( op->vtbl->reduct_vtbl ); 00238 assert( op->vtbl->reduct_vtbl->obj_create ); 00239 #endif 00240 err = op->vtbl->reduct_vtbl->obj_create( 00241 op->vtbl->reduct_vtbl,op->obj_data,reduct_obj ); 00242 if(err) return err; 00243 if( op->vtbl->reduct_obj_reinit ) 00244 return op->vtbl->reduct_obj_reinit( 00245 op->vtbl,op->obj_data,*reduct_obj ); 00246 return err; 00247 } 00248 00249 int RTOp_reduct_obj_reinit( const struct RTOp_RTOp* op 00250 , RTOp_ReductTarget reduct_obj ) 00251 { 00252 #ifdef RTOp_DEBUG 00253 assert( op ); 00254 assert( op->vtbl ); 00255 assert( op->vtbl->reduct_vtbl ); 00256 assert( op->vtbl->reduct_vtbl->obj_reinit ); 00257 assert( reduct_obj != RTOp_REDUCT_OBJ_NULL ); 00258 #endif 00259 if( op->vtbl->reduct_obj_reinit ) 00260 return op->vtbl->reduct_obj_reinit( 00261 op->vtbl,op->obj_data,reduct_obj ); 00262 else 00263 return op->vtbl->reduct_vtbl->obj_reinit( 00264 op->vtbl->reduct_vtbl,op->obj_data,reduct_obj ); 00265 } 00266 00267 int RTOp_reduct_obj_free( const struct RTOp_RTOp* op 00268 , RTOp_ReductTarget* reduct_obj ) 00269 { 00270 #ifdef RTOp_DEBUG 00271 assert( op ); 00272 assert( op->vtbl ); 00273 assert( op->vtbl->reduct_vtbl ); 00274 assert( op->vtbl->reduct_vtbl->obj_free ); 00275 #endif 00276 return op->vtbl->reduct_vtbl->obj_free( 00277 op->vtbl->reduct_vtbl,op->obj_data,reduct_obj); 00278 } 00279 00280 int RTOp_extract_reduct_obj_state( 00281 const struct RTOp_RTOp* op 00282 ,const RTOp_ReductTarget reduct_obj 00283 ,int num_values 00284 ,RTOp_value_type value_data[] 00285 ,int num_indexes 00286 ,RTOp_index_type index_data[] 00287 ,int num_chars 00288 ,RTOp_char_type char_data[] 00289 ) 00290 { 00291 #ifdef RTOp_DEBUG 00292 assert( op ); 00293 assert( op->vtbl ); 00294 assert( op->vtbl->reduct_vtbl ); 00295 assert( op->vtbl->reduct_vtbl->extract_state ); 00296 if(num_values) assert( value_data ); 00297 if(num_indexes) assert( index_data ); 00298 if(num_chars) assert( char_data ); 00299 #endif 00300 return op->vtbl->reduct_vtbl->extract_state( 00301 op->vtbl->reduct_vtbl, op->obj_data, reduct_obj 00302 ,num_values, value_data 00303 ,num_indexes, index_data 00304 ,num_chars, char_data ); 00305 } 00306 00307 int RTOp_load_reduct_obj_state( 00308 const struct RTOp_RTOp* op 00309 ,int num_values 00310 ,const RTOp_value_type value_data[] 00311 ,int num_indexes 00312 ,const RTOp_index_type index_data[] 00313 ,int num_chars 00314 ,const RTOp_char_type char_data[] 00315 ,RTOp_ReductTarget reduct_obj 00316 ) 00317 { 00318 RTOp_ReductTarget reduct_obj_in = reduct_obj; /* Just keep a reference */ 00319 int err = 0; 00320 #ifdef RTOp_DEBUG 00321 assert( op ); 00322 assert( op->vtbl ); 00323 assert( op->vtbl->reduct_vtbl ); 00324 assert( op->vtbl->reduct_vtbl->load_state ); 00325 if(num_values) assert( value_data ); 00326 if(num_indexes) assert( index_data ); 00327 if(num_chars) assert( char_data ); 00328 #endif 00329 err = op->vtbl->reduct_vtbl->load_state( 00330 op->vtbl->reduct_vtbl, op->obj_data 00331 ,num_values, value_data 00332 ,num_indexes, index_data 00333 ,num_chars, char_data 00334 ,&reduct_obj ); 00335 if(err != 0) return err; 00336 if( reduct_obj != reduct_obj_in ) 00337 return RTOp_ERR_INVALID_USAGE; 00338 return 0; /* Success! */ 00339 } 00340 00341 int RTOp_coord_invariant( 00342 const struct RTOp_RTOp *op 00343 ,int *coord_invariant 00344 ) 00345 { 00346 #ifdef RTOp_DEBUG 00347 assert( op ); 00348 assert( op->vtbl ); 00349 /* assert( op->vtbl->coord_invariant ); */ 00350 assert( coord_invariant ); 00351 #endif 00352 /* return op->vtbl->coord_invariant(op->vtbl,op->obj_data,coord_invariant); */ 00353 *coord_invariant = 1; /* ToDo: Implement the above code! */ 00354 return 0; 00355 } 00356 00357 int RTOp_apply_op( const struct RTOp_RTOp* op 00358 , const int num_vecs, const struct RTOp_SubVector sub_vecs[] 00359 , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_sub_vecs[] 00360 , RTOp_ReductTarget reduct_obj ) 00361 { 00362 #ifdef RTOp_DEBUG 00363 assert( op ); 00364 assert( op->vtbl ); 00365 assert( op->vtbl->apply_op ); 00366 if(num_vecs) assert(sub_vecs); 00367 if(num_targ_vecs) assert(targ_sub_vecs); 00368 #endif 00369 return op->vtbl->apply_op( 00370 op->vtbl,op->obj_data,num_vecs,sub_vecs,num_targ_vecs,targ_sub_vecs 00371 ,reduct_obj); 00372 } 00373 00374 int RTOp_reduce_reduct_objs( const struct RTOp_RTOp* op 00375 , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj ) 00376 { 00377 #ifdef RTOp_DEBUG 00378 assert( op ); 00379 assert( op->vtbl ); 00380 assert( op->vtbl->reduce_reduct_objs ); 00381 #endif 00382 return op->vtbl->reduce_reduct_objs(op->vtbl,op->obj_data,in_reduct_obj,inout_reduct_obj); 00383 } 00384 00385 int RTOp_get_reduct_op( const struct RTOp_RTOp* op 00386 , RTOp_reduct_op_func_ptr_t* reduct_op_func_ptr ) 00387 { 00388 #ifdef RTOp_DEBUG 00389 assert( op ); 00390 assert( op->vtbl ); 00391 assert( op->vtbl->get_reduct_op ); 00392 #endif 00393 return op->vtbl->get_reduct_op(op->vtbl,op->obj_data,reduct_op_func_ptr); 00394 } 00395 00396 /* */ 00397 /* RTOp_Server */ 00398 /* */ 00399 00400 /* RTOp_Server data */ 00401 00402 static int RTOp_Server_num_ops = 0; 00403 00404 #define RTOp_SERVER_MAX_NUM_ENTRIES 50 00405 struct RTOp_Server_op_class_name { 00406 char name[RTOp_SERVER_MAX_NUM_ENTRIES+1]; 00407 }; 00408 static struct RTOp_Server_op_class_name 00409 RTOp_Server_op_names[RTOp_SERVER_MAX_NUM_ENTRIES]; 00410 typedef const struct RTOp_RTOp_vtbl_t* RTOp_RTOp_vtbl_t_ptr; 00411 static RTOp_RTOp_vtbl_t_ptr 00412 RTOp_Server_op_vtbl[RTOp_SERVER_MAX_NUM_ENTRIES]; 00413 00414 /* */ 00415 /* Private RTOp_Server functions */ 00416 /* */ 00417 /* In this simplistic implementation the names and vtbl pointers */ 00418 /* are stored an accessed in unsorted tables. */ 00419 /* */ 00420 00421 /* returns the position in the table where this name is found. */ 00422 /* otherwise it returns < 0. */ 00423 static int find_op_name( const struct RTOp_Server_op_class_name op_name_tbl[] 00424 , int num_entries, const char op_name[] ) 00425 { 00426 int k = 0; 00427 for( k = 0; k < num_entries; ++k ) 00428 { 00429 if( strcmp( op_name_tbl[k].name, op_name ) == 0 ) 00430 return k; 00431 } 00432 return -1; /* Did not find the name */ 00433 } 00434 00435 /* returns the position in the table where this reduct vtbl is found. */ 00436 /* otherwise it returns < 0. */ 00437 static int find_op_vtbl( const RTOp_RTOp_vtbl_t_ptr op_vtbl_tbl[] 00438 , int num_entries, RTOp_RTOp_vtbl_t_ptr op_vtbl ) 00439 { 00440 int k = 0; 00441 for( k = 0; k < num_entries; ++k ) 00442 { 00443 if( op_vtbl_tbl[k] == op_vtbl ) 00444 return k; 00445 } 00446 return -1; /* Did not find the name */ 00447 } 00448 00449 /* */ 00450 /* Public RTOp_Server functions */ 00451 /* */ 00452 00453 int RTOp_Server_add_op_name_vtbl( const char op_class_name[] 00454 , const struct RTOp_RTOp_vtbl_t* op_class_vtbl ) 00455 { 00456 int k = 0; 00457 if( strlen( op_class_name ) > RTOp_MAX_REDUCT_TRANS_OP_CLASS_NAME ) 00458 return RTOp_SERVER_OP_NAME_TOO_LONG; 00459 if( (k = find_op_name( RTOp_Server_op_names 00460 , RTOp_Server_num_ops, op_class_name ) ) >= 0 ) 00461 { 00462 if( RTOp_Server_op_vtbl[k] != op_class_vtbl ) 00463 return RTOp_SERVER_INCOMPATIBLE_OPS; 00464 return k; /* The name exits but vtble is the same */ 00465 } 00466 strcpy( RTOp_Server_op_names[RTOp_Server_num_ops].name, op_class_name ); 00467 RTOp_Server_op_vtbl[RTOp_Server_num_ops] = op_class_vtbl; 00468 ++RTOp_Server_num_ops; 00469 return 0; /* Successfully added it */ 00470 } 00471 00472 int RTOp_Server_lookup_op_name( const struct RTOp_RTOp_vtbl_t* op_class_vtbl 00473 , char op_class_name[] ) 00474 { 00475 int k = 0; 00476 if( ( k = find_op_vtbl(RTOp_Server_op_vtbl,RTOp_Server_num_ops,op_class_vtbl) ) >= 0 ) 00477 { 00478 strcpy( op_class_name, RTOp_Server_op_names[k].name ); 00479 return 0; /* Success */ 00480 } 00481 return -1; /* Did not find vtbl */ 00482 } 00483 00484 int RTOp_Server_construct_op( 00485 const char op_class_name[] 00486 ,int num_values 00487 ,const RTOp_value_type value_data[] 00488 ,int num_indexes 00489 ,const RTOp_index_type index_data[] 00490 ,int num_chars 00491 ,const RTOp_char_type char_data[] 00492 ,struct RTOp_RTOp* op 00493 ) 00494 { 00495 int k = 0; 00496 int err = 0; /* success? */ 00497 if( strlen( op_class_name ) > RTOp_MAX_REDUCT_TRANS_OP_CLASS_NAME ) 00498 return RTOp_SERVER_OP_NAME_TOO_LONG; 00499 if( ( k = find_op_name(RTOp_Server_op_names,RTOp_Server_num_ops, op_class_name) ) >= 0 ) 00500 { 00501 op->obj_data = NULL; /* Will be dyn allocated below! */ 00502 op->vtbl = RTOp_Server_op_vtbl[k]; 00503 err = RTOp_load_op_state( 00504 num_values,value_data,num_indexes,index_data,num_chars,char_data 00505 ,op); 00506 return err; 00507 } 00508 return -1; /* op_class_name not found */ 00509 } 00510 00511 void RTOp_Server_dump( FILE* file ) 00512 { 00513 int k = 0; 00514 int jn = 0, jv = 0; 00515 fprintf( file, "Class names and vtbl pointers for RTOp_RTOp subcasses\n" ); 00516 for( k = 0; k < RTOp_Server_num_ops; ++k ) { 00517 jn = find_op_name( RTOp_Server_op_names 00518 , RTOp_Server_num_ops, RTOp_Server_op_names[k].name ); 00519 jv = find_op_vtbl( RTOp_Server_op_vtbl, RTOp_Server_num_ops 00520 , RTOp_Server_op_vtbl[k] ); 00521 fprintf( file 00522 , " class name = \"%s\"\n" 00523 " looked up class name = \"%s\"\n" 00524 " vtbl = %p\n" 00525 " looked up vtbl = %p\n" 00526 , RTOp_Server_op_names[k].name 00527 , RTOp_Server_op_names[jn].name 00528 , RTOp_Server_op_vtbl[k] 00529 , RTOp_Server_op_vtbl[jv] 00530 ); 00531 } 00532 }
1.7.6.1