浏览代码

[MLA-1540] Training Analytics (#4780)

/MLA-1734-demo-provider
GitHub 4 年前
当前提交
d8835857
共有 38 个文件被更改,包括 2134 次插入76 次删除
  1. 7
      com.unity.ml-agents/Runtime/Academy.cs
  2. 63
      com.unity.ml-agents/Runtime/Analytics/Events.cs
  3. 8
      com.unity.ml-agents/Runtime/Analytics/InferenceAnalytics.cs
  4. 52
      com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs
  5. 5
      com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs
  6. 5
      com.unity.ml-agents/Runtime/Communicator/UnityRLCapabilities.cs
  7. 39
      com.unity.ml-agents/Runtime/Grpc/CommunicatorObjects/Capabilities.cs
  8. 14
      com.unity.ml-agents/Runtime/Policies/RemotePolicy.cs
  9. 18
      com.unity.ml-agents/Tests/Editor/Analytics/InferenceAnalyticsTests.cs
  10. 32
      com.unity.ml-agents/Tests/Editor/Communicator/GrpcExtensionsTests.cs
  11. 11
      ml-agents-envs/mlagents_envs/communicator_objects/capabilities_pb2.py
  12. 6
      ml-agents-envs/mlagents_envs/communicator_objects/capabilities_pb2.pyi
  13. 6
      ml-agents-envs/mlagents_envs/environment.py
  14. 2
      ml-agents-envs/mlagents_envs/side_channel/engine_configuration_channel.py
  15. 2
      ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py
  16. 12
      ml-agents/mlagents/trainers/env_manager.py
  17. 14
      ml-agents/mlagents/trainers/learn.py
  18. 72
      ml-agents/mlagents/trainers/subprocess_env_manager.py
  19. 2
      ml-agents/mlagents/trainers/tests/simple_test_envs.py
  20. 45
      ml-agents/mlagents/trainers/tests/test_subprocess_env_manager.py
  21. 3
      ml-agents/mlagents/trainers/trainer_controller.py
  22. 3
      protobuf-definitions/proto/mlagents_envs/communicator_objects/capabilities.proto
  23. 40
      com.unity.ml-agents/Runtime/Analytics/AnalyticsUtils.cs
  24. 3
      com.unity.ml-agents/Runtime/Analytics/AnalyticsUtils.cs.meta
  25. 246
      com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs
  26. 3
      com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs.meta
  27. 850
      com.unity.ml-agents/Runtime/Grpc/CommunicatorObjects/TrainingAnalytics.cs
  28. 11
      com.unity.ml-agents/Runtime/Grpc/CommunicatorObjects/TrainingAnalytics.cs.meta
  29. 50
      com.unity.ml-agents/Runtime/SideChannels/TrainingAnalyticsSideChannel.cs
  30. 3
      com.unity.ml-agents/Runtime/SideChannels/TrainingAnalyticsSideChannel.cs.meta
  31. 42
      com.unity.ml-agents/Tests/Editor/Analytics/TrainingAnalyticsTest.cs
  32. 3
      com.unity.ml-agents/Tests/Editor/Analytics/TrainingAnalyticsTest.cs.meta
  33. 65
      com.unity.ml-agents/Tests/Editor/TrainingAnalyticsSideChannelTests.cs
  34. 3
      com.unity.ml-agents/Tests/Editor/TrainingAnalyticsSideChannelTests.cs.meta
  35. 243
      ml-agents-envs/mlagents_envs/communicator_objects/training_analytics_pb2.py
  36. 97
      ml-agents-envs/mlagents_envs/communicator_objects/training_analytics_pb2.pyi
  37. 99
      ml-agents/mlagents/training_analytics_side_channel.py
  38. 31
      protobuf-definitions/proto/mlagents_envs/communicator_objects/training_analytics.proto

7
com.unity.ml-agents/Runtime/Academy.cs


/// <term>1.3.0</term>
/// <description>Support both continuous and discrete actions.</description>
/// </item>
/// <item>
/// <term>1.4.0</term>
/// <description>Support training analytics sent from python trainer to the editor.</description>
/// </item>
const string k_ApiVersion = "1.3.0";
const string k_ApiVersion = "1.4.0";
/// <summary>
/// Unity package version of com.unity.ml-agents.

EnableAutomaticStepping();
SideChannelManager.RegisterSideChannel(new EngineConfigurationChannel());
SideChannelManager.RegisterSideChannel(new TrainingAnalyticsSideChannel());
m_EnvironmentParameters = new EnvironmentParameters();
m_StatsRecorder = new StatsRecorder();

63
com.unity.ml-agents/Runtime/Analytics/Events.cs


};
}
}
internal struct RemotePolicyInitializedEvent
{
public string TrainingSessionGuid;
/// <summary>
/// Hash of the BehaviorName.
/// </summary>
public string BehaviorName;
public List<EventObservationSpec> ObservationSpecs;
public EventActionSpec ActionSpec;
/// <summary>
/// This will be the same as TrainingEnvironmentInitializedEvent if available, but
/// TrainingEnvironmentInitializedEvent maybe not always be available with older trainers.
/// </summary>
public string MLAgentsEnvsVersion;
public string TrainerCommunicationVersion;
}
internal struct TrainingEnvironmentInitializedEvent
{
public string TrainingSessionGuid;
public string TrainerPythonVersion;
public string MLAgentsVersion;
public string MLAgentsEnvsVersion;
public string TorchVersion;
public string TorchDeviceType;
public int NumEnvironments;
public int NumEnvironmentParameters;
}
[Flags]
internal enum RewardSignals
{
Extrinsic = 1 << 0,
Gail = 1 << 1,
Curiosity = 1 << 2,
Rnd = 1 << 3,
}
[Flags]
internal enum TrainingFeatures
{
BehavioralCloning = 1 << 0,
Recurrent = 1 << 1,
Threaded = 1 << 2,
SelfPlay = 1 << 3,
Curriculum = 1 << 4,
}
internal struct TrainingBehaviorInitializedEvent
{
public string TrainingSessionGuid;
public string BehaviorName;
public string TrainerType;
public RewardSignals RewardSignalFlags;
public TrainingFeatures TrainingFeatureFlags;
public string VisualEncoder;
public int NumNetworkLayers;
public int NumNetworkHiddenUnits;
}
}

8
com.unity.ml-agents/Runtime/Analytics/InferenceAnalytics.cs


// Note - to debug, use JsonUtility.ToJson on the event.
//Debug.Log(JsonUtility.ToJson(data, true));
#if UNITY_EDITOR
EditorAnalytics.SendEventWithLimit(k_EventName, data, k_EventVersion);
if (AnalyticsUtils.s_SendEditorAnalytics)
{
EditorAnalytics.SendEventWithLimit(k_EventName, data, k_EventVersion);
}
#else
return;
#endif

