Use ptr from mmap for GHistIndexMatrix and ColumnMatrix. (#9315)
* Use ptr from mmap for `GHistIndexMatrix` and `ColumnMatrix`. - Define a resource for holding various types of memory pointers. - Define ref vector for holding resources. - Swap the underlying resources for GHist and ColumnM. - Add documentation for current status. - s390x support is removed. It should work if you can compile XGBoost, all the old workaround code does is to get GCC to compile.
This commit is contained in:
@@ -3,11 +3,12 @@
|
||||
*/
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <fstream>
|
||||
#include <cstddef> // for size_t
|
||||
#include <fstream> // for ofstream
|
||||
|
||||
#include "../../../src/common/io.h"
|
||||
#include "../helpers.h"
|
||||
#include "../filesystem.h" // dmlc::TemporaryDirectory
|
||||
#include "../helpers.h"
|
||||
|
||||
namespace xgboost::common {
|
||||
TEST(MemoryFixSizeBuffer, Seek) {
|
||||
@@ -89,6 +90,57 @@ TEST(IO, LoadSequentialFile) {
|
||||
ASSERT_THROW(LoadSequentialFile("non-exist", true), dmlc::Error);
|
||||
}
|
||||
|
||||
TEST(IO, Resource) {
|
||||
{
|
||||
// test malloc basic
|
||||
std::size_t n = 128;
|
||||
std::shared_ptr<ResourceHandler> resource = std::make_shared<MallocResource>(n);
|
||||
ASSERT_EQ(resource->Size(), n);
|
||||
ASSERT_EQ(resource->Type(), ResourceHandler::kMalloc);
|
||||
}
|
||||
|
||||
// test malloc resize
|
||||
auto test_malloc_resize = [](bool force_malloc) {
|
||||
std::size_t n = 64;
|
||||
std::shared_ptr<ResourceHandler> resource = std::make_shared<MallocResource>(n);
|
||||
auto ptr = reinterpret_cast<std::uint8_t *>(resource->Data());
|
||||
std::iota(ptr, ptr + n, 0);
|
||||
|
||||
auto malloc_resource = std::dynamic_pointer_cast<MallocResource>(resource);
|
||||
ASSERT_TRUE(malloc_resource);
|
||||
if (force_malloc) {
|
||||
malloc_resource->Resize<true>(n * 2);
|
||||
} else {
|
||||
malloc_resource->Resize<false>(n * 2);
|
||||
}
|
||||
for (std::size_t i = 0; i < n; ++i) {
|
||||
ASSERT_EQ(malloc_resource->DataAs<std::uint8_t>()[i], i) << force_malloc;
|
||||
}
|
||||
for (std::size_t i = n; i < 2 * n; ++i) {
|
||||
ASSERT_EQ(malloc_resource->DataAs<std::uint8_t>()[i], 0);
|
||||
}
|
||||
};
|
||||
test_malloc_resize(true);
|
||||
test_malloc_resize(false);
|
||||
|
||||
{
|
||||
// test mmap
|
||||
dmlc::TemporaryDirectory tmpdir;
|
||||
auto path = tmpdir.path + "/testfile";
|
||||
|
||||
std::ofstream fout(path, std::ios::binary);
|
||||
double val{1.0};
|
||||
fout.write(reinterpret_cast<char const *>(&val), sizeof(val));
|
||||
fout << 1.0 << std::endl;
|
||||
fout.close();
|
||||
|
||||
auto resource = std::make_shared<MmapResource>(path, 0, sizeof(double));
|
||||
ASSERT_EQ(resource->Size(), sizeof(double));
|
||||
ASSERT_EQ(resource->Type(), ResourceHandler::kMmap);
|
||||
ASSERT_EQ(resource->DataAs<double>()[0], val);
|
||||
}
|
||||
}
|
||||
|
||||
TEST(IO, PrivateMmapStream) {
|
||||
dmlc::TemporaryDirectory tempdir;
|
||||
auto path = tempdir.path + "/testfile";
|
||||
@@ -124,17 +176,35 @@ TEST(IO, PrivateMmapStream) {
|
||||
// Turn size info offset
|
||||
std::partial_sum(offset.begin(), offset.end(), offset.begin());
|
||||
|
||||
// Test read
|
||||
for (std::size_t i = 0; i < n_batches; ++i) {
|
||||
std::size_t off = offset[i];
|
||||
std::size_t n = offset.at(i + 1) - offset[i];
|
||||
std::unique_ptr<dmlc::Stream> fi{std::make_unique<PrivateMmapConstStream>(path, off, n)};
|
||||
auto fi{std::make_unique<PrivateMmapConstStream>(path, off, n)};
|
||||
std::vector<T> data;
|
||||
|
||||
std::uint64_t size{0};
|
||||
fi->Read(&size);
|
||||
ASSERT_TRUE(fi->Read(&size));
|
||||
ASSERT_EQ(fi->Tell(), sizeof(size));
|
||||
data.resize(size);
|
||||
|
||||
fi->Read(data.data(), size * sizeof(T));
|
||||
ASSERT_EQ(fi->Read(data.data(), size * sizeof(T)), size * sizeof(T));
|
||||
ASSERT_EQ(data, batches[i]);
|
||||
}
|
||||
|
||||
// Test consume
|
||||
for (std::size_t i = 0; i < n_batches; ++i) {
|
||||
std::size_t off = offset[i];
|
||||
std::size_t n = offset.at(i + 1) - offset[i];
|
||||
std::unique_ptr<AlignedResourceReadStream> fi{std::make_unique<PrivateMmapConstStream>(path, off, n)};
|
||||
std::vector<T> data;
|
||||
|
||||
std::uint64_t size{0};
|
||||
ASSERT_TRUE(fi->Consume(&size));
|
||||
ASSERT_EQ(fi->Tell(), sizeof(size));
|
||||
data.resize(size);
|
||||
|
||||
ASSERT_EQ(fi->Read(data.data(), size * sizeof(T)), sizeof(T) * size);
|
||||
ASSERT_EQ(data, batches[i]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user