Skip to content
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

Investigate simple syntax for shared parameters for common scenarios #236

Open
jaredhoberock opened this issue Aug 3, 2016 · 2 comments

Comments

@jaredhoberock
Copy link
Collaborator

jaredhoberock commented Aug 3, 2016

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 use share<T>().

@jaredhoberock
Copy link
Collaborator Author

jaredhoberock commented Aug 4, 2016

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.

@jaredhoberock jaredhoberock modified the milestones: Release0.X, Release0.2 Aug 17, 2016
@jaredhoberock
Copy link
Collaborator Author

jaredhoberock commented Oct 4, 2016

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant