Skip to content

Commit

Permalink
Fix: Check if no allocation is necessary in jagged vec buffer (#233)
Browse files Browse the repository at this point in the history
* Add tests for jagged vectors with 0 internal/external size(s).

* Skip unnecessary operations in jagged vec buffer with 0 size(s)

* Complicate core jagged container test
  • Loading branch information
guilhermeAlmeida1 authored Jun 21, 2023
1 parent 5c4bb55 commit bbb712a
Show file tree
Hide file tree
Showing 6 changed files with 593 additions and 4 deletions.
4 changes: 2 additions & 2 deletions core/include/vecmem/containers/impl/jagged_vector_buffer.ipp
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ jagged_vector_buffer<TYPE>::jagged_vector_buffer(
TYPE* data_ptr = nullptr;

// Allocate the "inner memory" for a fixed size buffer.
if (type == buffer_type::fixed_size) {
if (type == buffer_type::fixed_size && total_elements != 0) {
m_inner_memory = vecmem::make_unique_alloc<char[]>(
resource, total_elements * sizeof(TYPE));
data_ptr = reinterpret_cast<TYPE*>(m_inner_memory.get());
}
// Allocate the "inner memory" for a resizable buffer.
else if (type == buffer_type::resizable) {
else if (type == buffer_type::resizable && capacities.size() != 0) {
std::tie(m_inner_memory, header_ptr, data_ptr) =
details::aligned_multiple_placement<header_t, TYPE>(
resource, capacities.size(), total_elements);
Expand Down
8 changes: 6 additions & 2 deletions tests/core/test_core_device_containers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,16 @@ TEST_F(core_device_container_test, vector_buffer) {
TEST_F(core_device_container_test, jagged_vector_buffer) {

// Create a dummy jagged vector in regular host memory.
std::vector<std::vector<int> > host_vector{{1, 2, 3, 4, 5},
std::vector<std::vector<int> > host_vector{{},
{1, 2, 3, 4, 5},
{6, 7},
{8, 9, 10, 11},
{12, 13, 14, 15, 16, 17, 18},
{},
{19, 20}};
{},
{19, 20},
{},
{21}};
auto host_data = vecmem::get_data(host_vector, &m_resource);

// Set up an "alternative" memory resource for the test.
Expand Down
88 changes: 88 additions & 0 deletions tests/core/test_core_jagged_vector_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,3 +170,91 @@ TEST_F(core_jagged_vector_view_test, filter) {
EXPECT_EQ(std::set<int>(output[5].begin(), output[5].end()),
std::set<int>({13, 15}));
}

TEST_F(core_jagged_vector_view_test, empty) {
// Helper object for performing memory copies.
vecmem::copy copy;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
{}, m_mem, nullptr, vecmem::data::buffer_type::resizable);
copy.setup(output_data);

vecmem::jagged_device_vector device_vec(output_data);
EXPECT_EQ(device_vec.size(), 0);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 0);
}

TEST_F(core_jagged_vector_view_test, empty_fixed) {
// Helper object for performing memory copies.
vecmem::copy copy;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
{}, m_mem, nullptr, vecmem::data::buffer_type::fixed_size);
copy.setup(output_data);

vecmem::jagged_device_vector device_vec(output_data);
EXPECT_EQ(device_vec.size(), 0);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 0);
}

TEST_F(core_jagged_vector_view_test, sizeless) {
// Helper object for performing memory copies.
vecmem::copy copy;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
std::vector<std::size_t>(3, 0), m_mem, nullptr,
vecmem::data::buffer_type::resizable);
copy.setup(output_data);

vecmem::jagged_device_vector device_vec(output_data);
EXPECT_EQ(device_vec.size(), 3);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 3);
EXPECT_EQ(output[0].size(), 0);
EXPECT_EQ(output[1].size(), 0);
EXPECT_EQ(output[2].size(), 0);
}

TEST_F(core_jagged_vector_view_test, sizeless_fixed) {
// Helper object for performing memory copies.
vecmem::copy copy;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
std::vector<std::size_t>(3, 0), m_mem, nullptr,
vecmem::data::buffer_type::fixed_size);
copy.setup(output_data);

vecmem::jagged_device_vector device_vec(output_data);
EXPECT_EQ(device_vec.size(), 3);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 3);
EXPECT_EQ(output[0].size(), 0);
EXPECT_EQ(output[1].size(), 0);
EXPECT_EQ(output[2].size(), 0);
}
155 changes: 155 additions & 0 deletions tests/cuda/test_cuda_jagged_vector_view.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -249,3 +249,158 @@ TEST_F(cuda_jagged_vector_view_test, zero_capacity) {
EXPECT_EQ(host_vector.at(4).size(), 100);
EXPECT_EQ(host_vector.at(5).size(), 2);
}

TEST_F(cuda_jagged_vector_view_test, empty) {
// Helper object for performing memory copies.
vecmem::cuda::copy copy;

// Dedicated device memory resource.
vecmem::cuda::device_memory_resource device_resource;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
{}, device_resource, &m_mem, vecmem::data::buffer_type::resizable);
copy.setup(output_data);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output)->wait();

// Check the output.
EXPECT_EQ(output.size(), 0);
}

TEST_F(cuda_jagged_vector_view_test, empty_fixed) {
// Helper object for performing memory copies.
vecmem::cuda::copy copy;

// Dedicated device memory resource.
vecmem::cuda::device_memory_resource device_resource;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
{}, device_resource, &m_mem, vecmem::data::buffer_type::fixed_size);
copy.setup(output_data);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 0);
}

TEST_F(cuda_jagged_vector_view_test, sizeless) {
// Helper object for performing memory copies.
vecmem::cuda::copy copy;

// Dedicated device memory resource.
vecmem::cuda::device_memory_resource device_resource;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
std::vector<std::size_t>(3, 0), device_resource, &m_mem,
vecmem::data::buffer_type::resizable);
copy.setup(output_data);

// Run the vector filling.
fillTransform(output_data);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 3);
EXPECT_EQ(output[0].size(), 0);
EXPECT_EQ(output[1].size(), 0);
EXPECT_EQ(output[2].size(), 0);
}

TEST_F(cuda_jagged_vector_view_test, sizeless_fixed) {
// Helper object for performing memory copies.
vecmem::cuda::copy copy;

// Dedicated device memory resource.
vecmem::cuda::device_memory_resource device_resource;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
std::vector<std::size_t>(3, 0), device_resource, &m_mem,
vecmem::data::buffer_type::fixed_size);
copy.setup(output_data);

// Run the vector filling.
fillTransform(output_data);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 3);
EXPECT_EQ(output[0].size(), 0);
EXPECT_EQ(output[1].size(), 0);
EXPECT_EQ(output[2].size(), 0);
}

TEST_F(cuda_jagged_vector_view_test, partially_sizeless) {
// Helper object for performing memory copies.
vecmem::cuda::copy copy;

// Dedicated device memory resource.
vecmem::cuda::device_memory_resource device_resource;

// Create a resizable buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
{10, 0, 10, 0, 10, 0}, device_resource, &m_mem,
vecmem::data::buffer_type::resizable);
copy.setup(output_data);

// Run the vector filling.
fillTransform(output_data);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 6);
EXPECT_EQ(output[0].size(), 10);
EXPECT_EQ(output[1].size(), 0);
EXPECT_EQ(output[2].size(), 10);
EXPECT_EQ(output[3].size(), 0);
EXPECT_EQ(output[4].size(), 10);
EXPECT_EQ(output[5].size(), 0);
}

TEST_F(cuda_jagged_vector_view_test, partially_sizeless_fixed) {
// Helper object for performing memory copies.
vecmem::cuda::copy copy;

// Dedicated device memory resource.
vecmem::cuda::device_memory_resource device_resource;

// Create a fixed-size buffer for a jagged vector.
vecmem::data::jagged_vector_buffer<int> output_data(
{10, 0, 10, 0, 10, 0}, device_resource, &m_mem,
vecmem::data::buffer_type::fixed_size);
copy.setup(output_data);
copy.memset(output_data, 0);

// Run the vector filling.
fillTransform(output_data);

// Copy the filtered output back into a "host object".
vecmem::jagged_vector<int> output(&m_mem);
copy(output_data, output);

// Check the output.
EXPECT_EQ(output.size(), 6);
EXPECT_EQ(output[0].size(), 10);
EXPECT_EQ(output[1].size(), 0);
EXPECT_EQ(output[2].size(), 10);
EXPECT_EQ(output[3].size(), 0);
EXPECT_EQ(output[4].size(), 10);
EXPECT_EQ(output[5].size(), 0);
}
Loading

0 comments on commit bbb712a

Please sign in to comment.