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

Structured broadcasting doesn't work with functions that may not preserve structure conditionally #1090

Open
jishnub opened this issue Sep 1, 2024 · 1 comment
Labels
broadcast Applying a function over a collection

Comments

@jishnub
Copy link
Collaborator

jishnub commented Sep 1, 2024

This might be too ambitious, but broadcasting a function that may conditionally preserve zeros fails currently:

julia> (x -> rand() < 0.5 ? 0 : 1).(Diagonal([1,2]))
ERROR: ArgumentError: cannot set off-diagonal entry (2, 1) to a nonzero value (1)
Stacktrace:
  [1] setindex!
    @ ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/LinearAlgebra/src/diagonal.jl:206 [inlined]
  [2] _setindex!
    @ ./abstractarray.jl:1472 [inlined]
  [3] setindex!
    @ ./abstractarray.jl:1442 [inlined]
  [4] macro expansion
    @ ./broadcast.jl:974 [inlined]
  [5] macro expansion
    @ ./simdloop.jl:77 [inlined]
  [6] copyto!
    @ ./broadcast.jl:973 [inlined]
  [7] copyto!(dest::Diagonal{…}, bc::Base.Broadcast.Broadcasted{…})
    @ LinearAlgebra ~/.julia/juliaup/julia-nightly/share/julia/stdlib/v1.12/LinearAlgebra/src/structuredbroadcast.jl:206
  [8] copy
    @ ./broadcast.jl:898 [inlined]
  [9] materialize(bc::Base.Broadcast.Broadcasted{LinearAlgebra.StructuredMatrixStyle{…}, Nothing, var"#35#36", Tuple{…}})
    @ Base.Broadcast ./broadcast.jl:873
 [10] top-level scope
    @ REPL[2]:1
Some type information was truncated. Use `show(err)` to see complete types.

julia> (x -> rand() < 0.5 ? 0 : 1).(Diagonal([1,2]))
2×2 Matrix{Int64}:
 0  0
 1  0

julia> versioninfo()
Julia Version 1.12.0-DEV.1127
Commit ca72e28f26b (2024-08-31 11:47 UTC)
Build Info:
  Official https://julialang.org release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × Intel(R) Core(TM) i5-10310U CPU @ 1.70GHz
  WORD_SIZE: 64
  LLVM: libLLVM-18.1.7 (ORCJIT, skylake)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)
Environment:
  JULIA_EDITOR = subl

This is because the function is evaluated once to check if it does preserve a zero, and the destination type is chosen based on this. In the first case, the destination is chosen to be a Diagonal, which fails, while in the second case, it is chosen to be a Matrix and the copyto! succeeds. This approach of choosing the destination by evaluating the function only works if the function always produces the same output for a zero input. I wonder if there might be some introspection tools that might help us assess this? Or at least, this should consistently error, so that a working code doesn't break on being run a second time.

@jishnub jishnub added the broadcast Applying a function over a collection label Sep 1, 2024
@Seelengrab
Copy link
Contributor

This is because the function is evaluated once to check if it does preserve a zero, and the destination type is chosen based on this.

I think this is basically the same as requiring the function to be :consistent. Unfortunately, that's not dispatchable information...

@KristofferC KristofferC transferred this issue from JuliaLang/julia Nov 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
broadcast Applying a function over a collection
Projects
None yet
Development

No branches or pull requests

2 participants