Skip to content

Commit

Permalink
Merge pull request #41 from CExA-project/add-benchmark
Browse files Browse the repository at this point in the history
Add benchmark
  • Loading branch information
yasahi-hpc authored Feb 8, 2024
2 parents 372860c + be2f301 commit dd796b1
Show file tree
Hide file tree
Showing 21 changed files with 908 additions and 33 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build_test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ jobs:
-DCMAKE_CXX_COMPILER=${{ matrix.backend.cxx_compiler }} \
-DCMAKE_CXX_STANDARD=17 \
-DBUILD_TESTING=ON \
-DKokkosFFT_ENABLE_BENCHMARK=ON \
-DKokkosFFT_INTERNAL_Kokkos=ON \
${{ matrix.backend.cmake_flags }} \
${{ matrix.target.cmake_flags }}
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,6 @@
[submodule "tpls/googletest"]
path = tpls/googletest
url = https://github.com/google/googletest.git
[submodule "tpls/benchmark"]
path = tpls/benchmark
url = https://github.com/google/benchmark.git
48 changes: 44 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,21 @@ list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake")

# Options
option(BUILD_EXAMPLES "Build KokkosFFT examples" ON)
option(KokkosFFT_ENABLE_HOST_AND_DEVICE "Enable FFT on both host and device")
option(KokkosFFT_INTERNAL_Kokkos "Build internal Kokkos instead of relying on external one")
option(KokkosFFT_ENABLE_HOST_AND_DEVICE "Enable FFT on both host and device" OFF)
option(KokkosFFT_INTERNAL_Kokkos "Build internal Kokkos instead of relying on external one" OFF)
option(KokkosFFT_ENABLE_BENCHMARK "Build benchmarks for KokkosFFT" OFF)

# Version information
set(KokkosFFT_VERSION_MAJOR 0)
set(KokkosFFT_VERSION_MINOR 0)
set(KokkosFFT_VERSION_PATCH 00)
set(KokkosFFT_VERSION "${KokkosFFT_VERSION_MAJOR}.${KokkosFFT_VERSION_MINOR}.${KokkosFFT_VERSION_PATCH}")

#Set variables for config file
math(EXPR KOKKOSFFT_VERSION "${KokkosFFT_VERSION_MAJOR} * 10000 + ${KokkosFFT_VERSION_MINOR} * 100 + ${KokkosFFT_VERSION_PATCH}")
math(EXPR KOKKOSFFT_VERSION_MAJOR "${KOKKOSFFT_VERSION} / 10000")
math(EXPR KOKKOSFFT_VERSION_MINOR "${KOKKOSFFT_VERSION} / 100 % 100")
math(EXPR KOKKOSFFT_VERSION_PATCH "${KOKKOSFFT_VERSION} % 100")

if (NOT KokkosFFT_INTERNAL_Kokkos)
# First check, Kokkos is added as subdirectory or not
Expand All @@ -27,6 +40,33 @@ if(BUILD_TESTING)
endif()
endif()

# Benchmark
if(KokkosFFT_ENABLE_BENCHMARK)
option(BENCHMARK_ENABLE_TESTING "Enable testing of the benchmark library." OFF)
add_subdirectory(tpls/benchmark)

# [TO DO] Fix this, it detects benchmark not a googlebench
#find_package(benchmark QUIET)
#if(NOT benchmark_FOUND)
# add_subdirectory(tpls/benchmark)
#endif()
endif()

# Configure files to display configuration
# Configure the library
set(
PACKAGE_NAME_CONFIG_FILES
KokkosFFT_config.h
KokkosFFT_Version_Info.hpp
)

foreach(CONFIG_FILE ${PACKAGE_NAME_CONFIG_FILES})
configure_file(
cmake/${CONFIG_FILE}.in
${CMAKE_BINARY_DIR}/${CONFIG_FILE}
)
endforeach()

# Set directories used for install
include(GNUInstallDirs)
set(LIBDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME})
Expand Down Expand Up @@ -71,12 +111,12 @@ configure_package_config_file(cmake/KokkosFFTConfig.cmake.in

write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/KokkosFFTConfigVersion.cmake
VERSION 0.0.0
VERSION ${KokkosFFT_VERSION}
COMPATIBILITY SameMajorVersion
)

install(
FILES ${CMAKE_CURRENT_BINARY_DIR}/KokkosFFTConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/KokkosFFTConfigVersion.cmake
DESTINATION ${INSTALL_LIBDIR}
)
)
36 changes: 36 additions & 0 deletions cmake/KokkosFFT_Version_Info.hpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
//@HEADER
// ************************************************************************
//
// Kokkos v. 4.0
// Copyright (2022) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
// See https://kokkos.org/LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//@HEADER

#ifndef KOKKOSFFT_VERSION_INFO_HPP
#define KOKKOSFFT_VERSION_INFO_HPP

#include <string_view>

namespace KokkosFFT {
namespace Impl {

constexpr std::string_view GIT_BRANCH = R"branch(@GIT_BRANCH@)branch";
constexpr std::string_view GIT_COMMIT_HASH = "@GIT_COMMIT_HASH@";
constexpr std::string_view GIT_CLEAN_STATUS = "@GIT_CLEAN_STATUS@";
constexpr std::string_view GIT_COMMIT_DESCRIPTION =
R"message(@GIT_COMMIT_DESCRIPTION@)message";
constexpr std::string_view GIT_COMMIT_DATE = "@GIT_COMMIT_DATE@";
constexpr std::string_view BENCHMARK_VERSION = "@BENCHMARK_VERSION@";

} // namespace Impl
} // namespace KokkosFFT

#endif
30 changes: 30 additions & 0 deletions cmake/KokkosFFT_config.h.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef KOKKOSFFT_CONFIG_H
#define KOKKOSFFT_CONFIG_H

/* Define the current version of Kokkos Kernels */
#define KOKKOSFFT_VERSION @KOKKOSFFT_VERSION@
#define KOKKOSFFT_VERSION_MAJOR @KOKKOSFFT_VERSION_MAJOR@
#define KOKKOSFFT_VERSION_MINOR @KOKKOSFFT_VERSION_MINOR@
#define KOKKOSFFT_VERSION_PATCH @KOKKOSFFT_VERSION_PATCH@

/* Define if building in debug mode */
#cmakedefine HAVE_KOKKOSFFT_DEBUG

#cmakedefine KOKKOSFFT_ENABLE_BENCHMARK

/* Define this macro if experimental features of KokkosFFT are enabled */
#cmakedefine HAVE_KOKKOSFFT_EXPERIMENTAL

/* FFTW */
#cmakedefine KOKKOSFFT_ENABLE_TPL_FFTW

/* CUFFT */
#cmakedefine KOKKOSFFT_ENABLE_TPL_CUFFT

/* HIPFFT */
#cmakedefine KOKKOSFFT_ENABLE_TPL_HIPFFT

/* ONEMKL */
#cmakedefine KOKKOSFFT_ENABLE_TPL_ONEMKL

#endif
11 changes: 8 additions & 3 deletions common/src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,33 +8,38 @@ target_link_libraries(common
if(Kokkos_ENABLE_CUDA)
find_package(CUDAToolkit REQUIRED COMPONENTS cufft)
target_link_libraries(common INTERFACE CUDA::cufft)
target_compile_definitions(common INTERFACE KOKKOSFFT_ENABLE_TPL_CUFFT)
if(KokkosFFT_ENABLE_HOST_AND_DEVICE)
find_package(FFTW MODULE REQUIRED)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double FFTW::FloatOpenMP FFTW::DoubleOpenMP)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE KOKKOSFFT_ENABLE_TPL_FFTW)
endif()
elseif(Kokkos_ENABLE_HIP)
find_package(hipfft REQUIRED)
target_link_libraries(common INTERFACE hip::hipfft)
target_compile_definitions(common INTERFACE KOKKOSFFT_ENABLE_TPL_HIPFFT)
if(KokkosFFT_ENABLE_HOST_AND_DEVICE)
find_package(FFTW MODULE REQUIRED)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double FFTW::FloatOpenMP FFTW::DoubleOpenMP)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE KOKKOSFFT_ENABLE_TPL_FFTW)
endif()
elseif(Kokkos_ENABLE_SYCL)
find_package(MKL REQUIRED COMPONENTS SYCL)
target_link_libraries(common INTERFACE MKL::MKL_SYCL)
target_compile_definitions(common INTERFACE KOKKOSFFT_ENABLE_TPL_ONEMKL)
if(KokkosFFT_ENABLE_HOST_AND_DEVICE)
find_package(FFTW MODULE REQUIRED)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double FFTW::FloatOpenMP FFTW::DoubleOpenMP)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE)
target_compile_definitions(common INTERFACE ENABLE_HOST_AND_DEVICE KOKKOSFFT_ENABLE_TPL_FFTW)
endif()
elseif(Kokkos_ENABLE_OPENMP)
find_package(FFTW MODULE REQUIRED)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double FFTW::FloatOpenMP FFTW::DoubleOpenMP)
target_compile_definitions(common INTERFACE KOKKOSFFT_ENABLE_TPL_FFTW)
elseif(Kokkos_ENABLE_SERIAL)
find_package(FFTW MODULE REQUIRED)
target_link_libraries(common INTERFACE FFTW::Float FFTW::Double)
target_compile_definitions(common INTERFACE KOKKOSFFT_ENABLE_TPL_FFTW)
endif()

target_compile_features(common INTERFACE cxx_std_17)
Expand Down
2 changes: 1 addition & 1 deletion common/src/KokkosFFT_normalization.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void normalize(const ExecutionSpace& exec_space, ViewType& inout,
if (to_normalize) _normalize(exec_space, inout, coef);
}

