1 #pragma once
2 // test_suite_logic.hpp : boolean logic relationship test suite for arbitrary universal number systems
3 //
4 // Copyright (C) 2017-2021 Stillwater Supercomputing, Inc.
5 //
6 // This file is part of the universal numbers project, which is released under an MIT Open Source license.
7 #include <iostream>
8 #include <iomanip>
9 #include <typeinfo>
10 
11 // CALLING ENVIRONMENT PREREQUISITE!!!!!
12 // We want the test suite to be used with different configurations of number systems
13 // so the calling environment needs to set the configuration
14 // This usually entails setting environment variables, such as
15 // #define POSIT_THOW_ARITHMETIC_EXCEPTIONS 1
16 // or
17 // #define AREAL_FAST_SPECIALIZATION 1
18 
19 #include <universal/verification/test_status.hpp>
20 #include <universal/verification/test_reporters.hpp>  // error/success reporting
21 
22 namespace sw::universal {
23 
24 
25 /////////////////////////////// VERIFICATION TEST SUITES ////////////////////////////////
26 
27 /////////////////////////////////////////////////////////////////////////////////////////
28 ///                             BOOLEAN LOGIC TEST SUITES                             ///
29 /////////////////////////////////////////////////////////////////////////////////////////
30 
31 	template<typename TestType>
VerifyLogicEqual()32 	int VerifyLogicEqual() {
33 		constexpr size_t nbits = TestType::nbits;  // standard interface to Universal number system classes
34 		size_t NR_TEST_CASES = (size_t(1) << nbits);
35 		int nrOfFailedTestCases = 0;
36 		for (unsigned i = 0; i < NR_TEST_CASES; i++) {
37 			TestType a;
38 			a.setbits(i);
39 			for (unsigned j = 0; j < NR_TEST_CASES; j++) {
40 				TestType b;
41 				b.setbits(j);
42 				// generate the golden reference
43 				bool ref = (i == j);	 // the same bit pattern should clearly be the same value
44 				// generate the number system's answer
45 				bool result = (a == b);
46 				if (ref != result) {
47 					nrOfFailedTestCases++;
48 					std::cout << a << " == " << b << " fails: reference is " << ref << " actual is " << result << std::endl;
49 				}
50 			}
51 		}
52 		return nrOfFailedTestCases;
53 	}
54 
55 	template<typename TestType>
VerifyLogicNotEqual()56 	int VerifyLogicNotEqual() {
57 		constexpr size_t nbits = TestType::nbits;  // standard interface to Universal number system classes
58 		size_t NR_TEST_CASES = (size_t(1) << nbits);
59 		int nrOfFailedTestCases = 0;
60 		for (unsigned i = 0; i < NR_TEST_CASES; i++) {
61 			TestType a;
62 			a.setbits(i);
63 			for (unsigned j = 0; j < NR_TEST_CASES; j++) {
64 				TestType b;
65 				b.setbits(j);
66 				// generate the golden reference
67 				bool ref = (i != j);	 // the same bit pattern should clearly be the same value
68 				// generate the number system's answer
69 				bool result = (a != b);
70 				if (ref != result) {
71 					nrOfFailedTestCases++;
72 					std::cout << a << " != " << b << " fails: reference is " << ref << " actual is " << result << std::endl;
73 				}
74 			}
75 		}
76 		return nrOfFailedTestCases;
77 	}
78 
79 	template<typename TestType>
VerifyLogicLessThan()80 	int VerifyLogicLessThan() {
81 		constexpr size_t nbits = TestType::nbits;  // standard interface to Universal number system classes
82 		size_t NR_TEST_CASES = (size_t(1) << nbits);
83 		int nrOfFailedTestCases = 0;
84 		for (unsigned i = 0; i < NR_TEST_CASES; i++) {
85 			TestType a;
86 			a.setbits(i);
87 			for (unsigned j = 0; j < NR_TEST_CASES; j++) {
88 				TestType b;
89 				b.setbits(j);
90 
91 				// generate the golden reference
92 				bool ref = (double(a) < double(b));
93 				bool result = (a < b);
94 				if (ref != result) {
95 					nrOfFailedTestCases++;
96 					std::cout << a << " < " << b << " fails: reference is " << ref << " actual is " << result << std::endl;
97 				}
98 			}
99 		}
100 		return nrOfFailedTestCases;
101 	}
102 
103 	template<typename TestType>
VerifyLogicGreaterThan()104 	int VerifyLogicGreaterThan() {
105 		constexpr size_t nbits = TestType::nbits;  // standard interface to Universal number system classes
106 		size_t NR_TEST_CASES = (size_t(1) << nbits);
107 		int nrOfFailedTestCases = 0;
108 		for (unsigned i = 0; i < NR_TEST_CASES; i++) {
109 			TestType a;
110 			a.setbits(i);
111 			for (unsigned j = 0; j < NR_TEST_CASES; j++) {
112 				TestType b;
113 				b.setbits(j);
114 
115 				// generate the golden reference
116 				bool ref = (double(a) > double(b)); // same behavior as IEEE floats
117 				bool presult = (a > b);
118 				if (ref != presult) {
119 					nrOfFailedTestCases++;
120 					std::cout << a << " > " << b << " fails: reference is " << ref << " actual is " << presult << std::endl;
121 				}
122 			}
123 		}
124 		return nrOfFailedTestCases;
125 	}
126 
127 	template<typename TestType>
VerifyLogicLessOrEqualThan()128 	int VerifyLogicLessOrEqualThan() {
129 		constexpr size_t nbits = TestType::nbits;  // standard interface to Universal number system classes
130 		size_t NR_TEST_CASES = (size_t(1) << nbits);
131 		int nrOfFailedTestCases = 0;
132 		for (unsigned i = 0; i < NR_TEST_CASES; i++) {
133 			TestType a;
134 			a.setbits(i);
135 			for (unsigned j = 0; j < NR_TEST_CASES; j++) {
136 				TestType b;
137 				b.setbits(j);
138 
139 				// set the golden reference
140 				bool ref = (double(a) <= double(b));// same behavior as IEEE floats
141 				bool presult = (a <= b);
142 				if (ref != presult) {
143 					nrOfFailedTestCases++;
144 					std::cout << a << " <= " << b << " fails: reference is " << ref << " actual is " << presult << std::endl;
145 				}
146 			}
147 		}
148 		return nrOfFailedTestCases;
149 	}
150 
151 	template<typename TestType>
VerifyLogicGreaterOrEqualThan()152 	int VerifyLogicGreaterOrEqualThan() {
153 		constexpr size_t nbits = TestType::nbits;  // standard interface to Universal number system classes
154 		size_t NR_TEST_CASES = (size_t(1) << nbits);
155 		int nrOfFailedTestCases = 0;
156 		for (unsigned i = 0; i < NR_TEST_CASES; i++) {
157 			TestType a;
158 			a.setbits(i);
159 			for (unsigned j = 0; j < NR_TEST_CASES; j++) {
160 				TestType b;
161 				b.setbits(j);
162 
163 				// set the golden reference
164 				bool ref = (double(a) >= double(b));// same behavior as IEEE floats
165 				bool presult = (a >= b);
166 				if (ref != presult) {
167 					nrOfFailedTestCases++;
168 					std::cout << a << " >= " << b << " fails: reference is " << ref << " actual is " << presult << std::endl;
169 				}
170 			}
171 		}
172 		return nrOfFailedTestCases;
173 	}
174 
175 } // namespace sw::universal
176