Open lewissbaker opened 4 months ago
I recall that the issue of how to deal with exceptions in concurrent algorithms was discussed at the Oulu meeting: there was a heated debate which couldn’t be settled. It may be worth to look at that discussion. For example http://wg21.link/p0323 (exception_list) and http://wg21.link/p0333 (improving parallel algorithm exception handling) are in that space. The current parallel algorithms may also have an approach.On 12 Jul 2024, at 07:13, Lewis Baker @.***> wrote: The current wording of bulk() in P2300R10 has a default implementation that invokes set_error(rcvr, current_exception()) if any of the invocations of f exit with an exception. However, this strategy only works for sequential execution implementation strategies. We need to specify what the semantics should be if f exits with an exception during implementations of bulk that execute f concurrently. Several options come to mind:
do not execute f concurrently if f is potentially throwing pick an arbitrary exception thrown by one of the invocations of f pick the first exception thrown by an invocation of f - e.g. decided by some atomic-rmw operation. reduce the exceptions into a single error value (perhaps by some user-provided reduction operation) terminate on error (this would be inconsistent with the well-defined behaviour of the default sequential implementation)
Also, what should the behaviour be for subsequent invocations of f? Should we try to cancel subsequent invocations of f after an invocation of f has exited with an exception? Or should it still try to call all subsequent invocations of f (this might be a reasonable strategy if we are reducing the errors)? What if a stop-request is issued after the f operation exits with an exception but before the executions on other threads can stop executing? Should the operation as a whole complete with set_error or should it complete with set_stopped?
—Reply to this email directly, view it on GitHub, or unsubscribe.You are receiving this because you are subscribed to this thread.Message ID: @.***>
The current parallel algorithms are specified to terminate if any of the element-access functions or the per-element operation to be performed exits with an exception - there is no attempt to try to combine the errors together.
That would be one way to approach this - terminate if anything fails within a bulk() operation. However, that would be inconsistent with the current specification of the default bulk implementation, which completes with an exception_ptr of the first exception to be thrown.
I would add another option:
This would allow the implementation to pick an arbitrary exception from what the function has thrown, group some of the exceptions into another exception (i.e., exception_list
) or throw an implementation-defined exception (e.g., cannot_serialize_user_exception
). For me, there 3 strategies are the only practically viable strategies that the implementations can use.
The current wording of
bulk()
in P2300R10 has a default implementation that invokesset_error(rcvr, current_exception())
if any of the invocations off
exit with an exception.However, this strategy only works for sequential execution implementation strategies.
We need to specify what the semantics should be if
f
exits with an exception during implementations ofbulk
that executef
concurrently.Several options come to mind:
f
concurrently iff
is potentially throwingf
isnoexcept
f
f
- e.g. decided by some atomic-rmw operation.Also, what should the behaviour be for subsequent invocations of
f
? Should we try to cancel subsequent invocations off
after an invocation off
has exited with an exception? Or should it still try to call all subsequent invocations off
(this might be a reasonable strategy if we are reducing the errors)?What if a stop-request is issued after the
f
operation exits with an exception but before the executions on other threads can stop executing? Should the operation as a whole complete withset_error
or should it complete withset_stopped
?