commit
48de5ffca7
@ -0,0 +1,222 @@
|
|||||||
|
#include "paddle/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());
|
||||||
|
|
||||||
|
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
|
@ -0,0 +1,109 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <boost/variant.hpp>
|
||||||
|
#include <initializer_list>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "paddle/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
|
@ -0,0 +1,32 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#define STRINGIFY(x) #x
|
||||||
|
#define TOSTRING(x) STRINGIFY(x)
|
||||||
|
|
||||||
|
#if defined(__APPLE__) && defined(__CUDA_ARCH__) && !defined(NDEBUG)
|
||||||
|
#include <stdio.h>
|
||||||
|
#define MAJEL_ASSERT(e) \
|
||||||
|
do { \
|
||||||
|
if (!(e)) { \
|
||||||
|
printf( \
|
||||||
|
"%s:%d Assertion `%s` failed.\n", __FILE__, __LINE__, TOSTRING(e)); \
|
||||||
|
asm("trap;"); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define MAJEL_ASSERT_MSG(e, m) \
|
||||||
|
do { \
|
||||||
|
if (!(e)) { \
|
||||||
|
printf("%s:%d Assertion `%s` failed (%s).\n", \
|
||||||
|
__FILE__, \
|
||||||
|
__LINE__, \
|
||||||
|
TOSTRING(e), \
|
||||||
|
m); \
|
||||||
|
asm("trap;"); \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
#else
|
||||||
|
#include <assert.h>
|
||||||
|
#define MAJEL_ASSERT(e) assert(e)
|
||||||
|
#define MAJEL_ASSERT_MSG(e, m) assert((e) && (m))
|
||||||
|
#endif
|
@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifdef __CUDACC__
|
||||||
|
#define HOSTDEVICE __host__ __device__
|
||||||
|
#define HOST __host__
|
||||||
|
#else
|
||||||
|
#define HOSTDEVICE
|
||||||
|
#define HOST
|
||||||
|
#endif
|
File diff suppressed because it is too large
Load Diff
@ -1,7 +1,12 @@
|
|||||||
cc_test(place_test
|
cc_test(place_test
|
||||||
SRCS place_test.cc
|
SRCS place_test.cc
|
||||||
DEPS majel)
|
DEPS place)
|
||||||
|
|
||||||
|
cc_test(ddim_test
|
||||||
|
SRCS ddim_test.cc
|
||||||
|
DEPS ddim)
|
||||||
|
|
||||||
if(WITH_GPU)
|
if(WITH_GPU)
|
||||||
nv_test(cuda_test SRCS cuda_test.cu)
|
nv_test(cuda_test SRCS cuda_test.cu)
|
||||||
|
nv_test(dim_test SRCS dim_test.cu DEPS ddim)
|
||||||
endif()
|
endif()
|
||||||
|
@ -0,0 +1,65 @@
|
|||||||
|
//#include <stdexcept>
|
||||||
|
//#include <unittest/unittest.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include "paddle/majel/ddim.h"
|
||||||
|
|
||||||
|
TEST(DDim, Equality) {
|
||||||
|
// construct a DDim from an initialization list
|
||||||
|
majel::DDim ddim = majel::make_ddim({9, 1, 5});
|
||||||
|
EXPECT_EQ(ddim[0], 9);
|
||||||
|
EXPECT_EQ(ddim[1], 1);
|
||||||
|
EXPECT_EQ(ddim[2], 5);
|
||||||
|
|
||||||
|
// construct a DDim from a vector
|
||||||
|
std::vector<int> vec({9, 1, 5});
|
||||||
|
majel::DDim vddim = majel::make_ddim(vec);
|
||||||
|
EXPECT_EQ(ddim[0], 9);
|
||||||
|
EXPECT_EQ(ddim[1], 1);
|
||||||
|
EXPECT_EQ(ddim[2], 5);
|
||||||
|
|
||||||
|
// mutate a DDim
|
||||||
|
ddim[1] = 2;
|
||||||
|
EXPECT_EQ(ddim[1], 2);
|
||||||
|
majel::set(ddim, 0, 6);
|
||||||
|
EXPECT_EQ(majel::get(ddim, 0), 6);
|
||||||
|
|
||||||
|
// vectorize a DDim
|
||||||
|
std::vector<int> res_vec = majel::vectorize(vddim);
|
||||||
|
EXPECT_EQ(res_vec[0], 9);
|
||||||
|
EXPECT_EQ(res_vec[1], 1);
|
||||||
|
EXPECT_EQ(res_vec[2], 5);
|
||||||
|
majel::Dim<3> d(3, 2, 1);
|
||||||
|
res_vec = majel::vectorize(majel::DDim(d));
|
||||||
|
EXPECT_EQ(res_vec[0], 3);
|
||||||
|
EXPECT_EQ(res_vec[1], 2);
|
||||||
|
EXPECT_EQ(res_vec[2], 1);
|
||||||
|
|
||||||
|
// add two DDims
|
||||||
|
majel::DDim ddim_sum = ddim + vddim;
|
||||||
|
EXPECT_EQ(ddim_sum[0], 15);
|
||||||
|
EXPECT_EQ(ddim_sum[1], 3);
|
||||||
|
EXPECT_EQ(ddim_sum[2], 10);
|
||||||
|
|
||||||
|
// multiply two DDims
|
||||||
|
majel::DDim ddim_mul = ddim * vddim;
|
||||||
|
EXPECT_EQ(ddim_mul[0], 54);
|
||||||
|
EXPECT_EQ(ddim_mul[1], 2);
|
||||||
|
EXPECT_EQ(ddim_mul[2], 25);
|
||||||
|
|
||||||
|
// arity of a DDim
|
||||||
|
EXPECT_EQ(majel::arity(ddim), 3);
|
||||||
|
|
||||||
|
// product of a DDim
|
||||||
|
EXPECT_EQ(majel::product(vddim), 45);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(DDim, Print) {
|
||||||
|
// print a DDim
|
||||||
|
std::stringstream ss;
|
||||||
|
majel::DDim ddim = majel::make_ddim({2, 3, 4});
|
||||||
|
ss << ddim;
|
||||||
|
EXPECT_EQ("2, 3, 4", ss.str());
|
||||||
|
}
|
@ -0,0 +1,128 @@
|
|||||||
|
#include <thrust/device_vector.h>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
#include "paddle/majel/dim.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
__global__ void test(majel::Dim<2>* o) {
|
||||||
|
o[0] = majel::make_dim(5, 6);
|
||||||
|
}
|
||||||
|
|
||||||
|
__global__ void dyn_idx_gpu(int* o) {
|
||||||
|
auto d = majel::make_dim(5, 6);
|
||||||
|
o[0] = d[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Dim, Equality) {
|
||||||
|
// construct a Dim on the CPU
|
||||||
|
auto a = majel::make_dim(3, 4);
|
||||||
|
EXPECT_EQ(majel::get<0>(a), 3);
|
||||||
|
EXPECT_EQ(majel::get<1>(a), 4);
|
||||||
|
|
||||||
|
// construct a Dim on the GPU
|
||||||
|
thrust::device_vector<majel::Dim<2>> t(2);
|
||||||
|
test<<<1,1>>>(thrust::raw_pointer_cast(t.data()));
|
||||||
|
a = t[0];
|
||||||
|
EXPECT_EQ(majel::get<0>(a), 5);
|
||||||
|
EXPECT_EQ(majel::get<1>(a), 6);
|
||||||
|
|
||||||
|
// linearization
|
||||||
|
auto b = majel::make_dim(7, 8);
|
||||||
|
EXPECT_EQ(majel::linearize(a, b), 83);
|
||||||
|
|
||||||
|
// product
|
||||||
|
EXPECT_EQ(majel::product(a), 30);
|
||||||
|
|
||||||
|
// mutate a Dim
|
||||||
|
majel::get<1>(b) = 10;
|
||||||
|
EXPECT_EQ(majel::get<0>(b), 7);
|
||||||
|
EXPECT_EQ(majel::get<1>(b), 10);
|
||||||
|
|
||||||
|
// dynamic access
|
||||||
|
majel::get(b, 0) = 8;
|
||||||
|
b[1] = 11;
|
||||||
|
EXPECT_EQ(majel::get<0>(b), 8);
|
||||||
|
EXPECT_EQ(majel::get<1>(b), 11);
|
||||||
|
EXPECT_EQ(majel::get(b, 0), 8);
|
||||||
|
EXPECT_EQ(b[1], 11);
|
||||||
|
|
||||||
|
// dynamic access on GPU
|
||||||
|
thrust::device_vector<int> r(1);
|
||||||
|
dyn_idx_gpu<<<1,1>>>(thrust::raw_pointer_cast(r.data()));
|
||||||
|
int res = r[0];
|
||||||
|
EXPECT_EQ(res, 6);
|
||||||
|
|
||||||
|
// ex_prefix_mul
|
||||||
|
majel::Dim<3> c = majel::ex_prefix_mul(majel::Dim<3>(3, 4, 5));
|
||||||
|
EXPECT_EQ(majel::get<0>(c), 1);
|
||||||
|
EXPECT_EQ(majel::get<1>(c), 3);
|
||||||
|
EXPECT_EQ(majel::get<2>(c), 12);
|
||||||
|
|
||||||
|
// contiguous_strides
|
||||||
|
c = majel::contiguous_strides(majel::Dim<3>(10, 1, 10));
|
||||||
|
EXPECT_EQ(majel::get<0>(c), 1);
|
||||||
|
EXPECT_EQ(majel::get<1>(c), 0);
|
||||||
|
EXPECT_EQ(majel::get<2>(c), 10);
|
||||||
|
c = majel::contiguous_strides(majel::Dim<3>(10, 10, 1));
|
||||||
|
EXPECT_EQ(majel::get<0>(c), 1);
|
||||||
|
EXPECT_EQ(majel::get<1>(c), 10);
|
||||||
|
EXPECT_EQ(majel::get<2>(c), 0);
|
||||||
|
c = majel::contiguous_strides(majel::Dim<3>(1, 10, 10));
|
||||||
|
EXPECT_EQ(majel::get<0>(c), 0);
|
||||||
|
EXPECT_EQ(majel::get<1>(c), 1);
|
||||||
|
EXPECT_EQ(majel::get<2>(c), 10);
|
||||||
|
c = majel::contiguous_strides(majel::Dim<3>(2, 3, 4));
|
||||||
|
EXPECT_EQ(majel::get<0>(c), 1);
|
||||||
|
EXPECT_EQ(majel::get<1>(c), 2);
|
||||||
|
EXPECT_EQ(majel::get<2>(c), 6);
|
||||||
|
|
||||||
|
// generate from an index
|
||||||
|
auto size = majel::make_dim(4, 5, 2);
|
||||||
|
c = majel::Dim<3>(14, size);
|
||||||
|
EXPECT_EQ(majel::get<0>(c), 2);
|
||||||
|
EXPECT_EQ(majel::get<1>(c), 3);
|
||||||
|
EXPECT_EQ(majel::get<2>(c), 0);
|
||||||
|
c = majel::Dim<3>(25, size);
|
||||||
|
EXPECT_EQ(majel::get<0>(c), 1);
|
||||||
|
EXPECT_EQ(majel::get<1>(c), 1);
|
||||||
|
EXPECT_EQ(majel::get<2>(c), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Dim, Bool) {
|
||||||
|
auto a = majel::make_dim(3, 4);
|
||||||
|
auto b = majel::make_dim(5, 6);
|
||||||
|
auto c = majel::make_dim(3, 4);
|
||||||
|
|
||||||
|
// in_bounds check
|
||||||
|
EXPECT_TRUE(majel::contained(a, b));
|
||||||
|
EXPECT_FALSE(majel::contained(b, a));
|
||||||
|
|
||||||
|
// comparison
|
||||||
|
EXPECT_TRUE(a == a);
|
||||||
|
EXPECT_FALSE(a == b);
|
||||||
|
EXPECT_TRUE(a == c);
|
||||||
|
|
||||||
|
// contiguous check
|
||||||
|
int x = 4, y = 5, z = 2;
|
||||||
|
majel::Dim<3> sizef(x, y, z);
|
||||||
|
majel::Dim<3> stridea(1, x, x*y);
|
||||||
|
majel::Dim<3> strideb(2, 2*x, 2*x*y);
|
||||||
|
majel::Dim<3> stridec(1, x, 2*x*y);
|
||||||
|
EXPECT_TRUE(majel::contiguous(sizef, stridea));
|
||||||
|
EXPECT_FALSE(majel::contiguous(sizef, strideb));
|
||||||
|
EXPECT_FALSE(majel::contiguous(sizef, stridec));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(Dim, Print) {
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
auto a = majel::make_dim(2, 3);
|
||||||
|
ss << a;
|
||||||
|
EXPECT_EQ(ss.str(), "2, 3");
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << majel::make_dim(8);
|
||||||
|
EXPECT_EQ(ss.str(), "8");
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue