Skip to content

Commit

Permalink
Add a trivial benchmark
Browse files Browse the repository at this point in the history
  • Loading branch information
Yuuichi Asahi committed Jan 31, 2024
1 parent 9f4f8e3 commit 131eca1
Show file tree
Hide file tree
Showing 8 changed files with 584 additions and 0 deletions.
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;
}
121 changes: 121 additions & 0 deletions fft/perf_test/Benchmark_Context.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
#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
71 changes: 71 additions & 0 deletions fft/perf_test/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
function(KOKKOSFFT_ADD_BENCHMARK name)
CMAKE_PARSE_ARGUMENTS(
BENCHMARK
""
""
"SOURCES"
${ARGN}
)

if(DEFINED BENCHMARK_UNPARSED_ARGUMENTS)
message(
WARNING
"Unexpected arguments when adding a benchmark: "
${BENCHMARK_UNPARSED_ARGUMENTS}
)
endif()

set(BENCHMARK_NAME ${PACKAGE_NAME}_${name})

#Adding BenchmarkMain.cpp to sources
list(APPEND BENCHMARK_SOURCES
BenchmarkMain.cpp
)

add_executable(
${BENCHMARK_NAME}
${BENCHMARK_SOURCES}
)
target_link_libraries(
${BENCHMARK_NAME}
PRIVATE benchmark::benchmark Kokkos::kokkos KokkosFFT::fft
)
target_include_directories(
${BENCHMARK_NAME}
SYSTEM PRIVATE ${benchmark_SOURCE_DIR}/include
)
target_include_directories(
${BENCHMARK_NAME}
PRIVATE ${CMAKE_BINARY_DIR}
)

foreach(SOURCE_FILE ${BENCHMARK_SOURCES})
SET_SOURCE_FILES_PROPERTIES(
${SOURCE_FILE}
PROPERTIES LANGUAGE CXX
)
endforeach()

string(TIMESTAMP BENCHMARK_TIME "%Y-%m-%d_T%H-%M-%S" UTC)
set(
BENCHMARK_ARGS
--benchmark_counters_tabular=true
--benchmark_out=${BENCHMARK_NAME}_${BENCHMARK_TIME}.json
)

add_test(
NAME ${BENCHMARK_NAME}
COMMAND ${BENCHMARK_NAME} ${BENCHMARK_ARGS}
)
endfunction()

# Set benchmark targets
set(
BENCHMARK_SOURCES
PerfTest_FFT1.cpp
)

KOKKOSFFT_ADD_BENCHMARK(
PerformanceTest_Benchmark
SOURCES ${BENCHMARK_SOURCES}
)
85 changes: 85 additions & 0 deletions fft/perf_test/KokkosFFT_PrintConfiguration.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//@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_PRINT_CONFIGURATION_HPP
#define KOKKOSFFT_PRINT_CONFIGURATION_HPP

#include "KokkosFFT_config.h"
#include "KokkosFFT_TplsVersion.hpp"
#include <iostream>

namespace KokkosFFT {
namespace Impl {

inline void print_cufft_version_if_enabled(std::ostream& os) {
#if defined(KOKKOSFFT_ENABLE_TPL_CUFFT)
os << " "
<< "KOKKOSFFT_ENABLE_TPL_CUFFT: " << cufft_version_string() << "\n";
#else
os << " "
<< "KOKKOSFFT_ENABLE_TPL_CUFFT: no\n";
#endif
}

inline void print_enabled_tpls(std::ostream& os) {
#ifdef KOKKOSFFT_ENABLE_TPL_FFTW
os << " "
<< "KOKKOSFFT_ENABLE_TPL_FFTW: yes\n";
#else
os << " "
<< "KOKKOSFFT_ENABLE_TPL_FFTW: no\n";
#endif

print_cufft_version_if_enabled(os);

#ifdef KOKKOSFFT_ENABLE_TPL_HIPFFT
os << " "
<< "KOKKOSFFT_ENABLE_TPL_HIPFFT: yes\n";
#else
os << " "
<< "KOKKOSFFT_ENABLE_TPL_HIPFFT: no\n";
#endif

#ifdef KOKKOSFFT_ENABLE_TPL_ONEMKL
os << " "
<< "KOKKOSFFT_ENABLE_TPL_ONEMKL: yes\n";
#else
os << " "
<< "KOKKOSFFT_ENABLE_TPL_ONEMKL: no\n";
#endif
}


inline void print_version(std::ostream& os) {

// KOKKOSFFT_VERSION is used because MAJOR, MINOR and PATCH macros
// are not available in FFT
os << " "
<< "KokkosFFT Version: " << KOKKOSFFT_VERSION_MAJOR << "."
<< KOKKOSFFT_VERSION_MINOR << "." << KOKKOSFFT_VERSION_PATCH
<< '\n';
}
} // namespace Impl

inline void print_configuration(std::ostream& os) {
Impl::print_version(os);

os << "TPLs: \n";
Impl::print_enabled_tpls(os);
}

} // namespace KokkosFFT

#endif
40 changes: 40 additions & 0 deletions fft/perf_test/KokkosFFT_TplsVersion.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
//@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_TPLS_VERSIONS_HPP
#define KOKKOSFFT_TPLS_VERSIONS_HPP

#include "KokkosFFT_config.h"
#include <sstream>
#include <iostream>

#if defined(KOKKOSFFT_ENABLE_TPL_CUFFT)
#include "cufft.h"
#endif

namespace KokkosFFT {
#if defined(KOKKOSFFT_ENABLE_TPL_CUFFT)
inline std::string cufft_version_string() {
// Print version
std::stringstream ss;

ss << CUFFT_VER_MAJOR << "." << CUFFT_VER_MINOR << "." << CUFFT_VER_PATCH;

return ss.str();
}
#endif

} // namespace KokkosFFT
#endif
Loading

0 comments on commit 131eca1

Please sign in to comment.