MOOCHO (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
RTOp_TOp_set_sub_vector.c
Go to the documentation of this file.
1 /*
2 // @HEADER
3 // ***********************************************************************
4 //
5 // Moocho: Multi-functional Object-Oriented arCHitecture for Optimization
6 // Copyright (2003) Sandia Corporation
7 //
8 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
9 // license for use of this work by or on behalf of the U.S. Government.
10 //
11 // Redistribution and use in source and binary forms, with or without
12 // modification, are permitted provided that the following conditions are
13 // met:
14 //
15 // 1. Redistributions of source code must retain the above copyright
16 // notice, this list of conditions and the following disclaimer.
17 //
18 // 2. Redistributions in binary form must reproduce the above copyright
19 // notice, this list of conditions and the following disclaimer in the
20 // documentation and/or other materials provided with the distribution.
21 //
22 // 3. Neither the name of the Corporation nor the names of the
23 // contributors may be used to endorse or promote products derived from
24 // this software without specific prior written permission.
25 //
26 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
27 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
29 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
30 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
31 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
32 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
33 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
34 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
35 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
36 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 //
38 // Questions? Contact Roscoe A. Bartlett (rabartl@sandia.gov)
39 //
40 // ***********************************************************************
41 // @HEADER
42 */
43 
45 #include "RTOp_obj_null_vtbl.h"
46 
47 #include <stdlib.h>
48 
49 /* Operator object data virtual function table */
50 
51 struct RTOp_TOp_set_sub_vector_state_t { /* operator object instance data */
52  struct RTOp_SparseSubVector sub_vec; /* The sub vector to set! */
53  int owns_mem; /* if true then memory is sub_vec must be deleted! */
54 };
55 
57  const struct RTOp_obj_type_vtbl_t* vtbl
58  ,const void* obj_data
59  ,int* num_values
60  ,int* num_indexes
61  ,int* num_chars
62  )
63 {
64  const struct RTOp_TOp_set_sub_vector_state_t *state = NULL;
65 #ifdef RTOp_DEBUG
66  assert( num_values );
67  assert( num_indexes );
68  assert( num_chars );
69  assert( obj_data );
70 #endif
71  state = (const struct RTOp_TOp_set_sub_vector_state_t*)obj_data;
72  *num_values = state->sub_vec.sub_nz; /* values[] */
73  *num_indexes =
74  8 /* global_offset, sub_dim, sub_nz, values_stride, indices_stride, local_offset, is_sorted, owns_mem */
75  + (state->sub_vec.indices ? state->sub_vec.sub_nz : 0 ); /* indices[] */
76  *num_chars = 0;
77  return 0;
78 }
79 
80 static int op_create(
81  const struct RTOp_obj_type_vtbl_t* vtbl, const void* instance_data
82  , RTOp_ReductTarget* obj )
83 {
84  struct RTOp_TOp_set_sub_vector_state_t *state = NULL;
85  *obj = malloc(sizeof(struct RTOp_TOp_set_sub_vector_state_t));
86  state = (struct RTOp_TOp_set_sub_vector_state_t*)*obj;
88  state->owns_mem = 0;
89  return 0;
90 }
91 
92 static int op_free(
93  const struct RTOp_obj_type_vtbl_t* vtbl, const void* dummy
94  , void ** obj_data )
95 {
96  struct RTOp_TOp_set_sub_vector_state_t *state = NULL;
97 #ifdef RTOp_DEBUG
98  assert( *obj_data );
99 #endif
100  state = (struct RTOp_TOp_set_sub_vector_state_t*)*obj_data;
101  if( state->owns_mem ) {
102  free( (void*)state->sub_vec.values );
103  free( (void*)state->sub_vec.indices );
104  }
105  free( *obj_data );
106  *obj_data = NULL;
107  return 0;
108 }
109 
110 static int extract_op_state(
111  const struct RTOp_obj_type_vtbl_t* vtbl
112  ,const void * dummy
113  ,void * obj_data
114  ,int num_values
115  ,RTOp_value_type value_data[]
116  ,int num_indexes
117  ,RTOp_index_type index_data[]
118  ,int num_chars
119  ,RTOp_char_type char_data[]
120  )
121 {
122  const struct RTOp_TOp_set_sub_vector_state_t *state = NULL;
123  register RTOp_index_type k, j;
124 #ifdef RTOp_DEBUG
125  assert( obj_data );
126 #endif
127  state = (const struct RTOp_TOp_set_sub_vector_state_t*)obj_data;
128 #ifdef RTOp_DEBUG
129  assert( num_values == state->sub_vec.sub_nz );
130  assert( num_indexes == 8 + (state->sub_vec.indices ? state->sub_vec.sub_nz : 0 ) );
131  assert( num_chars == 0 );
132  assert( value_data );
133  assert( index_data );
134 #endif
135  for( k = 0; k < state->sub_vec.sub_nz; ++k )
136  value_data[k] = state->sub_vec.values[k];
137  index_data[k=0] = state->sub_vec.global_offset;
138  index_data[++k] = state->sub_vec.sub_dim;
139  index_data[++k] = state->sub_vec.sub_nz;
140  index_data[++k] = state->sub_vec.values_stride;
141  index_data[++k] = state->sub_vec.indices_stride;
142  index_data[++k] = state->sub_vec.local_offset;
143  index_data[++k] = state->sub_vec.is_sorted;
144  index_data[++k] = state->owns_mem;
145  if( state->sub_vec.indices ) {
146  for( j = 0; j < state->sub_vec.sub_nz; ++j )
147  index_data[++k] = state->sub_vec.indices[j];
148  }
149  return 0;
150 }
151 
152 static int load_op_state(
153  const struct RTOp_obj_type_vtbl_t* vtbl
154  ,const void * dummy
155  ,int num_values
156  ,const RTOp_value_type value_data[]
157  ,int num_indexes
158  ,const RTOp_index_type index_data[]
159  ,int num_chars
160  ,const RTOp_char_type char_data[]
161  ,void ** obj_data
162  )
163 {
164  struct RTOp_TOp_set_sub_vector_state_t *state = NULL;
165  register RTOp_index_type k, j;
166  RTOp_value_type *values = NULL;
167  /* Allocate the operator object's state data if it has not been already */
168  if( *obj_data == NULL ) {
169  *obj_data = (void*)malloc(sizeof(struct RTOp_TOp_set_sub_vector_state_t));
170  state = (struct RTOp_TOp_set_sub_vector_state_t*)*obj_data;
172  state->owns_mem = 0;
173  }
174  /* Get the operator object's state data */
175 #ifdef RTOp_DEBUG
176  assert( *obj_data );
177 #endif
178  state = (struct RTOp_TOp_set_sub_vector_state_t*)*obj_data;
179 #ifdef RTOp_DEBUG
180  if( num_indexes > 8 ) assert( num_values == num_indexes - 8 );
181 #endif
182  /* Reallocate storage if we have to */
183  if( num_values != state->sub_vec.sub_nz || !state->owns_mem ) {
184  /* Delete current storage if owned */
185  if( state->owns_mem ) {
186  free( (RTOp_value_type*)state->sub_vec.values );
187  free( (RTOp_index_type*)state->sub_vec.indices );
188  }
189  /* We need to reallocate storage for values[] and perhaps */
190  state->sub_vec.values = (RTOp_value_type*)malloc(num_values*sizeof(RTOp_value_type));
191  if( num_indexes > 8 )
192  state->sub_vec.indices = (RTOp_index_type*)malloc(num_values*sizeof(RTOp_index_type));
193  state->owns_mem = 1;
194  }
195  /* Set the internal state! */
196 #ifdef RTOp_DEBUG
197  assert( num_chars == 0 );
198  assert( value_data );
199  assert( index_data );
200 #endif
201  for( values = (RTOp_value_type*)state->sub_vec.values, k = 0; k < num_values; ++k )
202  *values++ = value_data[k];
203  state->sub_vec.global_offset = index_data[k=0];
204  state->sub_vec.sub_dim = index_data[++k];
205  state->sub_vec.sub_nz = index_data[++k];
206  state->sub_vec.values_stride = index_data[++k];
207  state->sub_vec.indices_stride = index_data[++k];
208  state->sub_vec.local_offset = index_data[++k];
209  state->sub_vec.is_sorted = index_data[++k];
210  state->owns_mem = index_data[++k];
211  if( num_indexes > 8 ) {
212  for( j = 0; j < num_values; ++j )
213  ((RTOp_index_type*)state->sub_vec.indices)[j] = index_data[++k];
214  }
215  return 0;
216 }
217 
219 {
221  ,op_create
222  ,NULL
223  ,op_free
226 };
227 
228 /* Implementation functions */
229 
231  const struct RTOp_RTOp_vtbl_t* vtbl, const void* obj_data
232  , const int num_vecs, const struct RTOp_SubVector vecs[]
233  , const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[]
234  , RTOp_ReductTarget targ_obj )
235 {
236  const struct RTOp_TOp_set_sub_vector_state_t *state = NULL;
237  RTOp_index_type v_global_offset;
238  RTOp_index_type v_sub_dim;
239  RTOp_index_type v_sub_nz;
240  const RTOp_value_type *v_val;
241  ptrdiff_t v_val_s;
242  const RTOp_index_type *v_ind;
243  ptrdiff_t v_ind_s;
244  ptrdiff_t v_l_off;
245  int v_sorted;
246  RTOp_index_type z_global_offset;
247  RTOp_index_type z_sub_dim;
248  RTOp_value_type *z_val;
249  ptrdiff_t z_val_s;
250  register RTOp_index_type k, i;
251  RTOp_index_type num_overlap;
252 
253  /* */
254  /* Validate the input */
255  /* */
256  if( num_vecs != 0 )
258  if( num_targ_vecs != 1 )
260  assert(targ_vecs);
261  assert(targ_obj == RTOp_REDUCT_OBJ_NULL);
262 
263  /* */
264  /* Get pointers to data */
265  /* */
266 
267  /* Get the sub-vector we are reading from */
268  assert(obj_data);
269  state = (const struct RTOp_TOp_set_sub_vector_state_t*)obj_data;
270 
271  /* v (the vector to read from) */
272  v_global_offset = state->sub_vec.global_offset;
273  v_sub_dim = state->sub_vec.sub_dim;
274  v_sub_nz = state->sub_vec.sub_nz;
275  v_val = state->sub_vec.values;
276  v_val_s = state->sub_vec.values_stride;
277  v_ind = state->sub_vec.indices;
278  v_ind_s = state->sub_vec.indices_stride;
279  v_l_off = state->sub_vec.local_offset;
280  v_sorted = state->sub_vec.is_sorted;
281 
282  /* z (the vector to set) */
283  z_global_offset = targ_vecs[0].global_offset;
284  z_sub_dim = targ_vecs[0].sub_dim;
285  z_val = targ_vecs[0].values;
286  z_val_s = targ_vecs[0].values_stride;
287 
288  /* */
289  /* Set part of the sub-vector for this chunk. */
290  /* */
291 
292  if( v_global_offset + v_sub_dim < z_global_offset + 1
293  || z_global_offset + z_sub_dim < v_global_offset + 1 )
294  return 0; /* The sub-vector that we are setting does not overlap with this vector chunk! */
295 
296  if( v_sub_nz == 0 )
297  return 0; /* The sparse sub-vector we are reading from is empty? */
298 
299  /* Get the number of elements that overlap */
300  if( v_global_offset <= z_global_offset ) {
301  if( v_global_offset + v_sub_dim >= z_global_offset + z_sub_dim )
302  num_overlap = z_sub_dim;
303  else
304  num_overlap = (v_global_offset + v_sub_dim) - z_global_offset;
305  }
306  else {
307  if( z_global_offset + z_sub_dim >= v_global_offset + v_sub_dim )
308  num_overlap = v_sub_dim;
309  else
310  num_overlap = (z_global_offset + z_sub_dim) - v_global_offset;
311  }
312 
313  /* Set the part of the sub-vector that overlaps */
314  if( v_ind != NULL ) {
315  /* Sparse elements */
316  /* Set the overlapping elements to zero first. */
317  if( v_global_offset >= z_global_offset )
318  z_val += (v_global_offset - z_global_offset) * z_val_s;
319  for( k = 0; k < num_overlap; ++k, z_val += z_val_s )
320  *z_val = 0.0;
321  /* Now set the sparse entries */
322  z_val = targ_vecs[0].values;
323  for( k = 0; k < v_sub_nz; ++k, v_val += v_val_s, v_ind += v_ind_s ) {
324  i = v_global_offset + v_l_off + (*v_ind);
325  if( z_global_offset < i && i <= z_global_offset + z_sub_dim )
326  z_val[ z_val_s * (i - z_global_offset - 1) ] = *v_val;
327  }
328  /* ToDo: Implement a faster version for v sorted and eliminate the */
329  /* if statement in the loop. */
330  }
331  else {
332  /* Dense elemements */
333  if( v_global_offset <= z_global_offset )
334  v_val += (z_global_offset - v_global_offset) * v_val_s;
335  else
336  z_val += (v_global_offset - z_global_offset) * z_val_s;
337  for( k = 0; k < num_overlap; ++k, v_val += v_val_s, z_val += z_val_s )
338  *z_val = *v_val;
339  }
340 
341  return 0; /* success? */
342 }
343 
344 /* Public interface */
345 
347 {
349  ,&RTOp_obj_null_vtbl /* use null type for reduction target object */
350  ,"RTOp_TOp_set_sub_vector"
351  ,NULL /* use default from reduct_vtbl */
353  ,NULL /* reduce_reduct_obj */
354  ,NULL /* get_reduct_op */
355 };
356 
358  const struct RTOp_SparseSubVector* sub_vec, struct RTOp_RTOp* op )
359 {
360 #ifdef RTOp_DEBUG
361  assert(sub_vec);
362  assert(op);
363 #endif
365  op->vtbl->obj_data_vtbl->obj_create(NULL,NULL,&op->obj_data);
366  return RTOp_TOp_set_sub_vector_set_sub_vec(sub_vec,op);
367 }
368 
370  const struct RTOp_SparseSubVector* sub_vec, struct RTOp_RTOp* op )
371 {
372  struct RTOp_TOp_set_sub_vector_state_t *state = NULL;
373 #ifdef RTOp_DEBUG
374  assert( op->obj_data );
375 #endif
376  state = (struct RTOp_TOp_set_sub_vector_state_t*)op->obj_data;
377  if( state->owns_mem ) {
378  free( (void*)state->sub_vec.values );
379  free( (void*)state->sub_vec.indices );
380  }
381  state->sub_vec = *sub_vec; /* We do not own the arrays values[] and indices[] */
382  state->owns_mem = 0;
383  return 0;
384 }
385 
387 {
388  op_free(NULL,NULL,&op->obj_data);
389  op->vtbl = NULL;
390  return 0;
391 }
double RTOp_value_type
Definition: RTOp.h:69
static int op_create(const struct RTOp_obj_type_vtbl_t *vtbl, const void *instance_data, RTOp_ReductTarget *obj)
ptrdiff_t values_stride
Definition: RTOp.h:338
const struct RTOp_RTOp_vtbl_t RTOp_TOp_set_sub_vector_vtbl
int RTOp_TOp_set_sub_vector_destroy(struct RTOp_RTOp *op)
void * RTOp_ReductTarget
Definition: RTOp.h:191
static int op_free(const struct RTOp_obj_type_vtbl_t *vtbl, const void *dummy, void **obj_data)
int(* obj_create)(const struct RTOp_obj_type_vtbl_t *vtbl, const void *instance_data, void **obj)
Definition: RTOp.h:941
const RTOp_index_type * indices
const struct RTOp_obj_type_vtbl_t * obj_data_vtbl
Definition: RTOp.h:819
void RTOp_sparse_sub_vector_null(struct RTOp_SparseSubVector *sub_vec)
static int RTOp_TOp_set_sub_vector_apply_op(const struct RTOp_RTOp_vtbl_t *vtbl, const void *obj_data, const int num_vecs, const struct RTOp_SubVector vecs[], const int num_targ_vecs, const struct RTOp_MutableSubVector targ_vecs[], RTOp_ReductTarget targ_obj)
char RTOp_char_type
Definition: RTOp.h:70
RTOp_index_type sub_dim
Definition: RTOp.h:334
int RTOp_TOp_set_sub_vector_construct(const struct RTOp_SparseSubVector *sub_vec, struct RTOp_RTOp *op)
static int load_op_state(const struct RTOp_obj_type_vtbl_t *vtbl, const void *dummy, int num_values, const RTOp_value_type value_data[], int num_indexes, const RTOp_index_type index_data[], int num_chars, const RTOp_char_type char_data[], void **obj_data)
#define RTOp_ERR_INVALID_NUM_VECS
Definition: RTOp.h:266
RTOp_index_type global_offset
RTOp_value_type * values
Definition: RTOp.h:336
const struct RTOp_obj_type_vtbl_t RTOp_obj_null_vtbl
static int extract_op_state(const struct RTOp_obj_type_vtbl_t *vtbl, const void *dummy, void *obj_data, int num_values, RTOp_value_type value_data[], int num_indexes, RTOp_index_type index_data[], int num_chars, RTOp_char_type char_data[])
struct RTOp_SparseSubVector sub_vec
static struct RTOp_obj_type_vtbl_t instance_obj_vtbl
void * obj_data
Definition: RTOp.h:800
const struct RTOp_RTOp_vtbl_t * vtbl
Definition: RTOp.h:802
static int get_op_type_num_entries(const struct RTOp_obj_type_vtbl_t *vtbl, const void *obj_data, int *num_values, int *num_indexes, int *num_chars)
RTOp_index_type global_offset
Definition: RTOp.h:332
const RTOp_value_type * values
#define RTOp_ERR_INVALID_NUM_TARG_VECS
Definition: RTOp.h:268
int RTOp_TOp_set_sub_vector_set_sub_vec(const struct RTOp_SparseSubVector *sub_vec, struct RTOp_RTOp *op)
Teuchos_Ordinal RTOp_index_type
Definition: RTOp.h:68
#define RTOp_REDUCT_OBJ_NULL
Definition: RTOp.h:192