-
Notifications
You must be signed in to change notification settings - Fork 54
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
Support custom vector types #905
Comments
To clarify, what we have is a situation in which our data should be considered as a 1D vector for linear algebra, but represents a 3D field in a physical context. Consider a 2D array that represents, for example, an image: julia> c = rand(3, 3)
3×3 Matrix{Float64}:
0.515044 0.981678 0.0473222
0.437767 0.142471 0.756243
0.284507 0.647186 0.445389 A "diffusion" operation, which can be interpreted as a kind of filter, is represented by the following operator: diffuse(i, j, c) = - 4 * c[i, j] + c[i+1, j] + c[i, j+1] + c[i-1, j] + c[i, j-1] The operator julia> c_vector = c[:]
9-element Vector{Float64}:
0.5150436482179653
0.43776719843960443
0.28450746235635493
0.9816775509672155
0.14247143653959915
0.6471861061623826
0.0473222143036538
0.7562428994779301
0.4453890152898158 Said again, we can apply the In Oceananigans we are concerned with 3D fluid dynamics, so you can take the above analogy but apply to a 3D matrix. If the matrix has While we could in principle represent our operators with sparse matrices and then evaluate matrix-vector products with sparse linear algebra, there's no intrinsic benefit to spending memory on the sparse matrix; we are interested in iterative methods that allow us to avoid allocating operator memory entirely. I think there are probably many such contexts, where the "native" data representation is an M-dimensional matrix with dimension sizes, |
Thanks for the explanation!
I will document that after INFORMS. |
@glwagner I’m wondering if we can do something similar for If it’s not possible, we will define our own wrapper as we discussed last week (not documented yet). |
Nice! I just want to note for clarity -- the key tricky part of the implementation is skipped over in that example, which is how boundary conditions are treated. For performance we cannot use short-circuiting operations which check whether we are on the boundary; instead (at least for a finite volume or difference code) the typical approach is to use "halo regions". In other words, the underlying data will be a 3D continuous array of size This means that we cannot use neat tricks like |
Thanks for the explanation, @glwagner! I will document how we can define our own vector type with an example of discretized PDE with halo regions. We will have all the code that we need for Oceanigans.jl after that. |
Let me clarify. Even homogeneous boundary conditions require some special attention to the boundary. The reason is not the condition itself but rather because the operator being applied is not generally correct or even applicable in-bounds for points that touch the boundary. In the code you've given in the example, this is accomplished with There is an additional point that inhomogeneous boundary conditions can be accounted for in the Poisson equation by changing the right hand side of the equation. But these changes would be implemented in addition to any special attention paid to evaluating a stencil on the boundary as described above. |
Agreed. For a minimal / example implementation what is needed is something like struct ThreeDimensionalizedVector{FT, D} <: AbstractVector{FT}
data :: D
function ThreeDimensionalizedVector(data)
FT = eltype(data)
D = typeof(data)
return new{FT, D}(data)
end
end Then if |
In some specific applications, users may want to use their own vector types. For example, in Oceananigans.jl, each vector is a slice of a 3D matrix and is of the type
Field
. (cc @glwagner)--> CliMA/Oceananigans.jl#3812
The best solution is to document how we can create a modular wrapper that fits the user's needs, with a very simple and limited API to implement.
I quickly experimented with a custom type that represents a vector of dual numbers, and it works.
Off-topic: @michel2323, this could be a way to perform low-level differentiation directly in Krylov.jl.
I should clean up the low-level API (functions starting with
k
), as these are not publicly available or documented for the user.@michel2323 @glwagner
I believe this is also the best way to introduce MPI usage in the future.
It will be independent of
Krylov.jl
and can be applied to any package.The text was updated successfully, but these errors were encountered: