MOOCHO (Single Doxygen Collection) Version of the Day
RTOp_ROp_get_sub_vector.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 // 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 "RTOp_ROp_get_sub_vector.h"
00045 #include "RTOp_obj_free_free.h"
00046 
00047 #include <stdlib.h>
00048 
00049 #define MY_MIN(a,b) a < b ? a : b
00050 
00051 /* Operator object data virtual function table */
00052 
00053 struct RTOp_ROp_get_sub_vector_rng_t { /* operator object instance data */
00054   RTOp_index_type  l;
00055   RTOp_index_type  u;
00056 };
00057 
00058 static int get_op_type_num_entries(
00059   const struct RTOp_obj_type_vtbl_t*   vtbl
00060   ,const void* obj_data
00061   ,int* num_values
00062   ,int* num_indexes
00063   ,int* num_chars
00064   )
00065 {
00066   assert( num_values );
00067   assert( num_indexes );
00068   assert( num_chars );
00069   *num_values  = 0;
00070   *num_indexes = 2; /* l, u */
00071   *num_chars   = 0;
00072   return 0;
00073 }
00074 
00075 static int obj_create(
00076   const struct RTOp_obj_type_vtbl_t* vtbl, const void* instance_data
00077   , RTOp_ReductTarget* obj )
00078 {
00079   *obj = malloc(sizeof(struct RTOp_ROp_get_sub_vector_rng_t));
00080   return 0;
00081 }
00082 
00083 static int extract_op_state(
00084   const struct RTOp_obj_type_vtbl_t*   vtbl
00085   ,const void *       dummy
00086   ,void *             obj_data
00087   ,int                num_values
00088   ,RTOp_value_type    value_data[]
00089   ,int                num_indexes
00090   ,RTOp_index_type    index_data[]
00091   ,int                num_chars
00092   ,RTOp_char_type     char_data[]
00093   )
00094 {
00095   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00096   assert(obj_data);
00097   assert( num_values  == 0 );
00098   assert( num_indexes == 2 );
00099   assert( num_chars   == 0 );
00100     rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00101   index_data[0] = rng->l;
00102   index_data[1] = rng->u;
00103   return 0;
00104 }
00105 
00106 static int load_op_state(
00107   const struct RTOp_obj_type_vtbl_t*   vtbl
00108   ,const void *            dummy
00109   ,int                     num_values
00110   ,const RTOp_value_type   value_data[]
00111   ,int                     num_indexes
00112   ,const RTOp_index_type   index_data[]
00113   ,int                     num_chars
00114   ,const RTOp_char_type    char_data[]
00115   ,void **                 obj_data
00116   )
00117 {
00118   struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00119   assert(obj_data);
00120   assert( num_values  == 0 );
00121   assert( num_indexes == 2 );
00122   assert( num_chars   == 0 );
00123   if(*obj_data == NULL)
00124     *obj_data = malloc(sizeof(struct RTOp_ROp_get_sub_vector_rng_t));
00125   rng = (struct RTOp_ROp_get_sub_vector_rng_t*)*obj_data;
00126   rng->l = index_data[0];
00127   rng->u = index_data[1];
00128   return 0;
00129 }
00130 
00131 static struct RTOp_obj_type_vtbl_t  instance_obj_vtbl =
00132 {
00133   get_op_type_num_entries
00134   ,obj_create
00135   ,NULL
00136   ,RTOp_obj_free_free
00137   ,extract_op_state
00138   ,load_op_state
00139 };
00140 
00141 /* Reduction object virtual function table */
00142 
00143 static int get_targ_type_num_entries(
00144   const struct RTOp_obj_type_vtbl_t* vtbl
00145   ,const void* obj_data
00146   ,int* num_values
00147   ,int* num_indexes
00148   ,int* num_chars
00149   )
00150 {
00151   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00152   assert(obj_data);
00153   assert( num_values );
00154   assert( num_indexes );
00155   assert( num_chars );
00156     rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00157   *num_values  = rng->u - rng->l + 1; /* dense storage for elements of sub-vector to get */
00158   *num_indexes = 2;                   /* l and u */
00159   *num_chars   = 0;
00160   return 0;
00161 }
00162 
00163 static int targ_obj_create(
00164   const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data
00165   , RTOp_ReductTarget* targ_obj )
00166 {
00167   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00168   const int mem_size = sizeof(struct RTOp_SubVector);
00169   struct RTOp_SubVector *sub_vec_targ = NULL;
00170   RTOp_index_type sub_dim = 0;
00171   /* Get the range of the sub-vector */
00172   assert(obj_data);
00173   rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00174   sub_dim = rng->u - rng->l + 1;
00175   /* Allocate the sub-vector target object */
00176   *targ_obj = malloc(mem_size);
00177   sub_vec_targ = (struct RTOp_SubVector*)*targ_obj;
00178   /* Setup storage for the target sub-vector */
00179   RTOp_sub_vector(
00180      rng->l - 1                                                        /* global_offset */
00181      ,sub_dim                                                          /* sub_dim */
00182      ,(const RTOp_value_type*)malloc(sub_dim*sizeof(RTOp_value_type))  /* values[] */
00183      ,1                                                                /* value_stride */
00184      ,sub_vec_targ );
00185   /* Initialize the sub-vector to zero */
00186   vtbl->obj_reinit( vtbl, obj_data, *targ_obj );
00187   return 0;
00188 }
00189 
00190 static int targ_obj_reinit(
00191   const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data
00192   , RTOp_ReductTarget targ_obj )
00193 {
00194   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00195   struct RTOp_SubVector *sub_vec_targ = NULL;
00196   RTOp_index_type sub_dim = 0;
00197   RTOp_value_type *values = NULL;
00198   register RTOp_index_type k;
00199   assert(obj_data);
00200   /* Get the range of the sub-vector */
00201     rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00202   sub_dim = rng->u - rng->l + 1;
00203   /* Get the target sub-vector */
00204   sub_vec_targ = (struct RTOp_SubVector*)targ_obj;
00205   assert( sub_dim == sub_vec_targ->sub_dim );
00206   assert( sub_vec_targ->values );
00207   /* Initialize the values to zero */
00208   values = (RTOp_value_type*)sub_vec_targ->values;
00209   for( k = 0; k < sub_dim; ++k )
00210     *values++ = 0.0;
00211   return 0;
00212 }
00213 
00214 static int targ_obj_free(
00215   const struct RTOp_obj_type_vtbl_t* vtbl, const void* obj_data
00216   , RTOp_ReductTarget* targ_obj )
00217 {
00218   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00219   struct RTOp_SubVector *sub_vec_targ = NULL;
00220   RTOp_index_type sub_dim = 0;
00221   assert(obj_data);
00222   /* Get the range of the sub-vector */
00223     rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00224   sub_dim = rng->u - rng->l + 1;
00225   /* Get the target sub-vector */
00226   sub_vec_targ = (struct RTOp_SubVector*)*targ_obj;
00227   assert( sub_dim == sub_vec_targ->sub_dim );
00228   assert( sub_vec_targ->values );
00229   /* Deallocate the vectors and the object */
00230   if( (void*)sub_vec_targ->values )
00231     free( (void*)sub_vec_targ->values );
00232   free( (void*)sub_vec_targ );
00233   *targ_obj = RTOp_REDUCT_OBJ_NULL;
00234   return 0;
00235 }
00236 
00237 static int targ_extract_state(
00238   const struct RTOp_obj_type_vtbl_t* vtbl
00239   ,const void *       obj_data
00240   ,void *             targ_obj
00241   ,int                num_values
00242   ,RTOp_value_type    value_data[]
00243   ,int                num_indexes
00244   ,RTOp_index_type    index_data[]
00245   ,int                num_chars
00246   ,RTOp_char_type     char_data[]
00247   )
00248 {
00249   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00250   struct RTOp_SubVector *sub_vec_targ = NULL;
00251   RTOp_index_type sub_dim = 0;
00252   register RTOp_index_type k;
00253   assert(obj_data);
00254   /* Get the range of the sub-vector */
00255   rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00256   sub_dim = rng->u - rng->l + 1;
00257   /* Get the target sub-vector */
00258   assert( targ_obj  );
00259   sub_vec_targ = (struct RTOp_SubVector*)targ_obj;
00260   assert( sub_dim == sub_vec_targ->sub_dim );
00261   assert( sub_vec_targ->values );
00262   /* Extract the state */
00263   assert( num_values  == sub_dim );
00264   assert( num_indexes == 2 );
00265   assert( num_chars   == 0 );
00266   for( k = 0; k < sub_dim; ++k )
00267     value_data[k] = sub_vec_targ->values[k];
00268   index_data[0] = rng->l;
00269   index_data[1] = rng->u;
00270   return 0;
00271 }
00272 
00273 static int targ_load_state(
00274   const struct RTOp_obj_type_vtbl_t* vtbl
00275   ,const void*             obj_data
00276   ,int                     num_values
00277   ,const RTOp_value_type   value_data[]
00278   ,int                     num_indexes
00279   ,const RTOp_index_type   index_data[]
00280   ,int                     num_chars
00281   ,const RTOp_char_type    char_data[]
00282   ,void **                 targ_obj
00283   )
00284 {
00285   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00286   struct RTOp_SubVector *sub_vec_targ = NULL;
00287   RTOp_index_type sub_dim = 0;
00288   RTOp_value_type *values = NULL;
00289   register RTOp_index_type k;
00290   assert(obj_data);
00291   /* Get the range of the sub-vector */
00292     rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00293   sub_dim = rng->u - rng->l + 1;
00294   /* Get the target sub-vector */
00295   assert( *targ_obj );
00296   sub_vec_targ = (struct RTOp_SubVector*)*targ_obj;
00297   assert( sub_dim == sub_vec_targ->sub_dim );
00298   assert( sub_vec_targ->values );
00299   /* Load the state */
00300   assert( num_values  == sub_dim );
00301   assert( num_indexes == 2 );
00302   assert( num_chars   == 0 );
00303   assert( index_data[0] == sub_vec_targ->global_offset + 1 );
00304   assert( index_data[1] == sub_vec_targ->global_offset + sub_vec_targ->sub_dim );
00305   values = (RTOp_value_type*)sub_vec_targ->values;
00306   for( k = 0; k < sub_dim; ++k )
00307     *values++ = value_data[k];
00308   RTOp_sub_vector(
00309     rng->l - 1             /* global_offset */
00310     ,sub_dim               /* sub_dim */
00311     ,sub_vec_targ->values  /* values[] */
00312     ,1                     /* value_stide */
00313     ,sub_vec_targ );
00314   return 0;
00315 }
00316 
00317 static struct RTOp_obj_type_vtbl_t  targ_obj_vtbl =
00318 {
00319   get_targ_type_num_entries
00320   ,targ_obj_create
00321   ,targ_obj_reinit
00322   ,targ_obj_free
00323   ,targ_extract_state
00324   ,targ_load_state
00325 };
00326 
00327 /* Implementation functions */
00328 
00329 static int RTOp_ROp_get_sub_vector_apply_op(
00330   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00331   , const int num_vecs, const struct RTOp_SubVector vecs[]
00332   , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
00333   , RTOp_ReductTarget targ_obj )
00334 {
00335   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00336   struct RTOp_SubVector *sub_vec_targ = NULL;
00337   RTOp_index_type        global_offset;
00338   RTOp_index_type        sub_dim;
00339   const RTOp_value_type  *v0_val;
00340   ptrdiff_t              v0_val_s;
00341   RTOp_index_type i, i_l, i_u;
00342 
00343   /* */
00344   /* Validate the input */
00345   /* */
00346   if( num_vecs != 1 )
00347     return RTOp_ERR_INVALID_NUM_VECS;
00348   if( num_targ_vecs != 0 )
00349     return RTOp_ERR_INVALID_NUM_TARG_VECS;
00350   assert(targ_obj);
00351   assert(vecs);
00352 
00353   /* */
00354   /* Get pointers to data */
00355   /* */
00356 
00357   /* Get the range of the sub-vector that we are trying to extract */
00358   assert(obj_data);
00359   rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00360 
00361   /* Get the sub-vector target object */
00362   assert( targ_obj );
00363   sub_vec_targ = (struct RTOp_SubVector*)targ_obj;
00364   assert( sub_vec_targ->global_offset + 1 == rng->l );
00365   assert( sub_vec_targ->global_offset + sub_vec_targ->sub_dim == rng->u );
00366 
00367   /* v0 */
00368   global_offset  = vecs[0].global_offset;
00369   sub_dim        = vecs[0].sub_dim;
00370   v0_val         = vecs[0].values;
00371   v0_val_s       = vecs[0].values_stride;
00372 
00373   /* */
00374   /* Extract part of the sub-vector for this chunk. */
00375   /* */
00376   /* We only want the elements from rng->l to rng->u */
00377   /* and this vector chunk only has elements from global_offset */
00378   /* to global_offset + sub_dim. */
00379   /* */
00380 
00381   if( rng->u < global_offset + 1 || global_offset + sub_dim < rng->l )
00382     return 0; /* None of the sub-vector that we are looking for is not in this vector chunk! */
00383 
00384   i_l = ( rng->l <= ( global_offset + 1 )       ? 1       : rng->l - global_offset  );
00385   i_u = ( rng->u >= ( global_offset + sub_dim ) ? sub_dim : rng->u - global_offset  );
00386 
00387   for( i = i_l; i <= i_u; ++i )
00388     ((RTOp_value_type*)sub_vec_targ->values)[i-1+(global_offset-(rng->l-1))] = v0_val[(i-1)*v0_val_s];
00389 
00390   return 0; /* success? */
00391 
00392 }
00393 
00394 static int reduce_reduct_objs(
00395   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data /* Can be NULL! */
00396   , RTOp_ReductTarget in_reduct_obj, RTOp_ReductTarget inout_reduct_obj )
00397 {
00398   const struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00399   struct RTOp_SubVector
00400     *in_sub_vec_targ    = NULL,
00401     *inout_sub_vec_targ = NULL;
00402   RTOp_index_type sub_dim = 0;
00403   RTOp_value_type *inout_values = NULL;
00404   register RTOp_index_type k;
00405   /* Get the range of the sub-vector */
00406   assert(obj_data);
00407     rng = (const struct RTOp_ROp_get_sub_vector_rng_t*)obj_data;
00408   sub_dim = rng->u - rng->l + 1;
00409   /* Get the in target sub-vector */
00410   assert( in_reduct_obj );
00411   in_sub_vec_targ = (struct RTOp_SubVector*)in_reduct_obj;
00412   assert( sub_dim == in_sub_vec_targ->sub_dim );
00413   assert( in_sub_vec_targ->values );
00414   /* Get the inout target sub-vector */
00415   assert( inout_reduct_obj );
00416   inout_sub_vec_targ = (struct RTOp_SubVector*)inout_reduct_obj;
00417   assert( sub_dim == inout_sub_vec_targ->sub_dim );
00418   assert( inout_sub_vec_targ->values );
00419   /* Perform the reduction */
00420   inout_values = (RTOp_value_type*)inout_sub_vec_targ->values;
00421   for( k = 0; k < sub_dim; ++k )
00422     *inout_values++ += in_sub_vec_targ->values[k];
00423   return 0;
00424 }
00425 
00426 static void CALL_API external_reduct_op( void* in_targ_array, void* inout_targ_array
00427   , int* len, RTOp_Datatype* datatype )
00428 {
00429   int num_values_off, num_indexes_off, num_chars_off
00430     , values_off, l_off, u_off;
00431   int num_values, num_indexes, num_chars;
00432   const RTOp_value_type *in_values    = NULL;
00433   RTOp_value_type       *inout_values = NULL;
00434   register RTOp_index_type k;
00435   /* Get the offsets for the number of elements of each data type */
00436   num_values_off  = 0;
00437   num_indexes_off = num_values_off  + sizeof(RTOp_value_type);
00438   num_chars_off   = num_indexes_off + sizeof(RTOp_value_type);
00439   /* Get the number of elements of each data type */
00440   num_values  = *(RTOp_value_type*)((char*)in_targ_array + num_values_off);
00441   num_indexes = *(RTOp_value_type*)((char*)in_targ_array + num_indexes_off);
00442   num_chars   = *(RTOp_value_type*)((char*)in_targ_array + num_chars_off);
00443 #ifdef RTOp_DEBUG
00444   assert( num_values > 0 );
00445   assert( num_indexes == 2 );
00446   assert( num_chars   == 0 );
00447   assert( num_values  == *(RTOp_value_type*)((char*)inout_targ_array + num_values_off) );
00448   assert( num_indexes == *(RTOp_value_type*)((char*)inout_targ_array + num_indexes_off) );
00449   assert( num_chars   == *(RTOp_value_type*)((char*)inout_targ_array + num_chars_off) );
00450 #endif
00451   /* Get the offsets for the sub-vector values and range l and u */
00452   values_off = num_chars_off + sizeof(RTOp_value_type);
00453   l_off      = values_off    + num_values * sizeof(RTOp_value_type);
00454   u_off      = l_off         + sizeof(RTOp_index_type);
00455 #ifdef RTOp_DEBUG
00456   assert( *(RTOp_index_type*)((char*)in_targ_array + l_off)
00457       == *(RTOp_index_type*)((char*)inout_targ_array + l_off) );
00458   assert( *(RTOp_index_type*)((char*)in_targ_array + u_off)
00459       == *(RTOp_index_type*)((char*)inout_targ_array + u_off) );
00460 #endif
00461   /* Perform the reduction! (just add the elements together) */
00462   in_values    = (const RTOp_value_type*)((char*)in_targ_array + values_off);
00463   inout_values = (RTOp_value_type*)((char*)inout_targ_array + values_off);
00464   for( k = 0; k < num_values; ++k )
00465     *inout_values++ += *in_values++;
00466 }
00467 
00468 static int get_reduct_op(
00469   const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
00470   , RTOp_reduct_op_func_ptr_t* reduct_op_func_ptr )
00471 {
00472   *reduct_op_func_ptr = external_reduct_op;
00473   return 0;
00474 }
00475 
00476 /* Public interface */
00477 
00478 const struct RTOp_RTOp_vtbl_t RTOp_ROp_get_sub_vector_vtbl =
00479 {
00480   &instance_obj_vtbl
00481   ,&targ_obj_vtbl
00482   ,"RTOp_ROp_get_sub_vector"
00483   ,NULL
00484   ,RTOp_ROp_get_sub_vector_apply_op
00485   ,reduce_reduct_objs
00486   ,get_reduct_op
00487 };
00488 
00489 int RTOp_ROp_get_sub_vector_construct(
00490   RTOp_index_type l, RTOp_index_type u, struct RTOp_RTOp* op )
00491 {
00492   struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00493   op->vtbl = &RTOp_ROp_get_sub_vector_vtbl;
00494   op->vtbl->obj_data_vtbl->obj_create(NULL,NULL,&op->obj_data);
00495   rng = (struct RTOp_ROp_get_sub_vector_rng_t*)op->obj_data;
00496   rng->l = l;
00497   rng->u = u;
00498   return 0;
00499 }
00500 
00501 int RTOp_ROp_get_sub_vector_set_range(
00502   RTOp_index_type l, RTOp_index_type u, struct RTOp_RTOp* op )
00503 {
00504   struct RTOp_ROp_get_sub_vector_rng_t *rng = NULL;
00505   assert( op->vtbl );
00506   assert( op->obj_data );
00507   rng = (struct RTOp_ROp_get_sub_vector_rng_t*)op->obj_data;
00508   rng->l = l;
00509   rng->u = u;
00510   return 0;
00511 }
00512 
00513 int RTOp_ROp_get_sub_vector_destroy( struct RTOp_RTOp* op )
00514 {
00515 #ifdef TEUCHOS_DEBUG
00516   assert( op->vtbl );
00517   assert( op->obj_data );
00518 #endif
00519   op->vtbl->obj_data_vtbl->obj_free(NULL,NULL,&op->obj_data);
00520   op->vtbl = NULL;
00521   return 0;
00522 }
00523 
00524 struct RTOp_SubVector RTOp_ROp_get_sub_vector_val(
00525   RTOp_ReductTarget targ_obj
00526   )
00527 {
00528   return *((struct RTOp_SubVector*)targ_obj);
00529 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines