Skip to content

Commit

Permalink
init from commit a2b6af99666ab21f3b7e339e80f463f9f6be632b of original…
Browse files Browse the repository at this point in the history
… repository
  • Loading branch information
AdhocMan committed Aug 28, 2019
0 parents commit c534fe9
Show file tree
Hide file tree
Showing 154 changed files with 21,501 additions and 0 deletions.
159 changes: 159 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
cmake_minimum_required(VERSION 3.8 FATAL_ERROR) # 3.8 added CUDA language support without FindCUDA
project(SpFFT LANGUAGES CXX VERSION 0.9.1)

# allow {module}_ROOT variables to be set
if(POLICY CMP0074)
cmake_policy(SET CMP0074 NEW)
endif()

# use INTERFACE_LINK_LIBRARIES property if available
if(POLICY CMP0022)
cmake_policy(SET CMP0022 NEW)
endif()

# set default build type to RELEASE
if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
"Debug" "Release" "MinSizeRel" "RelWithDebInfo"
)
endif()

# set language and standard
set(CMAKE_CXX_STANDARD 11)

#add local module path
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${PROJECT_SOURCE_DIR}/cmake/modules)

# Options
option(SPFFT_STATIC "Compile as static library" OFF)
option(SPFFT_OMP "Compile with OpenMP support" ON)
option(SPFFT_MPI "Compile with MPI support" ON)
option(SPFFT_GPU_DIRECT "Compile with GPU direct (GPU aware MPI) support." OFF)
option(SPFFT_BUILD_TESTS "Build tests" OFF)
option(SPFFT_SINGLE_PRECISION "Enable single precision support" OFF)
option(SPFFT_INSTALL "Enable CMake install commands" ON)

set(SPFFT_GPU_BACKEND "OFF" CACHE STRING "GPU backend")
set_property(CACHE SPFFT_GPU_BACKEND PROPERTY STRINGS
"OFF" "CUDA" "ROCM"
)


# set preferred library type
if (SPFFT_STATIC)
# prefer static over dynamic libraries with the find_library() command by changing the order
set(CMAKE_FIND_LIBRARY_SUFFIXES_SAVE ${CMAKE_FIND_LIBRARY_SUFFIXES})
if(APPLE)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .tbd .dylib .so)
elseif(UNIX)
set(CMAKE_FIND_LIBRARY_SUFFIXES .a .so)
endif()
set(SPFFT_LIBRARY_TYPE STATIC)
else()
set(SPFFT_LIBRARY_TYPE SHARED)
endif()

set(SPFFT_DEFINITIONS)
set(SPFFT_EXTERNAL_COMPILE_OPTIONS)
set(SPFFT_LIBS)
set(SPFFT_EXTERNAL_LIBS)
set(SPFFT_INTERFACE_LIBS)
set(SPFFT_INCLUDE_DIRS)
set(SPFFT_EXTERNAL_INCLUDE_DIRS)

# Options combination check
set(SPFFT_CUDA OFF)
set(SPFFT_ROCM OFF)
if(SPFFT_GPU_BACKEND)
if(SPFFT_GPU_BACKEND STREQUAL "CUDA")
set(SPFFT_CUDA ON)
elseif(SPFFT_GPU_BACKEND STREQUAL "ROCM")
set(SPFFT_ROCM ON)
else()
message(FATAL_ERROR "Invalid GPU backend option")
endif()
endif()
mark_as_advanced(SPFFT_CUDA SPFFT_ROCM)

