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

Bring in multiple hot patches for the library into main #15

Merged
merged 24 commits into from
Mar 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
14efb39
Remove not_null (not used anymore)
Rinzii Mar 9, 2024
6ea7c01
Bring version 0.1.1 into main (#12) (#13)
Rinzii Mar 9, 2024
380ce23
Bring version 0.1.1 into main (#12) (#14)
Rinzii Mar 9, 2024
020d47f
Update bullet points for features of library
Rinzii Mar 11, 2024
5d81723
Remove unused helpers
Rinzii Mar 11, 2024
1d5f1db
add float_t and double_t to monolithic header
Rinzii Mar 11, 2024
8cecf8a
Cleanup and minor adjustments
Rinzii Mar 11, 2024
22df99d
Update sources to remove deleted headers
Rinzii Mar 11, 2024
1896c29
Fix ambiguity bug between float and integer
Rinzii Mar 11, 2024
11925d0
Fix ambiguity issues
Rinzii Mar 11, 2024
07dc8d8
Implement basic benchmarking for log and log2
Rinzii Mar 11, 2024
60469d0
Merge remote-tracking branch 'origin/dev' into dev
Rinzii Mar 11, 2024
c44cd13
Update all test suite to use the monolithic header instead of functio…
Rinzii Mar 12, 2024
a4f2b36
Setup some basic benchmark suites for log and abs
Rinzii Mar 12, 2024
dcca178
Minor cleanup
Rinzii Mar 12, 2024
44b97f3
Add first class support for Intel DPC++
Rinzii Mar 12, 2024
383aff7
Fix small bug with compiler identification
Rinzii Mar 12, 2024
96e6bc2
Add first class support to Nvidia HPC C++
Rinzii Mar 12, 2024
3e3ce75
Having internal issues with detection of NVidia HPC C++. Removing spe…
Rinzii Mar 12, 2024
a7c1720
Add support for Nvidia HPC and remove use of enums.
Rinzii Mar 12, 2024
10374f6
Fix minor bug with NVHPC
Rinzii Mar 12, 2024
022804c
Re-enable static_assert for fpclassify and verify it works with CI
Rinzii Mar 12, 2024
bbf336b
Re-enable static_assert for fpclassify and verify it works with CI
Rinzii Mar 12, 2024
dccc368
Add extra comment to static_assert
Rinzii Mar 12, 2024
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
20 changes: 13 additions & 7 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
cmake_minimum_required(VERSION 3.18)

enable_language(CXX)

set(CCMATH_BUILD_VERSION 0.1.1)
set(INTERNAL_PROJ_DEFAULT_NAME ccmath)

Expand Down Expand Up @@ -33,6 +31,12 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL Clang OR CMAKE_CXX_COMPILER_ID STREQUAL GNU)
target_compile_options(${PROJECT_NAME}-compile-options INTERFACE
-Wall -Wextra -Wpedantic -Wconversion -Werror=return-type
)
# TODO: Remove this later.
# Some variables have been provided but are not currently being used, but it would not atm make sense to remove them.
# So to clean up the warnings we are just silencing these specific cases.
target_compile_options(${PROJECT_NAME}-compile-options INTERFACE
-Wno-unused-but-set-variable -Wno-unused-value
)
endif()

if(CMAKE_CXX_COMPILER_ID STREQUAL MSVC)
Expand All @@ -58,16 +62,18 @@ target_link_libraries(${PROJECT_NAME} INTERFACE
)




configure_file(cmake/version.hpp.in "${CMAKE_CURRENT_BINARY_DIR}/include/${PROJECT_NAME}/version.hpp" @ONLY)

if (CCMATH_BUILD_EXAMPLES OR CCMATH_BUILD_BENCHMARKS OR CCMATH_BUILD_TEST)
add_subdirectory(ext)
endif()

if (CCMATH_BUILD_EXAMPLES)
add_subdirectory(example)
endif()

if (CCMATH_BUILD_EXAMPLES OR CCMATH_BUILD_BENCHMARKS OR CCMATH_BUILD_TEST)
add_subdirectory(ext)
if (CCMATH_BUILD_BENCHMARKS)
add_subdirectory(benchmark)
endif()

if (CCMATH_BUILD_TEST)
Expand All @@ -77,7 +83,7 @@ endif()

if (CCMATH_USE_SIMD)
# TODO: Add a better way to handle enabling simd internally.
add_compile_definitions(INTERNAL_ENABLE_CHECK_FOR_SIMD)
add_compile_definitions(INTERNAL_CCMATH_ENABLE_CHECK_FOR_SIMD)
endif ()


Expand Down
20 changes: 20 additions & 0 deletions CMakePresets.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,26 @@
"CMAKE_CXX_COMPILER": "clang++"
}
},
{
"name": "ninja-intel",
"description": "Build configuration using Ninja Multi-config / clang",
"inherits": "default",
"binaryDir": "${sourceDir}/out/intel",
"cacheVariables": {
"CMAKE_C_COMPILER": "icx",
"CMAKE_CXX_COMPILER": "icx"
}
},
{
"name": "ninja-nvidia-hpc",
"description": "Build configuration using Ninja Multi-config / clang",
"inherits": "default",
"binaryDir": "${sourceDir}/out/nvidia-hpc",
"cacheVariables": {
"CMAKE_C_COMPILER": "nvc",
"CMAKE_CXX_COMPILER": "nvc++"
}
},
{
"name": "ninja-ubsan",
"description": "UBSan build configuration using Ninja Multi-config",
Expand Down
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ ccmath is a C++17 library that provides a re-implementation of the standard `<cm

## Features

- **Full constexpr Compatibility**: All functions provided by ccmath are implemented as `constexpr`, allowing them to be evaluated at compile time when used with constant expressions.
- **Full constexpr Compatibility**: All functions provided by ccmath are implemented as `constexpr` along with an active effort made to ensure all functions work within `static_assert`. The primary goal is to ensure every function can be evaluated at compile time.

- **Standard Math Functions**: ccmath provides a comprehensive set of mathematical functions similar to those in the standard `<cmath>` library, including trigonometric, exponential, logarithmic, and other common mathematical operations. If `<cmath>` has it then it is likely ccmath has implemented it.
- **Dropin Replacement for Standard Math Library**: ccmath provides a comprehensive set of mathematical functions that are 1:1 compatible with the C++ standard library `<cmath>`. The goal of ccmath is to effectively be a drop in replacement for `<cmath>` with little to no discernable difference between the two. This includes trigonometric, exponential, logarithmic, and other common mathematical operations. If `<cmath>` has it then it is likely ccmath has implemented it.

- **Performance Optimization**: By leveraging constexpr, ccmath aims to optimize performance by computing mathematical expressions at compile time when possible, reducing runtime overhead.
- **Performance Optimization**: Past all of the functions being able to be evaluated at compile time, ccmath was also built with speed in mind. We strive to have speeds nearly as fast as the standards implementation.

- **No External Dependencies**: ccmath has no external dependencies and only requires a C++17-compliant compiler.

Expand All @@ -33,7 +33,7 @@ int main() {
ccmath has a comprehensive cmake setup and can be easily included in your project using fetchcontent like so:

```cmake
cmake_minimum_required(VERSION 3.11) # FetchContent is new in version 3.11.
cmake_minimum_required(VERSION 3.18)

include(FetchContent)
FetchContent_Declare(
Expand Down
1 change: 1 addition & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ add_executable(${PROJECT_NAME})
add_executable(${INTERNAL_PROJ_DEFAULT_NAME}::benchmark ALIAS ${PROJECT_NAME})
target_link_libraries(${PROJECT_NAME} PUBLIC
ccmath::ccmath
benchmark::benchmark
)
target_include_directories(${PROJECT_NAME} PUBLIC .)
target_sources(${PROJECT_NAME} PRIVATE
Expand Down
133 changes: 131 additions & 2 deletions benchmark/ccmath_benchmark_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,135 @@
* See LICENSE for more information.
*/

int main(int argc, char** argv)
{
#include <benchmark/benchmark.h>
#include <vector>
#include <random>

#include <cmath>
#include "ccmath/ccmath.hpp"

namespace bm = benchmark;

// Global seed value for random number generator
constexpr unsigned int DefaultSeed = 937162211; // Using a long prime number as our default seed

// Generate a fixed set of random integers for benchmarking
std::vector<int> generateRandomIntegers(size_t count, unsigned int seed) {
std::vector<int> randomIntegers;
std::mt19937 gen(seed);
std::uniform_int_distribution<int> dist(std::numeric_limits<int>::min(), std::numeric_limits<int>::max());
for (size_t i = 0; i < count; ++i) {
randomIntegers.push_back(dist(gen));
}
return randomIntegers;
}

// Generate a fixed set of random integers for benchmarking
std::vector<double> generateRandomDoubles(size_t count, unsigned int seed) {
std::vector<double> randomDouble;
std::mt19937 gen(seed);
std::uniform_real_distribution<double> dist(std::numeric_limits<double>::min(), std::numeric_limits<double>::max());
for (size_t i = 0; i < count; ++i) {
randomDouble.push_back(dist(gen));
}
return randomDouble;
}

// Benchmarking std::abs with the same set of random integers
static void BM_std_abs_rand_int(benchmark::State& state) {
auto randomIntegers = generateRandomIntegers(static_cast<size_t>(state.range(0)), DefaultSeed);
while (state.KeepRunning()) {
for (auto x : randomIntegers) {
benchmark::DoNotOptimize(std::abs(x));
}
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_std_abs_rand_int)->Range(8, 8<<10)->Complexity();

// Benchmarking ccm::abs with the same set of random integers
static void BM_ccm_abs_rand_int(benchmark::State& state) {
auto randomIntegers = generateRandomIntegers(static_cast<size_t>(state.range(0)), DefaultSeed);
while (state.KeepRunning()) {
for (auto x : randomIntegers) {
benchmark::DoNotOptimize(ccm::abs(x));
}
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_ccm_abs_rand_int)->Range(8, 8<<10)->Complexity();

// Benchmarking std::abs with the same set of random integers
static void BM_std_abs_rand_double(benchmark::State& state) {
auto randomIntegers = generateRandomDoubles(static_cast<size_t>(state.range(0)), DefaultSeed);
while (state.KeepRunning()) {
for (auto x : randomIntegers) {
benchmark::DoNotOptimize(std::abs(x));
}
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_std_abs_rand_double)->Range(8, 8<<10)->Complexity();

// Benchmarking ccm::abs with the same set of random integers
static void BM_ccm_abs_rand_double(benchmark::State& state) {
auto randomIntegers = generateRandomDoubles(static_cast<size_t>(state.range(0)), DefaultSeed);
while (state.KeepRunning()) {
for (auto x : randomIntegers) {
benchmark::DoNotOptimize(ccm::abs(x));
}
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_ccm_abs_rand_double)->Range(8, 8<<10)->Complexity();


static void BM_std_abs(benchmark::State& state) {
for (auto _ : state) {
benchmark::DoNotOptimize(std::abs(state.range(0)));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_std_abs)->Arg(16)->Arg(256)->Arg(4096)->Arg(65536)->Complexity();

static void BM_ccm_abs(benchmark::State& state) {
for (auto _ : state) {
benchmark::DoNotOptimize(ccm::abs(state.range(0)));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_ccm_abs)->Arg(16)->Arg(256)->Arg(4096)->Arg(65536)->Complexity();


static void BM_ccm_log(bm::State& state) {
for (auto _ : state) {
bm::DoNotOptimize(ccm::log(state.range(0)));
}
}
BENCHMARK(BM_ccm_log)->Arg(16)->Arg(256)->Arg(4096)->Arg(65536)->Complexity();

static void BM_std_log(bm::State& state) {
for (auto _ : state) {
bm::DoNotOptimize(std::log(state.range(0)));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_std_log)->Arg(16)->Arg(256)->Arg(4096)->Arg(65536)->Complexity();

static void BM_ccm_log2(bm::State& state) {
for (auto _ : state) {
bm::DoNotOptimize(ccm::log2(state.range(0)));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_ccm_log2)->Arg(16)->Arg(256)->Arg(4096)->Arg(65536)->Complexity();

static void BM_std_log2(bm::State& state) {
for (auto _ : state) {
bm::DoNotOptimize(std::log2(state.range(0)));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_std_log2)->Arg(16)->Arg(256)->Arg(4096)->Arg(65536)->Complexity();

BENCHMARK_MAIN();
12 changes: 3 additions & 9 deletions ccmath_headers.cmake
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
set(ccmath_internal_helpers_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/bits.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/endian.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/narrow_cast.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/promote.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/make_mantisa.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/not_null.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/fpclassify_helper.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/pow_integral.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/find_number.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/is_odd.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/exponentiation_helpers.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/bits.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/floating_point_type.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/helpers/fpclassify_helper.hpp
)

set(ccmath_internal_predef_headers
Expand Down
13 changes: 11 additions & 2 deletions cmake/GlobalConfig.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,24 @@ endif()
# - GNUCXX can still be set on macOS when using Clang
if(MSVC)
set(CCMATH_COMPILER_MSVC 1)

# Identify if we are using clang-CL
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CCMATH_COMPILER_CLANG_CL 1)
endif()

elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
set(CCMATH_COMPILER_CLANG 1)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM")
set(CCMATH_COMPILER_INTEL 1)
elseif (CMAKE_CXX_COMPILER_ID MATCHES "NVHPC")
set(CCMATH_COMPILER_NVIDIA_HPC 1)
elseif(CMAKE_COMPILER_IS_GNUCXX)
set(CCMATH_COMPILER_GCC 1)

execute_process(COMMAND "${CMAKE_CXX_COMPILER}" "--version" OUTPUT_VARIABLE GCC_COMPILER_VERSION)
string(REGEX MATCHALL ".*(tdm[64]*-[1-9]).*" CCMATH_COMPILER_GCC_TDM "${GCC_COMPILER_VERSION}")
else()
message(FATAL_ERROR "Unsupported compiler")
message(WARNING "Unsupported compiler: ${CMAKE_CXX_COMPILER_ID}")
return()
endif()

Expand All @@ -55,3 +60,7 @@ else()
message(FATAL_ERROR "Unsupported architecture")
return()
endif()

message(STATUS "CCMake Detected OS: ${CMAKE_SYSTEM_NAME}")
message(STATUS "CCMake Detected Compiler: ${CMAKE_CXX_COMPILER_ID}")
message(STATUS "CCMake Detected Architecture: ${CMAKE_SYSTEM_PROCESSOR}")
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,7 @@
* See LICENSE for more information.
*/

#pragma once

namespace ccm::helpers
int main()
{
template <typename T>
[[nodiscard]]
inline constexpr bool is_odd(T value) noexcept
{
return value % 2 != 0;
}

}
7 changes: 7 additions & 0 deletions example/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,18 @@
* See LICENSE for more information.
*/

#include "ccmath/ccmath.hpp"
#include "iostream"

int main()
{
auto test = ccm::log(1.0);

std::cout << test;

// TODO: Implement actual examples showcasing the library



return 0;
}
27 changes: 26 additions & 1 deletion ext/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,28 @@ project(${INTERNAL_PROJ_DEFAULT_NAME}-ext)

include(FetchContent)


if (CCMATH_BUILD_BENCHMARKS)
# Intel does implement the regex library but google test is unable to detect this.
# Lets help them out and set the var ourselves.
if (CCMATH_COMPILER_INTEL)
set(HAVE_STD_REGEX ON CACHE BOOL "" FORCE)
endif ()
set(BENCHMARK_ENABLE_TESTING NO)
FetchContent_Declare(
benchmark
GIT_REPOSITORY https://github.com/google/benchmark.git
GIT_TAG v1.8.3
)
FetchContent_MakeAvailable(benchmark)
endif ()

if (CCMATH_BUILD_TEST)
# Intel does implement the regex library but google test is unable to detect this.
# Lets help them out and set the var ourselves.
if (CCMATH_COMPILER_INTEL)
set(HAVE_STD_REGEX ON CACHE BOOL "" FORCE)
endif ()

# PThreads are not available on Windows
# So tell gtest to not use them.
if(CCMATH_WINDOWS)
Expand Down Expand Up @@ -42,3 +61,9 @@ if(CCMATH_BUILD_TEST)
)
endif ()

if(CCMATH_BUILD_BENCHMARKS)
target_link_libraries(${PROJECT_NAME} INTERFACE
benchmark::benchmark
)
endif ()

3 changes: 3 additions & 0 deletions include/ccmath/ccmath.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ CCMATH REQUIREMENTS:
* Anything implemented by cmath that is already constexpr is allowed to be wrapped by ccmath and not implemented by ccmath.
*/

// Includes ccm::float_t and ccm::double_t
#include "ccmath/internal/helpers/floating_point_type.hpp"

/// Basic math functions
#include "ccmath/basic.hpp"

Expand Down
Loading
Loading