Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions .yamato/training-backcompat-tests.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@

test_mac_backcompat_2020.1:
{% capture editor_version %}2020.1{% endcapture %}
test_mac_backcompat_2019.4:
{% capture editor_version %}2019.4{% endcapture %}
{% capture csharp_backcompat_version %}1.0.0{% endcapture %}
# This test has to run on mac because it requires the custom build of tensorflow without AVX
# Test against 2020.1 because 2020.2 has to run against package version 1.2.0
name: Test Mac Backcompat Training {{ editor_version }}
agent:
type: Unity::VM::osx
image: ml-agents/ml-agents-bokken-mac:0.1.4-492264
image: ml-agents/ml-agents-bokken-mac:0.1.5-853758
flavor: b1.small
variables:
UNITY_VERSION: {{ editor_version }}
commands:
- |
python3 -m venv venv && source venv/bin/activate
python -m venv venv && source venv/bin/activate
python -m pip install pyyaml --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
python -m pip install unity-downloader-cli --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple --upgrade
unity-downloader-cli -u {{ editor_version }} -c editor --wait --fast
Expand All @@ -23,9 +23,9 @@ test_mac_backcompat_2020.1:
python -u -m ml-agents.tests.yamato.standalone_build_tests --build-target=mac
python -u -m ml-agents.tests.yamato.training_int_tests --csharp {{ csharp_backcompat_version }}
- |
python3 -m venv venv_old && source venv_old/bin/activate
python -m venv venv_old && source venv_old/bin/activate
python -m pip install pyyaml --index-url https://artifactory.prd.it.unity3d.com/artifactory/api/pypi/pypi/simple
python -u -m ml-agents.tests.yamato.training_int_tests --python 0.16.0
python -u -m ml-agents.tests.yamato.training_int_tests --python 0.24.0
triggers:
cancel_old_ci: true
recurring:
Expand Down
3 changes: 3 additions & 0 deletions com.unity.ml-agents/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ and this project adheres to
### Minor Changes
#### com.unity.ml-agents (C#)
- Upgrade to 2.0.1
#### ml-agents / ml-agents-envs / gym-unity (Python)
- Set gym version in gym-unity to gym release 0.20.0
- Added minimal analytics collection to LL-API (#5511)

## [2.0.0] - 2021-09-01
### Minor Changes
Expand Down
Binary file not shown.
31 changes: 24 additions & 7 deletions com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#define MLA_SUPPORTED_TRAINING_PLATFORM
#endif

# if MLA_SUPPORTED_TRAINING_PLATFORM
#if MLA_SUPPORTED_TRAINING_PLATFORM
using Grpc.Core;
#if UNITY_EDITOR
using UnityEditor;
Expand Down Expand Up @@ -50,6 +50,7 @@ internal class RpcCommunicator : ICommunicator

/// The Unity to External client.
UnityToExternalProto.UnityToExternalProtoClient m_Client;
Channel m_Channel;

/// <summary>
/// Initializes a new instance of the RPCCommunicator class.
Expand Down Expand Up @@ -140,6 +141,7 @@ out input
Debug.Log($"Unexpected exception when trying to initialize communication: {ex}");
}
initParametersOut = new UnityRLInitParameters();
NotifyQuitAndShutDownChannel();
return false;
}

Expand Down Expand Up @@ -181,6 +183,8 @@ out input

UpdateEnvironmentWithInput(input.RlInput);
initParametersOut = initializationInput.RlInitializationInput.ToUnityRLInitParameters();
// Be sure to shut down the grpc channel when the application is quitting.
Application.quitting += NotifyQuitAndShutDownChannel;
return true;
#else
initParametersOut = new UnityRLInitParameters();
Expand Down Expand Up @@ -217,9 +221,9 @@ void UpdateEnvironmentWithInput(UnityRLInputProto rlInput)
UnityInputProto Initialize(int port, UnityOutputProto unityOutput, out UnityInputProto unityInput)
{
m_IsOpen = true;
var channel = new Channel($"localhost:{port}", ChannelCredentials.Insecure);
m_Channel = new Channel($"localhost:{port}", ChannelCredentials.Insecure);

m_Client = new UnityToExternalProto.UnityToExternalProtoClient(channel);
m_Client = new UnityToExternalProto.UnityToExternalProtoClient(m_Channel);
var result = m_Client.Exchange(WrapMessage(unityOutput, 200));
var inputMessage = m_Client.Exchange(WrapMessage(null, 200));
unityInput = inputMessage.UnityInput;
Expand All @@ -229,11 +233,24 @@ UnityInputProto Initialize(int port, UnityOutputProto unityOutput, out UnityInpu
if (result.Header.Status != 200 || inputMessage.Header.Status != 200)
{
m_IsOpen = false;
QuitCommandReceived?.Invoke();
NotifyQuitAndShutDownChannel();
}
return result.UnityInput;
}

void NotifyQuitAndShutDownChannel()
{
QuitCommandReceived?.Invoke();
try
{
m_Channel.ShutdownAsync().Wait();
}
catch (Exception)
{
// do nothing
}
}

#endregion

#region Destruction
Expand Down Expand Up @@ -269,7 +286,7 @@ void SendCommandEvent(CommandProto command)
{
case CommandProto.Quit:
{
QuitCommandReceived?.Invoke();
NotifyQuitAndShutDownChannel();
return;
}
case CommandProto.Reset:
Expand Down Expand Up @@ -456,7 +473,7 @@ UnityInputProto Exchange(UnityOutputProto unityOutput)
// Not sure if the quit command is actually sent when a
// non 200 message is received. Notify that we are indeed
// quitting.
QuitCommandReceived?.Invoke();
NotifyQuitAndShutDownChannel();
return message.UnityInput;
}
catch (Exception ex)
Expand Down Expand Up @@ -488,7 +505,7 @@ UnityInputProto Exchange(UnityOutputProto unityOutput)
}