# CUDA
if(SPFFT_CUDA)
enable_language(CUDA)
find_library(CUDA_CUDART_LIBRARY cudart PATHS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
find_library(CUDA_CUFFT_LIBRARY cufft PATHS ${CMAKE_CUDA_IMPLICIT_LINK_DIRECTORIES})
list(APPEND SPFFT_EXTERNAL_LIBS ${CUDA_CUDART_LIBRARY} ${CUDA_CUFFT_LIBRARY})
list(APPEND SPFFT_EXTERNAL_INCLUDE_DIRS ${CMAKE_CUDA_TOOLKIT_INCLUDE_DIRECTORIES})
endif()

# ROCM
if(SPFFT_ROCM)
find_package(ROCM REQUIRED COMPONENTS rocfft)
list(APPEND SPFFT_EXTERNAL_INCLUDE_DIRS ${ROCM_INCLUDE_DIRS})
list(APPEND SPFFT_EXTERNAL_LIBS ${ROCM_LIBRARIES})
list(APPEND SPFFT_EXTERNAL_COMPILE_OPTIONS ${ROCM_DEFINITIONS})
endif()



if(SPFFT_MPI)
find_package(MPI REQUIRED)
list(APPEND SPFFT_EXTERNAL_LIBS MPI::MPI_CXX)
list(APPEND SPFFT_INTERFACE_LIBS ${MPI_CXX_LIBRARIES})
endif()

if(SPFFT_OMP)
find_package(OpenMP REQUIRED)
list(APPEND SPFFT_EXTERNAL_LIBS OpenMP::OpenMP_CXX)
list(APPEND SPFFT_INTERFACE_LIBS ${OpenMP_CXX_LIBRARIES})
endif()

if(SPFFT_GPU_DIRECT)
message(STATUS "GPU Direct support enabled: Additional environment variables might have to be set before execution. (e.g \"export MPICH_RDMA_ENABLED_CUDA=1\")")
endif()



# Use MKL if available, otherwise require FFTW3
find_package(MKLSequential)
if(MKLSequential_FOUND)
list(APPEND SPFFT_EXTERNAL_LIBS MKL::Sequential)
list(APPEND SPFFT_INTERFACE_LIBS ${MKLSequential_LIBRARIES})
else()
find_package(FFTW REQUIRED)
list(APPEND SPFFT_EXTERNAL_LIBS FFTW::FFTW)
list(APPEND SPFFT_INTERFACE_LIBS ${FFTW_LIBRARIES})
if(SPFFT_SINGLE_PRECISION AND NOT FFTW_FLOAT_FOUND)
message(FATAL_ERROR "FFTW library with single precision support NOT FOUND. Disable SPFFT_SINGLE_PRECISION or provide path to library.")
endif()
endif()


if(SPFFT_BUILD_TESTS)
# enable timing with testing
set(SPFFT_TIMING ON)
endif()

# generate config.h
configure_file(include/spfft/config.h.in ${PROJECT_BINARY_DIR}/spfft/config.h)

list(APPEND SPFFT_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/src)
list(APPEND SPFFT_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/include)
list(APPEND SPFFT_INCLUDE_DIRS ${PROJECT_BINARY_DIR})
list(APPEND SPFFT_EXTERNAL_INCLUDE_DIRS ${PROJECT_SOURCE_DIR}/ext)

#############################################################################
# All include dirs and definitions must be set before sub-directory is added!
#############################################################################
add_subdirectory(src)

list(APPEND SPFFT_LIBS spfft)

# add tests for developement
if(SPFFT_BUILD_TESTS)
add_subdirectory(tests)
endif()

# reset cmake library suffixes
if(SPFFT_STATIC)
set(CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES_SAVE})
endif()
25 changes: 25 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
Copyright (c) 2019 ETH Zurich, Simon Frasch

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
165 changes: 165 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
# SpFFT
SpFFT is a library for the computation 3D FFTs with sparse frequency domain data written in C++ with support for MPI, OpenMP, CUDA and ROCm.

It was originally intended for transforms of data with spherical cutoff in frequency domain, as required by some computational material science codes, but was generalized to sparse frequency domain data.


### Design Goals
- Sparse frequency domain input
- Reuse of pre-allocated memory
- Support of negative indexing for frequency domain data
- Unified interface for calculations on CPUs and GPUs
- Support of Complex-To-Real and Real-To-Complex transforms, where the full hermitian symmetry property is utilized. Therefore, there is no redundant frequency domain data, as is usually the case for dense 3D R2C / C2R transforms with libraries such as FFTW.
- C++, C and Fortran interfaces

### Interface Design
To allow for pre-allocation and reuse of memory, the design is based on two classes:

- **Grid**: Allocates memory for transforms up to a given size in each dimension.
- **Transform**: Is created using a *Grid* and can have any size up to the maximum allowed by the *Grid*. A *Transform* holds a counted reference to the underlying *Grid*. Therefore, *Transforms* created from the same *Grid* will share the memory, which is only freed, once the *Grid* and all associated *Transforms* are destroyed.

The user provides memory for storing the sparse frequency domain data, while a *Transform* provides memory for the space domain data. This implies, that executing a *Transform* will override the space domain data of all other *Transforms* associated to the same *Grid*.

## Documentation
Documentation can be found HERE (TODO).

## Requirements
- C++ Compiler with C++11 support
- CMake version 3.8 or greater
- Library providing a FFTW 3.x interface (FFTW3 or Intel MKL)
- For multi-threading: OpenMP support by the compiler
- For GPU support: CUDA or ROCm

## Installation
The build system follows the standard CMake workflow. Example:
```console
mkdir build
cd build
cmake .. -DSPFFT_OMP=ON -DSPFFT_MPI=ON -DSPFFT_GPU_BACKEND=CUDA -DSPFFT_SINGLE_PRECISION=OFF -DCMAKE_INSTALL_PREFIX=/usr/local
make -j8 install
```

