1*4bdc9457SAndroid Build Coastguard Worker // Copyright 2021 Google LLC 2*4bdc9457SAndroid Build Coastguard Worker // 3*4bdc9457SAndroid Build Coastguard Worker // This source code is licensed under the BSD-style license found in the 4*4bdc9457SAndroid Build Coastguard Worker // LICENSE file in the root directory of this source tree. 5*4bdc9457SAndroid Build Coastguard Worker 6*4bdc9457SAndroid Build Coastguard Worker #include <algorithm> 7*4bdc9457SAndroid Build Coastguard Worker #include <cmath> 8*4bdc9457SAndroid Build Coastguard Worker #include <cstddef> 9*4bdc9457SAndroid Build Coastguard Worker #include <cstdint> 10*4bdc9457SAndroid Build Coastguard Worker #include <cstdlib> 11*4bdc9457SAndroid Build Coastguard Worker #include <iomanip> 12*4bdc9457SAndroid Build Coastguard Worker #include <ios> 13*4bdc9457SAndroid Build Coastguard Worker #include <vector> 14*4bdc9457SAndroid Build Coastguard Worker 15*4bdc9457SAndroid Build Coastguard Worker #include <gtest/gtest.h> 16*4bdc9457SAndroid Build Coastguard Worker 17*4bdc9457SAndroid Build Coastguard Worker #include <fp16.h> 18*4bdc9457SAndroid Build Coastguard Worker 19*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/aligned-allocator.h> 20*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/common.h> 21*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/isa-checks.h> 22*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/math.h> 23*4bdc9457SAndroid Build Coastguard Worker #include <xnnpack/math-stubs.h> 24*4bdc9457SAndroid Build Coastguard Worker 25*4bdc9457SAndroid Build Coastguard Worker 26*4bdc9457SAndroid Build Coastguard Worker constexpr int kBlockSize = 1024; 27*4bdc9457SAndroid Build Coastguard Worker 28*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64 TEST(CVT__SSE2_INT16,positive_normal)29*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, positive_normal) { 30*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 31*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 32*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 33*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 34*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 35*4bdc9457SAndroid Build Coastguard Worker } 36*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 37*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 38*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 39*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 40*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 41*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 42*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 43*4bdc9457SAndroid Build Coastguard Worker } 44*4bdc9457SAndroid Build Coastguard Worker } 45*4bdc9457SAndroid Build Coastguard Worker } 46*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,negative_normal)47*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, negative_normal) { 48*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 49*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 50*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 51*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 52*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 53*4bdc9457SAndroid Build Coastguard Worker } 54*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 55*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 56*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 57*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 58*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 59*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 60*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 61*4bdc9457SAndroid Build Coastguard Worker } 62*4bdc9457SAndroid Build Coastguard Worker } 63*4bdc9457SAndroid Build Coastguard Worker } 64*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,positive_zero)65*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, positive_zero) { 66*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 67*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 68*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 69*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 70*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 71*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 72*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 73*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 74*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 75*4bdc9457SAndroid Build Coastguard Worker } 76*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,negative_zero)77*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, negative_zero) { 78*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 79*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 80*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 81*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 82*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 83*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 84*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 85*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 86*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 87*4bdc9457SAndroid Build Coastguard Worker } 88*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,positive_subnormal)89*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, positive_subnormal) { 90*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 91*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 92*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 93*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 94*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 95*4bdc9457SAndroid Build Coastguard Worker } 96*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 97*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 98*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 99*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 100*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 101*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 102*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 103*4bdc9457SAndroid Build Coastguard Worker } 104*4bdc9457SAndroid Build Coastguard Worker } 105*4bdc9457SAndroid Build Coastguard Worker } 106*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,negative_subnormal)107*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, negative_subnormal) { 108*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 109*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 110*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 111*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 112*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 113*4bdc9457SAndroid Build Coastguard Worker } 114*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 115*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 116*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 117*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 118*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 119*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 120*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 121*4bdc9457SAndroid Build Coastguard Worker } 122*4bdc9457SAndroid Build Coastguard Worker } 123*4bdc9457SAndroid Build Coastguard Worker } 124*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,positive_infinity)125*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, positive_infinity) { 126*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 127*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 128*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 129*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 130*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 131*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 132*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 133*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 134*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 135*4bdc9457SAndroid Build Coastguard Worker } 136*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,negative_infinity)137*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, negative_infinity) { 138*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 139*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 140*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 141*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 142*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 143*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 144*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 145*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 146*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 147*4bdc9457SAndroid Build Coastguard Worker } 148*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,positive_nan)149*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, positive_nan) { 150*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 151*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 152*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 153*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 154*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 155*4bdc9457SAndroid Build Coastguard Worker } 156*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 157*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 158*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 159*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 160*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 161*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 162*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 163*4bdc9457SAndroid Build Coastguard Worker } 164*4bdc9457SAndroid Build Coastguard Worker } 165*4bdc9457SAndroid Build Coastguard Worker } 166*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16,negative_nan)167*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT16, negative_nan) { 168*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 169*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 170*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 171*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 172*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 173*4bdc9457SAndroid Build Coastguard Worker } 174*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 175*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 176*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 177*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 178*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 179*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 180*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 181*4bdc9457SAndroid Build Coastguard Worker } 182*4bdc9457SAndroid Build Coastguard Worker } 183*4bdc9457SAndroid Build Coastguard Worker } 184*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_X86 || XNN_ARCH_X86_64 185*4bdc9457SAndroid Build Coastguard Worker 186*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64 TEST(CVT__SSE2_INT32,positive_normal)187*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, positive_normal) { 188*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 189*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 190*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 191*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 192*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 193*4bdc9457SAndroid Build Coastguard Worker } 194*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 195*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 196*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 197*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 198*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 199*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 200*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 201*4bdc9457SAndroid Build Coastguard Worker } 202*4bdc9457SAndroid Build Coastguard Worker } 203*4bdc9457SAndroid Build Coastguard Worker } 204*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,negative_normal)205*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, negative_normal) { 206*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 207*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 208*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 209*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 210*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 211*4bdc9457SAndroid Build Coastguard Worker } 212*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 213*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 214*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 215*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 216*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 217*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 218*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 219*4bdc9457SAndroid Build Coastguard Worker } 220*4bdc9457SAndroid Build Coastguard Worker } 221*4bdc9457SAndroid Build Coastguard Worker } 222*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,positive_zero)223*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, positive_zero) { 224*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 225*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 226*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 227*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 228*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 229*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 230*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 231*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 232*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 233*4bdc9457SAndroid Build Coastguard Worker } 234*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,negative_zero)235*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, negative_zero) { 236*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 237*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 238*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 239*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 240*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 241*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 242*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 243*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 244*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 245*4bdc9457SAndroid Build Coastguard Worker } 246*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,positive_subnormal)247*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, positive_subnormal) { 248*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 249*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 250*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 251*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 252*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 253*4bdc9457SAndroid Build Coastguard Worker } 254*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 255*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 256*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 257*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 258*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 259*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 260*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 261*4bdc9457SAndroid Build Coastguard Worker } 262*4bdc9457SAndroid Build Coastguard Worker } 263*4bdc9457SAndroid Build Coastguard Worker } 264*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,negative_subnormal)265*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, negative_subnormal) { 266*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 267*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 268*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 269*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 270*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 271*4bdc9457SAndroid Build Coastguard Worker } 272*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 273*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 274*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 275*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 276*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 277*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 278*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 279*4bdc9457SAndroid Build Coastguard Worker } 280*4bdc9457SAndroid Build Coastguard Worker } 281*4bdc9457SAndroid Build Coastguard Worker } 282*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,positive_infinity)283*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, positive_infinity) { 284*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 285*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 286*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 287*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 288*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 289*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 290*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 291*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 292*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 293*4bdc9457SAndroid Build Coastguard Worker } 294*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,negative_infinity)295*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, negative_infinity) { 296*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 297*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 298*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 299*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 300*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 301*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 302*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 303*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 304*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 305*4bdc9457SAndroid Build Coastguard Worker } 306*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,positive_nan)307*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, positive_nan) { 308*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 309*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 310*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 311*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 312*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 313*4bdc9457SAndroid Build Coastguard Worker } 314*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 315*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 316*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 317*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 318*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 319*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 320*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 321*4bdc9457SAndroid Build Coastguard Worker } 322*4bdc9457SAndroid Build Coastguard Worker } 323*4bdc9457SAndroid Build Coastguard Worker } 324*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32,negative_nan)325*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE2_INT32, negative_nan) { 326*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 327*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 328*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 329*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 330*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 331*4bdc9457SAndroid Build Coastguard Worker } 332*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse2_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 333*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 334*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 335*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 336*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 337*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 338*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 339*4bdc9457SAndroid Build Coastguard Worker } 340*4bdc9457SAndroid Build Coastguard Worker } 341*4bdc9457SAndroid Build Coastguard Worker } 342*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_X86 || XNN_ARCH_X86_64 343*4bdc9457SAndroid Build Coastguard Worker 344*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64 TEST(CVT__SSE41_INT16,positive_normal)345*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, positive_normal) { 346*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 347*4bdc9457SAndroid Build Coastguard Worker 348*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 349*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 350*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 351*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 352*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 353*4bdc9457SAndroid Build Coastguard Worker } 354*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 355*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 356*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 357*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 358*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 359*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 360*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 361*4bdc9457SAndroid Build Coastguard Worker } 362*4bdc9457SAndroid Build Coastguard Worker } 363*4bdc9457SAndroid Build Coastguard Worker } 364*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,negative_normal)365*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, negative_normal) { 366*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 367*4bdc9457SAndroid Build Coastguard Worker 368*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 369*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 370*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 371*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 372*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 373*4bdc9457SAndroid Build Coastguard Worker } 374*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 375*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 376*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 377*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 378*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 379*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 380*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 381*4bdc9457SAndroid Build Coastguard Worker } 382*4bdc9457SAndroid Build Coastguard Worker } 383*4bdc9457SAndroid Build Coastguard Worker } 384*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,positive_zero)385*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, positive_zero) { 386*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 387*4bdc9457SAndroid Build Coastguard Worker 388*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 389*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 390*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 391*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 392*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 393*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 394*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 395*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 396*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 397*4bdc9457SAndroid Build Coastguard Worker } 398*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,negative_zero)399*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, negative_zero) { 400*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 401*4bdc9457SAndroid Build Coastguard Worker 402*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 403*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 404*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 405*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 406*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 407*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 408*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 409*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 410*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 411*4bdc9457SAndroid Build Coastguard Worker } 412*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,positive_subnormal)413*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, positive_subnormal) { 414*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 415*4bdc9457SAndroid Build Coastguard Worker 416*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 417*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 418*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 419*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 420*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 421*4bdc9457SAndroid Build Coastguard Worker } 422*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 423*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 424*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 425*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 426*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 427*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 428*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 429*4bdc9457SAndroid Build Coastguard Worker } 430*4bdc9457SAndroid Build Coastguard Worker } 431*4bdc9457SAndroid Build Coastguard Worker } 432*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,negative_subnormal)433*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, negative_subnormal) { 434*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 435*4bdc9457SAndroid Build Coastguard Worker 436*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 437*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 438*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 439*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 440*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 441*4bdc9457SAndroid Build Coastguard Worker } 442*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 443*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 444*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 445*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 446*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 447*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 448*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 449*4bdc9457SAndroid Build Coastguard Worker } 450*4bdc9457SAndroid Build Coastguard Worker } 451*4bdc9457SAndroid Build Coastguard Worker } 452*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,positive_infinity)453*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, positive_infinity) { 454*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 455*4bdc9457SAndroid Build Coastguard Worker 456*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 457*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 458*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 459*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 460*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 461*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 462*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 463*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 464*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 465*4bdc9457SAndroid Build Coastguard Worker } 466*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,negative_infinity)467*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, negative_infinity) { 468*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 469*4bdc9457SAndroid Build Coastguard Worker 470*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 471*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 472*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 473*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 474*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 475*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 476*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 477*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 478*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 479*4bdc9457SAndroid Build Coastguard Worker } 480*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,positive_nan)481*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, positive_nan) { 482*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 483*4bdc9457SAndroid Build Coastguard Worker 484*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 485*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 486*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 487*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 488*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 489*4bdc9457SAndroid Build Coastguard Worker } 490*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 491*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 492*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 493*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 494*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 495*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 496*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 497*4bdc9457SAndroid Build Coastguard Worker } 498*4bdc9457SAndroid Build Coastguard Worker } 499*4bdc9457SAndroid Build Coastguard Worker } 500*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16,negative_nan)501*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT16, negative_nan) { 502*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 503*4bdc9457SAndroid Build Coastguard Worker 504*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 505*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 506*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 507*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 508*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 509*4bdc9457SAndroid Build Coastguard Worker } 510*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 511*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 512*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 513*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 514*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 515*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 516*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 517*4bdc9457SAndroid Build Coastguard Worker } 518*4bdc9457SAndroid Build Coastguard Worker } 519*4bdc9457SAndroid Build Coastguard Worker } 520*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_X86 || XNN_ARCH_X86_64 521*4bdc9457SAndroid Build Coastguard Worker 522*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64 TEST(CVT__SSE41_INT32,positive_normal)523*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, positive_normal) { 524*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 525*4bdc9457SAndroid Build Coastguard Worker 526*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 527*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 528*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 529*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 530*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 531*4bdc9457SAndroid Build Coastguard Worker } 532*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 533*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 534*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 535*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 536*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 537*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 538*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 539*4bdc9457SAndroid Build Coastguard Worker } 540*4bdc9457SAndroid Build Coastguard Worker } 541*4bdc9457SAndroid Build Coastguard Worker } 542*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,negative_normal)543*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, negative_normal) { 544*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 545*4bdc9457SAndroid Build Coastguard Worker 546*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 547*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 548*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 549*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 550*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 551*4bdc9457SAndroid Build Coastguard Worker } 552*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 553*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 554*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 555*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 556*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 557*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 558*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 559*4bdc9457SAndroid Build Coastguard Worker } 560*4bdc9457SAndroid Build Coastguard Worker } 561*4bdc9457SAndroid Build Coastguard Worker } 562*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,positive_zero)563*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, positive_zero) { 564*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 565*4bdc9457SAndroid Build Coastguard Worker 566*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 567*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 568*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 569*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 570*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 571*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 572*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 573*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 574*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 575*4bdc9457SAndroid Build Coastguard Worker } 576*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,negative_zero)577*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, negative_zero) { 578*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 579*4bdc9457SAndroid Build Coastguard Worker 580*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 581*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 582*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 583*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 584*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 585*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 586*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 587*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 588*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 589*4bdc9457SAndroid Build Coastguard Worker } 590*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,positive_subnormal)591*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, positive_subnormal) { 592*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 593*4bdc9457SAndroid Build Coastguard Worker 594*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 595*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 596*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 597*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 598*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 599*4bdc9457SAndroid Build Coastguard Worker } 600*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 601*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 602*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 603*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 604*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 605*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 606*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 607*4bdc9457SAndroid Build Coastguard Worker } 608*4bdc9457SAndroid Build Coastguard Worker } 609*4bdc9457SAndroid Build Coastguard Worker } 610*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,negative_subnormal)611*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, negative_subnormal) { 612*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 613*4bdc9457SAndroid Build Coastguard Worker 614*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 615*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 616*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 617*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 618*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 619*4bdc9457SAndroid Build Coastguard Worker } 620*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 621*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 622*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 623*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 624*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 625*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 626*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 627*4bdc9457SAndroid Build Coastguard Worker } 628*4bdc9457SAndroid Build Coastguard Worker } 629*4bdc9457SAndroid Build Coastguard Worker } 630*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,positive_infinity)631*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, positive_infinity) { 632*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 633*4bdc9457SAndroid Build Coastguard Worker 634*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 635*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 636*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 637*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 638*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 639*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 640*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 641*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 642*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 643*4bdc9457SAndroid Build Coastguard Worker } 644*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,negative_infinity)645*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, negative_infinity) { 646*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 647*4bdc9457SAndroid Build Coastguard Worker 648*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 649*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 650*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 651*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 652*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 653*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 654*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 655*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 656*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 657*4bdc9457SAndroid Build Coastguard Worker } 658*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,positive_nan)659*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, positive_nan) { 660*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 661*4bdc9457SAndroid Build Coastguard Worker 662*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 663*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 664*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 665*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 666*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 667*4bdc9457SAndroid Build Coastguard Worker } 668*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 669*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 670*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 671*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 672*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 673*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 674*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 675*4bdc9457SAndroid Build Coastguard Worker } 676*4bdc9457SAndroid Build Coastguard Worker } 677*4bdc9457SAndroid Build Coastguard Worker } 678*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32,negative_nan)679*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__SSE41_INT32, negative_nan) { 680*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_SSE41; 681*4bdc9457SAndroid Build Coastguard Worker 682*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 683*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 684*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 685*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 686*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 687*4bdc9457SAndroid Build Coastguard Worker } 688*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__sse41_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 689*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 690*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 691*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 692*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 693*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 694*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 695*4bdc9457SAndroid Build Coastguard Worker } 696*4bdc9457SAndroid Build Coastguard Worker } 697*4bdc9457SAndroid Build Coastguard Worker } 698*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_X86 || XNN_ARCH_X86_64 699*4bdc9457SAndroid Build Coastguard Worker 700*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_X86 || XNN_ARCH_X86_64 TEST(CVT__F16C,positive_normal)701*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, positive_normal) { 702*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 703*4bdc9457SAndroid Build Coastguard Worker 704*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 705*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 706*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 707*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 708*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 709*4bdc9457SAndroid Build Coastguard Worker } 710*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 711*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 712*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 713*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 714*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 715*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 716*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 717*4bdc9457SAndroid Build Coastguard Worker } 718*4bdc9457SAndroid Build Coastguard Worker } 719*4bdc9457SAndroid Build Coastguard Worker } 720*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,negative_normal)721*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, negative_normal) { 722*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 723*4bdc9457SAndroid Build Coastguard Worker 724*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 725*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 726*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 727*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 728*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 729*4bdc9457SAndroid Build Coastguard Worker } 730*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 731*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 732*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 733*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 734*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 735*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 736*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 737*4bdc9457SAndroid Build Coastguard Worker } 738*4bdc9457SAndroid Build Coastguard Worker } 739*4bdc9457SAndroid Build Coastguard Worker } 740*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,positive_zero)741*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, positive_zero) { 742*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 743*4bdc9457SAndroid Build Coastguard Worker 744*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 745*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 746*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 747*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 748*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 749*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 750*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 751*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 752*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 753*4bdc9457SAndroid Build Coastguard Worker } 754*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,negative_zero)755*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, negative_zero) { 756*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 757*4bdc9457SAndroid Build Coastguard Worker 758*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 759*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 760*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 761*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 762*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 763*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 764*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 765*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 766*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 767*4bdc9457SAndroid Build Coastguard Worker } 768*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,positive_subnormal)769*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, positive_subnormal) { 770*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 771*4bdc9457SAndroid Build Coastguard Worker 772*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 773*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 774*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 775*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 776*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 777*4bdc9457SAndroid Build Coastguard Worker } 778*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 779*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 780*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 781*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 782*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 783*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 784*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 785*4bdc9457SAndroid Build Coastguard Worker } 786*4bdc9457SAndroid Build Coastguard Worker } 787*4bdc9457SAndroid Build Coastguard Worker } 788*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,negative_subnormal)789*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, negative_subnormal) { 790*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 791*4bdc9457SAndroid Build Coastguard Worker 792*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 793*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 794*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 795*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 796*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 797*4bdc9457SAndroid Build Coastguard Worker } 798*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 799*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 800*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 801*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 802*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 803*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 804*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 805*4bdc9457SAndroid Build Coastguard Worker } 806*4bdc9457SAndroid Build Coastguard Worker } 807*4bdc9457SAndroid Build Coastguard Worker } 808*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,positive_infinity)809*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, positive_infinity) { 810*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 811*4bdc9457SAndroid Build Coastguard Worker 812*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 813*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 814*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 815*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 816*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 817*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 818*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 819*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 820*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 821*4bdc9457SAndroid Build Coastguard Worker } 822*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,negative_infinity)823*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, negative_infinity) { 824*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 825*4bdc9457SAndroid Build Coastguard Worker 826*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 827*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 828*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 829*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 830*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 831*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 832*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 833*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 834*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 835*4bdc9457SAndroid Build Coastguard Worker } 836*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,positive_nan)837*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, positive_nan) { 838*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 839*4bdc9457SAndroid Build Coastguard Worker 840*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 841*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 842*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 843*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 844*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 845*4bdc9457SAndroid Build Coastguard Worker } 846*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 847*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 848*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 849*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 850*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 851*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 852*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 853*4bdc9457SAndroid Build Coastguard Worker } 854*4bdc9457SAndroid Build Coastguard Worker } 855*4bdc9457SAndroid Build Coastguard Worker } 856*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C,negative_nan)857*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__F16C, negative_nan) { 858*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_X86_F16C; 859*4bdc9457SAndroid Build Coastguard Worker 860*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 861*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 862*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 863*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 864*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 865*4bdc9457SAndroid Build Coastguard Worker } 866*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__f16c(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 867*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 868*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 869*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 870*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 871*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 872*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 873*4bdc9457SAndroid Build Coastguard Worker } 874*4bdc9457SAndroid Build Coastguard Worker } 875*4bdc9457SAndroid Build Coastguard Worker } 876*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_X86 || XNN_ARCH_X86_64 877*4bdc9457SAndroid Build Coastguard Worker 878*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64 TEST(CVT__NEON_INT16,positive_normal)879*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, positive_normal) { 880*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 881*4bdc9457SAndroid Build Coastguard Worker 882*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 883*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 884*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 885*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 886*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 887*4bdc9457SAndroid Build Coastguard Worker } 888*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 889*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 890*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 891*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 892*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 893*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 894*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 895*4bdc9457SAndroid Build Coastguard Worker } 896*4bdc9457SAndroid Build Coastguard Worker } 897*4bdc9457SAndroid Build Coastguard Worker } 898*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,negative_normal)899*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, negative_normal) { 900*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 901*4bdc9457SAndroid Build Coastguard Worker 902*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 903*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 904*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 905*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 906*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 907*4bdc9457SAndroid Build Coastguard Worker } 908*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 909*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 910*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 911*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 912*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 913*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 914*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 915*4bdc9457SAndroid Build Coastguard Worker } 916*4bdc9457SAndroid Build Coastguard Worker } 917*4bdc9457SAndroid Build Coastguard Worker } 918*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,positive_zero)919*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, positive_zero) { 920*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 921*4bdc9457SAndroid Build Coastguard Worker 922*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 923*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 924*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 925*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 926*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 927*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 928*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 929*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 930*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 931*4bdc9457SAndroid Build Coastguard Worker } 932*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,negative_zero)933*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, negative_zero) { 934*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 935*4bdc9457SAndroid Build Coastguard Worker 936*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 937*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 938*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 939*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 940*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 941*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 942*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 943*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 944*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 945*4bdc9457SAndroid Build Coastguard Worker } 946*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,positive_subnormal)947*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, positive_subnormal) { 948*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 949*4bdc9457SAndroid Build Coastguard Worker 950*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 951*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 952*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 953*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 954*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 955*4bdc9457SAndroid Build Coastguard Worker } 956*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 957*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 958*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 959*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 960*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 961*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 962*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 963*4bdc9457SAndroid Build Coastguard Worker } 964*4bdc9457SAndroid Build Coastguard Worker } 965*4bdc9457SAndroid Build Coastguard Worker } 966*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,negative_subnormal)967*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, negative_subnormal) { 968*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 969*4bdc9457SAndroid Build Coastguard Worker 970*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 971*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 972*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 973*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 974*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 975*4bdc9457SAndroid Build Coastguard Worker } 976*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 977*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 978*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 979*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 980*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 981*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 982*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 983*4bdc9457SAndroid Build Coastguard Worker } 984*4bdc9457SAndroid Build Coastguard Worker } 985*4bdc9457SAndroid Build Coastguard Worker } 986*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,positive_infinity)987*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, positive_infinity) { 988*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 989*4bdc9457SAndroid Build Coastguard Worker 990*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 991*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 992*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 993*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 994*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 995*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 996*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 997*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 998*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 999*4bdc9457SAndroid Build Coastguard Worker } 1000*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,negative_infinity)1001*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, negative_infinity) { 1002*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1003*4bdc9457SAndroid Build Coastguard Worker 1004*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1005*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1006*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 1007*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1008*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1009*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1010*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1011*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1012*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1013*4bdc9457SAndroid Build Coastguard Worker } 1014*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,positive_nan)1015*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, positive_nan) { 1016*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1017*4bdc9457SAndroid Build Coastguard Worker 1018*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1019*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1020*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1021*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1022*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 1023*4bdc9457SAndroid Build Coastguard Worker } 1024*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1025*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1026*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1027*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1028*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1029*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1030*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1031*4bdc9457SAndroid Build Coastguard Worker } 1032*4bdc9457SAndroid Build Coastguard Worker } 1033*4bdc9457SAndroid Build Coastguard Worker } 1034*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16,negative_nan)1035*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT16, negative_nan) { 1036*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1037*4bdc9457SAndroid Build Coastguard Worker 1038*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1039*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1040*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1041*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1042*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 1043*4bdc9457SAndroid Build Coastguard Worker } 1044*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1045*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1046*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1047*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1048*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1049*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1050*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1051*4bdc9457SAndroid Build Coastguard Worker } 1052*4bdc9457SAndroid Build Coastguard Worker } 1053*4bdc9457SAndroid Build Coastguard Worker } 1054*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_ARM || XNN_ARCH_ARM64 1055*4bdc9457SAndroid Build Coastguard Worker 1056*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64 TEST(CVT__NEON_INT32,positive_normal)1057*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, positive_normal) { 1058*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1059*4bdc9457SAndroid Build Coastguard Worker 1060*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1061*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1062*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 1063*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1064*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1065*4bdc9457SAndroid Build Coastguard Worker } 1066*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1067*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1068*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1069*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1070*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1071*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1072*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1073*4bdc9457SAndroid Build Coastguard Worker } 1074*4bdc9457SAndroid Build Coastguard Worker } 1075*4bdc9457SAndroid Build Coastguard Worker } 1076*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,negative_normal)1077*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, negative_normal) { 1078*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1079*4bdc9457SAndroid Build Coastguard Worker 1080*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1081*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1082*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 1083*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1084*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1085*4bdc9457SAndroid Build Coastguard Worker } 1086*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1087*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1088*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1089*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1090*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1091*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1092*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1093*4bdc9457SAndroid Build Coastguard Worker } 1094*4bdc9457SAndroid Build Coastguard Worker } 1095*4bdc9457SAndroid Build Coastguard Worker } 1096*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,positive_zero)1097*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, positive_zero) { 1098*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1099*4bdc9457SAndroid Build Coastguard Worker 1100*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1101*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1102*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 1103*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1104*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1105*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1106*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1107*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1108*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1109*4bdc9457SAndroid Build Coastguard Worker } 1110*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,negative_zero)1111*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, negative_zero) { 1112*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1113*4bdc9457SAndroid Build Coastguard Worker 1114*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1115*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1116*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 1117*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1118*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1119*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1120*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1121*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1122*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1123*4bdc9457SAndroid Build Coastguard Worker } 1124*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,positive_subnormal)1125*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, positive_subnormal) { 1126*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1127*4bdc9457SAndroid Build Coastguard Worker 1128*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1129*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1130*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 1131*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1132*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 1133*4bdc9457SAndroid Build Coastguard Worker } 1134*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1135*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1136*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1137*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1138*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1139*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1140*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1141*4bdc9457SAndroid Build Coastguard Worker } 1142*4bdc9457SAndroid Build Coastguard Worker } 1143*4bdc9457SAndroid Build Coastguard Worker } 1144*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,negative_subnormal)1145*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, negative_subnormal) { 1146*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1147*4bdc9457SAndroid Build Coastguard Worker 1148*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1149*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1150*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 1151*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1152*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 1153*4bdc9457SAndroid Build Coastguard Worker } 1154*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1155*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1156*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1157*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1158*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1159*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1160*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1161*4bdc9457SAndroid Build Coastguard Worker } 1162*4bdc9457SAndroid Build Coastguard Worker } 1163*4bdc9457SAndroid Build Coastguard Worker } 1164*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,positive_infinity)1165*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, positive_infinity) { 1166*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1167*4bdc9457SAndroid Build Coastguard Worker 1168*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1169*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1170*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 1171*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1172*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1173*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1174*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1175*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1176*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1177*4bdc9457SAndroid Build Coastguard Worker } 1178*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,negative_infinity)1179*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, negative_infinity) { 1180*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1181*4bdc9457SAndroid Build Coastguard Worker 1182*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1183*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1184*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 1185*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1186*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1187*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1188*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1189*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1190*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1191*4bdc9457SAndroid Build Coastguard Worker } 1192*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,positive_nan)1193*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, positive_nan) { 1194*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1195*4bdc9457SAndroid Build Coastguard Worker 1196*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1197*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1198*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1199*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1200*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 1201*4bdc9457SAndroid Build Coastguard Worker } 1202*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1203*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1204*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1205*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1206*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1207*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1208*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1209*4bdc9457SAndroid Build Coastguard Worker } 1210*4bdc9457SAndroid Build Coastguard Worker } 1211*4bdc9457SAndroid Build Coastguard Worker } 1212*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32,negative_nan)1213*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEON_INT32, negative_nan) { 1214*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON; 1215*4bdc9457SAndroid Build Coastguard Worker 1216*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1217*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1218*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1219*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1220*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 1221*4bdc9457SAndroid Build Coastguard Worker } 1222*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neon_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1223*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1224*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1225*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1226*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1227*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1228*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1229*4bdc9457SAndroid Build Coastguard Worker } 1230*4bdc9457SAndroid Build Coastguard Worker } 1231*4bdc9457SAndroid Build Coastguard Worker } 1232*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_ARM || XNN_ARCH_ARM64 1233*4bdc9457SAndroid Build Coastguard Worker 1234*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_ARM || XNN_ARCH_ARM64 TEST(CVT__NEONFP16,positive_normal)1235*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, positive_normal) { 1236*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1237*4bdc9457SAndroid Build Coastguard Worker 1238*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1239*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1240*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 1241*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1242*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1243*4bdc9457SAndroid Build Coastguard Worker } 1244*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1245*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1246*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1247*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1248*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1249*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1250*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1251*4bdc9457SAndroid Build Coastguard Worker } 1252*4bdc9457SAndroid Build Coastguard Worker } 1253*4bdc9457SAndroid Build Coastguard Worker } 1254*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,negative_normal)1255*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, negative_normal) { 1256*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1257*4bdc9457SAndroid Build Coastguard Worker 1258*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1259*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1260*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 1261*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1262*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1263*4bdc9457SAndroid Build Coastguard Worker } 1264*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1265*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1266*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1267*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1268*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1269*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1270*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1271*4bdc9457SAndroid Build Coastguard Worker } 1272*4bdc9457SAndroid Build Coastguard Worker } 1273*4bdc9457SAndroid Build Coastguard Worker } 1274*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,positive_zero)1275*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, positive_zero) { 1276*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1277*4bdc9457SAndroid Build Coastguard Worker 1278*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1279*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1280*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 1281*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1282*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1283*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1284*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1285*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1286*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1287*4bdc9457SAndroid Build Coastguard Worker } 1288*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,negative_zero)1289*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, negative_zero) { 1290*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1291*4bdc9457SAndroid Build Coastguard Worker 1292*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1293*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1294*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 1295*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1296*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1297*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1298*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1299*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1300*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1301*4bdc9457SAndroid Build Coastguard Worker } 1302*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,positive_subnormal)1303*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, positive_subnormal) { 1304*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1305*4bdc9457SAndroid Build Coastguard Worker 1306*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1307*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1308*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 1309*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1310*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 1311*4bdc9457SAndroid Build Coastguard Worker } 1312*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1313*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1314*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1315*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1316*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1317*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1318*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1319*4bdc9457SAndroid Build Coastguard Worker } 1320*4bdc9457SAndroid Build Coastguard Worker } 1321*4bdc9457SAndroid Build Coastguard Worker } 1322*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,negative_subnormal)1323*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, negative_subnormal) { 1324*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1325*4bdc9457SAndroid Build Coastguard Worker 1326*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1327*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1328*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 1329*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1330*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 1331*4bdc9457SAndroid Build Coastguard Worker } 1332*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1333*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1334*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1335*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1336*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1337*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1338*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1339*4bdc9457SAndroid Build Coastguard Worker } 1340*4bdc9457SAndroid Build Coastguard Worker } 1341*4bdc9457SAndroid Build Coastguard Worker } 1342*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,positive_infinity)1343*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, positive_infinity) { 1344*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1345*4bdc9457SAndroid Build Coastguard Worker 1346*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1347*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1348*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 1349*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1350*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1351*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1352*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1353*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1354*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1355*4bdc9457SAndroid Build Coastguard Worker } 1356*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,negative_infinity)1357*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, negative_infinity) { 1358*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1359*4bdc9457SAndroid Build Coastguard Worker 1360*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1361*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1362*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 1363*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1364*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1365*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1366*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1367*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1368*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1369*4bdc9457SAndroid Build Coastguard Worker } 1370*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,positive_nan)1371*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, positive_nan) { 1372*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1373*4bdc9457SAndroid Build Coastguard Worker 1374*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1375*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1376*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1377*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1378*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 1379*4bdc9457SAndroid Build Coastguard Worker } 1380*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1381*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1382*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1383*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1384*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1385*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1386*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1387*4bdc9457SAndroid Build Coastguard Worker } 1388*4bdc9457SAndroid Build Coastguard Worker } 1389*4bdc9457SAndroid Build Coastguard Worker } 1390*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16,negative_nan)1391*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__NEONFP16, negative_nan) { 1392*4bdc9457SAndroid Build Coastguard Worker TEST_REQUIRES_ARM_NEON_FP16; 1393*4bdc9457SAndroid Build Coastguard Worker 1394*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1395*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1396*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1397*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1398*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 1399*4bdc9457SAndroid Build Coastguard Worker } 1400*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__neonfp16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1401*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1402*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1403*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1404*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1405*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1406*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1407*4bdc9457SAndroid Build Coastguard Worker } 1408*4bdc9457SAndroid Build Coastguard Worker } 1409*4bdc9457SAndroid Build Coastguard Worker } 1410*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_ARM || XNN_ARCH_ARM64 1411*4bdc9457SAndroid Build Coastguard Worker 1412*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD TEST(CVT__WASMSIMD_INT16,positive_normal)1413*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, positive_normal) { 1414*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1415*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1416*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 1417*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1418*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1419*4bdc9457SAndroid Build Coastguard Worker } 1420*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1421*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1422*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1423*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1424*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1425*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1426*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1427*4bdc9457SAndroid Build Coastguard Worker } 1428*4bdc9457SAndroid Build Coastguard Worker } 1429*4bdc9457SAndroid Build Coastguard Worker } 1430*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,negative_normal)1431*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, negative_normal) { 1432*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1433*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1434*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 1435*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1436*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1437*4bdc9457SAndroid Build Coastguard Worker } 1438*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1439*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1440*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1441*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1442*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1443*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1444*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1445*4bdc9457SAndroid Build Coastguard Worker } 1446*4bdc9457SAndroid Build Coastguard Worker } 1447*4bdc9457SAndroid Build Coastguard Worker } 1448*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,positive_zero)1449*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, positive_zero) { 1450*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1451*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1452*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 1453*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1454*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1455*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1456*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1457*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1458*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1459*4bdc9457SAndroid Build Coastguard Worker } 1460*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,negative_zero)1461*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, negative_zero) { 1462*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1463*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1464*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 1465*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1466*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1467*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1468*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1469*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1470*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1471*4bdc9457SAndroid Build Coastguard Worker } 1472*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,positive_subnormal)1473*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, positive_subnormal) { 1474*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1475*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1476*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 1477*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1478*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 1479*4bdc9457SAndroid Build Coastguard Worker } 1480*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1481*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1482*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1483*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1484*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1485*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1486*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1487*4bdc9457SAndroid Build Coastguard Worker } 1488*4bdc9457SAndroid Build Coastguard Worker } 1489*4bdc9457SAndroid Build Coastguard Worker } 1490*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,negative_subnormal)1491*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, negative_subnormal) { 1492*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1493*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1494*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 1495*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1496*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 1497*4bdc9457SAndroid Build Coastguard Worker } 1498*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1499*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1500*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1501*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1502*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1503*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1504*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1505*4bdc9457SAndroid Build Coastguard Worker } 1506*4bdc9457SAndroid Build Coastguard Worker } 1507*4bdc9457SAndroid Build Coastguard Worker } 1508*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,positive_infinity)1509*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, positive_infinity) { 1510*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1511*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1512*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 1513*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1514*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1515*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1516*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1517*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1518*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1519*4bdc9457SAndroid Build Coastguard Worker } 1520*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,negative_infinity)1521*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, negative_infinity) { 1522*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1523*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1524*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 1525*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1526*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1527*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1528*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1529*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1530*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1531*4bdc9457SAndroid Build Coastguard Worker } 1532*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,positive_nan)1533*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, positive_nan) { 1534*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1535*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1536*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1537*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1538*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 1539*4bdc9457SAndroid Build Coastguard Worker } 1540*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1541*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1542*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1543*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1544*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1545*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1546*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1547*4bdc9457SAndroid Build Coastguard Worker } 1548*4bdc9457SAndroid Build Coastguard Worker } 1549*4bdc9457SAndroid Build Coastguard Worker } 1550*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16,negative_nan)1551*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT16, negative_nan) { 1552*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1553*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1554*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1555*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1556*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 1557*4bdc9457SAndroid Build Coastguard Worker } 1558*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int16(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1559*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1560*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1561*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1562*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1563*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1564*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1565*4bdc9457SAndroid Build Coastguard Worker } 1566*4bdc9457SAndroid Build Coastguard Worker } 1567*4bdc9457SAndroid Build Coastguard Worker } 1568*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD 1569*4bdc9457SAndroid Build Coastguard Worker 1570*4bdc9457SAndroid Build Coastguard Worker #if XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD TEST(CVT__WASMSIMD_INT32,positive_normal)1571*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, positive_normal) { 1572*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1573*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1574*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x0400); n < UINT16_C(0x7C00); n += kBlockSize) { 1575*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1576*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1577*4bdc9457SAndroid Build Coastguard Worker } 1578*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1579*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1580*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1581*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1582*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1583*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1584*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1585*4bdc9457SAndroid Build Coastguard Worker } 1586*4bdc9457SAndroid Build Coastguard Worker } 1587*4bdc9457SAndroid Build Coastguard Worker } 1588*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,negative_normal)1589*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, negative_normal) { 1590*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1591*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1592*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8400); n < UINT16_C(0xFC00); n += kBlockSize) { 1593*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1594*4bdc9457SAndroid Build Coastguard Worker inputs[i] = n + i; 1595*4bdc9457SAndroid Build Coastguard Worker } 1596*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1597*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1598*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1599*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1600*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1601*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1602*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1603*4bdc9457SAndroid Build Coastguard Worker } 1604*4bdc9457SAndroid Build Coastguard Worker } 1605*4bdc9457SAndroid Build Coastguard Worker } 1606*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,positive_zero)1607*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, positive_zero) { 1608*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1609*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1610*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x0000)); 1611*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1612*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1613*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1614*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1615*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1616*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1617*4bdc9457SAndroid Build Coastguard Worker } 1618*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,negative_zero)1619*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, negative_zero) { 1620*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1621*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1622*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x8000)); 1623*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1624*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1625*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1626*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1627*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1628*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1629*4bdc9457SAndroid Build Coastguard Worker } 1630*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,positive_subnormal)1631*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, positive_subnormal) { 1632*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1633*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1634*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = 0; n < UINT16_C(0x0400); n += kBlockSize) { 1635*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1636*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x0001)); 1637*4bdc9457SAndroid Build Coastguard Worker } 1638*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1639*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1640*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1641*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1642*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1643*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1644*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1645*4bdc9457SAndroid Build Coastguard Worker } 1646*4bdc9457SAndroid Build Coastguard Worker } 1647*4bdc9457SAndroid Build Coastguard Worker } 1648*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,negative_subnormal)1649*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, negative_subnormal) { 1650*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1651*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1652*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x8000); n < UINT16_C(0x8400); n += kBlockSize) { 1653*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1654*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x8001)); 1655*4bdc9457SAndroid Build Coastguard Worker } 1656*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1657*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1658*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1659*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1660*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1661*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1662*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1663*4bdc9457SAndroid Build Coastguard Worker } 1664*4bdc9457SAndroid Build Coastguard Worker } 1665*4bdc9457SAndroid Build Coastguard Worker } 1666*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,positive_infinity)1667*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, positive_infinity) { 1668*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1669*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1670*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0x7C00)); 1671*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1672*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1673*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1674*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1675*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1676*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1677*4bdc9457SAndroid Build Coastguard Worker } 1678*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,negative_infinity)1679*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, negative_infinity) { 1680*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1681*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1682*4bdc9457SAndroid Build Coastguard Worker std::fill(inputs.begin(), inputs.end(), UINT16_C(0xFC00)); 1683*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1684*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[0])); 1685*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[0])) 1686*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[0]) 1687*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1688*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[0]); 1689*4bdc9457SAndroid Build Coastguard Worker } 1690*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,positive_nan)1691*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, positive_nan) { 1692*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1693*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1694*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1695*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1696*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(n + i, UINT16_C(0x7C01)); 1697*4bdc9457SAndroid Build Coastguard Worker } 1698*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1699*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1700*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1701*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1702*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1703*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1704*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1705*4bdc9457SAndroid Build Coastguard Worker } 1706*4bdc9457SAndroid Build Coastguard Worker } 1707*4bdc9457SAndroid Build Coastguard Worker } 1708*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32,negative_nan)1709*4bdc9457SAndroid Build Coastguard Worker TEST(CVT__WASMSIMD_INT32, negative_nan) { 1710*4bdc9457SAndroid Build Coastguard Worker std::vector<uint16_t, AlignedAllocator<uint16_t, 64>> inputs(kBlockSize); 1711*4bdc9457SAndroid Build Coastguard Worker std::vector<float, AlignedAllocator<float, 64>> outputs(kBlockSize); 1712*4bdc9457SAndroid Build Coastguard Worker for (uint16_t n = UINT16_C(0x7C00); n < UINT16_C(0x8000); n += kBlockSize) { 1713*4bdc9457SAndroid Build Coastguard Worker for (uint16_t i = 0; i < kBlockSize; i++) { 1714*4bdc9457SAndroid Build Coastguard Worker inputs[i] = std::max<uint16_t>(UINT16_C(0x8000) | (n + i), UINT16_C(0xFC01)); 1715*4bdc9457SAndroid Build Coastguard Worker } 1716*4bdc9457SAndroid Build Coastguard Worker xnn_math_f16_f32_cvt__wasmsimd_int32(kBlockSize * sizeof(float), inputs.data(), outputs.data()); 1717*4bdc9457SAndroid Build Coastguard Worker for (uint32_t i = 0; i < kBlockSize; i++) { 1718*4bdc9457SAndroid Build Coastguard Worker const uint32_t reference_output = float_as_uint32(fp16_ieee_to_fp32_value(inputs[i])); 1719*4bdc9457SAndroid Build Coastguard Worker ASSERT_EQ(reference_output, float_as_uint32(outputs[i])) 1720*4bdc9457SAndroid Build Coastguard Worker << "input = 0x" << std::hex << std::setw(4) << std::setfill('0') << float_as_uint32(inputs[i]) 1721*4bdc9457SAndroid Build Coastguard Worker << ", reference = 0x" << std::hex << std::setw(8) << std::setfill('0') << reference_output 1722*4bdc9457SAndroid Build Coastguard Worker << ", optimized = 0x" << std::hex << std::setw(8) << std::setfill('0') << float_as_uint32(outputs[i]); 1723*4bdc9457SAndroid Build Coastguard Worker } 1724*4bdc9457SAndroid Build Coastguard Worker } 1725*4bdc9457SAndroid Build Coastguard Worker } 1726*4bdc9457SAndroid Build Coastguard Worker #endif // XNN_ARCH_WASMSIMD || XNN_ARCH_WASMRELAXEDSIMD 1727