Fixed Point (Chapter 13): Clarification Request


CDS <cohen.steed@...>
 

The definition  of the numeric range (at the beginning of section 13) matches the definition of an integer, not of a fixed-point number. For example, the range specified is the range of an integer, not a number of 1.X or 2.X format. This doesn't seem to be a fixed-point specification in a manner consistent with other fixed-point operations commercially available. As INTEGER-ONLY operations go, these are likely useful instructions. As a fixed-point specification, this section seems to raise a lot of concerns.
Fixed Point math, itself, is somewhat niche. It mostly sees use in legacy audio and mixed signal applications. If it needs to be a part of RISC-V:
  • Could it be a sub-spec, or an optional consideration? The implementation requirements to support these are non-trivial and seem to target a small use-case demand.
  • Specify a 1.X format (or some fixed, deterministic point position). The current specification has no definition of a fixed point number format. The number format is implied, as a side effect in some instructions.
  • There is a need for a fixed<->float conversion instruction (as used in signal processing applications on mixed fixed/float processing systems, or for conversion of data from e.g. ADCs/DACs).


Andrew Waterman
 



On Fri, Aug 7, 2020 at 8:49 AM CDS <cohen.steed@...> wrote:
The definition  of the numeric range (at the beginning of section 13) matches the definition of an integer, not of a fixed-point number. For example, the range specified is the range of an integer, not a number of 1.X or 2.X format. This doesn't seem to be a fixed-point specification in a manner consistent with other fixed-point operations commercially available. As INTEGER-ONLY operations go, these are likely useful instructions. As a fixed-point specification, this section seems to raise a lot of concerns.
Fixed Point math, itself, is somewhat niche. It mostly sees use in legacy audio and mixed signal applications. If it needs to be a part of RISC-V:
  • Could it be a sub-spec, or an optional consideration? The implementation requirements to support these are non-trivial and seem to target a small use-case demand.
Having implemented these instructions recently, I can say they weren’t unduly onerous to provide, and the HW cost increase wasn’t that great (the rounding and clipping logic are new; the rest reuses the integer datapath). But it’s nonzero cost, so your point holds.

I agree that fixed-point could be broken out into a separate extension so that embedded vector units can exclude it for applications where integer-only or integer-and-float-only would suffice.

  • Specify a 1.X format (or some fixed, deterministic point position). The current specification has no definition of a fixed point number format. The number format is implied, as a side effect in some instructions.
  • There is a need for a fixed<->float conversion instruction (as used in signal processing applications on mixed fixed/float processing systems, or for conversion of data from e.g. ADCs/DACs).

I think this can be done in two instructions without additional loss of precision: convert from int to float, then multiply by a floating-point scalar to move the binary point (or vice-versa).


CDS <cohen.steed@...>
 

Thank you for the response, Andrew.

Given that these operations are intended to be conveniences, in the first place (hence: vector), the addition of a required macro for inclusion could be considered a basic element. Fixed point is almost always going to be used in conjunction with other data formats, and the conversion, as you say, could be two instructions - or it could be one.

The confusion my team and I are having with fixed point is not so much with the implementation, but the use-case. If we're going to have fixed-point in RISC-V, how about we look at how it's used and build that? Barring a (possibly necessary) overhaul, making the specification optional *entirely* - separating it out from the rest of vector, may be a compelling option.


Krste Asanovic
 

On Fri, 07 Aug 2020 14:48:34 -0700, "CDS" <cohen.steed@...> said:
| Thank you for the response, Andrew.
| Given that these operations are intended to be conveniences, in the first place (hence: vector), the
| addition of a required macro for inclusion could be considered a basic element. Fixed point is almost
| always going to be used in conjunction with other data formats, and the conversion, as you say, could
| be two instructions - or it could be one.

I disagree with "almost always" unless you refer to mixing integer and
fixed-point. There are certainly many use cases with no
floating-point.

