Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce MLNumber for specifying numeric inputs of any type (#647)
For some `MLGraphBuilder` methods the type of a numeric input can vary - e.g. for `constant()` an explicit `MLOperandDataType` is provided; for `clamp()` and `pad()` the data type is implied by input operands. In these cases, specifying the numeric value as either a float/double or int64 type runs into accuracy or range issues - you can't accurately represent all int64 values as a double, and you can't represent the full range of floats as int64. (You also can't represent all int64 values as an long long either - over 2^53 things get wierd. But that's a digression.) - Some methods that took a float or double argument/option but can operate on integer data types now take `MLNumber` - a "variant" (union) of either a JS Number (equivalent to a double a.k.a. float64) or BigInt (for full precision int64/uint64 use) - `constant()` (scalar overload) - `MLNumber` - `clamp()` (min/max options) - `MLNumber` - `pad()` (padding value) - `MLNumber` - This fixes #442 - Other methods that took a `float` argument/option now take a `double`. These are all ops that only operate on floating point types, so no need for `MLNumber` though it would be harmless to use it there to allow BigInt inputs. This follows web API best practices, and allows full precision conversion to float16 (since float64 to float32 to float16 can yield different results than float64 directly to float16) - `batchNormalization()`, `instanceNormalization()`, `layerNormalization()` - `epsilon` option - `elu()`, `gemm()`, `hardSigmoid()`, `leakyRelu()`, `linear()` - `alpha` and `beta` options - This fixes #325 - In all of these cases, the input number is cast to the input/output operand data type when it is used. Casting algorithms are spelled out, always have "clamp" semantics (i.e. no weird modulus wrapping), and never fail. - For `MLOperand`-vending methods, the conversion can be done eagerly. - For `MLActivation`s, the conversion is done at "fusion time"; it's notable that the same `MLActivation` instance could be fused with multiple ops, and cast differently for each. - This fixes #678 - Using a BigInt/numeric union is novel here, but WebIDL experts agree it's reasonable (whatwg/webidl/issues/1388). Note that all existing WebIDL/JS APIs that are designed to take just a Number or just a BigInt will throw if the other thing is passed - there is intentionally no silent conversion. So we are in novel territory here and should look for implementation and developer feedback. Fixes #442, #325, #678 --------- Co-authored-by: Dwayne Robinson <[email protected]> Co-authored-by: Ningxin Hu <[email protected]>
- Loading branch information