var inferenceEvent = new InferenceEvent();
// Hash the behavior name so that there's no concern about PII or "secret" data being leaked.
var behaviorNameHash = Hash128.Compute(behaviorName);
inferenceEvent.BehaviorName = behaviorNameHash.ToString();
inferenceEvent.BehaviorName = AnalyticsUtils.Hash(behaviorName);
inferenceEvent.BarracudaModelSource = barracudaModel.IrSource;
inferenceEvent.BarracudaModelVersion = barracudaModel.IrVersion;

52
com.unity.ml-agents/Runtime/Communicator/GrpcExtensions.cs


using UnityEngine;
using System.Runtime.CompilerServices;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Analytics;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.Demonstrations;
using Unity.MLAgents.Policies;

ConcatenatedPngObservations = proto.ConcatenatedPngObservations,
CompressedChannelMapping = proto.CompressedChannelMapping,
HybridActions = proto.HybridActions,
TrainingAnalytics = proto.TrainingAnalytics,
};
}

ConcatenatedPngObservations = rlCaps.ConcatenatedPngObservations,
CompressedChannelMapping = rlCaps.CompressedChannelMapping,
HybridActions = rlCaps.HybridActions,
TrainingAnalytics = rlCaps.TrainingAnalytics,
};
}

}
return true;
}
#region Analytics
internal static TrainingEnvironmentInitializedEvent ToTrainingEnvironmentInitializedEvent(
this TrainingEnvironmentInitialized inputProto)
{
return new TrainingEnvironmentInitializedEvent
{
TrainerPythonVersion = inputProto.PythonVersion,
MLAgentsVersion = inputProto.MlagentsVersion,
MLAgentsEnvsVersion = inputProto.MlagentsEnvsVersion,
TorchVersion = inputProto.TorchVersion,
TorchDeviceType = inputProto.TorchDeviceType,
NumEnvironments = inputProto.NumEnvs,
NumEnvironmentParameters = inputProto.NumEnvironmentParameters,
};
}
internal static TrainingBehaviorInitializedEvent ToTrainingBehaviorInitializedEvent(
this TrainingBehaviorInitialized inputProto)
{
RewardSignals rewardSignals = 0;
rewardSignals |= inputProto.ExtrinsicRewardEnabled ? RewardSignals.Extrinsic : 0;
rewardSignals |= inputProto.GailRewardEnabled ? RewardSignals.Gail : 0;
rewardSignals |= inputProto.CuriosityRewardEnabled ? RewardSignals.Curiosity : 0;
rewardSignals |= inputProto.RndRewardEnabled ? RewardSignals.Rnd : 0;
TrainingFeatures trainingFeatures = 0;
trainingFeatures |= inputProto.BehavioralCloningEnabled ? TrainingFeatures.BehavioralCloning : 0;
trainingFeatures |= inputProto.RecurrentEnabled ? TrainingFeatures.Recurrent : 0;
trainingFeatures |= inputProto.TrainerThreaded ? TrainingFeatures.Threaded : 0;
trainingFeatures |= inputProto.SelfPlayEnabled ? TrainingFeatures.SelfPlay : 0;
trainingFeatures |= inputProto.CurriculumEnabled ? TrainingFeatures.Curriculum : 0;
return new TrainingBehaviorInitializedEvent
{
BehaviorName = inputProto.BehaviorName,
TrainerType = inputProto.TrainerType,
RewardSignalFlags = rewardSignals,
TrainingFeatureFlags = trainingFeatures,
VisualEncoder = inputProto.VisualEncoder,
NumNetworkLayers = inputProto.NumNetworkLayers,
NumNetworkHiddenUnits = inputProto.NumNetworkHiddenUnits,
};
}
#endregion
}
}

5
com.unity.ml-agents/Runtime/Communicator/RpcCommunicator.cs


using System.Linq;
using UnityEngine;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Analytics;
using Unity.MLAgents.CommunicatorObjects;
using Unity.MLAgents.Sensors;
using Unity.MLAgents.SideChannels;

},
out input);
var pythonCommunicationVersion = initializationInput.RlInitializationInput.CommunicationVersion;
var pythonCommunicationVersion = initializationInput.RlInitializationInput.CommunicationVersion;
TrainingAnalytics.SetTrainerInformation(pythonPackageVersion, pythonCommunicationVersion);
var communicationIsCompatible = CheckCommunicationVersionsAreCompatible(unityCommunicationVersion,
pythonCommunicationVersion,

5
com.unity.ml-agents/Runtime/Communicator/UnityRLCapabilities.cs


public bool ConcatenatedPngObservations;
public bool CompressedChannelMapping;
public bool HybridActions;
public bool TrainingAnalytics;
/// <summary>
/// A class holding the capabilities flags for Reinforcement Learning across C# and the Trainer codebase. This

bool baseRlCapabilities = true,
bool concatenatedPngObservations = true,
bool compressedChannelMapping = true,
bool hybridActions = true)
bool hybridActions = true,
bool trainingAnalytics = true)
TrainingAnalytics = trainingAnalytics;
}
/// <summary>

39
com.unity.ml-agents/Runtime/Grpc/CommunicatorObjects/Capabilities.cs


byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CjVtbGFnZW50c19lbnZzL2NvbW11bmljYXRvcl9vYmplY3RzL2NhcGFiaWxp",
"dGllcy5wcm90bxIUY29tbXVuaWNhdG9yX29iamVjdHMilAEKGFVuaXR5UkxD",
"dGllcy5wcm90bxIUY29tbXVuaWNhdG9yX29iamVjdHMirwEKGFVuaXR5UkxD",
"ASgIQiWqAiJVbml0eS5NTEFnZW50cy5Db21tdW5pY2F0b3JPYmplY3RzYgZw",
"cm90bzM="));
"ASgIEhkKEXRyYWluaW5nQW5hbHl0aWNzGAUgASgIQiWqAiJVbml0eS5NTEFn",
"ZW50cy5Db21tdW5pY2F0b3JPYmplY3RzYgZwcm90bzM="));
new pbr::GeneratedClrTypeInfo(typeof(global::Unity.MLAgents.CommunicatorObjects.UnityRLCapabilitiesProto), global::Unity.MLAgents.CommunicatorObjects.UnityRLCapabilitiesProto.Parser, new[]{ "BaseRLCapabilities", "ConcatenatedPngObservations", "CompressedChannelMapping", "HybridActions" }, null, null, null)
new pbr::GeneratedClrTypeInfo(typeof(global::Unity.MLAgents.CommunicatorObjects.UnityRLCapabilitiesProto), global::Unity.MLAgents.CommunicatorObjects.UnityRLCapabilitiesProto.Parser, new[]{ "BaseRLCapabilities", "ConcatenatedPngObservations", "CompressedChannelMapping", "HybridActions", "TrainingAnalytics" }, null, null, null)
}));
}
#endregion

