diff --git a/Content.Benchmarks/DeltaPressureBenchmark.cs b/Content.Benchmarks/DeltaPressureBenchmark.cs index dac79e0376..f4ae62a465 100644 --- a/Content.Benchmarks/DeltaPressureBenchmark.cs +++ b/Content.Benchmarks/DeltaPressureBenchmark.cs @@ -32,7 +32,7 @@ public class DeltaPressureBenchmark /// /// Number of entities (windows, really) to spawn with a . /// - [Params(1, 10, 100, 1000, 5000, 10000, 50000, 100000)] + [Params(100, 1000, 5000, 10000)] public int EntityCount; /// diff --git a/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs b/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs index 24f3ffaa26..0619e26c4b 100644 --- a/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs +++ b/Content.Client/Atmos/EntitySystems/AtmosphereSystem.Gases.cs @@ -1,3 +1,4 @@ +using System.Numerics.Tensors; using System.Runtime.CompilerServices; using Content.Shared.Atmos; using Content.Shared.Atmos.Reactions; @@ -26,15 +27,15 @@ public sealed partial class AtmosphereSystem public override bool IsMixtureFuel(GasMixture mixture, float epsilon = Atmospherics.Epsilon) { var tmp = new float[Atmospherics.AdjustedNumberOfGases]; - NumericsHelpers.Multiply(mixture.Moles, GasFuelMask, tmp); - return NumericsHelpers.HorizontalAdd(tmp) > epsilon; + TensorPrimitives.Multiply(mixture.Moles, GasFuelMask, tmp); + return TensorPrimitives.Sum(tmp) > epsilon; } public override bool IsMixtureOxidizer(GasMixture mixture, float epsilon = Atmospherics.Epsilon) { var tmp = new float[Atmospherics.AdjustedNumberOfGases]; - NumericsHelpers.Multiply(mixture.Moles, GasOxidizerMask, tmp); - return NumericsHelpers.HorizontalAdd(tmp) > epsilon; + TensorPrimitives.Multiply(mixture.Moles, GasOxidizerMask, tmp); + return TensorPrimitives.Sum(tmp) > epsilon; } public override float GetMass(GasMixture mix) @@ -45,17 +46,17 @@ public sealed partial class AtmosphereSystem public override float GetMass(float[] moles) { var tmp = new float[moles.Length]; - NumericsHelpers.Multiply(moles, GasMolarMasses, tmp); + TensorPrimitives.Multiply(moles, GasMolarMasses, tmp); // Conversion of grams to kilograms. - return NumericsHelpers.HorizontalAdd(tmp) * Atmospherics.gToKg; + return TensorPrimitives.Sum(tmp) * Atmospherics.gToKg; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override float GetHeatCapacityCalculation(float[] moles, bool space) { // Little hack to make space gas mixtures have heat capacity, therefore allowing them to cool down rooms. - if (space && MathHelper.CloseTo(NumericsHelpers.HorizontalAdd(moles), 0f)) + if (space && MathHelper.CloseTo(TensorPrimitives.Sum(moles), 0f)) { return Atmospherics.SpaceHeatCapacity; } @@ -65,9 +66,9 @@ public sealed partial class AtmosphereSystem // though this isnt the hottest code path so it should be fine // the gc can eat a little as a treat var tmp = new float[moles.Length]; - NumericsHelpers.Multiply(moles, GasMolarHeatCapacities, tmp); + TensorPrimitives.Multiply(moles, GasMolarHeatCapacities, tmp); // Adjust heat capacity by speedup, because this is primarily what // determines how quickly gases heat up/cool. - return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity); + return MathF.Max(TensorPrimitives.Sum(tmp), Atmospherics.MinimumHeatCapacity); } } diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs index 27e9f33653..50c3add748 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs @@ -1,5 +1,6 @@ using System.Buffers; using System.Diagnostics; +using System.Numerics.Tensors; using Content.Server.NodeContainer.NodeGroups; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; @@ -366,10 +367,9 @@ public partial class AtmosphereSystem mixtMoles[i] = mixture.TotalMoles; } - // TODO NumericsHelpers need a method that substitutes NaNs with zeros. AVX-512 has one iirc but for 256/128 we need to do some masking bs - NumericsHelpers.Multiply(mixtMoles, Atmospherics.R); - NumericsHelpers.Multiply(mixtMoles, mixtTemp); - NumericsHelpers.Divide(mixtMoles, mixtVol, pressures); + TensorPrimitives.Multiply(mixtMoles, Atmospherics.R, mixtMoles); + TensorPrimitives.Multiply(mixtMoles, mixtTemp, mixtMoles); + TensorPrimitives.Divide(mixtMoles, mixtVol, pressures); } finally { diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.DeltaPressure.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.DeltaPressure.cs index 81fa1c6e6f..fe11a62f14 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.DeltaPressure.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.DeltaPressure.cs @@ -1,5 +1,6 @@ using System.Buffers; using System.Collections.Concurrent; +using System.Numerics.Tensors; using Content.Server.Atmos.Components; using Content.Shared.Atmos; using Content.Shared.Atmos.Components; @@ -162,9 +163,9 @@ public sealed partial class AtmosphereSystem } // Time to get crankin - NumericsHelpers.Max(groupA, groupB, groupMax); - NumericsHelpers.Sub(groupA, groupB); - NumericsHelpers.Abs(groupA); + TensorPrimitives.Max(groupA, groupB, groupMax); + TensorPrimitives.Subtract(groupA, groupB, groupA); + TensorPrimitives.Abs(groupA, groupA); // Now go through each entity and determine their max pressure & delta pressure. // Queue for damage if necessary. diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs index d3c51086ca..9a4af9ebf0 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Gases.cs @@ -1,4 +1,5 @@ using System.Linq; +using System.Numerics.Tensors; using System.Runtime.CompilerServices; using Content.Server.Atmos.Reactions; using Content.Shared.Atmos; @@ -36,40 +37,40 @@ namespace Content.Server.Atmos.EntitySystems public override float GetMass(float[] moles) { Span tmp = stackalloc float[moles.Length]; - NumericsHelpers.Multiply(moles, GasMolarMasses, tmp); + TensorPrimitives.Multiply(moles, GasMolarMasses, tmp); // Conversion of grams to kilograms. - return NumericsHelpers.HorizontalAdd(tmp) * Atmospherics.gToKg; + return TensorPrimitives.Sum(tmp) * Atmospherics.gToKg; } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected override float GetHeatCapacityCalculation(float[] moles, bool space) { // Little hack to make space gas mixtures have heat capacity, therefore allowing them to cool down rooms. - if (space && MathHelper.CloseTo(NumericsHelpers.HorizontalAdd(moles), 0f)) + if (space && MathHelper.CloseTo(TensorPrimitives.Sum(moles), 0f)) { return Atmospherics.SpaceHeatCapacity; } Span tmp = stackalloc float[moles.Length]; - NumericsHelpers.Multiply(moles, GasMolarHeatCapacities, tmp); + TensorPrimitives.Multiply(moles, GasMolarHeatCapacities, tmp); // Adjust heat capacity by speedup, because this is primarily what // determines how quickly gases heat up/cool. - return MathF.Max(NumericsHelpers.HorizontalAdd(tmp), Atmospherics.MinimumHeatCapacity); + return MathF.Max(TensorPrimitives.Sum(tmp), Atmospherics.MinimumHeatCapacity); } public override bool IsMixtureFuel(GasMixture mixture, float epsilon = Atmospherics.Epsilon) { Span tmp = stackalloc float[Atmospherics.AdjustedNumberOfGases]; - NumericsHelpers.Multiply(mixture.Moles, GasFuelMask, tmp); - return NumericsHelpers.HorizontalAdd(tmp) > epsilon; + TensorPrimitives.Multiply(mixture.Moles, GasFuelMask, tmp); + return TensorPrimitives.Sum(tmp) > epsilon; } public override bool IsMixtureOxidizer(GasMixture mixture, float epsilon = Atmospherics.Epsilon) { Span tmp = stackalloc float[Atmospherics.AdjustedNumberOfGases]; - NumericsHelpers.Multiply(mixture.Moles, GasOxidizerMask, tmp); - return NumericsHelpers.HorizontalAdd(tmp) > epsilon; + TensorPrimitives.Multiply(mixture.Moles, GasOxidizerMask, tmp); + return TensorPrimitives.Sum(tmp) > epsilon; } /// @@ -131,8 +132,8 @@ namespace Content.Server.Atmos.EntitySystems } // transfer moles - NumericsHelpers.Multiply(source.Moles, fraction, buffer); - NumericsHelpers.Add(receiver.Moles, buffer); + TensorPrimitives.Multiply(source.Moles, fraction, buffer); + TensorPrimitives.Add(receiver.Moles, buffer, receiver.Moles); } } @@ -325,13 +326,8 @@ namespace Content.Server.Atmos.EntitySystems [PublicAPI] public static void AddMolsToMixture(GasMixture mixture, ReadOnlySpan molsToAdd) { - // Span length should be as long as the length of the gas array. - // Technically this is a redundant check because NumericsHelpers will do the same thing, - // but eh. - ArgumentOutOfRangeException.ThrowIfNotEqual(mixture.Moles.Length, molsToAdd.Length, nameof(mixture.Moles.Length)); - - NumericsHelpers.Add(mixture.Moles, molsToAdd); - NumericsHelpers.Max(mixture.Moles, 0f); + TensorPrimitives.Add(mixture.Moles, molsToAdd, mixture.Moles); + TensorPrimitives.Max(mixture.Moles, 0f, mixture.Moles); } public enum GasCompareResult diff --git a/Content.Shared/Atmos/EntitySystems/SharedAtmosphereSystem.Gases.cs b/Content.Shared/Atmos/EntitySystems/SharedAtmosphereSystem.Gases.cs index 240711f048..7a2c8339d7 100644 --- a/Content.Shared/Atmos/EntitySystems/SharedAtmosphereSystem.Gases.cs +++ b/Content.Shared/Atmos/EntitySystems/SharedAtmosphereSystem.Gases.cs @@ -1,3 +1,4 @@ +using System.Numerics.Tensors; using System.Runtime.CompilerServices; using Content.Shared.Atmos.Prototypes; using Content.Shared.Atmos.Reactions; @@ -110,7 +111,7 @@ public abstract partial class SharedAtmosphereSystem [PublicAPI] public void GetFlammableMoles(GasMixture mixture, float[] buffer) { - NumericsHelpers.Multiply(mixture.Moles, GasOxidiserFuelMask, buffer); + TensorPrimitives.Multiply(mixture.Moles, GasOxidiserFuelMask, buffer); } /// @@ -213,7 +214,7 @@ public abstract partial class SharedAtmosphereSystem } } - NumericsHelpers.Add(receiver.Moles, giver.Moles); + TensorPrimitives.Add(receiver.Moles, giver.Moles, receiver.Moles); } /// diff --git a/Content.Shared/Atmos/GasMixture.cs b/Content.Shared/Atmos/GasMixture.cs index 3da7827cdd..a5fc04e611 100644 --- a/Content.Shared/Atmos/GasMixture.cs +++ b/Content.Shared/Atmos/GasMixture.cs @@ -1,6 +1,7 @@ using System.Collections; using System.Diagnostics.CodeAnalysis; using System.Linq; +using System.Numerics.Tensors; using System.Runtime.CompilerServices; using Content.Shared.Atmos.EntitySystems; using Content.Shared.Atmos.Reactions; @@ -42,7 +43,7 @@ namespace Content.Shared.Atmos public float TotalMoles { [MethodImpl(MethodImplOptions.AggressiveInlining)] - get => NumericsHelpers.HorizontalAdd(Moles); + get => TensorPrimitives.Sum(Moles); } [ViewVariables] @@ -177,9 +178,9 @@ namespace Content.Shared.Atmos var removed = new GasMixture(Volume) { Temperature = Temperature }; Moles.CopyTo(removed.Moles.AsSpan()); - NumericsHelpers.Multiply(removed.Moles, ratio); + TensorPrimitives.Multiply(removed.Moles, ratio, removed.Moles); if (!Immutable) - NumericsHelpers.Sub(Moles, removed.Moles); + TensorPrimitives.Subtract(Moles, removed.Moles, Moles); for (var i = 0; i < Moles.Length; i++) { @@ -223,7 +224,7 @@ namespace Content.Shared.Atmos public void Multiply(float multiplier) { if (Immutable) return; - NumericsHelpers.Multiply(Moles, multiplier); + TensorPrimitives.Multiply(Moles, multiplier, Moles); } void ISerializationHooks.AfterDeserialization() diff --git a/Content.Shared/Content.Shared.csproj b/Content.Shared/Content.Shared.csproj index da32cdf817..f8f986c9c5 100644 --- a/Content.Shared/Content.Shared.csproj +++ b/Content.Shared/Content.Shared.csproj @@ -6,6 +6,7 @@ + diff --git a/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs b/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs index 07b45bfe11..936a9f13d6 100644 --- a/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs +++ b/Content.Tests/Server/Atmos/AddMolsToMixtureTest.cs @@ -21,10 +21,8 @@ public sealed class AddMolsToMixtureTest var mixture = new GasMixture(); var wrongLength = new float[Atmospherics.AdjustedNumberOfGases + num]; - var ex = Assert.Throws(() => + Assert.Throws(() => AtmosphereSystem.AddMolsToMixture(mixture, wrongLength)); - - Assert.That(ex!.ParamName, Is.EqualTo("Length")); } ///