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

[Feature] Introduce grouping in VMAS #1658

Merged
merged 19 commits into from
Nov 2, 2023
Merged

Conversation

matteobettini
Copy link
Contributor

@matteobettini matteobettini commented Oct 27, 2023

This PR allows VMAS to use the MARL api with grouping.

Users will be able to provide a group_map to VMAS.
By default this will try to group agents named name_n into a group named "name".

In case at least one agent does not follow this convention and not group map is specified, VMAS will try to group all agents under the "agent" group

@facebook-github-bot facebook-github-bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 27, 2023
@matteobettini matteobettini changed the title [VMAS] Fix tests [VMAS] Introduce grouping in VMAS Oct 27, 2023
@matteobettini matteobettini marked this pull request as ready for review October 31, 2023 18:33
Copy link
Contributor Author

@matteobettini matteobettini left a comment

Choose a reason for hiding this comment

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

@vmoens this is ready for review when u can

@@ -50,9 +63,75 @@ def _get_envs():
]


@set_gym_backend("gym")
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Detached vmas from gym spec conversion to have custom conversion rules

Comment on lines +505 to +519
agent_indices = {}
action_list = []
n_agents = 0
for group, agent_names in self.group_map.items():
group_action = tensordict.get((group, "action"))
group_action_list = list(self.read_action(group_action, group=group))
agent_indices.update(
{
self.agent_names_to_indices_map[agent_name]: i + n_agents
for i, agent_name in enumerate(agent_names)
}
)
n_agents += len(agent_names)
action_list += group_action_list
action = [action_list[agent_indices[i]] for i in range(self.n_agents)]
Copy link
Contributor Author

Choose a reason for hiding this comment

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

this will convert actions from group dicts to the list (ordered as it should)

This bit of logic is the focus of the new test

Copy link
Contributor

@vmoens vmoens left a comment

Choose a reason for hiding this comment

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

@vmoens this is ready for review when u can

I guess you mean "you", "u" is my father :p

LGTM, I left some comments and suggestions

test/test_libs.py Show resolved Hide resolved
test/test_libs.py Outdated Show resolved Hide resolved
test/test_libs.py Outdated Show resolved Hide resolved
test/test_libs.py Outdated Show resolved Hide resolved
test/test_libs.py Outdated Show resolved Hide resolved
torchrl/envs/libs/vmas.py Outdated Show resolved Hide resolved
torchrl/envs/libs/vmas.py Outdated Show resolved Hide resolved
group_reward_spec,
group_info_spec,
) = self._make_unbatched_group_specs(group)
self.unbatched_action_spec[group] = group_action_spec
Copy link
Contributor

Choose a reason for hiding this comment

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

is self.unbatched_action_spec public on purpose?
Can we review the public attributes of VMAS? I feel there are a lot of them and most are undocumented. This will hamper development in the future. I would make anything that is not user facing private to give us more dev freedom.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure I will make private all I don't need to be public.
This will be bc-breaking though as the methods will not be available anymore.

Regarding the unbatched_spec, these are needed when creating modules. Giving the specs with the batch_size to the modules will lead to errors #1018. These attirbutes are used in BenchMARL for example

Copy link
Contributor

Choose a reason for hiding this comment

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

This will be bc-breaking though as the methods will not be available anymore.

you can always make a property that raises a warning

torchrl/envs/libs/vmas.py Outdated Show resolved Hide resolved
@@ -419,14 +590,10 @@ def read_reward(self, rewards):
rewards = _selective_unsqueeze(rewards, batch_size=self.batch_size)
return rewards

def read_action(self, action):
def read_action(self, action, group: str):
Copy link
Contributor

Choose a reason for hiding this comment

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

this is a public method and we're adding a new arg without default value, hence it's bc-breaking. Any chance we can make this non-bc breaking?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I can, or I can make it private, as requested above, which will be more bc breaking though

matteobettini and others added 3 commits November 1, 2023 14:39
@matteobettini
Copy link
Contributor Author

Ok I made all methods private.

I would like to keep the attributes public so that they can be accessed by libraries like BenchMARL.
I'll document them

@vmoens vmoens changed the title [VMAS] Introduce grouping in VMAS [Feature] Introduce grouping in VMAS Nov 1, 2023
@vmoens vmoens added the enhancement New feature or request label Nov 1, 2023
Copy link
Contributor

@vmoens vmoens left a comment

Choose a reason for hiding this comment

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

sorry for the spammy reviews

rewards = _selective_unsqueeze(rewards, batch_size=self.batch_size)
return rewards

def read_action(self, action):
def _read_action(self, action, group: str):
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this solution is worse, it used to be public and now it's private. Is there a solution that does not break previous behaviour?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes but it will leave the method public.

Just so to understand, do you want these methods public or private? I am happy to leave them public and making thewm bc comptible, but I thoght that private is what you wanted

Copy link
Contributor

Choose a reason for hiding this comment

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

The least bc-breaking the better.
I wasn't pointing at these methods in particular, more at all the attributes created when creating specs. It seems like there are loads of them.
read_action is public in other wrappers so I don't think it's a problem if it's public here too.

@matteobettini
Copy link
Contributor Author

ok now there shold be no bc changes and the public attributes should be all doxumented

@vmoens vmoens merged commit 04fbaa1 into pytorch:main Nov 2, 2023
52 of 59 checks passed
@matteobettini matteobettini deleted the fix_vmas branch December 4, 2023 11:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants