Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

cover change with gtest unittests, clean up cmake script and code includes #106

Merged
merged 28 commits into from
Sep 26, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
36e4c2f
remove no need env
chenqin Sep 17, 2019
77eea8d
use rand back off to avoid swap tracker
Sep 17, 2019
4ff7cee
use determinstic backoff retry considering smooth traffic
Sep 18, 2019
415f4c6
adding googletests support
Sep 18, 2019
6aefaa0
add unittests on allreduce parameters init
Sep 19, 2019
8224bda
Merge branch 'master' of github.com:chenqin/rabit
chenqin Sep 19, 2019
566e7bc
per feedback
chenqin Sep 19, 2019
7a44877
revert main
chenqin Sep 19, 2019
bd8227f
fix failure
chenqin Sep 19, 2019
700c86c
use test_main
chenqin Sep 19, 2019
58344af
fix rabit_reduce_ring_mincount parser
Sep 20, 2019
3346a46
add README
Sep 20, 2019
216610b
Clean up CMake scripts.
trivialfis Sep 21, 2019
d4abb6d
Setup gtest on travis.
trivialfis Sep 21, 2019
72a5f33
Install tree.
trivialfis Sep 21, 2019
5650d99
Use before_install.
trivialfis Sep 21, 2019
64963dc
Specify GTEST_ROOT.
trivialfis Sep 21, 2019
0f6bc00
Force c++11 in test.
trivialfis Sep 21, 2019
3fa3803
Merge pull request #5 from trivialfis/clean-cmake
chenqin Sep 22, 2019
8188f0a
add back cpplint
chenqin Sep 22, 2019
6e13671
move pip3 install before setup script
chenqin Sep 22, 2019
16d5f0d
try fix cmake test issue on osx
chenqin Sep 22, 2019
0e90e01
spring clean includes
chenqin Sep 23, 2019
492024a
downgrade cmake
chenqin Sep 23, 2019
65eb5c0
more cleanup on DMLC_ROOT
Sep 23, 2019
4114087
build engempty for win32 asis
Sep 23, 2019
5bb3045
fix relateive path of install prefix
Sep 23, 2019
f0cfd4c
revert backoff change for another pr
Sep 23, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 4 additions & 8 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,25 +38,22 @@ addons:
- openssh-server
- python3
- python3-setuptools
- python3-pip
- tree
homebrew:
packages:
- gcc49
- openssl
- libgit2
- python3
update: true

before_install:
- git clone https://github.com/dmlc/dmlc-core
- export TRAVIS=dmlc-core/scripts/travis/
- source ${TRAVIS}/travis_setup_env.sh
- ${TRAVIS}/travis_osx_install.sh

install:
- if [[ ${TRAVIS_OS_NAME} == "linux" ]]; then sudo apt-get install python3-pip; fi
- if [[ ${TRAVIS_OS_NAME} == "osx" ]]; then brew install python3; fi
- pip3 install cpplint pylint urllib3 numpy
- pip3 install websocket-client kubernetes
- source ./scripts/travis_setup.sh

script: scripts/travis_script.sh

Expand All @@ -78,4 +75,3 @@ notifications:
email:
on_success: change
on_failure: always

85 changes: 53 additions & 32 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,85 +1,106 @@
cmake_minimum_required(VERSION 3.3)

project(rabit VERSION 0.3.0)

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
project(rabit VERSION 0.3.0 LANGUAGES CXX)

option(RABIT_BUILD_TESTS "Build rabit tests" OFF)
option(RABIT_BUILD_MPI "Build MPI" OFF)
option(RABIT_BUILD_DMLC "Include DMLC_CORE in build" OFF)
option(RABIT_WITH_R_LIB "Fit the strict environment of R" OFF)

option(DMLC_ROOT "Specify root of external dmlc core.")
# by default point to xgboost/dmlc-core
set(DMLC_ROOT ${CMAKE_CURRENT_LIST_DIR}/../dmlc-core)
Copy link
Member

@trivialfis trivialfis Sep 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You spent so much effort on rabit I assume you don't want to make it XGBoost exclusive right? Since last time I check rabit is only using some headers from dmlc-core, there's no linkage involved. So technically rabit can use dmlc-core in system path, say /usr/ or /home/chenqin/.local/ or any other directories that follow the bin/include/lib/lib64 pattern without any problem, and you can set above path as DMLC_ROOT for your convenience. With this, you can simply throw an error if DMLC_ROOT is not specified.

In the future (not for this PR), I may add this to rabit as dmlc-core has very good support for CMake target.

if (NOT DMLC_ROOT)
  find_package(dmlc)
  target_link_libraries(rabit dmlc::dmlc)  # This line also handles include directory.
endif (NOT DMLC_ROOT)


# moved from xgboost build
if(R_LIB OR MINGW OR WIN32)
add_library(rabit_base src/allreduce_base.cc src/engine_base.cc src/c_api.cc)
add_library(rabit src/engine_empty.cc src/c_api.cc)
set(rabit_libs rabit)
set_target_properties(rabit PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON)
ELSE()
set_target_properties(rabit
PROPERTIES CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE ON)
else()
add_library(rabit src/allreduce_base.cc src/allreduce_robust.cc src/engine.cc src/c_api.cc)
add_library(rabit_base src/allreduce_base.cc src/engine_base.cc src/c_api.cc)
add_library(rabit_empty src/engine_empty.cc src/c_api.cc)
add_library(rabit_mock_static src/allreduce_base.cc src/allreduce_robust.cc src/engine_mock.cc src/c_api.cc)
add_library(rabit_mock SHARED src/allreduce_base.cc src/allreduce_robust.cc src/engine_mock.cc src/c_api.cc)

set(rabit_libs rabit rabit_base rabit_empty rabit_mock rabit_mock_static)
set_target_properties(rabit rabit_base rabit_empty rabit_mock rabit_mock_static PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON)
set_target_properties(rabit rabit_base rabit_empty rabit_mock rabit_mock_static
PROPERTIES CXX_STANDARD 11
CXX_STANDARD_REQUIRED ON
POSITION_INDEPENDENT_CODE ON)
ENDIF(R_LIB OR MINGW OR WIN32)

if(RABIT_BUILD_MPI)
find_package(MPI REQUIRED)
if (NOT MPI_CXX_FOUND)
message(FATAL_ERROR "CXX Interface for MPI is required for building MPI backend.")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote this line, but do we actually want to support MPI backend? I thought it's a proof of concept for the paper. And now that the MPI CXX interface is deprecated, there will be some more works for bring it up. @chenqin What do you think?

Copy link
Contributor Author

@chenqin chenqin Sep 24, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We might discuss this in another thread how to support MPI runtime. The rationale is there are lots of similar frameworks highly optimized such as facebook/gloo that just do MPI optimization. None of which offers failed single worker recover. But I don't have clear picture who is using rabit other than distributed XGBoost.

endif (NOT MPI_CXX_FOUND)
add_library(rabit_mpi src/engine_mpi.cc ${MPI_INCLUDE_PATH})
target_link_libraries(rabit_mpi ${MPI_CXX_LIBRARIES})
list(APPEND rabit_libs rabit_mpi)
endif()

# place binaries and libraries according to GNU standards
include(GNUInstallDirs)
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_LIBDIR})
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/${CMAKE_INSTALL_BINDIR})

if(RABIT_BUILD_DMLC)
foreach(lib ${rabit_libs})
#include "./internal/utils.h"
target_include_directories(${lib} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/dmlc-core/include>"
)
endforeach()
else()
# we use this to get code coverage
if ((CMAKE_CONFIGURATION_TYPES STREQUAL "Debug") AND (CMAKE_CXX_COMPILER_ID MATCHES GNU))
foreach(lib ${rabit_libs})
#include "./internal/utils.h"
target_include_directories(${lib} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/../dmlc_core/include>"
)
endforeach()
target_compile_options(${lib}
-fprofile-arcs
-ftest-coverage)
endforeach()
endif((CMAKE_CONFIGURATION_TYPES STREQUAL "Debug") AND (CMAKE_CXX_COMPILER_ID MATCHES GNU))

if(RABIT_BUILD_DMLC)
set(DMLC_ROOT ${CMAKE_CURRENT_LIST_DIR}/dmlc-core)
endif()

if(RABIT_BUILD_TESTS)
if(DMLC_ROOT)
message("DMLC_ROOT point to " ${DMLC_ROOT})
endif(DMLC_ROOT)

foreach(lib ${rabit_libs})
target_include_directories(${lib} PUBLIC
"$<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/include>"
"$<BUILD_INTERFACE:${DMLC_ROOT}/include>")
endforeach()

if (RABIT_BUILD_TESTS)
enable_testing()
add_subdirectory(${rabit_SOURCE_DIR}/test/cpp)

# rabit mock based integration tests
list(REMOVE_ITEM rabit_libs "rabit_mock_static") # remove here to avoid installing it
set(tests lazy_recover local_recover model_recover)

foreach(test ${tests})
add_executable(${test} test/${test}.cc)
target_link_libraries(${test} rabit_mock_static)
set_target_properties(${test} PROPERTIES CXX_STANDARD 11 CXX_STANDARD_REQUIRED ON)
install(TARGETS ${test} DESTINATION test)
install(TARGETS ${test} DESTINATION test) # Why are we installing these??
endforeach()

if(RABIT_BUILD_MPI)
add_executable(speed_test_mpi test/speed_test.cc)
target_link_libraries(speed_test_mpi rabit_mpi)
install(TARGETS speed_test_mpi DESTINATION test)
endif()
endif()
endif (RABIT_BUILD_TESTS)

# Installation (https://github.com/forexample/package-example) {

# Layout. This works for all platforms:
# * <prefix>/lib/cmake/<PROJECT-NAME>
# * <prefix>/lib/
# * <prefix>/include/
set(CMAKE_INSTALL_PREFIX "../")
set(CMAKE_INSTALL_PREFIX "${rabit_SOURCE_DIR}")
set(config_install_dir "lib/cmake/${PROJECT_NAME}")
set(include_install_dir "include")

Expand Down
20 changes: 20 additions & 0 deletions cmake/googletest-download.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# code copied from https://crascit.com/2015/07/25/cmake-gtest/
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't seem necessary anymore. I'm OK for keeping it here for the convenience of others.

Copy link
Contributor

@hcho3 hcho3 Sep 25, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@trivialfis I added this because this was the easiest way to install Google Test on Windows platform. Sorry, I forgot that this PR is in Rabit. I added something like this in dmlc-core, and it's quite convenient. I suggest we keep it.

cmake_minimum_required(VERSION 3.5 FATAL_ERROR)

project(googletest-download NONE)

include(ExternalProject)

ExternalProject_Add(
googletest
SOURCE_DIR "@GOOGLETEST_DOWNLOAD_ROOT@/googletest-src"
BINARY_DIR "@GOOGLETEST_DOWNLOAD_ROOT@/googletest-build"
GIT_REPOSITORY
https://github.com/google/googletest.git
GIT_TAG
release-1.8.0
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND ""
TEST_COMMAND ""
)
32 changes: 32 additions & 0 deletions cmake/googletest.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# the following code to fetch googletest
# is inspired by and adapted after https://crascit.com/2015/07/25/cmake-gtest/
# download and unpack googletest at configure time

macro(fetch_googletest _download_module_path _download_root)
set(GOOGLETEST_DOWNLOAD_ROOT ${_download_root})
configure_file(
${_download_module_path}/googletest-download.cmake
${_download_root}/CMakeLists.txt
@ONLY
)
unset(GOOGLETEST_DOWNLOAD_ROOT)

execute_process(
COMMAND
"${CMAKE_COMMAND}" -G "${CMAKE_GENERATOR}" .
WORKING_DIRECTORY
${_download_root}
)
execute_process(
COMMAND
"${CMAKE_COMMAND}" --build .
WORKING_DIRECTORY
${_download_root}
)

# adds the targers: gtest, gtest_main, gmock, gmock_main
add_subdirectory(
${_download_root}/googletest-src
${_download_root}/googletest-build
)
endmacro()
2 changes: 1 addition & 1 deletion include/rabit/internal/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
#ifndef RABIT_INTERNAL_ENGINE_H_
#define RABIT_INTERNAL_ENGINE_H_
#include <string>
#include "../serializable.h"
#include "rabit/serializable.h"

#if (defined(__GNUC__) && !defined(__clang__))
#define _FILE __builtin_FILE()
Expand Down
4 changes: 2 additions & 2 deletions include/rabit/internal/io.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
#include <cstring>
#include <string>
#include <algorithm>
#include "./utils.h"
#include "../serializable.h"
#include "rabit/internal/utils.h"
#include "rabit/serializable.h"

namespace rabit {
namespace utils {
Expand Down
6 changes: 3 additions & 3 deletions include/rabit/internal/rabit-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
// use engine for implementation
#include <vector>
#include <string>
#include "./io.h"
#include "./utils.h"
#include "../rabit.h"
#include "rabit/internal/io.h"
#include "rabit/internal/utils.h"
#include "rabit/rabit.h"

namespace rabit {
namespace engine {
Expand Down
8 changes: 4 additions & 4 deletions src/socket.h → include/rabit/internal/socket.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* \brief this file aims to provide a wrapper of sockets
* \author Tianqi Chen
*/
#ifndef RABIT_SOCKET_H_
#define RABIT_SOCKET_H_
#ifndef RABIT_INTERNAL_SOCKET_H_
#define RABIT_INTERNAL_SOCKET_H_
#if defined(_WIN32)
#include <winsock2.h>
#include <ws2tcpip.h>
Expand All @@ -26,7 +26,7 @@
#include <cstring>
#include <vector>
#include <unordered_map>
#include "../include/rabit/internal/utils.h"
#include "utils.h"

#if defined(_WIN32) || defined(__MINGW32__)
typedef int ssize_t;
Expand Down Expand Up @@ -533,4 +533,4 @@ struct PollHelper {
};
} // namespace utils
} // namespace rabit
#endif // RABIT_SOCKET_H_
#endif // RABIT_INTERNAL_SOCKET_H_
6 changes: 3 additions & 3 deletions src/thread_local.h → include/rabit/internal/thread_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
* \file thread_local.h
* \brief Common utility for thread local storage.
*/
#ifndef RABIT_THREAD_LOCAL_H_
#define RABIT_THREAD_LOCAL_H_
#ifndef RABIT_INTERNAL_THREAD_LOCAL_H_
#define RABIT_INTERNAL_THREAD_LOCAL_H_

#include "../include/dmlc/base.h"

Expand Down Expand Up @@ -84,4 +84,4 @@ class ThreadLocalStore {
std::vector<T*> data_;
};
} // namespace rabit
#endif // RABIT_THREAD_LOCAL_H_
#endif // RABIT_INTERNAL_THREAD_LOCAL_H_
4 changes: 2 additions & 2 deletions include/rabit/serializable.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
#define RABIT_SERIALIZABLE_H_
#include <vector>
#include <string>
#include "./internal/utils.h"
#include "rabit/internal/utils.h"

#ifndef DMLC_IO_H_
#include "../../dmlc-core/include/dmlc/io.h"
#include "dmlc/io.h"
#endif // DMLC_IO_H_

namespace rabit {
Expand Down
7 changes: 5 additions & 2 deletions scripts/travis_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ fi
if [ ${TASK} == "cmake-test" ]; then
mkdir build
cd build
cmake -DRABIT_BUILD_TESTS=ON -DRABIT_BUILD_DMLC=ON ..
cmake -DRABIT_BUILD_TESTS=ON -DRABIT_BUILD_DMLC=ON -DGTEST_ROOT=${HOME}/.local ..
#unit tests
make
make test
make install || exit -1
cd ../test
../scripts/travis_runtest.sh || exit -1
rm -rf ../build
fi
fi
35 changes: 35 additions & 0 deletions scripts/travis_setup.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#!/bin/bash

echo "Testing on: ${TRAVIS_OS_NAME}, Home directory: ${HOME}"

pip3 install cpplint pylint urllib3 numpy cpplint
pip3 install websocket-client kubernetes


# Install googletest under home directory
GTEST_VERSION=1.8.1
GTEST_RELEASE=release-${GTEST_VERSION}.tar.gz
GTEST_TAR_BALL=googletest_${GTEST_RELEASE}

wget https://github.com/google/googletest/archive/${GTEST_RELEASE} -O ${GTEST_TAR_BALL}
echo "152b849610d91a9dfa1401293f43230c2e0c33f8 ${GTEST_TAR_BALL}" | sha1sum -c
tar -xf ${GTEST_TAR_BALL}
pushd .

cd googletest-release-${GTEST_VERSION}
mkdir build
cd build
echo "Installing to ${HOME}/.local"
cmake .. -DBUILD_SHARED_LIBS=ON -DCMAKE_INSTALL_PREFIX=${HOME}/.local
make -j$(nproc)
make install

popd

if [ ${TRAVIS_OS_NAME} == "linux" ]; then
sudo apt-get install python3-pip tree
fi

if [ ${TRAVIS_OS_NAME} == "osx" ]; then
brew install python3
fi
17 changes: 17 additions & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
option(DMLC_ROOT "Specify root of external dmlc core.")

add_library(allreduce_base "")

target_sources(
allreduce_base
PRIVATE
allreduce_base.cc
PUBLIC
${CMAKE_CURRENT_LIST_DIR}/allreduce_base.h
)

target_include_directories(
allreduce_base
PUBLIC
${DMLC_ROOT}/include
${CMAKE_CURRENT_LIST_DIR}/../../include)
Loading