Skip to content

Commit

Permalink
WIP: fixed bugs in regime and exponent fields for fast posit<16,2>, r…
Browse files Browse the repository at this point in the history
…ounding still buggy
  • Loading branch information
Ravenwater committed Dec 31, 2023
1 parent 8c395c5 commit 40a475a
Show file tree
Hide file tree
Showing 4 changed files with 123 additions and 203 deletions.
37 changes: 27 additions & 10 deletions include/universal/number/posit/specialized/posit_16_2.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,28 +380,35 @@ class posit<NBITS_IS_16, ES_IS_2> {
uint16_t remaining{ 0 }; // Remaining bits after the regime: 0<remaining_bits>0..0
decode_regime(lhs, m, remaining);

//std::cout << "lhs m : " << int(m) << '\n';

// extract the exponent
int16_t exp = (remaining >> 13); // 16 - 1(sign) - 2(exponent)
//std::cout << "lhs exp : " << exp << '\n';

// extract remaining fraction bits
uint16_t lhs_fraction = (0x4000 | remaining << 1) & 0x7FFF; // 0x4000 is the hidden bit
uint32_t fraction = (uint32_t) lhs_fraction << 14;
//std::cout << "fraction : " << to_binary(fraction, 32, true) << '\n';

// adjust shift and extract fraction bits of rhs
extractDividand(rhs, m, remaining);
uint16_t rhsExp = (remaining >> 13);

std::cout << to_binary(*this, true) << " : exp " << exp << '\n';
std::cout << to_binary(b, true) << " : exp " << rhsExp << '\n';
std::cout << "m : " << int(m) << '\n';

//uint16_t rhsExp = (remaining >> 13);
exp -= (remaining >> 13);
//std::cout << "result m : " << int(m) << '\n';
//std::cout << "rhs exp : " << rhsExp << '\n';
//std::cout << "final exp : " << exp << '\n';

uint16_t rhs_fraction = (0x4000 | remaining << 1) & 0x7FFF; // 0x4000 is the hidden bit
//std::cout << "lhs frac : " << to_binary(lhs_fraction, 16, true) << '\n';
//std::cout << "rhs frac : " << to_binary(rhs_fraction, 16, true) << '\n';

div_t result = div(fraction, rhs_fraction);
uint32_t result_fraction = result.quot;
uint32_t remainder = result.rem;

//std::cout << "result : " << to_binary(result_fraction, 32, true) << '\n';

// adjust the exponent if needed
if (exp < 0) {
exp += 4;
Expand Down Expand Up @@ -849,14 +856,16 @@ class posit<NBITS_IS_16, ES_IS_2> {
}

if (reglen > 14) {
bits = (m < 0 ? 0x0001 : 0x7FFF); // minpos and maxpos
bits = (m<0 ? 0x0001 : 0x7FFF); // minpos and maxpos
}
else {
fraction &= 0x3FFF; // remove both carry bits
uint16_t final_fbits = uint16_t(fraction >> (reglen + 2));
bool bitNPlusOne = false;
if (reglen != 14) {
bitNPlusOne = bool((fraction >> reglen) & 0x1);
//std::cout << "fraction : " << to_binary(fraction, 16, true) << '\n';
//std::cout << "nplusone : " << to_binary((fraction >> (reglen - 1)), 16, true) << '\n';
bitNPlusOne = bool((fraction >> (reglen - 1)) & 0x1);
}
else if (final_fbits > 0) {
final_fbits = 0;
Expand All @@ -866,11 +875,19 @@ class posit<NBITS_IS_16, ES_IS_2> {
exp = 0;
}
else {
exp <<= (13 - reglen);
exp <<= (12 - reglen);
}
bits = uint16_t(regime) + uint16_t(exp) + uint16_t(final_fbits);
//std::cout << "regime : " << to_binary(regime, 16, true) << '\n';
//std::cout << "exponent : " << to_binary(exp, 16, true) << '\n';
//std::cout << "fraction : " << to_binary(final_fbits, 16, true) << '\n';
bits = uint16_t(regime) | uint16_t(exp) | uint16_t(final_fbits);
//std::cout << "bits : " << to_binary(bits, 16, true) << '\n';

if (bitNPlusOne) {
//uint16_t more = (fraction & ((1 << reglen) - 1));
//std::cout << "morebits : " << to_binary(more, 16, true) << '\n';
//uint16_t mask = ((1 << reglen) - 1);
//std::cout << "mask : " << to_binary(mask, 16, true) << '\n';
uint16_t moreBits = (fraction & ((1 << reglen) - 1)) ? 0x0001 : 0x0000;
if (nonZeroRemainder) moreBits = 0x0001;
// n+1 frac bit is 1. Need to check if another bit is 1 too, if not round to even
Expand Down
4 changes: 3 additions & 1 deletion include/universal/verification/posit_test_randoms.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,9 +334,11 @@ namespace sw { namespace universal {
case OPCODE_ASINH:
case OPCODE_ACOSH:
case OPCODE_ATANH:
// valid unary function
break;
// two operand elementary functions
case OPCODE_POW:
std::cerr << "Unsupported binary operator, test cancelled\n";
std::cerr << "Unsupported binary function, test cancelled\n";
return 1;
}
// generate the full state space set of valid posit values
Expand Down
135 changes: 50 additions & 85 deletions static/posit/specialized/posit_16_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@
#include <universal/verification/posit_test_suite.hpp>
#endif

void TestWithValues(double av, double bv) {
using namespace sw::universal;
posit<16, 2> a, b, c;
a = av;
b = bv;
c = a / b;
ReportBinaryOperation(a, "/", b, c);
double da = double(a);
double db = double(b);
double dc = da / db;
// ReportBinaryOperation(da, "/", db, dc);
posit<16, 2> ref(dc);
ReportBinaryOperation(a, "/", b, ref);
if (c != ref) std::cout << "FAIL\n";
}

// Standard posit with nbits = 16 have es = 2 exponent bit.

// Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is an override
Expand Down Expand Up @@ -54,7 +70,7 @@ try {
#endif

std::string test_tag = "arithmetic type tests";
bool reportTestCases = true;
bool reportTestCases = false;
int nrOfFailedTestCases = 0;

ReportTestSuiteHeader(test_suite, reportTestCases);
Expand All @@ -67,98 +83,47 @@ try {
std::string tag = type_tag(p);

#if MANUAL_TESTING
/*
a : 0b0.10.01.00000000000 : 2
b : 0b0.10.00.00000000000 : 1 +
c : 0b0.10.01.10000000000 : 3
a : 0b0.10.1.000000000000 : 2
b : 0b0.10.0.000000000000 : 1 +
c : 0b0.10.1.100000000000 : 3
*/

posit<16, 2> a, b, c, cref;
float fa, fb, fc;

{

a.maxpos();
uint64_t i64 = uint64_t(a);
std::cout << "posit<16,2> : " << i64 << " : " << a << " : " << to_binary(a) << '\n';
std::cout << std::setw(25) << "maxpos" << " : " << to_binary(i64, 64, true) << " : " << i64 << '\n';
i64 /= 2;
std::cout << std::setw(25) << "half maxpos" << " : " << to_binary(i64, 64, true) << " : " << i64 << '\n';

/*
FAIL
-1232 / -1.5916157281026244164e-12 != 281474976710656 golden reference is 1125899906842624
0b1.1110.10.001101000 / 0b1.00000000001.00.11 != 0b0.11111111111110.0. golden reference is 0b0.11111111111110.1.
*/
a.setbits(0x0001);
//b.setbits(0xCFFF); // 0b1.10.0'1.111'1111'1111
b.setbits(0x809F); // 0b1000'0000'1001'1111
a = -1232;
std::cout << a << '\n';
b = -1.5916157281026244164e-12;
c = a - b;
fa = float(a);
fb = float(b);
fc = fa - fb;
cref = fc;
std::cout
<< std::setw(NUMBER_COLUMN_WIDTH) << a << " - "
<< std::setw(NUMBER_COLUMN_WIDTH) << b << " = "
<< std::setw(NUMBER_COLUMN_WIDTH) << c << '\n';
std::cout
<< std::setw(NUMBER_COLUMN_WIDTH) << fa << " - "
<< std::setw(NUMBER_COLUMN_WIDTH) << fb << " = "
<< std::setw(NUMBER_COLUMN_WIDTH) << fc << '\n';
std::cout
<< std::setw(NUMBER_COLUMN_WIDTH) << to_binary(fa) << " - "
<< std::setw(NUMBER_COLUMN_WIDTH) << to_binary(fb) << " = "
<< std::setw(NUMBER_COLUMN_WIDTH) << to_binary(fc) << '\n';

Compare(c, cref, fc, true);
ReportBinaryOperation(a, "-", b, c);
ReportBinaryArithmeticError("bla", "-", a, b, c, cref);
}
return 0;
std::cout << "Manual exhaustive div" << std::endl;
nrOfFailedTestCases += ReportTestResult(VerifyDivision<nbits, es>(reportTestCases), tag, "div (native) ");
std::cout << "Manual exhaustive mul" << std::endl;
nrOfFailedTestCases += ReportTestResult(VerifyMultiplication<nbits, es>(reportTestCases), tag, "mul (native) ");
std::cout << "Manual exhaustive sub" << std::endl;
nrOfFailedTestCases += ReportTestResult(VerifySubtraction<nbits, es>(reportTestCases), tag, "sub (native) ");
std::cout << "Manual exhaustive add" << std::endl;
nrOfFailedTestCases += ReportTestResult(VerifyAddition<nbits, es>(reportTestCases), tag, "add (native) ");

nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(reportTestCases, OPCODE_IPA, 100), tag, "+= (native) ");
nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(reportTestCases, OPCODE_IPS, 100), tag, "-= (native) ");
nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(reportTestCases, OPCODE_IPM, 100), tag, "*= (native) ");
nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(reportTestCases, OPCODE_IPD, 100), tag, "/= (native) ");
nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(true, OPCODE_IPD, 100), tag, "/= (native) ");

a.setnar(); b.setnar();
testLogicOperators(a, b);
a = +1; b = +1; --b;
testLogicOperators(a, b);
a = +1; b = +1; ++b;
testLogicOperators(a, b);
a = -1; b = -1; --b;
testLogicOperators(a, b);
a = -1; b = -1; ++b;
testLogicOperators(a, b);
TestWithValues(1.1368683772161602974e-13, 8.5265128291212022305e-14);
goto epilog;

a.setbits(0xfffd); b.setbits(0xfffe);
testLogicOperators(a, b);
std::cout << "Exhaustive tests" << std::endl;
nrOfFailedTestCases += ReportTestResult(VerifyDivision <nbits, es>(reportTestCases), tag, "div (native) ");
nrOfFailedTestCases += ReportTestResult(VerifyMultiplication<nbits, es>(reportTestCases), tag, "mul (native) ");
nrOfFailedTestCases += ReportTestResult(VerifySubtraction <nbits, es>(reportTestCases), tag, "sub (native) ");
nrOfFailedTestCases += ReportTestResult(VerifyAddition <nbits, es>(reportTestCases), tag, "add (native) ");

uint16_t v1 = 0x7fff;
uint16_t v2 = 0x8001;
std::cout << v1 << " vs " << int16_t(v1) << '\n';
std::cout << v2 << " vs " << int16_t(v2) << '\n';
a.setbits(v1); b.setbits(v2);
testLogicOperators(a, b);
testLogicOperators(b, a);
{
posit<16, 2> a, b, c;
a.setnar(); b.setnar();
testLogicOperators(a, b);
a = +1; b = +1; --b;
testLogicOperators(a, b);
a = +1; b = +1; ++b;
testLogicOperators(a, b);
a = -1; b = -1; --b;
testLogicOperators(a, b);
a = -1; b = -1; ++b;
testLogicOperators(a, b);

a.setbits(0xfffd); b.setbits(0xfffe);
testLogicOperators(a, b);

uint16_t v1 = 0x7fff;
uint16_t v2 = 0x8001;
std::cout << v1 << " vs " << int16_t(v1) << '\n';
std::cout << v2 << " vs " << int16_t(v2) << '\n';
a.setbits(v1); b.setbits(v2);
testLogicOperators(a, b);
testLogicOperators(b, a);
}

epilog:
ReportTestSuiteResults(test_suite, nrOfFailedTestCases);
return EXIT_SUCCESS; // ignore failures
#else
Expand Down
Loading

0 comments on commit 40a475a

Please sign in to comment.