Open jaredhoberock opened 8 years ago
It looks like this will work, at least for bulk_invoke()
. Will have to verify it also works for bulk_async()
& bulk_then()
.
This sort of usage is possible:
std::mutex mut;
agency::bulk_invoke(agency::par(10), [&](agency::parallel_agent& self, int& shared_integer)
{
mut.lock();
std::cout << "shared_integer: " << shared_integer << std::endl;
++shared_integer;
mut.unlock();
});
This syntax shares the shared_integer
parameters automatically, at the innermost levels of the execution hierarchy. Another convention would be to create a single shared_integer
parameter at the outermost level. One reason to prefer the innermost level is that it's already possible to share something among all the agents by capturing a variable by reference, as this example does with the std::mutex
variable.
We could also come up with some additional syntax to explicitly specify the level at which to share individual parameters. Something like this may be possible:
std::mutex mut;
constexpr int level = 0;
agency::bulk_invoke(agency::par(10), [&](agency::parallel_agent& self, shared<level,int>& shared_parm)
{
int& shared_integer = shared_parm.get();
mut.lock();
std::cout << "shared_integer: " << shared_integer << std::endl;
++shared_integer;
mut.unlock();
});
We might also be able to reuse the shared<level,T>
type to store dynamically-allocated shared objects as well.
One drawback to this approach is that there's not really a way to initialize the values of the shared parameters besides simply calling their default constructor.
It might be worth investigating a way to call some other special constructor. For example, it would be convenient to be able to automatically create a container whose size is initialized to the number of execution agents sharing the vector. The problem is that the variable's lifetime begins before the execution agents -- so we can't just pass self
to the variable's constructor. Even if we could, it's not clear that would be helpful -- which execution agent would we choose? And how would we guarantee that the object has been constructed before all agents call the user's function?
It might be possible to teach
bulk_invoke()
and friends how to introspect the types of shared parameter objects to create automatically by inspecting a lambda's parameter types. This would avoid needing to useshare<T>()
.