concatenatedPngObservations_ = other.concatenatedPngObservations_;
compressedChannelMapping_ = other.compressedChannelMapping_;
hybridActions_ = other.hybridActions_;
trainingAnalytics_ = other.trainingAnalytics_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}

}
}
/// <summary>Field number for the "trainingAnalytics" field.</summary>
public const int TrainingAnalyticsFieldNumber = 5;
private bool trainingAnalytics_;
/// <summary>
/// support for training analytics
/// </summary>
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public bool TrainingAnalytics {
get { return trainingAnalytics_; }
set {
trainingAnalytics_ = value;
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as UnityRLCapabilitiesProto);

if (ConcatenatedPngObservations != other.ConcatenatedPngObservations) return false;
if (CompressedChannelMapping != other.CompressedChannelMapping) return false;
if (HybridActions != other.HybridActions) return false;
if (TrainingAnalytics != other.TrainingAnalytics) return false;
return Equals(_unknownFields, other._unknownFields);
}

if (ConcatenatedPngObservations != false) hash ^= ConcatenatedPngObservations.GetHashCode();
if (CompressedChannelMapping != false) hash ^= CompressedChannelMapping.GetHashCode();
if (HybridActions != false) hash ^= HybridActions.GetHashCode();
if (TrainingAnalytics != false) hash ^= TrainingAnalytics.GetHashCode();
if (_unknownFields != null) {
hash ^= _unknownFields.GetHashCode();
}

output.WriteRawTag(32);
output.WriteBool(HybridActions);
}
if (TrainingAnalytics != false) {
output.WriteRawTag(40);
output.WriteBool(TrainingAnalytics);
}
if (_unknownFields != null) {
_unknownFields.WriteTo(output);
}

if (HybridActions != false) {
size += 1 + 1;
}
if (TrainingAnalytics != false) {
size += 1 + 1;
}
if (_unknownFields != null) {
size += _unknownFields.CalculateSize();
}

}
if (other.HybridActions != false) {
HybridActions = other.HybridActions;
}
if (other.TrainingAnalytics != false) {
TrainingAnalytics = other.TrainingAnalytics;
}
_unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
}

}
case 32: {
HybridActions = input.ReadBool();
break;
}
case 40: {
TrainingAnalytics = input.ReadBool();
break;
}
}

14
com.unity.ml-agents/Runtime/Policies/RemotePolicy.cs


using System.Collections.Generic;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Analytics;
namespace Unity.MLAgents.Policies
{

string m_FullyQualifiedBehaviorName;
ActionSpec m_ActionSpec;
ActionBuffers m_LastActionBuffer;
private bool m_AnalyticsSent = false;
internal ICommunicator m_Communicator;

{
m_FullyQualifiedBehaviorName = fullyQualifiedBehaviorName;
m_Communicator = Academy.Instance.Communicator;
m_Communicator.SubscribeBrain(m_FullyQualifiedBehaviorName, actionSpec);
m_Communicator?.SubscribeBrain(m_FullyQualifiedBehaviorName, actionSpec);
m_ActionSpec = actionSpec;
}

if (!m_AnalyticsSent)
{
m_AnalyticsSent = true;
TrainingAnalytics.RemotePolicyInitialized(
m_FullyQualifiedBehaviorName,
sensors,
m_ActionSpec
);
}
m_AgentId = info.episodeId;
m_Communicator?.PutObservations(m_FullyQualifiedBehaviorName, info, sensors);
}

18
com.unity.ml-agents/Tests/Editor/Analytics/InferenceAnalyticsTests.cs


[SetUp]
public void SetUp()
{
if (Academy.IsInitialized)
{
Academy.Instance.Dispose();
}
continuousONNXModel = (NNModel)AssetDatabase.LoadAssetAtPath(k_continuousONNXPath, typeof(NNModel));
var go = new GameObject("SensorA");
sensor_21_20_3 = go.AddComponent<Test3DSensorComponent>();

Assert.IsTrue(jsonString.Contains("NumDiscreteActions"));
Assert.IsTrue(jsonString.Contains("SensorName"));
Assert.IsTrue(jsonString.Contains("Flags"));
}
[Test]
public void TestBarracudaPolicy()
{
// Explicitly request decisions for a policy so we get code coverage on the event sending
using (new AnalyticsUtils.DisableAnalyticsSending())
{
var sensors = new List<ISensor> { sensor_21_20_3.Sensor, sensor_20_22_3.Sensor };
var policy = new BarracudaPolicy(GetContinuous2vis8vec2actionActionSpec(), continuousONNXModel, InferenceDevice.CPU, "testBehavior");
policy.RequestDecision(new AgentInfo(), sensors);
}
Academy.Instance.Dispose();
}
}
}

32
com.unity.ml-agents/Tests/Editor/Communicator/GrpcExtensionsTests.cs


using NUnit.Framework;
using Unity.MLAgents.Policies;
using Unity.MLAgents.Demonstrations;
using Unity.MLAgents.Analytics;
using Unity.MLAgents.CommunicatorObjects;
using Unity.MLAgents.Demonstrations;
using Unity.MLAgents.Policies;
using Unity.MLAgents.Sensors;
namespace Unity.MLAgents.Tests

Assert.AreEqual(GrpcExtensions.IsTrivialMapping(sparseChannelSensor), false);
sparseChannelSensor.Mapping = new[] { 0, 0, 0, 1, 1, 1 };
Assert.AreEqual(GrpcExtensions.IsTrivialMapping(sparseChannelSensor), false);
}
[Test]
public void TestDefaultTrainingEvents()
{
var trainingEnvInit = new TrainingEnvironmentInitialized
{
PythonVersion = "test",
};
var trainingEnvInitEvent = trainingEnvInit.ToTrainingEnvironmentInitializedEvent();
Assert.AreEqual(trainingEnvInit.PythonVersion, trainingEnvInitEvent.TrainerPythonVersion);
var trainingBehavInit = new TrainingBehaviorInitialized
{
BehaviorName = "testBehavior",
ExtrinsicRewardEnabled = true,
CuriosityRewardEnabled = true,
RecurrentEnabled = true,
SelfPlayEnabled = true,
};
var trainingBehavInitEvent = trainingBehavInit.ToTrainingBehaviorInitializedEvent();
Assert.AreEqual(trainingBehavInit.BehaviorName, trainingBehavInitEvent.BehaviorName);
Assert.AreEqual(RewardSignals.Extrinsic | RewardSignals.Curiosity, trainingBehavInitEvent.RewardSignalFlags);
Assert.AreEqual(TrainingFeatures.Recurrent | TrainingFeatures.SelfPlay, trainingBehavInitEvent.TrainingFeatureFlags);
}
}
}

11
ml-agents-envs/mlagents_envs/communicator_objects/capabilities_pb2.py


name='mlagents_envs/communicator_objects/capabilities.proto',
package='communicator_objects',
syntax='proto3',
serialized_pb=_b('\n5mlagents_envs/communicator_objects/capabilities.proto\x12\x14\x63ommunicator_objects\"\x94\x01\n\x18UnityRLCapabilitiesProto\x12\x1a\n\x12\x62\x61seRLCapabilities\x18\x01 \x01(\x08\x12#\n\x1b\x63oncatenatedPngObservations\x18\x02 \x01(\x08\x12 \n\x18\x63ompressedChannelMapping\x18\x03 \x01(\x08\x12\x15\n\rhybridActions\x18\x04 \x01(\x08\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3')
serialized_pb=_b('\n5mlagents_envs/communicator_objects/capabilities.proto\x12\x14\x63ommunicator_objects\"\xaf\x01\n\x18UnityRLCapabilitiesProto\x12\x1a\n\x12\x62\x61seRLCapabilities\x18\x01 \x01(\x08\x12#\n\x1b\x63oncatenatedPngObservations\x18\x02 \x01(\x08\x12 \n\x18\x63ompressedChannelMapping\x18\x03 \x01(\x08\x12\x15\n\rhybridActions\x18\x04 \x01(\x08\x12\x19\n\x11trainingAnalytics\x18\x05 \x01(\x08\x42%\xaa\x02\"Unity.MLAgents.CommunicatorObjectsb\x06proto3')
)

message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None, file=DESCRIPTOR),
_descriptor.FieldDescriptor(
name='trainingAnalytics', full_name='communicator_objects.UnityRLCapabilitiesProto.trainingAnalytics', index=4,
number=5, type=8, cpp_type=7, label=1,
has_default_value=False, default_value=False,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None, file=DESCRIPTOR),
],
extensions=[
],

oneofs=[
],
serialized_start=80,
serialized_end=228,
serialized_end=255,
)
DESCRIPTOR.message_types_by_name['UnityRLCapabilitiesProto'] = _UNITYRLCAPABILITIESPROTO

6
ml-agents-envs/mlagents_envs/communicator_objects/capabilities_pb2.pyi


concatenatedPngObservations = ... # type: builtin___bool
compressedChannelMapping = ... # type: builtin___bool
hybridActions = ... # type: builtin___bool
trainingAnalytics = ... # type: builtin___bool
def __init__(self,
*,

hybridActions : typing___Optional[builtin___bool] = None,
trainingAnalytics : typing___Optional[builtin___bool] = None,
) -> None: ...
@classmethod
def FromString(cls, s: builtin___bytes) -> UnityRLCapabilitiesProto: ...

def ClearField(self, field_name: typing_extensions___Literal[u"baseRLCapabilities",u"compressedChannelMapping",u"concatenatedPngObservations",u"hybridActions"]) -> None: ...
def ClearField(self, field_name: typing_extensions___Literal[u"baseRLCapabilities",u"compressedChannelMapping",u"concatenatedPngObservations",u"hybridActions",u"trainingAnalytics"]) -> None: ...
def ClearField(self, field_name: typing_extensions___Literal[u"baseRLCapabilities",b"baseRLCapabilities",u"compressedChannelMapping",b"compressedChannelMapping",u"concatenatedPngObservations",b"concatenatedPngObservations",u"hybridActions",b"hybridActions"]) -> None: ...
def ClearField(self, field_name: typing_extensions___Literal[u"baseRLCapabilities",b"baseRLCapabilities",u"compressedChannelMapping",b"compressedChannelMapping",u"concatenatedPngObservations",b"concatenatedPngObservations",u"hybridActions",b"hybridActions",u"trainingAnalytics",b"trainingAnalytics"]) -> None: ...

6
ml-agents-envs/mlagents_envs/environment.py


# * 1.1.0 - support concatenated PNGs for compressed observations.
# * 1.2.0 - support compression mapping for stacked compressed observations.
# * 1.3.0 - support action spaces with both continuous and discrete actions.
API_VERSION = "1.3.0"
# * 1.4.0 - support training analytics sent from python trainer to the editor.
API_VERSION = "1.4.0"
# Default port that the editor listens on. If an environment executable
# isn't specified, this port will be used.

capabilities.concatenatedPngObservations = True
capabilities.compressedChannelMapping = True
capabilities.hybridActions = True
capabilities.trainingAnalytics = True
return capabilities
@staticmethod

self._worker_id = worker_id
self._side_channel_manager = SideChannelManager(side_channels)
self._log_folder = log_folder
self.academy_capabilities: UnityRLCapabilitiesProto = None # type: ignore
# If the environment name is None, a new environment will not be launched
# and the communicator will directly try to connect to an existing unity environment.

self._env_actions: Dict[str, ActionTuple] = {}
self._is_first_message = True
self._update_behavior_specs(aca_output)
self.academy_capabilities = aca_params.capabilities
@staticmethod
def _get_communicator(worker_id, base_port, timeout_wait):

2
ml-agents-envs/mlagents_envs/side_channel/engine_configuration_channel.py


"""
raise UnityCommunicationException(
"The EngineConfigurationChannel received a message from Unity, "
+ "this should not have happend."
+ "this should not have happened."
)
def set_configuration_parameters(

2
ml-agents-envs/mlagents_envs/side_channel/environment_parameters_channel.py


def on_message_received(self, msg: IncomingMessage) -> None:
raise UnityCommunicationException(
"The EnvironmentParametersChannel received a message from Unity, "
+ "this should not have happend."
+ "this should not have happened."
)
def set_float_parameter(self, key: str, value: float) -> None:

12
ml-agents/mlagents/trainers/env_manager.py


from mlagents.trainers.policy import Policy
from mlagents.trainers.agent_processor import AgentManager, AgentManagerQueue
from mlagents.trainers.action_info import ActionInfo
from mlagents.trainers.settings import TrainerSettings
from mlagents_envs.logging_util import get_logger
AllStepResult = Dict[BehaviorName, Tuple[DecisionSteps, TerminalSteps]]

Sends environment parameter settings to C# via the
EnvironmentParametersSideChannel.
:param config: Dict of environment parameter keys and values
"""
pass
def on_training_started(
self, behavior_name: str, trainer_settings: TrainerSettings
) -> None:
"""
Handle traing starting for a new behavior type. Generally nothing is necessary here.
:param behavior_name:
:param trainer_settings:
:return:
"""
pass

14
ml-agents/mlagents/trainers/learn.py


from mlagents_envs.base_env import BaseEnv
from mlagents.trainers.subprocess_env_manager import SubprocessEnvManager
from mlagents_envs.side_channel.side_channel import SideChannel
from mlagents_envs.side_channel.engine_configuration_channel import EngineConfig
from mlagents_envs.timers import (
hierarchical_timer,
get_timer_tree,

env_settings.env_args,
os.path.abspath(run_logs_dir), # Unity environment requires absolute path
)
engine_config = EngineConfig(
width=engine_settings.width,
height=engine_settings.height,
quality_level=engine_settings.quality_level,
time_scale=engine_settings.time_scale,
target_frame_rate=engine_settings.target_frame_rate,
capture_frame_rate=engine_settings.capture_frame_rate,
)
env_manager = SubprocessEnvManager(
env_factory, engine_config, env_settings.num_envs
)
env_manager = SubprocessEnvManager(env_factory, options, env_settings.num_envs)
env_parameter_manager = EnvironmentParameterManager(
options.environment_parameters, run_seed, restore=checkpoint_settings.resume
)

