Skip to content

Commit 609cfbf

Browse files
committed
cherrypick Custom trainer editor analytics (#5511)
1 parent a4c985f commit 609cfbf

File tree

5 files changed

+75
-5
lines changed

5 files changed

+75
-5
lines changed

com.unity.ml-agents/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ and this project adheres to
2020
terminated teammates. (#5441)
2121
- Fixed wrong attribute name in argparser for torch device option (#5433)(#5467)
2222
- Fixed conflicting CLI and yaml options regarding resume & initialize_from (#5495)
23+
- Added minimal analytics collection to LL-API (#5511)
2324
## [2.1.0-exp.1] - 2021-06-09
2425
### Minor Changes
2526
#### com.unity.ml-agents / com.unity.ml-agents.extensions (C#)

ml-agents-envs/mlagents_envs/environment.py

+13
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
from mlagents_envs.logging_util import get_logger
1212
from mlagents_envs.side_channel.side_channel import SideChannel
13+
from mlagents_envs.side_channel import DefaultTrainingAnalyticsSideChannel
1314
from mlagents_envs.side_channel.side_channel_manager import SideChannelManager
1415
from mlagents_envs import env_utils
1516

@@ -186,6 +187,16 @@ def __init__(
186187
self._timeout_wait: int = timeout_wait
187188
self._communicator = self._get_communicator(worker_id, base_port, timeout_wait)
188189
self._worker_id = worker_id
190+
if side_channels is None:
191+
side_channels = []
192+
default_training_side_channel: Optional[
193+
DefaultTrainingAnalyticsSideChannel
194+
] = None
195+
if DefaultTrainingAnalyticsSideChannel.CHANNEL_ID not in [
196+
_.channel_id for _ in side_channels
197+
]:
198+
default_training_side_channel = DefaultTrainingAnalyticsSideChannel()
199+
side_channels.append(default_training_side_channel)
189200
self._side_channel_manager = SideChannelManager(side_channels)
190201
self._log_folder = log_folder
191202
self.academy_capabilities: UnityRLCapabilitiesProto = None # type: ignore
@@ -246,6 +257,8 @@ def __init__(
246257
self._is_first_message = True
247258
self._update_behavior_specs(aca_output)
248259
self.academy_capabilities = aca_params.capabilities
260+
if default_training_side_channel is not None:
261+
default_training_side_channel.environment_initialized()
249262

250263
@staticmethod
251264
def _get_communicator(worker_id, base_port, timeout_wait):

ml-agents-envs/mlagents_envs/side_channel/__init__.py

+3
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22
from mlagents_envs.side_channel.outgoing_message import OutgoingMessage # noqa
33

44
from mlagents_envs.side_channel.side_channel import SideChannel # noqa
5+
from mlagents_envs.side_channel.default_training_analytics_side_channel import ( # noqa
6+
DefaultTrainingAnalyticsSideChannel, # noqa
7+
) # noqa
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import sys
2+
import uuid
3+
import mlagents_envs
4+
5+
from mlagents_envs.exception import UnityCommunicationException
6+
from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage
7+
from mlagents_envs.communicator_objects.training_analytics_pb2 import (
8+
TrainingEnvironmentInitialized,
9+
)
10+
from google.protobuf.any_pb2 import Any
11+
12+
13+
class DefaultTrainingAnalyticsSideChannel(SideChannel):
14+
"""
15+
Side channel that sends information about the training to the Unity environment so it can be logged.
16+
"""
17+
18+
CHANNEL_ID = uuid.UUID("b664a4a9-d86f-5a5f-95cb-e8353a7e8356")
19+
20+
def __init__(self) -> None:
21+
# >>> uuid.uuid5(uuid.NAMESPACE_URL, "com.unity.ml-agents/TrainingAnalyticsSideChannel")
22+
# UUID('b664a4a9-d86f-5a5f-95cb-e8353a7e8356')
23+
# We purposefully use the SAME side channel as the TrainingAnalyticsSideChannel
24+
25+
super().__init__(DefaultTrainingAnalyticsSideChannel.CHANNEL_ID)
26+
27+
def on_message_received(self, msg: IncomingMessage) -> None:
28+
raise UnityCommunicationException(
29+
"The DefaultTrainingAnalyticsSideChannel received a message from Unity, "
30+
+ "this should not have happened."
31+
)
32+
33+
def environment_initialized(self) -> None:
34+
# Tuple of (major, minor, patch)
35+
vi = sys.version_info
36+
37+
msg = TrainingEnvironmentInitialized(
38+
python_version=f"{vi[0]}.{vi[1]}.{vi[2]}",
39+
mlagents_version="Custom",
40+
mlagents_envs_version=mlagents_envs.__version__,
41+
torch_version="Unknown",
42+
torch_device_type="Unknown",
43+
)
44+
any_message = Any()
45+
any_message.Pack(msg)
46+
47+
env_init_msg = OutgoingMessage()
48+
env_init_msg.set_raw_bytes(any_message.SerializeToString()) # type: ignore
49+
super().queue_message_to_send(env_init_msg)

ml-agents/mlagents/training_analytics_side_channel.py

+9-5
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import sys
22
from typing import Optional
3-
import uuid
43
import mlagents_envs
54
import mlagents.trainers
65
from mlagents import torch_utils
76
from mlagents.trainers.settings import RewardSignalType
87
from mlagents_envs.exception import UnityCommunicationException
9-
from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage
8+
from mlagents_envs.side_channel import (
9+
IncomingMessage,
10+
OutgoingMessage,
11+
DefaultTrainingAnalyticsSideChannel,
12+
)
1013
from mlagents_envs.communicator_objects.training_analytics_pb2 import (
1114
TrainingEnvironmentInitialized,
1215
TrainingBehaviorInitialized,
@@ -16,21 +19,22 @@
1619
from mlagents.trainers.settings import TrainerSettings, RunOptions
1720

1821

19-
class TrainingAnalyticsSideChannel(SideChannel):
22+
class TrainingAnalyticsSideChannel(DefaultTrainingAnalyticsSideChannel):
2023
"""
2124
Side channel that sends information about the training to the Unity environment so it can be logged.
2225
"""
2326

2427
def __init__(self) -> None:
2528
# >>> uuid.uuid5(uuid.NAMESPACE_URL, "com.unity.ml-agents/TrainingAnalyticsSideChannel")
2629
# UUID('b664a4a9-d86f-5a5f-95cb-e8353a7e8356')
27-
super().__init__(uuid.UUID("b664a4a9-d86f-5a5f-95cb-e8353a7e8356"))
30+
# Use the same uuid as the parent side channel
31+
super().__init__()
2832
self.run_options: Optional[RunOptions] = None
2933

3034
def on_message_received(self, msg: IncomingMessage) -> None:
3135
raise UnityCommunicationException(
3236
"The TrainingAnalyticsSideChannel received a message from Unity, "
33-
+ "this should not have happened."
37+
"this should not have happened."
3438
)
3539

3640
def environment_initialized(self, run_options: RunOptions) -> None:

0 commit comments

Comments
 (0)