RTOp.c

Go to the documentation of this file.
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
Generated on Wed Apr 13 10:11:01 2011 for MOOCHO (Single Doxygen Collection) by  doxygen 1.6.3