From c782c517ae508f6508cefe3acdd05e77b8f8247f Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Mon, 8 Jun 2020 17:15:27 -0700 Subject: [PATCH 1/3] add conversions for halfs to and from normalized image channel orders --- ext/cl_khr_fp16.asciidoc | 123 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/ext/cl_khr_fp16.asciidoc b/ext/cl_khr_fp16.asciidoc index b85eac29..a80735d6 100644 --- a/ext/cl_khr_fp16.asciidoc +++ b/ext/cl_khr_fp16.asciidoc @@ -1788,3 +1788,126 @@ precision floating-point values and performing the operation in single precision floating-point. In this case, the implementation will use the_ `half` _scalar or vector data type as a storage only format_. + +[[cl_khr_fp16-additions-to-chapter-8-of-the-opencl-2.0-specification]] +=== Additions to Chapter 8 of the OpenCL 2.0 C Specification + +Add new sub-sections to _section 8.3.1. Conversion rules for normalized integer channel data types_: + +[[cl_khr_fp16-converting-normalized-integer-channel-data-types-to-floating-point-values]] +==== Converting normalized integer channel data types to half precision floating-point values + +For images created with image channel data type of `CL_UNORM_INT8` and +`CL_UNORM_INT16`, *read_imagef* will convert the channel values from an +8-bit or 16-bit unsigned integer to normalized half precision +floating-point values in the range [`0.0h`, `1.0h`]. + +For images created with image channel data type of `CL_SNORM_INT8` and +`CL_SNORM_INT16`, *read_imagef* will convert the channel values from an +8-bit or 16-bit signed integer to normalized half precision floating-point +values in the range [`-1.0h`, `1.0h`]. + +These conversions are performed as follows: + +`CL_UNORM_INT8` (8-bit unsigned integer) {rightarrow} `half` + + :: normalized `half` value = `round_to_half(c / 255)` + +`CL_UNORM_INT_101010` (10-bit unsigned integer) {rightarrow} `half` + + :: normalized `half` value = `round_to_half(c / 1023)` + +`CL_UNORM_INT16` (16-bit unsigned integer) {rightarrow} `half` + + :: normalized `half` value = `round_to_half(c / 65535)` + +`CL_SNORM_INT8` (8-bit signed integer) {rightarrow} `half` + + :: normalized `half` value = `max(-1.0f, round_to_half(c / 127))` + +`CL_SNORM_INT16` (16-bit signed integer) {rightarrow} `half` + + :: normalized `half` value = `max(-1.0f, round_to_half(c / 32767))` + +The accuracy of the above conversions must be \<= 1.5 ulp except for the +following cases. + +For `CL_UNORM_INT8` + + :: 0 must convert to `0.0h` and + :: 255 must convert to `1.0h` + +For `CL_UNORM_INT_101010` + + :: 0 must convert to `0.0h` and + :: 1023 must convert to `1.0h` + +For `CL_UNORM_INT16` + + :: 0 must convert to `0.0h` and + :: 65535 must convert to `1.0h` + +For `CL_SNORM_INT8` + + :: -128 and -127 must convert to `-1.0j`, + :: 0 must convert to `0.0h` and + :: 127 must convert to `1.0h` + +For `CL_SNORM_INT16` + + :: -32768 and -32767 must convert to `-1.0h`, + :: 0 must convert to `0.0h` and + :: 32767 must convert to `1.0h` + + +[[cl_khr_fp16-converting-floating-point-values-to-normalized-integer-channel-data-types]] +==== Converting half precision floating-point values to normalized integer channel data types + +For images created with image channel data type of `CL_UNORM_INT8` and +`CL_UNORM_INT16`, *write_imagef* will convert the floating-point color value +to an 8-bit or 16-bit unsigned integer. + +For images created with image channel data type of `CL_SNORM_INT8` and +`CL_SNORM_INT16`, *write_imagef* will convert the floating-point color value +to an 8-bit or 16-bit signed integer. + +The preferred conversion uses the round to nearest even (`_rte`) rounding +mode, but OpenCL implementations may choose to approximate the rounding mode +used in the conversions described below. +When approximate rounding is used instead of the preferred rounding, +the result of the conversion must satisfy the bound given below. + +`half` {rightarrow} `CL_UNORM_INT8` (8-bit unsigned integer) + + :: Let f~exact~ = *max*(`0`, *min*(`f * 255`, `255`)) + :: Let f~preferred~ = *convert_uchar_sat_rte*(`f * 255.0f`) + :: Let f~approx~ = *convert_uchar_sat_*(`f * 255.0f`) + :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 + +`half` {rightarrow} `CL_UNORM_INT_101010` (10-bit unsigned integer) + + :: Let f~exact~ = *max*(`0`, *min*(`f * 1023`, `1023`)) + :: Let f~preferred~ = *min*(*convert_ushort_sat_rte*(`f * 1023.0f`), `1023`) + :: Let f~approx~ = *convert_ushort_sat_*(`f * 1023.0f`) + :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 + +`half` {rightarrow} `CL_UNORM_INT16` (16-bit unsigned integer) + + :: Let f~exact~ = *max*(`0`, *min*(`f * 65535`, `65535`)) + :: Let f~preferred~ = *convert_ushort_sat_rte*(`f * 65535.0f`) + :: Let f~approx~ = *convert_ushort_sat_*(`f * 65535.0f`) + :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 + +`half` {rightarrow} `CL_SNORM_INT8` (8-bit signed integer) + + :: Let f~exact~ = *max*(`-128`, *min*(`f * 127`, `127`)) + :: Let f~preferred~ = *convert_char_sat_rte*(`f * 127.0f`) + :: Let f~approx~ = *convert_char_sat_*(`f * 127.0f`) + :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 + +`half` {rightarrow} `CL_SNORM_INT16` (16-bit signed integer) + + :: Let f~exact~ = *max*(`-32768`, *min*(`f * 32767`, `32767`)) + :: Let f~preferred~ = *convert_short_sat_rte*(`f * 32767.0f`) + :: Let f~approx~ = *convert_short_sat_*(`f * 32767.0f`) + :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 From d89784b60e02793eddc9cc2a16037ff7d14789b7 Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Mon, 29 Jun 2020 16:45:08 -0700 Subject: [PATCH 2/3] fix list syntax --- ext/cl_khr_fp16.asciidoc | 89 +++++++++++++++++++++++----------------- 1 file changed, 52 insertions(+), 37 deletions(-) diff --git a/ext/cl_khr_fp16.asciidoc b/ext/cl_khr_fp16.asciidoc index a80735d6..26127452 100644 --- a/ext/cl_khr_fp16.asciidoc +++ b/ext/cl_khr_fp16.asciidoc @@ -1811,53 +1811,63 @@ These conversions are performed as follows: `CL_UNORM_INT8` (8-bit unsigned integer) {rightarrow} `half` - :: normalized `half` value = `round_to_half(c / 255)` +[none] +* normalized `half` value = `round_to_half(c / 255)` `CL_UNORM_INT_101010` (10-bit unsigned integer) {rightarrow} `half` - :: normalized `half` value = `round_to_half(c / 1023)` +[none] +* normalized `half` value = `round_to_half(c / 1023)` `CL_UNORM_INT16` (16-bit unsigned integer) {rightarrow} `half` - :: normalized `half` value = `round_to_half(c / 65535)` +[none] +* normalized `half` value = `round_to_half(c / 65535)` `CL_SNORM_INT8` (8-bit signed integer) {rightarrow} `half` - :: normalized `half` value = `max(-1.0f, round_to_half(c / 127))` +[none] +* normalized `half` value = `max(-1.0f, round_to_half(c / 127))` `CL_SNORM_INT16` (16-bit signed integer) {rightarrow} `half` - :: normalized `half` value = `max(-1.0f, round_to_half(c / 32767))` +[none] +* normalized `half` value = `max(-1.0f, round_to_half(c / 32767))` The accuracy of the above conversions must be \<= 1.5 ulp except for the following cases. For `CL_UNORM_INT8` - :: 0 must convert to `0.0h` and - :: 255 must convert to `1.0h` +[none] +* 0 must convert to `0.0h` and +* 255 must convert to `1.0h` For `CL_UNORM_INT_101010` - :: 0 must convert to `0.0h` and - :: 1023 must convert to `1.0h` +[none] +* 0 must convert to `0.0h` and +* 1023 must convert to `1.0h` For `CL_UNORM_INT16` - :: 0 must convert to `0.0h` and - :: 65535 must convert to `1.0h` +[none] +* 0 must convert to `0.0h` and +* 65535 must convert to `1.0h` For `CL_SNORM_INT8` - :: -128 and -127 must convert to `-1.0j`, - :: 0 must convert to `0.0h` and - :: 127 must convert to `1.0h` +[none] +* -128 and -127 must convert to `-1.0j`, +* 0 must convert to `0.0h` and +* 127 must convert to `1.0h` For `CL_SNORM_INT16` - :: -32768 and -32767 must convert to `-1.0h`, - :: 0 must convert to `0.0h` and - :: 32767 must convert to `1.0h` +[none] +* -32768 and -32767 must convert to `-1.0h`, +* 0 must convert to `0.0h` and +* 32767 must convert to `1.0h` [[cl_khr_fp16-converting-floating-point-values-to-normalized-integer-channel-data-types]] @@ -1879,35 +1889,40 @@ the result of the conversion must satisfy the bound given below. `half` {rightarrow} `CL_UNORM_INT8` (8-bit unsigned integer) - :: Let f~exact~ = *max*(`0`, *min*(`f * 255`, `255`)) - :: Let f~preferred~ = *convert_uchar_sat_rte*(`f * 255.0f`) - :: Let f~approx~ = *convert_uchar_sat_*(`f * 255.0f`) - :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 +[none] +* Let f~exact~ = *max*(`0`, *min*(`f * 255`, `255`)) +* Let f~preferred~ = *convert_uchar_sat_rte*(`f * 255.0f`) +* Let f~approx~ = *convert_uchar_sat_*(`f * 255.0f`) +* *fabs*(f~exact~ - f~approx~) must be \<= 0.6 `half` {rightarrow} `CL_UNORM_INT_101010` (10-bit unsigned integer) - :: Let f~exact~ = *max*(`0`, *min*(`f * 1023`, `1023`)) - :: Let f~preferred~ = *min*(*convert_ushort_sat_rte*(`f * 1023.0f`), `1023`) - :: Let f~approx~ = *convert_ushort_sat_*(`f * 1023.0f`) - :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 +[none] +* Let f~exact~ = *max*(`0`, *min*(`f * 1023`, `1023`)) +* Let f~preferred~ = *min*(*convert_ushort_sat_rte*(`f * 1023.0f`), `1023`) +* Let f~approx~ = *convert_ushort_sat_*(`f * 1023.0f`) +* *fabs*(f~exact~ - f~approx~) must be \<= 0.6 `half` {rightarrow} `CL_UNORM_INT16` (16-bit unsigned integer) - :: Let f~exact~ = *max*(`0`, *min*(`f * 65535`, `65535`)) - :: Let f~preferred~ = *convert_ushort_sat_rte*(`f * 65535.0f`) - :: Let f~approx~ = *convert_ushort_sat_*(`f * 65535.0f`) - :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 +[none] +* Let f~exact~ = *max*(`0`, *min*(`f * 65535`, `65535`)) +* Let f~preferred~ = *convert_ushort_sat_rte*(`f * 65535.0f`) +* Let f~approx~ = *convert_ushort_sat_*(`f * 65535.0f`) +* *fabs*(f~exact~ - f~approx~) must be \<= 0.6 `half` {rightarrow} `CL_SNORM_INT8` (8-bit signed integer) - :: Let f~exact~ = *max*(`-128`, *min*(`f * 127`, `127`)) - :: Let f~preferred~ = *convert_char_sat_rte*(`f * 127.0f`) - :: Let f~approx~ = *convert_char_sat_*(`f * 127.0f`) - :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 +[none] +* Let f~exact~ = *max*(`-128`, *min*(`f * 127`, `127`)) +* Let f~preferred~ = *convert_char_sat_rte*(`f * 127.0f`) +* Let f~approx~ = *convert_char_sat_*(`f * 127.0f`) +* *fabs*(f~exact~ - f~approx~) must be \<= 0.6 `half` {rightarrow} `CL_SNORM_INT16` (16-bit signed integer) - :: Let f~exact~ = *max*(`-32768`, *min*(`f * 32767`, `32767`)) - :: Let f~preferred~ = *convert_short_sat_rte*(`f * 32767.0f`) - :: Let f~approx~ = *convert_short_sat_*(`f * 32767.0f`) - :: *fabs*(f~exact~ - f~approx~) must be \<= 0.6 +[none] +* Let f~exact~ = *max*(`-32768`, *min*(`f * 32767`, `32767`)) +* Let f~preferred~ = *convert_short_sat_rte*(`f * 32767.0f`) +* Let f~approx~ = *convert_short_sat_*(`f * 32767.0f`) +* *fabs*(f~exact~ - f~approx~) must be \<= 0.6 From 2235d92255a422926a17c8ff749b36e31523a6e1 Mon Sep 17 00:00:00 2001 From: Ben Ashbaugh Date: Mon, 29 Jun 2020 16:48:36 -0700 Subject: [PATCH 3/3] change literals from float 1.0f to half 1.0h --- ext/cl_khr_fp16.asciidoc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/ext/cl_khr_fp16.asciidoc b/ext/cl_khr_fp16.asciidoc index 26127452..58a42f92 100644 --- a/ext/cl_khr_fp16.asciidoc +++ b/ext/cl_khr_fp16.asciidoc @@ -1827,12 +1827,12 @@ These conversions are performed as follows: `CL_SNORM_INT8` (8-bit signed integer) {rightarrow} `half` [none] -* normalized `half` value = `max(-1.0f, round_to_half(c / 127))` +* normalized `half` value = `max(-1.0h, round_to_half(c / 127))` `CL_SNORM_INT16` (16-bit signed integer) {rightarrow} `half` [none] -* normalized `half` value = `max(-1.0f, round_to_half(c / 32767))` +* normalized `half` value = `max(-1.0h, round_to_half(c / 32767))` The accuracy of the above conversions must be \<= 1.5 ulp except for the following cases. @@ -1858,7 +1858,7 @@ For `CL_UNORM_INT16` For `CL_SNORM_INT8` [none] -* -128 and -127 must convert to `-1.0j`, +* -128 and -127 must convert to `-1.0h`, * 0 must convert to `0.0h` and * 127 must convert to `1.0h`