-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
628 triangle counting algorithm #190
base: develop
Are you sure you want to change the base?
Changes from all commits
06590c0
670e85e
0d3fd9d
14a380b
3904c71
5c1f559
1cf4e29
e5fb254
c1b812f
624c193
1c09729
8ad6be6
8746909
5db9121
e6101b9
a4bb7a5
28599ab
0e59cfa
4a0d635
3a83956
fa76769
b5dd0c5
45589eb
6972be0
765d3e3
7253d93
841aeec
7d5f34c
dccb53b
218775e
17b6d7d
aea630d
d80ccf5
96ea3fa
1d30646
90380a6
d6c785d
4d9ba81
fee2add
725b81f
ba7c80e
a005d64
37c3ef4
aaafcac
e0cd596
8ce27af
ce3a176
8efbcbf
671da32
be71215
8cef1ab
22319fb
dd8e901
dd5f7ee
888cb3f
a89b6eb
9e3007e
2ecdf1e
8933de1
5064f1b
513764d
331158e
194a303
8cf6dec
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,249 @@ | ||
|
||
/* | ||
* Copyright 2023 Huawei Technologies Co., Ltd. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
/** | ||
* @file | ||
* | ||
* Implements the triangle counting algorithm, using different methods. | ||
* | ||
* @author Benjamin Lozes | ||
* @date: May 10th, 2023 | ||
*/ | ||
|
||
#ifndef _H_GRB_TRIANGLE_COUNT | ||
#define _H_GRB_TRIANGLE_COUNT | ||
|
||
#include <map> | ||
#include <numeric> | ||
#include <vector> | ||
|
||
#include <graphblas/utils/iterators/nonzeroIterator.hpp> | ||
|
||
#include <graphblas.hpp> | ||
|
||
namespace grb { | ||
|
||
namespace algorithms { | ||
|
||
enum class TriangleCountAlgorithm { Burkhardt, Cohen, Sandia_TT }; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. doxy comment missing -- may be nice to add the references for each variant in the doxy |
||
|
||
std::map< TriangleCountAlgorithm, std::string > TriangleCountAlgorithmNames = { | ||
{ TriangleCountAlgorithm::Burkhardt, "Burkhardt" }, | ||
{ TriangleCountAlgorithm::Cohen, "Cohen" }, | ||
{ TriangleCountAlgorithm::Sandia_TT, "Sandia_TT" } | ||
}; | ||
Comment on lines
+44
to
+48
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should move into a |
||
|
||
template< | ||
class Semiring, class MulMonoid, class SumMonoid, | ||
Descriptor descr_mxm = descriptors::no_operation, | ||
Descriptor descr_ewa = descriptors::no_operation, | ||
Descriptor descr_reduce = descriptors::no_operation, | ||
typename D1, typename RIT1, typename CIT1, typename NIT1, | ||
typename D2, typename RIT2, typename CIT2, typename NIT2, | ||
typename D3, typename RIT3, typename CIT3, typename NIT3, | ||
typename D4, typename RIT4, typename CIT4, typename NIT4, | ||
typename D5, typename RIT5, typename CIT5, typename NIT5, | ||
typename D6 | ||
> | ||
RC triangle_count_generic( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should probably also go into a |
||
size_t & count, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no space after There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (below args also) |
||
Matrix< D1, config::default_backend, RIT1, CIT1, NIT1 > & MXM_out, | ||
const Matrix< D2, config::default_backend, RIT2, CIT2, NIT2 > & MXM_lhs, | ||
const Matrix< D3, config::default_backend, RIT3, CIT3, NIT3 > & MXM_rhs, | ||
Matrix< D4, config::default_backend, RIT4, CIT4, NIT4 > & EWA_out, | ||
const Matrix< D5, config::default_backend, RIT5, CIT5, NIT5 > & EWA_rhs, | ||
const D6 div_factor, | ||
const Semiring mxm_semiring = Semiring(), | ||
const MulMonoid ewiseapply_monoid = MulMonoid(), | ||
const SumMonoid sumreduce_monoid = SumMonoid() | ||
) { | ||
if( ( &MXM_out == &MXM_lhs ) || ( &MXM_out == &MXM_rhs ) ) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. use |
||
return ILLEGAL; | ||
} | ||
|
||
RC rc = SUCCESS; | ||
|
||
// Compute MXM_out = Mlhs * Mrhs | ||
rc = rc ? rc : mxm< descr_mxm >( MXM_out, MXM_lhs, MXM_rhs, mxm_semiring, Phase::RESIZE ); | ||
rc = rc ? rc : mxm< descr_mxm >( MXM_out, MXM_lhs, MXM_rhs, mxm_semiring, Phase::EXECUTE ); | ||
|
||
// Compute MXM_out .*= EWA_rhs | ||
// FIXME: Replace by a foldl( Matrix[in,out], Matrix[in], Monoid ) - not implemented yet | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. does an issue exist to provide it? |
||
// Will then become: | ||
// rc = rc ? rc : eWiseApply< descr_ewa >( MXM_out, MXM_out, EWA_rhs, ewiseapply_monoid, Phase::RESIZE ); | ||
// rc = rc ? rc : eWiseApply< descr_ewa >( MXM_out, MXM_out, EWA_rhs, ewiseapply_monoid, Phase::EXECUTE ); | ||
Comment on lines
+87
to
+88
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. eWiseApply -> foldl and remove one of the duplicate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, if replacing it with |
||
// Instead of: | ||
rc = rc ? rc : eWiseApply< descr_ewa >( EWA_out, MXM_out, EWA_rhs, ewiseapply_monoid, Phase::RESIZE ); | ||
rc = rc ? rc : eWiseApply< descr_ewa >( EWA_out, MXM_out, EWA_rhs, ewiseapply_monoid, Phase::EXECUTE ); | ||
|
||
// Compute a sum reduction over <EWA_out> into <count> | ||
count = static_cast< size_t >( 0 ); | ||
rc = rc ? rc : foldl< descr_reduce >( count, EWA_out, sumreduce_monoid ); | ||
|
||
// Apply the div_factor to the reduction result | ||
count /= div_factor; | ||
|
||
return rc; | ||
} | ||
|
||
/** | ||
* Given a graph, indicates how many triangles are contained within. | ||
* | ||
* @tparam D The type of the matrix non-zero values. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. alignment should be done with spaces (the white space between There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (below also) |
||
* | ||
* @param[out] count The number of triangles. | ||
* Any prior contents will be ignored. | ||
* @param[in] A The input graph. | ||
* @param[in,out] MXM_out Buffer matrix with the same dimensions as the input | ||
* graph. Any prior contents will be ignored. | ||
Comment on lines
+110
to
+112
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The spec doesn't say |
||
* @param[in] L Lower triangular matrix of the input graph (optional) | ||
* @param[in] U Lower triangular matrix of the input graph (optional) | ||
* | ||
* | ||
* @returns #grb::SUCCESS When the computation completes successfully. | ||
* @returns #grb::MISMATCH If the dimensions of the input matrices/buffers | ||
* are incompatible. | ||
* @returns #grb::ILLEGAL If the given algorithm does not exist. | ||
* @returns #grb::PANIC If an unrecoverable error has been encountered. The | ||
* output as well as the state of ALP/GraphBLAS is | ||
* undefined. | ||
* | ||
* \par Performance semantics | ||
* | ||
* -# This function does not allocate nor free dynamic memory, nor shall it | ||
* make any system calls. | ||
* | ||
Comment on lines
+127
to
+129
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a resize phase which can actually dynamically allocate memory. Therefore, the #grb::OUT_OF_MEMORY error code should be added to the directly preceding list of return options, where the highlighted text here should mention that the performance here strongly depends on the sparsity structure, which affects all of work, data movement, and memory usage costs. The only thing that is kept constant in all algorithms is the number of synchronisations needed in case there are more than 1 user processes-- namely, those required for one mxm, one eWiseApply (or foldl), and one reduction. ("For BSP1D, this amounts to 2 synchronisations." could be added as a |
||
* For performance semantics regarding work, inter-process data movement, | ||
* intra-process data movement, synchronisations, and memory use, please see | ||
* the specification of the ALP primitives this function relies on. These | ||
* performance semantics, with the exception of getters such as #grb::nnz, are | ||
* specific to the backend selected during compilation. | ||
*/ | ||
template< | ||
Descriptor descr = descriptors::no_operation, | ||
typename D1, typename RIT1, typename CIT1, typename NIT1, | ||
typename D2, typename RIT2, typename CIT2, typename NIT2, | ||
typename D3, typename RIT3, typename CIT3, typename NIT3, | ||
typename D4, typename RIT4, typename CIT4, typename NIT4, | ||
class Semiring = Semiring< operators::add< D1 >, | ||
operators::mul< D1 >, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. too many tabs (below also) |
||
identities::zero, | ||
identities::one >, | ||
class MulMonoid = Monoid< operators::mul< D1 >, | ||
identities::one >, | ||
class SumMonoid = Monoid< operators::add< size_t, D1, size_t >, | ||
identities::zero > | ||
> | ||
RC triangle_count( | ||
const TriangleCountAlgorithm algo, | ||
size_t & count, | ||
const Matrix< D1, config::default_backend, RIT1, CIT1, NIT1 > & A, | ||
Matrix< D2, config::default_backend, RIT2, CIT2, NIT2 > & MXM_out, | ||
Matrix< D3, config::default_backend, RIT3, CIT3, NIT3 > & EWA_out, | ||
Matrix< D4, config::default_backend, RIT4, CIT4, NIT4 > & L = { 0, 0 }, | ||
Matrix< D4, config::default_backend, RIT4, CIT4, NIT4 > & U = { 0, 0 } | ||
) { | ||
// Static assertions | ||
static_assert( std::is_integral< D1 >::value, "Type D1 must be integral" ); | ||
|
||
// Sanity checks | ||
if( nrows( A ) != ncols( A ) ) { | ||
std::cerr << "Matrix A must be square" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( ncols( L ) != nrows( L ) ) { | ||
std::cerr << "Matrix L must be square" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( nrows( A ) != ncols( L ) ) { | ||
std::cerr << "Matrices A and L must have the same dimensions" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( ncols( U ) != nrows( U ) ) { | ||
std::cerr << "Matrix U must be square" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( nrows( A ) != ncols( U ) ) { | ||
std::cerr << "Matrices A and U must have the same dimensions" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( ncols( MXM_out ) != nrows( MXM_out ) ) { | ||
std::cerr << "Matrix MXM_out must be square" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( nrows( A ) != ncols( MXM_out ) ) { | ||
std::cerr << "Matrices A and MXM_out must have the same dimensions" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( ncols( EWA_out ) != nrows( EWA_out ) ) { | ||
std::cerr << "Matrix EWA_out must be square" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( nrows( A ) != ncols( EWA_out ) ) { | ||
std::cerr << "Matrices A and EWA_out must have the same dimensions" << std::endl; | ||
return MISMATCH; | ||
} | ||
|
||
// Dispatch to the appropriate algorithm | ||
switch( algo ) { | ||
case TriangleCountAlgorithm::Burkhardt: { | ||
return triangle_count_generic< | ||
Semiring, MulMonoid, SumMonoid, | ||
descr | descriptors::transpose_right | ||
>( count, MXM_out, A, A, EWA_out, A, 6UL ); | ||
} | ||
|
||
case TriangleCountAlgorithm::Cohen: { | ||
if( nrows( L ) == 0 || ncols( L ) == 0 ) { | ||
std::cerr << "Matrix L must be provided for the Cohen algorithm" << std::endl; | ||
return MISMATCH; | ||
} | ||
if( nrows( U ) == 0 || ncols( U ) == 0 ) { | ||
std::cerr << "Matrix U must be provided for the Cohen algorithm" << std::endl; | ||
return MISMATCH; | ||
} | ||
|
||
return triangle_count_generic< | ||
Semiring, MulMonoid, SumMonoid | ||
>( count, MXM_out, L, U, EWA_out, A, 2UL ); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. extra space before |
||
} | ||
|
||
case TriangleCountAlgorithm::Sandia_TT: { | ||
if( ( nrows( U ) == 0 || ncols( U ) == 0 ) && ( nrows( L ) == 0 || ncols( L ) == 0 ) ) { | ||
std::cerr << "Matrix L or U must be provided for the Sandia_TT algorithm" << std::endl; | ||
return MISMATCH; | ||
} | ||
|
||
const Matrix< D4, config::default_backend, RIT4, CIT4, NIT4 > & T = ( nrows( U ) == 0 || ncols( U ) == 0 ) ? L : U; | ||
return triangle_count_generic< | ||
Semiring, MulMonoid, SumMonoid | ||
>( count, MXM_out, T, T, EWA_out, T, 1UL ); | ||
} | ||
|
||
default: | ||
std::cerr << "Unknown TriangleCountAlgorithm enum value" << std::endl; | ||
return ILLEGAL; | ||
} | ||
|
||
return SUCCESS; | ||
} | ||
|
||
} // namespace algorithms | ||
|
||
} // namespace grb | ||
|
||
#endif // _H_GRB_TRIANGLE_COUNT | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. missing empty line at the end here |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One more empty line here