Closed ajdawson closed 8 years ago
Ping @dueben @samhatfield.
I've updated this branch. The main change is the use of a constructor interface instead of rpe_literal
. I feel this is a closer representation of what the interface does. I've also added tests and updated the documentation.
@dueben - can you review this when you get a chance please?
So I understand, in this example:
type(rpe_var) :: a, b, r
! Work with 10 bits precision by default.
RPE_DEFAULT_SBITS = 10
a = 1.234
b = 5.678
r = 0.9 * a + b
significand_bits(r) == 10
still, no? Even though the two intermediate calculations are performed in full precision, the full significand of 0.9 doesn't 'cross' the equals sign?
Correct, assignments always truncate to the number of bits the variable on the LHS has. This is a simplified example which probably wouldn't suffer too badly. However, we have has cases "in the wild" where this situation has caused big problems.
After offline discussion, I've changed back to the name rpe_literal
as it fits better with the intended usage scope, otherwise as it was.
Any last issues or objections @samhatfield @dueben?
Looks good to me!
Sometimes you want to perform a reduced-precision calculation that involves a real literal constant (something not defined as a variable), and currently this could cause the precision of intermediate steps to be increased.
A simple example:
Because of casting between mixed precision types the last calculation will be evaluated retaining 23 bits in the significand (the intermediate
tmp1 = 0.9 * a
is stored at 23 bits because0.9
is a real number with a 23-bit significand, andtmp1 + b
is also evaluated with 23 bits of precision becausetmp1
has 23 bits in its significand).This PR adds a new interface
rpe_var
which is a quick and convenient way of generating one-shot reduced-precision variables from a literal. Using it the example above would become:The function
rpe_literal(value)
call takes a literal input and converts it to anrpe_var
instance with the default number of significand bits, in the example above 10 (i.e. the value is truncated to 10-bits in the significand and returned as anrpe_type
). Optionally you can pass a number of bits as in:which would only use 5 significand bits to represent the literal
0.9
.Thoughts and feedback on both usefulness and implementation welcome.