-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #265 from sparcityeu/feature/min_degree_column
Feature/min degree column
- Loading branch information
Showing
6 changed files
with
305 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
#include "min_degree_column.h" | ||
|
||
#include <memory> | ||
#include <tuple> | ||
#include <unordered_map> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "sparsebase/utils/parameterizable.h" | ||
|
||
namespace sparsebase::feature { | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::MinDegreeColumn(ParamsType) { | ||
MinDegreeColumn(); | ||
} | ||
template <typename IDType, typename NNZType, typename ValueType> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::MinDegreeColumn() { | ||
Register(); | ||
this->params_ = std::shared_ptr<ParamsType>(new ParamsType()); | ||
this->pmap_.insert({get_id_static(), this->params_}); | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::MinDegreeColumn( | ||
const MinDegreeColumn<IDType, NNZType, ValueType> &d) { | ||
Register(); | ||
this->params_ = d.params_; | ||
this->pmap_ = d.pmap_; | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::MinDegreeColumn( | ||
const std::shared_ptr<ParamsType> r) { | ||
Register(); | ||
this->params_ = r; | ||
this->pmap_[get_id_static()] = r; | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::~MinDegreeColumn() = default; | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
void MinDegreeColumn<IDType, NNZType, ValueType>::Register() { | ||
this->RegisterFunction( | ||
{format::CSC<IDType, NNZType, ValueType>::get_id_static()}, | ||
GetMinDegreeColumnCSC); | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
std::vector<std::type_index> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::get_sub_ids() { | ||
return {typeid(MinDegreeColumn<IDType, NNZType, ValueType>)}; | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
std::vector<utils::Extractable *> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::get_subs() { | ||
return {new MinDegreeColumn<IDType, NNZType, ValueType>(*this)}; | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
std::type_index MinDegreeColumn<IDType, NNZType, ValueType>::get_id_static() { | ||
return typeid(MinDegreeColumn<IDType, NNZType, ValueType>); | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
std::unordered_map<std::type_index, std::any> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::Extract(format::Format *format, | ||
std::vector<context::Context *> c, | ||
bool convert_input) { | ||
return {{this->get_id(), | ||
std::forward<NNZType *>(GetMinDegreeColumn(format, c, convert_input))}}; | ||
}; | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
NNZType *MinDegreeColumn<IDType, NNZType, ValueType>::GetMinDegreeColumn( | ||
format::Format *format, std::vector<context::Context *> c, | ||
bool convert_input) { | ||
return this->Execute(this->params_.get(), c, convert_input, format); | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
std::tuple<std::vector<std::vector<format::Format *>>, NNZType *> | ||
MinDegreeColumn<IDType, NNZType, ValueType>::GetMinDegreeColumnCached( | ||
format::Format *format, std::vector<context::Context *> c, | ||
bool convert_input) { | ||
return this->CachedExecute(this->params_.get(), c, convert_input, false, | ||
format); | ||
} | ||
|
||
template <typename IDType, typename NNZType, typename ValueType> | ||
NNZType *MinDegreeColumn<IDType, NNZType, ValueType>::GetMinDegreeColumnCSC( | ||
std::vector<format::Format *> formats, utils::Parameters *params) { | ||
auto csc = formats[0]->AsAbsolute<format::CSC<IDType, NNZType, ValueType>>(); | ||
IDType num_col = csc->get_dimensions()[0]; | ||
auto *cols = csc->get_col_ptr(); | ||
NNZType *min_degree = new NNZType; | ||
*min_degree = cols[1] - cols[0]; | ||
for (int i = 1; i < num_col; i++) { | ||
*min_degree = std::min(*min_degree, cols[i + 1] - cols[i]); | ||
} | ||
return min_degree; | ||
} | ||
|
||
#if !defined(_HEADER_ONLY) | ||
#include "init/min_degree_column.inc" | ||
#endif | ||
} // namespace sparsebase::feature |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#include <vector> | ||
|
||
#include "sparsebase/config.h" | ||
#include "sparsebase/feature/feature_preprocess_type.h" | ||
#include "sparsebase/format/csc.h" | ||
#include "sparsebase/utils/parameterizable.h" | ||
|
||
#ifndef SPARSEBASE_PROJECT_MIN_DEGREE_COLUMN_H | ||
#define SPARSEBASE_PROJECT_MIN_DEGREE_COLUMN_H | ||
|
||
namespace sparsebase::feature { | ||
//! Find the min degree in the graph representation of a format object | ||
template <typename IDType, typename NNZType, typename ValueType> | ||
class MinDegreeColumn : public feature::FeaturePreprocessType<NNZType *> { | ||
public: | ||
//! An empty struct used for the parameters of Min Degree | ||
typedef utils::Parameters ParamsType; | ||
MinDegreeColumn(); | ||
MinDegreeColumn(ParamsType); | ||
MinDegreeColumn(const MinDegreeColumn<IDType, NNZType, ValueType> &d); | ||
MinDegreeColumn(std::shared_ptr<ParamsType>); | ||
std::unordered_map<std::type_index, std::any> Extract( | ||
format::Format *format, std::vector<context::Context *>, | ||
bool convert_input) override; | ||
std::vector<std::type_index> get_sub_ids() override; | ||
std::vector<utils::Extractable *> get_subs() override; | ||
static std::type_index get_id_static(); | ||
|
||
//! Min Degree executor function that carries out function matching | ||
/*! | ||
* | ||
* @param format a single format pointer to any format | ||
* @param contexts vector of contexts that can be used for extracting | ||
* features. | ||
* @param convert_input whether or not to convert the input format if that is | ||
* needed. | ||
* @return min degree in the graph representation of `format` | ||
*/ | ||
NNZType *GetMinDegreeColumn(format::Format *format, | ||
std::vector<context::Context *> contexts, | ||
bool convert_input); | ||
std:: | ||
tuple<std::vector<std::vector<format::Format *>>, NNZType *> | ||
//! Min Degree executor function that carries out function | ||
//! matching with cached output | ||
/*! | ||
* | ||
* @param format a single format pointer to any format | ||
* @param contexts vector of contexts that can be used for extracting | ||
* features. | ||
* @param convert_input whether or not to convert the input format if that | ||
* is needed. | ||
* @return min degree in the graph representation of `format` | ||
*/ | ||
GetMinDegreeColumnCached(format::Format *format, | ||
std::vector<context::Context *> contexts, | ||
bool convert_input); | ||
//! Min Degree implementation function for CSCs | ||
/*! | ||
* | ||
* @param formats A vector containing a single format pointer that should | ||
* point at a CSR object | ||
* @param params a Parameters pointer, though it | ||
* is not used in the function | ||
* @return min degree in the graph representations of 'format[0]' | ||
*/ | ||
static NNZType *GetMinDegreeColumnCSC(std::vector<format::Format *> formats, | ||
utils::Parameters *params); | ||
~MinDegreeColumn(); | ||
|
||
protected: | ||
void Register(); | ||
}; | ||
|
||
} // namespace sparsebase::feature | ||
#ifdef _HEADER_ONLY | ||
#include "sparsebase/feature/min_degree_column.cc" | ||
#endif | ||
|
||
#endif // SPARSEBASE_PROJECT_MIN_DEGREE_COLUMN_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
99 changes: 99 additions & 0 deletions
99
tests/suites/sparsebase/feature/min_degree_column_tests.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#include <memory> | ||
#include <typeindex> | ||
#include <typeinfo> | ||
#include <utility> | ||
#include <vector> | ||
|
||
#include "gtest/gtest.h" | ||
#include "sparsebase/bases/reorder_base.h" | ||
#include "sparsebase/context/context.h" | ||
#include "sparsebase/feature/min_degree_column.h" | ||
#include "sparsebase/format/coo.h" | ||
#include "sparsebase/format/csc.h" | ||
#include "sparsebase/format/csr.h" | ||
#include "sparsebase/format/format_order_one.h" | ||
#include "sparsebase/format/format_order_two.h" | ||
#include "sparsebase/reorder/degree_reorder.h" | ||
#include "sparsebase/reorder/reorderer.h" | ||
#include "sparsebase/utils/exception.h" | ||
|
||
using namespace sparsebase; | ||
using namespace sparsebase::reorder; | ||
using namespace sparsebase::bases; | ||
using namespace sparsebase::feature; | ||
#include "../functionality_common.inc" | ||
|
||
class MinDegreeColumnTest : public ::testing::Test { | ||
protected: | ||
feature::MinDegreeColumn<int, int, int> feature; | ||
|
||
struct Params1 : sparsebase::utils::Parameters {}; | ||
struct Params2 : sparsebase::utils::Parameters {}; | ||
}; | ||
|
||
TEST_F(MinDegreeColumnTest, AllTests) { | ||
// test get_sub_ids | ||
EXPECT_EQ(feature.get_sub_ids().size(), 1); | ||
EXPECT_EQ(feature.get_sub_ids()[0], std::type_index(typeid(feature))); | ||
|
||
// Test get_subs | ||
auto subs = feature.get_subs(); | ||
// a single sub-feature | ||
EXPECT_EQ(subs.size(), 1); | ||
// same type as feature but different address | ||
auto &feat = *(subs[0]); | ||
EXPECT_EQ(std::type_index(typeid(feat)), std::type_index(typeid(feature))); | ||
EXPECT_NE(subs[0], &feature); | ||
|
||
// Check GetMinDegreeColumnCSC implementation function | ||
Params1 p1; | ||
auto min_degree = | ||
feature::MinDegreeColumn<int, int, int>::GetMinDegreeColumnCSC({&global_csc}, &p1); | ||
|
||
auto min_in_degrees = (int)1e9; | ||
for (int i = 0; i < n; ++i) | ||
min_in_degrees = std::min(min_in_degrees, degrees[i]); | ||
EXPECT_EQ(*min_degree, min_in_degrees); | ||
delete min_degree; | ||
// Check GetMinDegree | ||
min_degree = feature.GetMinDegreeColumn(&global_csc, {&cpu_context}, true); | ||
EXPECT_EQ(*min_degree, min_in_degrees); | ||
delete min_degree; | ||
|
||
min_degree = feature.GetMinDegreeColumn(&global_csc, {&cpu_context}, false); | ||
EXPECT_EQ(*min_degree, min_in_degrees); | ||
delete min_degree; | ||
|
||
// Check GetMinDegree with conversion | ||
min_degree = feature.GetMinDegreeColumn(&global_coo, {&cpu_context}, true); | ||
EXPECT_EQ(*min_degree, min_in_degrees); | ||
|
||
EXPECT_THROW(feature.GetMinDegreeColumn(&global_coo, {&cpu_context}, false), | ||
utils::DirectExecutionNotAvailableException< | ||
std::vector<std::type_index>>); | ||
// Check Extract | ||
auto feature_map = feature.Extract(&global_csc, {&cpu_context}, true); | ||
// Check map size and type | ||
EXPECT_EQ(feature_map.size(), 1); | ||
for (auto feat : feature_map) { | ||
EXPECT_EQ(feat.first, std::type_index(typeid(feature))); | ||
} | ||
|
||
EXPECT_EQ(*std::any_cast<int *>(feature_map[feature.get_id()]), min_in_degrees); | ||
|
||
// Check Extract with conversion | ||
feature_map = feature.Extract(&global_coo, {&cpu_context}, true); | ||
// Check map size and type | ||
EXPECT_EQ(feature_map.size(), 1); | ||
for (auto feat : feature_map) { | ||
EXPECT_EQ(feat.first, std::type_index(typeid(feature))); | ||
} | ||
|
||
EXPECT_EQ(*std::any_cast<int *>(feature_map[feature.get_id()]), min_in_degrees); | ||
|
||
EXPECT_THROW(feature.Extract(&global_coo, {&cpu_context}, false), | ||
utils::DirectExecutionNotAvailableException< | ||
std::vector<std::type_index>>); | ||
delete min_degree; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters