Skip to content

Commit

Permalink
Release v1.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
alexa-ca committed Dec 22, 2021
2 parents 9330ede + 262d170 commit b4a1d5a
Show file tree
Hide file tree
Showing 41 changed files with 1,545 additions and 116 deletions.
30 changes: 28 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
cmake_minimum_required (VERSION 3.8)
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")

project (GaspiCxx)
include (read_version)
configure_version(VERSION_FILE "${CMAKE_SOURCE_DIR}/version.in")

project (GaspiCxx ${GaspiCxx_VERSION})

include(GNUInstallDirs)
set(THREADS_PREFER_PTHREAD_FLAG ON)
Expand All @@ -10,18 +13,41 @@ find_package(GPI2 REQUIRED)

option (ENABLE_TESTS "Compile tests [default: disabled]" off)
option (BUILD_SHARED_LIBS "Create shared libraries [default: disabled (creates static libraries)]" off)
option (BUILD_PYTHON_BINDINGS "Build Python bindings [default: disabled]" off)

set (CMAKE_CXX_STANDARD 17)
set (CMAKE_BUILD_TYPE Release)
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Werror")

# Set a default build type if none was specified
set(default_build_type "Release")
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting default build type to '${default_build_type}'.")
set(CMAKE_BUILD_TYPE "${default_build_type}" CACHE
STRING "Define build type." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo")
endif()

set(INCLUDE_DIR "${CMAKE_SOURCE_DIR}/include")

add_subdirectory (src)
add_subdirectory (examples)

if(BUILD_PYTHON_BINDINGS)
find_package(PythonModules REQUIRED)
find_package(pybind11 CONFIG REQUIRED)
add_subdirectory (src/python)
endif()

if(ENABLE_TESTS)
enable_testing()
find_package(GTest REQUIRED)
include(GoogleTest)
add_subdirectory (tests)

if(BUILD_PYTHON_BINDINGS)
find_package(PythonModules COMPONENTS pytest)
add_subdirectory (tests/python)
endif()
endif()
125 changes: 119 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,138 @@
# GaspiCxx

GaspiCxx is a C++ interface for the communication library GPI-2. The C++ interface aims at an abstraction for the native C based communication interface of GPI-2 without impacting the underlying performance. The interface design makes the explicit management of communication resources required by the native
C interface fully transparent to the application. They do not need to be managed explicitly any more. Instead, objects with exclusive and auto-managed resources for groups, queues, segments are provided by GaspiCxx. The dynamic management of segment memory and segment synchronization primitives is provided by allocators. The single-sided and the passive communication are built on top of that. Allocations within the partitioned global address space and the respective synchronization primitives can be easily connected with each other on the source and the target side for efficient communication.
GaspiCxx is a C++ interface for the GPI-2 communication library,
which aims at providing a high-level abstraction layer on top of
the native communication primitives.
GaspiCxx is designed to achieve the following goals:
* scalability
* performance
* productivity

The interface design replaces the explicit management of communication
resources required by the native GPI-2 interface with fully-transparent
and easy-to-use primitives.
The GaspiCxx API implements the following automatically managed resources:
* Groups
* Segments
* Queues
* Point-to-point single-sided communication primitives
* SourceBuffer/TargetBuffers
* Non-blocking collective primitives
* Allreduce
* Allgatherv
* Broadcast
* Blocking collectives
* Barrier

Additionally, GaspiCxx provides a Python extension called `PyGPI`, which exposes the
GaspiCxx point-to-point and collective primitives as an easy-to-use, intuitive Python library.
More details regarding the installation and configuration of `PyGPI` can be found
[here](src/python/README.md).


## Installation

### Compiler and build system

GaspiCxx can be built using a recent compiler with support for C++17.
It was tested with [gcc](https://gcc.gnu.org/) starting from version `8.4.0` and [clang](https://clang.llvm.org/) `10.0.0`.
You will also need the build tool [CMake](https://cmake.org/) (from version `3.12`).


### Step 1: Software dependencies

GaspiCxx depends on
GaspiCxx depends on:

- Google test
- [GPI-2](https://github.com/cc-hpc-itwm/GPI-2)
- (Optional) Google test

#### Installing GPI-2

To install `GPI-2`, clone the following [git repository](https://github.com/cc-hpc-itwm/GPI-2.git)
and checkout the `1.5.1` tag:

```bash
git clone https://github.com/cc-hpc-itwm/GPI-2.git
cd GPI-2
git fetch --tags
git checkout -b v1.5.1 v1.5.1
```

Now, use [autotools](https://www.gnu.org/software/automake/)
to configure and compile the code:

```bash
./autogen.sh
export GPI2_INSTALLATION_PATH=/your/installation/path
CFLAGS="-fPIC" CPPFLAGS="-fPIC" ./configure --with-infiniband --prefix=${GPI2_INSTALLATION_PATH}
make $nprocs
```

where `${GPI2_INSTALLATION_PATH}` needs to be replaced with the path where you want to install
GPI-2. Note the `--with-infiniband` option, which should be used on most HPC clusters that
provide Infiniband support.

In case you want to install GPI-2 on a laptop or workstation, replace the above
option with ``--with-ethernet``, which will use standard TCP sockets for communication.
Now you are ready to install GPI-2 with:

```bash
make install
export PATH=${GPI2_INSTALLATION_PATH}/bin:$PATH
```

### Step 2: Build GaspiCxx

CMake is used as build system The dependency to GPI-2 is resolved by pkg-config. In order to allow CMake to find the GPI-2 configuration files, the path `GPI2_INSTALL_DIR/lib64/pkgconfig` needs to be appended to the `PKG_CONFIG_PATH` environment variable before invocation of CMake, e.g. by
Compile and install the GaspiCxx library as follows:

```bash
git clone https://github.com/cc-hpc-itwm/GaspiCxx.git
cd GaspiCxx
mkdir build && cd build

export GASPICXX_INSTALLATION_PATH=/your/gaspicxx/installation/path
cmake -DCMAKE_INSTALL_PREFIX=${GASPICXX_INSTALLATION_PATH} ../
make -j$nprocs install
```
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:GPI2_INSTALL_DIR/lib64/pkgconfig

### (Optional) Step 3: Run tests

#### Install Google Test

Download and install Google test from its
[GitHub repository](https://github.com/google/googletest/tree/main/googletest).

```bash
export GTEST_INSTALLATION_PATH=/path/to/gtest

git clone https://github.com/google/googletest.git -b release-1.11.0
cd googletest
mkdir build && cd build
cmake -DCMAKE_INSTALL_PREFIX=${GTEST_INSTALLATION_PATH} ../
make -j$nprocs install
```

#### Compile GaspiCxx with testing enabled

```bash
export GASPICXX_INSTALLATION_PATH=/your/gaspicxx/installation/path
cmake -DENABLE_TESTS=ON \
-DCMAKE_PREFIX_PATH=${GTEST_INSTALLATION_PATH} \
-DCMAKE_INSTALL_PREFIX=${GASPICXX_INSTALLATION_PATH} ../
make -j$nprocs install
```

#### Run tests
GaspiCxx tests can be executed using the `ctest` command
```bash
# list tests
ctest -N

# run all tests
ctest
```


## License
This project is licensed under the GPLv3.0 License - see the
[COPYING](COPYING) file for details
60 changes: 60 additions & 0 deletions cmake/FindPythonModules.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#[=======================================================================[.rst:
FindPythonModules
-------
Finds installed PythonModules
Result Variables
^^^^^^^^^^^^^^^^
This will define the following variables:
``PythonModules_FOUND``
True if all the required PythonModules could be loaded.
``PythonModules_modulename_FOUND``
True if `modulename` could be loaded.
``Python_EXECUTABLE``
Path to the Python executable.
Cache Variables
^^^^^^^^^^^^^^^
The following cache variables may also be set:
``GPI2_INCLUDE_DIR``
The directory containing ``gaspi.h``.
``GPI2_LIBRARY``
The path to the GPI2 library.
#]=======================================================================]

execute_process(COMMAND sh -c "which python"
OUTPUT_VARIABLE python_path
RESULT_VARIABLE result
ERROR_QUIET
OUTPUT_STRIP_TRAILING_WHITESPACE)
if (result EQUAL "0" AND EXISTS ${python_path})
set(Python_EXECUTABLE "${python_path}")
endif()

set(PythonModules_FOUND TRUE)
if (Python_EXECUTABLE)
foreach (module IN LISTS PythonModules_FIND_COMPONENTS)
execute_process(COMMAND ${Python_EXECUTABLE} -c
"import ${module}"
RESULT_VARIABLE result
ERROR_QUIET OUTPUT_QUIET)

if(result)
set (PythonModules_${module}_FOUND FALSE)
set (PythonModules_FOUND FALSE)
else()
set (PythonModules_${module}_FOUND TRUE)
endif()
endforeach()
endif()

include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (PythonModules
REQUIRED_VARS Python_EXECUTABLE PythonModules_FOUND
HANDLE_COMPONENTS)
17 changes: 17 additions & 0 deletions cmake/read_version.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
include (parse_arguments)

function (configure_version)
set(one_value_options VERSION_FILE)
set(required_options VERSION_FILE)
_parse_arguments(ARG "${options}" "${one_value_options}"
"${multi_value_options}" "${required_options}" ${ARGN})

file(READ ${ARG_VERSION_FILE} ver)
string(REGEX MATCH "gaspicxx_version[ ]*=[ ]*[\'\"]([0-9]+\.[0-9]+\.[0-9]+)[\'\"]" _ ${ver})
if(CMAKE_MATCH_COUNT EQUAL 1)
set(TNT_VERSION ${CMAKE_MATCH_1} PARENT_SCOPE)
message(STATUS "GaspiCxx version: ${CMAKE_MATCH_1}")
else()
message(FATAL_ERROR "Invalid version string in ${ARG_VERSION_FILE}" )
endif()
endfunction()
40 changes: 37 additions & 3 deletions cmake/test_helpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function (gaspicxx_gen_test_script)

message(STATUS "Test: Generating ${ARG_NAME} script")
gaspicxx_gen_executable_script(SCRIPT_NAME ${ARG_NAME}
SCRIPT_DIR ${ARG_SCRIPT_DIR})
SCRIPT_DIR ${ARG_SCRIPT_DIR})

gaspicxx_gen_environment_paths(VARIABLE_LIST env_paths)

Expand All @@ -64,7 +64,7 @@ function (gaspicxx_gen_test_script)
endforeach()
if (ARG_IS_PYTHON_TEST)
# Python test
file(APPEND ${script_path} "export PYTHONPATH=${CMAKE_BINARY_DIR}:${CMAKE_SOURCE_DIR}/src:\$\{PYTHONPATH\}\n")
file(APPEND ${script_path} "export PYTHONPATH=${CMAKE_BINARY_DIR}:${CMAKE_BINARY_DIR}/python:${CMAKE_BINARY_DIR}/src/python/bindings:\$\{PYTHONPATH\}\n")
file(APPEND ${script_path} "\n${Python_EXECUTABLE} -m pytest ${ARG_TEST_EXECUTABLE}\n")
else()
# regular executable test
Expand Down Expand Up @@ -198,4 +198,38 @@ function (gaspicxx_generate_cleanup_test)
SLEEP 0)
set_tests_properties(${CLEANUP_TEST_NAME}_${ARG_LOCALRANKS}ranks
PROPERTIES FIXTURES_CLEANUP ${CLEANUP_TEST_NAME})
endfunction()
endfunction()

function (gaspicxx_generate_python_gpi_test)
set (one_value_options NAME TEST_EXECUTABLE DESCRIPTION TIMEOUT)
set (multi_value_options LOCALRANKS_LIST LABELS ARGS)
set (required_options NAME TEST_EXECUTABLE LOCALRANKS_LIST)
_parse_arguments (ARG "${options}" "${one_value_options}"
"${multi_value_options}" "${required_options}" ${ARGN})
set(CLEANUP_TEST_NAME gpi_cleanup)
list(APPEND ARG_LABELS "Python")
list(REMOVE_DUPLICATES ARG_LABELS)

set(ARG_NAME "Py_${ARG_NAME}")

# wrap call to the test executable in a script that exports the current environment
# the script can then be executed within a `gaspi_run` call
set(script_name run_${ARG_NAME}.sh)
set(script_path ${CMAKE_CURRENT_BINARY_DIR}/${script_name})
gaspicxx_gen_test_script(NAME ${script_name}
SCRIPT_DIR ${CMAKE_CURRENT_BINARY_DIR}
TEST_EXECUTABLE ${ARG_TEST_EXECUTABLE}
IS_PYTHON_TEST)

message(STATUS "Test: Generating gaspi_run tests for ${ARG_NAME} with ${ARG_LOCALRANKS_LIST} ranks")
foreach(nlocalranks ${ARG_LOCALRANKS_LIST})
gaspicxx_add_gpi_test(NAME ${ARG_NAME}
NRANKS ${nlocalranks}
TEST_SCRIPT ${script_path}
RUNCOMMAND ${GPI2_GASPI_RUN}
TIMEOUT ${ARG_TIMEOUT}
CLEANUP ${CLEANUP_TEST_NAME}
SLEEP 0
LABELS ${ARG_LABELS})
endforeach()
endfunction()
9 changes: 8 additions & 1 deletion include/GaspiCxx/collectives/non_blocking/Allgatherv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ namespace gaspi
void waitForCompletion(void* outputs) override;
void waitForCompletion(std::vector<T>& outputs);

std::size_t getOutputCount() override;
std::vector<std::size_t> get_counts() override;

private:
Expand Down Expand Up @@ -130,5 +131,11 @@ namespace gaspi
{
return counts;
}

template<typename T, AllgathervAlgorithm Algorithm>
std::size_t Allgatherv<T, Algorithm>::getOutputCount()
{
return allgatherv_impl->getOutputCount();
}
}
}
}
10 changes: 10 additions & 0 deletions include/GaspiCxx/collectives/non_blocking/Allreduce.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@

#include <GaspiCxx/collectives/non_blocking/Collective.hpp>
#include <GaspiCxx/collectives/non_blocking/collectives_lowlevel/AllreduceCommon.hpp>
#include <GaspiCxx/collectives/non_blocking/collectives_lowlevel/AllreduceRing.hpp>
#include <GaspiCxx/collectives/non_blocking/collectives_lowlevel/AllreduceRecursiveDoubling.hpp>
#include <GaspiCxx/progress_engine/ProgressEngine.hpp>
#include <GaspiCxx/Runtime.hpp>

Expand Down Expand Up @@ -53,6 +55,8 @@ namespace gaspi
void waitForCompletion(void* outputs) override;
void waitForCompletion(std::vector<T>& outputs);

std::size_t getOutputCount() override;

private:
progress_engine::ProgressEngine& progress_engine;
progress_engine::ProgressEngine::CollectiveHandle handle;
Expand Down Expand Up @@ -114,5 +118,11 @@ namespace gaspi
{
waitForCompletion(static_cast<void*>(outputs.data()));
}

template<typename T, AllreduceAlgorithm Algorithm>
std::size_t Allreduce<T, Algorithm>::getOutputCount()
{
return allreduce_impl->getOutputCount();
}
}
}
Loading

0 comments on commit b4a1d5a

Please sign in to comment.