Use generic dispatching routine for array interface. (#6672)

This commit is contained in:
Jiaming Yuan
2021-02-05 09:23:38 +08:00
committed by GitHub
parent a4101de678
commit 1e949110da
4 changed files with 65 additions and 31 deletions

View File

@@ -1,5 +1,5 @@
/*!
* Copyright 2020 by XGBoost Contributors
* Copyright 2020-2021 by XGBoost Contributors
*/
#include <gtest/gtest.h>
#include <xgboost/host_device_vector.h>
@@ -15,6 +15,17 @@ TEST(ArrayInterface, Initialize) {
ASSERT_EQ(arr_interface.num_rows, kRows);
ASSERT_EQ(arr_interface.num_cols, kCols);
ASSERT_EQ(arr_interface.data, storage.ConstHostPointer());
ASSERT_EQ(arr_interface.ElementSize(), 4);
ASSERT_EQ(arr_interface.type, ArrayInterface::kF4);
HostDeviceVector<size_t> u64_storage(storage.Size());
std::string u64_arr_str;
Json::Dump(GetArrayInterface(&u64_storage, kRows, kCols), &u64_arr_str);
std::copy(storage.ConstHostVector().cbegin(), storage.ConstHostVector().cend(),
u64_storage.HostSpan().begin());
auto u64_arr = ArrayInterface{u64_arr_str};
ASSERT_EQ(u64_arr.ElementSize(), 8);
ASSERT_EQ(u64_arr.type, ArrayInterface::kU8);
}
TEST(ArrayInterface, Error) {

View File

@@ -190,24 +190,7 @@ void RandomDataGenerator::GenerateDense(HostDeviceVector<float> *out) const {
Json RandomDataGenerator::ArrayInterfaceImpl(HostDeviceVector<float> *storage,
size_t rows, size_t cols) const {
this->GenerateDense(storage);
Json array_interface {Object()};
array_interface["data"] = std::vector<Json>(2);
if (storage->DeviceCanRead()) {
array_interface["data"][0] =
Integer(reinterpret_cast<int64_t>(storage->ConstDevicePointer()));
} else {
array_interface["data"][0] =
Integer(reinterpret_cast<int64_t>(storage->ConstHostPointer()));
}
array_interface["data"][1] = Boolean(false);
array_interface["shape"] = std::vector<Json>(2);
array_interface["shape"][0] = rows;
array_interface["shape"][1] = cols;
array_interface["typestr"] = String("<f4");
array_interface["version"] = 1;
return array_interface;
return GetArrayInterface(storage, rows, cols);
}
std::string RandomDataGenerator::GenerateArrayInterface(

View File

@@ -22,6 +22,7 @@
#include "../../src/common/common.h"
#include "../../src/gbm/gbtree_model.h"
#include "../../src/data/array_interface.h"
#if defined(__CUDACC__)
#define DeclareUnifiedTest(name) GPU ## name
@@ -181,6 +182,29 @@ class SimpleRealUniformDistribution {
}
};
template <typename T>
Json GetArrayInterface(HostDeviceVector<T> *storage, size_t rows, size_t cols) {
Json array_interface{Object()};
array_interface["data"] = std::vector<Json>(2);
if (storage->DeviceCanRead()) {
array_interface["data"][0] =
Integer(reinterpret_cast<int64_t>(storage->ConstDevicePointer()));
} else {
array_interface["data"][0] =
Integer(reinterpret_cast<int64_t>(storage->ConstHostPointer()));
}
array_interface["data"][1] = Boolean(false);
array_interface["shape"] = std::vector<Json>(2);
array_interface["shape"][0] = rows;
array_interface["shape"][1] = cols;
char t = ArrayInterfaceHandler::TypeChar<T>();
array_interface["typestr"] = String(std::string{"<"} + t + std::to_string(sizeof(T)));
array_interface["version"] = 1;
return array_interface;
}
// Generate in-memory random data without using DMatrix.
class RandomDataGenerator {
bst_row_t rows_;