modular
modular copied to clipboard
[BUG]: Incorrect output of `Math.pow` with negative `Int` exponent
Bug description
Incorrectly calculates the result when SIMD is raised to the power of a negative Int, producing accurate results only when both operands are SIMD.
Steps to reproduce
For example this works when you use the SIMD version for the rhs argument:
from DType import DType
from Math import pow
let x = Float64(4.0)
let res = pow(x, Float64(-1.0))
print(res)
0.25
But using an Int in the rhs will result in the incorrect output:
from DType import DType
from Math import pow
let x = Float64(4.0)
let res = pow(x, -1)
print(res)
1
And the shorthand also produces incorrect results:
let x = float64(4.0)
print(x**-1)
1
System information
11:hugetlb:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
10:devices:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
9:pids:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
8:blkio:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
7:cpuset:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
6:perf_event:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
5:cpu,cpuacct:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
4:net_cls,net_prio:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
3:memory:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
2:freezer:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
1:name=systemd:/kubepods.slice/kubepods-burstable.slice/kubepods-burstable-pod3c39d252_9da9_4a44_afb3_a4a9d291dbff.slice/cri-containerd-7b08c194ddc8e2965257590ac4ab2f1fe2170ad67c30d825c477b486b0b90d39.scope
0::/
@abduld FYI
Thanks for reporting. One question is handling the negative power on integral values.
I also don't know what the standard approach here is for "powi" operations, seems like a weird thing to handle given roots typically produce fractional results. Are there examples in other languages that work this way?
Are there examples in other languages that work this way?
@lattner In Rust you have powi and powf for floats, for the integer version e.g.:
let f: f64 = 4.0;
f.powi(-1)
The source code is:
/// Raises an `f64` to an integer power.
///
/// The stabilized version of this intrinsic is
/// [`f64::powi`](../../std/primitive.f64.html#method.powi)
#[rustc_nounwind]
pub fn powif64(a: f64, x: i32) -> f64;
The intrinsic is llvm.powi.f64:
Syntax
This is an overloaded intrinsic. You can use llvm.powi on any floating-point or vector of floating-point type. Not all targets support all types however.
Generally, the only supported type for the exponent is the one matching with the C type int.
declare float @llvm.powi.f32.i32(float %Val, i32 %power)
declare double @llvm.powi.f64.i16(double %Val, i16 %power)
declare x86_fp80 @llvm.powi.f80.i32(x86_fp80 %Val, i32 %power)
declare fp128 @llvm.powi.f128.i32(fp128 %Val, i32 %power)
declare ppc_fp128 @llvm.powi.ppcf128.i32(ppc_fp128 %Val, i32 %power)
Overview
The ‘llvm.powi.*’ intrinsics return the first operand raised to the specified (positive or negative) power. The order of evaluation of multiplications is not defined. When a vector of floating-point type is used, the second argument remains a scalar integer value.
Arguments
The second argument is an integer power, and the first is a value to raise to that power.
Semantics
This function returns the first value raised to the second power with an unspecified sequence of rounding operations.
And integer types can't be raised to a negative value in Rust as it expects a u32:
FYI @abduld
It appears at some point this issue was resolved. Granted powi with a negative exponent returning 0 is still odd in my opinion.
fn main():
var x = Float64(4.0)
var res = x ** -1
print(res) # 0.25
x = Float64(4.0)
res = x ** Float64(-1)
print(res) # 0.25
var y = Int64(4)
var r = y ** -1
print(r) # 0
Closing as completed, it works now