Skip to content

Conversation

@felixcremer
Copy link
Member

This should make broadcasting mixed type arrays much more robust.
I had the problem that when I broadcasted two YAXArrays with Union{Missing, UInt8} the outtype was determined as Missing and then the actual results where not able to be written into the Array.

I added a test for such a case.

I am wondering whether we should also make this the default for xmap outtypes in general.

@codecov
Copy link

codecov bot commented Nov 12, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.55%. Comparing base (7ab2a92) to head (1317d32).
⚠️ Report is 1 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #562      +/-   ##
==========================================
+ Coverage   67.34%   68.55%   +1.21%     
==========================================
  Files          15       15              
  Lines        2205     2204       -1     
==========================================
+ Hits         1485     1511      +26     
+ Misses        720      693      -27     
Files with missing lines Coverage Δ
src/DAT/broadcast.jl 85.71% <100.00%> (+85.71%) ⬆️

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@felixcremer
Copy link
Member Author

I don't understand why this change is not hit by codecov

@felixcremer
Copy link
Member Author

I found it, we didn't include the broadcast tests. They are now enabled.

intypes = (eltype.(args2)...,)
@debug intypes
outtypes = Base.return_types(bc.f, intypes)
outtype = Union{outtypes...}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this doesn't do unions of Float64, Float32 and such, right? I guess promotion applies there. Or things like Union{Float64, Float64}, because of the splat.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, you are right we should be doing a promote_type instead of the Union to merge Float32 and Float64 to return Float64

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
outtype = Union{outtypes...}
outtype = promote_type{outtypes...}

@test isa(a .+ b, YAXArray)
end

@testset "missing handling" begin
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we also test the promote_type? as well as forcing the outtype? just to make sure things work in all cases.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes we could also test the promote_type.
How would you force the outtype in a broadcast operation?
What would be the syntax?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree outtype does not exist for broadcast but only for xmap. However, a quick test for something a function like f(x) = rand() > 0.5 ? Float64(1) : Float32(1) and then f.(cube) would be nice to add.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this coming from an actual use case or is this good to have in case?
For Union{Float32, Float64} we run into problems with zero because this is not defined for these general unions. zero is used in DiskArrayEngine.create_userfunction to provide an init value.
The Union{Missing, T} works, because this is special cased for zero and one in Julia Base.

args2 = map(to_yax, args2)
# determine output type by calling `eltype` on a dummy function call
dummy_args = map(a -> first(a.data), args2)
outtype = typeof(bc.f(dummy_args...))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applying f here is for a reason, isn't? e.g. this could determine if the output is just a number or an Array, an f that reduces along a given dimension or not, like cumsum.

not sure...

@lazarusA
Copy link
Collaborator

@felixcremer ? merge? or do we still want?

However, a quick test for something a function like f(x) = rand() > 0.5 ? Float64(1) : Float32(1) and then f.(cube) would be nice to add.

@lazarusA
Copy link
Collaborator

is this related to #540 ?

@felixcremer
Copy link
Member Author

is this related to #540 ?

No, this was a user error on my part and we could ease this a bit with a better error message.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants