Kokkos Core Kernels Package  Version of the Day
Kokkos_StaticCrsGraph.hpp
1 /*
2 //@HEADER
3 // ************************************************************************
4 //
5 // Kokkos v. 2.0
6 // Copyright (2014) Sandia Corporation
7 //
8 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
9 // the U.S. Government retains certain rights in this software.
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 H. Carter Edwards (hcedwar@sandia.gov)
39 //
40 // ************************************************************************
41 //@HEADER
42 */
43 
44 #ifndef KOKKOS_STATICCRSGRAPH_HPP
45 #define KOKKOS_STATICCRSGRAPH_HPP
46 
47 #include <string>
48 #include <vector>
49 
50 #include <Kokkos_Core.hpp>
51 
52 namespace Kokkos {
53 
54 namespace Impl {
55  template<class RowOffsetsType, class RowBlockOffsetsType>
56  struct StaticCrsGraphBalancerFunctor {
57  typedef typename RowOffsetsType::non_const_value_type int_type;
58  RowOffsetsType row_offsets;
59  RowBlockOffsetsType row_block_offsets;
60 
61  int_type cost_per_row, num_blocks;
62 
63  StaticCrsGraphBalancerFunctor(RowOffsetsType row_offsets_,
64  RowBlockOffsetsType row_block_offsets_,
65  int_type cost_per_row_, int_type num_blocks_):
66  row_offsets(row_offsets_),
67  row_block_offsets(row_block_offsets_),
68  cost_per_row(cost_per_row_),
69  num_blocks(num_blocks_){}
70 
71  KOKKOS_INLINE_FUNCTION
72  void operator() (const int_type& iRow) const {
73  const int_type num_rows = row_offsets.dimension_0()-1;
74  const int_type num_entries = row_offsets(num_rows);
75  const int_type total_cost = num_entries + num_rows*cost_per_row;
76 
77  const double cost_per_workset = 1.0*total_cost/num_blocks;
78 
79  const int_type row_cost = row_offsets(iRow+1)-row_offsets(iRow) + cost_per_row;
80 
81  int_type count = row_offsets(iRow+1) + cost_per_row*iRow;
82 
83  if(iRow == num_rows-1) row_block_offsets(num_blocks) = num_rows;
84 
85  if(true) {
86  int_type current_block = (count-row_cost-cost_per_row)/cost_per_workset;
87  int_type end_block = count/cost_per_workset;
88 
89  // Handle some corner cases for the last two blocks.
90  if(current_block >= num_blocks-2) {
91  if((current_block == num_blocks-2) && (count >= (current_block + 1) * cost_per_workset)) {
92  int_type row = iRow;
93  int_type cc = count-row_cost-cost_per_row;
94  int_type block = cc/cost_per_workset;
95  while((block>0) && (block==current_block)) {
96  cc = row_offsets(row)+row*cost_per_row;
97  block = cc/cost_per_workset;
98  row--;
99  }
100  if((count-cc-row_cost-cost_per_row) < num_entries-row_offsets(iRow+1)) {
101  row_block_offsets(current_block+1) = iRow+1;
102  } else {
103  row_block_offsets(current_block+1) = iRow;
104  }
105  }
106  } else {
107  if((count >= (current_block + 1) * cost_per_workset) ||
108  (iRow+2 == row_offsets.dimension_0())) {
109  if(end_block>current_block+1) {
110  int_type num_block = end_block-current_block;
111  row_block_offsets(current_block+1) = iRow;
112  for(int_type block = current_block+2; block <= end_block; block++)
113  if((block<current_block+2+(num_block-1)/2))
114  row_block_offsets(block) = iRow;
115  else
116  row_block_offsets(block) = iRow+1;
117  } else {
118  row_block_offsets(current_block+1) = iRow+1;
119  }
120  }
121  }
122 
123  }
124  }
125  };
126 }
127 
158 template< class DataType,
159  class Arg1Type,
160  class Arg2Type = void,
161  typename SizeType = typename ViewTraits<DataType*, Arg1Type, Arg2Type, void >::size_type>
163 private:
165 
166 public:
167  typedef DataType data_type;
168  typedef typename traits::array_layout array_layout;
169  typedef typename traits::execution_space execution_space;
170  typedef typename traits::device_type device_type;
171  typedef SizeType size_type;
172 
178 
179  entries_type entries;
180  row_map_type row_map;
181  row_block_type row_block_offsets;
182 
184  StaticCrsGraph () : entries(), row_map(), row_block_offsets() {}
185 
187  StaticCrsGraph (const StaticCrsGraph& rhs) : entries (rhs.entries), row_map (rhs.row_map),
188  row_block_offsets(rhs.row_block_offsets)
189  {}
190 
191  template<class EntriesType, class RowMapType>
192  StaticCrsGraph (const EntriesType& entries_,const RowMapType& row_map_) : entries (entries_), row_map (row_map_),
193  row_block_offsets()
194  {}
195 
200  StaticCrsGraph& operator= (const StaticCrsGraph& rhs) {
201  entries = rhs.entries;
202  row_map = rhs.row_map;
203  row_block_offsets = rhs.row_block_offsets;
204  return *this;
205  }
206 
211 
214  KOKKOS_INLINE_FUNCTION
215  size_type numRows() const {
216  return (row_map.dimension_0 () != 0) ?
217  row_map.dimension_0 () - static_cast<size_type> (1) :
218  static_cast<size_type> (0);
219  }
220 
224  void create_block_partitioning(size_type num_blocks, size_type fix_cost_per_row = 4) {
226  block_offsets("StatisCrsGraph::load_balance_offsets",num_blocks+1);
227 
228  Impl::StaticCrsGraphBalancerFunctor<row_map_type,View< size_type* , array_layout, device_type > >
229  partitioner(row_map,block_offsets,fix_cost_per_row,num_blocks);
230 
232  Kokkos::fence();
233 
234  row_block_offsets = block_offsets;
235  }
236 };
237 
238 //----------------------------------------------------------------------------
239 
240 template< class StaticCrsGraphType , class InputSizeType >
241 typename StaticCrsGraphType::staticcrsgraph_type
242 create_staticcrsgraph( const std::string & label ,
243  const std::vector< InputSizeType > & input );
244 
245 template< class StaticCrsGraphType , class InputSizeType >
246 typename StaticCrsGraphType::staticcrsgraph_type
247 create_staticcrsgraph( const std::string & label ,
248  const std::vector< std::vector< InputSizeType > > & input );
249 
250 //----------------------------------------------------------------------------
251 
252 template< class DataType ,
253  class Arg1Type ,
254  class Arg2Type ,
255  typename SizeType >
257 create_mirror_view( const StaticCrsGraph<DataType,Arg1Type,Arg2Type,SizeType > & input );
258 
259 template< class DataType ,
260  class Arg1Type ,
261  class Arg2Type ,
262  typename SizeType >
264 create_mirror( const StaticCrsGraph<DataType,Arg1Type,Arg2Type,SizeType > & input );
265 
266 } // namespace Kokkos
267 
268 //----------------------------------------------------------------------------
269 //----------------------------------------------------------------------------
270 
271 #include <impl/Kokkos_StaticCrsGraph_factory.hpp>
272 
273 //----------------------------------------------------------------------------
274 //----------------------------------------------------------------------------
275 
276 namespace Kokkos {
277 namespace Impl {
278 
279 template< class GraphType >
280 struct StaticCrsGraphMaximumEntry {
281 
282  typedef typename GraphType::execution_space execution_space ;
283  typedef typename GraphType::data_type value_type ;
284 
285  const typename GraphType::entries_type entries ;
286 
287  StaticCrsGraphMaximumEntry( const GraphType & graph ) : entries( graph.entries ) {}
288 
289  KOKKOS_INLINE_FUNCTION
290  void operator()( const unsigned i , value_type & update ) const
291  { if ( update < entries(i) ) update = entries(i); }
292 
293  KOKKOS_INLINE_FUNCTION
294  void init( value_type & update ) const
295  { update = 0 ; }
296 
297  KOKKOS_INLINE_FUNCTION
298  void join( volatile value_type & update ,
299  volatile const value_type & input ) const
300  { if ( update < input ) update = input ; }
301 };
302 
303 }
304 
305 template< class DataType, class Arg1Type, class Arg2Type, typename SizeType >
306 DataType maximum_entry( const StaticCrsGraph< DataType , Arg1Type , Arg2Type , SizeType > & graph )
307 {
309  typedef Impl::StaticCrsGraphMaximumEntry< GraphType > FunctorType ;
310 
311  DataType result = 0 ;
312  Kokkos::parallel_reduce( graph.entries.dimension_0(),
313  FunctorType(graph), result );
314  return result ;
315 }
316 
317 } // namespace Kokkos
318 
319 //----------------------------------------------------------------------------
320 //----------------------------------------------------------------------------
321 
322 #endif /* #ifndef KOKKOS_CRSARRAY_HPP */
323 
void parallel_reduce(const std::string &label, const PolicyType &policy, const FunctorType &functor, ReturnType &return_value, typename Impl::enable_if< Kokkos::Impl::is_execution_policy< PolicyType >::value >::type *=0)
Parallel reduction.
~StaticCrsGraph()
Destroy this view of the array. If the last view then allocated memory is deallocated.
void create_block_partitioning(size_type num_blocks, size_type fix_cost_per_row=4)
Create a row partitioning into a given number of blocks balancing non-zeros + a fixed cost per row...
StaticCrsGraph(const StaticCrsGraph &rhs)
Copy constructor (shallow copy).
Memory space for main process and CPU execution spaces.
void parallel_for(const ExecPolicy &policy, const FunctorType &functor, const std::string &str="", typename Impl::enable_if< ! Impl::is_integral< ExecPolicy >::value >::type *=0)
Execute functor in parallel according to the execution policy.
Execution policy for work over a range of an integral type.
Compressed row storage array.
KOKKOS_INLINE_FUNCTION size_type numRows() const
Return number of rows in the graph.
Traits class for accessing attributes of a View.
StaticCrsGraph()
Construct an empty view.