-
Notifications
You must be signed in to change notification settings - Fork 9
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
Add operator_matrix to MatrixFields, along with tests and docs #1399
Conversation
96d568f
to
5faf79d
Compare
bors try |
tryBuild failed: |
5faf79d
to
3ee210d
Compare
a4371c6
to
9e8a6d3
Compare
bors try |
tryBuild failed: |
9e8a6d3
to
bde9f87
Compare
bors try |
tryBuild failed: |
end | ||
end | ||
|
||
include("matrix_field_test_utils.jl") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
❤️
bde9f87
to
403cb67
Compare
bors try |
tryBuild failed: |
403cb67
to
4b747af
Compare
5d5aedc
to
3003cb4
Compare
This PR has gotten too long, so I'm going to peel off a few smaller PRs before flagging this for a final review. |
1423: Clean up MatrixFields tests r=dennisYatunin a=dennisYatunin Peeled off from #1399. Cleans up `test/MatrixFields` by creating `matrix_field_test_utils.jl` and moving all shared testing code there. Simplifies the matrix broadcast tests by removing a lot of variables that were being passed around as function arguments (e.g., replaces anonymous functions of the form `(args...) -> f(args...)` with `() -> f(args...)`, since both give the same benchmarking results). Sets the default values of `time_ratio_limit` and `max_eps_error_limit` to 10, which should help us avoid random CI failures. - [x] Code follows the [style guidelines](https://clima.github.io/ClimateMachine.jl/latest/DevDocs/CodeStyle/) OR N/A. - [x] Unit tests are included OR N/A. - [x] Code is exercised in an integration test OR N/A. - [x] Documentation has been added/updated OR N/A. Co-authored-by: Dennis Yatunin <dyatun@gmail.com>
3003cb4
to
a95e919
Compare
1424: Fix matrix multiplication at boundaries r=dennisYatunin a=dennisYatunin Peeled off from #1399. Fixes a bug in matrix-matrix multiplication (i.e., the `MultiplyColumnwiseBandMatrixField()` operator with two matrix fields as inputs) that was causing entries from outside the second input matrix to be used in the computation of entries outside the product matrix. These entries are used for padding, allowing us to store the nonzero entries of band matrices in `Field`s with rectangular parent arrays, so using them during the computation of matrix-matrix products leads to an unnecessary performance loss. Moreover, it breaks the assumption that these outside entries have no effect on program behavior. In addition to fixing the bug, this PR - Updates the documentation of `MultiplyColumnwiseBandMatrixField` to reflect the change. - Adds a unit test which ensures that outside entries are never used during matrix-matrix multiplication. - Simplifies some of the code for `MultiplyColumnwiseBandMatrixField`, making sure that it reflects the updated documentation as closely as possible. - Introduces the `column_axes(matrix_field)` utility function, which can be used to obtain the space that corresponds to the columns of `matrix_field` (as opposed to `axes(matrix_field)`, which corresponds to the rows). This function simplifies the computation of interior/boundary indices during matrix multiplication. - Fixes a type instability in `field2arrays` and updates the corresponding unit test. This also decreases the memory allocated by the new unit test for outside entries. - Modifies the `show` method for matrix `Field`s so that it also displays the matrix shape. Co-authored-by: Dennis Yatunin <dyatun@gmail.com>
1424: Fix matrix multiplication at boundaries r=dennisYatunin a=dennisYatunin Peeled off from #1399. Fixes a bug in matrix-matrix multiplication (i.e., the `MultiplyColumnwiseBandMatrixField()` operator with two matrix fields as inputs) that was causing entries from outside the second input matrix to be used in the computation of entries outside the product matrix. These entries are used for padding, allowing us to store the nonzero entries of band matrices in `Field`s with rectangular parent arrays, so using them during the computation of matrix-matrix products leads to an unnecessary performance loss. Moreover, it breaks the assumption that these outside entries have no effect on program behavior. In addition to fixing the bug, this PR - Updates the documentation of `MultiplyColumnwiseBandMatrixField` to reflect the change. - Adds a unit test which ensures that outside entries are never used during matrix-matrix multiplication. - Simplifies some of the code for `MultiplyColumnwiseBandMatrixField`, making sure that it reflects the updated documentation as closely as possible. - Introduces the `column_axes(matrix_field)` utility function, which can be used to obtain the space that corresponds to the columns of `matrix_field` (as opposed to `axes(matrix_field)`, which corresponds to the rows). This function simplifies the computation of interior/boundary indices during matrix multiplication. - Fixes a type instability in `field2arrays` and updates the corresponding unit test. This also decreases the memory allocated by the new unit test for outside entries. - Modifies the `show` method for matrix `Field`s so that it also displays the matrix shape. Co-authored-by: Dennis Yatunin <dyatun@gmail.com>
1424: Fix matrix multiplication at boundaries r=dennisYatunin a=dennisYatunin Peeled off from #1399. Fixes a bug in matrix-matrix multiplication (i.e., the `MultiplyColumnwiseBandMatrixField()` operator with two matrix fields as inputs) that was causing entries from outside the second input matrix to be used in the computation of entries outside the product matrix. These entries are used for padding, allowing us to store the nonzero entries of band matrices in `Field`s with rectangular parent arrays, so using them during the computation of matrix-matrix products leads to an unnecessary performance loss. Moreover, it breaks the assumption that these outside entries have no effect on program behavior. In addition to fixing the bug, this PR - Updates the documentation of `MultiplyColumnwiseBandMatrixField` to reflect the change. - Adds a unit test which ensures that outside entries are never used during matrix-matrix multiplication. - Simplifies some of the code for `MultiplyColumnwiseBandMatrixField`, making sure that it reflects the updated documentation as closely as possible. - Introduces the `column_axes(matrix_field)` utility function, which can be used to obtain the space that corresponds to the columns of `matrix_field` (as opposed to `axes(matrix_field)`, which corresponds to the rows). This function simplifies the computation of interior/boundary indices during matrix multiplication. - Fixes a type instability in `field2arrays` and updates the corresponding unit test. This also decreases the memory allocated by the new unit test for outside entries. - Modifies the `show` method for matrix `Field`s so that it also displays the matrix shape. Co-authored-by: Dennis Yatunin <dyatun@gmail.com>
1424: Fix matrix multiplication at boundaries r=dennisYatunin a=dennisYatunin Peeled off from #1399. Fixes a bug in matrix-matrix multiplication (i.e., the `MultiplyColumnwiseBandMatrixField()` operator with two matrix fields as inputs) that was causing entries from outside the second input matrix to be used in the computation of entries outside the product matrix. These entries are used for padding, allowing us to store the nonzero entries of band matrices in `Field`s with rectangular parent arrays, so using them during the computation of matrix-matrix products leads to an unnecessary performance loss. Moreover, it breaks the assumption that these outside entries have no effect on program behavior. In addition to fixing the bug, this PR - Updates the documentation of `MultiplyColumnwiseBandMatrixField` to reflect the change. - Adds a unit test which ensures that outside entries are never used during matrix-matrix multiplication. - Simplifies some of the code for `MultiplyColumnwiseBandMatrixField`, making sure that it reflects the updated documentation as closely as possible. - Introduces the `column_axes(matrix_field)` utility function, which can be used to obtain the space that corresponds to the columns of `matrix_field` (as opposed to `axes(matrix_field)`, which corresponds to the rows). This function simplifies the computation of interior/boundary indices during matrix multiplication. - Fixes a type instability in `field2arrays` and updates the corresponding unit test. This also decreases the memory allocated by the new unit test for outside entries. - Modifies the `show` method for matrix `Field`s so that it also displays the matrix shape. Co-authored-by: Dennis Yatunin <dyatun@gmail.com>
1424: Fix matrix multiplication at boundaries r=dennisYatunin a=dennisYatunin Peeled off from #1399. Fixes a bug in matrix-matrix multiplication (i.e., the `MultiplyColumnwiseBandMatrixField()` operator with two matrix fields as inputs) that was causing entries from outside the second input matrix to be used in the computation of entries outside the product matrix. These entries are used for padding, allowing us to store the nonzero entries of band matrices in `Field`s with rectangular parent arrays, so using them during the computation of matrix-matrix products leads to an unnecessary performance loss. Moreover, it breaks the assumption that these outside entries have no effect on program behavior. In addition to fixing the bug, this PR - Updates the documentation of `MultiplyColumnwiseBandMatrixField` to reflect the change. - Adds a unit test which ensures that outside entries are never used during matrix-matrix multiplication. - Simplifies some of the code for `MultiplyColumnwiseBandMatrixField`, making sure that it reflects the updated documentation as closely as possible. - Introduces the `column_axes(matrix_field)` utility function, which can be used to obtain the space that corresponds to the columns of `matrix_field` (as opposed to `axes(matrix_field)`, which corresponds to the rows). This function simplifies the computation of interior/boundary indices during matrix multiplication. - Fixes a type instability in `field2arrays` and updates the corresponding unit test. This also decreases the memory allocated by the new unit test for outside entries. - Modifies the `show` method for matrix `Field`s so that it also displays the matrix shape. Co-authored-by: Dennis Yatunin <dyatun@gmail.com>
8b40c6b
to
70eba2e
Compare
bors try |
tryBuild failed: |
bors try |
tryBuild succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
ce23cf0
to
d284e69
Compare
There was one unit test whose reference function was taking too long to compile on Julia 1.9. I've disabled the reference function for now (so the test isn't going to check for correctness, but it will still check for allocations and type instabilities), though we should probably figure out how to re-enable it with reasonable compilation time in the future. |
bors r+ |
Build succeeded! The publicly hosted instance of bors-ng is deprecated and will go away soon. If you want to self-host your own instance, instructions are here. If you want to switch to GitHub's built-in merge queue, visit their help page. |
Purpose
Second PR of #1230. Refactors what is currently in
src/operators/operator2stencil.jl
.Content
operator_matrix(op)
, which will replaceOperator2Stencil(op)
. This function has a detailed docstring and throws descriptive errors for operators without well-defined operator matrices.-1/2
and+1/2
) needs to be computed with@. matrix_field = interp_matrix(ones_field)
, whereones_field
is a field filled with the number1
that is used to infer the space and entry type of the matrix. Now, this matrix can just be computed with@. matrix_field = interp_matrix()
. In order to make this work,interp_matrix
is now defined as a "lazy operator". When a broadcast expression containing lazy operators is evaluated, each lazy operator is replaced with an actual operator, and it is given one or more fields as input arguments. In this case,interp_matrix
is given the local geometry field as an input argument, and this field is used to infer the space and entry type of the operator matrix.@. op(func(field))
is equivalent to@. op_matrix(ones_field) ⋅ func(field)
, and the derivative of this expression with respect tofield
can be specified as@. op_matrix(func'(field))
, wherefunc'
is the derivative of the point-wise functionfunc
. With this new interface,@. op(func(field))
is equivalent to@. op_matrix() ⋅ func(field)
, and the derivative can be specified as@. op_matrix() ⋅ DiagonalMatrixRow(func'(field))
. Similarly, the derivative of@. op2(func2(op1(func1(field))))
with respect tofield
isop2_matrix(func2'(op1(func1(field)))) ⋅ op1_matrix(func1'(field))
with our pre-existing code andop2_matrix() ⋅ DiagonalMatrixRow(func2'(op1(func1(field)))) ⋅ op1_matrix() ⋅ DiagonalMatrixRow(func1'(field))
with the new interface. Although the new interface leads to longer derivative expressions, those expressions are more similar to how the chain rule is usually written out, and they can be debugged/analyzed more incrementally.op
is theUpwind3rdOrderBiasedProductC2F
operator, then@. op(velocity_field, tracer_field)
is equivalent to@. op_matrix(velocity_field) ⋅ tracer_field
. The implementation is similar to that of single-argument operators, except that it does not require the use of "lazy operators" (since there is already a field being passed to the operator matrix, the local geometry field can be obtained from that field during the evaluation ofBase.Broadcast.broadcasted
).Extrapolate
boundary conditions. These boundary conditions cause the matrices to have larger bandwidths than other boundary conditions.operator_matrix
function with every valid combination of finite difference operators and boundary conditions. The tests check for correctness, type stability, and lack of allocations. The tests are run on both CPUs and GPUs. In addition, the tests print out how the performance of@. op_matrix() ⋅ field
compares to the performance of@. op(field)
; the two expressions are similarly fast on GPUs (between-70%
and+40%
relative change in speed), though the operator matrix expressions tend to be slower on CPUs.test_field_broadcast
so that it also tests whetherget_result
generates the same result asset_result!
.*
method forBandMatrixRow
so that matrix fields can be scaled by vectors/covectors in addition to numbers. This simplifies a few of the complicated broadcast tests.Geometery
) in the method ofstencil_left_boundary
forGradientF2C
.rpromote_type
that was preventing empty matrix rows from being constructed.Base.Broadcast.broadcasted
method forFiniteDifferenceOperator
andSpectralElementOperator
so that lazy operators can work correctly (the original versions of these methods would always overwrite theLazyOperatorStyle
withStencilStyle
orSpectralStyle
, respectively).broadcasted
for lazy operators: