-
Notifications
You must be signed in to change notification settings - Fork 5.9k
Add Majel's Dim to Paddle #2202
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
Changes from 3 commits
646334b
051f0b9
110a402
82c60bb
fc35881
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 |
|---|---|---|
| @@ -1,4 +1,4 @@ | ||
| cc_library(majel SRCS place.cc) | ||
| cc_library(majel SRCS place.cc ddim.cc) | ||
|
|
||
| if(WITH_TESTING) | ||
| add_subdirectory(test) | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,222 @@ | ||
| #include <majel/ddim.h> | ||
|
||
|
|
||
| namespace majel { | ||
|
|
||
| ///@cond HIDDEN | ||
|
|
||
| template <int i> | ||
| Dim<i> make_dim(const int* d) { | ||
| return Dim<i>(*d, make_dim<i - 1>(d + 1)); | ||
| } | ||
|
|
||
| template <> | ||
| Dim<1> make_dim<1>(const int* d) { | ||
| return Dim<1>(*d); | ||
| } | ||
|
|
||
| void make_ddim(DDim& ddim, const int* dims, int n) { | ||
| switch (n) { | ||
| case 1: | ||
| ddim = make_dim<1>(dims); | ||
| break; | ||
| case 2: | ||
| ddim = make_dim<2>(dims); | ||
| break; | ||
| case 3: | ||
| ddim = make_dim<3>(dims); | ||
| break; | ||
| case 4: | ||
| ddim = make_dim<4>(dims); | ||
| break; | ||
| case 5: | ||
| ddim = make_dim<5>(dims); | ||
| break; | ||
| case 6: | ||
| ddim = make_dim<6>(dims); | ||
| break; | ||
| case 7: | ||
| ddim = make_dim<7>(dims); | ||
| break; | ||
| case 8: | ||
| ddim = make_dim<8>(dims); | ||
| break; | ||
| case 9: | ||
| ddim = make_dim<9>(dims); | ||
| break; | ||
| default: | ||
| throw std::invalid_argument( | ||
| "Dynamic dimensions must have between [1, 9] dimensions."); | ||
| } | ||
| } | ||
|
|
||
| ///@endcond | ||
|
|
||
| DDim make_ddim(std::initializer_list<int> dims) { | ||
| DDim result(make_dim(0)); | ||
| make_ddim(result, dims.begin(), dims.size()); | ||
| return result; | ||
| } | ||
|
|
||
| DDim make_ddim(const std::vector<int>& dims) { | ||
| DDim result(make_dim(0)); | ||
| make_ddim(result, &dims[0], dims.size()); | ||
| return result; | ||
| } | ||
|
|
||
| ///@cond HIDDEN | ||
| // XXX For some reason, putting this in an anonymous namespace causes errors | ||
| class DynamicMutableIndexer : public boost::static_visitor<int&> { | ||
| public: | ||
| DynamicMutableIndexer(int idx) : idx_(idx) {} | ||
|
|
||
| template <int D> | ||
| int& operator()(Dim<D>& dim) const { | ||
| return dim[idx_]; | ||
| } | ||
|
|
||
| private: | ||
| int idx_; | ||
| }; | ||
|
|
||
| class DynamicConstIndexer : public boost::static_visitor<int> { | ||
| public: | ||
| DynamicConstIndexer(int idx) : idx_(idx) {} | ||
|
|
||
| template <int D> | ||
| int operator()(const Dim<D>& dim) const { | ||
| return dim[idx_]; | ||
| } | ||
|
|
||
| private: | ||
| int idx_; | ||
| }; | ||
|
|
||
| ///@endcond | ||
|
|
||
| int& DDim::operator[](int idx) { | ||
| return boost::apply_visitor(DynamicMutableIndexer(idx), var); | ||
| } | ||
|
|
||
| int DDim::operator[](int idx) const { | ||
| return boost::apply_visitor(DynamicConstIndexer(idx), var); | ||
| } | ||
|
|
||
| bool DDim::operator==(DDim d) const { | ||
| if (var.which() != d.getVar().which()) { | ||
| return false; | ||
| } else { | ||
| std::vector<int> v1 = vectorize(*this); | ||
| std::vector<int> v2 = vectorize(d); | ||
|
|
||
| for (unsigned int i = 0; i < v1.size(); i++) { | ||
| if (v1[i] != v2[i]) { | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| return true; | ||
| } | ||
| } | ||
|
|
||
| bool DDim::operator!=(DDim d) const { return !(*this == d); } | ||
|
|
||
| DDim DDim::operator+(DDim d) const { | ||
| std::vector<int> v1 = vectorize(*this); | ||
| std::vector<int> v2 = vectorize(d); | ||
|
|
||
| std::vector<int> v3; | ||
|
|
||
| assert(v1.size() == v2.size()); | ||
|
Contributor
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. Why not use the
Collaborator
Author
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. According to |
||
|
|
||
| for (unsigned int i = 0; i < v1.size(); i++) { | ||
| v3.push_back(v1[i] + v2[i]); | ||
| } | ||
|
|
||
| return make_ddim(v3); | ||
| } | ||
|
|
||
| DDim DDim::operator*(DDim d) const { | ||
| std::vector<int> v1 = vectorize(*this); | ||
| std::vector<int> v2 = vectorize(d); | ||
|
|
||
| std::vector<int> v3; | ||
|
|
||
| assert(v1.size() == v2.size()); | ||
|
|
||
| for (unsigned int i = 0; i < v1.size(); i++) { | ||
| v3.push_back(v1[i] * v2[i]); | ||
| } | ||
|
|
||
| return make_ddim(v3); | ||
| } | ||
|
|
||
| int get(const DDim& ddim, int idx) { return ddim[idx]; } | ||
|
|
||
| void set(DDim& ddim, int idx, int value) { ddim[idx] = value; } | ||
|
|
||
| ///@cond HIDDEN | ||
| struct VectorizeVisitor : public boost::static_visitor<> { | ||
| std::vector<int>& vector; | ||
|
|
||
| VectorizeVisitor(std::vector<int>& v) : vector(v) {} | ||
|
|
||
| template <typename T> | ||
| void operator()(const T& t) { | ||
| vector.push_back(t.head); | ||
| this->operator()(t.tail); | ||
| } | ||
|
|
||
| void operator()(const Dim<1>& t) { vector.push_back(t.head); } | ||
| }; | ||
| ///@endcond | ||
|
|
||
| std::vector<int> vectorize(const DDim& ddim) { | ||
| std::vector<int> result; | ||
| VectorizeVisitor visitor(result); | ||
| boost::apply_visitor(visitor, ddim); | ||
| return result; | ||
| } | ||
|
|
||
| ssize_t product(const DDim& ddim) { | ||
| ssize_t result = 1; | ||
| std::vector<int> v = vectorize(ddim); | ||
| for (auto i : v) { | ||
| result *= i; | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
| ///\cond HIDDEN | ||
|
|
||
| struct ArityVisitor : boost::static_visitor<int> { | ||
| template <int D> | ||
| int operator()(Dim<D>) const { | ||
| return D; | ||
| } | ||
| }; | ||
|
|
||
| ///\endcond | ||
|
|
||
| int arity(const DDim& d) { return boost::apply_visitor(ArityVisitor(), d); } | ||
|
|
||
| ///\cond HIDDEN | ||
|
|
||
| struct DDimPrinter : boost::static_visitor<void> { | ||
| std::ostream& os; | ||
| DDimPrinter(std::ostream& os_) : os(os_) {} | ||
|
|
||
| template <typename T> | ||
| void operator()(const T& t) { | ||
| os << t; | ||
| } | ||
| }; | ||
|
|
||
| ///\endcond | ||
|
|
||
| std::ostream& operator<<(std::ostream& os, const majel::DDim& ddim) { | ||
| DDimPrinter printer(os); | ||
| boost::apply_visitor(printer, ddim); | ||
| return os; | ||
| } | ||
|
|
||
| } // namespace majel | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| #pragma once | ||
|
|
||
| #include <boost/variant.hpp> | ||
| #include <initializer_list> | ||
| #include <stdexcept> | ||
| #include <vector> | ||
|
|
||
| #include "majel/dim.h" | ||
|
|
||
| namespace majel { | ||
|
|
||
| namespace { | ||
| typedef boost::variant<Dim<1>, | ||
| Dim<2>, | ||
| Dim<3>, | ||
| Dim<4>, | ||
| Dim<5>, | ||
| Dim<6>, | ||
| Dim<7>, | ||
| Dim<8>, | ||
| Dim<9>> | ||
| DDimVar; | ||
| } | ||
|
|
||
| /** | ||
| * \brief A dynamically sized dimension. | ||
| * | ||
| * The number of dimensions must be between [1, 9]. | ||
| */ | ||
| struct DDim { | ||
| DDimVar var; | ||
|
|
||
| DDim() : var(Dim<1>()) {} | ||
|
|
||
| template <int D> | ||
| DDim(const Dim<D>& in) : var(in) {} | ||
|
|
||
| template <int D> | ||
| DDim& operator=(const Dim<D>& in) { | ||
| var = in; | ||
| return *this; | ||
| } | ||
|
|
||
| int& operator[](int idx); | ||
| int operator[](int idx) const; | ||
|
|
||
| template <typename Visitor> | ||
| typename Visitor::result_type apply_visitor(Visitor& visitor) { | ||
| return var.apply_visitor(visitor); | ||
| } | ||
|
|
||
| template <typename Visitor> | ||
| typename Visitor::result_type apply_visitor(Visitor& visitor) const { | ||
| return var.apply_visitor(visitor); | ||
| } | ||
|
|
||
| DDimVar getVar() { return var; } | ||
|
|
||
| bool operator==(DDim d) const; | ||
|
|
||
| bool operator!=(DDim d) const; | ||
|
|
||
| DDim operator+(DDim d) const; | ||
|
|
||
| DDim operator*(DDim d) const; | ||
| }; | ||
|
|
||
| /** | ||
| * \brief Make a DDim from std::vector<int> | ||
| * | ||
| * \param dims An vector of ints. Must be sized between [1, 9] | ||
| */ | ||
| DDim make_ddim(const std::vector<int>& dims); | ||
|
|
||
| /** | ||
| * \brief Make a DDim from an initializer list | ||
| * | ||
| * \param dims An initializer list of ints. Must be sized between [1, 9] | ||
| * | ||
| */ | ||
| DDim make_ddim(std::initializer_list<int> dims); | ||
|
|
||
| int get(const DDim& dim, int idx); | ||
| void set(DDim& dim, int idx, int val); | ||
|
|
||
| std::vector<int> vectorize(const DDim& ddim); | ||
|
|
||
| ssize_t product(const DDim& ddim); | ||
|
|
||
| /** | ||
| * \brief What is the length of this dimension? | ||
| * | ||
| * \param Dynamic dimension to inspect | ||
| */ | ||
|
|
||
| int arity(const DDim& ddim); | ||
|
|
||
| std::ostream& operator<<(std::ostream&, const majel::DDim&); | ||
|
|
||
| } // namespace majel | ||
|
|
||
| namespace boost { | ||
|
|
||
| template <typename T> | ||
| T get(const majel::DDim& in) { | ||
| return boost::get<T>(in.var); | ||
| } | ||
|
|
||
| } // namespace boost |
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.
According to our design, I believe that this line should be
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.
Maybe we need to add an optional
OBJECT, because CMakeadd_library(name OBJECT source)can generate*.oUh oh!
There was an error while loading. Please reload this page.
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.
done.
But
Dimis only a part ofDDim, it is not an independent module and only has adim.hfile. So maybe these lines should beThere 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.
Got it. Thanks!