### CMake options
| Option | Default | Description |
|------------------------|---------|--------------------------------------------------|
| SPFFT_MPI | ON | Enable MPI support |
| SPFFT_OMP | ON | Enable multi-threading with OpenMP |
| SPFFT_GPU_BACKEND | OFF | Select GPU backend. Can be OFF, CUDA or ROCM |
| SPFFT_GPU_DIRECT | OFF | Use GPU aware MPI with GPUDirect |
| SPFFT_SINGLE_PRECISION | OFF | Enable single precision support |
| SPFFT_STATIC | OFF | Build as static library |
| SPFFT_BUILD_TESTS | OFF | Build test executables for developement purposes |
| SPFFT_INSTALL | ON | Add library to install target |

## Examples
Further exmples for C++, C and Fortran can be found in the "examples" folder.
```cpp
#include <complex>
#include <iostream>
#include <vector>

#include "spfft/spfft.hpp"

int main(int argc, char** argv) {
const int dimX = 2;
const int dimY = 2;
const int dimZ = 2;

std::cout << "Dimensions: x = " << dimX << ", y = " << dimY << ", z = " << dimZ << std::endl
<< std::endl;

const int numThreads = -1; // Use default OpenMP value

std::vector<std::complex<double>> freqValues;
freqValues.reserve(dimX * dimY * dimZ);

std::vector<int> indices;
indices.reserve(dimX * dimY * dimZ * 3);

// initialize frequency domain values and indices
double initValue = 0.0;
for (int xIndex = 0; xIndex < dimX; ++xIndex) {
for (int yIndex = 0; yIndex < dimY; ++yIndex) {
for (int zIndex = 0; zIndex < dimZ; ++zIndex) {
// init values
freqValues.emplace_back(initValue, -initValue);

// add index triplet for value
indices.emplace_back(xIndex);
indices.emplace_back(yIndex);
indices.emplace_back(zIndex);

initValue += 1.0;
}
}
}

std::cout << "Input:" << std::endl;
for (const auto& value : freqValues) {
std::cout << value.real() << ", " << value.imag() << std::endl;
}

// create local Grid. For distributed computations, a MPI Communicator has to be provided
spfft::Grid grid(dimX, dimY, dimZ, dimX * dimY, SPFFT_PU_HOST, numThreads);

// create transform
spfft::Transform transform =
grid.create_transform(SPFFT_PU_HOST, SPFFT_TRANS_C2C, dimX, dimY, dimZ, dimZ,
freqValues.size(), SPFFT_INDEX_TRIPLETS, indices.data());

// get pointer to space domain data. Alignment is guaranteed to fullfill requirements for
// std::complex
std::complex<double>* realValues =
reinterpret_cast<std::complex<double>*>(transform.space_domain_data(SPFFT_PU_HOST));

// transform backward
transform.backward(reinterpret_cast<double*>(freqValues.data()), SPFFT_PU_HOST);

std::cout << std::endl << "After backward transform:" << std::endl;
for (int i = 0; i < transform.local_slice_size(); ++i) {
std::cout << realValues[i].real() << ", " << realValues[i].imag() << std::endl;
}

// transform forward
transform.forward(SPFFT_PU_HOST, reinterpret_cast<double*>(freqValues.data()), SPFFT_NO_SCALING);

std::cout << std::endl << "After forward transform (without scaling):" << std::endl;
for (const auto& value : freqValues) {
std::cout << value.real() << ", " << value.imag() << std::endl;
}

return 0;
}
```
## License
```
Copyright (c) 2019 ETH Zurich, Simon Frasch

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.

2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.

3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software
without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
POSSIBILITY OF SUCH DAMAGE.
```
14 changes: 14 additions & 0 deletions cmake/SpFFTConfig.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# options used for building library
set(SPFFT_OMP @SPFFT_OMP@)
set(SPFFT_MPI @SPFFT_MPI@)
set(SPFFT_STATIC @SPFFT_STATIC@)
set(SPFFT_GPU_DIRECT @SPFFT_GPU_DIRECT@)
set(SPFFT_SINGLE_PRECISION @SPFFT_SINGLE_PRECISION@)
set(SPFFT_GPU_BACKEND @SPFFT_GPU_BACKEND@)

# add version of package
include("${CMAKE_CURRENT_LIST_DIR}/SpFFTConfigVersion.cmake")

# add library target
include("${CMAKE_CURRENT_LIST_DIR}/SpFFTTargets.cmake")

Loading

0 comments on commit c534fe9

Please sign in to comment.