/* Crafter® Build Copyright (C) 2026 Catcrafts® Catcrafts.net This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License version 3.0 as published by the Free Software Foundation; This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ import Crafter.Math; import std; using namespace Crafter; extern "C" { std::string* RunTest() { // Test 1: Load/Store functionality { _Float16 floats[] {0,1,2,3,4,5,6,7}; VectorF16<8, 1> vec1(floats); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i]) { return new std::string("Load Store does not match"); } } } // Test 2: Addition operator { _Float16 floats[] {0,1,2,3,4,5,6,7}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 + vec1; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] + floats[i]) { return new std::string("Add does not match"); } } } // Test 3: Subtraction operator { _Float16 floats[] {0,1,2,3,4,5,6,7}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 - vec1; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] - floats[i]) { return new std::string("Subtract does not match"); } } } // Test 4: Multiplication operator { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 * vec1; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] * floats[i]) { return new std::string("Multiply does not match"); } } } // Test 5: Division operator { _Float16 floats[] {2,4,6,8,10,12,14,16}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 / vec1; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] / floats[i]) { return new std::string("Divide does not match"); } } } // Test 6: Compound addition operator { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> vec2(floats); vec1 += vec2; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] + floats[i]) { return new std::string("Compound Add does not match"); } } } // Test 7: Compound subtraction operator { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> vec2(floats); vec1 -= vec2; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] - floats[i]) { return new std::string("Compound Subtract does not match"); } } } // Test 8: Compound multiplication operator { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> vec2(floats); vec1 *= vec2; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] * floats[i]) { return new std::string("Compound Multiply does not match"); } } } // Test 9: Compound division operator { _Float16 floats[] {2,4,6,8,10,12,14,16}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> vec2(floats); vec1 /= vec2; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] / floats[i]) { return new std::string("Compound Divide does not match"); } } } // Test 10: Scalar addition { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 + _Float16(1.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] + 1.0) { return new std::string("Scalar Add does not match"); } } } // Test 11: Scalar subtraction { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 - _Float16(1.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] - 1.0) { return new std::string("Scalar Subtract does not match"); } } } // Test 12: Scalar multiplication { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 * _Float16(2.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] * 2.0) { return new std::string("Scalar Multiply does not match"); } } } // Test 13: Scalar division { _Float16 floats[] {2,4,6,8,10,12,14,16}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = vec1 / _Float16(2.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] / 2.0) { return new std::string("Scalar Divide does not match"); } } } // Test 14: Compound scalar addition { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); vec1 += _Float16(1.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] + 1.0) { return new std::string("Compound Scalar Add does not match"); } } } // Test 15: Compound scalar subtraction { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); vec1 -= _Float16(1.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] - 1.0) { return new std::string("Compound Scalar Subtract does not match"); } } } // Test 16: Compound scalar multiplication { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); vec1 *= _Float16(2.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] * 2.0) { return new std::string("Compound Scalar Multiply does not match"); } } } // Test 17: Compound scalar division { _Float16 floats[] {2,4,6,8,10,12,14,16}; VectorF16<8, 1> vec1(floats); vec1 /= _Float16(2.0); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != floats[i] / 2.0) { return new std::string("Compound Scalar Divide does not match"); } } } // Test 18: Equality operator { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> vec2(floats); if (!(vec1 == vec2)) { return new std::string("Equality operator does not match"); } } // Test 19: Inequality operator { _Float16 floats1[] {1,2,3,4,5,6,7,8}; _Float16 floats2[] {2,3,4,5,6,7,8,9}; VectorF16<8, 1> vec1(floats1); VectorF16<8, 1> vec2(floats2); if (!(vec1 != vec2)) { return new std::string("Inequality operator does not match"); } } // Test 20: Negation operator { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); VectorF16<8, 1> result = -vec1; Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != -floats[i]) { return new std::string("Negation operator does not match"); } } } // Test 21: Length calculation { _Float16 floats[] {3,4,0,0,0,0,0,0}; VectorF16<8, 1> vec1(floats); _Float16 length = vec1.Length(); _Float16 expectedLength = 5.0; // sqrt(3^2 + 4^2) if (std::abs((float)length - (float)expectedLength) > 0.001) { return new std::string("Length calculation does not match"); } } // Test 22: Length squared calculation { _Float16 floats[] {3,4,0,0,0,0,0,0}; VectorF16<8, 1> vec1(floats); _Float16 lengthSq = vec1.LengthSq(); _Float16 expectedLengthSq = 25.0; // 3^2 + 4^2 if (std::abs((float)lengthSq - (float)expectedLengthSq) > 0.001) { return new std::string("Length squared calculation does not match"); } } // Test 25: Shuffle operation { _Float16 floats[] {1,2,3,4,5,6,7,8}; VectorF16<8, 1> vec1(floats); // Shuffle indices 0,1,2,3 -> 3,2,1,0 (reverse first 4 elements) VectorF16<8, 1> result = vec1.template Shuffle<{{3,2,1,0,7,6,5,4}}>(); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); if (stored.v[0] != 4 || stored.v[1] != 3 || stored.v[2] != 2 || stored.v[3] != 1) { return new std::string("Shuffle operation does not match"); } } // Test 26: Dot product { _Float16 floats1[] {1,2,3,4,0,0,0,0}; _Float16 floats2[] {2,3,4,5,0,0,0,0}; VectorF16<8, 1> vec1(floats1); VectorF16<8, 1> vec2(floats2); _Float16 dot = VectorF16<8, 1>::Dot(vec1, vec2); _Float16 expectedDot = 1*2 + 2*3 + 3*4 + 4*5; // 2 + 6 + 12 + 20 = 40 if (std::abs((float)dot - (float)expectedDot) > 0.001) { return new std::string("Dot product does not match"); } } // Test 27: Cross product (for 3D vectors) { _Float16 floats1[] {1,2,3,0,0,0,0,0}; _Float16 floats2[] {4,5,6,0,0,0,0,0}; VectorF16<3, 1> vec1(floats1); VectorF16<3, 1> vec2(floats2); VectorF16<3, 1> result = VectorF16<3, 1>::Cross(vec1, vec2); Vector<_Float16, 3, VectorF16<3, 1>::Alignment> stored = result.Store(); // Cross product: (1,2,3) x (4,5,6) = (2*6-3*5, 3*4-1*6, 1*5-2*4) = (-3, 6, -3) if (stored.v[0] != -3 || stored.v[1] != 6 || stored.v[2] != -3) { return new std::string("Cross product does not match"); } } // Test 28: Multiply-Add operation { _Float16 floats1[] {1,2,3,4,0,0,0,0}; _Float16 floats2[] {2,3,4,5,0,0,0,0}; _Float16 floats3[] {1,1,1,1,0,0,0,0}; VectorF16<8, 1> vec1(floats1); VectorF16<8, 1> vec2(floats2); VectorF16<8, 1> vec3(floats3); VectorF16<8, 1> result = VectorF16<8, 1>::MulitplyAdd(vec1, vec2, vec3); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); // Should compute (1*2 + 1, 2*3 + 1, 3*4 + 1, 4*5 + 1, ...) = (3, 7, 13, 21, ...) for(std::uint8_t i = 0; i < 4; i++) { if(stored.v[i] != floats1[i]*floats2[i] + floats3[i]) { return new std::string("Multiply-Add operation does not match"); } } } // Test 29: Multiply-Subtract operation { _Float16 floats1[] {1,2,3,4,0,0,0,0}; _Float16 floats2[] {2,3,4,5,0,0,0,0}; _Float16 floats3[] {1,1,1,1,0,0,0,0}; VectorF16<8, 1> vec1(floats1); VectorF16<8, 1> vec2(floats2); VectorF16<8, 1> vec3(floats3); VectorF16<8, 1> result = VectorF16<8, 1>::MulitplySub(vec1, vec2, vec3); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = result.Store(); // Should compute (1*2 - 1, 2*3 - 1, 3*4 - 1, 4*5 - 1, ...) = (1, 5, 11, 19, ...) for(std::uint8_t i = 0; i < 4; i++) { if(stored.v[i] != floats1[i]*floats2[i] - floats3[i]) { return new std::string("Multiply-Subtract operation does not match"); } } } // Test 30: Constructor with single value { VectorF16<8, 1> vec1(_Float16(5.0)); Vector<_Float16, 8, VectorF16<8, 1>::Alignment> stored = vec1.Store(); for(std::uint8_t i = 0; i < 8; i++) { if(stored.v[i] != 5.0) { return new std::string("Single value constructor does not match"); } } } return nullptr; } }