Initial commit (part 5)
Browse filesThis view is limited to 50 files because it contains too many changes. See raw diff
- com.unity.ml-agents.tests/.buginfo +5 -0
- com.unity.ml-agents.tests/Tests/Editor/AcademyTests.cs +50 -0
- com.unity.ml-agents.tests/Tests/Editor/AcademyTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSegmentTests.cs +62 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSegmentTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSpecTests.cs +37 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSpecTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorDiscreteActionMaskTests.cs +136 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorDiscreteActionMaskTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorManagerTests.cs +352 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorManagerTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/TestActuator.cs +48 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/TestActuator.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/VectorActuatorTests.cs +117 -0
- com.unity.ml-agents.tests/Tests/Editor/Actuators/VectorActuatorTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Analytics.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Analytics/InferenceAnalyticsTests.cs +105 -0
- com.unity.ml-agents.tests/Tests/Editor/Analytics/InferenceAnalyticsTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Analytics/TrainingAnalyticsTest.cs +96 -0
- com.unity.ml-agents.tests/Tests/Editor/Analytics/TrainingAnalyticsTest.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Areas.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Areas/TrainingAreaReplicatorTests.cs +83 -0
- com.unity.ml-agents.tests/Tests/Editor/Areas/TrainingAreaReplicatorTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/BehaviorParameterTests.cs +76 -0
- com.unity.ml-agents.tests/Tests/Editor/BehaviorParameterTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Communicator.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Communicator/GrpcExtensionsTests.cs +276 -0
- com.unity.ml-agents.tests/Tests/Editor/Communicator/GrpcExtensionsTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Communicator/RpcCommunicatorTests.cs +40 -0
- com.unity.ml-agents.tests/Tests/Editor/Communicator/RpcCommunicatorTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Communicator/UnityRLCapabilitiesTests.cs +22 -0
- com.unity.ml-agents.tests/Tests/Editor/Communicator/UnityRLCapabilitiesTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/DemonstrationTests.cs +150 -0
- com.unity.ml-agents.tests/Tests/Editor/DemonstrationTests.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/DiscreteActionOutputApplierTest.cs +83 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/DiscreteActionOutputApplierTest.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorApplier.cs +192 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorApplier.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorGenerator.cs +313 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorGenerator.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/ModelRunnerTest.cs +240 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/ModelRunnerTest.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/ParameterLoaderTest.cs +542 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/ParameterLoaderTest.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/TensorUtilsTest.cs +132 -0
- com.unity.ml-agents.tests/Tests/Editor/Inference/TensorUtilsTest.cs.meta +0 -0
- com.unity.ml-agents.tests/Tests/Editor/InplaceArrayTests.cs +190 -0
- com.unity.ml-agents.tests/Tests/Editor/InplaceArrayTests.cs.meta +0 -0
com.unity.ml-agents.tests/.buginfo
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
system: jira
|
| 2 |
+
server: jira.unity3d.com
|
| 3 |
+
issuetype: Bug
|
| 4 |
+
project: UUM
|
| 5 |
+
package: ML Agents
|
com.unity.ml-agents.tests/Tests/Editor/AcademyTests.cs
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using NUnit.Framework;
|
| 2 |
+
using Unity.MLAgents.Sensors;
|
| 3 |
+
using UnityEngine;
|
| 4 |
+
|
| 5 |
+
namespace Unity.MLAgents.Tests
|
| 6 |
+
{
|
| 7 |
+
[TestFixture]
|
| 8 |
+
public class AcademyTests
|
| 9 |
+
{
|
| 10 |
+
[Test]
|
| 11 |
+
public void TestPackageVersion()
|
| 12 |
+
{
|
| 13 |
+
var packageInfo = UnityEditor.PackageManager.PackageInfo.FindForAssembly(typeof(Agent).Assembly);
|
| 14 |
+
Assert.AreEqual("com.unity.ml-agents", packageInfo.name);
|
| 15 |
+
Assert.AreEqual(Academy.k_PackageVersion, packageInfo.version);
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
class RecursiveAgent : Agent
|
| 19 |
+
{
|
| 20 |
+
int m_collectObsCount;
|
| 21 |
+
public override void CollectObservations(VectorSensor sensor)
|
| 22 |
+
{
|
| 23 |
+
m_collectObsCount++;
|
| 24 |
+
if (m_collectObsCount == 1)
|
| 25 |
+
{
|
| 26 |
+
// NEVER DO THIS IN REAL CODE!
|
| 27 |
+
Academy.Instance.EnvironmentStep();
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
}
|
| 31 |
+
|
| 32 |
+
[Test]
|
| 33 |
+
public void TestRecursiveStepThrows()
|
| 34 |
+
{
|
| 35 |
+
var gameObj = new GameObject();
|
| 36 |
+
var agent = gameObj.AddComponent<RecursiveAgent>();
|
| 37 |
+
agent.Awake();
|
| 38 |
+
agent.LazyInitialize();
|
| 39 |
+
agent.RequestDecision();
|
| 40 |
+
|
| 41 |
+
Assert.Throws<UnityAgentsException>(() =>
|
| 42 |
+
{
|
| 43 |
+
Academy.Instance.EnvironmentStep();
|
| 44 |
+
});
|
| 45 |
+
|
| 46 |
+
// Make sure the Academy reset to a good state and is still steppable.
|
| 47 |
+
Academy.Instance.EnvironmentStep();
|
| 48 |
+
}
|
| 49 |
+
}
|
| 50 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/AcademyTests.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Actuators.meta
ADDED
|
Binary file (172 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSegmentTests.cs
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using NUnit.Framework;
|
| 3 |
+
using Unity.MLAgents.Actuators;
|
| 4 |
+
|
| 5 |
+
namespace Unity.MLAgents.Tests.Actuators
|
| 6 |
+
{
|
| 7 |
+
[TestFixture]
|
| 8 |
+
public class ActionSegmentTests
|
| 9 |
+
{
|
| 10 |
+
[Test]
|
| 11 |
+
public void TestConstruction()
|
| 12 |
+
{
|
| 13 |
+
var floatArray = new[] { 1f, 2f, 3f, 4f, 5f, 6f, 7f };
|
| 14 |
+
Assert.Throws<ArgumentOutOfRangeException>(
|
| 15 |
+
() => new ActionSegment<float>(floatArray, 100, 1));
|
| 16 |
+
|
| 17 |
+
var segment = new ActionSegment<float>(Array.Empty<float>(), 0, 0);
|
| 18 |
+
Assert.AreEqual(segment, ActionSegment<float>.Empty);
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
[Test]
|
| 22 |
+
public void TestIndexing()
|
| 23 |
+
{
|
| 24 |
+
var floatArray = new[] { 1f, 2f, 3f, 4f, 5f, 6f, 7f };
|
| 25 |
+
for (var i = 0; i < floatArray.Length; i++)
|
| 26 |
+
{
|
| 27 |
+
var start = 0 + i;
|
| 28 |
+
var length = floatArray.Length - i;
|
| 29 |
+
var actionSegment = new ActionSegment<float>(floatArray, start, length);
|
| 30 |
+
for (var j = 0; j < actionSegment.Length; j++)
|
| 31 |
+
{
|
| 32 |
+
Assert.AreEqual(actionSegment[j], floatArray[start + j]);
|
| 33 |
+
}
|
| 34 |
+
}
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
[Test]
|
| 38 |
+
public void TestEnumerator()
|
| 39 |
+
{
|
| 40 |
+
var floatArray = new[] { 1f, 2f, 3f, 4f, 5f, 6f, 7f };
|
| 41 |
+
for (var i = 0; i < floatArray.Length; i++)
|
| 42 |
+
{
|
| 43 |
+
var start = 0 + i;
|
| 44 |
+
var length = floatArray.Length - i;
|
| 45 |
+
var actionSegment = new ActionSegment<float>(floatArray, start, length);
|
| 46 |
+
var j = 0;
|
| 47 |
+
foreach (var item in actionSegment)
|
| 48 |
+
{
|
| 49 |
+
Assert.AreEqual(item, floatArray[start + j++]);
|
| 50 |
+
}
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
[Test]
|
| 55 |
+
public void TestNullConstructor()
|
| 56 |
+
{
|
| 57 |
+
var actionSegment = new ActionSegment<float>(null);
|
| 58 |
+
Assert.IsTrue(actionSegment.Length == 0);
|
| 59 |
+
Assert.IsTrue(actionSegment.Array == Array.Empty<float>());
|
| 60 |
+
}
|
| 61 |
+
}
|
| 62 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSegmentTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSpecTests.cs
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Collections.Generic;
|
| 2 |
+
using System.Linq;
|
| 3 |
+
using NUnit.Framework;
|
| 4 |
+
using Unity.MLAgents.Actuators;
|
| 5 |
+
|
| 6 |
+
namespace Unity.MLAgents.Tests.Actuators
|
| 7 |
+
{
|
| 8 |
+
[TestFixture]
|
| 9 |
+
public class ActionSpecTests
|
| 10 |
+
{
|
| 11 |
+
[Test]
|
| 12 |
+
public void ActionSpecCombineTest()
|
| 13 |
+
{
|
| 14 |
+
var as0 = new ActionSpec(3, new[] { 3, 2, 1 });
|
| 15 |
+
var as1 = new ActionSpec(1, new[] { 35, 122, 1, 3, 8, 3 });
|
| 16 |
+
|
| 17 |
+
var as0NumCon = 3;
|
| 18 |
+
var as0NumDis = as0.NumDiscreteActions;
|
| 19 |
+
var as1NumCon = 1;
|
| 20 |
+
var as1NumDis = as1.NumDiscreteActions;
|
| 21 |
+
var branchSizes = new List<int>();
|
| 22 |
+
branchSizes.AddRange(as0.BranchSizes);
|
| 23 |
+
branchSizes.AddRange(as1.BranchSizes);
|
| 24 |
+
|
| 25 |
+
var asc = ActionSpec.Combine(as0, as1);
|
| 26 |
+
|
| 27 |
+
Assert.AreEqual(as0NumCon + as1NumCon, asc.NumContinuousActions);
|
| 28 |
+
Assert.AreEqual(as0NumDis + as1NumDis, asc.NumDiscreteActions);
|
| 29 |
+
Assert.IsTrue(branchSizes.ToArray().SequenceEqual(asc.BranchSizes));
|
| 30 |
+
|
| 31 |
+
as0 = new ActionSpec(3);
|
| 32 |
+
as1 = new ActionSpec(1);
|
| 33 |
+
asc = ActionSpec.Combine(as0, as1);
|
| 34 |
+
Assert.IsEmpty(asc.BranchSizes);
|
| 35 |
+
}
|
| 36 |
+
}
|
| 37 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActionSpecTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorDiscreteActionMaskTests.cs
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Collections.Generic;
|
| 2 |
+
using NUnit.Framework;
|
| 3 |
+
using Unity.MLAgents.Actuators;
|
| 4 |
+
|
| 5 |
+
namespace Unity.MLAgents.Tests.Actuators
|
| 6 |
+
{
|
| 7 |
+
[TestFixture]
|
| 8 |
+
public class ActuatorDiscreteActionMaskTests
|
| 9 |
+
{
|
| 10 |
+
[Test]
|
| 11 |
+
public void Construction()
|
| 12 |
+
{
|
| 13 |
+
var masker = new ActuatorDiscreteActionMask(new List<IActuator>(), 0, 0);
|
| 14 |
+
Assert.IsNotNull(masker);
|
| 15 |
+
}
|
| 16 |
+
|
| 17 |
+
[Test]
|
| 18 |
+
public void NullMask()
|
| 19 |
+
{
|
| 20 |
+
var masker = new ActuatorDiscreteActionMask(new List<IActuator>(), 0, 0);
|
| 21 |
+
var mask = masker.GetMask();
|
| 22 |
+
Assert.IsNull(mask);
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
[Test]
|
| 26 |
+
public void FirstBranchMask()
|
| 27 |
+
{
|
| 28 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 4, 5, 6 }), "actuator1");
|
| 29 |
+
var masker = new ActuatorDiscreteActionMask(new IActuator[] { actuator1 }, 15, 3);
|
| 30 |
+
var mask = masker.GetMask();
|
| 31 |
+
Assert.IsNull(mask);
|
| 32 |
+
masker.SetActionEnabled(0, 1, false);
|
| 33 |
+
masker.SetActionEnabled(0, 2, false);
|
| 34 |
+
masker.SetActionEnabled(0, 3, false);
|
| 35 |
+
mask = masker.GetMask();
|
| 36 |
+
Assert.IsFalse(mask[0]);
|
| 37 |
+
Assert.IsTrue(mask[1]);
|
| 38 |
+
Assert.IsTrue(mask[2]);
|
| 39 |
+
Assert.IsTrue(mask[3]);
|
| 40 |
+
Assert.IsFalse(mask[4]);
|
| 41 |
+
Assert.AreEqual(mask.Length, 15);
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
[Test]
|
| 45 |
+
public void CanOverwriteMask()
|
| 46 |
+
{
|
| 47 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 4, 5, 6 }), "actuator1");
|
| 48 |
+
var masker = new ActuatorDiscreteActionMask(new IActuator[] { actuator1 }, 15, 3);
|
| 49 |
+
masker.SetActionEnabled(0, 1, false);
|
| 50 |
+
var mask = masker.GetMask();
|
| 51 |
+
Assert.IsTrue(mask[1]);
|
| 52 |
+
|
| 53 |
+
masker.SetActionEnabled(0, 1, true);
|
| 54 |
+
Assert.IsFalse(mask[1]);
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
[Test]
|
| 58 |
+
public void SecondBranchMask()
|
| 59 |
+
{
|
| 60 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 4, 5, 6 }), "actuator1");
|
| 61 |
+
var masker = new ActuatorDiscreteActionMask(new[] { actuator1 }, 15, 3);
|
| 62 |
+
masker.SetActionEnabled(1, 1, false);
|
| 63 |
+
masker.SetActionEnabled(1, 2, false);
|
| 64 |
+
masker.SetActionEnabled(1, 3, false);
|
| 65 |
+
var mask = masker.GetMask();
|
| 66 |
+
Assert.IsFalse(mask[0]);
|
| 67 |
+
Assert.IsFalse(mask[4]);
|
| 68 |
+
Assert.IsTrue(mask[5]);
|
| 69 |
+
Assert.IsTrue(mask[6]);
|
| 70 |
+
Assert.IsTrue(mask[7]);
|
| 71 |
+
Assert.IsFalse(mask[8]);
|
| 72 |
+
Assert.IsFalse(mask[9]);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
[Test]
|
| 76 |
+
public void MaskReset()
|
| 77 |
+
{
|
| 78 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 4, 5, 6 }), "actuator1");
|
| 79 |
+
var masker = new ActuatorDiscreteActionMask(new IActuator[] { actuator1 }, 15, 3);
|
| 80 |
+
masker.SetActionEnabled(1, 1, false);
|
| 81 |
+
masker.SetActionEnabled(1, 2, false);
|
| 82 |
+
masker.SetActionEnabled(1, 3, false);
|
| 83 |
+
masker.ResetMask();
|
| 84 |
+
var mask = masker.GetMask();
|
| 85 |
+
for (var i = 0; i < 15; i++)
|
| 86 |
+
{
|
| 87 |
+
Assert.IsFalse(mask[i]);
|
| 88 |
+
}
|
| 89 |
+
}
|
| 90 |
+
|
| 91 |
+
[Test]
|
| 92 |
+
public void ThrowsError()
|
| 93 |
+
{
|
| 94 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 4, 5, 6 }), "actuator1");
|
| 95 |
+
var masker = new ActuatorDiscreteActionMask(new IActuator[] { actuator1 }, 15, 3);
|
| 96 |
+
Assert.Catch<UnityAgentsException>(
|
| 97 |
+
() => masker.SetActionEnabled(0, 5, false));
|
| 98 |
+
Assert.Catch<UnityAgentsException>(
|
| 99 |
+
() => masker.SetActionEnabled(1, 5, false));
|
| 100 |
+
masker.SetActionEnabled(2, 5, false);
|
| 101 |
+
Assert.Catch<UnityAgentsException>(
|
| 102 |
+
() => masker.SetActionEnabled(3, 1, false));
|
| 103 |
+
masker.GetMask();
|
| 104 |
+
masker.ResetMask();
|
| 105 |
+
masker.SetActionEnabled(0, 0, false);
|
| 106 |
+
masker.SetActionEnabled(0, 1, false);
|
| 107 |
+
masker.SetActionEnabled(0, 2, false);
|
| 108 |
+
masker.SetActionEnabled(0, 3, false);
|
| 109 |
+
Assert.Catch<UnityAgentsException>(
|
| 110 |
+
() => masker.GetMask());
|
| 111 |
+
}
|
| 112 |
+
|
| 113 |
+
[Test]
|
| 114 |
+
public void MultipleMaskEdit()
|
| 115 |
+
{
|
| 116 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 4, 5, 6 }), "actuator1");
|
| 117 |
+
var masker = new ActuatorDiscreteActionMask(new IActuator[] { actuator1 }, 15, 3);
|
| 118 |
+
masker.SetActionEnabled(0, 0, false);
|
| 119 |
+
masker.SetActionEnabled(0, 1, false);
|
| 120 |
+
masker.SetActionEnabled(0, 3, false);
|
| 121 |
+
masker.SetActionEnabled(2, 1, false);
|
| 122 |
+
var mask = masker.GetMask();
|
| 123 |
+
for (var i = 0; i < 15; i++)
|
| 124 |
+
{
|
| 125 |
+
if ((i == 0) || (i == 1) || (i == 3) || (i == 10))
|
| 126 |
+
{
|
| 127 |
+
Assert.IsTrue(mask[i]);
|
| 128 |
+
}
|
| 129 |
+
else
|
| 130 |
+
{
|
| 131 |
+
Assert.IsFalse(mask[i]);
|
| 132 |
+
}
|
| 133 |
+
}
|
| 134 |
+
}
|
| 135 |
+
}
|
| 136 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorDiscreteActionMaskTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorManagerTests.cs
ADDED
|
@@ -0,0 +1,352 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using System.Collections.Generic;
|
| 3 |
+
using System.Globalization;
|
| 4 |
+
using System.Linq;
|
| 5 |
+
using NUnit.Framework;
|
| 6 |
+
using Unity.MLAgents.Actuators;
|
| 7 |
+
using UnityEngine;
|
| 8 |
+
using UnityEngine.TestTools;
|
| 9 |
+
using Assert = UnityEngine.Assertions.Assert;
|
| 10 |
+
|
| 11 |
+
namespace Unity.MLAgents.Tests.Actuators
|
| 12 |
+
{
|
| 13 |
+
[TestFixture]
|
| 14 |
+
public class ActuatorManagerTests
|
| 15 |
+
{
|
| 16 |
+
[Test]
|
| 17 |
+
public void TestEnsureBufferSizeContinuous()
|
| 18 |
+
{
|
| 19 |
+
var manager = new ActuatorManager();
|
| 20 |
+
var actuator1 = new TestActuator(ActionSpec.MakeContinuous(10), "actuator1");
|
| 21 |
+
var actuator2 = new TestActuator(ActionSpec.MakeContinuous(2), "actuator2");
|
| 22 |
+
manager.Add(actuator1);
|
| 23 |
+
manager.Add(actuator2);
|
| 24 |
+
var actuator1ActionSpaceDef = actuator1.ActionSpec;
|
| 25 |
+
var actuator2ActionSpaceDef = actuator2.ActionSpec;
|
| 26 |
+
manager.ReadyActuatorsForExecution(new[] { actuator1, actuator2 },
|
| 27 |
+
actuator1ActionSpaceDef.NumContinuousActions + actuator2ActionSpaceDef.NumContinuousActions,
|
| 28 |
+
actuator1ActionSpaceDef.SumOfDiscreteBranchSizes + actuator2ActionSpaceDef.SumOfDiscreteBranchSizes,
|
| 29 |
+
actuator1ActionSpaceDef.NumDiscreteActions + actuator2ActionSpaceDef.NumDiscreteActions);
|
| 30 |
+
|
| 31 |
+
manager.UpdateActions(new ActionBuffers(new[]
|
| 32 |
+
{ 0f, 1f, 2f, 3f, 4f, 5f, 6f, 7f, 8f, 9f, 10f, 11f }, Array.Empty<int>()));
|
| 33 |
+
|
| 34 |
+
Assert.IsTrue(12 == manager.NumContinuousActions);
|
| 35 |
+
Assert.IsTrue(0 == manager.NumDiscreteActions);
|
| 36 |
+
Assert.IsTrue(0 == manager.SumOfDiscreteBranchSizes);
|
| 37 |
+
Assert.IsTrue(12 == manager.StoredActions.ContinuousActions.Length);
|
| 38 |
+
Assert.IsTrue(0 == manager.StoredActions.DiscreteActions.Length);
|
| 39 |
+
}
|
| 40 |
+
|
| 41 |
+
[Test]
|
| 42 |
+
public void TestEnsureBufferDiscrete()
|
| 43 |
+
{
|
| 44 |
+
var manager = new ActuatorManager();
|
| 45 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3, 4 }), "actuator1");
|
| 46 |
+
var actuator2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 1, 1 }), "actuator2");
|
| 47 |
+
manager.Add(actuator1);
|
| 48 |
+
manager.Add(actuator2);
|
| 49 |
+
var actuator1ActionSpaceDef = actuator1.ActionSpec;
|
| 50 |
+
var actuator2ActionSpaceDef = actuator2.ActionSpec;
|
| 51 |
+
manager.ReadyActuatorsForExecution(new[] { actuator1, actuator2 },
|
| 52 |
+
actuator1ActionSpaceDef.NumContinuousActions + actuator2ActionSpaceDef.NumContinuousActions,
|
| 53 |
+
actuator1ActionSpaceDef.SumOfDiscreteBranchSizes + actuator2ActionSpaceDef.SumOfDiscreteBranchSizes,
|
| 54 |
+
actuator1ActionSpaceDef.NumDiscreteActions + actuator2ActionSpaceDef.NumDiscreteActions);
|
| 55 |
+
|
| 56 |
+
manager.UpdateActions(new ActionBuffers(Array.Empty<float>(),
|
| 57 |
+
new[] { 0, 1, 2, 3, 4, 5, 6 }));
|
| 58 |
+
|
| 59 |
+
Assert.IsTrue(0 == manager.NumContinuousActions);
|
| 60 |
+
Assert.IsTrue(7 == manager.NumDiscreteActions);
|
| 61 |
+
Assert.IsTrue(13 == manager.SumOfDiscreteBranchSizes);
|
| 62 |
+
Assert.IsTrue(0 == manager.StoredActions.ContinuousActions.Length);
|
| 63 |
+
Assert.IsTrue(7 == manager.StoredActions.DiscreteActions.Length);
|
| 64 |
+
}
|
| 65 |
+
|
| 66 |
+
[Test]
|
| 67 |
+
public void TestAllowMixedActions()
|
| 68 |
+
{
|
| 69 |
+
// Make sure discrete + continuous actuators are allowed.
|
| 70 |
+
var manager = new ActuatorManager();
|
| 71 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3, 4 }), "actuator1");
|
| 72 |
+
var actuator2 = new TestActuator(ActionSpec.MakeContinuous(3), "actuator2");
|
| 73 |
+
manager.Add(actuator1);
|
| 74 |
+
manager.Add(actuator2);
|
| 75 |
+
manager.ReadyActuatorsForExecution(new[] { actuator1, actuator2 }, 3, 10, 4);
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
[Test]
|
| 79 |
+
public void TestFailOnSameActuatorName()
|
| 80 |
+
{
|
| 81 |
+
var manager = new ActuatorManager();
|
| 82 |
+
var actuator1 = new TestActuator(ActionSpec.MakeContinuous(3), "actuator1");
|
| 83 |
+
var actuator2 = new TestActuator(ActionSpec.MakeContinuous(3), "actuator1");
|
| 84 |
+
manager.Add(actuator1);
|
| 85 |
+
manager.Add(actuator2);
|
| 86 |
+
manager.ReadyActuatorsForExecution(new[] { actuator1, actuator2 }, 3, 10, 4);
|
| 87 |
+
LogAssert.Expect(LogType.Assert, "Actuator names must be unique.");
|
| 88 |
+
}
|
| 89 |
+
|
| 90 |
+
[Test]
|
| 91 |
+
public void TestExecuteActionsDiscrete()
|
| 92 |
+
{
|
| 93 |
+
var manager = new ActuatorManager();
|
| 94 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3, 4 }), "actuator1");
|
| 95 |
+
var actuator2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 1, 1 }), "actuator2");
|
| 96 |
+
manager.Add(actuator1);
|
| 97 |
+
manager.Add(actuator2);
|
| 98 |
+
|
| 99 |
+
var discreteActionBuffer = new[] { 0, 1, 2, 3, 4, 5, 6 };
|
| 100 |
+
manager.UpdateActions(new ActionBuffers(Array.Empty<float>(),
|
| 101 |
+
discreteActionBuffer));
|
| 102 |
+
|
| 103 |
+
manager.ExecuteActions();
|
| 104 |
+
var actuator1Actions = actuator1.LastActionBuffer.DiscreteActions;
|
| 105 |
+
var actuator2Actions = actuator2.LastActionBuffer.DiscreteActions;
|
| 106 |
+
TestSegmentEquality(actuator1Actions, discreteActionBuffer); TestSegmentEquality(actuator2Actions, discreteActionBuffer);
|
| 107 |
+
}
|
| 108 |
+
|
| 109 |
+
[Test]
|
| 110 |
+
public void TestExecuteActionsContinuous()
|
| 111 |
+
{
|
| 112 |
+
var manager = new ActuatorManager();
|
| 113 |
+
var actuator1 = new TestActuator(ActionSpec.MakeContinuous(3),
|
| 114 |
+
"actuator1");
|
| 115 |
+
var actuator2 = new TestActuator(ActionSpec.MakeContinuous(3), "actuator2");
|
| 116 |
+
manager.Add(actuator1);
|
| 117 |
+
manager.Add(actuator2);
|
| 118 |
+
|
| 119 |
+
var continuousActionBuffer = new[] { 0f, 1f, 2f, 3f, 4f, 5f };
|
| 120 |
+
manager.UpdateActions(new ActionBuffers(continuousActionBuffer,
|
| 121 |
+
Array.Empty<int>()));
|
| 122 |
+
|
| 123 |
+
manager.ExecuteActions();
|
| 124 |
+
var actuator1Actions = actuator1.LastActionBuffer.ContinuousActions;
|
| 125 |
+
var actuator2Actions = actuator2.LastActionBuffer.ContinuousActions;
|
| 126 |
+
TestSegmentEquality(actuator1Actions, continuousActionBuffer);
|
| 127 |
+
TestSegmentEquality(actuator2Actions, continuousActionBuffer);
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
static void TestSegmentEquality<T>(ActionSegment<T> actionSegment, T[] actionBuffer)
|
| 131 |
+
where T : struct
|
| 132 |
+
{
|
| 133 |
+
Assert.IsFalse(actionSegment.Length == 0);
|
| 134 |
+
for (var i = 0; i < actionSegment.Length; i++)
|
| 135 |
+
{
|
| 136 |
+
var action = actionSegment[i];
|
| 137 |
+
Assert.AreEqual(action, actionBuffer[actionSegment.Offset + i]);
|
| 138 |
+
}
|
| 139 |
+
}
|
| 140 |
+
|
| 141 |
+
[Test]
|
| 142 |
+
public void TestUpdateActionsContinuous()
|
| 143 |
+
{
|
| 144 |
+
var manager = new ActuatorManager();
|
| 145 |
+
var actuator1 = new TestActuator(ActionSpec.MakeContinuous(3),
|
| 146 |
+
"actuator1");
|
| 147 |
+
var actuator2 = new TestActuator(ActionSpec.MakeContinuous(3), "actuator2");
|
| 148 |
+
manager.Add(actuator1);
|
| 149 |
+
manager.Add(actuator2);
|
| 150 |
+
var continuousActionBuffer = new[] { 0f, 1f, 2f, 3f, 4f, 5f };
|
| 151 |
+
manager.UpdateActions(new ActionBuffers(continuousActionBuffer,
|
| 152 |
+
Array.Empty<int>()));
|
| 153 |
+
|
| 154 |
+
Assert.IsTrue(manager.StoredActions.ContinuousActions.SequenceEqual(continuousActionBuffer));
|
| 155 |
+
}
|
| 156 |
+
|
| 157 |
+
[Test]
|
| 158 |
+
public void TestUpdateActionsDiscrete()
|
| 159 |
+
{
|
| 160 |
+
var manager = new ActuatorManager();
|
| 161 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }),
|
| 162 |
+
"actuator1");
|
| 163 |
+
var actuator2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }), "actuator2");
|
| 164 |
+
manager.Add(actuator1);
|
| 165 |
+
manager.Add(actuator2);
|
| 166 |
+
var discreteActionBuffer = new[] { 0, 1, 2, 3, 4, 5 };
|
| 167 |
+
manager.UpdateActions(new ActionBuffers(Array.Empty<float>(),
|
| 168 |
+
discreteActionBuffer));
|
| 169 |
+
|
| 170 |
+
Debug.Log(manager.StoredActions.DiscreteActions);
|
| 171 |
+
Debug.Log(discreteActionBuffer);
|
| 172 |
+
Assert.IsTrue(manager.StoredActions.DiscreteActions.SequenceEqual(discreteActionBuffer));
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
[Test]
|
| 176 |
+
public void TestRemove()
|
| 177 |
+
{
|
| 178 |
+
var manager = new ActuatorManager();
|
| 179 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }),
|
| 180 |
+
"actuator1");
|
| 181 |
+
var actuator2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }), "actuator2");
|
| 182 |
+
|
| 183 |
+
manager.Add(actuator1);
|
| 184 |
+
manager.Add(actuator2);
|
| 185 |
+
Assert.IsTrue(manager.NumDiscreteActions == 6);
|
| 186 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 12);
|
| 187 |
+
|
| 188 |
+
manager.Remove(actuator2);
|
| 189 |
+
|
| 190 |
+
Assert.IsTrue(manager.NumDiscreteActions == 3);
|
| 191 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 6);
|
| 192 |
+
|
| 193 |
+
manager.Remove(null);
|
| 194 |
+
|
| 195 |
+
Assert.IsTrue(manager.NumDiscreteActions == 3);
|
| 196 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 6);
|
| 197 |
+
|
| 198 |
+
manager.RemoveAt(0);
|
| 199 |
+
Assert.IsTrue(manager.NumDiscreteActions == 0);
|
| 200 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 0);
|
| 201 |
+
}
|
| 202 |
+
|
| 203 |
+
[Test]
|
| 204 |
+
public void TestClear()
|
| 205 |
+
{
|
| 206 |
+
var manager = new ActuatorManager();
|
| 207 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }),
|
| 208 |
+
"actuator1");
|
| 209 |
+
var actuator2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }), "actuator2");
|
| 210 |
+
manager.Add(actuator1);
|
| 211 |
+
manager.Add(actuator2);
|
| 212 |
+
|
| 213 |
+
Assert.IsTrue(manager.NumDiscreteActions == 6);
|
| 214 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 12);
|
| 215 |
+
|
| 216 |
+
manager.Clear();
|
| 217 |
+
|
| 218 |
+
Assert.IsTrue(manager.NumDiscreteActions == 0);
|
| 219 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 0);
|
| 220 |
+
}
|
| 221 |
+
|
| 222 |
+
[Test]
|
| 223 |
+
public void TestIndexSet()
|
| 224 |
+
{
|
| 225 |
+
var manager = new ActuatorManager();
|
| 226 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3, 4 }),
|
| 227 |
+
"actuator1");
|
| 228 |
+
var actuator2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }), "actuator2");
|
| 229 |
+
manager.Add(actuator1);
|
| 230 |
+
Assert.IsTrue(manager.NumDiscreteActions == 4);
|
| 231 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 10);
|
| 232 |
+
manager[0] = actuator2;
|
| 233 |
+
Assert.IsTrue(manager.NumDiscreteActions == 3);
|
| 234 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 6);
|
| 235 |
+
}
|
| 236 |
+
|
| 237 |
+
[Test]
|
| 238 |
+
public void TestInsert()
|
| 239 |
+
{
|
| 240 |
+
var manager = new ActuatorManager();
|
| 241 |
+
var actuator1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3, 4 }),
|
| 242 |
+
"actuator1");
|
| 243 |
+
var actuator2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }), "actuator2");
|
| 244 |
+
manager.Add(actuator1);
|
| 245 |
+
Assert.IsTrue(manager.NumDiscreteActions == 4);
|
| 246 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 10);
|
| 247 |
+
manager.Insert(0, actuator2);
|
| 248 |
+
Assert.IsTrue(manager.NumDiscreteActions == 7);
|
| 249 |
+
Assert.IsTrue(manager.SumOfDiscreteBranchSizes == 16);
|
| 250 |
+
Assert.IsTrue(manager.IndexOf(actuator2) == 0);
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
[Test]
|
| 254 |
+
public void TestResetData()
|
| 255 |
+
{
|
| 256 |
+
var manager = new ActuatorManager();
|
| 257 |
+
var actuator1 = new TestActuator(ActionSpec.MakeContinuous(3),
|
| 258 |
+
"actuator1");
|
| 259 |
+
var actuator2 = new TestActuator(ActionSpec.MakeContinuous(3), "actuator2");
|
| 260 |
+
manager.Add(actuator1);
|
| 261 |
+
manager.Add(actuator2);
|
| 262 |
+
var continuousActionBuffer = new[] { 0f, 1f, 2f, 3f, 4f, 5f };
|
| 263 |
+
manager.UpdateActions(new ActionBuffers(continuousActionBuffer,
|
| 264 |
+
Array.Empty<int>()));
|
| 265 |
+
|
| 266 |
+
Assert.IsTrue(manager.StoredActions.ContinuousActions.SequenceEqual(continuousActionBuffer));
|
| 267 |
+
Assert.IsTrue(manager.NumContinuousActions == 6);
|
| 268 |
+
manager.ResetData();
|
| 269 |
+
|
| 270 |
+
Assert.IsTrue(manager.StoredActions.ContinuousActions.SequenceEqual(new[] { 0f, 0f, 0f, 0f, 0f, 0f }));
|
| 271 |
+
}
|
| 272 |
+
|
| 273 |
+
[Test]
|
| 274 |
+
public void TestWriteDiscreteActionMask()
|
| 275 |
+
{
|
| 276 |
+
var manager = new ActuatorManager(2);
|
| 277 |
+
var va1 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 1, 2, 3 }), "name");
|
| 278 |
+
var va2 = new TestActuator(ActionSpec.MakeDiscrete(new[] { 3, 2, 1 }), "name1");
|
| 279 |
+
manager.Add(va1);
|
| 280 |
+
manager.Add(va2);
|
| 281 |
+
|
| 282 |
+
var groundTruthMask = new[]
|
| 283 |
+
{
|
| 284 |
+
false,
|
| 285 |
+
true, false,
|
| 286 |
+
false, true, true,
|
| 287 |
+
true, false, true,
|
| 288 |
+
false, true,
|
| 289 |
+
false
|
| 290 |
+
};
|
| 291 |
+
|
| 292 |
+
va1.Masks = new[]
|
| 293 |
+
{
|
| 294 |
+
Array.Empty<int>(),
|
| 295 |
+
new[] { 0 },
|
| 296 |
+
new[] { 1, 2 }
|
| 297 |
+
};
|
| 298 |
+
|
| 299 |
+
va2.Masks = new[]
|
| 300 |
+
{
|
| 301 |
+
new[] {0, 2},
|
| 302 |
+
new[] {1},
|
| 303 |
+
Array.Empty<int>()
|
| 304 |
+
};
|
| 305 |
+
manager.WriteActionMask();
|
| 306 |
+
Assert.IsTrue(groundTruthMask.SequenceEqual(manager.DiscreteActionMask.GetMask()));
|
| 307 |
+
}
|
| 308 |
+
|
| 309 |
+
[Test]
|
| 310 |
+
public void TestHeuristic()
|
| 311 |
+
{
|
| 312 |
+
var manager = new ActuatorManager(2);
|
| 313 |
+
var va1 = new TestActuator(ActionSpec.MakeDiscrete(1, 2, 3), "name");
|
| 314 |
+
var va2 = new TestActuator(ActionSpec.MakeDiscrete(3, 2, 1, 8), "name1");
|
| 315 |
+
manager.Add(va1);
|
| 316 |
+
manager.Add(va2);
|
| 317 |
+
|
| 318 |
+
var actionBuf = new ActionBuffers(Array.Empty<float>(), new[] { 0, 0, 0, 0, 0, 0, 0 });
|
| 319 |
+
manager.ApplyHeuristic(actionBuf);
|
| 320 |
+
|
| 321 |
+
Assert.IsTrue(va1.m_HeuristicCalled);
|
| 322 |
+
Assert.AreEqual(va1.m_DiscreteBufferSize, 3);
|
| 323 |
+
Assert.IsTrue(va2.m_HeuristicCalled);
|
| 324 |
+
Assert.AreEqual(va2.m_DiscreteBufferSize, 4);
|
| 325 |
+
}
|
| 326 |
+
|
| 327 |
+
/// <summary>
|
| 328 |
+
/// Test that sensors sort by name consistently across culture settings.
|
| 329 |
+
/// Example strings and cultures taken from
|
| 330 |
+
/// https://docs.microsoft.com/en-us/globalization/locale/sorting-and-string-comparison
|
| 331 |
+
/// </summary>
|
| 332 |
+
/// <param name="culture"></param>
|
| 333 |
+
[TestCase("da-DK")]
|
| 334 |
+
[TestCase("en-US")]
|
| 335 |
+
public void TestSortActuators(string culture)
|
| 336 |
+
{
|
| 337 |
+
List<IActuator> actuators = new List<IActuator>();
|
| 338 |
+
var actuator0 = new TestActuator(ActionSpec.MakeContinuous(2), "Apple");
|
| 339 |
+
var actuator1 = new TestActuator(ActionSpec.MakeContinuous(2), "Æble");
|
| 340 |
+
actuators.Add(actuator0);
|
| 341 |
+
actuators.Add(actuator1);
|
| 342 |
+
|
| 343 |
+
var originalCulture = CultureInfo.CurrentCulture;
|
| 344 |
+
CultureInfo.CurrentCulture = new CultureInfo(culture);
|
| 345 |
+
ActuatorManager.SortActuators(actuators);
|
| 346 |
+
CultureInfo.CurrentCulture = originalCulture;
|
| 347 |
+
|
| 348 |
+
Assert.AreEqual(actuator1, actuators[0]);
|
| 349 |
+
Assert.AreEqual(actuator0, actuators[1]);
|
| 350 |
+
}
|
| 351 |
+
}
|
| 352 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/ActuatorManagerTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/TestActuator.cs
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using Unity.MLAgents.Actuators;
|
| 2 |
+
namespace Unity.MLAgents.Tests.Actuators
|
| 3 |
+
{
|
| 4 |
+
internal class TestActuator : IActuator
|
| 5 |
+
{
|
| 6 |
+
public ActionBuffers LastActionBuffer;
|
| 7 |
+
public int[][] Masks;
|
| 8 |
+
public bool m_HeuristicCalled;
|
| 9 |
+
public int m_DiscreteBufferSize;
|
| 10 |
+
|
| 11 |
+
public TestActuator(ActionSpec actuatorSpace, string name)
|
| 12 |
+
{
|
| 13 |
+
ActionSpec = actuatorSpace;
|
| 14 |
+
|
| 15 |
+
Name = name;
|
| 16 |
+
}
|
| 17 |
+
|
| 18 |
+
public void OnActionReceived(ActionBuffers actionBuffers)
|
| 19 |
+
{
|
| 20 |
+
LastActionBuffer = actionBuffers;
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
public void WriteDiscreteActionMask(IDiscreteActionMask actionMask)
|
| 24 |
+
{
|
| 25 |
+
for (var i = 0; i < Masks.Length; i++)
|
| 26 |
+
{
|
| 27 |
+
foreach (var actionIndex in Masks[i])
|
| 28 |
+
{
|
| 29 |
+
actionMask.SetActionEnabled(i, actionIndex, false);
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
public ActionSpec ActionSpec { get; }
|
| 35 |
+
|
| 36 |
+
public string Name { get; }
|
| 37 |
+
|
| 38 |
+
public void ResetData()
|
| 39 |
+
{
|
| 40 |
+
}
|
| 41 |
+
|
| 42 |
+
public void Heuristic(in ActionBuffers actionBuffersOut)
|
| 43 |
+
{
|
| 44 |
+
m_HeuristicCalled = true;
|
| 45 |
+
m_DiscreteBufferSize = actionBuffersOut.DiscreteActions.Length;
|
| 46 |
+
}
|
| 47 |
+
}
|
| 48 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/TestActuator.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/VectorActuatorTests.cs
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using System.Collections.Generic;
|
| 3 |
+
using System.Linq;
|
| 4 |
+
using NUnit.Framework;
|
| 5 |
+
using Unity.MLAgents.Actuators;
|
| 6 |
+
using Assert = UnityEngine.Assertions.Assert;
|
| 7 |
+
|
| 8 |
+
namespace Unity.MLAgents.Tests.Actuators
|
| 9 |
+
{
|
| 10 |
+
[TestFixture]
|
| 11 |
+
public class VectorActuatorTests
|
| 12 |
+
{
|
| 13 |
+
class TestActionReceiver : IActionReceiver, IHeuristicProvider
|
| 14 |
+
{
|
| 15 |
+
public ActionBuffers LastActionBuffers;
|
| 16 |
+
public int Branch;
|
| 17 |
+
public IList<int> Mask;
|
| 18 |
+
public ActionSpec ActionSpec { get; }
|
| 19 |
+
public bool HeuristicCalled;
|
| 20 |
+
|
| 21 |
+
public void OnActionReceived(ActionBuffers actionBuffers)
|
| 22 |
+
{
|
| 23 |
+
LastActionBuffers = actionBuffers;
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
public void WriteDiscreteActionMask(IDiscreteActionMask actionMask)
|
| 27 |
+
{
|
| 28 |
+
foreach (var actionIndex in Mask)
|
| 29 |
+
{
|
| 30 |
+
actionMask.SetActionEnabled(Branch, actionIndex, false);
|
| 31 |
+
}
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
public void Heuristic(in ActionBuffers actionBuffersOut)
|
| 35 |
+
{
|
| 36 |
+
HeuristicCalled = true;
|
| 37 |
+
}
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
[Test]
|
| 41 |
+
public void TestConstruct()
|
| 42 |
+
{
|
| 43 |
+
var ar = new TestActionReceiver();
|
| 44 |
+
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(1, 2, 3), "name");
|
| 45 |
+
|
| 46 |
+
Assert.IsTrue(va.ActionSpec.NumDiscreteActions == 3);
|
| 47 |
+
Assert.IsTrue(va.ActionSpec.SumOfDiscreteBranchSizes == 6);
|
| 48 |
+
Assert.IsTrue(va.ActionSpec.NumContinuousActions == 0);
|
| 49 |
+
|
| 50 |
+
var va1 = new VectorActuator(ar, ActionSpec.MakeContinuous(4), "name");
|
| 51 |
+
|
| 52 |
+
Assert.IsTrue(va1.ActionSpec.NumContinuousActions == 4);
|
| 53 |
+
Assert.IsTrue(va1.ActionSpec.SumOfDiscreteBranchSizes == 0);
|
| 54 |
+
Assert.AreEqual(va1.Name, "name-Continuous");
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
[Test]
|
| 58 |
+
public void TestOnActionReceived()
|
| 59 |
+
{
|
| 60 |
+
var ar = new TestActionReceiver();
|
| 61 |
+
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(1, 2, 3), "name");
|
| 62 |
+
|
| 63 |
+
var discreteActions = new[] { 0, 1, 1 };
|
| 64 |
+
var ab = new ActionBuffers(ActionSegment<float>.Empty,
|
| 65 |
+
new ActionSegment<int>(discreteActions, 0, 3));
|
| 66 |
+
|
| 67 |
+
va.OnActionReceived(ab);
|
| 68 |
+
|
| 69 |
+
Assert.AreEqual(ar.LastActionBuffers, ab);
|
| 70 |
+
va.ResetData();
|
| 71 |
+
Assert.AreEqual(va.ActionBuffers.ContinuousActions, ActionSegment<float>.Empty);
|
| 72 |
+
Assert.AreEqual(va.ActionBuffers.DiscreteActions, ActionSegment<int>.Empty);
|
| 73 |
+
}
|
| 74 |
+
|
| 75 |
+
[Test]
|
| 76 |
+
public void TestResetData()
|
| 77 |
+
{
|
| 78 |
+
var ar = new TestActionReceiver();
|
| 79 |
+
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(1, 2, 3), "name");
|
| 80 |
+
|
| 81 |
+
var discreteActions = new[] { 0, 1, 1 };
|
| 82 |
+
var ab = new ActionBuffers(ActionSegment<float>.Empty,
|
| 83 |
+
new ActionSegment<int>(discreteActions, 0, 3));
|
| 84 |
+
|
| 85 |
+
va.OnActionReceived(ab);
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
[Test]
|
| 89 |
+
public void TestWriteDiscreteActionMask()
|
| 90 |
+
{
|
| 91 |
+
var ar = new TestActionReceiver();
|
| 92 |
+
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(1, 2, 3), "name");
|
| 93 |
+
var bdam = new ActuatorDiscreteActionMask(new[] { va }, 6, 3);
|
| 94 |
+
|
| 95 |
+
var groundTruthMask = new[] { false, true, false, false, true, true };
|
| 96 |
+
|
| 97 |
+
ar.Branch = 1;
|
| 98 |
+
ar.Mask = new[] { 0 };
|
| 99 |
+
va.WriteDiscreteActionMask(bdam);
|
| 100 |
+
ar.Branch = 2;
|
| 101 |
+
ar.Mask = new[] { 1, 2 };
|
| 102 |
+
va.WriteDiscreteActionMask(bdam);
|
| 103 |
+
|
| 104 |
+
Assert.IsTrue(groundTruthMask.SequenceEqual(bdam.GetMask()));
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
[Test]
|
| 108 |
+
public void TestHeuristic()
|
| 109 |
+
{
|
| 110 |
+
var ar = new TestActionReceiver();
|
| 111 |
+
var va = new VectorActuator(ar, ActionSpec.MakeDiscrete(1, 2, 3), "name");
|
| 112 |
+
|
| 113 |
+
va.Heuristic(new ActionBuffers(Array.Empty<float>(), va.ActionSpec.BranchSizes));
|
| 114 |
+
Assert.IsTrue(ar.HeuristicCalled);
|
| 115 |
+
}
|
| 116 |
+
}
|
| 117 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Actuators/VectorActuatorTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Analytics.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Analytics/InferenceAnalyticsTests.cs
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using System.Collections.Generic;
|
| 3 |
+
using NUnit.Framework;
|
| 4 |
+
using Unity.MLAgents.Sensors;
|
| 5 |
+
using UnityEngine;
|
| 6 |
+
using Unity.InferenceEngine;
|
| 7 |
+
using Unity.MLAgents.Actuators;
|
| 8 |
+
using Unity.MLAgents.Policies;
|
| 9 |
+
using Unity.MLAgents.Analytics;
|
| 10 |
+
using UnityEditor;
|
| 11 |
+
|
| 12 |
+
|
| 13 |
+
namespace Unity.MLAgents.Tests.Analytics
|
| 14 |
+
{
|
| 15 |
+
[TestFixture]
|
| 16 |
+
public class InferenceAnalyticsTests
|
| 17 |
+
{
|
| 18 |
+
const string k_continuousONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/continuous2vis8vec2action_v1_0.onnx";
|
| 19 |
+
ModelAsset continuousONNXModel;
|
| 20 |
+
Test3DSensorComponent sensor_21_20_3;
|
| 21 |
+
Test3DSensorComponent sensor_20_22_3;
|
| 22 |
+
|
| 23 |
+
ActionSpec GetContinuous2vis8vec2actionActionSpec()
|
| 24 |
+
{
|
| 25 |
+
return ActionSpec.MakeContinuous(2);
|
| 26 |
+
}
|
| 27 |
+
|
| 28 |
+
[SetUp]
|
| 29 |
+
public void SetUp()
|
| 30 |
+
{
|
| 31 |
+
if (Academy.IsInitialized)
|
| 32 |
+
{
|
| 33 |
+
Academy.Instance.Dispose();
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
continuousONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_continuousONNXPath, typeof(ModelAsset));
|
| 37 |
+
var go = new GameObject("SensorA");
|
| 38 |
+
sensor_21_20_3 = go.AddComponent<Test3DSensorComponent>();
|
| 39 |
+
sensor_21_20_3.Sensor = new Test3DSensor("SensorA", 21, 20, 3);
|
| 40 |
+
sensor_20_22_3 = go.AddComponent<Test3DSensorComponent>();
|
| 41 |
+
sensor_20_22_3.Sensor = new Test3DSensor("SensorB", 20, 22, 3);
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
[Test]
|
| 45 |
+
public void TestModelEvent()
|
| 46 |
+
{
|
| 47 |
+
var sensors = new List<ISensor> { sensor_21_20_3.Sensor, sensor_20_22_3.Sensor };
|
| 48 |
+
var behaviorName = "continuousModel";
|
| 49 |
+
var actionSpec = GetContinuous2vis8vec2actionActionSpec();
|
| 50 |
+
|
| 51 |
+
var vectorActuator = new VectorActuator(null, actionSpec, "test'");
|
| 52 |
+
var actuators = new IActuator[] { vectorActuator };
|
| 53 |
+
|
| 54 |
+
var continuousEvent = InferenceAnalytics.GetEventForModel(
|
| 55 |
+
continuousONNXModel, behaviorName,
|
| 56 |
+
InferenceDevice.Burst, sensors, actionSpec,
|
| 57 |
+
actuators
|
| 58 |
+
);
|
| 59 |
+
|
| 60 |
+
// The behavior name should be hashed, not pass-through.
|
| 61 |
+
Assert.AreNotEqual(behaviorName, continuousEvent.BehaviorName);
|
| 62 |
+
|
| 63 |
+
Assert.AreEqual(2, continuousEvent.ActionSpec.NumContinuousActions);
|
| 64 |
+
Assert.AreEqual(0, continuousEvent.ActionSpec.NumDiscreteActions);
|
| 65 |
+
Assert.AreEqual(2, continuousEvent.ObservationSpecs.Count);
|
| 66 |
+
Assert.AreEqual(3, continuousEvent.ObservationSpecs[0].DimensionInfos.Length);
|
| 67 |
+
Assert.AreEqual(20, continuousEvent.ObservationSpecs[0].DimensionInfos[1].Size);
|
| 68 |
+
Assert.AreEqual(0, continuousEvent.ObservationSpecs[0].ObservationType);
|
| 69 |
+
Assert.AreEqual((int)DimensionProperty.TranslationalEquivariance, continuousEvent.ObservationSpecs[0].DimensionInfos[1].Flags);
|
| 70 |
+
Assert.AreEqual((int)DimensionProperty.None, continuousEvent.ObservationSpecs[0].DimensionInfos[0].Flags);
|
| 71 |
+
Assert.AreEqual("None", continuousEvent.ObservationSpecs[0].CompressionType);
|
| 72 |
+
Assert.AreEqual(Test3DSensor.k_BuiltInSensorType, continuousEvent.ObservationSpecs[0].BuiltInSensorType);
|
| 73 |
+
Assert.AreEqual((int)BuiltInActuatorType.VectorActuator, continuousEvent.ActuatorInfos[0].BuiltInActuatorType);
|
| 74 |
+
Assert.AreNotEqual(null, continuousEvent.ModelHash);
|
| 75 |
+
|
| 76 |
+
// Make sure nested fields get serialized
|
| 77 |
+
var jsonString = JsonUtility.ToJson(continuousEvent, true);
|
| 78 |
+
Assert.IsTrue(jsonString.Contains("ObservationSpecs"));
|
| 79 |
+
Assert.IsTrue(jsonString.Contains("ActionSpec"));
|
| 80 |
+
Assert.IsTrue(jsonString.Contains("NumDiscreteActions"));
|
| 81 |
+
Assert.IsTrue(jsonString.Contains("SensorName"));
|
| 82 |
+
Assert.IsTrue(jsonString.Contains("Flags"));
|
| 83 |
+
Assert.IsTrue(jsonString.Contains("ActuatorInfos"));
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
[Test]
|
| 87 |
+
public void TestSentisPolicy()
|
| 88 |
+
{
|
| 89 |
+
// Explicitly request decisions for a policy so we get code coverage on the event sending
|
| 90 |
+
using (new AnalyticsUtils.DisableAnalyticsSending())
|
| 91 |
+
{
|
| 92 |
+
var sensors = new List<ISensor> { sensor_21_20_3.Sensor, sensor_20_22_3.Sensor };
|
| 93 |
+
var policy = new SentisPolicy(
|
| 94 |
+
GetContinuous2vis8vec2actionActionSpec(),
|
| 95 |
+
Array.Empty<IActuator>(),
|
| 96 |
+
continuousONNXModel,
|
| 97 |
+
InferenceDevice.Burst,
|
| 98 |
+
"testBehavior"
|
| 99 |
+
);
|
| 100 |
+
policy.RequestDecision(new AgentInfo(), sensors);
|
| 101 |
+
}
|
| 102 |
+
Academy.Instance.Dispose();
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Analytics/InferenceAnalyticsTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Analytics/TrainingAnalyticsTest.cs
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using System.Collections.Generic;
|
| 3 |
+
using NUnit.Framework;
|
| 4 |
+
using Unity.MLAgents.Sensors;
|
| 5 |
+
using Unity.MLAgents.Actuators;
|
| 6 |
+
using Unity.MLAgents.Analytics;
|
| 7 |
+
using Unity.MLAgents.Policies;
|
| 8 |
+
using UnityEditor;
|
| 9 |
+
|
| 10 |
+
namespace Unity.MLAgents.Tests.Analytics
|
| 11 |
+
{
|
| 12 |
+
[TestFixture]
|
| 13 |
+
public class TrainingAnalyticsTests
|
| 14 |
+
{
|
| 15 |
+
[TestCase("foo?team=42", ExpectedResult = "foo")]
|
| 16 |
+
[TestCase("foo", ExpectedResult = "foo")]
|
| 17 |
+
[TestCase("foo?bar?team=1337", ExpectedResult = "foo?bar")]
|
| 18 |
+
public string TestParseBehaviorName(string fullyQualifiedBehaviorName)
|
| 19 |
+
{
|
| 20 |
+
return TrainingAnalytics.ParseBehaviorName(fullyQualifiedBehaviorName);
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
[Test]
|
| 24 |
+
public void TestRemotePolicyEvent()
|
| 25 |
+
{
|
| 26 |
+
var behaviorName = "testBehavior";
|
| 27 |
+
var sensor1 = new Test3DSensor("SensorA", 21, 20, 3);
|
| 28 |
+
var sensor2 = new Test3DSensor("SensorB", 20, 22, 3);
|
| 29 |
+
var sensors = new List<ISensor> { sensor1, sensor2 };
|
| 30 |
+
|
| 31 |
+
var actionSpec = ActionSpec.MakeContinuous(2);
|
| 32 |
+
|
| 33 |
+
var vectorActuator = new VectorActuator(null, actionSpec, "test'");
|
| 34 |
+
var actuators = new IActuator[] { vectorActuator };
|
| 35 |
+
|
| 36 |
+
var remotePolicyEvent = TrainingAnalytics.GetEventForRemotePolicy(behaviorName, sensors, actionSpec, actuators);
|
| 37 |
+
|
| 38 |
+
// The behavior name should be hashed, not pass-through.
|
| 39 |
+
Assert.AreNotEqual(behaviorName, remotePolicyEvent.BehaviorName);
|
| 40 |
+
|
| 41 |
+
Assert.AreEqual(2, remotePolicyEvent.ObservationSpecs.Count);
|
| 42 |
+
Assert.AreEqual(3, remotePolicyEvent.ObservationSpecs[0].DimensionInfos.Length);
|
| 43 |
+
Assert.AreEqual(20, remotePolicyEvent.ObservationSpecs[0].DimensionInfos[1].Size);
|
| 44 |
+
Assert.AreEqual(0, remotePolicyEvent.ObservationSpecs[0].ObservationType);
|
| 45 |
+
Assert.AreEqual("None", remotePolicyEvent.ObservationSpecs[0].CompressionType);
|
| 46 |
+
Assert.AreEqual(Test3DSensor.k_BuiltInSensorType, remotePolicyEvent.ObservationSpecs[0].BuiltInSensorType);
|
| 47 |
+
|
| 48 |
+
Assert.AreEqual(2, remotePolicyEvent.ActionSpec.NumContinuousActions);
|
| 49 |
+
Assert.AreEqual(0, remotePolicyEvent.ActionSpec.NumDiscreteActions);
|
| 50 |
+
|
| 51 |
+
Assert.AreEqual(2, remotePolicyEvent.ActuatorInfos[0].NumContinuousActions);
|
| 52 |
+
Assert.AreEqual(0, remotePolicyEvent.ActuatorInfos[0].NumDiscreteActions);
|
| 53 |
+
}
|
| 54 |
+
|
| 55 |
+
[Test]
|
| 56 |
+
public void TestRemotePolicy()
|
| 57 |
+
{
|
| 58 |
+
if (Academy.IsInitialized)
|
| 59 |
+
{
|
| 60 |
+
Academy.Instance.Dispose();
|
| 61 |
+
}
|
| 62 |
+
|
| 63 |
+
using (new AnalyticsUtils.DisableAnalyticsSending())
|
| 64 |
+
{
|
| 65 |
+
var actionSpec = ActionSpec.MakeContinuous(3);
|
| 66 |
+
var policy = new RemotePolicy(actionSpec, Array.Empty<IActuator>(), "TestBehavior?team=42");
|
| 67 |
+
policy.RequestDecision(new AgentInfo(), new List<ISensor>());
|
| 68 |
+
}
|
| 69 |
+
|
| 70 |
+
Academy.Instance.Dispose();
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
[TestCase("a name we expect to hash", ExpectedResult = "d084a8b6da6a6a1c097cdc9ffea95e1546da4647352113ed77cbe7b4192e6d73")]
|
| 74 |
+
[TestCase("another_name", ExpectedResult = "0b74613c872e79aba11e06eda3538f2b646eb2b459e75087829ea500bd703d0b")]
|
| 75 |
+
[TestCase("0b74613c872e79aba11e06eda3538f2b646eb2b459e75087829ea500bd703d0b", ExpectedResult = "0b74613c872e79aba11e06eda3538f2b646eb2b459e75087829ea500bd703d0b")]
|
| 76 |
+
public string TestTrainingBehaviorInitialized(string stringToMaybeHash)
|
| 77 |
+
{
|
| 78 |
+
var tbiEvent = new TrainingBehaviorInitializedEvent();
|
| 79 |
+
tbiEvent.BehaviorName = stringToMaybeHash;
|
| 80 |
+
tbiEvent.Config = "{}";
|
| 81 |
+
|
| 82 |
+
var sanitizedEvent = TrainingAnalytics.SanitizeTrainingBehaviorInitializedEvent(tbiEvent);
|
| 83 |
+
return sanitizedEvent.BehaviorName;
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
[Test]
|
| 87 |
+
public void TestEnableAnalytics()
|
| 88 |
+
{
|
| 89 |
+
#if UNITY_EDITOR && MLA_UNITY_ANALYTICS_MODULE && ENABLE_CLOUD_SERVICES_ANALYTICS
|
| 90 |
+
Assert.IsTrue(TrainingAnalytics.EnableAnalytics());
|
| 91 |
+
#else
|
| 92 |
+
Assert.IsFalse(TrainingAnalytics.EnableAnalytics());
|
| 93 |
+
#endif
|
| 94 |
+
}
|
| 95 |
+
}
|
| 96 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Analytics/TrainingAnalyticsTest.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Areas.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Areas/TrainingAreaReplicatorTests.cs
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Linq;
|
| 2 |
+
using NUnit.Framework;
|
| 3 |
+
using Unity.Mathematics;
|
| 4 |
+
using Unity.MLAgents.Areas;
|
| 5 |
+
using UnityEngine;
|
| 6 |
+
|
| 7 |
+
namespace Unity.MLAgents.Tests.Areas
|
| 8 |
+
{
|
| 9 |
+
[TestFixture]
|
| 10 |
+
public class TrainingAreaReplicatorTests
|
| 11 |
+
{
|
| 12 |
+
TrainingAreaReplicator m_Replicator;
|
| 13 |
+
|
| 14 |
+
[SetUp]
|
| 15 |
+
public void Setup()
|
| 16 |
+
{
|
| 17 |
+
var gameObject = new GameObject();
|
| 18 |
+
var trainingArea = new GameObject();
|
| 19 |
+
trainingArea.name = "MyTrainingArea";
|
| 20 |
+
m_Replicator = gameObject.AddComponent<TrainingAreaReplicator>();
|
| 21 |
+
m_Replicator.baseArea = trainingArea;
|
| 22 |
+
}
|
| 23 |
+
|
| 24 |
+
[TearDown]
|
| 25 |
+
public void TearDown()
|
| 26 |
+
{
|
| 27 |
+
var trainingAreas = Resources.FindObjectsOfTypeAll<GameObject>().Where(obj => obj.name == m_Replicator.TrainingAreaName);
|
| 28 |
+
foreach (var trainingArea in trainingAreas)
|
| 29 |
+
{
|
| 30 |
+
Object.DestroyImmediate(trainingArea);
|
| 31 |
+
}
|
| 32 |
+
m_Replicator = null;
|
| 33 |
+
}
|
| 34 |
+
|
| 35 |
+
private static object[] NumAreasCases =
|
| 36 |
+
{
|
| 37 |
+
new object[] {1},
|
| 38 |
+
new object[] {2},
|
| 39 |
+
new object[] {5},
|
| 40 |
+
new object[] {7},
|
| 41 |
+
new object[] {8},
|
| 42 |
+
new object[] {64},
|
| 43 |
+
new object[] {63},
|
| 44 |
+
};
|
| 45 |
+
|
| 46 |
+
[TestCaseSource(nameof(NumAreasCases))]
|
| 47 |
+
public void TestComputeGridSize(int numAreas)
|
| 48 |
+
{
|
| 49 |
+
m_Replicator.numAreas = numAreas;
|
| 50 |
+
m_Replicator.Awake();
|
| 51 |
+
m_Replicator.OnEnable();
|
| 52 |
+
var m_CorrectGridSize = int3.zero;
|
| 53 |
+
var m_RootNumAreas = Mathf.Pow(numAreas, 1.0f / 3.0f);
|
| 54 |
+
m_CorrectGridSize.x = Mathf.CeilToInt(m_RootNumAreas);
|
| 55 |
+
m_CorrectGridSize.y = Mathf.CeilToInt(m_RootNumAreas);
|
| 56 |
+
m_CorrectGridSize.z = Mathf.CeilToInt((float)numAreas / (m_CorrectGridSize.x * m_CorrectGridSize.y));
|
| 57 |
+
Assert.GreaterOrEqual(m_Replicator.GridSize.x * m_Replicator.GridSize.y * m_Replicator.GridSize.z, m_Replicator.numAreas);
|
| 58 |
+
Assert.AreEqual(m_CorrectGridSize, m_Replicator.GridSize);
|
| 59 |
+
}
|
| 60 |
+
|
| 61 |
+
[Test]
|
| 62 |
+
public void TestAddEnvironments()
|
| 63 |
+
{
|
| 64 |
+
m_Replicator.numAreas = 10;
|
| 65 |
+
m_Replicator.buildOnly = false;
|
| 66 |
+
m_Replicator.Awake();
|
| 67 |
+
m_Replicator.OnEnable();
|
| 68 |
+
var trainingAreas = Resources.FindObjectsOfTypeAll<GameObject>().Where(obj => obj.name == m_Replicator.TrainingAreaName);
|
| 69 |
+
Assert.AreEqual(10, trainingAreas.Count());
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
[Test]
|
| 73 |
+
public void TestAddEnvironmentsBuildOnly()
|
| 74 |
+
{
|
| 75 |
+
m_Replicator.numAreas = 10;
|
| 76 |
+
m_Replicator.buildOnly = true;
|
| 77 |
+
m_Replicator.Awake();
|
| 78 |
+
m_Replicator.OnEnable();
|
| 79 |
+
var trainingAreas = Resources.FindObjectsOfTypeAll<GameObject>().Where(obj => obj.name == m_Replicator.TrainingAreaName);
|
| 80 |
+
Assert.AreEqual(1, trainingAreas.Count());
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Areas/TrainingAreaReplicatorTests.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/BehaviorParameterTests.cs
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using NUnit.Framework;
|
| 2 |
+
using Unity.InferenceEngine;
|
| 3 |
+
using Unity.MLAgents.Actuators;
|
| 4 |
+
using UnityEngine;
|
| 5 |
+
using Unity.MLAgents.Policies;
|
| 6 |
+
using UnityEditor;
|
| 7 |
+
using UnityEngine.TestTools;
|
| 8 |
+
|
| 9 |
+
namespace Unity.MLAgents.Tests
|
| 10 |
+
{
|
| 11 |
+
[TestFixture]
|
| 12 |
+
public class BehaviorParameterTests : IHeuristicProvider
|
| 13 |
+
{
|
| 14 |
+
const string k_continuousONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/continuous2vis8vec2action_v1_0.onnx";
|
| 15 |
+
public void Heuristic(in ActionBuffers actionsOut)
|
| 16 |
+
{
|
| 17 |
+
// No-op
|
| 18 |
+
}
|
| 19 |
+
|
| 20 |
+
[Test]
|
| 21 |
+
public void TestNoModelInferenceOnlyThrows()
|
| 22 |
+
{
|
| 23 |
+
var gameObj = new GameObject();
|
| 24 |
+
var bp = gameObj.AddComponent<BehaviorParameters>();
|
| 25 |
+
bp.BehaviorType = BehaviorType.InferenceOnly;
|
| 26 |
+
var actionSpec = new ActionSpec();
|
| 27 |
+
|
| 28 |
+
Assert.Throws<UnityAgentsException>(() =>
|
| 29 |
+
{
|
| 30 |
+
bp.GeneratePolicy(actionSpec, new ActuatorManager());
|
| 31 |
+
});
|
| 32 |
+
}
|
| 33 |
+
|
| 34 |
+
[Test]
|
| 35 |
+
public void TestIsInHeuristicMode()
|
| 36 |
+
{
|
| 37 |
+
var gameObj = new GameObject();
|
| 38 |
+
var bp = gameObj.AddComponent<BehaviorParameters>();
|
| 39 |
+
bp.Model = null;
|
| 40 |
+
gameObj.AddComponent<Agent>();
|
| 41 |
+
bp.BehaviorType = BehaviorType.HeuristicOnly;
|
| 42 |
+
Assert.IsTrue(bp.IsInHeuristicMode());
|
| 43 |
+
|
| 44 |
+
bp.BehaviorType = BehaviorType.Default;
|
| 45 |
+
Assert.IsTrue(bp.IsInHeuristicMode());
|
| 46 |
+
|
| 47 |
+
bp.Model = ScriptableObject.CreateInstance<ModelAsset>();
|
| 48 |
+
Assert.IsFalse(bp.IsInHeuristicMode());
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
[Test]
|
| 52 |
+
public void TestPolicyUpdateEventFired()
|
| 53 |
+
{
|
| 54 |
+
var gameObj = new GameObject();
|
| 55 |
+
var bp = gameObj.AddComponent<BehaviorParameters>();
|
| 56 |
+
gameObj.AddComponent<Agent>().LazyInitialize();
|
| 57 |
+
bp.OnPolicyUpdated += delegate (bool isInHeuristicMode) { Debug.Log($"OnPolicyChanged:{isInHeuristicMode}"); };
|
| 58 |
+
bp.BehaviorType = BehaviorType.HeuristicOnly;
|
| 59 |
+
LogAssert.Expect(LogType.Log, $"OnPolicyChanged:{true}");
|
| 60 |
+
|
| 61 |
+
bp.BehaviorType = BehaviorType.Default;
|
| 62 |
+
LogAssert.Expect(LogType.Log, $"OnPolicyChanged:{true}");
|
| 63 |
+
|
| 64 |
+
Assert.Throws<UnityAgentsException>(() =>
|
| 65 |
+
{
|
| 66 |
+
bp.BehaviorType = BehaviorType.InferenceOnly;
|
| 67 |
+
});
|
| 68 |
+
|
| 69 |
+
bp.Model = AssetDatabase.LoadAssetAtPath<ModelAsset>(k_continuousONNXPath);
|
| 70 |
+
LogAssert.Expect(LogType.Log, $"OnPolicyChanged:{false}");
|
| 71 |
+
|
| 72 |
+
bp.BehaviorType = BehaviorType.HeuristicOnly;
|
| 73 |
+
LogAssert.Expect(LogType.Log, $"OnPolicyChanged:{true}");
|
| 74 |
+
}
|
| 75 |
+
}
|
| 76 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/BehaviorParameterTests.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Communicator.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Communicator/GrpcExtensionsTests.cs
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using System.Text.RegularExpressions;
|
| 3 |
+
using Google.Protobuf;
|
| 4 |
+
using NUnit.Framework;
|
| 5 |
+
using Unity.MLAgents.Actuators;
|
| 6 |
+
using Unity.MLAgents.Demonstrations;
|
| 7 |
+
using Unity.MLAgents.Policies;
|
| 8 |
+
using Unity.MLAgents.Sensors;
|
| 9 |
+
|
| 10 |
+
using Unity.MLAgents.Analytics;
|
| 11 |
+
using Unity.MLAgents.CommunicatorObjects;
|
| 12 |
+
using UnityEngine;
|
| 13 |
+
using UnityEngine.TestTools;
|
| 14 |
+
|
| 15 |
+
namespace Unity.MLAgents.Tests
|
| 16 |
+
{
|
| 17 |
+
[TestFixture]
|
| 18 |
+
public class GrpcExtensionsTests
|
| 19 |
+
{
|
| 20 |
+
[SetUp]
|
| 21 |
+
public void SetUp()
|
| 22 |
+
{
|
| 23 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
|
| 24 |
+
}
|
| 25 |
+
|
| 26 |
+
[Test]
|
| 27 |
+
public void TestDefaultBrainParametersToProto()
|
| 28 |
+
{
|
| 29 |
+
// Should be able to convert a default instance to proto.
|
| 30 |
+
var brain = new BrainParameters();
|
| 31 |
+
brain.ToProto("foo", false);
|
| 32 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 33 |
+
{
|
| 34 |
+
BaseRLCapabilities = true,
|
| 35 |
+
HybridActions = false
|
| 36 |
+
};
|
| 37 |
+
brain.ToProto("foo", false);
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
[Test]
|
| 41 |
+
public void TestDefaultActionSpecToProto()
|
| 42 |
+
{
|
| 43 |
+
// Should be able to convert a default instance to proto.
|
| 44 |
+
var actionSpec = new ActionSpec();
|
| 45 |
+
actionSpec.ToBrainParametersProto("foo", false);
|
| 46 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 47 |
+
{
|
| 48 |
+
BaseRLCapabilities = true,
|
| 49 |
+
HybridActions = false
|
| 50 |
+
};
|
| 51 |
+
actionSpec.ToBrainParametersProto("foo", false);
|
| 52 |
+
|
| 53 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
|
| 54 |
+
// Continuous
|
| 55 |
+
actionSpec = ActionSpec.MakeContinuous(3);
|
| 56 |
+
actionSpec.ToBrainParametersProto("foo", false);
|
| 57 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 58 |
+
{
|
| 59 |
+
BaseRLCapabilities = true,
|
| 60 |
+
HybridActions = false
|
| 61 |
+
};
|
| 62 |
+
actionSpec.ToBrainParametersProto("foo", false);
|
| 63 |
+
|
| 64 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
|
| 65 |
+
|
| 66 |
+
// Discrete
|
| 67 |
+
actionSpec = ActionSpec.MakeDiscrete(1, 2, 3);
|
| 68 |
+
actionSpec.ToBrainParametersProto("foo", false);
|
| 69 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 70 |
+
{
|
| 71 |
+
BaseRLCapabilities = true,
|
| 72 |
+
HybridActions = false
|
| 73 |
+
};
|
| 74 |
+
actionSpec.ToBrainParametersProto("foo", false);
|
| 75 |
+
}
|
| 76 |
+
|
| 77 |
+
[Test]
|
| 78 |
+
public void ToBrainParameters()
|
| 79 |
+
{
|
| 80 |
+
// Should be able to convert a default instance to proto.
|
| 81 |
+
var actionSpec = new ActionSpec();
|
| 82 |
+
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
|
| 83 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 84 |
+
{
|
| 85 |
+
BaseRLCapabilities = true,
|
| 86 |
+
HybridActions = false
|
| 87 |
+
};
|
| 88 |
+
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
|
| 89 |
+
|
| 90 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
|
| 91 |
+
// Continuous
|
| 92 |
+
actionSpec = ActionSpec.MakeContinuous(3);
|
| 93 |
+
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
|
| 94 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 95 |
+
{
|
| 96 |
+
BaseRLCapabilities = true,
|
| 97 |
+
HybridActions = false
|
| 98 |
+
};
|
| 99 |
+
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
|
| 100 |
+
|
| 101 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities();
|
| 102 |
+
|
| 103 |
+
// Discrete
|
| 104 |
+
actionSpec = ActionSpec.MakeDiscrete(1, 2, 3);
|
| 105 |
+
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
|
| 106 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 107 |
+
{
|
| 108 |
+
BaseRLCapabilities = true,
|
| 109 |
+
HybridActions = false
|
| 110 |
+
};
|
| 111 |
+
actionSpec.ToBrainParametersProto("foo", false).ToBrainParameters();
|
| 112 |
+
}
|
| 113 |
+
|
| 114 |
+
[Test]
|
| 115 |
+
public void TestDefaultAgentInfoToProto()
|
| 116 |
+
{
|
| 117 |
+
// Should be able to convert a default instance to proto.
|
| 118 |
+
var agentInfo = new AgentInfo();
|
| 119 |
+
var pairProto = agentInfo.ToInfoActionPairProto();
|
| 120 |
+
pairProto.AgentInfo.Observations.Add(new ObservationProto
|
| 121 |
+
{
|
| 122 |
+
CompressedData = ByteString.Empty,
|
| 123 |
+
CompressionType = CompressionTypeProto.None,
|
| 124 |
+
FloatData = new ObservationProto.Types.FloatData(),
|
| 125 |
+
ObservationType = ObservationTypeProto.Default,
|
| 126 |
+
Name = "Sensor"
|
| 127 |
+
});
|
| 128 |
+
pairProto.AgentInfo.Observations[0].Shape.Add(0);
|
| 129 |
+
pairProto.GetObservationSummaries();
|
| 130 |
+
agentInfo.ToAgentInfoProto();
|
| 131 |
+
agentInfo.groupId = 1;
|
| 132 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 133 |
+
{
|
| 134 |
+
BaseRLCapabilities = true,
|
| 135 |
+
MultiAgentGroups = false
|
| 136 |
+
};
|
| 137 |
+
agentInfo.ToAgentInfoProto();
|
| 138 |
+
LogAssert.Expect(LogType.Warning, new Regex(".+"));
|
| 139 |
+
Academy.Instance.TrainerCapabilities = new UnityRLCapabilities
|
| 140 |
+
{
|
| 141 |
+
BaseRLCapabilities = true,
|
| 142 |
+
MultiAgentGroups = true
|
| 143 |
+
};
|
| 144 |
+
agentInfo.ToAgentInfoProto();
|
| 145 |
+
}
|
| 146 |
+
|
| 147 |
+
[Test]
|
| 148 |
+
public void TestDefaultDemonstrationMetaDataToProto()
|
| 149 |
+
{
|
| 150 |
+
// Should be able to convert a default instance to proto.
|
| 151 |
+
var demoMetaData = new DemonstrationMetaData();
|
| 152 |
+
demoMetaData.ToProto();
|
| 153 |
+
}
|
| 154 |
+
|
| 155 |
+
class DummySensor : ISensor
|
| 156 |
+
{
|
| 157 |
+
public ObservationSpec ObservationSpec;
|
| 158 |
+
public SensorCompressionType CompressionType;
|
| 159 |
+
|
| 160 |
+
public ObservationSpec GetObservationSpec()
|
| 161 |
+
{
|
| 162 |
+
return ObservationSpec;
|
| 163 |
+
}
|
| 164 |
+
|
| 165 |
+
public int Write(ObservationWriter writer)
|
| 166 |
+
{
|
| 167 |
+
return 0;
|
| 168 |
+
}
|
| 169 |
+
|
| 170 |
+
public byte[] GetCompressedObservation()
|
| 171 |
+
{
|
| 172 |
+
return new byte[] { 13, 37 };
|
| 173 |
+
}
|
| 174 |
+
|
| 175 |
+
public void Update() { }
|
| 176 |
+
|
| 177 |
+
public void Reset() { }
|
| 178 |
+
|
| 179 |
+
public CompressionSpec GetCompressionSpec()
|
| 180 |
+
{
|
| 181 |
+
return new CompressionSpec(CompressionType);
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
public string GetName()
|
| 185 |
+
{
|
| 186 |
+
return "Dummy";
|
| 187 |
+
}
|
| 188 |
+
}
|
| 189 |
+
|
| 190 |
+
[Test]
|
| 191 |
+
public void TestGetObservationProtoCapabilities()
|
| 192 |
+
{
|
| 193 |
+
// Shape, compression type, concatenatedPngObservations, expect throw
|
| 194 |
+
var variants = new[]
|
| 195 |
+
{
|
| 196 |
+
// Vector observations
|
| 197 |
+
(new[] {3}, SensorCompressionType.None, false, false),
|
| 198 |
+
// Uncompressed floats
|
| 199 |
+
(new[] {3, 4, 4}, SensorCompressionType.None, false, false),
|
| 200 |
+
// Compressed floats, 3 channels
|
| 201 |
+
(new[] {3, 4, 4}, SensorCompressionType.PNG, false, true),
|
| 202 |
+
|
| 203 |
+
// Compressed floats, >3 channels
|
| 204 |
+
(new[] {4, 4, 4}, SensorCompressionType.PNG, false, false), // Unsupported - results in uncompressed
|
| 205 |
+
(new[] {4, 4, 4}, SensorCompressionType.PNG, true, true), // Supported compressed
|
| 206 |
+
};
|
| 207 |
+
|
| 208 |
+
foreach (var (shape, compressionType, supportsMultiPngObs, expectCompressed) in variants)
|
| 209 |
+
{
|
| 210 |
+
var inplaceShape = InplaceArray<int>.FromList(shape);
|
| 211 |
+
var dummySensor = new DummySensor();
|
| 212 |
+
var obsWriter = new ObservationWriter();
|
| 213 |
+
|
| 214 |
+
if (shape.Length == 1)
|
| 215 |
+
{
|
| 216 |
+
dummySensor.ObservationSpec = ObservationSpec.Vector(shape[0]);
|
| 217 |
+
}
|
| 218 |
+
else if (shape.Length == 3)
|
| 219 |
+
{
|
| 220 |
+
dummySensor.ObservationSpec = ObservationSpec.Visual(shape[0], shape[1], shape[2]);
|
| 221 |
+
}
|
| 222 |
+
else
|
| 223 |
+
{
|
| 224 |
+
throw new ArgumentOutOfRangeException();
|
| 225 |
+
}
|
| 226 |
+
dummySensor.CompressionType = compressionType;
|
| 227 |
+
obsWriter.SetTarget(new float[128], inplaceShape, 0);
|
| 228 |
+
|
| 229 |
+
var caps = new UnityRLCapabilities
|
| 230 |
+
{
|
| 231 |
+
ConcatenatedPngObservations = supportsMultiPngObs
|
| 232 |
+
};
|
| 233 |
+
Academy.Instance.TrainerCapabilities = caps;
|
| 234 |
+
|
| 235 |
+
|
| 236 |
+
var obsProto = dummySensor.GetObservationProto(obsWriter);
|
| 237 |
+
if (expectCompressed)
|
| 238 |
+
{
|
| 239 |
+
Assert.Greater(obsProto.CompressedData.Length, 0);
|
| 240 |
+
Assert.AreEqual(obsProto.FloatData, null);
|
| 241 |
+
}
|
| 242 |
+
else
|
| 243 |
+
{
|
| 244 |
+
Assert.Greater(obsProto.FloatData.Data.Count, 0);
|
| 245 |
+
Assert.AreEqual(obsProto.CompressedData.Length, 0);
|
| 246 |
+
}
|
| 247 |
+
}
|
| 248 |
+
}
|
| 249 |
+
|
| 250 |
+
[Test]
|
| 251 |
+
public void TestDefaultTrainingEvents()
|
| 252 |
+
{
|
| 253 |
+
var trainingEnvInit = new TrainingEnvironmentInitialized
|
| 254 |
+
{
|
| 255 |
+
PythonVersion = "test",
|
| 256 |
+
};
|
| 257 |
+
var trainingEnvInitEvent = trainingEnvInit.ToTrainingEnvironmentInitializedEvent();
|
| 258 |
+
Assert.AreEqual(trainingEnvInit.PythonVersion, trainingEnvInitEvent.TrainerPythonVersion);
|
| 259 |
+
|
| 260 |
+
var trainingBehavInit = new TrainingBehaviorInitialized
|
| 261 |
+
{
|
| 262 |
+
BehaviorName = "testBehavior",
|
| 263 |
+
ExtrinsicRewardEnabled = true,
|
| 264 |
+
CuriosityRewardEnabled = true,
|
| 265 |
+
|
| 266 |
+
RecurrentEnabled = true,
|
| 267 |
+
SelfPlayEnabled = true,
|
| 268 |
+
};
|
| 269 |
+
var trainingBehavInitEvent = trainingBehavInit.ToTrainingBehaviorInitializedEvent();
|
| 270 |
+
Assert.AreEqual(trainingBehavInit.BehaviorName, trainingBehavInitEvent.BehaviorName);
|
| 271 |
+
|
| 272 |
+
Assert.AreEqual(RewardSignals.Extrinsic | RewardSignals.Curiosity, trainingBehavInitEvent.RewardSignalFlags);
|
| 273 |
+
Assert.AreEqual(TrainingFeatures.Recurrent | TrainingFeatures.SelfPlay, trainingBehavInitEvent.TrainingFeatureFlags);
|
| 274 |
+
}
|
| 275 |
+
}
|
| 276 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Communicator/GrpcExtensionsTests.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Communicator/RpcCommunicatorTests.cs
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using NUnit.Framework;
|
| 2 |
+
using UnityEngine.TestTools;
|
| 3 |
+
|
| 4 |
+
namespace Unity.MLAgents.Tests.Communicator
|
| 5 |
+
{
|
| 6 |
+
[TestFixture]
|
| 7 |
+
public class RpcCommunicatorTests
|
| 8 |
+
{
|
| 9 |
+
[Test]
|
| 10 |
+
public void TestCheckCommunicationVersionsAreCompatible()
|
| 11 |
+
{
|
| 12 |
+
var unityVerStr = "1.0.0";
|
| 13 |
+
var pythonVerStr = "1.0.0";
|
| 14 |
+
|
| 15 |
+
Assert.IsTrue(RpcCommunicator.CheckCommunicationVersionsAreCompatible(unityVerStr,
|
| 16 |
+
pythonVerStr));
|
| 17 |
+
LogAssert.NoUnexpectedReceived();
|
| 18 |
+
|
| 19 |
+
pythonVerStr = "1.1.0";
|
| 20 |
+
Assert.IsTrue(RpcCommunicator.CheckCommunicationVersionsAreCompatible(unityVerStr,
|
| 21 |
+
pythonVerStr));
|
| 22 |
+
LogAssert.NoUnexpectedReceived();
|
| 23 |
+
|
| 24 |
+
unityVerStr = "2.0.0";
|
| 25 |
+
Assert.IsFalse(RpcCommunicator.CheckCommunicationVersionsAreCompatible(unityVerStr,
|
| 26 |
+
pythonVerStr));
|
| 27 |
+
|
| 28 |
+
unityVerStr = "0.15.0";
|
| 29 |
+
pythonVerStr = "0.15.0";
|
| 30 |
+
Assert.IsTrue(RpcCommunicator.CheckCommunicationVersionsAreCompatible(unityVerStr,
|
| 31 |
+
pythonVerStr));
|
| 32 |
+
unityVerStr = "0.16.0";
|
| 33 |
+
Assert.IsFalse(RpcCommunicator.CheckCommunicationVersionsAreCompatible(unityVerStr,
|
| 34 |
+
pythonVerStr));
|
| 35 |
+
unityVerStr = "1.15.0";
|
| 36 |
+
Assert.IsFalse(RpcCommunicator.CheckCommunicationVersionsAreCompatible(unityVerStr,
|
| 37 |
+
pythonVerStr));
|
| 38 |
+
}
|
| 39 |
+
}
|
| 40 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Communicator/RpcCommunicatorTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Communicator/UnityRLCapabilitiesTests.cs
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Text.RegularExpressions;
|
| 2 |
+
using NUnit.Framework;
|
| 3 |
+
using UnityEngine;
|
| 4 |
+
using UnityEngine.TestTools;
|
| 5 |
+
|
| 6 |
+
namespace Unity.MLAgents.Tests.Communicator
|
| 7 |
+
{
|
| 8 |
+
[TestFixture]
|
| 9 |
+
public class UnityRLCapabilitiesTests
|
| 10 |
+
{
|
| 11 |
+
[Test]
|
| 12 |
+
public void TestWarnOnPythonMissingBaseRLCapabilities()
|
| 13 |
+
{
|
| 14 |
+
var caps = new UnityRLCapabilities();
|
| 15 |
+
Assert.False(caps.WarnOnPythonMissingBaseRLCapabilities());
|
| 16 |
+
LogAssert.NoUnexpectedReceived();
|
| 17 |
+
caps = new UnityRLCapabilities(false);
|
| 18 |
+
Assert.True(caps.WarnOnPythonMissingBaseRLCapabilities());
|
| 19 |
+
LogAssert.Expect(LogType.Warning, new Regex(".+"));
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Communicator/UnityRLCapabilitiesTests.cs.meta
ADDED
|
Binary file (86 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/DemonstrationTests.cs
ADDED
|
@@ -0,0 +1,150 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using NUnit.Framework;
|
| 2 |
+
using UnityEngine;
|
| 3 |
+
using System.IO.Abstractions.TestingHelpers;
|
| 4 |
+
using System.Reflection;
|
| 5 |
+
using Unity.MLAgents.Actuators;
|
| 6 |
+
using Unity.MLAgents.CommunicatorObjects;
|
| 7 |
+
using Unity.MLAgents.Sensors;
|
| 8 |
+
using Unity.MLAgents.Demonstrations;
|
| 9 |
+
using Unity.MLAgents.Policies;
|
| 10 |
+
using Unity.MLAgents.Utils.Tests;
|
| 11 |
+
|
| 12 |
+
namespace Unity.MLAgents.Tests
|
| 13 |
+
{
|
| 14 |
+
[TestFixture]
|
| 15 |
+
public class DemonstrationTests
|
| 16 |
+
{
|
| 17 |
+
const string k_DemoDirectory = "Assets/Demonstrations/";
|
| 18 |
+
const string k_ExtensionType = ".demo";
|
| 19 |
+
const string k_DemoName = "Test";
|
| 20 |
+
|
| 21 |
+
[SetUp]
|
| 22 |
+
public void SetUp()
|
| 23 |
+
{
|
| 24 |
+
if (Academy.IsInitialized)
|
| 25 |
+
{
|
| 26 |
+
Academy.Instance.Dispose();
|
| 27 |
+
}
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
[Test]
|
| 31 |
+
public void TestSanitization()
|
| 32 |
+
{
|
| 33 |
+
const string dirtyString = "abc1234567&!@";
|
| 34 |
+
const string knownCleanString = "abc123";
|
| 35 |
+
var cleanString = DemonstrationRecorder.SanitizeName(dirtyString, 6);
|
| 36 |
+
Assert.AreNotEqual(dirtyString, cleanString);
|
| 37 |
+
Assert.AreEqual(cleanString, knownCleanString);
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
[Test]
|
| 41 |
+
public void TestStoreInitialize()
|
| 42 |
+
{
|
| 43 |
+
var fileSystem = new MockFileSystem();
|
| 44 |
+
|
| 45 |
+
var gameobj = new GameObject("gameObj");
|
| 46 |
+
|
| 47 |
+
var bp = gameobj.AddComponent<BehaviorParameters>();
|
| 48 |
+
bp.BrainParameters.VectorObservationSize = 3;
|
| 49 |
+
bp.BrainParameters.NumStackedVectorObservations = 2;
|
| 50 |
+
bp.BrainParameters.VectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
|
| 51 |
+
bp.BrainParameters.ActionSpec = ActionSpec.MakeDiscrete(2, 2);
|
| 52 |
+
|
| 53 |
+
gameobj.AddComponent<TestAgent>();
|
| 54 |
+
|
| 55 |
+
Assert.IsFalse(fileSystem.Directory.Exists(k_DemoDirectory));
|
| 56 |
+
|
| 57 |
+
var demoRec = gameobj.AddComponent<DemonstrationRecorder>();
|
| 58 |
+
demoRec.Record = true;
|
| 59 |
+
demoRec.DemonstrationName = k_DemoName;
|
| 60 |
+
demoRec.DemonstrationDirectory = k_DemoDirectory;
|
| 61 |
+
var demoWriter = demoRec.LazyInitialize(fileSystem);
|
| 62 |
+
|
| 63 |
+
Assert.IsTrue(fileSystem.Directory.Exists(k_DemoDirectory));
|
| 64 |
+
Assert.IsTrue(fileSystem.FileExists(k_DemoDirectory + k_DemoName + k_ExtensionType));
|
| 65 |
+
|
| 66 |
+
var agentInfo = new AgentInfo
|
| 67 |
+
{
|
| 68 |
+
reward = 1f,
|
| 69 |
+
discreteActionMasks = new[] { false, true },
|
| 70 |
+
done = true,
|
| 71 |
+
episodeId = 5,
|
| 72 |
+
maxStepReached = true,
|
| 73 |
+
storedActions = new ActionBuffers(null, new[] { 0, 1 }),
|
| 74 |
+
};
|
| 75 |
+
|
| 76 |
+
|
| 77 |
+
demoWriter.Record(agentInfo, new System.Collections.Generic.List<ISensor>());
|
| 78 |
+
demoRec.Close();
|
| 79 |
+
|
| 80 |
+
// Make sure close can be called multiple times
|
| 81 |
+
demoWriter.Close();
|
| 82 |
+
demoRec.Close();
|
| 83 |
+
|
| 84 |
+
// Make sure trying to write after closing doesn't raise an error.
|
| 85 |
+
demoWriter.Record(agentInfo, new System.Collections.Generic.List<ISensor>());
|
| 86 |
+
}
|
| 87 |
+
|
| 88 |
+
public class ObservationAgent : TestAgent
|
| 89 |
+
{
|
| 90 |
+
public override void CollectObservations(VectorSensor sensor)
|
| 91 |
+
{
|
| 92 |
+
collectObservationsCalls += 1;
|
| 93 |
+
sensor.AddObservation(1f);
|
| 94 |
+
sensor.AddObservation(2f);
|
| 95 |
+
sensor.AddObservation(3f);
|
| 96 |
+
}
|
| 97 |
+
}
|
| 98 |
+
|
| 99 |
+
[Test]
|
| 100 |
+
public void TestAgentWrite()
|
| 101 |
+
{
|
| 102 |
+
var agentGo1 = new GameObject("TestAgent");
|
| 103 |
+
var bpA = agentGo1.AddComponent<BehaviorParameters>();
|
| 104 |
+
bpA.BrainParameters.VectorObservationSize = 3;
|
| 105 |
+
bpA.BrainParameters.NumStackedVectorObservations = 1;
|
| 106 |
+
bpA.BrainParameters.VectorActionDescriptions = new[] { "TestActionA", "TestActionB" };
|
| 107 |
+
bpA.BrainParameters.ActionSpec = ActionSpec.MakeDiscrete(2, 2);
|
| 108 |
+
|
| 109 |
+
agentGo1.AddComponent<ObservationAgent>();
|
| 110 |
+
var agent1 = agentGo1.GetComponent<ObservationAgent>();
|
| 111 |
+
|
| 112 |
+
agentGo1.AddComponent<DemonstrationRecorder>();
|
| 113 |
+
var demoRecorder = agentGo1.GetComponent<DemonstrationRecorder>();
|
| 114 |
+
var fileSystem = new MockFileSystem();
|
| 115 |
+
demoRecorder.DemonstrationDirectory = k_DemoDirectory;
|
| 116 |
+
demoRecorder.DemonstrationName = "TestBrain";
|
| 117 |
+
demoRecorder.Record = true;
|
| 118 |
+
demoRecorder.LazyInitialize(fileSystem);
|
| 119 |
+
|
| 120 |
+
var agentEnableMethod = typeof(Agent).GetMethod("OnEnable",
|
| 121 |
+
BindingFlags.Instance | BindingFlags.NonPublic);
|
| 122 |
+
var agentSendInfo = typeof(Agent).GetMethod("SendInfo",
|
| 123 |
+
BindingFlags.Instance | BindingFlags.NonPublic);
|
| 124 |
+
|
| 125 |
+
agentEnableMethod?.Invoke(agent1, new object[] { });
|
| 126 |
+
|
| 127 |
+
// Step the agent
|
| 128 |
+
agent1.RequestDecision();
|
| 129 |
+
agentSendInfo?.Invoke(agent1, new object[] { });
|
| 130 |
+
|
| 131 |
+
demoRecorder.Close();
|
| 132 |
+
|
| 133 |
+
// Read back the demo file and make sure observations were written
|
| 134 |
+
var reader = fileSystem.File.OpenRead("Assets/Demonstrations/TestBrain.demo");
|
| 135 |
+
reader.Seek(DemonstrationWriter.MetaDataBytes + 1, 0);
|
| 136 |
+
BrainParametersProto.Parser.ParseDelimitedFrom(reader);
|
| 137 |
+
|
| 138 |
+
var agentInfoProto = AgentInfoActionPairProto.Parser.ParseDelimitedFrom(reader).AgentInfo;
|
| 139 |
+
var obs = agentInfoProto.Observations[2]; // skip dummy sensors
|
| 140 |
+
{
|
| 141 |
+
var vecObs = obs.FloatData.Data;
|
| 142 |
+
Assert.AreEqual(bpA.BrainParameters.VectorObservationSize, vecObs.Count);
|
| 143 |
+
for (var i = 0; i < vecObs.Count; i++)
|
| 144 |
+
{
|
| 145 |
+
Assert.AreEqual((float)i + 1, vecObs[i]);
|
| 146 |
+
}
|
| 147 |
+
}
|
| 148 |
+
}
|
| 149 |
+
}
|
| 150 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/DemonstrationTests.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Inference.meta
ADDED
|
Binary file (172 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Inference/DiscreteActionOutputApplierTest.cs
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Collections.Generic;
|
| 2 |
+
using Unity.InferenceEngine;
|
| 3 |
+
using NUnit.Framework;
|
| 4 |
+
using Unity.MLAgents.Actuators;
|
| 5 |
+
using Unity.MLAgents.Inference;
|
| 6 |
+
|
| 7 |
+
namespace Unity.MLAgents.Tests
|
| 8 |
+
{
|
| 9 |
+
public class DiscreteActionOutputApplierTest
|
| 10 |
+
{
|
| 11 |
+
[Test]
|
| 12 |
+
public void TestDiscreteApply()
|
| 13 |
+
{
|
| 14 |
+
var actionSpec = ActionSpec.MakeDiscrete(3, 2);
|
| 15 |
+
|
| 16 |
+
var applier = new DiscreteActionOutputApplier(actionSpec, 2020);
|
| 17 |
+
var agentIds = new List<int> { 42, 1337 };
|
| 18 |
+
var actionBuffers = new Dictionary<int, ActionBuffers>();
|
| 19 |
+
actionBuffers[42] = new ActionBuffers(actionSpec);
|
| 20 |
+
actionBuffers[1337] = new ActionBuffers(actionSpec);
|
| 21 |
+
|
| 22 |
+
var actionTensor = new TensorProxy
|
| 23 |
+
{
|
| 24 |
+
data = new Tensor<int>(
|
| 25 |
+
new TensorShape(2, 2),
|
| 26 |
+
new[]
|
| 27 |
+
{
|
| 28 |
+
2, // Agent 0, branch 0
|
| 29 |
+
1, // Agent 0, branch 1
|
| 30 |
+
0, // Agent 1, branch 0
|
| 31 |
+
0 // Agent 1, branch 1
|
| 32 |
+
}),
|
| 33 |
+
shape = new int[] { 2, 2 },
|
| 34 |
+
valueType = TensorProxy.TensorType.Integer
|
| 35 |
+
};
|
| 36 |
+
|
| 37 |
+
applier.Apply(actionTensor, agentIds, actionBuffers);
|
| 38 |
+
Assert.AreEqual(2, actionBuffers[42].DiscreteActions[0]);
|
| 39 |
+
Assert.AreEqual(1, actionBuffers[42].DiscreteActions[1]);
|
| 40 |
+
|
| 41 |
+
Assert.AreEqual(0, actionBuffers[1337].DiscreteActions[0]);
|
| 42 |
+
Assert.AreEqual(0, actionBuffers[1337].DiscreteActions[1]);
|
| 43 |
+
}
|
| 44 |
+
}
|
| 45 |
+
|
| 46 |
+
public class LegacyDiscreteActionOutputApplierTest
|
| 47 |
+
{
|
| 48 |
+
[Test]
|
| 49 |
+
public void TestDiscreteApply()
|
| 50 |
+
{
|
| 51 |
+
var actionSpec = ActionSpec.MakeDiscrete(3, 2);
|
| 52 |
+
const float smallLogProb = -1000.0f;
|
| 53 |
+
const float largeLogProb = -1.0f;
|
| 54 |
+
|
| 55 |
+
var logProbs = new TensorProxy
|
| 56 |
+
{
|
| 57 |
+
data = new Tensor<float>(
|
| 58 |
+
new TensorShape(2, 5),
|
| 59 |
+
new[]
|
| 60 |
+
{
|
| 61 |
+
smallLogProb, smallLogProb, largeLogProb, // Agent 0, branch 0
|
| 62 |
+
smallLogProb, largeLogProb, // Agent 0, branch 1
|
| 63 |
+
largeLogProb, smallLogProb, smallLogProb, // Agent 1, branch 0
|
| 64 |
+
largeLogProb, smallLogProb, // Agent 1, branch 1
|
| 65 |
+
}),
|
| 66 |
+
valueType = TensorProxy.TensorType.FloatingPoint
|
| 67 |
+
};
|
| 68 |
+
|
| 69 |
+
var applier = new LegacyDiscreteActionOutputApplier(actionSpec, 2020);
|
| 70 |
+
var agentIds = new List<int> { 42, 1337 };
|
| 71 |
+
var actionBuffers = new Dictionary<int, ActionBuffers>();
|
| 72 |
+
actionBuffers[42] = new ActionBuffers(actionSpec);
|
| 73 |
+
actionBuffers[1337] = new ActionBuffers(actionSpec);
|
| 74 |
+
|
| 75 |
+
applier.Apply(logProbs, agentIds, actionBuffers);
|
| 76 |
+
Assert.AreEqual(2, actionBuffers[42].DiscreteActions[0]);
|
| 77 |
+
Assert.AreEqual(1, actionBuffers[42].DiscreteActions[1]);
|
| 78 |
+
|
| 79 |
+
Assert.AreEqual(0, actionBuffers[1337].DiscreteActions[0]);
|
| 80 |
+
Assert.AreEqual(0, actionBuffers[1337].DiscreteActions[1]);
|
| 81 |
+
}
|
| 82 |
+
}
|
| 83 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Inference/DiscreteActionOutputApplierTest.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorApplier.cs
ADDED
|
@@ -0,0 +1,192 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Collections.Generic;
|
| 2 |
+
using NUnit.Framework;
|
| 3 |
+
using Unity.InferenceEngine;
|
| 4 |
+
using Unity.MLAgents.Actuators;
|
| 5 |
+
using Unity.MLAgents.Inference;
|
| 6 |
+
|
| 7 |
+
namespace Unity.MLAgents.Tests
|
| 8 |
+
{
|
| 9 |
+
public class EditModeTestInternalBrainTensorApplier
|
| 10 |
+
{
|
| 11 |
+
class TestAgent : Agent { }
|
| 12 |
+
|
| 13 |
+
[Test]
|
| 14 |
+
public void Construction()
|
| 15 |
+
{
|
| 16 |
+
var actionSpec = new ActionSpec();
|
| 17 |
+
var mem = new Dictionary<int, List<float>>();
|
| 18 |
+
var tensorGenerator = new TensorApplier(actionSpec, 0, mem);
|
| 19 |
+
Assert.IsNotNull(tensorGenerator);
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
[Test]
|
| 23 |
+
public void ApplyContinuousActionOutput()
|
| 24 |
+
{
|
| 25 |
+
var actionSpec = ActionSpec.MakeContinuous(3);
|
| 26 |
+
var inputTensor = new TensorProxy()
|
| 27 |
+
{
|
| 28 |
+
shape = new int[] { 2, 3 },
|
| 29 |
+
data = new Tensor<float>(new TensorShape(2, 3), new float[] { 1, 2, 3, 4, 5, 6 })
|
| 30 |
+
};
|
| 31 |
+
|
| 32 |
+
var applier = new ContinuousActionOutputApplier(actionSpec);
|
| 33 |
+
|
| 34 |
+
var agentIds = new List<int>() { 0, 1 };
|
| 35 |
+
|
| 36 |
+
// Dictionary from AgentId to Action
|
| 37 |
+
var actionDict = new Dictionary<int, ActionBuffers>() { { 0, ActionBuffers.Empty }, { 1, ActionBuffers.Empty } };
|
| 38 |
+
|
| 39 |
+
applier.Apply(inputTensor, agentIds, actionDict);
|
| 40 |
+
|
| 41 |
+
|
| 42 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[0], 1);
|
| 43 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[1], 2);
|
| 44 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[2], 3);
|
| 45 |
+
|
| 46 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[0], 4);
|
| 47 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[1], 5);
|
| 48 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[2], 6);
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
[Test]
|
| 52 |
+
public void ApplyDiscreteActionOutputLegacy()
|
| 53 |
+
{
|
| 54 |
+
var actionSpec = ActionSpec.MakeDiscrete(2, 3);
|
| 55 |
+
var inputTensor = new TensorProxy()
|
| 56 |
+
{
|
| 57 |
+
shape = new int[] { 2, 5 },
|
| 58 |
+
data = new Tensor<float>(
|
| 59 |
+
new TensorShape(2, 5),
|
| 60 |
+
new[] { 0.5f, 22.5f, 0.1f, 5f, 1f, 4f, 5f, 6f, 7f, 8f })
|
| 61 |
+
};
|
| 62 |
+
var applier = new LegacyDiscreteActionOutputApplier(actionSpec, 0);
|
| 63 |
+
|
| 64 |
+
var agentIds = new List<int>() { 0, 1 };
|
| 65 |
+
|
| 66 |
+
// Dictionary from AgentId to Action
|
| 67 |
+
var actionDict = new Dictionary<int, ActionBuffers>() { { 0, ActionBuffers.Empty }, { 1, ActionBuffers.Empty } };
|
| 68 |
+
|
| 69 |
+
|
| 70 |
+
applier.Apply(inputTensor, agentIds, actionDict);
|
| 71 |
+
|
| 72 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[0], 1);
|
| 73 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[1], 1);
|
| 74 |
+
|
| 75 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[0], 1);
|
| 76 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[1], 2);
|
| 77 |
+
}
|
| 78 |
+
|
| 79 |
+
[Test]
|
| 80 |
+
public void ApplyDiscreteActionOutput()
|
| 81 |
+
{
|
| 82 |
+
var actionSpec = ActionSpec.MakeDiscrete(2, 3);
|
| 83 |
+
var inputTensor = new TensorProxy()
|
| 84 |
+
{
|
| 85 |
+
shape = new int[] { 2, 2 },
|
| 86 |
+
data = new Tensor<int>(
|
| 87 |
+
new TensorShape(2, 2),
|
| 88 |
+
new[] { 1, 1, 1, 2 }),
|
| 89 |
+
valueType = TensorProxy.TensorType.Integer
|
| 90 |
+
};
|
| 91 |
+
var applier = new DiscreteActionOutputApplier(actionSpec, 0);
|
| 92 |
+
|
| 93 |
+
var agentIds = new List<int>() { 0, 1 };
|
| 94 |
+
|
| 95 |
+
// Dictionary from AgentId to Action
|
| 96 |
+
var actionDict = new Dictionary<int, ActionBuffers>() { { 0, ActionBuffers.Empty }, { 1, ActionBuffers.Empty } };
|
| 97 |
+
|
| 98 |
+
|
| 99 |
+
applier.Apply(inputTensor, agentIds, actionDict);
|
| 100 |
+
|
| 101 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[0], 1);
|
| 102 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[1], 1);
|
| 103 |
+
|
| 104 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[0], 1);
|
| 105 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[1], 2);
|
| 106 |
+
}
|
| 107 |
+
|
| 108 |
+
[Test]
|
| 109 |
+
public void ApplyHybridActionOutputLegacy()
|
| 110 |
+
{
|
| 111 |
+
var actionSpec = new ActionSpec(3, new[] { 2, 3 });
|
| 112 |
+
var continuousInputTensor = new TensorProxy()
|
| 113 |
+
{
|
| 114 |
+
shape = new int[] { 2, 3 },
|
| 115 |
+
data = new Tensor<float>(new TensorShape(2, 3), new float[] { 1, 2, 3, 4, 5, 6 })
|
| 116 |
+
};
|
| 117 |
+
var discreteInputTensor = new TensorProxy()
|
| 118 |
+
{
|
| 119 |
+
shape = new int[] { 2, 8 },
|
| 120 |
+
data = new Tensor<float>(
|
| 121 |
+
new TensorShape(2, 5),
|
| 122 |
+
new[] { 0.5f, 22.5f, 0.1f, 5f, 1f, 4f, 5f, 6f, 7f, 8f })
|
| 123 |
+
};
|
| 124 |
+
var continuousApplier = new ContinuousActionOutputApplier(actionSpec);
|
| 125 |
+
var discreteApplier = new LegacyDiscreteActionOutputApplier(actionSpec, 0);
|
| 126 |
+
|
| 127 |
+
var agentIds = new List<int>() { 0, 1 };
|
| 128 |
+
|
| 129 |
+
// Dictionary from AgentId to Action
|
| 130 |
+
var actionDict = new Dictionary<int, ActionBuffers>() { { 0, ActionBuffers.Empty }, { 1, ActionBuffers.Empty } };
|
| 131 |
+
|
| 132 |
+
|
| 133 |
+
continuousApplier.Apply(continuousInputTensor, agentIds, actionDict);
|
| 134 |
+
discreteApplier.Apply(discreteInputTensor, agentIds, actionDict);
|
| 135 |
+
|
| 136 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[0], 1);
|
| 137 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[1], 2);
|
| 138 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[2], 3);
|
| 139 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[0], 1);
|
| 140 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[1], 1);
|
| 141 |
+
|
| 142 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[0], 4);
|
| 143 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[1], 5);
|
| 144 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[2], 6);
|
| 145 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[0], 1);
|
| 146 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[1], 2);
|
| 147 |
+
}
|
| 148 |
+
|
| 149 |
+
[Test]
|
| 150 |
+
public void ApplyHybridActionOutput()
|
| 151 |
+
{
|
| 152 |
+
var actionSpec = new ActionSpec(3, new[] { 2, 3 });
|
| 153 |
+
var continuousInputTensor = new TensorProxy()
|
| 154 |
+
{
|
| 155 |
+
shape = new int[] { 2, 3 },
|
| 156 |
+
data = new Tensor<float>(new TensorShape(2, 3), new float[] { 1, 2, 3, 4, 5, 6 }),
|
| 157 |
+
valueType = TensorProxy.TensorType.FloatingPoint
|
| 158 |
+
};
|
| 159 |
+
var discreteInputTensor = new TensorProxy()
|
| 160 |
+
{
|
| 161 |
+
shape = new int[] { 2, 2 },
|
| 162 |
+
data = new Tensor<int>(
|
| 163 |
+
new TensorShape(2, 2),
|
| 164 |
+
new[] { 1, 1, 1, 2 }),
|
| 165 |
+
valueType = TensorProxy.TensorType.Integer
|
| 166 |
+
};
|
| 167 |
+
var continuousApplier = new ContinuousActionOutputApplier(actionSpec);
|
| 168 |
+
var discreteApplier = new DiscreteActionOutputApplier(actionSpec, 0);
|
| 169 |
+
|
| 170 |
+
var agentIds = new List<int>() { 0, 1 };
|
| 171 |
+
|
| 172 |
+
// Dictionary from AgentId to Action
|
| 173 |
+
var actionDict = new Dictionary<int, ActionBuffers>() { { 0, ActionBuffers.Empty }, { 1, ActionBuffers.Empty } };
|
| 174 |
+
|
| 175 |
+
|
| 176 |
+
continuousApplier.Apply(continuousInputTensor, agentIds, actionDict);
|
| 177 |
+
discreteApplier.Apply(discreteInputTensor, agentIds, actionDict);
|
| 178 |
+
|
| 179 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[0], 1);
|
| 180 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[1], 2);
|
| 181 |
+
Assert.AreEqual(actionDict[0].ContinuousActions[2], 3);
|
| 182 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[0], 1);
|
| 183 |
+
Assert.AreEqual(actionDict[0].DiscreteActions[1], 1);
|
| 184 |
+
|
| 185 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[0], 4);
|
| 186 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[1], 5);
|
| 187 |
+
Assert.AreEqual(actionDict[1].ContinuousActions[2], 6);
|
| 188 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[0], 1);
|
| 189 |
+
Assert.AreEqual(actionDict[1].DiscreteActions[1], 2);
|
| 190 |
+
}
|
| 191 |
+
}
|
| 192 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorApplier.cs.meta
ADDED
|
Binary file (88 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorGenerator.cs
ADDED
|
@@ -0,0 +1,313 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Collections.Generic;
|
| 2 |
+
using Unity.InferenceEngine;
|
| 3 |
+
using NUnit.Framework;
|
| 4 |
+
using UnityEngine;
|
| 5 |
+
using UnityEngine.TestTools;
|
| 6 |
+
using Unity.MLAgents.Actuators;
|
| 7 |
+
using Unity.MLAgents.Inference;
|
| 8 |
+
using Unity.MLAgents.Policies;
|
| 9 |
+
using Unity.MLAgents.Sensors;
|
| 10 |
+
using Unity.MLAgents.Utils.Tests;
|
| 11 |
+
|
| 12 |
+
namespace Unity.MLAgents.Tests
|
| 13 |
+
{
|
| 14 |
+
internal class OverflowSensor : ISensor
|
| 15 |
+
{
|
| 16 |
+
readonly string m_Name;
|
| 17 |
+
readonly int m_Size;
|
| 18 |
+
|
| 19 |
+
public OverflowSensor(string name, int size)
|
| 20 |
+
{
|
| 21 |
+
m_Name = name;
|
| 22 |
+
m_Size = size;
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
public ObservationSpec GetObservationSpec()
|
| 26 |
+
{
|
| 27 |
+
return ObservationSpec.Vector(m_Size);
|
| 28 |
+
}
|
| 29 |
+
|
| 30 |
+
public int Write(ObservationWriter writer)
|
| 31 |
+
{
|
| 32 |
+
for (var i = 0; i < m_Size; i++)
|
| 33 |
+
writer[i] = i + 1f;
|
| 34 |
+
return m_Size;
|
| 35 |
+
}
|
| 36 |
+
|
| 37 |
+
public byte[] GetCompressedObservation() { return null; }
|
| 38 |
+
public CompressionSpec GetCompressionSpec() { return new CompressionSpec(SensorCompressionType.None); }
|
| 39 |
+
public string GetName() { return m_Name; }
|
| 40 |
+
public void Update() { }
|
| 41 |
+
public void Reset() { }
|
| 42 |
+
}
|
| 43 |
+
|
| 44 |
+
[TestFixture]
|
| 45 |
+
public class EditModeTestInternalBrainTensorGenerator
|
| 46 |
+
{
|
| 47 |
+
[SetUp]
|
| 48 |
+
public void SetUp()
|
| 49 |
+
{
|
| 50 |
+
if (Academy.IsInitialized)
|
| 51 |
+
{
|
| 52 |
+
Academy.Instance.Dispose();
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
static List<TestAgent> GetFakeAgents(ObservableAttributeOptions observableAttributeOptions = ObservableAttributeOptions.Ignore)
|
| 57 |
+
{
|
| 58 |
+
var goA = new GameObject("goA");
|
| 59 |
+
var bpA = goA.AddComponent<BehaviorParameters>();
|
| 60 |
+
bpA.BrainParameters.VectorObservationSize = 3;
|
| 61 |
+
bpA.BrainParameters.NumStackedVectorObservations = 1;
|
| 62 |
+
bpA.ObservableAttributeHandling = observableAttributeOptions;
|
| 63 |
+
var agentA = goA.AddComponent<TestAgent>();
|
| 64 |
+
|
| 65 |
+
var goB = new GameObject("goB");
|
| 66 |
+
var bpB = goB.AddComponent<BehaviorParameters>();
|
| 67 |
+
bpB.BrainParameters.VectorObservationSize = 3;
|
| 68 |
+
bpB.BrainParameters.NumStackedVectorObservations = 1;
|
| 69 |
+
bpB.ObservableAttributeHandling = observableAttributeOptions;
|
| 70 |
+
var agentB = goB.AddComponent<TestAgent>();
|
| 71 |
+
|
| 72 |
+
var agents = new List<TestAgent> { agentA, agentB };
|
| 73 |
+
foreach (var agent in agents)
|
| 74 |
+
{
|
| 75 |
+
agent.LazyInitialize();
|
| 76 |
+
}
|
| 77 |
+
agentA.collectObservationsSensor.AddObservation(new Vector3(1, 2, 3));
|
| 78 |
+
agentB.collectObservationsSensor.AddObservation(new Vector3(4, 5, 6));
|
| 79 |
+
|
| 80 |
+
var infoA = new AgentInfo
|
| 81 |
+
{
|
| 82 |
+
storedActions = new ActionBuffers(null, new[] { 1, 2 }),
|
| 83 |
+
discreteActionMasks = null,
|
| 84 |
+
};
|
| 85 |
+
|
| 86 |
+
var infoB = new AgentInfo
|
| 87 |
+
{
|
| 88 |
+
storedActions = new ActionBuffers(null, new[] { 3, 4 }),
|
| 89 |
+
discreteActionMasks = new[] { true, false, false, false, false },
|
| 90 |
+
};
|
| 91 |
+
|
| 92 |
+
|
| 93 |
+
agentA._Info = infoA;
|
| 94 |
+
agentB._Info = infoB;
|
| 95 |
+
return agents;
|
| 96 |
+
}
|
| 97 |
+
|
| 98 |
+
[Test]
|
| 99 |
+
public void Construction()
|
| 100 |
+
{
|
| 101 |
+
var mem = new Dictionary<int, List<float>>();
|
| 102 |
+
var tensorGenerator = new TensorGenerator(0, mem);
|
| 103 |
+
Assert.IsNotNull(tensorGenerator);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
[Test]
|
| 107 |
+
public void GenerateBatchSize()
|
| 108 |
+
{
|
| 109 |
+
var inputTensor = new TensorProxy();
|
| 110 |
+
const int batchSize = 4;
|
| 111 |
+
var generator = new BatchSizeGenerator();
|
| 112 |
+
generator.Generate(inputTensor, batchSize, null);
|
| 113 |
+
Assert.IsNotNull(inputTensor.data);
|
| 114 |
+
Assert.AreEqual(((Tensor<int>)inputTensor.data)[0], batchSize);
|
| 115 |
+
}
|
| 116 |
+
|
| 117 |
+
[Test]
|
| 118 |
+
public void GenerateSequenceLength()
|
| 119 |
+
{
|
| 120 |
+
var inputTensor = new TensorProxy();
|
| 121 |
+
const int batchSize = 4;
|
| 122 |
+
var generator = new SequenceLengthGenerator();
|
| 123 |
+
generator.Generate(inputTensor, batchSize, null);
|
| 124 |
+
Assert.IsNotNull(inputTensor.data);
|
| 125 |
+
Assert.AreEqual(((Tensor<int>)inputTensor.data)[0], 1);
|
| 126 |
+
}
|
| 127 |
+
|
| 128 |
+
[Test]
|
| 129 |
+
public void GenerateVectorObservation()
|
| 130 |
+
{
|
| 131 |
+
var inputTensor = new TensorProxy
|
| 132 |
+
{
|
| 133 |
+
valueType = TensorProxy.TensorType.FloatingPoint,
|
| 134 |
+
shape = new int[] { 2, 4 }
|
| 135 |
+
};
|
| 136 |
+
const int batchSize = 4;
|
| 137 |
+
var agentInfos = GetFakeAgents(ObservableAttributeOptions.ExamineAll);
|
| 138 |
+
var generator = new ObservationGenerator();
|
| 139 |
+
generator.AddSensorIndex(0); // ObservableAttribute (size 1)
|
| 140 |
+
generator.AddSensorIndex(1); // TestSensor (size 0)
|
| 141 |
+
generator.AddSensorIndex(2); // TestSensor (size 0)
|
| 142 |
+
generator.AddSensorIndex(3); // VectorSensor (size 3)
|
| 143 |
+
var agent0 = agentInfos[0];
|
| 144 |
+
var agent1 = agentInfos[1];
|
| 145 |
+
var inputs = new List<AgentInfoSensorsPair>
|
| 146 |
+
{
|
| 147 |
+
new AgentInfoSensorsPair { agentInfo = agent0._Info, sensors = agent0.sensors },
|
| 148 |
+
new AgentInfoSensorsPair { agentInfo = agent1._Info, sensors = agent1.sensors },
|
| 149 |
+
};
|
| 150 |
+
generator.Generate(inputTensor, batchSize, inputs);
|
| 151 |
+
Assert.IsNotNull(inputTensor.data);
|
| 152 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[0, 1], 1);
|
| 153 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[0, 3], 3);
|
| 154 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[1, 1], 4);
|
| 155 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[1, 3], 6);
|
| 156 |
+
}
|
| 157 |
+
|
| 158 |
+
[Test]
|
| 159 |
+
public void GeneratePreviousActionInput()
|
| 160 |
+
{
|
| 161 |
+
var inputTensor = new TensorProxy
|
| 162 |
+
{
|
| 163 |
+
shape = new int[] { 2, 2 },
|
| 164 |
+
valueType = TensorProxy.TensorType.Integer
|
| 165 |
+
};
|
| 166 |
+
const int batchSize = 4;
|
| 167 |
+
var agentInfos = GetFakeAgents();
|
| 168 |
+
var generator = new PreviousActionInputGenerator();
|
| 169 |
+
var agent0 = agentInfos[0];
|
| 170 |
+
var agent1 = agentInfos[1];
|
| 171 |
+
var inputs = new List<AgentInfoSensorsPair>
|
| 172 |
+
{
|
| 173 |
+
new AgentInfoSensorsPair { agentInfo = agent0._Info, sensors = agent0.sensors },
|
| 174 |
+
new AgentInfoSensorsPair { agentInfo = agent1._Info, sensors = agent1.sensors },
|
| 175 |
+
};
|
| 176 |
+
generator.Generate(inputTensor, batchSize, inputs);
|
| 177 |
+
Assert.IsNotNull(inputTensor.data);
|
| 178 |
+
Assert.AreEqual(((Tensor<int>)inputTensor.data)[0, 0], 1);
|
| 179 |
+
Assert.AreEqual(((Tensor<int>)inputTensor.data)[0, 1], 2);
|
| 180 |
+
Assert.AreEqual(((Tensor<int>)inputTensor.data)[1, 0], 3);
|
| 181 |
+
Assert.AreEqual(((Tensor<int>)inputTensor.data)[1, 1], 4);
|
| 182 |
+
}
|
| 183 |
+
|
| 184 |
+
[Test]
|
| 185 |
+
public void GenerateActionMaskInput()
|
| 186 |
+
{
|
| 187 |
+
var inputTensor = new TensorProxy
|
| 188 |
+
{
|
| 189 |
+
shape = new int[] { 2, 5 },
|
| 190 |
+
valueType = TensorProxy.TensorType.FloatingPoint
|
| 191 |
+
};
|
| 192 |
+
const int batchSize = 4;
|
| 193 |
+
var agentInfos = GetFakeAgents();
|
| 194 |
+
var generator = new ActionMaskInputGenerator();
|
| 195 |
+
|
| 196 |
+
var agent0 = agentInfos[0];
|
| 197 |
+
var agent1 = agentInfos[1];
|
| 198 |
+
var inputs = new List<AgentInfoSensorsPair>
|
| 199 |
+
{
|
| 200 |
+
new AgentInfoSensorsPair { agentInfo = agent0._Info, sensors = agent0.sensors },
|
| 201 |
+
new AgentInfoSensorsPair { agentInfo = agent1._Info, sensors = agent1.sensors },
|
| 202 |
+
};
|
| 203 |
+
|
| 204 |
+
generator.Generate(inputTensor, batchSize, inputs);
|
| 205 |
+
Assert.IsNotNull(inputTensor.data);
|
| 206 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[0, 0], 1);
|
| 207 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[0, 4], 1);
|
| 208 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[1, 0], 0);
|
| 209 |
+
Assert.AreEqual((int)((Tensor<float>)inputTensor.data)[1, 4], 1);
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
[Test]
|
| 213 |
+
public void GenerateVectorObservation_CapacityGuardPreventsOverflow()
|
| 214 |
+
{
|
| 215 |
+
// Tensor can hold 3 floats, sensor0 fills it exactly (3),
|
| 216 |
+
// so the guard fires before sensor1 can write anything.
|
| 217 |
+
var inputTensor = new TensorProxy
|
| 218 |
+
{
|
| 219 |
+
valueType = TensorProxy.TensorType.FloatingPoint,
|
| 220 |
+
shape = new int[] { 1, 3 }
|
| 221 |
+
};
|
| 222 |
+
|
| 223 |
+
var sensor0 = new OverflowSensor("sensor0", 3);
|
| 224 |
+
var sensor1 = new OverflowSensor("sensor1", 3);
|
| 225 |
+
var sensors = new List<ISensor> { sensor0, sensor1 };
|
| 226 |
+
|
| 227 |
+
var generator = new ObservationGenerator();
|
| 228 |
+
generator.AddSensorIndex(0);
|
| 229 |
+
generator.AddSensorIndex(1);
|
| 230 |
+
|
| 231 |
+
var inputs = new List<AgentInfoSensorsPair>
|
| 232 |
+
{
|
| 233 |
+
new AgentInfoSensorsPair
|
| 234 |
+
{
|
| 235 |
+
agentInfo = new AgentInfo { done = false },
|
| 236 |
+
sensors = sensors
|
| 237 |
+
}
|
| 238 |
+
};
|
| 239 |
+
|
| 240 |
+
LogAssert.Expect(LogType.Warning, new System.Text.RegularExpressions.Regex("Sensor write overflow"));
|
| 241 |
+
generator.Generate(inputTensor, 1, inputs);
|
| 242 |
+
|
| 243 |
+
// First sensor's 3 writes land, second sensor is skipped by capacity guard
|
| 244 |
+
Assert.AreEqual(1f, ((Tensor<float>)inputTensor.data)[0, 0]);
|
| 245 |
+
Assert.AreEqual(2f, ((Tensor<float>)inputTensor.data)[0, 1]);
|
| 246 |
+
Assert.AreEqual(3f, ((Tensor<float>)inputTensor.data)[0, 2]);
|
| 247 |
+
}
|
| 248 |
+
|
| 249 |
+
[Test]
|
| 250 |
+
public void GenerateVectorObservation_SingleSensorOverflowIsClamped()
|
| 251 |
+
{
|
| 252 |
+
// Tensor can hold 2 floats, but sensor writes 5
|
| 253 |
+
var inputTensor = new TensorProxy
|
| 254 |
+
{
|
| 255 |
+
valueType = TensorProxy.TensorType.FloatingPoint,
|
| 256 |
+
shape = new int[] { 1, 2 }
|
| 257 |
+
};
|
| 258 |
+
|
| 259 |
+
var sensor = new OverflowSensor("big_sensor", 5);
|
| 260 |
+
var sensors = new List<ISensor> { sensor };
|
| 261 |
+
|
| 262 |
+
var generator = new ObservationGenerator();
|
| 263 |
+
generator.AddSensorIndex(0);
|
| 264 |
+
|
| 265 |
+
var inputs = new List<AgentInfoSensorsPair>
|
| 266 |
+
{
|
| 267 |
+
new AgentInfoSensorsPair
|
| 268 |
+
{
|
| 269 |
+
agentInfo = new AgentInfo { done = false },
|
| 270 |
+
sensors = sensors
|
| 271 |
+
}
|
| 272 |
+
};
|
| 273 |
+
|
| 274 |
+
// No crash — ObservationWriter bounds cap prevents the buffer overrun
|
| 275 |
+
generator.Generate(inputTensor, 1, inputs);
|
| 276 |
+
|
| 277 |
+
Assert.AreEqual(1f, ((Tensor<float>)inputTensor.data)[0, 0]);
|
| 278 |
+
Assert.AreEqual(2f, ((Tensor<float>)inputTensor.data)[0, 1]);
|
| 279 |
+
}
|
| 280 |
+
|
| 281 |
+
[Test]
|
| 282 |
+
public void GenerateVectorObservation_ExactFitNoWarning()
|
| 283 |
+
{
|
| 284 |
+
// Tensor exactly fits the sensor output — no warning should fire
|
| 285 |
+
var inputTensor = new TensorProxy
|
| 286 |
+
{
|
| 287 |
+
valueType = TensorProxy.TensorType.FloatingPoint,
|
| 288 |
+
shape = new int[] { 1, 3 }
|
| 289 |
+
};
|
| 290 |
+
|
| 291 |
+
var sensor = new OverflowSensor("exact_sensor", 3);
|
| 292 |
+
var sensors = new List<ISensor> { sensor };
|
| 293 |
+
|
| 294 |
+
var generator = new ObservationGenerator();
|
| 295 |
+
generator.AddSensorIndex(0);
|
| 296 |
+
|
| 297 |
+
var inputs = new List<AgentInfoSensorsPair>
|
| 298 |
+
{
|
| 299 |
+
new AgentInfoSensorsPair
|
| 300 |
+
{
|
| 301 |
+
agentInfo = new AgentInfo { done = false },
|
| 302 |
+
sensors = sensors
|
| 303 |
+
}
|
| 304 |
+
};
|
| 305 |
+
|
| 306 |
+
generator.Generate(inputTensor, 1, inputs);
|
| 307 |
+
|
| 308 |
+
Assert.AreEqual(1f, ((Tensor<float>)inputTensor.data)[0, 0]);
|
| 309 |
+
Assert.AreEqual(2f, ((Tensor<float>)inputTensor.data)[0, 1]);
|
| 310 |
+
Assert.AreEqual(3f, ((Tensor<float>)inputTensor.data)[0, 2]);
|
| 311 |
+
}
|
| 312 |
+
}
|
| 313 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Inference/EditModeTestInternalBrainTensorGenerator.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Inference/ModelRunnerTest.cs
ADDED
|
@@ -0,0 +1,240 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using System.Linq;
|
| 3 |
+
using NUnit.Framework;
|
| 4 |
+
using UnityEngine;
|
| 5 |
+
using UnityEditor;
|
| 6 |
+
using Unity.InferenceEngine;
|
| 7 |
+
using Unity.MLAgents.Actuators;
|
| 8 |
+
using Unity.MLAgents.Inference;
|
| 9 |
+
using Unity.MLAgents.Policies;
|
| 10 |
+
using System.Collections.Generic;
|
| 11 |
+
|
| 12 |
+
namespace Unity.MLAgents.Tests
|
| 13 |
+
{
|
| 14 |
+
public class FloatThresholdComparer : IEqualityComparer<float>
|
| 15 |
+
{
|
| 16 |
+
private readonly float _threshold;
|
| 17 |
+
public FloatThresholdComparer(float threshold)
|
| 18 |
+
{
|
| 19 |
+
_threshold = threshold;
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
public bool Equals(float x, float y)
|
| 23 |
+
{
|
| 24 |
+
return Math.Abs(x - y) < _threshold;
|
| 25 |
+
}
|
| 26 |
+
|
| 27 |
+
public int GetHashCode(float f)
|
| 28 |
+
{
|
| 29 |
+
throw new NotImplementedException("Unable to generate a hash code for threshold floats, do not use this method");
|
| 30 |
+
}
|
| 31 |
+
}
|
| 32 |
+
|
| 33 |
+
[TestFixture]
|
| 34 |
+
public class ModelRunnerTest
|
| 35 |
+
{
|
| 36 |
+
const string k_hybrid_ONNX_recurr_v2 = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/hybrid0vis8vec_2c_2_3d_v2_0.onnx";
|
| 37 |
+
|
| 38 |
+
const string k_continuousONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/continuous2vis8vec2action_v1_0.onnx";
|
| 39 |
+
const string k_discreteONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/discrete1vis0vec_2_3action_obsolete_recurr_v1_0.onnx";
|
| 40 |
+
const string k_hybridONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/hybrid0vis53vec_3c_2daction_v1_0.onnx";
|
| 41 |
+
// const string k_continuousNNPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/continuous2vis8vec2action_deprecated_v1_0.nn";
|
| 42 |
+
// const string k_discreteNNPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/discrete1vis0vec_2_3action_recurr_deprecated_v1_0.nn";
|
| 43 |
+
// models with deterministic action tensors
|
| 44 |
+
private const string k_deterministic_discreteNNPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/deterDiscrete1obs3action_v2_0.onnx";
|
| 45 |
+
private const string k_deterministic_continuousNNPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/deterContinuous2vis8vec2action_v2_0.onnx";
|
| 46 |
+
|
| 47 |
+
ModelAsset hybridONNXModelV2;
|
| 48 |
+
ModelAsset continuousONNXModel;
|
| 49 |
+
ModelAsset discreteONNXModel;
|
| 50 |
+
ModelAsset hybridONNXModel;
|
| 51 |
+
// Model continuousNNModel;
|
| 52 |
+
// Model discreteNNModel;
|
| 53 |
+
ModelAsset deterministicDiscreteNNModel;
|
| 54 |
+
ModelAsset deterministicContinuousNNModel;
|
| 55 |
+
Test3DSensorComponent sensor_21_20_3;
|
| 56 |
+
Test3DSensorComponent sensor_20_22_3;
|
| 57 |
+
|
| 58 |
+
|
| 59 |
+
ActionSpec GetContinuous2vis8vec2actionActionSpec()
|
| 60 |
+
{
|
| 61 |
+
return ActionSpec.MakeContinuous(2);
|
| 62 |
+
}
|
| 63 |
+
|
| 64 |
+
ActionSpec GetDiscrete1vis0vec_2_3action_recurrModelActionSpec()
|
| 65 |
+
{
|
| 66 |
+
return ActionSpec.MakeDiscrete(2, 3);
|
| 67 |
+
}
|
| 68 |
+
|
| 69 |
+
ActionSpec GetHybrid0vis53vec_3c_2dActionSpec()
|
| 70 |
+
{
|
| 71 |
+
return new ActionSpec(3, new[] { 2 });
|
| 72 |
+
}
|
| 73 |
+
|
| 74 |
+
[SetUp]
|
| 75 |
+
public void SetUp()
|
| 76 |
+
{
|
| 77 |
+
hybridONNXModelV2 = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_hybrid_ONNX_recurr_v2, typeof(ModelAsset));
|
| 78 |
+
|
| 79 |
+
continuousONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_continuousONNXPath, typeof(ModelAsset));
|
| 80 |
+
discreteONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_discreteONNXPath, typeof(ModelAsset));
|
| 81 |
+
hybridONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_hybridONNXPath, typeof(ModelAsset));
|
| 82 |
+
// continuousNNModel = (Model)AssetDatabase.LoadAssetAtPath(k_continuousNNPath, typeof(NNModel));
|
| 83 |
+
// discreteNNModel = (Model)AssetDatabase.LoadAssetAtPath(k_discreteNNPath, typeof(NNModel));
|
| 84 |
+
deterministicDiscreteNNModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_deterministic_discreteNNPath, typeof(ModelAsset));
|
| 85 |
+
deterministicContinuousNNModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_deterministic_continuousNNPath, typeof(ModelAsset));
|
| 86 |
+
var go = new GameObject("SensorA");
|
| 87 |
+
sensor_21_20_3 = go.AddComponent<Test3DSensorComponent>();
|
| 88 |
+
sensor_21_20_3.Sensor = new Test3DSensor("SensorA", 21, 20, 3);
|
| 89 |
+
sensor_20_22_3 = go.AddComponent<Test3DSensorComponent>();
|
| 90 |
+
sensor_20_22_3.Sensor = new Test3DSensor("SensorB", 20, 22, 3);
|
| 91 |
+
}
|
| 92 |
+
|
| 93 |
+
[Test]
|
| 94 |
+
public void TestModelExist()
|
| 95 |
+
{
|
| 96 |
+
Assert.IsNotNull(continuousONNXModel);
|
| 97 |
+
Assert.IsNotNull(discreteONNXModel);
|
| 98 |
+
Assert.IsNotNull(hybridONNXModel);
|
| 99 |
+
// Assert.IsNotNull(continuousNNModel);
|
| 100 |
+
// Assert.IsNotNull(discreteNNModel);
|
| 101 |
+
Assert.IsNotNull(hybridONNXModelV2);
|
| 102 |
+
Assert.IsNotNull(deterministicDiscreteNNModel);
|
| 103 |
+
Assert.IsNotNull(deterministicContinuousNNModel);
|
| 104 |
+
}
|
| 105 |
+
|
| 106 |
+
[Test]
|
| 107 |
+
public void TestCreation()
|
| 108 |
+
{
|
| 109 |
+
var inferenceDevice = InferenceDevice.Burst;
|
| 110 |
+
var modelRunner = new ModelRunner(continuousONNXModel, GetContinuous2vis8vec2actionActionSpec(), inferenceDevice);
|
| 111 |
+
modelRunner.Dispose();
|
| 112 |
+
Assert.Throws<UnityAgentsException>(() =>
|
| 113 |
+
{
|
| 114 |
+
// Cannot load a model trained with 1.x that has an LSTM
|
| 115 |
+
modelRunner = new ModelRunner(discreteONNXModel, GetDiscrete1vis0vec_2_3action_recurrModelActionSpec(), inferenceDevice);
|
| 116 |
+
modelRunner.Dispose();
|
| 117 |
+
});
|
| 118 |
+
modelRunner = new ModelRunner(hybridONNXModel, GetHybrid0vis53vec_3c_2dActionSpec(), inferenceDevice);
|
| 119 |
+
modelRunner.Dispose();
|
| 120 |
+
// modelRunner = new ModelRunner(continuousNNModel, GetContinuous2vis8vec2actionActionSpec(), inferenceDevice);
|
| 121 |
+
// modelRunner.Dispose();
|
| 122 |
+
|
| 123 |
+
// Assert.Throws<UnityAgentsException>(() =>
|
| 124 |
+
// {
|
| 125 |
+
// Cannot load a model trained with 1.x that has an LSTM
|
| 126 |
+
// modelRunner = new ModelRunner(discreteNNModel, GetDiscrete1vis0vec_2_3action_recurrModelActionSpec(), inferenceDevice);
|
| 127 |
+
// modelRunner.Dispose();
|
| 128 |
+
// });
|
| 129 |
+
// This one was trained with 2.0 so it should not raise an error:
|
| 130 |
+
modelRunner = new ModelRunner(hybridONNXModelV2, new ActionSpec(2, new[] { 2, 3 }), inferenceDevice);
|
| 131 |
+
modelRunner.Dispose();
|
| 132 |
+
|
| 133 |
+
// V2.0 Model that has serialized deterministic action tensors, discrete
|
| 134 |
+
modelRunner = new ModelRunner(deterministicDiscreteNNModel, new ActionSpec(0, new[] { 7 }), inferenceDevice);
|
| 135 |
+
modelRunner.Dispose();
|
| 136 |
+
// V2.0 Model that has serialized deterministic action tensors, continuous
|
| 137 |
+
modelRunner = new ModelRunner(deterministicContinuousNNModel,
|
| 138 |
+
GetContinuous2vis8vec2actionActionSpec(), inferenceDevice,
|
| 139 |
+
deterministicInference: true);
|
| 140 |
+
modelRunner.Dispose();
|
| 141 |
+
}
|
| 142 |
+
|
| 143 |
+
[Test]
|
| 144 |
+
public void TestHasModel()
|
| 145 |
+
{
|
| 146 |
+
var modelRunner = new ModelRunner(continuousONNXModel, GetContinuous2vis8vec2actionActionSpec(), InferenceDevice.Burst);
|
| 147 |
+
Assert.True(modelRunner.HasModel(continuousONNXModel, InferenceDevice.Burst));
|
| 148 |
+
Assert.False(modelRunner.HasModel(continuousONNXModel, InferenceDevice.ComputeShader));
|
| 149 |
+
Assert.False(modelRunner.HasModel(discreteONNXModel, InferenceDevice.Burst));
|
| 150 |
+
modelRunner.Dispose();
|
| 151 |
+
}
|
| 152 |
+
|
| 153 |
+
[Test]
|
| 154 |
+
public void TestRunModel()
|
| 155 |
+
{
|
| 156 |
+
var actionSpec = GetContinuous2vis8vec2actionActionSpec();
|
| 157 |
+
var modelRunner = new ModelRunner(continuousONNXModel, actionSpec, InferenceDevice.Burst);
|
| 158 |
+
var sensor_8 = new Sensors.VectorSensor(8, "VectorSensor8");
|
| 159 |
+
var info1 = new AgentInfo();
|
| 160 |
+
info1.episodeId = 1;
|
| 161 |
+
modelRunner.PutObservations(info1, new[]
|
| 162 |
+
{
|
| 163 |
+
sensor_8,
|
| 164 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 165 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 166 |
+
}.ToList());
|
| 167 |
+
var info2 = new AgentInfo();
|
| 168 |
+
info2.episodeId = 2;
|
| 169 |
+
modelRunner.PutObservations(info2, new[]
|
| 170 |
+
{
|
| 171 |
+
sensor_8,
|
| 172 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 173 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 174 |
+
}.ToList());
|
| 175 |
+
|
| 176 |
+
modelRunner.DecideBatch();
|
| 177 |
+
|
| 178 |
+
Assert.IsFalse(modelRunner.GetAction(1).Equals(ActionBuffers.Empty));
|
| 179 |
+
Assert.IsFalse(modelRunner.GetAction(2).Equals(ActionBuffers.Empty));
|
| 180 |
+
Assert.IsTrue(modelRunner.GetAction(3).Equals(ActionBuffers.Empty));
|
| 181 |
+
Assert.AreEqual(actionSpec.NumDiscreteActions, modelRunner.GetAction(1).DiscreteActions.Length);
|
| 182 |
+
modelRunner.Dispose();
|
| 183 |
+
}
|
| 184 |
+
|
| 185 |
+
[Test]
|
| 186 |
+
public void TestRunModel_stochastic()
|
| 187 |
+
{
|
| 188 |
+
var actionSpec = GetContinuous2vis8vec2actionActionSpec();
|
| 189 |
+
// deterministicInference = false by default
|
| 190 |
+
var modelRunner = new ModelRunner(deterministicContinuousNNModel, actionSpec, InferenceDevice.Burst);
|
| 191 |
+
var sensor_8 = new Sensors.VectorSensor(8, "VectorSensor8");
|
| 192 |
+
var info1 = new AgentInfo();
|
| 193 |
+
var obs = new[]
|
| 194 |
+
{
|
| 195 |
+
sensor_8,
|
| 196 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 197 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 198 |
+
}.ToList();
|
| 199 |
+
info1.episodeId = 1;
|
| 200 |
+
modelRunner.PutObservations(info1, obs);
|
| 201 |
+
modelRunner.DecideBatch();
|
| 202 |
+
var stochAction1 = (float[])modelRunner.GetAction(1).ContinuousActions.Array.Clone();
|
| 203 |
+
|
| 204 |
+
modelRunner.PutObservations(info1, obs);
|
| 205 |
+
modelRunner.DecideBatch();
|
| 206 |
+
var stochAction2 = (float[])modelRunner.GetAction(1).ContinuousActions.Array.Clone();
|
| 207 |
+
// Stochastic action selection should output randomly different action values with same obs
|
| 208 |
+
Assert.IsFalse(Enumerable.SequenceEqual(stochAction1, stochAction2, new FloatThresholdComparer(0.001f)));
|
| 209 |
+
modelRunner.Dispose();
|
| 210 |
+
}
|
| 211 |
+
|
| 212 |
+
[Test]
|
| 213 |
+
public void TestRunModel_deterministic()
|
| 214 |
+
{
|
| 215 |
+
var actionSpec = GetContinuous2vis8vec2actionActionSpec();
|
| 216 |
+
var modelRunner = new ModelRunner(deterministicContinuousNNModel, actionSpec, InferenceDevice.Burst);
|
| 217 |
+
var sensor_8 = new Sensors.VectorSensor(8, "VectorSensor8");
|
| 218 |
+
var info1 = new AgentInfo();
|
| 219 |
+
var obs = new[]
|
| 220 |
+
{
|
| 221 |
+
sensor_8,
|
| 222 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 223 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 224 |
+
}.ToList();
|
| 225 |
+
var deterministicModelRunner = new ModelRunner(deterministicContinuousNNModel, actionSpec, InferenceDevice.Burst,
|
| 226 |
+
deterministicInference: true);
|
| 227 |
+
info1.episodeId = 1;
|
| 228 |
+
deterministicModelRunner.PutObservations(info1, obs);
|
| 229 |
+
deterministicModelRunner.DecideBatch();
|
| 230 |
+
var deterministicAction1 = (float[])deterministicModelRunner.GetAction(1).ContinuousActions.Array.Clone();
|
| 231 |
+
|
| 232 |
+
deterministicModelRunner.PutObservations(info1, obs);
|
| 233 |
+
deterministicModelRunner.DecideBatch();
|
| 234 |
+
var deterministicAction2 = (float[])deterministicModelRunner.GetAction(1).ContinuousActions.Array.Clone();
|
| 235 |
+
// Deterministic action selection should output same action everytime
|
| 236 |
+
Assert.IsTrue(Enumerable.SequenceEqual(deterministicAction1, deterministicAction2, new FloatThresholdComparer(0.001f)));
|
| 237 |
+
modelRunner.Dispose();
|
| 238 |
+
}
|
| 239 |
+
}
|
| 240 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Inference/ModelRunnerTest.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Inference/ParameterLoaderTest.cs
ADDED
|
@@ -0,0 +1,542 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System.Linq;
|
| 2 |
+
using NUnit.Framework;
|
| 3 |
+
using UnityEngine;
|
| 4 |
+
using UnityEditor;
|
| 5 |
+
using Unity.InferenceEngine;
|
| 6 |
+
using Unity.MLAgents.Actuators;
|
| 7 |
+
using Unity.MLAgents.Inference;
|
| 8 |
+
using Unity.MLAgents.Sensors;
|
| 9 |
+
using Unity.MLAgents.Policies;
|
| 10 |
+
|
| 11 |
+
namespace Unity.MLAgents.Tests
|
| 12 |
+
{
|
| 13 |
+
public class Test3DSensorComponent : SensorComponent
|
| 14 |
+
{
|
| 15 |
+
public ISensor Sensor;
|
| 16 |
+
|
| 17 |
+
public override ISensor[] CreateSensors()
|
| 18 |
+
{
|
| 19 |
+
return new ISensor[] { Sensor };
|
| 20 |
+
}
|
| 21 |
+
}
|
| 22 |
+
|
| 23 |
+
public class Test3DSensor : ISensor, IBuiltInSensor
|
| 24 |
+
{
|
| 25 |
+
int m_Width;
|
| 26 |
+
int m_Height;
|
| 27 |
+
int m_Channels;
|
| 28 |
+
string m_Name;
|
| 29 |
+
// Dummy value for the IBuiltInSensor interface
|
| 30 |
+
public const int k_BuiltInSensorType = -42;
|
| 31 |
+
|
| 32 |
+
public Test3DSensor(string name, int width, int height, int channels)
|
| 33 |
+
{
|
| 34 |
+
m_Width = width;
|
| 35 |
+
m_Height = height;
|
| 36 |
+
m_Channels = channels;
|
| 37 |
+
m_Name = name;
|
| 38 |
+
}
|
| 39 |
+
|
| 40 |
+
public ObservationSpec GetObservationSpec()
|
| 41 |
+
{
|
| 42 |
+
return ObservationSpec.Visual(m_Channels, m_Height, m_Width);
|
| 43 |
+
}
|
| 44 |
+
|
| 45 |
+
public int Write(ObservationWriter writer)
|
| 46 |
+
{
|
| 47 |
+
for (int i = 0; i < m_Width * m_Height * m_Channels; i++)
|
| 48 |
+
{
|
| 49 |
+
writer[i] = 0.0f;
|
| 50 |
+
}
|
| 51 |
+
return m_Width * m_Height * m_Channels;
|
| 52 |
+
}
|
| 53 |
+
|
| 54 |
+
public byte[] GetCompressedObservation()
|
| 55 |
+
{
|
| 56 |
+
return new byte[0];
|
| 57 |
+
}
|
| 58 |
+
|
| 59 |
+
public void Update() { }
|
| 60 |
+
public void Reset() { }
|
| 61 |
+
|
| 62 |
+
public CompressionSpec GetCompressionSpec()
|
| 63 |
+
{
|
| 64 |
+
return CompressionSpec.Default();
|
| 65 |
+
}
|
| 66 |
+
|
| 67 |
+
public string GetName()
|
| 68 |
+
{
|
| 69 |
+
return m_Name;
|
| 70 |
+
}
|
| 71 |
+
|
| 72 |
+
public BuiltInSensorType GetBuiltInSensorType()
|
| 73 |
+
{
|
| 74 |
+
return (BuiltInSensorType)k_BuiltInSensorType;
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
[TestFixture]
|
| 79 |
+
public class ParameterLoaderTest
|
| 80 |
+
{
|
| 81 |
+
const string k_discrete_ONNX_v2 = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/discrete_rank2_vector_v2_0.onnx";
|
| 82 |
+
const string k_hybrid_ONNX_recurr_v2 = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/hybrid0vis8vec_2c_2_3d_v2_0.onnx";
|
| 83 |
+
|
| 84 |
+
|
| 85 |
+
// ONNX model with continuous/discrete action output (support hybrid action)
|
| 86 |
+
const string k_continuousONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/continuous2vis8vec2action_v1_0.onnx";
|
| 87 |
+
const string k_discreteONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/discrete1vis0vec_2_3action_obsolete_recurr_v1_0.onnx";
|
| 88 |
+
const string k_hybridONNXPath = "Packages/com.unity.ml-agents.tests/Tests/Editor/TestModels/hybrid0vis53vec_3c_2daction_v1_0.onnx";
|
| 89 |
+
// NN model with single action output (deprecated, does not support hybrid action).
|
| 90 |
+
// Same BrainParameters settings as the corresponding ONNX model.
|
| 91 |
+
|
| 92 |
+
ModelAsset rank2ONNXModel;
|
| 93 |
+
ModelAsset hybridRecurrV2Model;
|
| 94 |
+
ModelAsset continuousONNXModel;
|
| 95 |
+
ModelAsset discreteONNXModel;
|
| 96 |
+
ModelAsset hybridONNXModel;
|
| 97 |
+
Test3DSensorComponent sensor_21_20_3;
|
| 98 |
+
Test3DSensorComponent sensor_20_22_3;
|
| 99 |
+
BufferSensor sensor_23_20;
|
| 100 |
+
VectorSensor sensor_8;
|
| 101 |
+
VectorSensor sensor_10;
|
| 102 |
+
|
| 103 |
+
BrainParameters GetContinuous2vis8vec2actionBrainParameters()
|
| 104 |
+
{
|
| 105 |
+
var validBrainParameters = new BrainParameters();
|
| 106 |
+
validBrainParameters.VectorObservationSize = 8;
|
| 107 |
+
validBrainParameters.NumStackedVectorObservations = 1;
|
| 108 |
+
validBrainParameters.ActionSpec = ActionSpec.MakeContinuous(2);
|
| 109 |
+
return validBrainParameters;
|
| 110 |
+
}
|
| 111 |
+
|
| 112 |
+
BrainParameters GetDiscrete1vis0vec_2_3action_recurrModelBrainParameters()
|
| 113 |
+
{
|
| 114 |
+
var validBrainParameters = new BrainParameters();
|
| 115 |
+
validBrainParameters.VectorObservationSize = 0;
|
| 116 |
+
validBrainParameters.NumStackedVectorObservations = 1;
|
| 117 |
+
validBrainParameters.ActionSpec = ActionSpec.MakeDiscrete(2, 3);
|
| 118 |
+
return validBrainParameters;
|
| 119 |
+
}
|
| 120 |
+
|
| 121 |
+
BrainParameters GetHybridBrainParameters()
|
| 122 |
+
{
|
| 123 |
+
var validBrainParameters = new BrainParameters();
|
| 124 |
+
validBrainParameters.VectorObservationSize = 53;
|
| 125 |
+
validBrainParameters.NumStackedVectorObservations = 1;
|
| 126 |
+
validBrainParameters.ActionSpec = new ActionSpec(3, new[] { 2 });
|
| 127 |
+
return validBrainParameters;
|
| 128 |
+
}
|
| 129 |
+
|
| 130 |
+
BrainParameters GetRank2BrainParameters()
|
| 131 |
+
{
|
| 132 |
+
var validBrainParameters = new BrainParameters();
|
| 133 |
+
validBrainParameters.VectorObservationSize = 4;
|
| 134 |
+
validBrainParameters.NumStackedVectorObservations = 2;
|
| 135 |
+
validBrainParameters.ActionSpec = ActionSpec.MakeDiscrete(3, 3, 3);
|
| 136 |
+
return validBrainParameters;
|
| 137 |
+
}
|
| 138 |
+
|
| 139 |
+
BrainParameters GetRecurrHybridBrainParameters()
|
| 140 |
+
{
|
| 141 |
+
var validBrainParameters = new BrainParameters();
|
| 142 |
+
validBrainParameters.VectorObservationSize = 8;
|
| 143 |
+
validBrainParameters.NumStackedVectorObservations = 1;
|
| 144 |
+
validBrainParameters.ActionSpec = new ActionSpec(2, new int[] { 2, 3 });
|
| 145 |
+
return validBrainParameters;
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
[SetUp]
|
| 149 |
+
public void SetUp()
|
| 150 |
+
{
|
| 151 |
+
continuousONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_continuousONNXPath, typeof(ModelAsset));
|
| 152 |
+
discreteONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_discreteONNXPath, typeof(ModelAsset));
|
| 153 |
+
hybridONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_hybridONNXPath, typeof(ModelAsset));
|
| 154 |
+
rank2ONNXModel = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_discrete_ONNX_v2, typeof(ModelAsset));
|
| 155 |
+
hybridRecurrV2Model = (ModelAsset)AssetDatabase.LoadAssetAtPath(k_hybrid_ONNX_recurr_v2, typeof(ModelAsset));
|
| 156 |
+
var go = new GameObject("SensorA");
|
| 157 |
+
sensor_21_20_3 = go.AddComponent<Test3DSensorComponent>();
|
| 158 |
+
sensor_21_20_3.Sensor = new Test3DSensor("SensorA", 21, 20, 3);
|
| 159 |
+
sensor_20_22_3 = go.AddComponent<Test3DSensorComponent>();
|
| 160 |
+
sensor_20_22_3.Sensor = new Test3DSensor("SensorA", 20, 22, 3);
|
| 161 |
+
sensor_23_20 = new BufferSensor(20, 23, "BufferSensor");
|
| 162 |
+
sensor_8 = new VectorSensor(8, "VectorSensor8");
|
| 163 |
+
sensor_10 = new VectorSensor(10, "VectorSensor10");
|
| 164 |
+
}
|
| 165 |
+
|
| 166 |
+
[Test]
|
| 167 |
+
public void TestModelExist()
|
| 168 |
+
{
|
| 169 |
+
Assert.IsNotNull(continuousONNXModel);
|
| 170 |
+
Assert.IsNotNull(discreteONNXModel);
|
| 171 |
+
Assert.IsNotNull(hybridONNXModel);
|
| 172 |
+
Assert.IsNotNull(rank2ONNXModel);
|
| 173 |
+
Assert.IsNotNull(hybridRecurrV2Model);
|
| 174 |
+
}
|
| 175 |
+
|
| 176 |
+
[Test]
|
| 177 |
+
public void TestGetInputTensorsContinuous()
|
| 178 |
+
{
|
| 179 |
+
var model = ModelLoader.Load(continuousONNXModel);
|
| 180 |
+
var modelInfo = new SentisModelInfo(model);
|
| 181 |
+
var inputNames = modelInfo.InputNames;
|
| 182 |
+
// Model should contain 3 inputs : vector, visual 1 and visual 2
|
| 183 |
+
Assert.AreEqual(3, inputNames.Count());
|
| 184 |
+
Assert.Contains(TensorNames.VectorObservationPlaceholder, inputNames);
|
| 185 |
+
Assert.Contains(TensorNames.VisualObservationPlaceholderPrefix + "0", inputNames);
|
| 186 |
+
Assert.Contains(TensorNames.VisualObservationPlaceholderPrefix + "1", inputNames);
|
| 187 |
+
|
| 188 |
+
Assert.AreEqual(2, modelInfo.NumVisualInputs);
|
| 189 |
+
|
| 190 |
+
modelInfo.Dispose();
|
| 191 |
+
}
|
| 192 |
+
|
| 193 |
+
public void TestGetInputTensorsDiscrete()
|
| 194 |
+
{
|
| 195 |
+
var model = ModelLoader.Load(discreteONNXModel);
|
| 196 |
+
var modelInfo = new SentisModelInfo(model);
|
| 197 |
+
var inputNames = modelInfo.InputNames;
|
| 198 |
+
// Model should contain 2 inputs : recurrent and visual 1
|
| 199 |
+
|
| 200 |
+
Assert.Contains(TensorNames.VisualObservationPlaceholderPrefix + "0", inputNames);
|
| 201 |
+
// TODO :There are some memory tensors as well
|
| 202 |
+
modelInfo.Dispose();
|
| 203 |
+
}
|
| 204 |
+
|
| 205 |
+
[Test]
|
| 206 |
+
public void TestGetInputTensorsHybrid()
|
| 207 |
+
{
|
| 208 |
+
var model = ModelLoader.Load(hybridONNXModel);
|
| 209 |
+
var modelInfo = new SentisModelInfo(model);
|
| 210 |
+
var inputNames = modelInfo.InputNames;
|
| 211 |
+
Assert.Contains(TensorNames.VectorObservationPlaceholder, inputNames);
|
| 212 |
+
modelInfo.Dispose();
|
| 213 |
+
}
|
| 214 |
+
|
| 215 |
+
[Test]
|
| 216 |
+
public void TestGetOutputTensorsContinuous()
|
| 217 |
+
{
|
| 218 |
+
var model = ModelLoader.Load(continuousONNXModel);
|
| 219 |
+
var modelInfo = new SentisModelInfo(model);
|
| 220 |
+
var outputNames = modelInfo.OutputNames;
|
| 221 |
+
var actionOutputName = TensorNames.ContinuousActionOutput;
|
| 222 |
+
Assert.Contains(actionOutputName, outputNames);
|
| 223 |
+
Assert.AreEqual(1, outputNames.Count());
|
| 224 |
+
modelInfo.Dispose();
|
| 225 |
+
}
|
| 226 |
+
|
| 227 |
+
[Test]
|
| 228 |
+
public void TestGetOutputTensorsDiscrete()
|
| 229 |
+
{
|
| 230 |
+
var model = ModelLoader.Load(discreteONNXModel);
|
| 231 |
+
var modelInfo = new SentisModelInfo(model);
|
| 232 |
+
var outputNames = modelInfo.OutputNames;
|
| 233 |
+
var actionOutputName = TensorNames.DiscreteActionOutput;
|
| 234 |
+
Assert.Contains(actionOutputName, outputNames);
|
| 235 |
+
// TODO : There are some memory tensors as well
|
| 236 |
+
modelInfo.Dispose();
|
| 237 |
+
}
|
| 238 |
+
|
| 239 |
+
[Test]
|
| 240 |
+
public void TestGetOutputTensorsHybrid()
|
| 241 |
+
{
|
| 242 |
+
var model = ModelLoader.Load(hybridONNXModel);
|
| 243 |
+
var modelInfo = new SentisModelInfo(model);
|
| 244 |
+
var outputNames = modelInfo.OutputNames;
|
| 245 |
+
|
| 246 |
+
Assert.AreEqual(2, outputNames.Count());
|
| 247 |
+
Assert.Contains(TensorNames.ContinuousActionOutput, outputNames);
|
| 248 |
+
Assert.Contains(TensorNames.DiscreteActionOutput, outputNames);
|
| 249 |
+
|
| 250 |
+
modelInfo.Dispose();
|
| 251 |
+
}
|
| 252 |
+
|
| 253 |
+
[Test]
|
| 254 |
+
public void TestCheckModelRank2()
|
| 255 |
+
{
|
| 256 |
+
var model = ModelLoader.Load(rank2ONNXModel);
|
| 257 |
+
var validBrainParameters = GetRank2BrainParameters();
|
| 258 |
+
|
| 259 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 260 |
+
model, validBrainParameters,
|
| 261 |
+
new ISensor[] { sensor_23_20, sensor_10, sensor_8 }, new ActuatorComponent[0]
|
| 262 |
+
);
|
| 263 |
+
Assert.AreEqual(0, errors.Count()); // There should not be any errors
|
| 264 |
+
|
| 265 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 266 |
+
model, validBrainParameters,
|
| 267 |
+
new ISensor[] { sensor_23_20, sensor_10 }, new ActuatorComponent[0]
|
| 268 |
+
);
|
| 269 |
+
Assert.AreNotEqual(0, errors.Count()); // Wrong number of sensors
|
| 270 |
+
|
| 271 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 272 |
+
model, validBrainParameters,
|
| 273 |
+
new ISensor[] { new BufferSensor(20, 40, "BufferSensor"), sensor_10, sensor_8 }, new ActuatorComponent[0]
|
| 274 |
+
);
|
| 275 |
+
Assert.AreNotEqual(0, errors.Count()); // Wrong buffer sensor size
|
| 276 |
+
|
| 277 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 278 |
+
model, validBrainParameters,
|
| 279 |
+
new ISensor[] { sensor_23_20, sensor_10, sensor_10 }, new ActuatorComponent[0]
|
| 280 |
+
);
|
| 281 |
+
Assert.AreNotEqual(0, errors.Count()); // Wrong vector sensor size
|
| 282 |
+
}
|
| 283 |
+
|
| 284 |
+
[Test]
|
| 285 |
+
public void TestCheckModelValidContinuous()
|
| 286 |
+
{
|
| 287 |
+
var model = ModelLoader.Load(continuousONNXModel);
|
| 288 |
+
var validBrainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 289 |
+
|
| 290 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 291 |
+
model, validBrainParameters,
|
| 292 |
+
new ISensor[]
|
| 293 |
+
{
|
| 294 |
+
new VectorSensor(8),
|
| 295 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 296 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 297 |
+
},
|
| 298 |
+
new ActuatorComponent[0]
|
| 299 |
+
);
|
| 300 |
+
Assert.AreEqual(0, errors.Count()); // There should not be any errors
|
| 301 |
+
}
|
| 302 |
+
|
| 303 |
+
[Test]
|
| 304 |
+
public void TestCheckModelValidDiscrete()
|
| 305 |
+
{
|
| 306 |
+
var model = ModelLoader.Load(discreteONNXModel);
|
| 307 |
+
var validBrainParameters = GetDiscrete1vis0vec_2_3action_recurrModelBrainParameters();
|
| 308 |
+
|
| 309 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 310 |
+
model, validBrainParameters,
|
| 311 |
+
new ISensor[] { sensor_21_20_3.CreateSensors()[0] }, new ActuatorComponent[0]
|
| 312 |
+
);
|
| 313 |
+
foreach (var e in errors)
|
| 314 |
+
{
|
| 315 |
+
Debug.Log(e.Message);
|
| 316 |
+
}
|
| 317 |
+
Assert.Greater(errors.Count(), 0); // There should be an error since LSTM v1.x is not supported
|
| 318 |
+
}
|
| 319 |
+
|
| 320 |
+
[Test]
|
| 321 |
+
public void TestCheckModelValidRecurrent()
|
| 322 |
+
{
|
| 323 |
+
var model = ModelLoader.Load(hybridRecurrV2Model);
|
| 324 |
+
var num_errors = 0; // A model trained with v2 should not raise errors
|
| 325 |
+
var validBrainParameters = GetRecurrHybridBrainParameters();
|
| 326 |
+
|
| 327 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 328 |
+
model, validBrainParameters,
|
| 329 |
+
new ISensor[] { sensor_8 }, new ActuatorComponent[0]
|
| 330 |
+
);
|
| 331 |
+
Assert.AreEqual(num_errors, errors.Count()); // There should not be any errors
|
| 332 |
+
|
| 333 |
+
var invalidBrainParameters = GetRecurrHybridBrainParameters();
|
| 334 |
+
invalidBrainParameters.ActionSpec = new ActionSpec(1, new int[] { 2, 3 });
|
| 335 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 336 |
+
model, invalidBrainParameters,
|
| 337 |
+
new ISensor[] { sensor_8 }, new ActuatorComponent[0]
|
| 338 |
+
);
|
| 339 |
+
Assert.AreEqual(1, errors.Count()); // 1 continuous action instead of 2
|
| 340 |
+
|
| 341 |
+
invalidBrainParameters.ActionSpec = new ActionSpec(2, new int[] { 3, 2 });
|
| 342 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 343 |
+
model, invalidBrainParameters,
|
| 344 |
+
new ISensor[] { sensor_8 }, new ActuatorComponent[0]
|
| 345 |
+
);
|
| 346 |
+
Assert.AreEqual(1, errors.Count()); // Discrete action branches flipped
|
| 347 |
+
}
|
| 348 |
+
|
| 349 |
+
[Test]
|
| 350 |
+
public void TestCheckModelValidHybrid()
|
| 351 |
+
{
|
| 352 |
+
var model = ModelLoader.Load(hybridONNXModel);
|
| 353 |
+
var validBrainParameters = GetHybridBrainParameters();
|
| 354 |
+
|
| 355 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 356 |
+
model, validBrainParameters,
|
| 357 |
+
new ISensor[]
|
| 358 |
+
{
|
| 359 |
+
new VectorSensor(validBrainParameters.VectorObservationSize)
|
| 360 |
+
}, new ActuatorComponent[0]
|
| 361 |
+
);
|
| 362 |
+
Assert.AreEqual(0, errors.Count()); // There should not be any errors
|
| 363 |
+
}
|
| 364 |
+
|
| 365 |
+
[Test]
|
| 366 |
+
public void TestCheckModelThrowsVectorObservationContinuous()
|
| 367 |
+
{
|
| 368 |
+
var model = ModelLoader.Load(continuousONNXModel);
|
| 369 |
+
|
| 370 |
+
var brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 371 |
+
brainParameters.VectorObservationSize = 9; // Invalid observation
|
| 372 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 373 |
+
model, brainParameters,
|
| 374 |
+
new ISensor[]
|
| 375 |
+
{
|
| 376 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 377 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 378 |
+
},
|
| 379 |
+
new ActuatorComponent[0]
|
| 380 |
+
);
|
| 381 |
+
Assert.Greater(errors.Count(), 0);
|
| 382 |
+
|
| 383 |
+
brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 384 |
+
brainParameters.NumStackedVectorObservations = 2;// Invalid stacking
|
| 385 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 386 |
+
model, brainParameters,
|
| 387 |
+
new ISensor[]
|
| 388 |
+
{
|
| 389 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 390 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 391 |
+
},
|
| 392 |
+
new ActuatorComponent[0]
|
| 393 |
+
);
|
| 394 |
+
Assert.Greater(errors.Count(), 0);
|
| 395 |
+
}
|
| 396 |
+
|
| 397 |
+
[Test]
|
| 398 |
+
public void TestCheckModelThrowsVectorObservationDiscrete()
|
| 399 |
+
{
|
| 400 |
+
var model = ModelLoader.Load(discreteONNXModel);
|
| 401 |
+
|
| 402 |
+
var brainParameters = GetDiscrete1vis0vec_2_3action_recurrModelBrainParameters();
|
| 403 |
+
brainParameters.VectorObservationSize = 1; // Invalid observation
|
| 404 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 405 |
+
model, brainParameters, new ISensor[]
|
| 406 |
+
{
|
| 407 |
+
sensor_21_20_3.CreateSensors()[0]
|
| 408 |
+
},
|
| 409 |
+
new ActuatorComponent[0]
|
| 410 |
+
);
|
| 411 |
+
Assert.Greater(errors.Count(), 0);
|
| 412 |
+
}
|
| 413 |
+
|
| 414 |
+
[Test]
|
| 415 |
+
public void TestCheckModelThrowsVectorObservationHybrid()
|
| 416 |
+
{
|
| 417 |
+
var model = ModelLoader.Load(hybridONNXModel);
|
| 418 |
+
|
| 419 |
+
var brainParameters = GetHybridBrainParameters();
|
| 420 |
+
brainParameters.VectorObservationSize = 9; // Invalid observation
|
| 421 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 422 |
+
model, brainParameters,
|
| 423 |
+
new ISensor[] { }, new ActuatorComponent[0]
|
| 424 |
+
);
|
| 425 |
+
Assert.Greater(errors.Count(), 0);
|
| 426 |
+
|
| 427 |
+
brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 428 |
+
brainParameters.NumStackedVectorObservations = 2;// Invalid stacking
|
| 429 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 430 |
+
model, brainParameters,
|
| 431 |
+
new ISensor[] { }, new ActuatorComponent[0]
|
| 432 |
+
);
|
| 433 |
+
Assert.Greater(errors.Count(), 0);
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
+
[Test]
|
| 437 |
+
public void TestCheckModelThrowsActionContinuous()
|
| 438 |
+
{
|
| 439 |
+
var model = ModelLoader.Load(continuousONNXModel);
|
| 440 |
+
|
| 441 |
+
var brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 442 |
+
brainParameters.ActionSpec = ActionSpec.MakeContinuous(3); // Invalid action
|
| 443 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 444 |
+
model, brainParameters, new ISensor[]
|
| 445 |
+
{
|
| 446 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 447 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 448 |
+
},
|
| 449 |
+
new ActuatorComponent[0]
|
| 450 |
+
);
|
| 451 |
+
Assert.Greater(errors.Count(), 0);
|
| 452 |
+
|
| 453 |
+
brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 454 |
+
brainParameters.ActionSpec = ActionSpec.MakeDiscrete(3); // Invalid SpaceType
|
| 455 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 456 |
+
model, brainParameters, new ISensor[]
|
| 457 |
+
{
|
| 458 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 459 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 460 |
+
},
|
| 461 |
+
new ActuatorComponent[0]
|
| 462 |
+
);
|
| 463 |
+
Assert.Greater(errors.Count(), 0);
|
| 464 |
+
}
|
| 465 |
+
|
| 466 |
+
[Test]
|
| 467 |
+
public void TestCheckModelThrowsActionDiscrete()
|
| 468 |
+
{
|
| 469 |
+
var model = ModelLoader.Load(discreteONNXModel);
|
| 470 |
+
|
| 471 |
+
var brainParameters = GetDiscrete1vis0vec_2_3action_recurrModelBrainParameters();
|
| 472 |
+
brainParameters.ActionSpec = ActionSpec.MakeDiscrete(3, 3); // Invalid action
|
| 473 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 474 |
+
model, brainParameters,
|
| 475 |
+
new ISensor[] { sensor_21_20_3.CreateSensors()[0] },
|
| 476 |
+
new ActuatorComponent[0]
|
| 477 |
+
);
|
| 478 |
+
Assert.Greater(errors.Count(), 0);
|
| 479 |
+
|
| 480 |
+
brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 481 |
+
brainParameters.ActionSpec = ActionSpec.MakeContinuous(2); // Invalid SpaceType
|
| 482 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 483 |
+
model,
|
| 484 |
+
brainParameters,
|
| 485 |
+
new ISensor[] { sensor_21_20_3.CreateSensors()[0] },
|
| 486 |
+
new ActuatorComponent[0]
|
| 487 |
+
);
|
| 488 |
+
Assert.Greater(errors.Count(), 0);
|
| 489 |
+
}
|
| 490 |
+
|
| 491 |
+
[Test]
|
| 492 |
+
public void TestCheckModelThrowsActionHybrid()
|
| 493 |
+
{
|
| 494 |
+
var model = ModelLoader.Load(hybridONNXModel);
|
| 495 |
+
|
| 496 |
+
var brainParameters = GetHybridBrainParameters();
|
| 497 |
+
brainParameters.ActionSpec = new ActionSpec(3, new[] { 3 }); // Invalid discrete action size
|
| 498 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 499 |
+
model,
|
| 500 |
+
brainParameters,
|
| 501 |
+
new ISensor[]
|
| 502 |
+
{
|
| 503 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 504 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 505 |
+
},
|
| 506 |
+
new ActuatorComponent[0]
|
| 507 |
+
);
|
| 508 |
+
Assert.Greater(errors.Count(), 0);
|
| 509 |
+
|
| 510 |
+
brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 511 |
+
brainParameters.ActionSpec = ActionSpec.MakeDiscrete(2); // Missing continuous action
|
| 512 |
+
errors = SentisModelParamLoader.CheckModel(
|
| 513 |
+
model,
|
| 514 |
+
brainParameters,
|
| 515 |
+
new ISensor[]
|
| 516 |
+
{
|
| 517 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 518 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 519 |
+
},
|
| 520 |
+
new ActuatorComponent[0]
|
| 521 |
+
);
|
| 522 |
+
Assert.Greater(errors.Count(), 0);
|
| 523 |
+
}
|
| 524 |
+
|
| 525 |
+
[Test]
|
| 526 |
+
public void TestCheckModelThrowsNoModel()
|
| 527 |
+
{
|
| 528 |
+
var brainParameters = GetContinuous2vis8vec2actionBrainParameters();
|
| 529 |
+
var errors = SentisModelParamLoader.CheckModel(
|
| 530 |
+
null,
|
| 531 |
+
brainParameters,
|
| 532 |
+
new ISensor[]
|
| 533 |
+
{
|
| 534 |
+
sensor_21_20_3.CreateSensors()[0],
|
| 535 |
+
sensor_20_22_3.CreateSensors()[0]
|
| 536 |
+
},
|
| 537 |
+
new ActuatorComponent[0]
|
| 538 |
+
);
|
| 539 |
+
Assert.Greater(errors.Count(), 0);
|
| 540 |
+
}
|
| 541 |
+
}
|
| 542 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Inference/ParameterLoaderTest.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/Inference/TensorUtilsTest.cs
ADDED
|
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using NUnit.Framework;
|
| 3 |
+
using Unity.InferenceEngine;
|
| 4 |
+
using Unity.MLAgents.Inference;
|
| 5 |
+
using Unity.MLAgents.Inference.Utils;
|
| 6 |
+
|
| 7 |
+
namespace Unity.MLAgents.Tests
|
| 8 |
+
{
|
| 9 |
+
public class TensorUtilsTest
|
| 10 |
+
{
|
| 11 |
+
[TestCase(4, TestName = "TestResizeTensor_4D")]
|
| 12 |
+
[TestCase(8, TestName = "TestResizeTensor_8D")]
|
| 13 |
+
public void TestResizeTensor(int dimension)
|
| 14 |
+
{
|
| 15 |
+
var height = 64;
|
| 16 |
+
var width = 84;
|
| 17 |
+
var channels = 3;
|
| 18 |
+
|
| 19 |
+
// Set shape to {1, ..., channels, height, width}
|
| 20 |
+
// For 8D, the ... are all 1's
|
| 21 |
+
var shape = new int[dimension];
|
| 22 |
+
for (var i = 0; i < dimension; i++)
|
| 23 |
+
{
|
| 24 |
+
shape[i] = 1;
|
| 25 |
+
}
|
| 26 |
+
shape[dimension - 3] = channels;
|
| 27 |
+
shape[dimension - 2] = height;
|
| 28 |
+
shape[dimension - 1] = width;
|
| 29 |
+
|
| 30 |
+
var intShape = new int[dimension];
|
| 31 |
+
for (var i = 0; i < dimension; i++)
|
| 32 |
+
{
|
| 33 |
+
intShape[i] = (int)shape[i];
|
| 34 |
+
}
|
| 35 |
+
|
| 36 |
+
var tensorProxy = new TensorProxy
|
| 37 |
+
{
|
| 38 |
+
valueType = TensorProxy.TensorType.Integer,
|
| 39 |
+
data = new Tensor<float>(new TensorShape(intShape)),
|
| 40 |
+
shape = shape,
|
| 41 |
+
};
|
| 42 |
+
|
| 43 |
+
// These should be invariant after the resize.
|
| 44 |
+
Assert.AreEqual(height, tensorProxy.data.shape.Height());
|
| 45 |
+
Assert.AreEqual(width, tensorProxy.data.shape.Width());
|
| 46 |
+
Assert.AreEqual(channels, tensorProxy.data.shape.Channels());
|
| 47 |
+
|
| 48 |
+
// TODO this resize is changing the tensor dimensions.need fix.
|
| 49 |
+
TensorUtils.ResizeTensor(tensorProxy, 42);
|
| 50 |
+
|
| 51 |
+
Assert.AreEqual(height, tensorProxy.shape[dimension - 2]);
|
| 52 |
+
Assert.AreEqual(width, tensorProxy.shape[dimension - 1]);
|
| 53 |
+
Assert.AreEqual(channels, tensorProxy.shape[dimension - 3]);
|
| 54 |
+
|
| 55 |
+
Assert.AreEqual(height, tensorProxy.data.shape.Height());
|
| 56 |
+
Assert.AreEqual(width, tensorProxy.data.shape.Width());
|
| 57 |
+
Assert.AreEqual(channels, tensorProxy.data.shape.Channels());
|
| 58 |
+
}
|
| 59 |
+
|
| 60 |
+
[Test]
|
| 61 |
+
public void RandomNormalTestTensorInt()
|
| 62 |
+
{
|
| 63 |
+
var rn = new RandomNormal(1982);
|
| 64 |
+
var t = new TensorProxy
|
| 65 |
+
{
|
| 66 |
+
valueType = TensorProxy.TensorType.Integer
|
| 67 |
+
};
|
| 68 |
+
|
| 69 |
+
Assert.Throws<NotImplementedException>(
|
| 70 |
+
() => TensorUtils.FillTensorWithRandomNormal(t, rn));
|
| 71 |
+
}
|
| 72 |
+
|
| 73 |
+
[Test]
|
| 74 |
+
public void RandomNormalTestDataNull()
|
| 75 |
+
{
|
| 76 |
+
var rn = new RandomNormal(1982);
|
| 77 |
+
var t = new TensorProxy
|
| 78 |
+
{
|
| 79 |
+
valueType = TensorProxy.TensorType.FloatingPoint
|
| 80 |
+
};
|
| 81 |
+
|
| 82 |
+
Assert.Throws<ArgumentNullException>(
|
| 83 |
+
() => TensorUtils.FillTensorWithRandomNormal(t, rn));
|
| 84 |
+
}
|
| 85 |
+
|
| 86 |
+
[Test]
|
| 87 |
+
public void RandomNormalTestTensor()
|
| 88 |
+
{
|
| 89 |
+
var rn = new RandomNormal(1982);
|
| 90 |
+
var t = new TensorProxy
|
| 91 |
+
{
|
| 92 |
+
valueType = TensorProxy.TensorType.FloatingPoint,
|
| 93 |
+
data = new Tensor<float>(new TensorShape(1, 3, 4, 2))
|
| 94 |
+
};
|
| 95 |
+
|
| 96 |
+
TensorUtils.FillTensorWithRandomNormal(t, rn);
|
| 97 |
+
|
| 98 |
+
var reference = new[]
|
| 99 |
+
{
|
| 100 |
+
-0.4315872f,
|
| 101 |
+
-1.11074f,
|
| 102 |
+
0.3414804f,
|
| 103 |
+
-1.130287f,
|
| 104 |
+
0.1413168f,
|
| 105 |
+
-0.5105762f,
|
| 106 |
+
-0.3027347f,
|
| 107 |
+
-0.2645015f,
|
| 108 |
+
1.225356f,
|
| 109 |
+
-0.02921959f,
|
| 110 |
+
0.3716498f,
|
| 111 |
+
-1.092338f,
|
| 112 |
+
0.9561074f,
|
| 113 |
+
-0.5018106f,
|
| 114 |
+
1.167787f,
|
| 115 |
+
-0.7763879f,
|
| 116 |
+
-0.07491868f,
|
| 117 |
+
0.5396146f,
|
| 118 |
+
-0.1377991f,
|
| 119 |
+
0.3331701f,
|
| 120 |
+
0.06144788f,
|
| 121 |
+
0.9520947f,
|
| 122 |
+
1.088157f,
|
| 123 |
+
-1.177194f,
|
| 124 |
+
};
|
| 125 |
+
|
| 126 |
+
for (var i = 0; i < t.data.Length(); i++)
|
| 127 |
+
{
|
| 128 |
+
Assert.AreEqual(((Tensor<float>)t.data)[i], reference[i], 0.0001);
|
| 129 |
+
}
|
| 130 |
+
}
|
| 131 |
+
}
|
| 132 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/Inference/TensorUtilsTest.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|
com.unity.ml-agents.tests/Tests/Editor/InplaceArrayTests.cs
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
using System;
|
| 2 |
+
using System.Collections;
|
| 3 |
+
using NUnit.Framework;
|
| 4 |
+
|
| 5 |
+
|
| 6 |
+
namespace Unity.MLAgents.Tests
|
| 7 |
+
{
|
| 8 |
+
[TestFixture]
|
| 9 |
+
public class InplaceArrayTests
|
| 10 |
+
{
|
| 11 |
+
class LengthCases : IEnumerable
|
| 12 |
+
{
|
| 13 |
+
public IEnumerator GetEnumerator()
|
| 14 |
+
{
|
| 15 |
+
yield return 1;
|
| 16 |
+
yield return 2;
|
| 17 |
+
yield return 3;
|
| 18 |
+
yield return 4;
|
| 19 |
+
}
|
| 20 |
+
}
|
| 21 |
+
|
| 22 |
+
private InplaceArray<int> GetTestArray(int length)
|
| 23 |
+
{
|
| 24 |
+
switch (length)
|
| 25 |
+
{
|
| 26 |
+
case 1:
|
| 27 |
+
return new InplaceArray<int>(11);
|
| 28 |
+
case 2:
|
| 29 |
+
return new InplaceArray<int>(11, 22);
|
| 30 |
+
case 3:
|
| 31 |
+
return new InplaceArray<int>(11, 22, 33);
|
| 32 |
+
case 4:
|
| 33 |
+
return new InplaceArray<int>(11, 22, 33, 44);
|
| 34 |
+
default:
|
| 35 |
+
throw new ArgumentException("bad test!");
|
| 36 |
+
}
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
private InplaceArray<int> GetZeroArray(int length)
|
| 40 |
+
{
|
| 41 |
+
switch (length)
|
| 42 |
+
{
|
| 43 |
+
case 1:
|
| 44 |
+
return new InplaceArray<int>(0);
|
| 45 |
+
case 2:
|
| 46 |
+
return new InplaceArray<int>(0, 0);
|
| 47 |
+
case 3:
|
| 48 |
+
return new InplaceArray<int>(0, 0, 0);
|
| 49 |
+
case 4:
|
| 50 |
+
return new InplaceArray<int>(0, 0, 0, 0);
|
| 51 |
+
default:
|
| 52 |
+
throw new ArgumentException("bad test!");
|
| 53 |
+
}
|
| 54 |
+
}
|
| 55 |
+
|
| 56 |
+
[Test]
|
| 57 |
+
public void TestInplaceArrayCtor()
|
| 58 |
+
{
|
| 59 |
+
var a1 = new InplaceArray<int>(11);
|
| 60 |
+
Assert.AreEqual(1, a1.Length);
|
| 61 |
+
Assert.AreEqual(11, a1[0]);
|
| 62 |
+
|
| 63 |
+
var a2 = new InplaceArray<int>(11, 22);
|
| 64 |
+
Assert.AreEqual(2, a2.Length);
|
| 65 |
+
Assert.AreEqual(11, a2[0]);
|
| 66 |
+
Assert.AreEqual(22, a2[1]);
|
| 67 |
+
|
| 68 |
+
var a3 = new InplaceArray<int>(11, 22, 33);
|
| 69 |
+
Assert.AreEqual(3, a3.Length);
|
| 70 |
+
Assert.AreEqual(11, a3[0]);
|
| 71 |
+
Assert.AreEqual(22, a3[1]);
|
| 72 |
+
Assert.AreEqual(33, a3[2]);
|
| 73 |
+
|
| 74 |
+
var a4 = new InplaceArray<int>(11, 22, 33, 44);
|
| 75 |
+
Assert.AreEqual(4, a4.Length);
|
| 76 |
+
Assert.AreEqual(11, a4[0]);
|
| 77 |
+
Assert.AreEqual(22, a4[1]);
|
| 78 |
+
Assert.AreEqual(33, a4[2]);
|
| 79 |
+
Assert.AreEqual(44, a4[3]);
|
| 80 |
+
}
|
| 81 |
+
|
| 82 |
+
[TestCaseSource(typeof(LengthCases))]
|
| 83 |
+
public void TestInplaceGetSet(int length)
|
| 84 |
+
{
|
| 85 |
+
var original = GetTestArray(length);
|
| 86 |
+
|
| 87 |
+
for (var i = 0; i < original.Length; i++)
|
| 88 |
+
{
|
| 89 |
+
var modified = original;
|
| 90 |
+
modified[i] = 0;
|
| 91 |
+
for (var j = 0; j < original.Length; j++)
|
| 92 |
+
{
|
| 93 |
+
if (i == j)
|
| 94 |
+
{
|
| 95 |
+
// This is the one we overwrote
|
| 96 |
+
Assert.AreEqual(0, modified[j]);
|
| 97 |
+
}
|
| 98 |
+
else
|
| 99 |
+
{
|
| 100 |
+
// Other elements should be unchanged
|
| 101 |
+
Assert.AreEqual(original[j], modified[j]);
|
| 102 |
+
}
|
| 103 |
+
}
|
| 104 |
+
}
|
| 105 |
+
}
|
| 106 |
+
|
| 107 |
+
[TestCaseSource(typeof(LengthCases))]
|
| 108 |
+
public void TestInvalidAccess(int length)
|
| 109 |
+
{
|
| 110 |
+
var tmp = 0;
|
| 111 |
+
var a = GetTestArray(length);
|
| 112 |
+
// get
|
| 113 |
+
Assert.Throws<IndexOutOfRangeException>(() => { tmp += a[-1]; });
|
| 114 |
+
Assert.Throws<IndexOutOfRangeException>(() => { tmp += a[length]; });
|
| 115 |
+
|
| 116 |
+
// set
|
| 117 |
+
Assert.Throws<IndexOutOfRangeException>(() => { a[-1] = 0; });
|
| 118 |
+
Assert.Throws<IndexOutOfRangeException>(() => { a[length] = 0; });
|
| 119 |
+
|
| 120 |
+
// Make sure temp is used
|
| 121 |
+
Assert.AreEqual(0, tmp);
|
| 122 |
+
}
|
| 123 |
+
|
| 124 |
+
[Test]
|
| 125 |
+
public void TestOperatorEqualsDifferentLengths()
|
| 126 |
+
{
|
| 127 |
+
// Check arrays of different length are never equal (even if they have 0s in all elements)
|
| 128 |
+
for (var l1 = 1; l1 <= 4; l1++)
|
| 129 |
+
{
|
| 130 |
+
var a1 = GetZeroArray(l1);
|
| 131 |
+
for (var l2 = 1; l2 <= 4; l2++)
|
| 132 |
+
{
|
| 133 |
+
var a2 = GetZeroArray(l2);
|
| 134 |
+
if (l1 == l2)
|
| 135 |
+
{
|
| 136 |
+
Assert.AreEqual(a1, a2);
|
| 137 |
+
Assert.IsTrue(a1 == a2);
|
| 138 |
+
}
|
| 139 |
+
else
|
| 140 |
+
{
|
| 141 |
+
Assert.AreNotEqual(a1, a2);
|
| 142 |
+
Assert.IsTrue(a1 != a2);
|
| 143 |
+
}
|
| 144 |
+
}
|
| 145 |
+
}
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
[TestCaseSource(typeof(LengthCases))]
|
| 149 |
+
public void TestOperatorEquals(int length)
|
| 150 |
+
{
|
| 151 |
+
for (var index = 0; index < length; index++)
|
| 152 |
+
{
|
| 153 |
+
var a1 = GetTestArray(length);
|
| 154 |
+
var a2 = GetTestArray(length);
|
| 155 |
+
Assert.AreEqual(a1, a2);
|
| 156 |
+
Assert.IsTrue(a1 == a2);
|
| 157 |
+
|
| 158 |
+
a1[index] = 42;
|
| 159 |
+
Assert.AreNotEqual(a1, a2);
|
| 160 |
+
Assert.IsTrue(a1 != a2);
|
| 161 |
+
|
| 162 |
+
a2[index] = 42;
|
| 163 |
+
Assert.AreEqual(a1, a2);
|
| 164 |
+
Assert.IsTrue(a1 == a2);
|
| 165 |
+
}
|
| 166 |
+
}
|
| 167 |
+
|
| 168 |
+
[Test]
|
| 169 |
+
public void TestToString()
|
| 170 |
+
{
|
| 171 |
+
Assert.AreEqual("[1]", new InplaceArray<int>(1).ToString());
|
| 172 |
+
Assert.AreEqual("[1, 2]", new InplaceArray<int>(1, 2).ToString());
|
| 173 |
+
Assert.AreEqual("[1, 2, 3]", new InplaceArray<int>(1, 2, 3).ToString());
|
| 174 |
+
Assert.AreEqual("[1, 2, 3, 4]", new InplaceArray<int>(1, 2, 3, 4).ToString());
|
| 175 |
+
}
|
| 176 |
+
|
| 177 |
+
[TestCaseSource(typeof(LengthCases))]
|
| 178 |
+
public void TestFromList(int length)
|
| 179 |
+
{
|
| 180 |
+
var intArray = new int[length];
|
| 181 |
+
for (var i = 0; i < length; i++)
|
| 182 |
+
{
|
| 183 |
+
intArray[i] = (i + 1) * 11; // 11, 22, etc.
|
| 184 |
+
}
|
| 185 |
+
|
| 186 |
+
var converted = InplaceArray<int>.FromList(intArray);
|
| 187 |
+
Assert.AreEqual(GetTestArray(length), converted);
|
| 188 |
+
}
|
| 189 |
+
}
|
| 190 |
+
}
|
com.unity.ml-agents.tests/Tests/Editor/InplaceArrayTests.cs.meta
ADDED
|
Binary file (243 Bytes). View file
|
|
|