Add sketch of new Tensor interface#2457
Conversation
d1c85a9 to
dc71352
Compare
271e3cd to
1f8a383
Compare
966abfc to
772a7fa
Compare
b6c3879 to
b9f7f37
Compare
9c066c5 to
e354450
Compare
dennisYatunin
left a comment
There was a problem hiding this comment.
I think this looks mergeable, save for some minor nitpicks. If you want to check this with ClimaAtmos before merging, feel free to define some aliases like const AxisTensor = Tensor, which I used to ensure backward compatibility when refactoring RecursiveApply.
|
|
||
| - A `UniformScaling`, which contains a `Number` | ||
| - A `DiagonalMatrixRow`, which can contain either a `Number` or a tensor (represented as a `Geometry.Axis2Tensor`) | ||
| - A `DiagonalMatrixRow`, which can contain either a `Number` or a rank-2 tensor (represented as a `Geometry.Tensor{2}`) |
There was a problem hiding this comment.
Should this say AbstractTensor{2} instead of Tensor{2}? Same for the instance of Tensor{2} below.
| x::T1, | ||
| y::T2, | ||
| ) where {T1 <: Geometry.AdjointAxisVector, T2 <: Geometry.Axis2Tensor} = (x * y)' | ||
| ) where {T1 <: Geometry.AbstractCovector, T2 <: Geometry.Tensor{2}} = (x * y)' |
There was a problem hiding this comment.
| ) where {T1 <: Geometry.AbstractCovector, T2 <: Geometry.Tensor{2}} = (x * y)' | |
| ) where {T1 <: Geometry.AbstractCovector, T2 <: Geometry.AbstractTensor{2}} = (x * y)' |
| # every conversion is a single matvec — names outside `lg`'s geometry `I` | ||
| # ride the identity block of the padded matrix automatically. Same-type |
There was a problem hiding this comment.
This is a bit unclear. The LocalGeometry tensors now cover all available dimension names, and there's no additional padding here.
| # 1D vector types can be constructed from a scalar + LocalGeometry. | ||
| # The LocalGeometry is ignored — the scalar is wrapped directly. |
There was a problem hiding this comment.
Does this need to be supported? It looks redundant.
| lg.∂ξ∂x[2, 1]*v[1, 1]+lg.∂ξ∂x[2, 2]*v[2, 1] lg.∂ξ∂x[2, 1]*v[1, 2]+lg.∂ξ∂x[2, 2]*v[2, 2] | ||
| ] | ||
| ) | ||
| for (BT, VecType, fn) in ( |
There was a problem hiding this comment.
It looks like BT should be a symbol here, and fn can be replaced with VecType.
| basis1(::Type{<:Tensor{2, <:Any, <:Tuple{B, Any}}}) where {B} = B | ||
| basis2(::Type{<:Tensor{2, <:Any, <:Tuple{Any, B}}}) where {B} = B |
There was a problem hiding this comment.
| basis1(::Type{<:Tensor{2, <:Any, <:Tuple{B, Any}}}) where {B} = B | |
| basis2(::Type{<:Tensor{2, <:Any, <:Tuple{Any, B}}}) where {B} = B | |
| basis1(::Type{T}) where {T <: AbstractTensor{2}} = Geometry.tensor_bases(T)[1] | |
| basis1(::Type{T}) where {T <: AbstractTensor{2}} = Geometry.tensor_bases(T)[2] |
Some of the other Tensor types below could also be replaced with AbstractTensors.
| @inline outer(x::AbstractVector, y::AbstractVector) = x * y' | ||
| @inline outer(x::AbstractVector, y::Number) = x * y | ||
| @inline outer(x::AbstractVector, y) = nested_broadcast(y -> x ⊗ y, y) |
There was a problem hiding this comment.
| @inline outer(x::AbstractVector, y::AbstractVector) = x * y' | |
| @inline outer(x::AbstractVector, y::Number) = x * y | |
| @inline outer(x::AbstractVector, y) = nested_broadcast(y -> x ⊗ y, y) | |
| @inline outer(x, y) = x * y' |
Both * and ' already call nested_broadcast, and you can call ' on a Number (that's just a no-op).
| - nested type (Tuple or NamedTuple), scalar type (Number, SMatrix, or | ||
| Tensor{2}/adjoint thereof), nested type (Tuple or NamedTuple) |
There was a problem hiding this comment.
This also looks like a relic from before the RecursiveApply refactor.
| @inline dss_transform( | ||
| arg::Geometry.Covariant3Vector, | ||
| local_geometry::Geometry.LocalGeometry, | ||
| weight, | ||
| ) = arg * weight |
There was a problem hiding this comment.
This case is already covered by the method below.
| (Tensor{2,FT,Tuple{Covariant3Axis,WAxis},SMatrix{1,1,FT,1}},LG_123_XYZ{FT}, 103), | ||
| ] | ||
| end | ||
|
|
There was a problem hiding this comment.
I feel like testing the padded FLOP counts here doesn't serve much of a purpose. You can leave it in if you want, but we only need tests like this for sparse tensors, which won't be introduced until a future PR.
This PR refactors the
Geometrymodule to use a much simpler interface, so that all vector/tensor operations can expressed using standard math operations instead of custom API functions. This will allow us to remove a large amount of duplicate code, reduce compilation latency, and speed up GPU runs by optimizing the geometry data passed to each kernel.