|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Fix some issues with the FP test in preparation for switching the host
tests to compile in 32-bit mode. There are a few things going on with
the FP tests.
The first thing to know about x86 is the compiler has a hard time
restricting itself to 32-bits even when you're seemingly only working
with float types. Part of this is C's fault, since C promotes floats to
doubles in cases like arguments handed to printf. This results in
weirdness. For instance, if I add a union like this:
union evanfloat {
float f;
unsigned int i;
};
And then print out the result and golden values from test_fpv3_dot(), I
get this:
421a5e35 421a5e35 38.592000 38.591999
How is it that the same hex value prints two different floats, even when
the values I'm passing are from the union, and I can see the byte value
contents of the floats are the same? The compiler gets exuberant
here and keeps the computation result in the floating point registers,
then lets them ride on through to printf. As an experiment, I tried
printing values from this union instead:
union evandouble {
double d;
unsigned long long i;
};
And I get the following:
40434bc6a58b4390 40434bc6a0000000 38.592000 38.591999
What this shows is that even though the return type of fpv3_dot() is a
float, the compiler is carrying around the extra precision of a double
computation.
The test was all carefully crafted to have the correct answers,
unfortunately with this implicit double advantage built in. So we run
afoul of this when we try to compile with -m32. i686 only has access to
the old x87 FPU instructions, rather than SSE2 that's part of AMD64. As
such, the double advantages come out slightly different, resulting in
1ULP (unit in last place) variations between x86_64 and i686. These
are likely errors that accumulate differently in intermediate
results of functions like fpv3_dot().
Really that's all fine, we just have to account for this in the test
so that both x86_64 and i686 can pass correctly.
In some cases like test_fpv3_dot(), this can be achieved by creating a
volatile fp_t and assigning the result to that. This forces the compiler
to dump the final value out of the FPU registers and save a float into
memory, truncating the hidden double bits.
In other cases, AMD64 and i686 disagreed by 1ULP, but the golden value
disagreed with both by a handful of ULP. Fix those golden values so
their hex values lined up better.
But even with the fixed golden values, amd64 and i686 still disagreed on
some results by 1ULP. In these cases it was necessary to increase the
tolerance from 0.0 to an approximation of 1ULP. As a side note,
expressing the tolerances as absolute values is a bit brittle, as it
requires that your testing values and results stay within a certain
exponent. If we were to write a new floating point test, it might be
better to have the test comparison macros decompose the values into
exponent and mantissa, and then compare those separately with a
tolerance on the mantissa.
BUG=b:179062230
BRANCH=none
TEST=make -j runhosttest BOARD=host on both amd64 and i686
Signed-off-by: Evan Green <evgreen@chromium.org>
Change-Id: I3f8d36713dfa9f2f8adefb1b4db1e47b84dec1f0
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3059227
Reviewed-by: Eric Yilun Lin <yllin@google.com>
|
|
Modified from floating point version. This includes changes to
vec3, vec4, mat33, mat44, and mag_cal.
Now fixed-point type (fp_*) functions is a function wrapper for both
fixed-point and floating point version operations:
* define CONFIG_FPU to use floating version mag_cal
* undef CONFIG_FPU to use fixed-point version mag_cal
Also, add tests for both float and fp types operations.
TEST=define CONFIG_FPU; flash on reef; See ARC++ magnetmeter app moving.
TEST=undef CONFIG_FPU; flash on reef; See ARC++ magnetmeter app moving.
TEST=make runtests -j
TEST=make buildalltests -j
BUG=b:113364863
BRANCH=None
Change-Id: Ie695945acb666912babb2a603e09c602a0624d44
Signed-off-by: Yilun Lin <yllin@google.com>
Reviewed-on: https://chromium-review.googlesource.com/1260704
Commit-Ready: Yilun Lin <yllin@chromium.org>
Tested-by: Yilun Lin <yllin@chromium.org>
Reviewed-by: Nicolas Boichat <drinkcat@chromium.org>
|