Collection of Concrete Vector Reduction/Transformation Operator Implementations  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
RTOpPack_TOpSetSubVector_def.hpp
1 // @HEADER
2 // *****************************************************************************
3 // RTOp: Interfaces and Support Software for Vector Reduction Transformation
4 // Operations
5 //
6 // Copyright 2006 NTESS and the RTOp contributors.
7 // SPDX-License-Identifier: BSD-3-Clause
8 // *****************************************************************************
9 // @HEADER
10 
11 #ifndef RTOPPACK_TOP_SET_SUB_VECTOR_DEF_HPP
12 #define RTOPPACK_TOP_SET_SUB_VECTOR_DEF_HPP
13 
14 
15 namespace RTOpPack {
16 
17 
18 template<class Scalar>
20  :RTOpT<Scalar>("TOpSetSubVector")
21 {}
22 
23 
24 template<class Scalar>
26  :RTOpT<Scalar>("TOpSetSubVector")
27 {
28  set_sub_vec(sub_vec);
29 }
30 
31 
32 template<class Scalar>
34 {
35  sub_vec_ = sub_vec;
36 }
37 
38 
39 // Overridden from RTOpT
40 
41 
42 template<class Scalar>
44 {
45  return false;
46 }
47 
48 
49 template<class Scalar>
51  const ArrayView<const ConstSubVectorView<Scalar> > &sub_vecs,
52  const ArrayView<const SubVectorView<Scalar> > &targ_sub_vecs,
53  const Ptr<ReductTarget> &reduct_obj
54  ) const
55 {
56 
57  typedef typename Teuchos::ArrayRCP<Scalar>::iterator iter_t;
58  typedef typename Teuchos::ArrayRCP<const Scalar>::iterator const_iter_t;
59  typedef typename Teuchos::ArrayRCP<const Teuchos_Ordinal>::iterator const_indices_iter_t;
60 
61  validate_apply_op( *this, 0, 1, false, sub_vecs, targ_sub_vecs, reduct_obj.getConst() );
62 
63  // Get the dense subvector data that we will set
64  const SubVectorView<Scalar> &z = targ_sub_vecs[0];
65  const index_type z_global_offset = z.globalOffset();
66  const index_type z_sub_dim = z.subDim();
67  iter_t z_val = z.values().begin();
68  const ptrdiff_t z_val_s = z.stride();
69 
70  // Get the sparse subvector data
71  const index_type v_global_offset = sub_vec_.globalOffset();
72  const index_type v_sub_dim = sub_vec_.subDim();
73  const index_type v_sub_nz = sub_vec_.subNz();
74  const_iter_t v_val = sub_vec_.values().begin();
75  const ptrdiff_t v_val_s = sub_vec_.valuesStride();
76  const bool has_v_ind = !is_null(sub_vec_.indices());
77  const_indices_iter_t v_ind = sub_vec_.indices().begin();
78  const ptrdiff_t v_ind_s = sub_vec_.indicesStride();
79  const ptrdiff_t v_l_off = sub_vec_.localOffset();
80  //const bool v_sorted = sub_vec_.isSorted();
81 
82  //
83  // Set part of the sub-vector v for this chunk z.
84  //
85 
86  if( v_global_offset + v_sub_dim < z_global_offset + 1
87  || z_global_offset + z_sub_dim < v_global_offset + 1 )
88  {
89  // The sub-vector that we are setting does not overlap with this vector
90  // chunk!
91  return;
92  }
93 
94  if( v_sub_nz == 0 )
95  return; // The sparse sub-vector we are reading from is empty?
96 
97  // Get the number of elements that overlap
98  index_type num_overlap;
99  if( v_global_offset <= z_global_offset ) {
100  if( v_global_offset + v_sub_dim >= z_global_offset + z_sub_dim )
101  num_overlap = z_sub_dim;
102  else
103  num_overlap = (v_global_offset + v_sub_dim) - z_global_offset;
104  }
105  else {
106  if( z_global_offset + z_sub_dim >= v_global_offset + v_sub_dim )
107  num_overlap = v_sub_dim;
108  else
109  num_overlap = (z_global_offset + z_sub_dim) - v_global_offset;
110  }
111 
112  // Set the part of the sub-vector that overlaps
113  if (has_v_ind) {
114  // Sparse elements
115  // Set the overlapping elements to zero first.
116  if( v_global_offset >= z_global_offset )
117  z_val += (v_global_offset - z_global_offset) * z_val_s;
118  for( index_type k = 0; k < num_overlap; ++k, z_val += z_val_s )
119  *z_val = 0.0;
120  // Now set the sparse entries
121  z_val = targ_sub_vecs[0].values().begin();
122  for( index_type k = 0; k < v_sub_nz; ++k, v_val += v_val_s, v_ind += v_ind_s ) {
123  const index_type i = v_global_offset + v_l_off + (*v_ind);
124  if( z_global_offset < i && i <= z_global_offset + z_sub_dim )
125  z_val[ z_val_s * (i - z_global_offset - 1) ] = *v_val;
126  }
127  // ToDo: Implement a faster version for v sorted and eliminate the
128  // if statement in the above loop.
129  }
130  else {
131  // Dense elements
132  if( v_global_offset <= z_global_offset )
133  v_val += (z_global_offset - v_global_offset) * v_val_s;
134  else
135  z_val += (v_global_offset - z_global_offset) * z_val_s;
136  for( index_type k = 0; k < num_overlap; ++k, v_val += v_val_s, z_val += z_val_s )
137  *z_val = *v_val;
138  }
139 }
140 
141 
142 } // namespace RTOpPack
143 
144 
145 #endif // RTOPPACK_TOP_SET_SUB_VECTOR_DEF_HPP
bool is_null(const boost::shared_ptr< T > &p)
void set_sub_vec(const SparseSubVectorT< Scalar > &sub_vec)
Ordinal globalOffset() const
void apply_op_impl(const ArrayView< const ConstSubVectorView< Scalar > > &sub_vecs, const ArrayView< const SubVectorView< Scalar > > &targ_sub_vecs, const Ptr< ReductTarget > &reduct_obj) const