RTOpPack: Extra C/C++ Code for Vector Reduction/Transformation Operators Version of the Day
RTOp.c
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                  = %#x\n"
00525         "    looked up vtbl        = %#x\n"
00526       , RTOp_Server_op_names[k].name
00527       , RTOp_Server_op_names[jn].name
00528       , (unsigned int)RTOp_Server_op_vtbl[k]
00529       , (unsigned int)RTOp_Server_op_vtbl[jv]
00530       );
00531   }
00532 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Friends