netmod-wg / yang-next

Feature requests for future versions of YANG
6 stars 0 forks source link

Add native support for float/double #34

Open rgwilton opened 6 years ago

rgwilton commented 6 years ago

Add support for IEEE 754 binary floats and doubles.

routing-types.yang (RFC 8294) defines bandwidth-ieee-float32, but ends up using a string as the base type (fine for text based encoding schemes, not so great for binary encoding schemes). Apparently OpenConfig have a similar definition that ends up with binary as the base type, but that also has its own problems.

schoenw commented 6 years ago

My understanding is that routing hardware does not use floats; some routing protocols use the IEEE floating format to communicate values, but that is all. Perhaps the routing-types hack is good enough?

rgwilton commented 6 years ago

Most of the RP and LC CPUs that I'm aware of do have hardware float capabilities. Even a 5$ Raspberry Pi Zero has hardware floating point support.

I agree that the forwarding ASICs themselves probably don't use floating point, but I'm not sure that is particularly relevant.

All of the NFV stuff means that more services will be executed either on general purpose CPUs (or GPUs) both of which have strong support for floats.

So to me, it seems like an unhelpful arbitrary restriction on the language. There is already a use for them in several models, so even if they are not used very frequently, it makes YANG more useful if they are supported as a native type. It feels like the cost of adding them would also be relatively low.

immibis commented 6 years ago

Any processor you can buy today, except for the simplest microcontrollers, can support floating-point even if it has to be done in software.

Even if there weren't routing protocols that use floating point, YANG is also used to configure subsystems that run on the device's CPU.

I would expect YANG floating point types to lean towards being implementation agnostic - it doesn't seem right to say that a particular value must be a float, if the implementation is capable of treating it as a double. (I also feel this way about the lack of generic int/uint types)

schoenw commented 6 years ago

It is not uncommon that OS kernels do not use floating point registers. It is not so much a question whether the hardware can do floating point arithmetic but a question of performance (saving/restoring floating point registers during system calls, little value of floating point numbers in the kernel).

Defining arbitrary precision numbers (floating point of integers) has the risk that implementations come with different levels of precision, which is not helping interoperability. Hence, if floating point numbers are really needed (and I am not yet convinced they are to configure and manage a system), better make them follow IEEE 754.

rgwilton commented 6 years ago

I was looking for IEEE 754 defined floats and doubles. I.e. something that both client and server can agree on having exactly the same meaning/definition.

I think that I heard that some implementations convert YANG decimal type to double (accepting a potential loss of precision) because they are easier to work with than YANGs decimal64 numbers, which are hard to represent cleanly in 64 bits. Perhaps it would have been better if YANG's decimal64 had been defined as 4 bits of fraction digits (1-16 inc), and a 60 bit signed number, so that it could be stored in a 64 bit number, or perhaps it should have been aligned to IEEE 754 decimal64 - although I think that was defined after YANG.

I don't think that YANG needs variable sized int types.

immibis commented 6 years ago

It is certainly a good idea for YANG to support IEEE 754 formats for use with protocols that use them. Does it need to be defined in YANG itself? I've seen at least one module (can't remember which, sorry) that uses a hexadecimal string for this purpose - it's not human-readable, but it should be adequate for machine-to-machine communication.

rgwilton commented 6 years ago

I would like a clean separation between the definition of the underlying type vs the encoding that is used. E.g. for XML, encoding a float as a string is fine, but for a binary encoding like CBOR, I would expect a more compact representation to be used.

Yes, strings can be used to represent floats and doubles, but these do not give such good binary encodings, and are not likely to be represented efficiently in the client or server unless extra code is written to convert these back into native float/double types. Having a native float/double type in YANG seems like a better choice to me.

kwatsen commented 5 years ago

Martin notes that confd has floating points and that they are rarely used.

Rob W. notes that Rob S. wants a float for OC models.

A.C. notes that there is interest in the IEEE bandwidth models.

aashaikh commented 4 years ago

I"m not sure of the current status of this item in YANG Next discussions. Rob W. referenced a recent issue we've had with users of OpenConfig YANG modules -- I'll reiterate that this problem resurfaces often, especially in context of optical transport, where many device configuration and telemetry values are floating point. We have defined a ieefloat32 based on YANG binary type (suboptimal), but it would be much preferred to have a native YANG type.

rovarga commented 4 years ago

+1 to @aashaikh 's comment, we've done the same in OpenDaylight's BGP/LS component and the result is not quite nice, as RESTCONF ends up with binary encoding, which is something our users hate.

tcareyintx commented 1 year ago

+1 to @aashaikh . In mobile we also need this for metrics in the radio network.

immibis commented 1 year ago

I would like a clean separation between the definition of the underlying type vs the encoding that is used. E.g. for XML, encoding a float as a string is fine, but for a binary encoding like CBOR, I would expect a more compact representation to be used.

Yes, strings can be used to represent floats and doubles, but these do not give such good binary encodings, and are not likely to be represented efficiently in the client or server unless extra code is written to convert these back into native float/double types. Having a native float/double type in YANG seems like a better choice to me.

Don't forget the YANG only defines the management-layer data model of the server. The server doesn't have to actually store the data in the same format the YANG says, as long as it converts it when talking to management clients. All complex custom types are defined as strings, or binary, because that's generic and allows unknown types to be passed around. If you care about compactness you might define a binary custom type.

I know that Tail-f's ConfD product does represent many types, such as IP addresses, that are defined as strings in YANG, internally in a compact way.

immibis commented 1 year ago

+1 to @aashaikh . In mobile we also need this for metrics in the radio network.

do you really, or can it be decimal64?

jhaas-pfrc commented 6 months ago

Since my attention was drawn here: IEEE 754 32-bit binary floating point numbers exist as config or operational state in some mechanisms in IETF, and are sometimes carried on the wire in the protocols.

I believe decimal 64 has precision encoding issues that prevent strict translation back and forth from valid numbers of the differing types. This means that upon conversion, even print won't display the same things. And on the wire, you may end up with a precision fault resulting in different protocol behavior if the precision delta is too high.

TL;DR: coercing op state from protocols that is float32 into decimal64 will lead to messy inconsistencies and should be avoided.

Note that from a human factors standpoint, I like decimal64 in YANG. It's just not exactly the same thing.

schoenw commented 6 months ago

I like D J Greaves discussion of floating point numbers. YANG does not support floating point numbers as this prevents having values in configuration where even simply things like equality comparisons (in decimal representations of binary fractions) can lead to surprises.

I do see that this gets ugly when you have to model software interfaces or protocols that do use floating point types (for good or bad reasons out of your control).

If we would be up for adding more complexity and expressiveness to YANG's type system, we could have type annotations that provide information about what types can do or can't do. (This might help with related issues, like some types having a hard time with canonicalization of values.) Knowing the properties of types can be used to check how they are used in other contexts, e.g., must or when expressions. Once sufficient information about types is available, tools can check whether expressions are potentially dangerous to generate relevant diagnostics.

The downside is that developers using floating point values without thinking much about whether this is a good idea will likely also ignore diagnostics and we will see things like timeouts using floating point values for no good reason.