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

Added a distributed alias table to YGM. #256

Open
wants to merge 1 commit into
base: v0.7-dev
Choose a base branch
from

Conversation

LFletch1
Copy link
Contributor

@LFletch1 LFletch1 commented Sep 5, 2024

  • Added a distributed alias_table data structure to ygm. Alias table data structure enables O(1) sampling time from a discrete distribution.
  • User samples items by calling alias_table::async_sample which requires the user provide a lambda that takes the item sampled as an argument.
  • Created new namespace ygm::random where the default_random_engine now sits as well as alias_table
  • Created tests for the new alias table. Further testing will be written for it, I figured I'd get this PR sent to go ahead and start discussing the interface/implementation of the alias table.

Copy link
Collaborator

@steiltre steiltre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recommend making use of concepts in the way they are used in existing container base classes. We can decide where to move these concepts and new ones to add independent of this PR.

The existing constructors look good, but constructors that work from STL containers should be added as well.

concept convertable_to_double = std::convertible_to<T,double>;

template<typename T>
concept is_pair = requires {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can try to use the existing DoubleItemTuple here. This will be satisfied by std::pair and std::tuple with two items. To make this general, you can access elements using std::get.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Forgot about this, but we have a checker for std::pair that could be turned into a concept as well.

}

template<typename Container>
requires is_associative_container<Container> &&
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a concept for checking if a container is an associative container is good, but I don't think it's what is needed here. What is needed here is the presence of a for_all argument and a check that types are appropriate (same as is currently done here).

The code that you have written can build an alias_table from a ygm::io::line_parser (probably requires a .transform() method to be really useful), but this is not a container at all.

I recommend modeling this off of the base_batch_erase functionality I linked to for now. We can re-evaluate the concepts we should make use of in a future PR.

};

template<typename T>
concept is_value_container = requires {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

std::vector will satisfy this concept. Checking for the presence of for_all_args (using HasForAll) and then probing it for the number of items within the for_all_args tuple could work, but this would also be satisfied by the ygm::io::line_parser.

Checking these things might be a little complicated generically. We may have to write a very targeted concept that checks the container_type to get what we want.

};


template <typename item_type, typename RNG>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's no written rules about this, but try emulating the use and style of template parameters and aliases already in use; the ygm::container::bag is a good example. The template parameters are capitalized to make it clear they are specifically template parameters (and not the name of some struct we have elsewhere). Create a public alias for types that are likely to be useful outside of the class itself so they can be inspected.

item_type b;

template <typename Archive>
void serialize(Archive& ar) { // Needed for cereal serialization
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think you're ever serializing a table_item.

template <typename Visitor, typename... VisitorArgs>
void async_sample(Visitor visitor, const VisitorArgs &...args) { // Sample should be provided a lambda/functor that takes as an argument the item type

auto sample_wrapper = [](auto ptr_MAT, const VisitorArgs &...args) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ptr_MAT looks like it should stand for "pointer to multi-alias table", which this isn't.

build_alias_table();
m_local_items.clear();
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about constructing from local STL containers?

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

Successfully merging this pull request may close these issues.

2 participants