auto swap_direction(Normalization normalization) {
inline auto swap_direction(Normalization normalization) {
Normalization new_direction = Normalization::FORWARD;
switch (normalization) {
case Normalization::FORWARD: new_direction = Normalization::BACKWARD; break;
Expand Down
2 changes: 1 addition & 1 deletion docker/hip/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
ARG BASE=rocm/dev-ubuntu-20.04:5.2
ARG BASE=rocm/dev-ubuntu-20.04:5.4
FROM $BASE

ARG ADDITIONAL_PACKAGES
Expand Down
4 changes: 4 additions & 0 deletions fft/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
add_subdirectory(src)
if(BUILD_TESTING)
add_subdirectory(unit_test)
endif()

if(KokkosFFT_ENABLE_BENCHMARK)
add_subdirectory(perf_test)
endif()
37 changes: 37 additions & 0 deletions fft/perf_test/BenchmarkMain.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
//@HEADER
// ************************************************************************
//
// Kokkos v. 4.0
// Copyright (2022) National Technology & Engineering
// Solutions of Sandia, LLC (NTESS).
//
// Under the terms of Contract DE-NA0003525 with NTESS,
// the U.S. Government retains certain rights in this software.
//
// Part of Kokkos, under the Apache License v2.0 with LLVM Exceptions.
// See https://kokkos.org/LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//@HEADER
*/

#include <benchmark/benchmark.h>

#include "Benchmark_Context.hpp"
#include <Kokkos_Core.hpp>

int main(int argc, char** argv) {
Kokkos::initialize(argc, argv);
{
benchmark::Initialize(&argc, argv);
benchmark::SetDefaultTimeUnit(benchmark::kSecond);
KokkosFFTBenchmark::add_benchmark_context(true);

benchmark::RunSpecifiedBenchmarks();

benchmark::Shutdown();
}
Kokkos::finalize();
return 0;
}
124 changes: 124 additions & 0 deletions fft/perf_test/Benchmark_Context.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
#ifndef KOKKOSFFT_BENCHMARK_CONTEXT_HPP
#define KOKKOSFFT_BENCHMARK_CONTEXT_HPP

#include <cstdlib>
#include <string>

#include <benchmark/benchmark.h>

#include <Kokkos_Core.hpp>
#include "KokkosFFT_PrintConfiguration.hpp"
#include <KokkosFFT_Version_Info.hpp>

namespace KokkosFFTBenchmark {
/// \brief Remove unwanted spaces and colon signs from input string. In case of
/// invalid input it will return an empty string.
inline std::string remove_unwanted_characters(std::string str) {
auto from = str.find_first_not_of(" :");
auto to = str.find_last_not_of(" :");

if (from == std::string::npos || to == std::string::npos) {
return "";
}

// return extracted part of string without unwanted spaces and colon signs
return str.substr(from, to + 1);
}

/// \brief Extract all key:value pairs from kokkos configuration and add it to
/// the benchmark context
inline void add_kokkos_configuration(bool verbose) {
std::ostringstream msg;
Kokkos::print_configuration(msg, verbose);
KokkosFFT::print_configuration(msg);

// Iterate over lines returned from kokkos and extract key:value pairs
std::stringstream ss{msg.str()};
for (std::string line; std::getline(ss, line, '\n');) {
auto found = line.find_first_of(':');
if (found != std::string::npos) {
auto val = remove_unwanted_characters(line.substr(found + 1));
// Ignore line without value, for example a category name
if (!val.empty()) {
benchmark::AddCustomContext(
remove_unwanted_characters(line.substr(0, found)), val);
}
}
}
}

/// \brief Add Kokkos Kernels git info and google benchmark release to
/// benchmark context.
inline void add_version_info() {
using namespace KokkosFFT::Impl;

if (!GIT_BRANCH.empty()) {
benchmark::AddCustomContext("GIT_BRANCH", std::string(GIT_BRANCH));
benchmark::AddCustomContext("GIT_COMMIT_HASH",
std::string(GIT_COMMIT_HASH));
benchmark::AddCustomContext("GIT_CLEAN_STATUS",
std::string(GIT_CLEAN_STATUS));
benchmark::AddCustomContext("GIT_COMMIT_DESCRIPTION",
std::string(GIT_COMMIT_DESCRIPTION));
benchmark::AddCustomContext("GIT_COMMIT_DATE",
std::string(GIT_COMMIT_DATE));
}
if (!BENCHMARK_VERSION.empty()) {
benchmark::AddCustomContext("GOOGLE_BENCHMARK_VERSION",
std::string(BENCHMARK_VERSION));
}
}

inline void add_env_info() {
auto num_threads = std::getenv("OMP_NUM_THREADS");
if (num_threads) {
benchmark::AddCustomContext("OMP_NUM_THREADS", num_threads);
}
auto dynamic = std::getenv("OMP_DYNAMIC");
if (dynamic) {
benchmark::AddCustomContext("OMP_DYNAMIC", dynamic);
}
auto proc_bind = std::getenv("OMP_PROC_BIND");
if (proc_bind) {
benchmark::AddCustomContext("OMP_PROC_BIND", proc_bind);
}
auto places = std::getenv("OMP_PLACES");
if (places) {
benchmark::AddCustomContext("OMP_PLACES", places);
}
}

/// \brief Gather all context information and add it to benchmark context
inline void add_benchmark_context(bool verbose = false) {
add_kokkos_configuration(verbose);
add_version_info();
add_env_info();
}

/**
* \brief Report throughput and amount of data processed for simple View
* operations
*/
template <typename InViewType, typename OutViewType>
void report_results(benchmark::State& state, InViewType in, OutViewType out,
double time) {
// data processed in megabytes
const double in_data_processed =
static_cast<double>(in.size() * sizeof(typename InViewType::value_type)) /
1.0e6;
const double out_data_processed =
static_cast<double>(out.size() *
sizeof(typename OutViewType::value_type)) /
1.0e6;

state.SetIterationTime(time);
state.counters["MB (In)"] = benchmark::Counter(in_data_processed);
state.counters["MB (Out)"] = benchmark::Counter(out_data_processed);
state.counters["GB/s"] =
benchmark::Counter((in_data_processed + out_data_processed) / 1.0e3,
benchmark::Counter::kIsIterationInvariantRate);
}

} // namespace KokkosFFTBenchmark

#endif
Loading

0 comments on commit dd796b1

Please sign in to comment.