Skip to content
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

Adds Block operator #1435

Merged
merged 4 commits into from
Jan 11, 2024
Merged

Adds Block operator #1435

merged 4 commits into from
Jan 11, 2024

Conversation

MarcelKoch
Copy link
Member

@MarcelKoch MarcelKoch commented Oct 16, 2023

This PR adds a block operator to Ginkgo. Similar to Combination, and Composition, this linear operator is build up from other linear operator. It represents block matrices of the form:

$$Op = \begin{bmatrix} A & B \\\ C & D \end{bmatrix}$$

Individual blocks can be 0, by using a nullptr, but no row or column can consist only of nullptr. The block operator does not need to be square.

The block operator can be created in the following way:

std::shared_ptr<LinOp> A;
std::shared_ptr<LinOp> B;
std::shared_ptr<LinOp> C;
std::shared_ptr<LinOp> D;
auto bop = BlockOperator::create(exec, {{A, B}, {C, D}});

The passed-in LinOps are copied to the correct executor if necessary.

The block operator can be applied to Dense vectors, or block operators (currently only single block column).

Todo:

  • documentation
  • apply with >1 block column -> not necessary due to below
  • maybe separate concerns and use block operator only for matrices and not for vectors -> only use BlockOperator for block matrices, not for vectors

@MarcelKoch MarcelKoch self-assigned this Oct 16, 2023
@ginkgo-bot ginkgo-bot added reg:build This is related to the build system. reg:testing This is related to testing. mod:core This is related to the core module. labels Oct 16, 2023
@MarcelKoch MarcelKoch added the 1:ST:ready-for-review This PR is ready for review label Oct 17, 2023
Copy link
Member

@yhmtsai yhmtsai left a comment

Choose a reason for hiding this comment

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

LGTM in general. Do you have some example or integration request this feature?

  • No EnableCreateMethod already?
  • multiple right hand side or multiple col block in right hand side
  • empty row and empty col allowance? It should be okay when only apply but it may not make sense when using them in solver.

@MarcelKoch
Copy link
Member Author

LGTM in general. Do you have some example or integration request this feature?

I did not intend to write an example for that. I think it has been mentioned somewhere before, but adding a new example for each new feature seems a bit overkill to me. Something like this could best be handled through documentation, but of course our current setup is not well suited for that.

* No EnableCreateMethod already?

Yes. I think that was a great suggestion by @upsj, so I'm using it, since it also has no effect on the user interface.

* multiple right hand side or multiple col block in right hand side

Since I'm not allowing using BlockOperator for block vectors, there should be no confusion here anymore. I decided to disallow block vectors because it requires non-const access to the blocks, and those block vectors could not be used in solvers anyway. So if we want to support block-vectors, that would have to be its own class.

* empty row and empty col allowance? It should be okay when only apply but it may not make sense when using them in solver.

It would be ok if the passed-in blocks are empty matrices (think of Csr::create(exec)). I only do not allow a row/column full of nullptrs, because that complicates determining the overall size of the block operator.

@yhmtsai

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 22 Code Smells

86.4% 86.4% Coverage
0.0% 0.0% Duplication

warning The version of Java (11.0.3) you have used to run this analysis is deprecated and we will stop accepting it soon. Please update to at least Java 17.
Read more here

Copy link
Member

@pratikvn pratikvn left a comment

Choose a reason for hiding this comment

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

Nice work! Mostly looks good to me. I think as this supports arbitrary block sizes, that should be tested as well. I think adding apply and advanced apply tests also for a block size of 3x3 would be good.

To ease comparisons, you can just create a single Dense matrix, create submatrices from it and compare the apply of both, separately.

Comment on lines +173 to +182
for (auto& row : blocks) {
for (auto& block : row) {
if (block && block->get_executor() != exec) {
blocks_.push_back(gko::clone(exec, block));
} else {
blocks_.push_back(std::move(block));
}
}
}
}
Copy link
Member

Choose a reason for hiding this comment

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

Is there a need to unroll them ? Why not just have std::vector<std::vector<...>> instead of std::vector<...> ?

Copy link
Member Author

Choose a reason for hiding this comment

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

I think there is no real reason to prefer one over the other. I can't remember why I picked the flat vector, but at least it's a bit nicer for the assignment operators.

@@ -13,20 +13,55 @@


namespace gko {
namespace detail {
Copy link
Member

Choose a reason for hiding this comment

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

This is already an internal header, does it need to be in the detail namespace ?

Copy link
Member Author

Choose a reason for hiding this comment

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

We also use that namespace in our private files from time to time. Here I use it because the run_impl functions should not be used directly and are just an implementation detail.

Comment on lines +249 to +252
exec, {{gko::initialize<Mtx>({{1, 2}, {2, 1}}, exec),
gko::initialize<Mtx>({{5, 6}, {6, 5}}, exec)},
{nullptr, gko::initialize<Mtx>({{3, 4}, {4, 3}}, exec)}});
Copy link
Member

Choose a reason for hiding this comment

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

Can maybe be formatted better:

Suggested change
exec, {{gko::initialize<Mtx>({{1, 2}, {2, 1}}, exec),
gko::initialize<Mtx>({{5, 6}, {6, 5}}, exec)},
{nullptr, gko::initialize<Mtx>({{3, 4}, {4, 3}}, exec)}});
exec, {
{gko::initialize<Mtx>({{1, 2}, {2, 1}}, exec), gko::initialize<Mtx>({{5, 6}, {6, 5}}, exec)},
{nullptr, gko::initialize<Mtx>({{3, 4}, {4, 3}}, exec)}
});

Copy link
Member Author

Choose a reason for hiding this comment

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

clang-format says no. I would rather not put clang-format off in there, since I don't think the formatting is that bad, or that this really needs proper formatting.

Comment on lines +175 to +176
if (block && block->get_executor() != exec) {
blocks_.push_back(gko::clone(exec, block));
Copy link
Member

Choose a reason for hiding this comment

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

Is it necessary to clone these block operators ? The apply should handle that correctly anyway. I think there is no need to have all the blocks on the same executor.

Copy link
Member Author

Choose a reason for hiding this comment

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

I'm following the same approach as Composition and Combination, which both do the same. I think it's better to be consistent here.

@MarcelKoch MarcelKoch force-pushed the block-operator branch 2 times, most recently from 9dc8210 to fb70ec0 Compare January 10, 2024 13:14
@MarcelKoch MarcelKoch added 1:ST:ready-to-merge This PR is ready to merge. and removed 1:ST:ready-for-review This PR is ready for review labels Jan 10, 2024
Copy link

Quality Gate Passed Quality Gate passed

The SonarCloud Quality Gate passed, but some issues were introduced.

10 New issues
0 Security Hotspots
88.5% Coverage on New Code
0.0% Duplication on New Code

See analysis details on SonarCloud

Copy link

codecov bot commented Jan 10, 2024

Codecov Report

Attention: 18 lines in your changes are missing coverage. Please review.

Comparison is base (2033f10) 89.35% compared to head (fb70ec0) 91.04%.

❗ Current head fb70ec0 differs from pull request most recent head d54f513. Consider uploading reports for the commit d54f513 to get more accurate results

Files Patch % Lines
core/base/block_operator.cpp 90.15% 13 Missing ⚠️
core/test/base/block_operator.cpp 97.60% 3 Missing ⚠️
core/base/dispatch_helper.hpp 87.50% 2 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##           develop    #1435      +/-   ##
===========================================
+ Coverage    89.35%   91.04%   +1.69%     
===========================================
  Files          697      700       +3     
  Lines        56940    56996      +56     
===========================================
+ Hits         50880    51894    +1014     
+ Misses        6060     5102     -958     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

MarcelKoch and others added 4 commits January 11, 2024 11:01
Co-authored-by: Yu-Hsiang M. Tsai <yhmtsai@gmail.com>
Co-authored-by: Yu-Hsiang M. Tsai <yhmtsai@gmail.com>
@MarcelKoch MarcelKoch merged commit 56f32b2 into develop Jan 11, 2024
7 of 13 checks passed
@MarcelKoch MarcelKoch deleted the block-operator branch January 11, 2024 10:03
@ginkgo-bot
Copy link
Member

Error: PR already merged!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
1:ST:ready-to-merge This PR is ready to merge. mod:core This is related to the core module. reg:build This is related to the build system. reg:testing This is related to testing.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants