diff --git a/CMakeLists.txt b/CMakeLists.txt index ad71de86..2597313f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,12 @@ if(ALLOW_GDRCOPY) find_package(GDRCopy) endif() +include(CTest) +include(FetchContent) +FetchContent_Declare(googletest URL https://github.com/google/googletest/archive/b796f7d44681514f58a683a3a71ff17c94edb0c1.zip) +FetchContent_MakeAvailable(googletest) +include(GoogleTest) + set(CLANG_FORMAT_SOURCE_DIRS src tests) include(${PROJECT_SOURCE_DIR}/cmake/AddClangFormatTargets.cmake) diff --git a/src/communicator.cc b/src/communicator.cc index 603d053d..c4abf818 100644 --- a/src/communicator.cc +++ b/src/communicator.cc @@ -75,7 +75,7 @@ struct MemorySender : public Setuppable MSCCLPP_API_CPP void Communicator::sendMemoryOnSetup(RegisteredMemory memory, int remoteRank, int tag) { - addSetup(std::make_shared(memory, remoteRank, tag)); + onSetup(std::make_shared(memory, remoteRank, tag)); } struct MemoryReceiver : public Setuppable @@ -99,7 +99,7 @@ struct MemoryReceiver : public Setuppable MSCCLPP_API_CPP NonblockingFuture Communicator::recvMemoryOnSetup(int remoteRank, int tag) { auto memoryReceiver = std::make_shared(remoteRank, tag); - addSetup(memoryReceiver); + onSetup(memoryReceiver); return NonblockingFuture(memoryReceiver->memoryPromise_.get_future()); } @@ -131,11 +131,11 @@ MSCCLPP_API_CPP std::shared_ptr Communicator::connectOnSetup(int rem throw mscclpp::Error("Unsupported transport", ErrorCode::InternalError); } pimpl->connections_.push_back(conn); - addSetup(conn); + onSetup(conn); return conn; } -MSCCLPP_API_CPP void Communicator::addSetup(std::shared_ptr setuppable) +MSCCLPP_API_CPP void Communicator::onSetup(std::shared_ptr setuppable) { pimpl->toSetup_.push_back(setuppable); } diff --git a/src/include/mscclpp.hpp b/src/include/mscclpp.hpp index a242d2bc..7ca8503b 100644 --- a/src/include/mscclpp.hpp +++ b/src/include/mscclpp.hpp @@ -361,7 +361,7 @@ public: std::shared_ptr connectOnSetup(int remoteRank, int tag, Transport transport); /* Add a custom Setuppable object to a list of objects to be setup later, when setup() is called. */ - void addSetup(std::shared_ptr setuppable); + void onSetup(std::shared_ptr setuppable); /* Setup all objects that have registered for setup. This includes any connections created by connect(). */ void setup(); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 17875d69..3eec4226 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,6 @@ function(add_test_executable name sources) add_executable(${name} ${sources}) - target_link_libraries(${name} mscclpp) + target_link_libraries(${name} mscclpp CUDA::cudart CUDA::cuda_driver) if(USE_MPI_FOR_TESTS) target_link_libraries(${name} MPI::MPI_CXX) target_compile_definitions(${name} PRIVATE MSCCLPP_USE_MPI_FOR_TESTS) @@ -10,5 +10,10 @@ endfunction() add_test_executable(bootstrap_test_cpp bootstrap_test_cpp.cc) add_test_executable(communicator_test_cpp communicator_test_cpp.cu) add_test_executable(allgather_test_cpp allgather_test_cpp.cu) +add_test_executable(ib_test ib_test.cc) -add_subdirectory(unittests) +# Unit tests +add_executable(unit_tests) +target_link_libraries(unit_tests GTest::gtest_main GTest::gmock_main mscclpp) +add_subdirectory(unit) # This adds the sources to the mscclpp target +gtest_discover_tests(unit_tests DISCOVERY_MODE PRE_TEST) diff --git a/tests/unittests/ib_test.cc b/tests/ib_test.cc similarity index 100% rename from tests/unittests/ib_test.cc rename to tests/ib_test.cc diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt new file mode 100644 index 00000000..a5b2f4b9 --- /dev/null +++ b/tests/unit/CMakeLists.txt @@ -0,0 +1,3 @@ +target_sources(unit_tests PRIVATE + core_tests.cc +) diff --git a/tests/unit/core_tests.cc b/tests/unit/core_tests.cc new file mode 100644 index 00000000..df4c165e --- /dev/null +++ b/tests/unit/core_tests.cc @@ -0,0 +1,49 @@ +#include +#include +#include "mscclpp.hpp" + +class LocalCommunicatorTest : public ::testing::Test { + protected: + void SetUp() override { + bootstrap = std::make_shared(0, 1); + comm = std::make_shared(bootstrap); + } + + std::shared_ptr bootstrap; + std::shared_ptr comm; +}; + +class MockSetuppable : public mscclpp::Setuppable { + public: + MOCK_METHOD(void, beginSetup, (std::shared_ptr bootstrap), (override)); + MOCK_METHOD(void, endSetup, (std::shared_ptr bootstrap), (override)); +}; + +TEST_F(LocalCommunicatorTest, OnSetup) { + auto mockSetuppable = std::make_shared(); + comm->onSetup(mockSetuppable); + EXPECT_CALL(*mockSetuppable, beginSetup(std::dynamic_pointer_cast(bootstrap))); + EXPECT_CALL(*mockSetuppable, endSetup(std::dynamic_pointer_cast(bootstrap))); + comm->setup(); +} + +TEST_F(LocalCommunicatorTest, RegisterMemory) { + int dummy[42]; + auto memory = comm->registerMemory(&dummy, sizeof(dummy), mscclpp::NoTransports); + EXPECT_EQ(memory.data(), &dummy); + EXPECT_EQ(memory.size(), sizeof(dummy)); + EXPECT_EQ(memory.rank(), 0); + EXPECT_EQ(memory.transports(), mscclpp::NoTransports); +} + +TEST_F(LocalCommunicatorTest, SendMemoryToSelf) { + int dummy[42]; + auto memory = comm->registerMemory(&dummy, sizeof(dummy), mscclpp::NoTransports); + comm->sendMemoryOnSetup(memory, 0, 0); + auto memoryFuture = comm->recvMemoryOnSetup(0, 0); + comm->setup(); + auto sameMemory = memoryFuture.get(); + EXPECT_EQ(sameMemory.size(), memory.size()); + EXPECT_EQ(sameMemory.rank(), memory.rank()); + EXPECT_EQ(sameMemory.transports(), memory.transports()); +} diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt deleted file mode 100644 index 44e405ad..00000000 --- a/tests/unittests/CMakeLists.txt +++ /dev/null @@ -1,2 +0,0 @@ -add_test_executable(ib_test ib_test.cc) -target_link_libraries(ib_test CUDA::cudart) \ No newline at end of file