72
ml-agents/mlagents/trainers/subprocess_env_manager.py


from mlagents_envs.base_env import BaseEnv, BehaviorName, BehaviorSpec
from mlagents_envs import logging_util
from mlagents.trainers.env_manager import EnvManager, EnvironmentStep, AllStepResult
from mlagents.trainers.settings import TrainerSettings
from mlagents_envs.timers import (
TimerNode,
timed,

)
from mlagents.trainers.settings import ParameterRandomizationSettings
from mlagents.trainers.settings import ParameterRandomizationSettings, RunOptions
from mlagents.trainers.action_info import ActionInfo
from mlagents_envs.side_channel.environment_parameters_channel import (
EnvironmentParametersChannel,

EngineConfig,
)
from mlagents_envs.side_channel.stats_side_channel import (
EnvironmentStats,
EnvironmentStats,
from mlagents.training_analytics_side_channel import TrainingAnalyticsSideChannel
from mlagents_envs.side_channel.side_channel import SideChannel

CLOSE = 5
ENV_EXITED = 6
CLOSED = 7
TRAINING_STARTED = 8
class EnvironmentRequest(NamedTuple):

step_queue: Queue,
pickled_env_factory: str,
worker_id: int,
engine_configuration: EngineConfig,
run_options: RunOptions,
log_level: int = logging_util.INFO,
) -> None:
env_factory: Callable[

engine_config = EngineConfig(
width=run_options.engine_settings.width,
height=run_options.engine_settings.height,
quality_level=run_options.engine_settings.quality_level,
time_scale=run_options.engine_settings.time_scale,
target_frame_rate=run_options.engine_settings.target_frame_rate,
capture_frame_rate=run_options.engine_settings.capture_frame_rate,
)
engine_configuration_channel.set_configuration(engine_configuration)
engine_configuration_channel.set_configuration(engine_config)
env: BaseEnv = None
training_analytics_channel: Optional[TrainingAnalyticsSideChannel] = None
if worker_id == 0:
training_analytics_channel = TrainingAnalyticsSideChannel()
env: UnityEnvironment = None
# Set log level. On some platforms, the logger isn't common with the
# main process, so we need to set it again.
logging_util.set_log_level(log_level)

return all_step_result
try:
env = env_factory(
worker_id, [env_parameters, engine_configuration_channel, stats_channel]
)
side_channels = [env_parameters, engine_configuration_channel, stats_channel]
if training_analytics_channel is not None:
side_channels.append(training_analytics_channel)
env = env_factory(worker_id, side_channels)
if (
not env.academy_capabilities
or not env.academy_capabilities.trainingAnalytics
):
# Make sure we don't try to send training analytics if the environment doesn't know how to process
# them. This wouldn't be catastrophic, but would result in unknown SideChannel UUIDs being used.
training_analytics_channel = None
if training_analytics_channel:
training_analytics_channel.environment_initialized(run_options)
while True:
req: EnvironmentRequest = parent_conn.recv()
if req.cmd == EnvironmentCommand.STEP:

for k, v in req.payload.items():
if isinstance(v, ParameterRandomizationSettings):
v.apply(k, env_parameters)
elif req.cmd == EnvironmentCommand.TRAINING_STARTED:
behavior_name, trainer_config = req.payload
if training_analytics_channel:
training_analytics_channel.training_started(
behavior_name, trainer_config
)
elif req.cmd == EnvironmentCommand.RESET:
env.reset()
all_step_result = _generate_all_results()

def __init__(
self,
env_factory: Callable[[int, List[SideChannel]], BaseEnv],
engine_configuration: EngineConfig,
run_options: RunOptions,
n_env: int = 1,
):
super().__init__()

for worker_idx in range(n_env):
self.env_workers.append(
self.create_worker(
worker_idx, self.step_queue, env_factory, engine_configuration
worker_idx, self.step_queue, env_factory, run_options
)
)
self.workers_alive += 1

worker_id: int,
step_queue: Queue,
env_factory: Callable[[int, List[SideChannel]], BaseEnv],
engine_configuration: EngineConfig,
run_options: RunOptions,
) -> UnityEnvWorker:
parent_conn, child_conn = Pipe()

step_queue,
pickled_env_factory,
worker_id,
engine_configuration,
run_options,
logger.level,
),
)

