-
Notifications
You must be signed in to change notification settings - Fork 82
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
[FEATURE] Forward call of indexed sequence pairs to alignment algorithm. #1358
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ | |
#include <type_traits> | ||
#include <vector> | ||
|
||
#include <seqan3/alignment/pairwise/detail/concept.hpp> | ||
#include <seqan3/contrib/parallel/buffer_queue.hpp> | ||
#include <seqan3/core/parallel/detail/reader_writer_manager.hpp> | ||
#include <seqan3/core/platform.hpp> | ||
|
@@ -127,6 +128,33 @@ class execution_handler_parallel | |
assert(status == contrib::queue_op_status::success); | ||
} | ||
|
||
/*!\brief Takes underlying range of sequence pairs and invokes an alignment on each instance. | ||
* \tparam algorithm_t The type of the alignment algorithm. | ||
* \tparam indexed_sequence_pairs_t The type of underlying sequence pairs annotated with an index; | ||
* must model seqan3::detail::indexed_sequence_pair_range. | ||
* \tparam delegate_type The type of the callable invoked on the std::invoke_result of `algorithm_t`. | ||
* | ||
* \param[in] algorithm The alignment algorithm to invoke. | ||
* \param[in] indexed_sequence_pairs The range of underlying annotated sequence pairs to be aligned. | ||
* \param[in] delegate A callable which will be invoked on each result of the computed alignments. | ||
*/ | ||
template <typename algorithm_t, indexed_sequence_pair_range indexed_sequence_pairs_t, typename delegate_type> | ||
void execute(algorithm_t && algorithm, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Isn't this always a specialisation of seqan3::alignment_algorithm? Or is this a policy? I also do not understand what a delegate is (for).. 🙈 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this is the algorithm that is supposed to be called by the execution handler. That can be basically anything that is invocable, so it was called fn_t for function before. Since it is only used in the context of executing alignment algorithms it is now refined to be a more specific in the name. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then maybe add the comment, that it must model callable ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And what is the delegate thing ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I will have another invocable concept for this after all the open PRs with these changes are mereged. Then I can make sure that this works. Is that ok? Ah and a delegate is another callable that is called on the result of the alignment algorithm. The term is a standard term for something that should be called on the result of something without jumping out of the process (as opposed to coroutines). https://stackoverflow.com/questions/9568150/what-is-a-c-delegate There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sure.
Ok, and what is the purpose of this here/what is the use case? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We have two interfaces for dealing with alignment results. The first one results a alignment result range and the second calls a user defined delegate on the result. Accordingly, there are two executors. The two way which we already know and the one way which will not implement the buffering. So both of them reuse the execution handlers which just get a delegate to call the alignment result on. The two way just passes a lambda that moves the result into the correct buffer location. |
||
indexed_sequence_pairs_t indexed_sequence_pairs, | ||
delegate_type && delegate) | ||
{ | ||
assert(state != nullptr); | ||
|
||
// Asynchronously pushes the alignment job as a task to the queue. | ||
task_type task = [=, indexed_sequence_pairs = std::move(indexed_sequence_pairs)] () | ||
{ | ||
delegate(algorithm(std::move(indexed_sequence_pairs))); | ||
}; | ||
|
||
[[maybe_unused]] contrib::queue_op_status status = state->queue.wait_push(std::move(task)); | ||
assert(status == contrib::queue_op_status::success); | ||
} | ||
|
||
//!\brief Waits until all submitted alignment jobs have been processed. | ||
void wait() | ||
{ | ||
|
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.
You say range here but copy. Do you assume that this copy is cheap? Is it a view?
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.
Ok, so it expects always a range.
It never uses the range as a lvalue reference because it executes the alignments asynchronously and want's to make sure that another thread is not modifying this reference. And in the implementation we actually pass in a rvalue view so that nothing is expensive in this context.
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.
Ok. If you always pass a view in our context we might want to constrain this?
But no strong feelings
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.
Well, the interface does not care really. It just takes a copy of whatever comes in. Just we use it by passing in a view which is lightweight. The only constraint I might add here is that the type is move constructible since afterwards we move it around.