-
Notifications
You must be signed in to change notification settings - Fork 978
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
limiter_node
fails to decrement/open with continue_msg
yet works with int
#419
Comments
Hi @diablodale. Thank you for opening up a separate issue to track this! The specialization for
Please make sure multifunction nodes indeed send messages to the output ports that are connected to the limiter_node's decrementer. I agree that this looks suspicious, since with the integral specialization of the limiter_node everything works on your side. |
I have a reproducer with bulk private code removed. The framework/flow is still there which I would prefer not be public. |
I have an idea what can go wrong - have you considered buffering policy of the limiter_node's predecessor(s) in your graph? Perhaps, some of the rejected messages by the Regarding the reproducer, you can use official inteltbbdevelopers@intel.com address or send the reproducer directly to me - my email address should be written on my GitHub account page. Please let me know if it is not the case. Wherever you ask, I am sure your IP will be treated appropriately since we have strict guidelines and trainings about working with third-party code in order not to leak its IP be that customer or company-owned one. |
Yes. I want to drop messages. My scenario is a graph that processes sensor frame data. If While further reducing, I got to a point I could run generate a trace for Flow Graph Analyzer. The graph chart looks correct. But the Graph rule-check is reporting errors that I do not see in code. And the node inspector is reporting incorrect types on outlets even though it is clearly correct in the template params. This seems to be bugs with the Flow Graph collector and analyzer. I won't discuss this further in this bug thread. I'm sending an email to inteltbbdevelopers@intel.com with a ZIP that contains this setup, cmake, and source files. Setup
Repro steps
Good Result 🙂Output showing a cascade of Bad Result 😢Output showing a cascade of NotesRun the above repro steps with both the default
These behaviors makes me suspect a race condition somewhere. And the simplied repro code exposes more bad scenarios that my real code with heavier/longer computation in the nodes doesn't expose. |
Hi. Checking back here to confirm that you received my email with the repo code. I sent it on the same day as above, 2 June 2021. |
Yes, we received it and did the analysis. We found two issues:
|
In the sample code I provided, there is only one call to graph::reset(). And it is in the Pipeline() constructor, which naturally is serial itself. The constructor is triggered at the start of main() which naturally is also serial. And am I right to assume that your (2) above is alluding that within that constructor I call The intention of the reset() is to (re)attach the graph to a specific task arena (for independent threads) and specific task group (for graph shutdown). I'm not aware of any other constructor arguments or apis that will associate a flowgraph with a specific arena. This is why I call A long time ago, I looked at If I can guarantee execute() never returns until after the Is there some other way to achieve the same goal? To have a unique arena, and to create a flowgraph associated with it? I understand what you are describing in (1). That approach would add unneeded complexity in my solution. So I will continue to use an integer decrementer. |
The enqueuing happens only if all available slots are occupied by other threads. Since |
ok. I read the (1) doc update in the PR. That looks good. I think there is value in adding a sentence or two...somewhere...that describes the one-and-only-way to assign a flowgraph to a specific arena and that the approach using reset() must be done within |
Yeah, definitely this information should be written somewhere. Not sure about the specification, but in the docs for sure. BTW, what do you think if constructor of the graph will allow specifying an arbitrary task arena it will attach its execution to? Will that be useful and less error-prone for you? |
Perhaps "Flow Graph Tips and Tricks" section? I also was thinking this one-and-only-way seemed an API itself rather than a documented strict set of API calls. 😏 I (re)read articles, now having somewhat more TBB experience, and I can imagine three approaches I would explore to achieve my goal. I can imagine the generic desire of "I want to run my flow graph in an explicit grouping of arena, task group, or isolation".
I do not have enough experience to know if 2. and 3. make sense with a flow graph. But it is something I would explore given time and an API. My specific scenario is to have some TLS isolation; preventing accidents, not malicious attacks. I use OpenCL via the OpenCV sdk. The OpenCV sdk has an api to choose the "current OpenCL gpu"; the impl stores it in TLS. Imagine now my code and some 3rd party code that both use OpenCV and perhaps also TBB. My code calls the OpenCV api in the The OpenCV api to select the gpu is expensive...and...it has tremendous amounts of state. It is important that the tasks in my flow graph don't have their gpu changed. When threads runs tasks in my flow graph, it must be guaranteed the OpenCV gpu choice stored in TLS was not accidentally changed by a 3rd party calling the same OpenCV apis. I used the brute-force approach of a dedicated |
@diablodale please take a look at this documentation page https://oneapi-src.github.io/oneTBB/main/tbb_userguide/attach_flow_graph_to_arena.html. This page was added as the result of #785. We also have created #932 to track request for usability improvement of |
Using the default limiter_node and sent continue_msg() via an edge to the limiter.decrementer() does not decrement and open again the limiter node. It stays closed and no messages pass.
I made a single code change to limiter_node<T, int> and sent (int)1 via the edges. Now I have no issues. The limiter_node works as I expect. 🤔
Related to discussion in #342 (comment)
Setup
Repo
I acknowledge a full compliable code example is best. My bandwidth is limited at the moment. Until something else exists...
limiter_node<myClass>>(flowgraph, 2)
tbb::flow::serial
while others to3
Result
About 2 or 3 messages will traverse the graph. Then no more.
Expected
Never ending flow of messages.
Workaround
The following workaround has been used for 3 months with 100% success. Across multiple VS versions, and both tbb v2021.1.1 and v2021.2.0
limiter_node<myClass, int>>(flowgraph, 2)
try_put(continue_msg())
totry_put(1)
Notes
I continue to be suspicious about the TBB
threshold_regulator
code in_flow_graph_body_impl
. The specialization for continue_msg has execute() but doesn't have try_put_task() with a decrement like its sibling specialization. Missing code? Race condition?The text was updated successfully, but these errors were encountered: