Replace RecursiveApply functions with AutoBroadcaster wrappers#2417
Replace RecursiveApply functions with AutoBroadcaster wrappers#2417dennisYatunin wants to merge 1 commit intomainfrom
Conversation
cc7a736 to
0b0cbe1
Compare
e603f47 to
5430722
Compare
30377bd to
92cf627
Compare
2bd7d7c to
52d17a0
Compare
8553df5 to
264d4d2
Compare
nefrathenrici
left a comment
There was a problem hiding this comment.
This looks good to me. It's nice to get rid of RecursiveApply. I didn't have any significant comments.
imreddyTeja
left a comment
There was a problem hiding this comment.
I left some comments and questions, but this looks mostly good to me
| which it is true, while leaving values for which it is false unmodified. Can | ||
| also be passed an iterator's type to infer the result type for such an iterator. | ||
| """ | ||
| add_auto_broadcasters(itr) = |
There was a problem hiding this comment.
I don't think we'd ever see structs nested that much, but should this have the recursion limit removed?
| wrappers no longer corresponds to a guaranteed error, it is returned instead of | ||
| the original `bc`. Otherwise, `bc` is returned without any modifications. | ||
| """ | ||
| function allow_auto_broadcasting(bc::Base.Broadcast.Broadcasted) |
There was a problem hiding this comment.
has this function been checked for allocations or dynamic function invokations?
| AutoBroadcaster(merge(unrolled_map(unwrap, args)...)) | ||
|
|
||
| for f in (:axes, :size, :firstindex, :lastindex) | ||
| @eval Base.$f(x::AutoBroadcaster) = $f(unwrap(x)) |
There was a problem hiding this comment.
Could this be combined with the loop on line 145?
| ) where {F, O} = | ||
| unrolled_mapreduce(f, op, unwrap(arg), unrolled_map(unwrap, args)...; init...) | ||
| Base.map(f::F, arg::AutoBroadcaster, args::AutoBroadcaster...) where {F} = | ||
| AutoBroadcaster(unrolled_map(f, unwrap(arg), unrolled_map(unwrap, args)...)) |
There was a problem hiding this comment.
How does this work if the arg is a AutoBroadcaster wrapping a tuple of AutoBroadcasters? Wouldn't it need to recurse with Base.map instead?
| ismutabletype(T) || unrolled_all(no_immutable_types, fieldtypes(T)) | ||
|
|
||
| drop_immutable_types(not_a_type) = not_a_type | ||
| drop_immutable_types(::Type{<:Type}) = DataType |
|
|
||
| no_immutable_types(::Type{<:Type}) = false | ||
| no_immutable_types(::Type{T}) where {T} = | ||
| ismutabletype(T) || unrolled_all(no_immutable_types, fieldtypes(T)) |
There was a problem hiding this comment.
This function could use a comment or docstring. How does unrolled_all(no_immutable_types, fieldtypes(T)) imply the type is immutible
Replaces the
RecursiveApplymodule with a new interface that follows the opposite design pattern: instead of defining functions forTuples andNamedTuples that need to be called inFields,Operators,MatrixFields, and sometimes even inClimaAtmos, we can now use a wrapper forTuples andNamedTuples that behaves the same way when passed to any standard math function. This should make it easy to decouple iteration over field variables from most of ClimaCore's internals.The new interface can be extended to any iterator type
Tby defining the methodis_auto_broadcastable(::T) = true, as long asTis compatible withUnrolledUtilities.jl. The@auto_broadcaster_argsannotation provides a convenient shorthand for extending the new interface to arbitrary functions ofNumbers orAbstractArrays, automatically broadcasting those functions overTuples,NamedTuples, andAutoBroadcasterss. This annotation can also be used to add methods for any other typeT, with the resulting behavior depending on whetheris_auto_broadcastableistruefor that type.