ALP User Documentation  0.8.preview
Algebraic Programming User Documentation
spy.hpp
Go to the documentation of this file.
1 
2 /*
3  * Copyright 2021 Huawei Technologies Co., Ltd.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
26 #ifndef _H_GRB_ALGORITHMS_SPY
27 #define _H_GRB_ALGORITHMS_SPY
28 
29 #include <type_traits>
30 #include <vector>
31 
32 #include <graphblas.hpp>
33 
34 
35 namespace grb {
36 
37  namespace algorithms {
38 
39  namespace internal {
40 
47  template< bool normalize, typename IOType, typename InputType >
48  RC spy_from_bool_or_void_input(
50  const size_t m, const size_t n,
51  const size_t small_m, const size_t small_n
52  ) {
53  static_assert( std::is_same< InputType, bool >::value ||
54  std::is_same< InputType, void >::value,
55  "Error in call to internal::spy_from_bool_or_void_input"
56  );
57 
58  // Q must be n by small_n
59  grb::Matrix< unsigned char > Q( n, small_n );
60  grb::RC ret = grb::resize( Q, n );
61  // TODO FIXME use repeating + auto-incrementing iterators
62  std::vector< size_t > I, J;
63  std::vector< unsigned char > V;
64  const double n_sample = static_cast< double >(n) /
65  static_cast< double >(small_n);
66  for( size_t i = 0; i < n; ++i ) {
67  I.push_back( i );
68  J.push_back( static_cast< double >(i) / n_sample );
69  V.push_back( 1 );
70  }
72  Q, &(I[0]), &(J[0]), &(V[0]), n,
74  );
75 
76  // P must be small_m by m
77  grb::Matrix< unsigned char > P( small_m, m );
78  if( ret == SUCCESS ) {
79  ret = grb::resize( P, m );
80  // TODO FIXME use repeating + auto-incrementing iterators
81  std::vector< size_t > I, J;
82  std::vector< unsigned char > V;
83  const double m_sample = static_cast< double >(m) /
84  static_cast< double >(small_m);
85  for( size_t i = 0; i < m; ++i ) {
86  I.push_back( static_cast< double >(i) / m_sample );
87  J.push_back( i );
88  V.push_back( 1 );
89  }
91  P, &(I[0]), &(J[0]), &(V[0]), m,
93  );
94  }
95 
96  // tmp must be m by small_n OR small_m by n
97  if( ret == SUCCESS && m - small_m > n - small_n ) {
103  > leftAssignAndAdd;
104  grb::Matrix< size_t > tmp( small_m, n );
105  ret = ret ? ret : grb::mxm( tmp, P, in, leftAssignAndAdd, RESIZE );
106  ret = ret ? ret : grb::mxm( tmp, P, in, leftAssignAndAdd, EXECUTE );
107  ret = ret ? ret : grb::mxm( out, tmp, Q, leftAssignAndAdd, RESIZE );
108  ret = ret ? ret : grb::mxm( out, tmp, Q, leftAssignAndAdd, EXECUTE );
109  } else {
115  > rightAssignAndAdd;
116  grb::Matrix< size_t > tmp( m, small_n );
117  ret = ret ? ret : grb::mxm( tmp, in, Q, rightAssignAndAdd, RESIZE );
118  ret = ret ? ret : grb::mxm( tmp, in, Q, rightAssignAndAdd, EXECUTE );
119  ret = ret ? ret : grb::mxm( out, P, tmp, rightAssignAndAdd, RESIZE );
120  ret = ret ? ret : grb::mxm( out, P, tmp, rightAssignAndAdd, EXECUTE );
121  }
122 
123  if( ret == SUCCESS && normalize ) {
124  ret = grb::eWiseLambda( [] (const size_t, const size_t, IOType &v ) {
125  assert( v > 0 );
126  v = static_cast< IOType >( 1 ) / v;
127  }, out );
128  }
129 
130  return ret;
131  }
132 
133  }
134 
194  template<
195  bool normalize = false,
196  typename IOType, typename InputType
197  >
199  static_assert( !normalize || std::is_floating_point< IOType >::value,
200  "When requesting a normalised spy plot, the data type must be "
201  "floating-point"
202  );
203 
204  const size_t m = grb::nrows( in );
205  const size_t n = grb::ncols( in );
206  const size_t small_m = grb::nrows( out );
207  const size_t small_n = grb::ncols( out );
208 
209  // runtime checks and shortcuts
210  if( small_m > m ) { return ILLEGAL; }
211  if( small_n > n ) { return ILLEGAL; }
212  if( small_m == m && small_n == n ) {
213  return grb::set< grb::descriptors::structural >( out, in, 1 );
214  }
215 
216  grb::RC ret = grb::clear( out );
217 
218  grb::Matrix< bool > tmp( m, n );
219  ret = ret ? ret : grb::resize( tmp, grb::nnz( in ) );
220  ret = ret ? ret : grb::set< grb::descriptors::structural >( tmp, in, true );
221  ret = ret ? ret : grb::algorithms::internal::template
222  spy_from_bool_or_void_input< normalize >(
223  out, tmp, m, n, small_m, small_n
224  );
225 
226  return ret;
227  }
228 
230  template< bool normalize = false, typename IOType >
232  static_assert( !normalize || std::is_floating_point< IOType >::value,
233  "When requesting a normalised spy plot, the data type must be "
234  "floating-point" );
235 
236  const size_t m = grb::nrows( in );
237  const size_t n = grb::ncols( in );
238  const size_t small_m = grb::nrows( out );
239  const size_t small_n = grb::ncols( out );
240 
241  // runtime checks and shortcuts
242  if( small_m > m ) { return ILLEGAL; }
243  if( small_n > n ) { return ILLEGAL; }
244  if( small_m == m && small_n == n ) {
245  return grb::set< grb::descriptors::structural >( out, in, 1 );
246  }
247 
248  grb::RC ret = grb::clear( out );
249 
250  ret = ret ? ret : grb::algorithms::internal::template
251  spy_from_bool_or_void_input< normalize >(
252  out, in, m, n, small_m, small_n
253  );
254 
255  return ret;
256  }
257 
259  template< bool normalize = false, typename IOType >
261  static_assert( !normalize || std::is_floating_point< IOType >::value,
262  "When requesting a normalised spy plot, the data type must be "
263  "floating-point"
264  );
265 
266  const size_t m = grb::nrows( in );
267  const size_t n = grb::ncols( in );
268  const size_t small_m = grb::nrows( out );
269  const size_t small_n = grb::ncols( out );
270 
271  // runtime checks and shortcuts
272  if( small_m > m ) { return ILLEGAL; }
273  if( small_n > n ) { return ILLEGAL; }
274  if( small_m == m && small_n == n ) {
275  return grb::set< grb::descriptors::structural >( out, in, 1 );
276  }
277 
278  grb::RC ret = grb::clear( out );
279 
280  ret = ret ? ret : grb::algorithms::internal::template
281  spy_from_bool_or_void_input< normalize >(
282  out, in, m, n, small_m, small_n
283  );
284 
285  return ret;
286  }
287 
288  } // end namespace ``grb::algorithms''
289 
290 } // end namespace ``grb''
291 
292 #endif // _H_GRB_ALGORITHMS_SPY
293 
RC spy(grb::Matrix< IOType > &out, const grb::Matrix< InputType > &in)
Given an input matrix and a smaller output matrix, map nonzeroes from the input matrix into the small...
Definition: spy.hpp:198
Standard identity for numerical addition.
Definition: identities.hpp:57
A call to a primitive has determined that one of its arguments was illegal as per the specification o...
Definition: rc.hpp:143
An ALP/GraphBLAS matrix.
Definition: matrix.hpp:72
RC
Return codes of ALP primitives.
Definition: rc.hpp:47
Speculatively assumes that the output container of the requested operation has enough capacity to com...
Definition: phase.hpp:257
Sequential mode IO.
Definition: iomode.hpp:75
size_t nnz(const Vector< DataType, backend, Coords > &x) noexcept
Request the number of nonzeroes in a given vector.
Definition: io.hpp:479
size_t nrows(const Matrix< InputType, backend, RIT, CIT, NIT > &A) noexcept
Requests the row size of a given matrix.
Definition: io.hpp:286
RC buildMatrixUnique(Matrix< InputType, implementation, RIT, CIT, NIT > &A, fwd_iterator1 I, const fwd_iterator1 I_end, fwd_iterator2 J, const fwd_iterator2 J_end, fwd_iterator3 V, const fwd_iterator3 V_end, const IOMode mode)
Assigns nonzeroes to the matrix from a coordinate format.
Definition: io.hpp:1340
This operator assigns the left-hand input if the right-hand input evaluates true.
Definition: ops.hpp:85
size_t ncols(const Matrix< InputType, backend, RIT, CIT, NIT > &A) noexcept
Requests the column size of a given matrix.
Definition: io.hpp:339
This operator assigns the right-hand input if the left-hand input evaluates true.
Definition: ops.hpp:141
Standard identity for the logical AND operator.
Definition: identities.hpp:178
This operator takes the sum of the two input parameters and writes it to the output variable.
Definition: ops.hpp:175
The ALP/GraphBLAS namespace.
Definition: graphblas.hpp:477
The main header to include in order to use the ALP/GraphBLAS API.
Speculatively assumes that the output container(s) of the requested operation lack the necessary capa...
Definition: phase.hpp:187
RC eWiseLambda(const Func f, const Vector< DataType, backend, Coords > &x, Args...)
Executes an arbitrary element-wise user-defined function f on any number of vectors of equal length.
Definition: blas1.hpp:3746
RC mxm(Matrix< OutputType, backend, CIT1, RIT1, NIT1 > &C, const Matrix< InputType1, backend, CIT2, RIT2, NIT2 > &A, const Matrix< InputType2, backend, CIT3, RIT3, NIT3 > &B, const Semiring &ring=Semiring(), const Phase &phase=EXECUTE)
Unmasked and in-place sparse matrix–sparse matrix multiplication (SpMSpM), .
Definition: blas3.hpp:96
Indicates the primitive has executed successfully.
Definition: rc.hpp:54
A generalised semiring.
Definition: semiring.hpp:190
RC clear(Vector< DataType, backend, Coords > &x) noexcept
Clears a given vector of all nonzeroes.
Definition: io.hpp:574
RC resize(Vector< InputType, backend, Coords > &x, const size_t new_nz) noexcept
Resizes the nonzero capacity of this vector.
Definition: io.hpp:703