| The confusion my team and I are having with fixed point is not so much with the implementation, but the
| use-case. If we're going to have fixed-point in RISC-V, how about we look at how it's used and build
| that? Barring a (possibly necessary) overhaul, making the specification optional *entirely* -
| separating it out from the rest of vector, may be a compelling
| option.

Fixed-point is widely used, and if anything, interest is growing in
low-precision fixed-point. Fixed-point codecs continue to be
widespread also.

I'm having trouble understanding your viewpoint here.

Krste



|


CDS <cohen.steed@...>
 
Edited

Perhaps, it is important to understand the history of why fixed point is utilized. Historically, fixed point was the alternative for expensive floating point implementations/operations, or was the easy option on top of an integer-only MCU. In today's chips, however,  if floating point is available in a processing system, then floating point will be used over fixed point - sometimes because fixed point introduces a lot of signal processing challenges that are not present in floating point; perhaps because most, if not all, signal processing math is designed in, and for, floating point. Conversion to fixed point happens if no other choice is available or to support legacy code bases.

Consider:
1. For the vector extension, floating point is mandatory. This could lead to the utilization of fixed point math being low. In this case, it will likely involve conversion in and out of floating point before doing the actual math.

2. Fixed point may be used more frequently if there is a significant benefit over floating point:
- legacy code is less of an issue on our architecture because it's new;
- power/performance - but we're already paying the price for area with floating point!

For the current vector extension definition that would, maybe, be for the 1.7 FP or 8-bit fixed point, where there could be a performance benefit depending on the factual implementation of the vector engine for a given RISCV core.

With that said, we are not opposed to supporting fixed point. We are questioning having fixed point being mandatory. Fixed point support has a significant impact on compilers and tools (no native data type + no clear definition) and a significant impact on the usage/support model (fixed point ISA section is missing expected fixed point options).

Hence the suggestion for making it optional, and working through some of the use-cases for fixed point to ensure that the fixed point ISA definition is "usable" by the intended target audience/users.

Internally we've worked through a few simple examples, like IIR and FIR filters, and it quickly becomes apparent that when using 1.(SEW-1) [industry standard definition] as a fixed point definition it quickly because "unmanageable" in terms of managing decimal points, overflows and mixed precision. "Unmanageable" here should be read as: requires a lot of additional checks around all math operations to ensure we don’t overflow or mix decimal points.


swallach
 

perhaps i am not upto date on this topic.   but addresses are fixed point. (integers).   and you need vector support for vector loads using the vector accumulators.(indexs).   the math, other than overflow is essentially the same

i hope this makes sense



On Aug 10, 2020, at 10:52 AM, CDS <cohen.steed@...> wrote:



[Edited Message Follows]

Perhaps, it is important to understand the history of why fixed point is utilized. Historically, fixed point was the alternative for expensive floating point implementations/operations, or was the easy option on top of an integer-only MCU. In today's chips, however,  if floating point is available in a processing system, then floating point will be used over fixed point - sometimes because fixed point introduces a lot of signal processing challenges that are not present in floating point; perhaps because most, if not all, signal processing math is designed in, and for, floating point. Conversion to fixed point happens if no other choice is available or to support legacy code bases.

Consider:
1. For the vector extension, floating point is mandatory. This could lead to the utilization of fixed point math being low. In this case, it will likely involve conversion in and out of floating point before doing the actual math.

2. Fixed point may be used more frequently if there is a significant benefit over floating point:
- legacy code is less of an issue on our architecture because it's new;
- power/performance - but we're already paying the price for area with floating point!

For the current vector extension definition that would, maybe, be for the 1.7 FP or 8-bit fixed point, where there could be a performance benefit depending on the factual implementation of the vector engine for a given RISCV core.

With that said, we are not opposed to supporting fixed point. We are questioning having fixed point being mandatory. Fixed point support has a significant impact on compilers and tools (no native data type + no clear definition) and a significant impact on the usage/support model (fixed point ISA section is missing expected fixed point options).

Hence the suggestion for making it optional, and working through some of the use-cases for fixed point to ensure that the fixed point ISA definition is "usable" by the intended target audience/users.

Internally we've worked through a few simple examples, like IIR and FIR filters, and it quickly becomes apparent that when using 1.(SEW-1) [industry standard definition] as a fixed point definition it quickly because "unmanageable" in terms of managing decimal points, overflows and mixed precision. "Unmanageable" here should be read as: requires a lot of additional checks around all math operations to ensure we don’t overflow or mix decimal points.



WARNING / LEGAL TEXT: This message is intended only for the use of the individual or entity to which it is addressed and may contain information which is privileged, confidential, proprietary, or exempt from disclosure under applicable law. If you are not the intended recipient or the person responsible for delivering the message to the intended recipient, you are strictly prohibited from disclosing, distributing, copying, or in any way using this message. If you have received this communication in error, please notify the sender and destroy and delete any copies you may have received.

http://www.bsc.es/disclaimer


Nick Knight
 

Hi Coheen,

Thanks for the discussion on the fixed-point vector instructions. Most of Chapter 13 predates my involvement with the Task Group, but I think I am able to address one of your comments:

On Mon, Aug 10, 2020 at 6:33 AM CDS <cohen.steed@...> wrote:
There's no definition of what the fixed point spec is working on, other than the definition of an integer.
Is this an implied 1.x format? e.g. 8-bit is 1.bbbbbbbb? Is this intended to be implementation-specific with regards to the fixed point location?

The specification doesn't say. Ambiguity could be removed with a clear statement, in the specification, around what the intended/proposed data format is.

Here's my proposed change to the preamble to Chapter 13:

image.png

Best,
Nick Knight


CDS <cohen.steed@...>
 

Nick,

Thank you for your response and proposed clarification.

This proposal for how to use the numbers fundamentally realigns our interpretation of how this would be used. This is much closer to the type of ADC work we've seen in the past, as opposed to do a hard "fixed point" format specification. I support the clarification. Perhaps we should see it included in the spec (merged).

Thanks,
Cohen


Allen Baum
 

I always understood fixpoint to have an implicit denominator that was restricted to a positive (integer) power of 2 (which could be fixed, or could be configured).
Arbitrary denominators mean that multiply has to perform a subsequent divide after the operation, instead of a simple shift.
I didn't think anyone was suggesting that.

On Mon, Aug 10, 2020 at 9:49 AM CDS <cohen.steed@...> wrote:
Nick,

Thank you for your response and proposed clarification.

This proposal for how to use the numbers fundamentally realigns our interpretation of how this would be used. This is much closer to the type of ADC work we've seen in the past, as opposed to do a hard "fixed point" format specification. I support the clarification. Perhaps we should see it included in the spec (merged).

Thanks,
Cohen


Mikael
 

I like the new definition of fixed point. Its quite crisp.

 

Building on the definition we can now argue that any integer number representation is: integer value/2^N

With N being a positive integer. N=0 is basically a regular INT, and N>0 is a fixed point number.

 

If we accept this definition we can ask ourselves how 13.2 and 13.3 fit into our new definition. This as both are built on the assumption that N=1, which goes against our more open-ended definition.

 

Arguably, 13.3 is just short hand for a vmul followed by vnclip.

Similarly, 13.2 is just short hand for vadd/vsub followed by vssra.

 

Utilizing this more crisp definition we can now semantically define fixed point math operations as:

 

#inner loop

vmul of SEW*SEW -> 2xSEW [N.(SEW-N) -> 2N.2(SEW-N)]

vssra of 2xSEW -> 2xSEW >> needed guarding for the expected math operation

vadd of guarded 2xSEW with guarded running sum vector

#roll out

vnclip of guarded running sum vector 2xSEW >> SEW-guard bits+N to convert back to N.(SEW-N)

#or if we want to utilize a 2N.2(SEW-N) double precision fixed point

#note this construct is currently not feasible

#vnclip_shift_left guarded 2xSEW << guard bits