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