-
Notifications
You must be signed in to change notification settings - Fork 94
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
Adds Block operator #1435
Conversation
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.
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.
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.
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.
Since I'm not allowing using
It would be ok if the passed-in blocks are empty matrices (think of |
Kudos, SonarCloud Quality Gate passed!
|
91c964a
to
7825ae8
Compare
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.
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.
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)); | ||
} | ||
} | ||
} | ||
} |
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.
Is there a need to unroll them ? Why not just have std::vector<std::vector<...>>
instead of std::vector<...>
?
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.
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 { |
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.
This is already an internal header, does it need to be in the detail
namespace ?
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.
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.
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)}}); |
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.
Can maybe be formatted better:
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)} | |
}); |
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.
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.
if (block && block->get_executor() != exec) { | ||
blocks_.push_back(gko::clone(exec, block)); |
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.
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.
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.
I'm following the same approach as Composition
and Combination
, which both do the same. I think it's better to be consistent here.
9dc8210
to
fb70ec0
Compare
|
Codecov ReportAttention:
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. |
Co-authored-by: Yu-Hsiang M. Tsai <yhmtsai@gmail.com>
Co-authored-by: Yu-Hsiang M. Tsai <yhmtsai@gmail.com>
fb70ec0
to
d54f513
Compare
Error: PR already merged! |
This PR adds a block operator to Ginkgo. Similar to
Combination
, andComposition
, this linear operator is build up from other linear operator. It represents block matrices of the form:Individual blocks can be
0
, by using anullptr
, but no row or column can consist only ofnullptr
. 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:
BlockOperator
for block matrices, not for vectors