xgboost/tests/cpp/common/test_span.h
2024-01-24 11:30:01 -08:00

346 lines
8.3 KiB
C++

/*!
* Copyright 2018 XGBoost contributors
*/
#ifndef XGBOOST_TEST_SPAN_H_
#define XGBOOST_TEST_SPAN_H_
#include <xgboost/base.h>
#include <xgboost/span.h>
template <typename Iter>
XGBOOST_DEVICE void InitializeRange(Iter _begin, Iter _end) {
float j = 0;
for (Iter i = _begin; i != _end; ++i, ++j) {
*i = j;
}
}
namespace xgboost {
namespace common {
#define SPAN_ASSERT_TRUE(cond, status) \
if (!(cond)) { \
*(status) = -1; \
}
#define SPAN_ASSERT_FALSE(cond, status) \
if ((cond)) { \
*(status) = -1; \
}
struct TestTestStatus {
int * status_;
TestTestStatus(int* _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
SPAN_ASSERT_TRUE(false, status_);
}
};
struct TestAssignment {
int* status_;
TestAssignment(int* _status) : status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
Span<float> s1;
float arr[] = {3, 4, 5};
Span<const float> s2 = arr;
SPAN_ASSERT_TRUE(s2.size() == 3, status_);
SPAN_ASSERT_TRUE(s2.data() == &arr[0], status_);
s2 = s1;
SPAN_ASSERT_TRUE(s2.empty(), status_);
}
};
struct TestBeginEnd {
int* status_;
TestBeginEnd(int* _status) : status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float arr[16];
InitializeRange(arr, arr + 16);
Span<float> s (arr);
Span<float>::iterator beg { s.begin() };
Span<float>::iterator end { s.end() };
SPAN_ASSERT_TRUE(end == beg + 16, status_);
SPAN_ASSERT_TRUE(*beg == arr[0], status_);
SPAN_ASSERT_TRUE(*(end - 1) == arr[15], status_);
}
};
struct TestRBeginREnd {
int * status_;
TestRBeginREnd(int* _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float arr[16];
InitializeRange(arr, arr + 16);
Span<float> s (arr);
#if defined(__CUDA_ARCH__) || defined(__HIPCC__)
auto rbeg = dh::trbegin(s);
auto rend = dh::trend(s);
#else
Span<float>::reverse_iterator rbeg{s.rbegin()};
Span<float>::reverse_iterator rend{s.rend()};
#endif
SPAN_ASSERT_TRUE(rbeg + 16 == rend, status_);
SPAN_ASSERT_TRUE(*(rbeg) == arr[15], status_);
SPAN_ASSERT_TRUE(*(rend - 1) == arr[0], status_);
}
};
struct TestObservers {
int * status_;
TestObservers(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
// empty
{
float *arr = nullptr;
Span<float> s(arr, static_cast<Span<float>::index_type>(0));
SPAN_ASSERT_TRUE(s.empty(), status_);
}
// size, size_types
{
float* arr = new float[16];
Span<float> s (arr, 16);
SPAN_ASSERT_TRUE(s.size() == 16, status_);
SPAN_ASSERT_TRUE(s.size_bytes() == 16 * sizeof(float), status_);
delete [] arr;
}
}
};
struct TestCompare {
int * status_;
TestCompare(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float lhs_arr[16], rhs_arr[16];
InitializeRange(lhs_arr, lhs_arr + 16);
InitializeRange(rhs_arr, rhs_arr + 16);
Span<float> lhs(lhs_arr);
Span<float> rhs(rhs_arr);
SPAN_ASSERT_TRUE(lhs == rhs, status_);
SPAN_ASSERT_FALSE(lhs != rhs, status_);
SPAN_ASSERT_TRUE(lhs <= rhs, status_);
SPAN_ASSERT_TRUE(lhs >= rhs, status_);
lhs[2] -= 1;
SPAN_ASSERT_FALSE(lhs == rhs, status_);
SPAN_ASSERT_TRUE(lhs < rhs, status_);
SPAN_ASSERT_FALSE(lhs > rhs, status_);
}
};
struct TestIterConstruct {
int * status_;
TestIterConstruct(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index.
Span<float>::iterator it1;
Span<float>::iterator it2;
SPAN_ASSERT_TRUE(it1 == it2, status_);
Span<float>::const_iterator cit1;
Span<float>::const_iterator cit2;
SPAN_ASSERT_TRUE(cit1 == cit2, status_);
}
};
struct TestIterRef {
int * status_;
TestIterRef(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float arr[16];
InitializeRange(arr, arr + 16);
Span<float> s (arr);
SPAN_ASSERT_TRUE(*(s.begin()) == s[0], status_);
SPAN_ASSERT_TRUE(*(s.end() - 1) == s[15], status_);
}
};
struct TestIterCalculate {
int * status_;
TestIterCalculate(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float arr[16];
InitializeRange(arr, arr + 16);
Span<float> s (arr);
Span<float>::iterator beg { s.begin() };
beg += 4;
SPAN_ASSERT_TRUE(*beg == 4, status_);
beg -= 2;
SPAN_ASSERT_TRUE(*beg == 2, status_);
++beg;
SPAN_ASSERT_TRUE(*beg == 3, status_);
--beg;
SPAN_ASSERT_TRUE(*beg == 2, status_);
beg++;
beg--;
SPAN_ASSERT_TRUE(*beg == 2, status_);
}
};
struct TestIterCompare {
int * status_;
TestIterCompare(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float arr[16];
InitializeRange(arr, arr + 16);
Span<float> s (arr);
Span<float>::iterator left { s.begin() };
Span<float>::iterator right { s.end() };
left += 1;
right -= 15;
SPAN_ASSERT_TRUE(left == right, status_);
SPAN_ASSERT_TRUE(left >= right, status_);
SPAN_ASSERT_TRUE(left <= right, status_);
++right;
SPAN_ASSERT_TRUE(right > left, status_);
SPAN_ASSERT_TRUE(left < right, status_);
SPAN_ASSERT_TRUE(left <= right, status_);
}
};
struct TestAsBytes {
int * status_;
TestAsBytes(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float arr[16];
InitializeRange(arr, arr + 16);
{
const Span<const float> s {arr};
const Span<const byte> bs = as_bytes(s);
SPAN_ASSERT_TRUE(bs.size() == s.size_bytes(), status_);
SPAN_ASSERT_TRUE(static_cast<const void*>(bs.data()) ==
static_cast<const void*>(s.data()),
status_);
}
{
Span<float> s;
const Span<const byte> bs = as_bytes(s);
SPAN_ASSERT_TRUE(bs.size() == s.size(), status_);
SPAN_ASSERT_TRUE(bs.size() == 0, status_);
SPAN_ASSERT_TRUE(bs.size_bytes() == 0, status_);
SPAN_ASSERT_TRUE(static_cast<const void*>(bs.data()) ==
static_cast<const void*>(s.data()),
status_);
SPAN_ASSERT_TRUE(bs.data() == nullptr, status_);
}
}
};
struct TestAsWritableBytes {
int * status_;
TestAsWritableBytes(int * _status): status_(_status) {}
XGBOOST_DEVICE void operator()() {
this->operator()(0);
}
XGBOOST_DEVICE void operator()(size_t) { // size_t for CUDA index
float arr[16];
InitializeRange(arr, arr + 16);
{
Span<float> s;
Span<byte> bs = as_writable_bytes(s);
SPAN_ASSERT_TRUE(bs.size() == s.size(), status_);
SPAN_ASSERT_TRUE(bs.size_bytes() == s.size_bytes(), status_);
SPAN_ASSERT_TRUE(bs.size() == 0, status_);
SPAN_ASSERT_TRUE(bs.size_bytes() == 0, status_);
SPAN_ASSERT_TRUE(bs.data() == nullptr, status_);
SPAN_ASSERT_TRUE(static_cast<void*>(bs.data()) ==
static_cast<void*>(s.data()), status_);
}
{
Span<float> s { arr };
Span<byte> bs { as_writable_bytes(s) };
SPAN_ASSERT_TRUE(s.size_bytes() == bs.size_bytes(), status_);
SPAN_ASSERT_TRUE(static_cast<void*>(bs.data()) ==
static_cast<void*>(s.data()), status_);
}
}
};
} // namespace common
} // namespace xgboost
#endif