m_IsOpen = false;
QuitCommandReceived?.Invoke();
NotifyQuitAndShutDownChannel();
return null;
}
}
Expand Down
2 changes: 1 addition & 1 deletion gym-unity/gym_unity/tests/test_gym.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ def create_mock_vector_steps(specs, num_agents=1, number_visual_observations=0):
:BehaviorSpecs specs: The BehaviorSpecs for this mock
:int num_agents: Number of "agents" to imitate in your BatchedStepResult values.
"""
obs = [np.array([num_agents * [1, 2, 3]]).reshape(num_agents, 3)]
obs = [np.array([num_agents * [1, 2, 3]], dtype=np.float32).reshape(num_agents, 3)]
if number_visual_observations:
obs += [
np.zeros(shape=(num_agents, 8, 8, 3), dtype=np.float32)
Expand Down
2 changes: 1 addition & 1 deletion gym-unity/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,6 @@ def run(self):
author_email="ML-Agents@unity3d.com",
url="https://github.com/Unity-Technologies/ml-agents",
packages=find_packages(),
install_requires=["gym", f"mlagents_envs=={VERSION}"],
install_requires=["gym==0.20.0", f"mlagents_envs=={VERSION}"],
cmdclass={"verify": VerifyVersionCommand},
)
1 change: 1 addition & 0 deletions junit/test-results.xml

Large diffs are not rendered by default.

13 changes: 13 additions & 0 deletions ml-agents-envs/mlagents_envs/environment.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

from mlagents_envs.logging_util import get_logger
from mlagents_envs.side_channel.side_channel import SideChannel
from mlagents_envs.side_channel import DefaultTrainingAnalyticsSideChannel
from mlagents_envs.side_channel.side_channel_manager import SideChannelManager
from mlagents_envs import env_utils

Expand Down Expand Up @@ -186,6 +187,16 @@ def __init__(
self._timeout_wait: int = timeout_wait
self._communicator = self._get_communicator(worker_id, base_port, timeout_wait)
self._worker_id = worker_id
if side_channels is None:
side_channels = []
default_training_side_channel: Optional[
DefaultTrainingAnalyticsSideChannel
] = None
if DefaultTrainingAnalyticsSideChannel.CHANNEL_ID not in [
_.channel_id for _ in side_channels
]:
default_training_side_channel = DefaultTrainingAnalyticsSideChannel()
side_channels.append(default_training_side_channel)
self._side_channel_manager = SideChannelManager(side_channels)
self._log_folder = log_folder
self.academy_capabilities: UnityRLCapabilitiesProto = None # type: ignore
Expand Down Expand Up @@ -246,6 +257,8 @@ def __init__(
self._is_first_message = True
self._update_behavior_specs(aca_output)
self.academy_capabilities = aca_params.capabilities
if default_training_side_channel is not None:
default_training_side_channel.environment_initialized()

@staticmethod
def _get_communicator(worker_id, base_port, timeout_wait):
Expand Down
3 changes: 3 additions & 0 deletions ml-agents-envs/mlagents_envs/side_channel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@
from mlagents_envs.side_channel.outgoing_message import OutgoingMessage # noqa

from mlagents_envs.side_channel.side_channel import SideChannel # noqa
from mlagents_envs.side_channel.default_training_analytics_side_channel import ( # noqa
DefaultTrainingAnalyticsSideChannel, # noqa
) # noqa
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import sys
import uuid
import mlagents_envs

from mlagents_envs.exception import UnityCommunicationException
from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage
from mlagents_envs.communicator_objects.training_analytics_pb2 import (
TrainingEnvironmentInitialized,
)
from google.protobuf.any_pb2 import Any


class DefaultTrainingAnalyticsSideChannel(SideChannel):
"""
Side channel that sends information about the training to the Unity environment so it can be logged.
"""

CHANNEL_ID = uuid.UUID("b664a4a9-d86f-5a5f-95cb-e8353a7e8356")

def __init__(self) -> None:
# >>> uuid.uuid5(uuid.NAMESPACE_URL, "com.unity.ml-agents/TrainingAnalyticsSideChannel")
# UUID('b664a4a9-d86f-5a5f-95cb-e8353a7e8356')
# We purposefully use the SAME side channel as the TrainingAnalyticsSideChannel

super().__init__(DefaultTrainingAnalyticsSideChannel.CHANNEL_ID)

def on_message_received(self, msg: IncomingMessage) -> None:
raise UnityCommunicationException(
"The DefaultTrainingAnalyticsSideChannel received a message from Unity, "
+ "this should not have happened."
)

def environment_initialized(self) -> None:
# Tuple of (major, minor, patch)
vi = sys.version_info

msg = TrainingEnvironmentInitialized(
python_version=f"{vi[0]}.{vi[1]}.{vi[2]}",
mlagents_version="Custom",
mlagents_envs_version=mlagents_envs.__version__,
torch_version="Unknown",
torch_device_type="Unknown",
)
any_message = Any()
any_message.Pack(msg)

env_init_msg = OutgoingMessage()
env_init_msg.set_raw_bytes(any_message.SerializeToString()) # type: ignore
super().queue_message_to_send(env_init_msg)
12 changes: 8 additions & 4 deletions ml-agents/mlagents/training_analytics_side_channel.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import sys
from typing import Optional
import uuid
import mlagents_envs
import mlagents.trainers
from mlagents import torch_utils
from mlagents.trainers.settings import RewardSignalType
from mlagents_envs.exception import UnityCommunicationException
from mlagents_envs.side_channel import SideChannel, IncomingMessage, OutgoingMessage
from mlagents_envs.side_channel import (
IncomingMessage,
OutgoingMessage,
DefaultTrainingAnalyticsSideChannel,
)
from mlagents_envs.communicator_objects.training_analytics_pb2 import (
TrainingEnvironmentInitialized,
TrainingBehaviorInitialized,
Expand All @@ -16,15 +19,16 @@
from mlagents.trainers.settings import TrainerSettings, RunOptions


class TrainingAnalyticsSideChannel(SideChannel):
class TrainingAnalyticsSideChannel(DefaultTrainingAnalyticsSideChannel):
"""
Side channel that sends information about the training to the Unity environment so it can be logged.
"""

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

def on_message_received(self, msg: IncomingMessage) -> None:
Expand Down
2 changes: 1 addition & 1 deletion ml-agents/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ def run(self):
# cattrs 1.1.0 dropped support for python 3.6, but 1.0.0 doesn't work for python 3.9
# Since there's no version that supports both, we have to draw the line somwehere.
"cattrs<1.1.0; python_version<'3.8'",
"cattrs>=1.1.0; python_version>='3.8'",
"cattrs>=1.1.0,<1.7; python_version>='3.8'",
"attrs>=19.3.0",
'pypiwin32==223;platform_system=="Windows"',
"importlib_metadata; python_version<'3.8'",
Expand Down
20 changes: 6 additions & 14 deletions ml-agents/tests/yamato/training_int_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import sys
import subprocess
import time
from typing import Any

from .yamato_utils import (
find_executables,
Expand All @@ -14,7 +13,6 @@
run_standalone_build,
init_venv,
override_config_file,
override_legacy_config_file,
checkout_csharp_version,
undo_git_checkout,
)
Expand All @@ -26,7 +24,7 @@ def run_training(python_version: str, csharp_version: str) -> bool:
print(
f"Running training with python={python_version or latest} and c#={csharp_version or latest}"
)
output_dir = "models" if python_version else "results"
output_dir = "results"
onnx_file_expected = f"./{output_dir}/{run_id}/3DBall.onnx"

if os.path.exists(onnx_file_expected):
Expand Down Expand Up @@ -70,17 +68,11 @@ def run_training(python_version: str, csharp_version: str) -> bool:
# Copy the default training config but override the max_steps parameter,
# and reduce the batch_size and buffer_size enough to ensure an update step happens.
yaml_out = "override.yaml"
if python_version:
overrides: Any = {"max_steps": 100, "batch_size": 10, "buffer_size": 10}
override_legacy_config_file(
python_version, "config/trainer_config.yaml", yaml_out, **overrides
)
else:
overrides = {
"hyperparameters": {"batch_size": 10, "buffer_size": 10},
"max_steps": 100,
}
override_config_file("config/ppo/3DBall.yaml", yaml_out, overrides)
overrides = {
"hyperparameters": {"batch_size": 10, "buffer_size": 10},
"max_steps": 100,
}
override_config_file("config/ppo/3DBall.yaml", yaml_out, overrides)

log_output_path = f"{get_base_output_path()}/training.log"
env_path = os.path.join(get_base_output_path(), standalone_player_path)
Expand Down
3 changes: 0 additions & 3 deletions ml-agents/tests/yamato/yamato_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,10 @@ def init_venv(
pip_commands = ["--upgrade pip", "--upgrade setuptools"]
if mlagents_python_version:
# install from pypi
if platform != "darwin":
raise RuntimeError("Yamato can only run tensorflow on mac platforms!")
pip_commands += [
f"mlagents=={mlagents_python_version}",
f"gym-unity=={mlagents_python_version}",
# TODO build these and publish to internal pypi
"~/tensorflow_pkg/tensorflow-2.0.0-cp37-cp37m-macosx_10_14_x86_64.whl",
"tf2onnx==1.6.1",
]
else:
Expand Down