Skip to content

Commit

Permalink
Merge branch 'v3.69' of https://github.com/stillwater-sc/universal in…
Browse files Browse the repository at this point in the history
…to v3.69
  • Loading branch information
Ravenwater committed Apr 23, 2023
2 parents bdbd140 + 9fef1df commit 396a998
Show file tree
Hide file tree
Showing 14 changed files with 63 additions and 83 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"image": "stillwater/universal:clang11builder"
"image": "stillwater/universal:clang14builder"
}
6 changes: 3 additions & 3 deletions benchmark/error/blas/dot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ void TraceProducts(const sw::universal::blas::vector<Scalar>& x, const sw::unive
auto nrSamples = size(x);
Scalar minInput = abs(x[0]);
Scalar maxInput = minInput;
Scalar minOutput = minInput;
Scalar maxOutput = maxInput;
// Scalar minOutput = minInput;
// Scalar maxOutput = maxInput;
Scalar minProduct = abs(x[0] * y[0]);
Scalar maxProduct = minProduct;
for (unsigned i = 1; i < nrSamples; ++i) {
Expand All @@ -41,9 +41,9 @@ void TraceProducts(const sw::universal::blas::vector<Scalar>& x, const sw::unive

template<typename Scalar, bool verbose = false>
void DotProductError(const sw::universal::blas::vector<double>& x, const sw::universal::blas::vector<double>& y) {
std::cout << "\nScalar type : " << typeid(Scalar).name() << '\n';
using std::log;
using namespace sw::universal;
std::cout << "\nScalar type : " << type_tag(Scalar()) << '\n';

auto nrSamples = size(x);
blas::vector<Scalar> xx(nrSamples);
Expand Down
2 changes: 1 addition & 1 deletion include/universal/internal/f2s/f2s.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ namespace sw {

template<typename UnsignedInt>
void GetCachedPowerForBinaryExponentRange(const int min_exponent, const int max_exponent, f2s<UnsignedInt>& power, int& decimal_exponent) {
using F2S = f2s<UnsignedInt>;
//using F2S = f2s<UnsignedInt>;
int kQ = sizeof(UnsignedInt) * 4;
double k = std::ceil((min_exponent + kQ - 1) * kD_1_LOG2_10);
int index = (kCachedPowersOffset + static_cast<int>(k) - 1) / kDecimalExponentDistance + 1;
Expand Down
2 changes: 2 additions & 0 deletions include/universal/native/ieee754.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#include <limits>
#include <tuple>
// configure the low level compiler interface to deal with floating-point bit manipulation
#include <universal/utility/architecture.hpp>
#include <universal/utility/compiler.hpp>
#include <universal/utility/bit_cast.hpp>
#include <universal/utility/long_double.hpp>
// support functions
Expand Down
14 changes: 7 additions & 7 deletions include/universal/native/manipulators.hpp
Original file line number Diff line number Diff line change
@@ -1,31 +1,31 @@
#pragma once
// manipulators.hpp: definition of manipulation functions for native types
//
// Copyright (C) 2017-2022 Stillwater Supercomputing, Inc.
// Copyright (C) 2017-2023 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <string>

namespace sw { namespace universal {

template<typename IntegralType,
std::enable_if_t< std::is_integral<IntegralType>::value, bool> = true
std::enable_if_t< ::std::is_integral<IntegralType>::value, bool> = true
>
std::string type_tag(IntegralType = {}) {
// can't use a simple typeid(Real).name() because gcc and clang obfuscate the native types
constexpr unsigned nbits = sizeof(IntegralType) * 8;
std::string type_string;
if constexpr (nbits == 8) {
type_string = std::string("char");
type_string = ::std::is_signed<IntegralType>::value ? std::string("int8_t") : std::string("uint8_t");
}
else if constexpr (nbits == 16) {
type_string = std::string("short");
type_string = ::std::is_signed<IntegralType>::value ? std::string("int16_t") : std::string("uint16_t");
}
else if constexpr (nbits == 32) {
type_string = std::string("long");
type_string = ::std::is_signed<IntegralType>::value ? std::string("int32_t") : std::string("uint32_t");
}
else if constexpr (nbits == 64) {
type_string = std::string("long long");
type_string = ::std::is_signed<IntegralType>::value ? std::string("int64_t") : std::string("uint64_t");
}
else {
type_string = std::string("unknown");
Expand All @@ -34,7 +34,7 @@ namespace sw { namespace universal {
}

template<typename RealType,
std::enable_if_t< std::is_floating_point<RealType>::value, bool> = true
std::enable_if_t< ::std::is_floating_point<RealType>::value, bool> = true
>
std::string type_tag(RealType = {}) {
// can't use a simple typeid(Real).name() because gcc and clang obfuscate the native types
Expand Down
2 changes: 1 addition & 1 deletion include/universal/number/cfloat/manipulators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ std::string type_tag(const cfloat<nbits, es, bt, hasSubnormals, hasSupernormals,
s << "cfloat<"
<< std::setw(3) << nbits << ", "
<< std::setw(3) << es << ", "
<< typeid(bt).name() << ", "
<< type_tag(bt()) << ", "
<< (hasSubnormals ? "hasSubnormals, " : " noSubnormals, ")
<< (hasSupernormals ? "hasSupernormals, " : " noSupernormals, ")
<< (isSaturating ? " Saturating>" : "notSaturating>");
Expand Down
3 changes: 2 additions & 1 deletion include/universal/number/lns/manipulators.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,11 @@ namespace sw { namespace universal {
>
inline std::string type_tag(const LnsType & = {}) {
std::stringstream s;
typename LnsType::BlockType bt{0};
s << "lns<"
<< std::setw(3) << LnsType::nbits << ", "
<< std::setw(3) << LnsType::rbits << ", "
<< typeid(typename LnsType::BlockType).name() << ", "
<< type_tag(bt) << ", "
<< std::setw(10) << type_tag(Behavior{ LnsType::behavior }) << '>';
return s.str();
}
Expand Down
2 changes: 1 addition & 1 deletion include/universal/utility/compiler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace sw { namespace universal {

void report_compiler() {
inline void report_compiler() {
#if defined(_MSC_VER) && (_MSC_VER >= 1300)
std::cout << "Microsoft Visual C++: " << _MSC_VER << '\n';
if constexpr (_MSC_VER == 1600) std::cout << "(Visual Studio 2010 version 10.0)\n";
Expand Down
10 changes: 5 additions & 5 deletions internal/f2s/api/api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,15 +71,15 @@ namespace sw {
// In fact: scaled_w - w*10^k < 1ulp (unit in the last place) of scaled_w.
// In other words: let f = scaled_w.f() and e = scaled_w.e(), then
// (f-1) * 2^e < w*10^k < (f+1) * 2^e
F2S scaled_w = (w * ten_mk);
assert(scaled_w.e() == boundary_plus.e() + ten_mk.e() + precision);
//F2S scaled_w = (w * ten_mk);
//assert(scaled_w.e() == boundary_plus.e() + ten_mk.e() + precision);
// In theory it would be possible to avoid some recomputations by computing
// the difference between w and boundary_minus/plus (a power of 2) and to
// compute scaled_boundary_minus/plus by subtracting/adding from
// scaled_w. However the code becomes much less readable and the speed
// enhancements are not terrific.
F2S scaled_boundary_minus = boundary_minus * ten_mk;
F2S scaled_boundary_plus = boundary_plus * ten_mk;
//F2S scaled_boundary_minus = boundary_minus * ten_mk;
//F2S scaled_boundary_plus = boundary_plus * ten_mk;

// DigitGen will generate the digits of scaled_w. Therefore we have
// v == (double) (scaled_w * 10^-mk).
Expand Down Expand Up @@ -188,7 +188,7 @@ try {
char buffer[128];
int nrOfDigits{ 0 };
int decimalExponent{ 0 };
bool success = Grisu3(1.0, buffer, nrOfDigits, decimalExponent) << '\n';
bool success = Grisu3(1.0, buffer, nrOfDigits, decimalExponent);
if (success) {
std::cout << std::string(buffer) << '\n';
}
Expand Down
8 changes: 4 additions & 4 deletions static/lns/arithmetic/addition.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// addition.cpp: test suite runner for addition arithmetic on fixed-sized, arbitrary precision logarithmic number system
//
// Copyright (C) 2017-2022 Stillwater Supercomputing, Inc.
// Copyright (C) 2017-2023 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <universal/utility/directives.hpp>
Expand All @@ -19,9 +19,9 @@ namespace sw { namespace universal {
template<typename LnsType>
int VerifyAddition(bool reportTestCases) {
constexpr size_t nbits = LnsType::nbits;
constexpr size_t rbits = LnsType::rbits;
constexpr Behavior behavior = LnsType::behavior;
using bt = typename LnsType::BlockType;
//constexpr size_t rbits = LnsType::rbits;
//constexpr Behavior behavior = LnsType::behavior;
//using bt = typename LnsType::BlockType;
constexpr size_t NR_ENCODINGS = (1ull << nbits);

int nrOfFailedTestCases = 0;
Expand Down
8 changes: 4 additions & 4 deletions static/lns/arithmetic/division.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// division.cpp: test suite runner for division arithmetic of fixed-sized, arbitrary precision logarithmic number system
//
// Copyright (C) 2017-2022 Stillwater Supercomputing, Inc.
// Copyright (C) 2017-2023 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <universal/utility/directives.hpp>
Expand All @@ -18,9 +18,9 @@ namespace sw { namespace universal {
template<typename LnsType>
int VerifyDivision(bool reportTestCases) {
constexpr size_t nbits = LnsType::nbits;
constexpr size_t rbits = LnsType::rbits;
constexpr Behavior behavior = LnsType::behavior;
using bt = typename LnsType::BlockType;
//constexpr size_t rbits = LnsType::rbits;
//constexpr Behavior behavior = LnsType::behavior;
//using bt = typename LnsType::BlockType;
constexpr size_t NR_ENCODINGS = (1ull << nbits);

int nrOfFailedTestCases = 0;
Expand Down
8 changes: 4 additions & 4 deletions static/lns/arithmetic/multiplication.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// multiplication.cpp: test suite runner for multiplication arithmetic of fixed-sized, arbitrary precision logarithmic number system
//
// Copyright (C) 2017-2022 Stillwater Supercomputing, Inc.
// Copyright (C) 2017-2023 Stillwater Supercomputing, Inc.
//
// This file is part of the universal numbers project, which is released under an MIT Open Source license.
#include <universal/utility/directives.hpp>
Expand All @@ -18,9 +18,9 @@ namespace sw { namespace universal {
template<typename LnsType>
int VerifyMultiplication(bool reportTestCases) {
constexpr size_t nbits = LnsType::nbits;
constexpr size_t rbits = LnsType::rbits;
constexpr Behavior behavior = LnsType::behavior;
using bt = typename LnsType::BlockType;
//constexpr size_t rbits = LnsType::rbits;
//constexpr Behavior behavior = LnsType::behavior;
//using bt = typename LnsType::BlockType;
constexpr size_t NR_ENCODINGS = (1ull << nbits);

int nrOfFailedTestCases = 0;
Expand Down
6 changes: 3 additions & 3 deletions static/lns/arithmetic/subtraction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ namespace sw { namespace universal {
template<typename LnsType>
int VerifySubtraction(bool reportTestCases) {
constexpr size_t nbits = LnsType::nbits;
constexpr size_t rbits = LnsType::rbits;
constexpr Behavior behavior = LnsType::behavior;
using bt = typename LnsType::BlockType;
//constexpr size_t rbits = LnsType::rbits;
//constexpr Behavior behavior = LnsType::behavior;
//using bt = typename LnsType::BlockType;
constexpr size_t NR_ENCODINGS = (1ull << nbits);

int nrOfFailedTestCases = 0;
Expand Down
73 changes: 25 additions & 48 deletions static/native/float/bit_manipulation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,23 @@ namespace sw { namespace universal {

template<typename Real,
typename = typename std::enable_if< std::is_floating_point<Real>::value, Real >::type>
int VerifyFloatFieldExtraction(bool reportTestCases) {
int VerifyRealFieldExtraction(bool reportTestCases) {
using namespace sw::universal;

constexpr unsigned fbits = ieee754_parameter<Real>::fbits;

int nrOfFailedTests = 0;

bool sign{ false };
std::uint64_t rawExponent{ 0 };
int exponent{ 0 };
std::uint64_t rawFraction{ 0 };
int fbits{ 64 };


Real a;
a = 1.0;
std::cout << to_binary(a) << " : " << a << '\n';
ReportValue(a);

if constexpr (sizeof(Real) == 4) {
fbits = 23;
}
else if constexpr (sizeof(Real) == 8) {
fbits = 52;
}
else if constexpr (sizeof(Real) == 16) {
fbits = 64;
}
extractFields(a, sign, rawExponent, rawFraction);
exponent = static_cast<int>(rawExponent) - ieee754_parameter<Real>::bias;
if (sign != false || exponent != 0 || rawFraction != 0) {
Expand All @@ -50,33 +45,6 @@ namespace sw { namespace universal {

} } // namespace sw::universal

union float_decoder {
float_decoder() : f{ 0.0f } {}
float_decoder(float _f) : f{ _f } {}
float f;
struct {
uint32_t fraction : 23;
uint32_t exponent : 8;
uint32_t sign : 1;
} parts;
};

template<typename Integer,
typename = typename std::enable_if< std::is_integral<Integer>::value, Integer >::type
>
inline std::string to_binary(const Integer& number, int nbits = 0, bool bNibbleMarker = true) {
std::stringstream s;
if (nbits == 0) nbits = 8 * sizeof(number);
s << 'b';
uint64_t mask = (uint64_t(1) << (nbits - 1));
for (int i = int(nbits) - 1; i >= 0; --i) {
s << ((number & mask) ? '1' : '0');
if (bNibbleMarker && i > 0 && i % 4 == 0) s << '\'';
mask >>= 1;
}
return s.str();
}

// Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is an override
#define MANUAL_TESTING 0
// REGRESSION_LEVEL_OVERRIDE is set by the cmake file to drive a specific regression intensity
Expand All @@ -99,7 +67,7 @@ try {

std::string test_suite = "native IEEE-754 bit manipulation verification";
std::string test_tag = "floating-point field extraction";
bool reportTestCases = false;
bool reportTestCases = true;
int nrOfFailedTestCases = 0;

ReportTestSuiteHeader(test_suite, reportTestCases);
Expand All @@ -114,22 +82,31 @@ try {
decoder.parts.sign = 0b1;

std::cout << decoder.f << '\n';
#ifdef BIT_CAST_SUPPORT
uint32_t bc = std::bit_cast<uint32_t, float>(decoder.f);

uint32_t bc = sw::bit_cast<uint32_t, float>(decoder.f);
std::cout << to_binary(bc, 32) << '\n';
#endif

nrOfFailedTestCases += ReportTestResult(VerifyFloatFieldExtraction<float>(reportTestCases), "float", test_tag);

float f{1.0f};
std::cout << "size of float : " << sizeof(f) << '\n';
ReportValue(f);
double d{1.0};
std::cout << "size of double : " << sizeof(d) << '\n';
ReportValue(d);
long double ld{1.0l};
std::cout << "size of long double : " << sizeof(ld) << '\n';
ReportValue(ld);

nrOfFailedTestCases += ReportTestResult(VerifyRealFieldExtraction<float>(reportTestCases), "float", test_tag);

ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
return EXIT_SUCCESS; // ignore failures
#else

#if REGRESSION_LEVEL_1
nrOfFailedTestCases += ReportTestResult(VerifyFloatFieldExtraction<float>(reportTestCases), "float", test_tag);
nrOfFailedTestCases += ReportTestResult(VerifyFloatFieldExtraction<double>(reportTestCases), "double", test_tag);
nrOfFailedTestCases += ReportTestResult(VerifyRealFieldExtraction<float>(reportTestCases), "float", test_tag);
nrOfFailedTestCases += ReportTestResult(VerifyRealFieldExtraction<double>(reportTestCases), "double", test_tag);
#if LONG_DOUBLE_SUPPORT
nrOfFailedTestCases += ReportTestResult(VerifyFloatFieldExtraction<long double>(reportTestCases), "long double", test_tag);
nrOfFailedTestCases += ReportTestResult(VerifyRealFieldExtraction<long double>(reportTestCases), "long double", test_tag);
#endif

#endif
Expand Down

0 comments on commit 396a998

Please sign in to comment.