"""
for ew in self.env_workers:
ew.send(EnvironmentCommand.ENVIRONMENT_PARAMETERS, config)
def on_training_started(
self, behavior_name: str, trainer_settings: TrainerSettings
) -> None:
"""
Handle traing starting for a new behavior type. Generally nothing is necessary here.
:param behavior_name:
:param trainer_settings:
:return:
"""
for ew in self.env_workers:
ew.send(
EnvironmentCommand.TRAINING_STARTED, (behavior_name, trainer_settings)
)
@property
def training_behaviors(self) -> Dict[BehaviorName, BehaviorSpec]:

2
ml-agents/mlagents/trainers/tests/simple_test_envs.py


self.step_result: Dict[str, Tuple[DecisionSteps, TerminalSteps]] = {}
self.agent_id: Dict[str, int] = {}
self.step_size = step_size # defines the difficulty of the test
# Allow to be used as a UnityEnvironment during tests
self.academy_capabilities = None
for name in self.names:
self.agent_id[name] = 0

45
ml-agents/mlagents/trainers/tests/test_subprocess_env_manager.py


import pytest
from queue import Empty as EmptyQueue
from mlagents.trainers.settings import RunOptions
from mlagents.trainers.subprocess_env_manager import (
SubprocessEnvManager,
EnvironmentResponse,

from mlagents.trainers.env_manager import EnvironmentStep
from mlagents_envs.base_env import BaseEnv
from mlagents_envs.side_channel.engine_configuration_channel import EngineConfig
from mlagents_envs.side_channel.stats_side_channel import StatsAggregationMethod
from mlagents_envs.exception import UnityEnvironmentException
from mlagents.trainers.tests.simple_test_envs import (

)
def test_environments_are_created(self, mock_create_worker):
mock_create_worker.side_effect = create_worker_mock
env = SubprocessEnvManager(mock_env_factory, EngineConfig.default_config(), 2)
run_options = RunOptions()
env = SubprocessEnvManager(mock_env_factory, run_options, 2)
mock.call(
0, env.step_queue, mock_env_factory, EngineConfig.default_config()
),
mock.call(
1, env.step_queue, mock_env_factory, EngineConfig.default_config()
),
mock.call(0, env.step_queue, mock_env_factory, run_options),
mock.call(1, env.step_queue, mock_env_factory, run_options),
]
)
self.assertEqual(len(env.env_workers), 2)

)
def test_reset_passes_reset_params(self, mock_create_worker):
mock_create_worker.side_effect = create_worker_mock
manager = SubprocessEnvManager(
mock_env_factory, EngineConfig.default_config(), 1
)
manager = SubprocessEnvManager(mock_env_factory, RunOptions(), 1)
params = {"test": "params"}
manager._reset_env(params)
manager.env_workers[0].send.assert_called_with(

)
def test_reset_collects_results_from_all_envs(self, mock_create_worker):
mock_create_worker.side_effect = create_worker_mock
manager = SubprocessEnvManager(
mock_env_factory, EngineConfig.default_config(), 4
)
manager = SubprocessEnvManager(mock_env_factory, RunOptions(), 4)
params = {"test": "params"}
res = manager._reset_env(params)

)
mock_create_worker.side_effect = create_worker_mock
manager = SubprocessEnvManager(
mock_env_factory, EngineConfig.default_config(), 4
)
manager = SubprocessEnvManager(mock_env_factory, RunOptions(), 4)
res = manager.training_behaviors
for env in manager.env_workers:

)
def test_step_takes_steps_for_all_non_waiting_envs(self, mock_create_worker):
mock_create_worker.side_effect = create_worker_mock
manager = SubprocessEnvManager(
mock_env_factory, EngineConfig.default_config(), 3
)
manager = SubprocessEnvManager(mock_env_factory, RunOptions(), 3)
manager.step_queue = Mock()
manager.step_queue.get_nowait.side_effect = [
EnvironmentResponse(EnvironmentCommand.STEP, 0, StepResponse(0, None, {})),

brain_name = "testbrain"
action_info_dict = {brain_name: MagicMock()}
mock_create_worker.side_effect = create_worker_mock
env_manager = SubprocessEnvManager(
mock_env_factory, EngineConfig.default_config(), 3
)
env_manager = SubprocessEnvManager(mock_env_factory, RunOptions(), 3)
training_behaviors_mock.return_value = [brain_name]
agent_manager_mock = mock.Mock()
mock_policy = mock.Mock()

env = SimpleEnvironment(["1D"], action_sizes=(0, 1))
return env
env_manager = SubprocessEnvManager(
simple_env_factory, EngineConfig.default_config(), num_envs
)
env_manager = SubprocessEnvManager(simple_env_factory, RunOptions(), num_envs)
# Run PPO using env_manager
check_environment_trains(
simple_env_factory(0, []),

)
return env
env_manager = SubprocessEnvManager(
failing_step_env_factory, EngineConfig.default_config()
)
env_manager = SubprocessEnvManager(failing_step_env_factory, RunOptions())
# Expect the exception raised to be routed back up to the top level.
with pytest.raises(CustomTestOnlyException):
check_environment_trains(

time.sleep(0.5)
raise UnityEnvironmentException()
env_manager = SubprocessEnvManager(
failing_env_factory, EngineConfig.default_config(), num_envs
)
env_manager = SubprocessEnvManager(failing_env_factory, RunOptions(), num_envs)
with pytest.raises(UnityEnvironmentException):
env_manager.reset()
env_manager.close()

3
ml-agents/mlagents/trainers/trainer_controller.py


target=self.trainer_update_func, args=(trainer,), daemon=True
)
self.trainer_threads.append(trainerthread)
env_manager.on_training_started(
brain_name, self.trainer_factory.trainer_config[brain_name]
)
policy = trainer.create_policy(
parsed_behavior_id,

3
protobuf-definitions/proto/mlagents_envs/communicator_objects/capabilities.proto


// support for hybrid action spaces (discrete + continuous)
bool hybridActions = 4;
// support for training analytics
bool trainingAnalytics = 5;
}

40
com.unity.ml-agents/Runtime/Analytics/AnalyticsUtils.cs


using System;
using UnityEngine;
namespace Unity.MLAgents.Analytics
{
internal static class AnalyticsUtils
{
/// <summary>
/// Hash a string to remove PII or secret info before sending to analytics
/// </summary>
/// <param name="s"></param>
/// <returns>A string containing the Hash128 of the input string.</returns>
public static string Hash(string s)
{
var behaviorNameHash = Hash128.Compute(s);
return behaviorNameHash.ToString();
}
internal static bool s_SendEditorAnalytics = true;
/// <summary>
/// Helper class to temporarily disable sending analytics from unit tests.
/// </summary>
internal class DisableAnalyticsSending : IDisposable
{
private bool m_PreviousSendEditorAnalytics;
public DisableAnalyticsSending()
{
m_PreviousSendEditorAnalytics = s_SendEditorAnalytics;
s_SendEditorAnalytics = false;
}
public void Dispose()
{
s_SendEditorAnalytics = m_PreviousSendEditorAnalytics;
}
}
}
}

3
com.unity.ml-agents/Runtime/Analytics/AnalyticsUtils.cs.meta


fileFormatVersion: 2
guid: af1ef3e70f1242938d7b39284b1a892b
timeCreated: 1610575760

246
com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs


using System;
using System.Collections.Generic;
using Unity.MLAgents.Actuators;
using Unity.MLAgents.Sensors;
using UnityEngine;
using UnityEngine.Analytics;
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.Analytics;
#endif
namespace Unity.MLAgents.Analytics
{
internal class TrainingAnalytics
{
const string k_VendorKey = "unity.ml-agents";
const string k_TrainingEnvironmentInitializedEventName = "ml_agents_training_environment_initialized";
const string k_TrainingBehaviorInitializedEventName = "ml_agents_training_behavior_initialized";
const string k_RemotePolicyInitializedEventName = "ml_agents_remote_policy_initialized";
private static readonly string[] s_EventNames =
{
k_TrainingEnvironmentInitializedEventName,
k_TrainingBehaviorInitializedEventName,
k_RemotePolicyInitializedEventName
};
/// <summary>
/// Whether or not we've registered this particular event yet
/// </summary>
static bool s_EventsRegistered = false;
/// <summary>
/// Hourly limit for this event name
/// </summary>
const int k_MaxEventsPerHour = 1000;
/// <summary>
/// Maximum number of items in this event.
/// </summary>
const int k_MaxNumberOfElements = 1000;
private static bool s_SentEnvironmentInitialized;
/// <summary>
/// Behaviors that we've already sent events for.
/// </summary>
private static HashSet<string> s_SentRemotePolicyInitialized;
private static HashSet<string> s_SentTrainingBehaviorInitialized;
private static Guid s_TrainingSessionGuid;
// These are set when the RpcCommunicator connects
private static string s_TrainerPackageVersion = "";
private static string s_TrainerCommunicationVersion = "";
static bool EnableAnalytics()
{
if (s_EventsRegistered)
{
return true;
}
foreach (var eventName in s_EventNames)
{
#if UNITY_EDITOR
AnalyticsResult result = EditorAnalytics.RegisterEventWithLimit(eventName, k_MaxEventsPerHour, k_MaxNumberOfElements, k_VendorKey);
#else
AnalyticsResult result = AnalyticsResult.UnsupportedPlatform;
#endif
if (result != AnalyticsResult.Ok)
{
return false;
}
}
s_EventsRegistered = true;
if (s_SentRemotePolicyInitialized == null)
{
s_SentRemotePolicyInitialized = new HashSet<string>();
s_SentTrainingBehaviorInitialized = new HashSet<string>();
s_TrainingSessionGuid = Guid.NewGuid();
}
return s_EventsRegistered;
}
/// <summary>
/// Cache information about the trainer when it becomes available in the RpcCommunicator.
/// </summary>
/// <param name="communicationVersion"></param>
/// <param name="packageVersion"></param>
public static void SetTrainerInformation(string packageVersion, string communicationVersion)
{
s_TrainerPackageVersion = packageVersion;
s_TrainerCommunicationVersion = communicationVersion;
}
public static bool IsAnalyticsEnabled()
{
#if UNITY_EDITOR
return EditorAnalytics.enabled;
#else
return false;
#endif
}
public static void TrainingEnvironmentInitialized(TrainingEnvironmentInitializedEvent tbiEvent)
{
if (!IsAnalyticsEnabled())
return;
if (!EnableAnalytics())
return;
if (s_SentEnvironmentInitialized)
{
// We already sent an TrainingEnvironmentInitializedEvent. Exit so we don't resend.
return;
}
s_SentEnvironmentInitialized = true;
tbiEvent.TrainingSessionGuid = s_TrainingSessionGuid.ToString();
// Note - to debug, use JsonUtility.ToJson on the event.
// Debug.Log(
// $"Would send event {k_TrainingEnvironmentInitializedEventName} with body {JsonUtility.ToJson(tbiEvent, true)}"
// );
#if UNITY_EDITOR
if (AnalyticsUtils.s_SendEditorAnalytics)
{
EditorAnalytics.SendEventWithLimit(k_TrainingEnvironmentInitializedEventName, tbiEvent);
}
#else
return;
#endif
}
public static void RemotePolicyInitialized(
string fullyQualifiedBehaviorName,
IList<ISensor> sensors,
ActionSpec actionSpec
)
{
if (!IsAnalyticsEnabled())
return;
if (!EnableAnalytics())
return;
// Extract base behavior name (no team ID)
var behaviorName = ParseBehaviorName(fullyQualifiedBehaviorName);
var added = s_SentRemotePolicyInitialized.Add(behaviorName);
if (!added)
{
// We previously added this model. Exit so we don't resend.
return;
}
var data = GetEventForRemotePolicy(behaviorName, sensors, actionSpec);
// Note - to debug, use JsonUtility.ToJson on the event.
// Debug.Log(
// $"Would send event {k_RemotePolicyInitializedEventName} with body {JsonUtility.ToJson(data, true)}"
// );
#if UNITY_EDITOR
if (AnalyticsUtils.s_SendEditorAnalytics)
{
EditorAnalytics.SendEventWithLimit(k_RemotePolicyInitializedEventName, data);
}
#else
return;
#endif
}
internal static string ParseBehaviorName(string fullyQualifiedBehaviorName)
{
var lastQuestionIndex = fullyQualifiedBehaviorName.LastIndexOf("?");
if (lastQuestionIndex < 0)
{
// Nothing to remove
return fullyQualifiedBehaviorName;
}
return fullyQualifiedBehaviorName.Substring(0, lastQuestionIndex);
}
public static void TrainingBehaviorInitialized(TrainingBehaviorInitializedEvent tbiEvent)
{
if (!IsAnalyticsEnabled())
return;
if (!EnableAnalytics())
return;
var behaviorName = tbiEvent.BehaviorName;
var added = s_SentTrainingBehaviorInitialized.Add(behaviorName);
if (!added)
{
// We previously added this model. Exit so we don't resend.
return;
}
// Hash the behavior name so that there's no concern about PII or "secret" data being leaked.
tbiEvent.TrainingSessionGuid = s_TrainingSessionGuid.ToString();
tbiEvent.BehaviorName = AnalyticsUtils.Hash(tbiEvent.BehaviorName);
// Note - to debug, use JsonUtility.ToJson on the event.
// Debug.Log(
// $"Would send event {k_TrainingBehaviorInitializedEventName} with body {JsonUtility.ToJson(tbiEvent, true)}"
// );
#if UNITY_EDITOR
if (AnalyticsUtils.s_SendEditorAnalytics)
{
EditorAnalytics.SendEventWithLimit(k_TrainingBehaviorInitializedEventName, tbiEvent);
}
#else
return;
#endif
}
static RemotePolicyInitializedEvent GetEventForRemotePolicy(
string behaviorName,
IList<ISensor> sensors,
ActionSpec actionSpec)
{
var remotePolicyEvent = new RemotePolicyInitializedEvent();
// Hash the behavior name so that there's no concern about PII or "secret" data being leaked.
remotePolicyEvent.BehaviorName = AnalyticsUtils.Hash(behaviorName);
remotePolicyEvent.TrainingSessionGuid = s_TrainingSessionGuid.ToString();
remotePolicyEvent.ActionSpec = EventActionSpec.FromActionSpec(actionSpec);
remotePolicyEvent.ObservationSpecs = new List<EventObservationSpec>(sensors.Count);
foreach (var sensor in sensors)
{
remotePolicyEvent.ObservationSpecs.Add(EventObservationSpec.FromSensor(sensor));
}
remotePolicyEvent.MLAgentsEnvsVersion = s_TrainerPackageVersion;
remotePolicyEvent.TrainerCommunicationVersion = s_TrainerCommunicationVersion;
return remotePolicyEvent;
}
}
}

3
com.unity.ml-agents/Runtime/Analytics/TrainingAnalytics.cs.meta


fileFormatVersion: 2
guid: 5ad0bc6b45614bb7929d25dd59d5ac38
timeCreated: 1608168600

850
com.unity.ml-agents/Runtime/Grpc/CommunicatorObjects/TrainingAnalytics.cs


// <auto-generated>
// Generated by the protocol buffer compiler. DO NOT EDIT!
// source: mlagents_envs/communicator_objects/training_analytics.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021
#region Designer generated code
using pb = global::Google.Protobuf;
using pbc = global::Google.Protobuf.Collections;
using pbr = global::Google.Protobuf.Reflection;
using scg = global::System.Collections.Generic;
namespace Unity.MLAgents.CommunicatorObjects {
/// <summary>Holder for reflection information generated from mlagents_envs/communicator_objects/training_analytics.proto</summary>
internal static partial class TrainingAnalyticsReflection {
#region Descriptor
/// <summary>File descriptor for mlagents_envs/communicator_objects/training_analytics.proto</summary>
public static pbr::FileDescriptor Descriptor {
get { return descriptor; }
}
private static pbr::FileDescriptor descriptor;
static TrainingAnalyticsReflection() {
byte[] descriptorData = global::System.Convert.FromBase64String(
string.Concat(
"CjttbGFnZW50c19lbnZzL2NvbW11bmljYXRvcl9vYmplY3RzL3RyYWluaW5n",
"X2FuYWx5dGljcy5wcm90bxIUY29tbXVuaWNhdG9yX29iamVjdHMi2QEKHlRy",
"YWluaW5nRW52aXJvbm1lbnRJbml0aWFsaXplZBIYChBtbGFnZW50c192ZXJz",
"aW9uGAEgASgJEh0KFW1sYWdlbnRzX2VudnNfdmVyc2lvbhgCIAEoCRIWCg5w",
"eXRob25fdmVyc2lvbhgDIAEoCRIVCg10b3JjaF92ZXJzaW9uGAQgASgJEhkK",
"EXRvcmNoX2RldmljZV90eXBlGAUgASgJEhAKCG51bV9lbnZzGAYgASgFEiIK",
"Gm51bV9lbnZpcm9ubWVudF9wYXJhbWV0ZXJzGAcgASgFIq0DChtUcmFpbmlu",
"Z0JlaGF2aW9ySW5pdGlhbGl6ZWQSFQoNYmVoYXZpb3JfbmFtZRgBIAEoCRIU",
"Cgx0cmFpbmVyX3R5cGUYAiABKAkSIAoYZXh0cmluc2ljX3Jld2FyZF9lbmFi",
"bGVkGAMgASgIEhsKE2dhaWxfcmV3YXJkX2VuYWJsZWQYBCABKAgSIAoYY3Vy",
"aW9zaXR5X3Jld2FyZF9lbmFibGVkGAUgASgIEhoKEnJuZF9yZXdhcmRfZW5h",
"YmxlZBgGIAEoCBIiChpiZWhhdmlvcmFsX2Nsb25pbmdfZW5hYmxlZBgHIAEo",
"CBIZChFyZWN1cnJlbnRfZW5hYmxlZBgIIAEoCBIWCg52aXN1YWxfZW5jb2Rl",
"chgJIAEoCRIaChJudW1fbmV0d29ya19sYXllcnMYCiABKAUSIAoYbnVtX25l",
"dHdvcmtfaGlkZGVuX3VuaXRzGAsgASgFEhgKEHRyYWluZXJfdGhyZWFkZWQY",
"DCABKAgSGQoRc2VsZl9wbGF5X2VuYWJsZWQYDSABKAgSGgoSY3VycmljdWx1",
"bV9lbmFibGVkGA4gASgIQiWqAiJVbml0eS5NTEFnZW50cy5Db21tdW5pY2F0",
"b3JPYmplY3RzYgZwcm90bzM="));
descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
new pbr::FileDescriptor[] { },
new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] {
new pbr::GeneratedClrTypeInfo(typeof(global::Unity.MLAgents.CommunicatorObjects.TrainingEnvironmentInitialized), global::Unity.MLAgents.CommunicatorObjects.TrainingEnvironmentInitialized.Parser, new[]{ "MlagentsVersion", "MlagentsEnvsVersion", "PythonVersion", "TorchVersion", "TorchDeviceType", "NumEnvs", "NumEnvironmentParameters" }, null, null, null),
new pbr::GeneratedClrTypeInfo(typeof(global::Unity.MLAgents.CommunicatorObjects.TrainingBehaviorInitialized), global::Unity.MLAgents.CommunicatorObjects.TrainingBehaviorInitialized.Parser, new[]{ "BehaviorName", "TrainerType", "ExtrinsicRewardEnabled", "GailRewardEnabled", "CuriosityRewardEnabled", "RndRewardEnabled", "BehavioralCloningEnabled", "RecurrentEnabled", "VisualEncoder", "NumNetworkLayers", "NumNetworkHiddenUnits", "TrainerThreaded", "SelfPlayEnabled", "CurriculumEnabled" }, null, null, null)
}));
}
#endregion
}
#region Messages
internal sealed partial class TrainingEnvironmentInitialized : pb::IMessage<TrainingEnvironmentInitialized> {
private static readonly pb::MessageParser<TrainingEnvironmentInitialized> _parser = new pb::MessageParser<TrainingEnvironmentInitialized>(() => new TrainingEnvironmentInitialized());
private pb::UnknownFieldSet _unknownFields;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pb::MessageParser<TrainingEnvironmentInitialized> Parser { get { return _parser; } }
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public static pbr::MessageDescriptor Descriptor {
get { return global::Unity.MLAgents.CommunicatorObjects.TrainingAnalyticsReflection.Descriptor.MessageTypes[0]; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
pbr::MessageDescriptor pb::IMessage.Descriptor {
get { return Descriptor; }
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TrainingEnvironmentInitialized() {
OnConstruction();
}
partial void OnConstruction();
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TrainingEnvironmentInitialized(TrainingEnvironmentInitialized other) : this() {
mlagentsVersion_ = other.mlagentsVersion_;
mlagentsEnvsVersion_ = other.mlagentsEnvsVersion_;
pythonVersion_ = other.pythonVersion_;
torchVersion_ = other.torchVersion_;
torchDeviceType_ = other.torchDeviceType_;
numEnvs_ = other.numEnvs_;
numEnvironmentParameters_ = other.numEnvironmentParameters_;
_unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public TrainingEnvironmentInitialized Clone() {
return new TrainingEnvironmentInitialized(this);
}
/// <summary>Field number for the "mlagents_version" field.</summary>
public const int MlagentsVersionFieldNumber = 1;
private string mlagentsVersion_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string MlagentsVersion {
get { return mlagentsVersion_; }
set {
mlagentsVersion_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "mlagents_envs_version" field.</summary>
public const int MlagentsEnvsVersionFieldNumber = 2;
private string mlagentsEnvsVersion_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string MlagentsEnvsVersion {
get { return mlagentsEnvsVersion_; }
set {
mlagentsEnvsVersion_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "python_version" field.</summary>
public const int PythonVersionFieldNumber = 3;
private string pythonVersion_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string PythonVersion {
get { return pythonVersion_; }
set {
pythonVersion_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "torch_version" field.</summary>
public const int TorchVersionFieldNumber = 4;
private string torchVersion_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TorchVersion {
get { return torchVersion_; }
set {
torchVersion_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "torch_device_type" field.</summary>
public const int TorchDeviceTypeFieldNumber = 5;
private string torchDeviceType_ = "";
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public string TorchDeviceType {
get { return torchDeviceType_; }
set {
torchDeviceType_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
}
}
/// <summary>Field number for the "num_envs" field.</summary>
public const int NumEnvsFieldNumber = 6;
private int numEnvs_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int NumEnvs {
get { return numEnvs_; }
set {
numEnvs_ = value;
}
}
/// <summary>Field number for the "num_environment_parameters" field.</summary>
public const int NumEnvironmentParametersFieldNumber = 7;
private int numEnvironmentParameters_;
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public int NumEnvironmentParameters {
get { return numEnvironmentParameters_; }
set {
numEnvironmentParameters_ = value;
}
}
[global::System.Diagnostics.DebuggerNonUserCodeAttribute]
public override bool Equals(object other) {
return Equals(other as TrainingEnvironmentInitialized);
}