Refactor core APIs, fix bugs, and improve safety
- Make image result/info structs readonly; improve error handling and memory safety in image library - Introduce IJobScheduler interface; move job scheduling docs to interface - Remove "index 0 invalid" convention from slot/sparse maps; fix Count logic - Add Owner<T> for disposable value types in low-level utilities - Improve ObjectPool<T> thread safety and logic - Change List<T>.RemoveAndSwapBack to return bool - Remove unsafe methods from generated math types; add debug range checks - Update benchmarks and enable collection checks in tests - Improve documentation, comments, and error messages - Bump assembly versions across all projects
This commit is contained in:
@@ -6,7 +6,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
{
|
||||
internal abstract class GeneratorBase
|
||||
{
|
||||
protected const string INLINE_METHOD_ATTRIBUTE = "[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining | global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveOptimization)]";
|
||||
protected const string INLINE_METHOD_ATTRIBUTE = "[global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]";
|
||||
|
||||
protected static readonly string[] s_matrixComponents = new[] { "c0", "c1", "c2", "c3" };
|
||||
protected static readonly string[] s_vectorComponents = new[] { "x", "y", "z", "w" };
|
||||
@@ -19,10 +19,9 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
this.typeInfo = typeInfo;
|
||||
sourceBuilder.Clear();
|
||||
|
||||
var message = Validation();
|
||||
if (message != null)
|
||||
if (!Validation(out var message))
|
||||
{
|
||||
return message;
|
||||
return message ?? string.Empty;
|
||||
}
|
||||
|
||||
Initialize();
|
||||
@@ -51,9 +50,10 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
#endregion");
|
||||
}
|
||||
|
||||
protected virtual string? Validation()
|
||||
protected virtual bool Validation(out string? message)
|
||||
{
|
||||
return null;
|
||||
message = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual void Initialize()
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Microsoft.CodeAnalysis;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection.Metadata;
|
||||
using System.Text;
|
||||
|
||||
namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
@@ -16,14 +15,16 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
.Replace("{c}", s_matrixComponents[componentIndex]);
|
||||
}
|
||||
|
||||
protected override string? Validation()
|
||||
protected override bool Validation(out string? message)
|
||||
{
|
||||
if (typeInfo.ElementTypeSymbol == null)
|
||||
{
|
||||
return "You must specify 'elementType' in NumericTypeAttribute for matrix types.";
|
||||
message = "You must specify 'elementType' in NumericTypeAttribute for matrix types.";
|
||||
return false;
|
||||
}
|
||||
|
||||
return null;
|
||||
message = null;
|
||||
return true;
|
||||
}
|
||||
|
||||
protected override void GenerateBody()
|
||||
@@ -36,7 +37,6 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
}
|
||||
|
||||
GenerateConstructors();
|
||||
GenerateUnsafeMethod();
|
||||
GenerateOverrideMethod();
|
||||
|
||||
if (typeInfo.Arithmetic)
|
||||
@@ -67,15 +67,20 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
{INLINE_METHOD_ATTRIBUTE}
|
||||
get
|
||||
{{
|
||||
#if ENABLE_COLLECTION_CHECKS
|
||||
if (index < 0 || index >= {typeInfo.Column})
|
||||
{{
|
||||
throw new global::System.ArgumentOutOfRangeException(nameof(index), $""Index {{index}} is out of range of '{typeInfo.TypeName}'"");
|
||||
}}
|
||||
#endif
|
||||
RangeCheck(index);
|
||||
return ref (({typeInfo.ComponentTypeFullName}*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref this))[index];
|
||||
}}
|
||||
}}");
|
||||
|
||||
sourceBuilder.AppendLine($@"
|
||||
[global::System.Diagnostics.Conditional(""ENABLE_COLLECTION_CHECKS"")]
|
||||
private void RangeCheck(int index)
|
||||
{{
|
||||
if (index < 0 || index >= {typeInfo.Column})
|
||||
{{
|
||||
throw new global::System.ArgumentOutOfRangeException(nameof(index), $""Index {{index}} is out of range of '{typeInfo.TypeName}'"");
|
||||
}}
|
||||
}}");
|
||||
}
|
||||
|
||||
private void GenerateUnitMatrix()
|
||||
@@ -213,27 +218,11 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
sourceBuilder.Append($@"
|
||||
this.{s_matrixComponents[i]} = {assignment[i]};");
|
||||
}
|
||||
sourceBuilder.AppendLine($@"
|
||||
sourceBuilder.AppendLine($@"
|
||||
}}");
|
||||
}
|
||||
}
|
||||
|
||||
private void GenerateUnsafeMethod()
|
||||
{
|
||||
sourceBuilder.AppendLine($@"
|
||||
{INLINE_METHOD_ATTRIBUTE}
|
||||
public unsafe {typeInfo.ComponentTypeFullName}* AsPointer()
|
||||
{{
|
||||
return ({typeInfo.ComponentTypeFullName}*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref this);
|
||||
}}
|
||||
|
||||
{INLINE_METHOD_ATTRIBUTE}
|
||||
public unsafe global::System.Span<{typeInfo.ComponentTypeFullName}> AsSpan()
|
||||
{{
|
||||
return new global::System.Span<{typeInfo.ComponentTypeFullName}>(AsPointer(), {typeInfo.Column});
|
||||
}}");
|
||||
}
|
||||
|
||||
private void GenerateOverrideMethod()
|
||||
{
|
||||
var components = s_matrixComponents.Take(typeInfo.Column).ToArray();
|
||||
@@ -760,7 +749,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
|
||||
var columnSizeBytes = lhsRows * typeInfo.ComponentSize;
|
||||
var vectorBits = columnSizeBytes > 16 ? 256 : 128;
|
||||
bool isFloatingPoint = typeInfo.ElementTypeSymbol!.SpecialType == SpecialType.System_Single||
|
||||
var isFloatingPoint = typeInfo.ElementTypeSymbol!.SpecialType == SpecialType.System_Single ||
|
||||
typeInfo.ElementTypeSymbol!.SpecialType == SpecialType.System_Double;
|
||||
|
||||
sourceBuilder.Append($@"
|
||||
@@ -768,7 +757,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
public static {resultVectorType} mul({lhsType} m, {rhsVectorType} v)
|
||||
{{");
|
||||
|
||||
for (int i = 0; i < lhsCols; i++)
|
||||
for (var i = 0; i < lhsCols; i++)
|
||||
{
|
||||
var component = s_vectorComponents[i];
|
||||
sourceBuilder.Append($@"
|
||||
@@ -779,7 +768,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
|
||||
var sum = global::System.Runtime.Intrinsics.Vector{vectorBits}.Multiply(m.c0.AsVector{vectorBits}(), vx);");
|
||||
|
||||
for (int i = 1; i < lhsCols; i++)
|
||||
for (var i = 1; i < lhsCols; i++)
|
||||
{
|
||||
var component = s_vectorComponents[i];
|
||||
var col = s_matrixComponents[i];
|
||||
|
||||
@@ -52,7 +52,6 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
}
|
||||
|
||||
GenerateConstructors();
|
||||
GenerateUnsafeMethod();
|
||||
GenerateOverrideMethod();
|
||||
GenerateConvertionMethod();
|
||||
|
||||
@@ -95,15 +94,20 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
{INLINE_METHOD_ATTRIBUTE}
|
||||
get
|
||||
{{
|
||||
#if ENABLE_COLLECTION_CHECKS
|
||||
if (index < 0 || index >= {typeInfo.Row})
|
||||
{{
|
||||
throw new global::System.ArgumentOutOfRangeException(nameof(index), $""Index {{index}} is out of range of '{typeInfo.TypeName}'"");
|
||||
}}
|
||||
#endif
|
||||
RangeCheck(index);
|
||||
return ref (({typeInfo.ComponentTypeFullName}*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref this))[index];
|
||||
}}
|
||||
}}");
|
||||
|
||||
sourceBuilder.AppendLine($@"
|
||||
[global::System.Diagnostics.Conditional(""ENABLE_COLLECTION_CHECKS"")]
|
||||
private void RangeCheck(int index)
|
||||
{{
|
||||
if (index < 0 || index >= {typeInfo.Row})
|
||||
{{
|
||||
throw new global::System.ArgumentOutOfRangeException(nameof(index), $""Index {{index}} is out of range of '{typeInfo.TypeName}'"");
|
||||
}}
|
||||
}}");
|
||||
}
|
||||
|
||||
private static List<List<int>> GetPartitions(int target)
|
||||
@@ -295,28 +299,10 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
EndRegion();
|
||||
}
|
||||
|
||||
private void GenerateUnsafeMethod()
|
||||
{
|
||||
var componentType = typeInfo.ComponentTypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
|
||||
StartRegion("Unsafe Methods");
|
||||
|
||||
sourceBuilder.AppendLine($@"
|
||||
{INLINE_METHOD_ATTRIBUTE}
|
||||
public unsafe {componentType}* AsPointer()
|
||||
{{
|
||||
return ({componentType}*)global::System.Runtime.CompilerServices.Unsafe.AsPointer(ref this);
|
||||
}}
|
||||
|
||||
{INLINE_METHOD_ATTRIBUTE}
|
||||
public unsafe global::System.Span<{componentType}> AsSpan()
|
||||
{{
|
||||
return new global::System.Span<{componentType}>(AsPointer(), {typeInfo.Row});
|
||||
}}");
|
||||
}
|
||||
|
||||
private void GenerateOverrideMethod()
|
||||
{
|
||||
StartRegion("Override Methods");
|
||||
|
||||
var typeName = typeInfo.TypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
var componentType = typeInfo.ComponentTypeSymbol.ToDisplayString(SymbolDisplayFormat.FullyQualifiedFormat);
|
||||
var components = s_vectorComponents.Take(typeInfo.Row).ToArray();
|
||||
@@ -715,6 +701,7 @@ namespace Misaki.HighPerformance.Mathematics.CodeGen.Generators
|
||||
var modifier = canSet ? "public" : "public readonly";
|
||||
|
||||
sourceBuilder.Append($@"
|
||||
[global::System.Text.Json.Serialization.JsonIgnore]
|
||||
{modifier} {targetStruct} {property}
|
||||
{{
|
||||
{INLINE_METHOD_ATTRIBUTE}
|
||||
|
||||
Reference in New Issue
Block a user