<div dir="ltr">Sorry I haven't gotten back on this. It got lost somehow.<br><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Mar 10, 2017 at 1:56 AM, Iago Toral <span dir="ltr"><<a href="mailto:itoral@igalia.com" target="_blank">itoral@igalia.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">On Thu, 2017-03-09 at 14:05 -0800, Jason Ekstrand wrote:<br>
> ---<br>
> src/compiler/nir/nir.h <wbr> | 4 ++++<br>
> src/compiler/nir/nir_<wbr>constant_expressions.py | 16 +++++++++++++++-<br>
> src/compiler/nir/nir_opcodes.<wbr>py | 6 +++++-<br>
> 3 files changed, 24 insertions(+), 2 deletions(-)<br>
><br>
> diff --git a/src/compiler/nir/nir.h b/src/compiler/nir/nir.h<br>
> index 57b8be3..eaa103d 100644<br>
> --- a/src/compiler/nir/nir.h<br>
> +++ b/src/compiler/nir/nir.h<br>
> @@ -105,6 +105,10 @@ typedef enum {<br>
> typedef union {<br>
> float f32[4];<br>
> double f64[4];<br>
> + int8_t i8[4];<br>
> + uint8_t u8[4];<br>
> + int16_t i16[4];<br>
> + uint16_t u16[4];<br>
> int32_t i32[4];<br>
> uint32_t u32[4];<br>
> int64_t i64[4];<br>
> <br>
> diff --git a/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> b/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> index aecca8b..cbda4b1 100644<br>
> --- a/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> +++ b/src/compiler/nir/nir_<wbr>constant_expressions.py<br>
> @@ -14,8 +14,10 @@ def type_size(type_):<br>
> def type_sizes(type_):<br>
> if type_has_size(type_):<br>
> return [type_size(type_)]<br>
> + elif type_ == 'float':<br>
> + return [16, 32, 64]<br>
> else:<br>
> - return [32, 64]<br>
> + return [8, 16, 32, 64]<br>
> <br>
> def type_add_size(type_, size):<br>
> if type_has_size(type_):<br>
> @@ -34,6 +36,8 @@ def op_bit_sizes(op):<br>
> def get_const_field(type_):<br>
> if type_ == "bool32":<br>
> return "u32"<br>
> + elif type_ == "float16":<br>
> + return "u16"<br>
<br>
</div></div>I was wondering why not have a f16 field with type float16_t<br>
in nir_const_value instead, but reading the rest of the patch it seems<br>
we really want to work with 32-bit floats and then encode results back to 16-bit values? Is it because there are some operations that we can't implement directly with half-floats?<span class="HOEnZb"><font color="#888888"><br></font></span></blockquote><div><br></div><div>Yes. CPUs cannot, in general, work with 16-bit floats so there is no actual float16_t type in C. We typedef float to float16_t below just because it makes the codegen easier. In reality, all 16-bit operations have to be done in 32-bit with a manual conversion to/from 16-bit float on both sides.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="HOEnZb"><font color="#888888">
Iago<br>
</font></span><div class="HOEnZb"><div class="h5"><br>
> else:<br>
> m = type_split_re.match(type_)<br>
> if not m:<br>
> @@ -246,6 +250,7 @@ unpack_half_1x16(uint16_t u)<br>
> }<br>
> <br>
> /* Some typed vector structures to make things like src0.y work */<br>
> +typedef float float16_t;<br>
> typedef float float32_t;<br>
> typedef double float64_t;<br>
> typedef bool bool32_t;<br>
> @@ -297,6 +302,8 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
> % for k in range(op.input_sizes[j]):<br>
> % if input_types[j] == "bool32":<br>
> _src[${j}].<wbr>u32[${k}] != 0,<br>
> + % elif input_types[j] == "float16":<br>
> + _mesa_half_to_<wbr>float(_src[${j}].u16[${k}]),<br>
> % else:<br>
> _src[${j}].${<wbr>get_const_field(input_types[j]<wbr>)}[${k}],<br>
> % endif<br>
> @@ -322,6 +329,9 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
> <% continue %><br>
> % elif input_types[j] == "bool32":<br>
> const bool src${j} = _src[${j}].u32[_i] != 0;<br>
> + % elif input_types[j] == "float16":<br>
> + const float src${j} =<br>
> + _mesa_<wbr>half_to_float(_src[${j}].u16[_<wbr>i]);<br>
> % else:<br>
> const ${input_types[j]}_t src${j} =<br>
> _src[${<wbr>j}].${get_const_field(input_<wbr>types[j])}[_<br>
> i];<br>
> @@ -344,6 +354,8 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
> % if output_type == "bool32":<br>
> ## Sanitize the C value to a proper NIR bool<br>
> _dst_val.u32[_<wbr>i] = dst ? NIR_TRUE : NIR_FALSE;<br>
> + % elif output_type == "float16":<br>
> + _dst_val.u16[_<wbr>i] = _mesa_float_to_half(dst);<br>
> % else:<br>
> _dst_val.${<wbr>get_const_field(output_type)}[<wbr>_i] = dst;<br>
> % endif<br>
> @@ -371,6 +383,8 @@ evaluate_${name}(MAYBE_UNUSED unsigned<br>
> num_components, unsigned bit_size,<br>
> % if output_type == "bool32":<br>
> ## Sanitize the C value to a proper NIR bool<br>
> _dst_val.u32[$<wbr>{k}] = dst.${"xyzw"[k]} ? NIR_TRUE :<br>
> NIR_FALSE;<br>
> + % elif output_type == "float16":<br>
> + _dst_val.u16[$<wbr>{k}] =<br>
> _mesa_float_to_half(dst.${"<wbr>xyzw"[k]});<br>
> % else:<br>
> _dst_val.${<wbr>get_const_field(output_type)}[<wbr>${k}] =<br>
> dst.${"xyzw"[k]};<br>
> % endif<br>
> diff --git a/src/compiler/nir/nir_<wbr>opcodes.py<br>
> b/src/compiler/nir/nir_<wbr>opcodes.py<br>
> index 53e9aff..37c655b 100644<br>
> --- a/src/compiler/nir/nir_<wbr>opcodes.py<br>
> +++ b/src/compiler/nir/nir_<wbr>opcodes.py<br>
> @@ -175,7 +175,11 @@ for src_t in [tint, tuint, tfloat]:<br>
> dst_types = [tint, tuint, tfloat]<br>
> <br>
> for dst_t in dst_types:<br>
> - for bit_size in [32, 64]:<br>
> + if dst_t == tfloat:<br>
> + bit_sizes = [16, 32, 64]<br>
> + else:<br>
> + bit_sizes = [8, 16, 32, 64]<br>
> + for bit_size in bit_sizes:<br>
> unop_convert("{}2{}{<wbr>}".format(src_t[0], dst_t[0],<br>
> bit_size),<br>
> dst_t + str(bit_size), src_t, "src0")<br>
> </div></div></blockquote></div><br></div></div>