<div dir="ltr">On 21 January 2013 15:24, Chad Versace <span dir="ltr"><<a href="mailto:chad.versace@linux.intel.com" target="_blank">chad.versace@linux.intel.com</a>></span> wrote:<br><div class="gmail_extra"><div class="gmail_quote">
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">+def make_inputs_for_pack_half_2x16():<br>
+ # The domain of packHalf2x16 is ([-inf, +inf] + {NaN})^2. The function<br>
+ # does not clamp its input.<br>
+ #<br>
+ # We test both -0.0 and +0.0 in order to stress the implementation's<br>
+ # handling of zero.<br>
+<br>
+ subnormal_min = 2.0**(-14) * (1.0 / 2.0**10)<br>
+ subnormal_max = 2.0**(-24) * (1023.0 / 2.0**10)<br>
+ normal_min = 2.0**(-14) * (1.0 + 0.0 / 2.0**10)<br>
+ normal_max = 2.0**15 * (1.0 + 1023.0 / 2.0**10)<br>
+ min_step = 2.0**(-24)<br>
+ max_step = 2.0**5<br>
+<br>
+ pos = tuple(float32(x) for x in (<br>
+ # Inputs that result in 0.0 .<br>
+ #<br>
+ 0.0,<br>
+ 0.0 + 0.25 * min_step,<br>
+<br>
+ # A thorny input...<br>
+ #<br>
+ # if round_to_even:<br>
+ # f16 := 0.0<br>
+ # elif round_to_nearest:<br>
+ # f16 := subnormal_min<br>
+ #<br>
+ 0.0 + 0.50 * min_step,<br>
+<br>
+ # Inputs that result in a subnormal float16.<br>
+ #<br>
+ 0.0 + 0.75 * min_step,<br>
+ subnormal_min + 0.00 * min_step,<br>
+ subnormal_min + 0.25 * min_step,<br>
+ subnormal_min + 0.50 * min_step,<br>
+ subnormal_min + 0.75 * min_step,<br>
+ subnormal_min + 1.00 * min_step,<br>
+ subnormal_min + 1.25 * min_step,<br>
+ subnormal_min + 1.50 * min_step,<br>
+ subnormal_min + 1.75 * min_step,<br>
+ subnormal_min + 2.00 * min_step,<br>
+<br>
+ normal_min - 2.00 * min_step,<br>
+ normal_min - 1.75 * min_step,<br>
+ normal_min - 1.50 * min_step,<br>
+ normal_min - 1.25 * min_step,<br>
+ normal_min - 1.00 * min_step,<br>
+ normal_min - 0.75 * min_step,<br>
+<br>
+ # Inputs that result in a normal float16.<br>
+ #<br>
+ normal_min - 0.50 * min_step,<br>
+ normal_min - 0.25 * min_step,<br>
+ normal_min + 0.00 * min_step,<br>
+ normal_min + 0.25 * min_step,<br>
+ normal_min + 0.50 * min_step,<br>
+ normal_min + 0.75 * min_step,<br>
+ normal_min + 1.00 * min_step,<br>
+ normal_min + 1.25 * min_step,<br>
+ normal_min + 1.50 * min_step,<br>
+ normal_min + 1.75 * min_step,<br>
+ normal_min + 2.00 * min_step,<br>
+<br>
+ normal_max - 2.00 * max_step,<br>
+ normal_max - 1.75 * max_step,<br>
+ normal_max - 1.50 * max_step,<br>
+ normal_max - 1.25 * max_step,<br>
+ normal_max - 1.00 * max_step,<br>
+ normal_max - 0.75 * max_step,<br>
+ normal_max - 0.50 * max_step,<br>
+ normal_max - 0.25 * max_step,<br>
+ normal_max + 0.00 * max_step,<br>
+ normal_max + 0.25 * max_step,<br>
+<br>
+ # Inputs that result in infinity.<br>
+ #<br>
+ normal_max + 0.50 * max_step,<br>
+ normal_max + 0.75 * max_step,<br>
+ normal_max + 1.00 * max_step,<br>
+<br>
+ "+inf",<br>
+ ))<br></blockquote><div><br></div><div>Now that I've had a look at the Mesa implementation, I'd like to suggest adding a few values to this list:<br><br></div><div>A. 2.0 * normal_min + 0.75 * min_step<br></div>
<div>B. 2.5 * normal_min<br></div><div>C. 0.5<br></div><div>D. 1.0<br></div><div>E. 1.5<br></div><div>F. normal_max + 2.0 * max_step<br><br></div>Rationale for A: The smallest range of normal float16s (e=1) actually has the same precision as subnormals (e=0). Therefore, if we have a bug that causes inputs in the range [normal_min, 2*normal_min] to get misclassified as subnormals, there will actually be no bug--your Mesa code will do the right thing. However, if we have a bug that causes inputs even higher than 2*normal_min to get misclassified as subnormals, then the first set of values that will go wrong will be those in the range (2.0*normal_min + 0.5*min_step, 2*normal_min + 1.0*min_step). These will get incorrectly converted to e=2, m=1, when the correct conversion is to e=2, m=0. So it makes sense to drop a test point exactly in the center of this range, at 2.0*normal_min + 0.75*min_step.<br>
<br></div><div>Rationale for F: If we have a bug that causes inputs beyond normal_max to get misclassified as normals, normal_max + 1.00 * max_step will actually get correctly converted to infinity, since it will get represented as e=31, m=0.5, which rounds down (thanks to round-to-even behaviour) to e=31, m=0. However, values in the range (normal_max + 1.0*max_step, normal_max + 3.0*max_step) will get incorrectly converted to e=31, m=1, which is NaN. So it makes sense to drop a test point exactly in the center of this range, at normal_max + 2.0*max_step.<br>
<br></div><div>Rationale for B-E: It would be nice to test a few values whose mantissas and exponents aren't near the corners, just to make sure we haven't missed something stupid :)<br></div></div></div>