-
Notifications
You must be signed in to change notification settings - Fork 235
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
Parallel Get/Put links #2316
Parallel Get/Put links #2316
Conversation
Wow! OK! I think I like this!
Some more comments to follow for specific lines of code. |
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.
Some minor commentary about specific lines of code ...
// If the argument is SetNode, then process atoms from queue | ||
// stored in SetNode value | ||
AtomSpace* as = getAtomSpace(); | ||
ValuePtr value = args->getValue(QueueValue::QUEUE_VALUE_KEY); |
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.
Change this to DEFAULT_QUEUE_VALUE_KEY
. We should also probably do the same thing for DEFAULT_TRUTH_VALUE_KEY
also (in some other pull req).
*/ | ||
|
||
template <typename T> | ||
class ClosableQueue |
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.
There already exists code for something that is very similar, in cogutils
, and I would rather that got used instead ...
{ | ||
protected: | ||
std::string _name; | ||
HandleClosableQueuePtr _handle_queue; |
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.
Rather than doing it for Handle
, doing it for Value
would be better.
*/ | ||
|
||
class QueueValue | ||
: public Value |
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.
Should probably inherit from StreamValue
instead ?
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.
Oh, hang on, maybe it would be better to inherit from LinkValue?
Or maybe StreamValue and LinkValue should be merged into one ? Or something like that? Yes, that would be a different, distinct discussion. So, for now, maybe this is OK as it is.
|
||
virtual ~QueueValue() {} | ||
|
||
HandleClosableQueuePtr get_queue() const { return _handle_queue; } |
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.
Rather than doing this, maybe it would be better to just add push and pop directly to the API?
One last remark: parallelizing the pattern matcher seems like it should be "easy" but might be quite difficult. There is a very obvious place to parallelize: the top-level search-starting-point loop. This is in |
try | ||
// If the argument is SetNode, then process atoms from queue | ||
// stored in SetNode value | ||
AtomSpace* as = getAtomSpace(); |
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 atomspace required here? It is not used in code below
@@ -388,6 +389,7 @@ SATISFYING_LINK <- PATTERN_LINK | |||
GET_LINK <- SATISFYING_LINK // Finds all groundings, returns them | |||
QUERY_LINK <- SATISFYING_LINK // Finds all groundings, substitutes. | |||
BIND_LINK <- QUERY_LINK // Finds all groundings, substitutes. | |||
PARALLEL_GET_LINK <- SATISFYING_LINK // Finds all groundings, puts them to queue |
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.
Should it be inherited from PATTERN_LINK instead?
HandleSeq handle_seq; | ||
handle_seq.push_back(h); | ||
handle_seq.push_back(_target); | ||
Handle member_link = createLink(handle_seq, MEMBER_LINK); |
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.
Why don't add results to the atomspace in the ParallelSatisfier
instead? Am I right that current implementation collects results as SetLink
and then puts them into atomspace as MemberLink
? It would be simpler to put them as MemberLink
without using a Set
as intermediate state.
Closing. interesting prototype. If you just want plain-old parallel atomspace/opencog/query/InitiateSearchCB.cc Lines 402 to 417 in 812580d
QueueValue , making it easy to pipeline producers and consumers (the pattern matcher being the producer, and some PutLink-type thing being a consumer.)
|
This is the draft pull request which arises from discussion #1502 "Stop using SetLink for search results".
The used idea is that pattern matcher creates results in parallel and other links read them in parallel.
The aim of this pull request is to show how this can work with introduced ParallelLink which puts its results into queue and PutLink reads them.
In the current design both ParallelLink and PutLink work on the same thread. Making pattern matcher parallel can be considered as the second step if the current design with queue looks appropriate.
Here is a simple sample how it works:
ParallelGetLink uses SetNode as input. Set node contains queue which used to exchange results between atoms.
ParallelGetLink puts its results to queue and generates MemberLinks:
PutLink uses SetNode as argument and reads results form the queue and produces: