Skip to content

1888/apply - #2070

Open
MarcelKoch wants to merge 21 commits into
1888/derive-dist-vectorfrom
1888/apply
Open

1888/apply#2070
MarcelKoch wants to merge 21 commits into
1888/derive-dist-vectorfrom
1888/apply

Conversation

@MarcelKoch

Copy link
Copy Markdown
Member

This PR changes the apply interface to only allow applying linops to multivectors. The apply implementations are changed to use the precision dispatch built into the multi vector interface.

@MarcelKoch MarcelKoch added this to the Ginkgo 2.0 milestone Aug 17, 2026
@MarcelKoch MarcelKoch self-assigned this Aug 17, 2026
@MarcelKoch MarcelKoch mentioned this pull request Aug 17, 2026
9 tasks
@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. mod:reference This is related to the reference module. reg:benchmarking This is related to benchmarking. type:solver This is related to the solvers type:preconditioner This is related to the preconditioners type:matrix-format This is related to the Matrix formats type:factorization This is related to the Factorizations type:reordering This is related to the matrix(LinOp) reordering type:multigrid This is related to multigrid type:stopping-criteria This is related to the stopping criteria labels Aug 17, 2026
@MarcelKoch
MarcelKoch force-pushed the 1888/derive-dist-vector branch from 1c82140 to ed710a9 Compare August 18, 2026 14:37
@MarcelKoch
MarcelKoch force-pushed the 1888/apply branch 2 times, most recently from a4150cd to 89a9e63 Compare August 18, 2026 14:57
@MarcelKoch
MarcelKoch force-pushed the 1888/derive-dist-vector branch from ed710a9 to 1dc8c10 Compare August 18, 2026 14:57
@MarcelKoch
MarcelKoch force-pushed the 1888/apply branch 2 times, most recently from 4f68eec to d2ab30c Compare August 19, 2026 10:22
@MarcelKoch
MarcelKoch force-pushed the 1888/derive-dist-vector branch from 1dc8c10 to d0862a3 Compare August 19, 2026 12:38
virtual bool apply_uses_initial_guess() const { return false; }

[[nodiscard]] precision get_precision() const noexcept;
[[nodiscard]] precision get_precision() const noexcept { return value_t_; }

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

at some point we might need to split to two core library: one is the utils which can be used by the backend and the other composes the backend together.

Comment on lines 295 to 296
* Implementers of LinOp should override this function instead
* of apply(const LinOp *, const LinOp *, const LinOp *, LinOp *).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

adding some note for the default implementation without mixed precision support

Comment thread core/base/lin_op.cpp
Comment on lines +80 to +90
std::visit(
[&](auto p) {
using value_type = std::decay_t<decltype(p)>;
auto dense_alpha = alpha->as_precision(this);
auto dense_beta = beta->as_precision(this);
auto x_clone = converted_x->clone();
this->apply_impl(converted_b.get(), x_clone.get());
converted_x->scale(dense_beta.get());
converted_x->add_scaled(dense_alpha.get(), x_clone);
},
precision_to_variant(this->get_precision()));

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggested change
std::visit(
[&](auto p) {
using value_type = std::decay_t<decltype(p)>;
auto dense_alpha = alpha->as_precision(this);
auto dense_beta = beta->as_precision(this);
auto x_clone = converted_x->clone();
this->apply_impl(converted_b.get(), x_clone.get());
converted_x->scale(dense_beta.get());
converted_x->add_scaled(dense_alpha.get(), x_clone);
},
precision_to_variant(this->get_precision()));
auto dense_alpha = alpha->as_precision(this);
auto dense_beta = beta->as_precision(this);
auto x_clone = converted_x->clone();
this->apply_impl(converted_b.get(), x_clone.get());
converted_x->scale(dense_beta.get());
converted_x->add_scaled(dense_alpha.get(), x_clone);

value_type is not used, so you do not need the visit, right?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, you're right. I will change this.

void write_data(json& output) { output["iterations"] = this->num_iters; }

protected:
void on_iteration_complete(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is considered public interface break, so we need to note it

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I don't think we consider the benchmarks public interface. They are not even exported/installed.

}


TEST_F(Dense, ApplyToMixedComplexIsEquivalentToRef)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

these MixedComplex needs to be recovered?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

No, they were deliberately removed, since this isn't (directly) supported anymore. We talked about this internally a while ago. The issue is essentially that this always requires two steps

  • convert complex to real (no precision conversion)
  • convert real to required precision

This creates two temporaries, which both need to be kept alive. I think it's best to leave it for the user to manage this. They can easily do it by themselves:

auto real = complex->create_real_view();
auto converted = real->as_precision(fp16)

Or switch the two steps.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

IIRC, we start to use A(real) b (complex) is from IDR. Do we use it in other place.
Another option can be that we even do not support V x Complex.
Users can use A->apply(b->create_real_view(), x->create_real_view()) because create_real_view is here, so it will still valid when the internal temporary conversion get destroyed.

Comment on lines +521 to +523
max_relative_norm2 =
std::max(host_absolute_norm->at(0, i) / host_answer_norm->at(0, i),
max_relative_norm2);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

compute_norm will return multivector no matter it is distributed or not

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, all reductions (compute_dot/compute_norm) use gko::matrix::MultiVector for their result. This is also how it is currently. Maybe if we have a column distributed vector it would make sense to return something else, but for now it doesn't.

Comment on lines -744 to +758
scale_diag->apply(diag_mtx_, diag_mtx_);
scale_diag->apply(off_diag_mtx_, off_diag_mtx_);
auto diag_mtx_csr =
as<gko::matrix::Csr<ValueType, LocalIndexType>>(diag_mtx_);
auto off_diag_mtx_csr =
as<gko::matrix::Csr<ValueType, LocalIndexType>>(off_diag_mtx_);

scale_diag->apply(diag_mtx_csr, diag_mtx_csr);
scale_diag->apply(off_diag_mtx_csr, off_diag_mtx_csr);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am thinking how to make generalized in the future when we support more scale on the matrix format.
Diagonal only scale csr and dense. here only deal with csr.
Dispatch here might be easy solution but it will not support user owned format, or we need to have feature class to allow that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think a feature class would be reasonable. But I think that is very far future right now, so I wouldn't worry too much.

Comment thread core/matrix/coo.cpp
Comment on lines +160 to +162
apply_precision_dispatch<ValueType>(
[this](auto dense_alpha, auto view_b, auto dense_beta, auto view_x,
auto...) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

what is auto... for?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

In the mixed precision case it's used to pass through the actual value types of the arguments. But here it is not necessary, so I will remove it. That might also give better differentiation between the two dispatches.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

1:ST:ready-for-review This PR is ready for review 1:ST:run-full-test mod:core This is related to the core module. mod:reference This is related to the reference module. reg:benchmarking This is related to benchmarking. reg:build This is related to the build system. reg:testing This is related to testing. type:factorization This is related to the Factorizations type:matrix-format This is related to the Matrix formats type:multigrid This is related to multigrid type:preconditioner This is related to the preconditioners type:reordering This is related to the matrix(LinOp) reordering type:solver This is related to the solvers type:stopping-criteria This is related to the stopping criteria

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants