diff --git a/src/care/KeyValueSorter_decl.h b/src/care/KeyValueSorter_decl.h index 95347c08..8803826e 100644 --- a/src/care/KeyValueSorter_decl.h +++ b/src/care/KeyValueSorter_decl.h @@ -135,7 +135,7 @@ class CARE_DLL_API KeyValueSorter { /// @brief Default constructor /// @return a KeyValueSorter instance /////////////////////////////////////////////////////////////////////////// - KeyValueSorter() {} + CARE_HOST_DEVICE KeyValueSorter() noexcept {} /////////////////////////////////////////////////////////////////////////// /// @author Peter Robinson, Alan Dayton diff --git a/src/care/host_device_map.h b/src/care/host_device_map.h index 4d13da6a..3b5e1220 100644 --- a/src/care/host_device_map.h +++ b/src/care/host_device_map.h @@ -245,7 +245,8 @@ namespace care { } // move constructor - CARE_HOST_DEVICE host_device_map(host_device_map&& other) noexcept { + CARE_HOST_DEVICE host_device_map(host_device_map&& other) noexcept + { m_max_size = other.m_max_size; m_signal = other.m_signal; m_gpu_map = std::move(other.m_gpu_map); @@ -271,6 +272,7 @@ namespace care { inline CARE_HOST_DEVICE void emplace(key_type key, mapped_type val) const { care::local_ptr size_ptr = m_size_ptr; int index = ATOMIC_ADD(size_ptr[0], 1); + // TODO: should this be removed? // commenting out to avoid having printfs compiled into every kernel that uses emplace //if (size_ptr[0] > m_max_size) { // printf("[CARE] Warning: host_device_map exceeds max size %d > %d\n", size_ptr[0], m_max_size); diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index a8cf4861..a70a8efe 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -97,6 +97,19 @@ target_include_directories(TestKeyValueSorter blt_add_test( NAME TestKeyValueSorter COMMAND TestKeyValueSorter ) +blt_add_executable( NAME TestHostDeviceMap + SOURCES TestHostDeviceMap.cpp + DEPENDS_ON ${care_test_dependencies} ) + +target_include_directories(TestHostDeviceMap + PRIVATE ${PROJECT_SOURCE_DIR}/src) + +target_include_directories(TestHostDeviceMap + PRIVATE ${PROJECT_BINARY_DIR}/include) + +blt_add_test( NAME TestHostDeviceMap + COMMAND TestHostDeviceMap ) + if (CARE_ENABLE_MANAGED_PTR) blt_add_executable( NAME TestManagedPtr SOURCES TestManagedPtr.cpp diff --git a/test/TestHostDeviceMap.cpp b/test/TestHostDeviceMap.cpp new file mode 100644 index 00000000..c1e229a3 --- /dev/null +++ b/test/TestHostDeviceMap.cpp @@ -0,0 +1,95 @@ +////////////////////////////////////////////////////////////////////////////// +// Copyright (c) 2020-25, Lawrence Livermore National Security, LLC and CARE +// project contributors. See the CARE LICENSE file for details. +// +// SPDX-License-Identifier: BSD-3-Clause +////////////////////////////////////////////////////////////////////////////// + +#include "care/config.h" + +#include "gtest/gtest.h" + +#include "care/DefaultMacros.h" +#include "care/host_device_map.h" +#include "care/host_device_ptr.h" +#include "care/detail/test_utils.h" + +#include + +#if defined(CARE_GPUCC) +GPU_TEST(HostDeviceMap, InsertSortLookup) +{ + init_care_for_testing(); + + constexpr int num_entries = 4; + constexpr int missing_key = 77; + constexpr int miss_signal = -999; + care::host_device_map map(num_entries, miss_signal); + + CARE_STREAM_LOOP(i, 0, num_entries) { + map.emplace((num_entries - 1) - i, 100 + i); + } CARE_STREAM_LOOP_END + + map.sort(); + EXPECT_EQ(map.size(), num_entries); + + care::host_device_ptr values(num_entries + 1, "map_values"); + + CARE_STREAM_LOOP(i, 0, num_entries) { + values[i] = map.at((num_entries - 1) - i); + } CARE_STREAM_LOOP_END + + CARE_STREAM_LOOP(i, num_entries, num_entries + 1) { + values[i] = map.at(missing_key); + } CARE_STREAM_LOOP_END + + EXPECT_EQ(values.pick(0), 100); + EXPECT_EQ(values.pick(1), 101); + EXPECT_EQ(values.pick(2), 102); + EXPECT_EQ(values.pick(3), 103); + EXPECT_EQ(values.pick(4), miss_signal); + + map.free(); +} + +GPU_TEST(HostDeviceMap, VectorDefaultConstruction) +{ + init_care_for_testing(); + + constexpr int num_maps = 2; + constexpr int num_entries = 2; + constexpr int miss_signal = -1; + std::vector> maps(num_maps); + + maps[0] = care::host_device_map(num_entries, miss_signal); + maps[1] = care::host_device_map(num_entries, miss_signal); + + auto map0_insert = maps[0]; + auto map1_insert = maps[1]; + + CARE_STREAM_LOOP(i, 0, num_entries) { + map0_insert.emplace(i, 10 + i); + map1_insert.emplace(10 + i, 20 + i); + } CARE_STREAM_LOOP_END + + maps[0].sort(); + maps[1].sort(); + + const auto map0 = maps[0]; + const auto map1 = maps[1]; + care::host_device_ptr values(2 * num_entries, "vector_map_values"); + + CARE_STREAM_LOOP(i, 0, num_entries) { + values[i] = map0.at(i); + values[num_entries + i] = map1.at(10 + i); + } CARE_STREAM_LOOP_END + + EXPECT_EQ(values.pick(0), 10); + EXPECT_EQ(values.pick(1), 11); + EXPECT_EQ(values.pick(2), 20); + EXPECT_EQ(values.pick(3), 21); + + maps[0].free(); + maps[1].free(); +} +#endif // CARE_GPUCC