Skip to content

Commit

Permalink
Bring hot patch version 0.1.2 into main (#18)
Browse files Browse the repository at this point in the history
* Remove not_null (not used anymore)

* Bring version 0.1.1 into main (#12) (#13)

* Add support for builtin detection

* Update comments to be more eye catching

* Add clang-cl and apple clang support

* Fix bug with MSVC where not checking for nan

* Remove msvc specific code in favor of generic approach

* Prepare for 0.1.0 release.

* Add doxygen docs

* Finalize min/max

* Add todo for later work on remquo

* Cleanup main for 0.1.0 release

* Bring standard back to C++17

* Minor cleanup to cmake list

* Prep files for v0.1.0 release

* Prepare for 0.1.0 release.

* Add doxygen docs

* Finalize min/max

* Add todo for later work on remquo

* Cleanup main for 0.1.0 release

* Bring standard back to C++17

* Minor cleanup to cmake list

* Prep files for v0.1.0 release

* Bring everything in

* Remove artifacts that mistakenly got pushed to main

* Implement isgreater

* Implement isgreaterequal

* Implement isless

* Implement islessequal

* Implement islessgreater

* Implement isnormal

* Implement isunordered

* Add test cases for all new compare functions

* Add boilerplate code for future unit tests

* Update progress

* A lot of work done so far on log

* log now far more efficient and accurate

* Update readme progress

* Continue work on log for double

* remove unnecessary include

* remove msvc section of unlikely

* improve variable names

* remove old log impl

* Cleanup double implementation of log

* cleanup of log details and add more comments.

* Finalize work on log function

* Update current progress

* Fix bug with ±0 in log

* Update test cases to cover all major edge cases

* Move to correct folder

* Add headers for log and log2

* Remove dependency on Threads

* Initial addition of Contribution Guide

* Cleanup README and add extra information

* Update project version to v0.1.1

* Add top12 bits function for upcoming work

* Finalize work with log function

* Initial working revision of log2

* Push current work. Need to revise log2 to resolve bugs later.

* Initial implementation of lerp

* Fix scope bug

* remove the direct use of cmath.

* Update include to use cfloat instead of float.h

* Cleanup macros and fix minor bugs

* Fix bug where we were improperly assigning a correct value to the wrong variable

* Update docs to mention not accounting for big-endian

* Add comment to mention we are mirroring impl from cmath

* Remove MSVC fallback that was inconsistent with every other impl

* Add additional helpers for future work

* Add test for static_assert support and some additional tests

* Finalize implementation of log2

* Remove static_assert for now

* Update README.md

* Bring version 0.1.1 into main (#12) (#14)

* Add support for builtin detection

* Update comments to be more eye catching

* Add clang-cl and apple clang support

* Fix bug with MSVC where not checking for nan

* Remove msvc specific code in favor of generic approach

* Prepare for 0.1.0 release.

* Add doxygen docs

* Finalize min/max

* Add todo for later work on remquo

* Cleanup main for 0.1.0 release

* Bring standard back to C++17

* Minor cleanup to cmake list

* Prep files for v0.1.0 release

* Prepare for 0.1.0 release.

* Add doxygen docs

* Finalize min/max

* Add todo for later work on remquo

* Cleanup main for 0.1.0 release

* Bring standard back to C++17

* Minor cleanup to cmake list

* Prep files for v0.1.0 release

* Bring everything in

* Remove artifacts that mistakenly got pushed to main

* Implement isgreater

* Implement isgreaterequal

* Implement isless

* Implement islessequal

* Implement islessgreater

* Implement isnormal

* Implement isunordered

* Add test cases for all new compare functions

* Add boilerplate code for future unit tests

* Update progress

* A lot of work done so far on log

* log now far more efficient and accurate

* Update readme progress

* Continue work on log for double

* remove unnecessary include

* remove msvc section of unlikely

* improve variable names

* remove old log impl

* Cleanup double implementation of log

* cleanup of log details and add more comments.

* Finalize work on log function

* Update current progress

* Fix bug with ±0 in log

* Update test cases to cover all major edge cases

* Move to correct folder

* Add headers for log and log2

* Remove dependency on Threads

* Initial addition of Contribution Guide

* Cleanup README and add extra information

* Update project version to v0.1.1

* Add top12 bits function for upcoming work

* Finalize work with log function

* Initial working revision of log2

* Push current work. Need to revise log2 to resolve bugs later.

* Initial implementation of lerp

* Fix scope bug

* remove the direct use of cmath.

* Update include to use cfloat instead of float.h

* Cleanup macros and fix minor bugs

* Fix bug where we were improperly assigning a correct value to the wrong variable

* Update docs to mention not accounting for big-endian

* Add comment to mention we are mirroring impl from cmath

* Remove MSVC fallback that was inconsistent with every other impl

* Add additional helpers for future work

* Add test for static_assert support and some additional tests

* Finalize implementation of log2

* Remove static_assert for now

* Update README.md

* Update bullet points for features of library

* Remove unused helpers

* add float_t and double_t to monolithic header

* Cleanup and minor adjustments

* Update sources to remove deleted headers

* Fix ambiguity bug between float and integer

* Fix ambiguity issues

* Implement basic benchmarking for log and log2

* Update all test suite to use the monolithic header instead of function specific header.

* Setup some basic benchmark suites for log and abs

* Minor cleanup

* Add first class support for Intel DPC++

* Fix small bug with compiler identification

* Add first class support to Nvidia HPC C++

* Having internal issues with detection of NVidia HPC C++. Removing specific section for now

* Add support for Nvidia HPC and remove use of enums.

* Fix minor bug with NVHPC

* Re-enable static_assert for fpclassify and verify it works with CI

* Re-enable static_assert for fpclassify and verify it works with CI

* Add extra comment to static_assert

* rename the exponent details folder to impl

* Cleanup the example mains

* Finish implementation of remquo

* Cleanup remquo test cases

* Update remquo to better handle specific edge cases

* Remove unused includes

* Temporarily remove problematic test cases.

* Layout some future functions for long double

* Implement copysign

* remove deleted file from headers

* Cleanup code and documentation

* Add last additional functions and documentation

* Cleanup implementation details

* Consolidate code and reduce code fragmentation along with minor refinement of documentation

* Fix missing SetComplexitN

* Minor cleanup

* Update README to reflect updated functions

* Update version number to 0.1.2 for upcoming hot patch
  • Loading branch information
Rinzii authored Mar 14, 2024
1 parent 4793fe2 commit b9dae17
Show file tree
Hide file tree
Showing 25 changed files with 898 additions and 331 deletions.
2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.18)

set(CCMATH_BUILD_VERSION 0.1.1)
set(CCMATH_BUILD_VERSION 0.1.2)
set(INTERNAL_PROJ_DEFAULT_NAME ccmath)

project(${INTERNAL_PROJ_DEFAULT_NAME} VERSION ${CCMATH_BUILD_VERSION})
Expand Down
202 changes: 101 additions & 101 deletions README.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions benchmark/ccmath_benchmark_main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ static void BM_ccm_log(bm::State& state) {
for (auto _ : state) {
bm::DoNotOptimize(ccm::log(state.range(0)));
}
state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_ccm_log)->Arg(16)->Arg(256)->Arg(4096)->Arg(65536)->Complexity();

Expand Down
36 changes: 28 additions & 8 deletions ccmath_headers.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
##########################################
# Internal headers
##########################################

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
Expand Down Expand Up @@ -39,7 +43,18 @@ set(ccmath_internal_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/internal/version.hpp
)


##########################################
# Detail headers
##########################################

set(ccmath_detail_basic_impl_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/basic/impl/remquo_float_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/basic/impl/remquo_double_impl.hpp
)

set(ccmath_detail_basic_headers
${ccmath_detail_basic_impl_headers}
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/basic/abs.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/basic/fdim.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/basic/fma.hpp
Expand All @@ -65,17 +80,17 @@ set(ccmath_detail_compare_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/compare/signbit.hpp
)

set(ccmath_detail_exponential_details_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/details/log_float_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/details/log_double_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/details/log_data.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/details/log2_float_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/details/log2_double_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/details/log2_data.hpp
set(ccmath_detail_exponential_impl_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/impl/log_float_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/impl/log_double_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/impl/log_data.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/impl/log2_float_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/impl/log2_double_impl.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/impl/log2_data.hpp
)

set(ccmath_detail_exponential_headers
${ccmath_detail_exponential_details_headers}
${ccmath_detail_exponential_impl_headers}
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/exp.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/exp2.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/detail/exponential/expm1.hpp
Expand Down Expand Up @@ -175,6 +190,11 @@ set(ccmath_detail_headers
${ccmath_detail_root_headers}
)


##########################################
# Root headers
##########################################

set(ccmath_root_headers
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/basic.hpp
${CMAKE_CURRENT_SOURCE_DIR}/include/ccmath/compare.hpp
Expand Down
1 change: 0 additions & 1 deletion include/ccmath/detail/basic/abs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
#pragma once

#include "ccmath/detail/compare/isnan.hpp"

#include <limits>

namespace ccm
Expand Down
38 changes: 9 additions & 29 deletions include/ccmath/detail/basic/fdim.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,10 @@

#include <limits>
#include <type_traits>

#include "ccmath/detail/compare/isnan.hpp"

namespace ccm
{
/// @cond MATH_DETAIL
namespace
{
namespace impl
{
template <typename T>
inline constexpr T fdim_impl(T x, T y)
{
if constexpr (std::is_floating_point_v<T>)
{
if (ccm::isnan(x)) { return x; }
if (ccm::isnan(y)) { return y; }
}

if (x <= y) { return T(+0.0); }
else if ((y < T(0.0)) && (x > (std::numeric_limits<T>::max() + y))) { return std::numeric_limits<T>::infinity(); }
else { return x - y; }
}

} // namespace impl
} // namespace
/// @endcond

/**
* @brief Computes the positive difference of two floating point values (max(0,x−y))
* @tparam T A floating-point type.
Expand All @@ -48,7 +24,11 @@ namespace ccm
template <typename T, std::enable_if_t<std::is_floating_point<T>::value, int> = 0>
inline constexpr T fdim(T x, T y)
{
return impl::fdim_impl(x, y);
if (ccm::isnan(x)) { return x; }
if (ccm::isnan(y)) { return y; }
if (x <= y) { return T(+0.0); }
else if ((y < T(0.0)) && (x > (std::numeric_limits<T>::max() + y))) { return std::numeric_limits<T>::infinity(); }
else { return x - y; }
}

/**
Expand All @@ -66,7 +46,7 @@ namespace ccm
using shared_type = std::common_type_t<T, U>;

// Convert the arguments to the common type
return fdim(static_cast<shared_type>(x), static_cast<shared_type>(y));
return fdim<shared_type>(static_cast<shared_type>(x), static_cast<shared_type>(y));
}

/**
Expand All @@ -79,7 +59,7 @@ namespace ccm
template <typename Integer, std::enable_if_t<std::is_integral<Integer>::value, int> = 0>
inline constexpr double fdim(Integer x, Integer y)
{
return fdim(static_cast<double>(x), static_cast<double>(y));
return fdim<double>(static_cast<double>(x), static_cast<double>(y));
}

/**
Expand All @@ -90,7 +70,7 @@ namespace ccm
*/
inline constexpr float fdimf(float x, float y)
{
return fdim(x, y);
return fdim<float>(x, y);
}

/**
Expand All @@ -101,7 +81,7 @@ namespace ccm
*/
inline constexpr long double fdiml(long double x, long double y)
{
return fdim(x, y);
return fdim<long double>(x, y);
}
} // namespace ccm

Expand Down
124 changes: 124 additions & 0 deletions include/ccmath/detail/basic/impl/remquo_double_impl.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* Copyright (c) 2024-Present Ian Pike
* Copyright (c) 2024-Present ccmath contributors
*
* This library is provided under the MIT License.
* See LICENSE for more information.
*/

#pragma once

#include <cstdint>
#include <limits>

#include "ccmath/internal/helpers/bits.hpp"
#include "ccmath/internal/predef/unlikely.hpp"
#include "ccmath/detail/basic/abs.hpp"
#include "ccmath/detail/basic/fmod.hpp"

namespace ccm::internal
{
namespace
{
namespace impl
{
inline constexpr double remquo_double_impl(double x, double y, int * quo) noexcept
{
std::int64_t x_i64{};
std::int64_t y_i64{};
std::uint64_t x_sign{};
std::uint64_t quotient_sign{};
int computed_quotient{};

x_i64 = ccm::helpers::double_to_int64(x);
y_i64 = ccm::helpers::double_to_int64(y);

// Determine the signs of x and the quotient.
x_sign = static_cast<std::uint64_t>(x_i64) & 0x8000000000000000ULL;
quotient_sign = x_sign ^ (static_cast<std::uint64_t>(y_i64) & 0x8000000000000000ULL);

// Clear the sign bits from the int64_t representations of x and y.
x_i64 &= 0x7fffffffffffffffULL;
y_i64 &= 0x7fffffffffffffffULL;

// If y is zero.
if (CCM_UNLIKELY(y_i64 == 0)) { return (x * y) / (x * y); }

// If x is not finite or y is NaN.
if (CCM_UNLIKELY(x_i64 >= 0x7ff0000000000000ULL || y_i64 > 0x7ff0000000000000ULL)) { return (x * y) / (x * y); }

// b (or bit 54) represents the highest bit we can compare against for both signed and unsigned integers without causing an overflow.
// Here we are checking that if y_i64 is within the range of signed 64-bit integers that can be represented without setting the MSB (i.e.,
// positive or zero).
if (y_i64 <= 0x7fbfffffffffffffULL)
{
x = ccm::fmod(x, 8 * y); // now x < (8 * y)
}

if (CCM_UNLIKELY(x_i64 == y_i64))
{
*quo = quotient_sign ? -1 : 1;
return 0.0 * x;
}

x = ccm::fabs(x);
y = ccm::helpers::int64_to_double(y_i64);
computed_quotient = 0;

if (y_i64 <= 0x7fcfffffffffffffULL && x >= 4 * y)
{
x -= 4 * y;
computed_quotient += 4;
}

if (y_i64 <= 0x7fdfffffffffffffULL && x >= 2 * y)
{
x -= 2 * y;
computed_quotient += 2;
}

if (y_i64 < 0x0020000000000000ULL)
{
if (x + x > y)
{
x -= y;
++computed_quotient;
if (x + x >= y)
{
x -= y;
++computed_quotient;
}
}
}
else
{
double y_half = 0.5 * y;
if (x > y_half)
{
x -= y;
++computed_quotient;
if (x >= y_half)
{
x -= y;
++computed_quotient;
}
}
}

*quo = quotient_sign ? -computed_quotient : computed_quotient;

// Make sure that the correct sign of zero results in round down mode.
if (x == 0.0) { x = 0.0; }
if (x_sign) { x = -x; }

return x;
}
} // namespace impl
} // namespace

template <typename T, typename = std::enable_if_t<std::is_floating_point_v<T>>>
inline constexpr T remquo_double(T x, T y, int * quo) noexcept
{
return static_cast<T>(impl::remquo_double_impl(x, y, quo));
}
} // namespace ccm::internal
Loading

0 comments on commit b9dae17

Please sign in to comment.