1 // posit_256_5.cpp: test suite runner for fast specialized 256-bit posit<256,5>
2 //
3 // Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
4 //
5 // This file is part of the universal numbers project, which is released under an MIT Open Source license.
6 #if defined(_MSC_VER)
7 #pragma warning(disable : 5045) // Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
8 #pragma warning(disable : 4514) // unreferenced inline function has been removed
9 #pragma warning(disable : 4820) // bytes padding added after data member
10 #pragma warning(disable : 4710) // function not inlined
11 #endif
12 // Configure the posit template environment
13 // first: enable fast specialized posit<256,5>
14 //#define POSIT_FAST_SPECIALIZATION // turns on all fast specializations
15 #define POSIT_FAST_POSIT_256_5 1 // TODO: fast posit<256,5> not implemented yet
16 // second: enable posit arithmetic exceptions
17 #define POSIT_THROW_ARITHMETIC_EXCEPTION 0
18 #include <universal/number/posit/posit.hpp>
19 #include <universal/verification/posit_test_suite.hpp>
20 #include <universal/verification/posit_test_randoms.hpp>
21
22 // Standard posits with nbits = 256 have 5 exponent bits.
23
24 // Regression testing guards: typically set by the cmake configuration, but MANUAL_TESTING is an override
25 #define MANUAL_TESTING 0
26 // REGRESSION_LEVEL_OVERRIDE is set by the cmake file to drive a specific regression intensity
27 // It is the responsibility of the regression test to organize the tests in a quartile progression.
28 //#undef REGRESSION_LEVEL_OVERRIDE
29 #ifndef REGRESSION_LEVEL_OVERRIDE
30 #define REGRESSION_LEVEL_1 1
31 #define REGRESSION_LEVEL_2 1
32 #define REGRESSION_LEVEL_3 1
33 #define REGRESSION_LEVEL_4 1
34 #endif
35
main()36 int main()
37 try {
38 using namespace sw::universal;
39
40 // configure posit<256,5>
41 constexpr size_t nbits = 256;
42 constexpr size_t es = 5;
43
44 int nrOfFailedTestCases = 0;
45 bool bReportIndividualTestCases = false;
46 size_t RND_TEST_CASES = 1000;
47 std::string tag = " posit<256,5>";
48
49 #if POSIT_FAST_POSIT_256_5
50 std::cout << "Fast specialization posit<256,5> configuration tests\n";
51 #else
52 std::cout << "Standard posit<256,5> configuration tests\n";
53 #endif
54
55 #if MANUAL_TESTING
56
57
58 #else
59 posit<nbits, es> p;
60 std::cout << dynamic_range(p) << "\n\n";
61
62 #if REGRESSION_LEVEL_1
63 // special cases
64 std::cout << "Special case tests\n";
65 std::string test = "Initialize to zero: ";
66 p = 0;
67 nrOfFailedTestCases += ReportCheck(tag, test, p.iszero());
68 test = "Initialize to NAN";
69 p = NAN;
70 nrOfFailedTestCases += ReportCheck(tag, test, p.isnar());
71 test = "Initialize to INFINITY";
72 p = INFINITY;
73 nrOfFailedTestCases += ReportCheck(tag, test, p.isnar());
74 test = "sign is true";
75 p = -1.0f;
76 nrOfFailedTestCases += ReportCheck(tag, test, p.sign());
77 test = "is negative";
78 nrOfFailedTestCases += ReportCheck(tag, test, p.isneg());
79 test = "sign is false";
80 p = +1.0f;
81 nrOfFailedTestCases += ReportCheck(tag, test, !p.sign());
82 test = "is positive";
83 nrOfFailedTestCases += ReportCheck(tag, test, p.ispos());
84
85 RND_TEST_CASES = 1024;
86 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_ADD, RND_TEST_CASES), tag, "addition ");
87 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_SUB, RND_TEST_CASES), tag, "subtraction ");
88 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_MUL, RND_TEST_CASES), tag, "multiplication");
89 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_DIV, RND_TEST_CASES), tag, "division ");
90
91 #endif
92
93 #if REGRESSION_LEVEL_2
94 RND_TEST_CASES = 1024 * 16;
95 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_ADD, RND_TEST_CASES), tag, "addition ");
96 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_SUB, RND_TEST_CASES), tag, "subtraction ");
97 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_MUL, RND_TEST_CASES), tag, "multiplication");
98 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_DIV, RND_TEST_CASES), tag, "division ");
99
100 #endif
101
102 #if REGRESSION_LEVEL_3
103
104 #endif
105
106 #if REGRESSION_LEVEL_4
107 // TODO: as we don't have a reference floating point implementation to Verify
108 // the arithmetic operations we are going to ignore the failures
109
110 RND_TEST_CASES = 1024 * 1024;
111 std::cout << "Arithmetic tests " << RND_TEST_CASES << " randoms each\n";
112 std::cout << "Without an arithmetic reference, test failures can be ignored\n";
113 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_ADD, RND_TEST_CASES), tag, "addition ");
114 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_SUB, RND_TEST_CASES), tag, "subtraction ");
115 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_MUL, RND_TEST_CASES), tag, "multiplication");
116 nrOfFailedTestCases += ReportTestResult(VerifyBinaryOperatorThroughRandoms<nbits, es>(bReportIndividualTestCases, OPCODE_DIV, RND_TEST_CASES), tag, "division ");
117 nrOfFailedTestCases = 0;
118 #endif
119
120 #endif // MANUAL_TESTING
121
122 return (nrOfFailedTestCases > 0 ? EXIT_FAILURE : EXIT_SUCCESS);
123 }
124 catch (char const* msg) {
125 std::cerr << msg << std::endl;
126 return EXIT_SUCCESS; //as we manually throwing the not supported yet it should not fall through the cracks EXIT_FAILURE;
127 }
128 catch (const sw::universal::posit_arithmetic_exception& err) {
129 std::cerr << "Uncaught posit arithmetic exception: " << err.what() << std::endl;
130 return EXIT_FAILURE;
131 }
132 catch (const sw::universal::quire_exception& err) {
133 std::cerr << "Uncaught quire exception: " << err.what() << std::endl;
134 return EXIT_FAILURE;
135 }
136 catch (const sw::universal::posit_internal_exception& err) {
137 std::cerr << "Uncaught posit internal exception: " << err.what() << std::endl;
138 return EXIT_FAILURE;
139 }
140 catch (const std::runtime_error& err) {
141 std::cerr << "Uncaught runtime exception: " << err.what() << std::endl;
142 return EXIT_FAILURE;
143 }
144 catch (...) {
145 std::cerr << "Caught unknown exception" << std::endl;
146 return EXIT_FAILURE;
147 }
148