1// 2// Copyright (c) 2020 The Khronos Group Inc. 3// 4// Licensed under the Apache License, Version 2.0 (the "License"); 5// you may not use this file except in compliance with the License. 6// You may obtain a copy of the License at 7// 8// http://www.apache.org/licenses/LICENSE-2.0 9// 10// Unless required by applicable law or agreed to in writing, software 11// distributed under the License is distributed on an "AS IS" BASIS, 12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13// See the License for the specific language governing permissions and 14// limitations under the License. 15// 16 17#include <math.h> 18#include <stdio.h> 19 20#include "CL/cl_half.h" 21 22union FI { 23 float f; 24 uint32_t i; 25}; 26 27int test_half_to_float(cl_half h, cl_float ref) 28{ 29 cl_float f = cl_half_to_float(h); 30 if (f != ref) { 31 union FI f_i, ref_i; 32 f_i.f = f; 33 ref_i.f = ref; 34 printf("\nERROR: converting 0x%04x to float: expected 0x%08x, got 0x%08x\n", 35 h, ref_i.i, f_i.i); 36 return 0; 37 } 38 return 1; 39} 40 41int test_half_from_float(cl_float f, cl_half ref, 42 cl_half_rounding_mode mode, const char *mode_str) 43{ 44 cl_half h = cl_half_from_float(f, mode); 45 if (h != ref) { 46 union FI f_i; 47 f_i.f = f; 48 printf( 49 "\nERROR: converting 0x%08x to half (%s): expected 0x%04x, got 0x%04x\n", 50 f_i.i, mode_str, ref, h); 51 return 0; 52 } 53 return 1; 54} 55 56int main(void) 57{ 58 printf("\nChecking conversion routines in cl_half.h\n"); 59 60#define CHECK_TO_FLOAT(h, ref) \ 61 if (!test_half_to_float(h, ref)) { \ 62 printf("Test failed on line %d.\n", __LINE__); \ 63 return 1; \ 64 } 65 66 // Check a handful of values 67 CHECK_TO_FLOAT(0x0000, 0.f); 68 CHECK_TO_FLOAT(0x3c00, 1.f); 69 CHECK_TO_FLOAT(0xbc00, -1.f); 70 CHECK_TO_FLOAT(0x7c00, INFINITY); 71 CHECK_TO_FLOAT(0xfc00, -INFINITY); 72 73 74#define CHECK_FROM_FLOAT(f, ref, mode) \ 75 if (!test_half_from_float(f, ref, CL_HALF_##mode, #mode)) { \ 76 printf("Test failed on line %d.\n", __LINE__); \ 77 return 1; \ 78 } 79 80 // Check a handful of normal values 81 CHECK_FROM_FLOAT(0.f, 0x0000, RTE); 82 CHECK_FROM_FLOAT(1.f, 0x3c00, RTE); 83 CHECK_FROM_FLOAT(-1.f, 0xbc00, RTE); 84 CHECK_FROM_FLOAT(CL_HALF_MAX, 0x7bff, RTE); 85 CHECK_FROM_FLOAT(CL_HALF_MIN, 0x0400, RTE); 86 87 // Check huge positive (non-inf) values round properly 88 CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7c00, RTE); 89 CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7c00, RTP); 90 CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7bff, RTN); 91 CHECK_FROM_FLOAT(CL_HALF_MAX + 1000.f, 0x7bff, RTZ); 92 93 // Check huge negative (non-inf) values round properly 94 CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfc00, RTE); 95 CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfbff, RTP); 96 CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfc00, RTN); 97 CHECK_FROM_FLOAT(-(CL_HALF_MAX + 1000.f), 0xfbff, RTZ); 98#if 0 // Hexadecimal float constant is C++17 99 // Check tiny positive values round properly 100 CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTE); 101 CHECK_FROM_FLOAT(0x1.000000p-25, 0x0001, RTP); 102 CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTN); 103 CHECK_FROM_FLOAT(0x1.000000p-25, 0x0000, RTZ); 104 105 // Check tiny negative values round properly 106 CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTE); 107 CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTP); 108 CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8001, RTN); 109 CHECK_FROM_FLOAT(-0x1.000000p-25, 0x8000, RTZ); 110#else 111 // Check tiny positive values round properly 112 CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTE); 113 CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0001, RTP); 114 CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTN); 115 CHECK_FROM_FLOAT(2.98023223876953125e-08, 0x0000, RTZ); 116 117 // Check tiny negative values round properly 118 CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTE); 119 CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTP); 120 CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8001, RTN); 121 CHECK_FROM_FLOAT(-2.98023223876953125e-08, 0x8000, RTZ); 122#endif 123 printf("\nAll tests passed!\n"); 124 125 return 0; 126} 127