Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mod is JIT-ed to HLO operator with the semantic of Julia's rem #755

Closed
giordano opened this issue Feb 16, 2025 · 6 comments · Fixed by #758
Closed

mod is JIT-ed to HLO operator with the semantic of Julia's rem #755

giordano opened this issue Feb 16, 2025 · 6 comments · Fixed by #758
Labels
bug Something isn't working

Comments

@giordano
Copy link
Member

giordano commented Feb 16, 2025

The fact that Base.mod and Base.rem both are lowered to the same HLO operator looks very fishy since they have different semantics in Julia.

https://openxla.org/xla/operation_semantics#element-wise_binary_arithmetic_operations

When Op is Rem, the sign of the result is taken from the dividend, and the absolute value of the result is always less than the divisor's absolute value.

This is the semantic of Julia's rem, the opposite of mod. See also https://openxla.org/stablehlo/spec#remainder for more details about the operator.

Originally posted by @giordano in #754 (comment)

@giordano
Copy link
Member Author

giordano commented Feb 16, 2025

I didn't find an HLO function for this operation in https://openxla.org/stablehlo/spec. If we have to roll our own, a possible implementation of mod could be

# Based on https://github.com/JuliaLang/julia/blob/39255d47db7657950ff1c82137ecec5a70bae622/base/float.jl#L608-L617
function Base.mod(@nospecialize(x::Reactant.TracedRNumber{T}), @nospecialize(y::Reactant.TracedRNumber{T})) where {T}
    r = rem(x, y)
    return ifelse(r == 0, copysign(r, y), ifelse((r > 0)  (y > 0), r + y, r))
end

but we don't have a method for copysign. How do I find the HLO function for this operation? Google is failing me.

@mofeing
Copy link
Collaborator

mofeing commented Feb 16, 2025

@giordano
Copy link
Member Author

That's not exactly the same thing.

@giordano
Copy link
Member Author

You can implement copysign(a, b) = sign(b) * abs(a), but this is likely going to be much less efficient than a proper builtin implementation. LLVM has a specific intrinsic for example.

@mofeing
Copy link
Collaborator

mofeing commented Feb 16, 2025

yep, but stablehlo has a limited amount of ops, and the only op close to it is that one. not even CHLO has one like this https://github.com/openxla/stablehlo/blob/main/stablehlo/dialect/ChloOps.td

You can implement copysign(a, b) = sign(b) * abs(a), but this is likely going to be much less efficient than a proper builtin implementation. LLVM has a specific intrinsic for example.

remember that this are very high-level ops, so probably XLA can optimize it if we express it well enough.

@giordano
Copy link
Member Author

You can implement copysign(a, b) = sign(b) * abs(a)

That's not true, sign is the completely wrong function to use here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants