From f6e897ed06c3e84aac2385b119dc3bfd7df24913 Mon Sep 17 00:00:00 2001 From: Youmu Liu <105042599+Nitload-NSI@users.noreply.github.com> Date: Fri, 6 Mar 2026 18:22:30 +0800 Subject: [PATCH] swiss ok, needs more benchmark --- ReadMe.md | 5 +- StgSharp.Benchmark/Program.cs | 11 +- StgSharp.Benchmark/StgSharp.Benchmark.csproj | 1 + StgSharp.Benchmark/SwissBenchmark.cs | 254 +++++++ StgSharp.Common/Collections/SwissTable.X86.cs | 130 ++-- StgSharp.Common/Collections/SwissTable.cs | 87 ++- StgSharp.Graphics/Camera.cs | 52 +- .../Global.cs | 10 +- StgSharp.Graphics/OpenGL/ShaderEdit/Shader.cs | 4 +- StgSharp.Graphics/OpenGL/glApiManager.cs | 102 +-- StgSharp.Graphics/OpenGL/glRenderStream.cs | 29 +- StgSharp.Graphics/glfw.cs | 28 +- StgSharp.Graphics/glfw.function.cs | 2 +- .../Geometries/GeometryScaler/Angle.cs | 89 ++- .../{Numeric/Scalar/Tan.cs => Global.cs} | 25 +- StgSharp.Mathematics/Internal/MatrixPanel.cs | 55 +- .../Internal/MatrixParallelTask.cs | 8 +- .../Internal/UnsafeCompute.cs | 22 +- .../Numeric/Graphics/Vector.GetAngle.cs | 14 +- .../Numeric/Graphics/Vector.GetLength.cs | 12 +- .../Numeric/Linear/Exception.cs | 130 ++-- StgSharp.Mathematics/Numeric/Linear/Matrix.cs | 103 +-- .../MatrixCompute.Factorize.cs.old} | 320 ++++----- .../MatrixCompute.Float.cs.old} | 628 +++++++++--------- .../Numeric/{ => Linear}/MatrixCompute.cs | 110 +-- .../MatrixCompute.double.cs.old} | 623 ++++++++--------- .../Numeric/Runtime/MatrixParallel.Await.cs | 21 +- .../Runtime/MatrixParallel.AwaitingQueue.cs | 29 +- .../Numeric/Runtime/MatrixParallel.Publish.cs | 12 +- ...Fma.cs => MatrixParallelThread.Fma.cs.old} | 184 ++--- ...l.cs => MatrixParallelThread.Model.cs.old} | 148 ++--- .../Numeric/Runtime/MatrixParallelThread.cs | 10 +- .../Numeric/Runtime/MatrixTaskFactory.cs | 3 - StgSharp.Mathematics/Numeric/Scalar/ACos.cs | 107 --- StgSharp.Mathematics/Numeric/Scalar/ASin.cs | 119 ---- StgSharp.Mathematics/Numeric/Scalar/ATan.cs | 116 ---- .../Numeric/Scalar/BasicOps.cs | 67 -- .../Numeric/Scalar/Compare.cs | 64 -- StgSharp.Mathematics/Numeric/Scalar/Cos.cs | 57 -- StgSharp.Mathematics/Numeric/Scalar/Ctor.cs | 52 -- StgSharp.Mathematics/Numeric/Scalar/Exp.cs | 109 --- .../Numeric/Scalar/Factorial.cs | 67 -- StgSharp.Mathematics/Numeric/Scalar/Log.cs | 80 --- StgSharp.Mathematics/Numeric/Scalar/Pow.cs | 121 ---- StgSharp.Mathematics/Numeric/Scalar/Random.cs | 126 ---- .../Numeric/Scalar/RandomGenerator.cs | 142 ---- StgSharp.Mathematics/Numeric/Scalar/SignOf.cs | 65 -- StgSharp.Mathematics/Numeric/Scalar/Sin.cs | 47 -- StgSharp.Mathematics/Numeric/Scalar/Sqrt.cs | 74 --- StgSharp.RegularAnalysis/Abstraction/Token.cs | 16 +- .../TextRegex/RegexAstNode.cs | 21 +- StgSharpDebug/MatrixTest.cs | 26 +- StgSharpDebug/RenderStream/Partical.cs | 12 +- StgSharpDebug/Shader/ControlItemRender.frag | 12 - StgSharpDebug/Shader/ControlItemRender.vert | 12 - StgSharpDebug/Shader/Image1.png | Bin 29445 -> 0 bytes StgSharpDebug/Shader/awesomeface.png | Bin 40855 -> 0 bytes StgSharpDebug/Shader/fbo.frag | 13 - StgSharpDebug/Shader/fbo.vert | 13 - StgSharpDebug/Shader/main.frag | 17 - StgSharpDebug/Shader/main.vert | 22 - StgSharpDebug/Shader/particle.frag | 12 - StgSharpDebug/Shader/particle.vert | 36 - StgSharpDebug/StgSharpDebug.csproj | 27 - StgSharpDebug/TestSwiss.cs | 16 +- StgSharpDebug/View/Control.cs | 61 -- StgSharpDebug/View/Design.cs | 91 --- StgSharpDebug/View/ViewMain.cs | 98 --- StgSharpDebug/ViewModelMain.cs | 75 --- StgSharpDevelop.slnLaunch.user | 6 + 70 files changed, 1889 insertions(+), 3371 deletions(-) create mode 100644 StgSharp.Benchmark/SwissBenchmark.cs rename StgSharp.Mathematics/Numeric/Scalar/Function.cs => StgSharp.Graphics/Global.cs (89%) rename StgSharp.Mathematics/{Numeric/Scalar/Tan.cs => Global.cs} (80%) rename StgSharpDebug/View/NewRender.cs => StgSharp.Mathematics/Numeric/Linear/Exception.cs (56%) rename StgSharp.Mathematics/Numeric/{MatrixCompute.Factorize.cs => Linear/MatrixCompute.Factorize.cs.old} (97%) rename StgSharp.Mathematics/Numeric/{MatrixCompute.Float.cs => Linear/MatrixCompute.Float.cs.old} (97%) rename StgSharp.Mathematics/Numeric/{ => Linear}/MatrixCompute.cs (97%) rename StgSharp.Mathematics/Numeric/{MatrixCompute.double.cs => Linear/MatrixCompute.double.cs.old} (92%) rename StgSharp.Mathematics/Numeric/Runtime/{MatrixParallelThread.Fma.cs => MatrixParallelThread.Fma.cs.old} (98%) rename StgSharp.Mathematics/Numeric/Runtime/{MatrixParallelThread.Model.cs => MatrixParallelThread.Model.cs.old} (97%) delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/ACos.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/ASin.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/ATan.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/BasicOps.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Compare.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Cos.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Ctor.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Exp.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Factorial.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Log.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Pow.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Random.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/RandomGenerator.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/SignOf.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Sin.cs delete mode 100644 StgSharp.Mathematics/Numeric/Scalar/Sqrt.cs delete mode 100644 StgSharpDebug/Shader/ControlItemRender.frag delete mode 100644 StgSharpDebug/Shader/ControlItemRender.vert delete mode 100644 StgSharpDebug/Shader/Image1.png delete mode 100644 StgSharpDebug/Shader/awesomeface.png delete mode 100644 StgSharpDebug/Shader/fbo.frag delete mode 100644 StgSharpDebug/Shader/fbo.vert delete mode 100644 StgSharpDebug/Shader/main.frag delete mode 100644 StgSharpDebug/Shader/main.vert delete mode 100644 StgSharpDebug/Shader/particle.frag delete mode 100644 StgSharpDebug/Shader/particle.vert delete mode 100644 StgSharpDebug/View/Control.cs delete mode 100644 StgSharpDebug/View/Design.cs delete mode 100644 StgSharpDebug/View/ViewMain.cs delete mode 100644 StgSharpDebug/ViewModelMain.cs create mode 100644 StgSharpDevelop.slnLaunch.user diff --git a/ReadMe.md b/ReadMe.md index fdd64267..8f5fe7ea 100644 --- a/ReadMe.md +++ b/ReadMe.md @@ -92,7 +92,10 @@ Toolchain=InProcessEmitToolchain InvocationCount=2048 UnrollFactor=1 | Hlsf | 76.23 µs | 0.355 µs | 0.315 µs | 0.44 | 0.01 | | Libc | 172.98 µs | 3.042 µs | 2.988 µs | 1.00 | 0.02 | -This run shows HLSF significantly faster than libc under the current configuration. See the HLSF document for details and caveats. +This benchmark measures steady-state small-block allocation throughput (64B–4KB), +which represents the dominant allocation pattern in StgSharp's matrix computation pipeline. +HLSF uses a pre-allocated arena with size-class free lists, avoiding kernel-mode allocation calls. +Under this workload, HLSF achieves ~2.3× throughput over system malloc. This is not a general-purpose allocator comparison. ### Graphics and Rendering diff --git a/StgSharp.Benchmark/Program.cs b/StgSharp.Benchmark/Program.cs index 7c0343ed..5082f864 100644 --- a/StgSharp.Benchmark/Program.cs +++ b/StgSharp.Benchmark/Program.cs @@ -26,8 +26,8 @@ // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- using BenchmarkDotNet.Configs; -using BenchmarkDotNet.Loggers; using BenchmarkDotNet.Jobs; +using BenchmarkDotNet.Loggers; using BenchmarkDotNet.Running; using BenchmarkDotNet.Toolchains.InProcess.Emit; using StgSharp.Benchmark; @@ -41,10 +41,11 @@ namespace StgSharp.Benchmark string[] args ) { - IConfig config = ManualConfig.Create(DefaultConfig.Instance) - .AddLogger(ConsoleLogger.Default) - .AddJob(Job.Default.WithToolchain(InProcessEmitToolchain.Instance)); - BenchmarkRunner.Run(config); + IConfig config = ManualConfig.Create(DefaultConfig.Instance) + .AddLogger(ConsoleLogger.Default) + .AddJob(Job.Default + .WithToolchain(InProcessEmitToolchain.Instance)); + _ = BenchmarkRunner.Run(config); } } diff --git a/StgSharp.Benchmark/StgSharp.Benchmark.csproj b/StgSharp.Benchmark/StgSharp.Benchmark.csproj index da48fac9..530fc952 100644 --- a/StgSharp.Benchmark/StgSharp.Benchmark.csproj +++ b/StgSharp.Benchmark/StgSharp.Benchmark.csproj @@ -2,6 +2,7 @@ $(MSBuildProjectDirectory)\..\ + Exe diff --git a/StgSharp.Benchmark/SwissBenchmark.cs b/StgSharp.Benchmark/SwissBenchmark.cs new file mode 100644 index 00000000..b5437d64 --- /dev/null +++ b/StgSharp.Benchmark/SwissBenchmark.cs @@ -0,0 +1,254 @@ +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="SwissBenchmark" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using BenchmarkDotNet.Attributes; +using StgSharp.Collections; +using System; +using System.Collections.Generic; + +namespace StgSharp.Benchmark +{ + /// + /// Benchmark comparing SwissTable (SSE2 SIMD probing, zero-GC, native memory) against for the L4 cache address mapping workload: concentrated + /// small-key insert/lookup/remove cycles. SwissTable.Create() performs a 1 MB memset + /// (65536 × 16 control bytes), which is separated into IterationSetup to avoid polluting + /// insert timings. + /// + [MemoryDiagnoser] + public class SwissTableBench + { + + private const int LookupCount = 4096; + + private nint[] _lookupKeys = null!; + + // ── Pre-generated key arrays ── + + private nint[] _preloadedKeys = null!; + private Dictionary _dictLookup = null!; + private Dictionary _freshDict = null!; + + // ── Fresh instances for insert/mixed (rebuilt each iteration) ── + + private SwissTable _freshSwiss = null!; + + // ── Lookup targets (pre-filled in GlobalSetup) ── + + private SwissTable _swissLookup = null!; + + [Params(500, 2000, 5000)] + public int KeyCount; + + [GlobalCleanup] + public void Cleanup() + { + _dictLookup.Clear(); + _dictLookup.TrimExcess(); + } + + // ══════════════════════════════════════ + // Insert: pure write throughput + // Empty table → fill N keys + // Create() cost excluded via IterationSetup + // ══════════════════════════════════════ + + [Benchmark] + public void Dictionary_Insert() + { + Dictionary dict = _freshDict; + nint[] keys = _preloadedKeys; + for (int i = 0; i < keys.Length; i++) { + dict[keys[i]] = keys[i] * 2; + } + } + + // ══════════════════════════════════════ + // Lookup: pure read throughput + // Pre-filled table, random key access + // ══════════════════════════════════════ + + [Benchmark(Baseline = true)] + public nint Dictionary_Lookup() + { + nint sum = 0; + nint[] keys = _lookupKeys; + Dictionary dict = _dictLookup; + for (int i = 0; i < keys.Length; i++) + { + if (dict.TryGetValue(keys[i], out nint value)) { + sum += value; + } + } + return sum; + } + + // ══════════════════════════════════════ + // Mixed: insert all → lookup half → remove half → lookup all + // Simulates L4 cache lifecycle: + // load working set → compute → evict → recompute + // ══════════════════════════════════════ + + [Benchmark] + public nint Dictionary_Mixed() + { + Dictionary dict = _freshDict; + nint[] keys = _preloadedKeys; + nint sum = 0; + + // insert all + for (int i = 0; i < keys.Length; i++) + { + dict[keys[i]] = keys[i] * 2; + } + + // lookup first half + for (int i = 0; i < keys.Length / 2; i++) + { + if (dict.TryGetValue(keys[i], out nint value)) { + sum += value; + } + } + + // remove first half (eviction) + for (int i = 0; i < keys.Length / 2; i++) + { + dict.Remove(keys[i]); + } + + // lookup all (half hit, half miss) + for (int i = 0; i < keys.Length; i++) + { + if (dict.TryGetValue(keys[i], out nint value)) { + sum += value; + } + } + + return sum; + } + + [IterationSetup(Targets = [ + nameof(SwissTable_Insert), + nameof(SwissTable_Mixed), + nameof(Dictionary_Insert), + nameof(Dictionary_Mixed) + ])] + public void IterationSetup() + { + _freshSwiss = SwissTable.Create(); + _freshDict = new Dictionary(KeyCount); + } + + // ── Setup / Teardown ── + + [GlobalSetup] + public void Setup() + { + _preloadedKeys = new nint[KeyCount]; + _lookupKeys = new nint[LookupCount]; + + _swissLookup = SwissTable.Create(); + _dictLookup = new Dictionary(KeyCount); + + for (int i = 0; i < KeyCount; i++) + { + _preloadedKeys[i] = (nint)i; + _swissLookup.TryAddOrSet((nint)i, (nint)(i * 2), out _); + _dictLookup[(nint)i] = (nint)(i * 2); + } + + Random rng = new Random(42); + for (int i = 0; i < LookupCount; i++) { + _lookupKeys[i] = (nint)rng.Next(0, KeyCount); + } + } + + [Benchmark] + public void SwissTable_Insert() + { + SwissTable swiss = _freshSwiss; + nint[] keys = _preloadedKeys; + for (int i = 0; i < keys.Length; i++) { + swiss.TryAddOrSet(keys[i], keys[i] * 2, out _); + } + } + + [Benchmark] + public nint SwissTable_Lookup() + { + nint sum = 0; + nint[] keys = _lookupKeys; + SwissTable swiss = _swissLookup; + for (int i = 0; i < keys.Length; i++) + { + if (swiss.TryGet(keys[i], out nint value)) { + sum += value; + } + } + return sum; + } + + [Benchmark] + public nint SwissTable_Mixed() + { + SwissTable swiss = _freshSwiss; + nint[] keys = _preloadedKeys; + nint sum = 0; + + // insert all + for (int i = 0; i < keys.Length; i++) + { + swiss.TryAddOrSet(keys[i], keys[i] * 2, out _); + } + + // lookup first half + for (int i = 0; i < keys.Length / 2; i++) + { + if (swiss.TryGet(keys[i], out nint value)) { + sum += value; + } + } + + // remove first half (eviction) + for (int i = 0; i < keys.Length / 2; i++) + { + swiss.TryRemove(keys[i], out _); + } + + // lookup all (half hit, half miss) + for (int i = 0; i < keys.Length; i++) + { + if (swiss.TryGet(keys[i], out nint value)) { + sum += value; + } + } + + return sum; + } + + } +} \ No newline at end of file diff --git a/StgSharp.Common/Collections/SwissTable.X86.cs b/StgSharp.Common/Collections/SwissTable.X86.cs index 9ed3cef9..6b009f92 100644 --- a/StgSharp.Common/Collections/SwissTable.X86.cs +++ b/StgSharp.Common/Collections/SwissTable.X86.cs @@ -25,6 +25,7 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- +using System; using System.Numerics; using System.Runtime.Intrinsics; using System.Runtime.Intrinsics.X86; @@ -39,29 +40,26 @@ namespace StgSharp.Collections public bool TryFind( nint key, - uint Hash, + uint hash, Bucket* bucket, out nint value ) { - byte ctrl = (byte)(Hash >> 8); + byte ctrl = (byte)((hash >> EntryMaskWidth) & 0x7F); Vector128 ctrlVector = Vector128.Create(ctrl); - for (int i = 0; i < BucketSize; i += 16) + Vector128 bucketCtrlVector = Sse2.LoadVector128((byte*)&bucket->Control); + Vector128 cmpResult = Sse2.CompareEqual(ctrlVector, bucketCtrlVector); + int mask = Sse2.MoveMask(cmpResult); + while (mask != 0) { - Vector128 bucketCtrlVector = Sse2.LoadVector128(&bucket->Control.Control + i); - Vector128 cmpResult = Sse2.CompareEqual(ctrlVector, bucketCtrlVector); - int mask = Sse2.MoveMask(cmpResult); - while (mask != 0) + int bitPos = BitOperations.TrailingZeroCount(mask); + int index = bitPos; + if (bucket->Keys[index] == key) { - int bitPos = BitOperations.TrailingZeroCount(mask); - int index = i + bitPos; - if (bucket->Keys.value == key) - { - value = bucket->Values.value; - return true; - } - mask &= mask - 1; + value = bucket->Values[index]; + return true; } + mask &= mask - 1; } value = default; return false; @@ -74,29 +72,25 @@ namespace StgSharp.Collections out nint value ) { - byte ctrl = (byte)(hash >> 8); + byte ctrl = (byte)((hash >> EntryMaskWidth) & 0x7F); Vector128 ctrlVector = Vector128.Create(ctrl); - for (int i = 0; i < BucketSize; i += 16) - { - Vector128 bucketCtrl = Sse2.LoadVector128( - &bucket->Control[i]); - Vector128 matchMask = Sse2.CompareEqual(ctrlVector, bucketCtrl); - int matches = Sse2.MoveMask(matchMask); + Vector128 bucketCtrl = Sse2.LoadVector128((byte*)&bucket->Control); + Vector128 matchMask = Sse2.CompareEqual(ctrlVector, bucketCtrl); + int matches = Sse2.MoveMask(matchMask); - while (matches != 0) + while (matches != 0) + { + int bitPos = BitOperations.TrailingZeroCount(matches); + int index = bitPos; + if (bucket->Keys[index] == key) { - int bitPos = BitOperations.TrailingZeroCount(matches); - int index = i + bitPos; - if (bucket->Keys[index] == key) - { - value = bucket->Values[index]; - bucket->Control[index] = 0xFE; // mark as DELETED - // no need to remove Key/Value - return true; - } - matches &= matches - 1; + value = bucket->Values[index]; + bucket->Control[index] = 0xFE; // mark as DELETED + // no need to remove Key/Value + return true; } + matches &= matches - 1; } value = default; return false; @@ -110,64 +104,44 @@ namespace StgSharp.Collections out bool isNewKey ) { - byte ctrl = (byte)(hash >> 8); // H2: upper 8 bits (highest bit is naturally 0) + byte ctrl = (byte)((hash >> EntryMaskWidth) & 0x7F); // H2: upper 8 bits (highest bit is naturally 0) Vector128 ctrlVector = Vector128.Create(ctrl); int firstAvailableSlot = -1; // Record the first insertable slot - for (int i = 0; i < BucketSize; i += 16) + Vector128 bucketCtrl = Sse2.LoadVector128( + (byte*)&bucket->Control); + + // === Phase 1: Look up an existing key === + Vector128 matchMask = Sse2.CompareEqual(ctrlVector, bucketCtrl); + int matches = Sse2.MoveMask(matchMask); + + while (matches != 0) { - Vector128 bucketCtrl = Sse2.LoadVector128( - &bucket->Control[i]); - - // === Phase 1: Look up an existing key === - Vector128 matchMask = Sse2.CompareEqual(ctrlVector, bucketCtrl); - int matches = Sse2.MoveMask(matchMask); - - while (matches != 0) + int bitPos = BitOperations.TrailingZeroCount(matches); + int index = bitPos; + if (bucket->Keys[index] == key) { - int bitPos = BitOperations.TrailingZeroCount(matches); - int index = i + bitPos; - if (bucket->Keys[index] == key) - { - // Key already exists -> update value - bucket->Values[index] = value; - isNewKey = false; - return true; - } - matches &= matches - 1; - } - - // === Phase 2: Track an available insertion slot === - if (firstAvailableSlot == -1) - { - // Find EMPTY (0xFF) or DELETED (0xFE) - // Trick: bytes with high bit set are insertable - int emptyOrDeleted = Sse2.MoveMask(bucketCtrl); - - // MoveMask extracts the top bit of each byte - // EMPTY/DELETED top bit = 1 -> mask bit = 1 - // OCCUPIED top bit = 0 -> mask bit = 0 - - if (emptyOrDeleted != 0) - { - int bitPos = BitOperations.TrailingZeroCount(emptyOrDeleted); - firstAvailableSlot = i + bitPos; - } + // Key already exists -> update value + bucket->Values[index] = value; + isNewKey = false; + return true; } + matches &= matches - 1; } - // === Phase 3: Key not found, try to insert === - if (firstAvailableSlot == -1) + // === Phase 2: Track an available insertion slot === + int emptyOrDeleted = Sse2.MoveMask(bucketCtrl); + if (emptyOrDeleted == 0) { - // Bucket is full; resize is required isNewKey = false; - return false; + return false; // bucket full } - bucket->Control[firstAvailableSlot] = ctrl; - bucket->Keys[firstAvailableSlot] = key; - bucket->Values[firstAvailableSlot] = value; + int slot = BitOperations.TrailingZeroCount(emptyOrDeleted); + bucket->Control[slot] = ctrl; + bucket->Keys[slot] = key; + bucket->Values[slot] = value; isNewKey = true; return true; } diff --git a/StgSharp.Common/Collections/SwissTable.cs b/StgSharp.Common/Collections/SwissTable.cs index 18798384..e5917ecd 100644 --- a/StgSharp.Common/Collections/SwissTable.cs +++ b/StgSharp.Common/Collections/SwissTable.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="SwissTable" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -41,41 +41,51 @@ namespace StgSharp.Collections { private const int BucketCount = 1 << EntryMaskWidth; - private const int BucketSize = 256; - private const int EntryMaskWidth = 10; // 1024 entries total, 256 per bucket - public const int MaxCapacity = 1024 * BucketSize; // 256 entries per bucket, 1024 buckets - + private const int BucketSize = 16; + private const uint CrcMagic = 0xffff9961; // Magic number for CRC32C, used in hash computation + private const int EntryMaskWidth = 16; // 65536 entries total, 16 per bucket + public const int MaxCapacity = BucketCount * BucketSize; // 256 entries per bucket, 1024 buckets + private readonly Entry* _entries; - private SwissTable(Entry* buffer) + private SwissTable( + Entry* buffer + ) { _entries = buffer; - for (int i = 0; i < BucketCount; i++) - { - // Set all control bytes to 0xFF (empty) - Unsafe.InitBlock(&_entries[i].Bucket.Control, 0xFF, BucketSize); - } } public static SwissTable Create() { - Entry* buffer = (Entry*)NativeMemory.AlignedAlloc((nuint)Marshal.SizeOf(), 16); + Entry* buffer = (Entry*)NativeMemory.AlignedAlloc((nuint)Unsafe.SizeOf(), 16); + for (int i = 0; i < BucketCount; i++) + { + // Set all control bytes to 0xFF (empty) + Unsafe.InitBlock(&(*buffer)[i].Control, 0xFF, BucketSize); + } return new SwissTable(buffer); } - public bool TryAddOrSet(nint key, nint value, out bool isNewKey) + public bool TryAddOrSet( + nint key, + nint value, + out bool isNewKey + ) { - uint hash = BitOperations.Crc32C(0xffff9961, (ulong)key); - short entry = (short)(hash & ((1 << 11) - 1)); - Bucket* bucket = &_entries[entry].Bucket; + uint hash = BitOperations.Crc32C(CrcMagic, (ulong)key); + ushort entry = (ushort)(hash & (BucketCount - 1)); + Bucket* bucket = &(*_entries)[entry]; return IBucketScanner.Current.TrySet(key, hash, bucket, value, out isNewKey); } - public bool TryGet(nint key, out nint value) + public bool TryGet( + nint key, + out nint value + ) { - uint hash = BitOperations.Crc32C(0xffff9961, (ulong)key); - short entry = (short)(hash & ((1 << 11) - 1)); - Bucket* bucket = &_entries[entry].Bucket; + uint hash = BitOperations.Crc32C(CrcMagic, (ulong)key); + ushort entry = (ushort)(hash & (BucketCount - 1)); + Bucket* bucket = &(*_entries)[entry]; return IBucketScanner.Current.TryFind(key, hash, bucket, out value); /* * hash = CRC32 of key @@ -86,11 +96,14 @@ namespace StgSharp.Collections */ } - public bool TryRemove(nint key, out nint value) + public bool TryRemove( + nint key, + out nint value + ) { - uint hash = BitOperations.Crc32C(0xffff9961, (ulong)key); - short entry = (short)(hash & ((1 << 11) - 1)); - Bucket* bucket = &_entries[entry].Bucket; + uint hash = BitOperations.Crc32C(CrcMagic, (ulong)key); + ushort entry = (ushort)(hash & (BucketCount - 1)); + Bucket* bucket = &(*_entries)[entry]; return IBucketScanner.Current.TryRemove(key, hash, bucket, out value); } @@ -121,15 +134,31 @@ namespace StgSharp.Collections static IBucketScanner Current { get; } = Create(); - bool TryFind(nint key, uint Hash, Bucket* bucket, out nint value); + bool TryFind( + nint key, + uint Hash, + Bucket* bucket, + out nint value + ); - unsafe bool TryRemove(nint key, uint hash, Bucket* bucket, out nint value); + unsafe bool TryRemove( + nint key, + uint hash, + Bucket* bucket, + out nint value + ); - bool TrySet(nint key, uint hash, Bucket* bucket, nint value, out bool isNewKey); + bool TrySet( + nint key, + uint hash, + Bucket* bucket, + nint value, + out bool isNewKey + ); private static IBucketScanner Create() { - if (X86Base.IsSupported) + if (Sse42.IsSupported) { return new BucketScannerX86(); } else if (ArmBase.IsSupported) diff --git a/StgSharp.Graphics/Camera.cs b/StgSharp.Graphics/Camera.cs index 56d7fe0f..71c4134d 100644 --- a/StgSharp.Graphics/Camera.cs +++ b/StgSharp.Graphics/Camera.cs @@ -58,7 +58,11 @@ namespace StgSharp.Mathematics.Graphics _projection = new Matrix44(); } - public Camera(Vec3 position, Vec3 target, Vec3 up) + public Camera( + Vec3 position, + Vec3 target, + Vec3 up + ) : this() { rotationAtt = Matrix44.Unit; @@ -103,13 +107,16 @@ namespace StgSharp.Mathematics.Graphics /// Shader program requires this camera. /// /// - /// ContextName of all related uniforms. If you fallow form from /// /// /// /// - public unsafe void GainAllUniforms(ShaderProgram source, params string[] uniformName) + public unsafe void GainAllUniforms( + ShaderProgram source, + params string[] uniformName + ) { if (uniformName is null || uniformName.Length != 1) { throw new ArgumentException( @@ -118,19 +125,25 @@ namespace StgSharp.Mathematics.Graphics convertedUniform = source.GetUniform(uniformName[0]); } - public void MoveNear(float distance) + public void MoveNear( + float distance + ) { cameraAtt.column[3].Z -= distance; _isLookAtAvailable = false; } - public void MoveRight(float distance) + public void MoveRight( + float distance + ) { cameraAtt.column[3].X -= distance; _isLookAtAvailable = false; } - public void MoveUp(float distance) + public void MoveUp( + float distance + ) { cameraAtt.column[3].Y -= distance; _isLookAtAvailable = false; @@ -142,7 +155,11 @@ namespace StgSharp.Mathematics.Graphics OpenGLFunction.CurrentGL.SetUniformValue(convertedUniform, Projection * View); } - public void SetViewDirection(Vec3 position, Vec3 target, Vec3 up) + public void SetViewDirection( + Vec3 position, + Vec3 target, + Vec3 up + ) { Vec3 direction = position - target; if ((position.reg == cameraAtt.column[3].reg) && @@ -181,7 +198,8 @@ namespace StgSharp.Mathematics.Graphics Radius fovRadius, Vec2 size, Vec2 offset, - (float front, float back) depthRange) + (float front, float back) depthRange + ) { float distance = _target.GetLength(), @@ -189,7 +207,7 @@ namespace StgSharp.Mathematics.Graphics far = distance + depthRange.back, offsetX = offset.X, offsetY = offset.Y, - width = Scalar.Abs(GeometryScaler.Tan(fovRadius / 2) * near * 2), + width = MathF.Abs(GeometryScaler.Tan(fovRadius / 2) * near * 2), height = width * size.Y / size.X; _projection.column[0].X = 2 * near / width; @@ -201,7 +219,9 @@ namespace StgSharp.Mathematics.Graphics _projection.column[3].Z = 2 * near * far / (near - far); } - public void Test(params Vec4[] vec) + public void Test( + params Vec4[] vec + ) { Console.WriteLine(View); Console.WriteLine(Projection); @@ -221,7 +241,9 @@ namespace StgSharp.Mathematics.Graphics #region rotation - public void Yaw(Radius r) + public void Yaw( + Radius r + ) { _yaw -= r; @@ -230,7 +252,9 @@ namespace StgSharp.Mathematics.Graphics InternalYaw(); } - public void Pitch(Radius r) + public void Pitch( + Radius r + ) { _pitch -= r; @@ -239,7 +263,9 @@ namespace StgSharp.Mathematics.Graphics InternalPitch(); } - public void Row(Radius r) + public void Row( + Radius r + ) { _row -= r; diff --git a/StgSharp.Mathematics/Numeric/Scalar/Function.cs b/StgSharp.Graphics/Global.cs similarity index 89% rename from StgSharp.Mathematics/Numeric/Scalar/Function.cs rename to StgSharp.Graphics/Global.cs index 571618d0..8210befb 100644 --- a/StgSharp.Mathematics/Numeric/Scalar/Function.cs +++ b/StgSharp.Graphics/Global.cs @@ -1,6 +1,6 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="Function" +// file="Global" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -25,7 +25,5 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- -namespace StgSharp.Mathematics -{ - public class Function { } -} +global using StgSharp.Internal; +global using System; \ No newline at end of file diff --git a/StgSharp.Graphics/OpenGL/ShaderEdit/Shader.cs b/StgSharp.Graphics/OpenGL/ShaderEdit/Shader.cs index cbe4b5b5..fdddf91c 100644 --- a/StgSharp.Graphics/OpenGL/ShaderEdit/Shader.cs +++ b/StgSharp.Graphics/OpenGL/ShaderEdit/Shader.cs @@ -66,7 +66,7 @@ namespace StgSharp.Graphics.OpenGL } - public class Shader : ISSDSerializable + public class Shader { private readonly OpenGLFunction GL; @@ -84,8 +84,6 @@ namespace StgSharp.Graphics.OpenGL type = usage; } - public SerializableTypeCode SSDTypeCode => SerializableTypeCode.Shader; - /// /// Attach one shader code to a shader program. /// diff --git a/StgSharp.Graphics/OpenGL/glApiManager.cs b/StgSharp.Graphics/OpenGL/glApiManager.cs index 9083afb1..74304e5b 100644 --- a/StgSharp.Graphics/OpenGL/glApiManager.cs +++ b/StgSharp.Graphics/OpenGL/glApiManager.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="glApiManager" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,11 +25,9 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- +using StgSharp.Internal; using StgSharp.Mathematics; using StgSharp.Mathematics; -using StgSharp.MVVM; -using StgSharp.MVVM; - using System; using System.Collections.Generic; using System.Linq; @@ -52,15 +50,15 @@ namespace StgSharp.Graphics.OpenGL "OpenGL SC " }; - private static string glExtensionList; - /// /// Load all supported OpenGL APIs and bind them to given . /// /// /// The handle to current OpenGL viewPortDisplay /// - public static unsafe void LoadOpenGLApiTo(IntPtr contextHandle) + public static unsafe void LoadOpenGLApiTo( + IntPtr contextHandle + ) { OpenglContext* context = (OpenglContext*)contextHandle; if (context->glGetString != null) { @@ -81,12 +79,13 @@ namespace StgSharp.Graphics.OpenGL if (context->glGetString(glVersion) == null) { DefaultLog.InternalWriteLog("Failed to call glGetString", LogType.Error); } - coreVersion = Marshal.PtrToStringAnsi((nint)context->glGetString(glVersion)) ?? string.Empty; + coreVersion = Marshal.PtrToStringAnsi((nint)context->glGetString(glVersion)) ?? + string.Empty; foreach (string branch in glBranch) { - if (coreVersion.Contains(branch)) { - coreVersion.Replace(branch, string.Empty); + if (coreVersion.Contains(branch, StringComparison.Ordinal)) { + coreVersion.Replace(branch, string.Empty, StringComparison.Ordinal); } } string[] versionSep = coreVersion!.Split('.'); @@ -163,182 +162,182 @@ namespace StgSharp.Graphics.OpenGL if (extensions.Contains("gl_AMD_blend_minmax_factor")) { AMD_blend_minmax_factor = true; - extensions.Remove("glAMD_blend_minmax_factor"); + extensions.Remove("gl_AMD_blend_minmax_factor"); } if (extensions.Contains("gl_AMD_conservative_depth")) { AMD_conservative_depth = true; - extensions.Remove("glAMD_conservative_depth"); + extensions.Remove("gl_AMD_conservative_depth"); } if (extensions.Contains("gl_AMD_debug_output")) { AMD_debug_output = true; - extensions.Remove("glAMD_debug_output"); + extensions.Remove("gl_AMD_debug_output"); } if (extensions.Contains("gl_AMD_depth_clamp_separate")) { AMD_depth_clamp_separate = true; - extensions.Remove("glAMD_depth_clamp_separate"); + extensions.Remove("gl_AMD_depth_clamp_separate"); } if (extensions.Contains("gl_AMD_draw_buffers_blend")) { AMD_draw_buffers_blend = true; - extensions.Remove("glAMD_draw_buffers_blend"); + extensions.Remove("gl_AMD_draw_buffers_blend"); } if (extensions.Contains("gl_AMD_framebuffer_multisample_advanced")) { AMD_framebuffer_multisample_advanced = true; - extensions.Remove("glAMD_framebuffer_multisample_advanced"); + extensions.Remove("gl_AMD_framebuffer_multisample_advanced"); } if (extensions.Contains("gl_AMD_framebuffer_sample_positions")) { AMD_framebuffer_sample_positions = true; - extensions.Remove("glAMD_framebuffer_sample_positions"); + extensions.Remove("gl_AMD_framebuffer_sample_positions"); } if (extensions.Contains("gl_AMD_gcn_shader")) { AMD_gcn_shader = true; - extensions.Remove("glAMD_gcn_shader"); + extensions.Remove("gl_AMD_gcn_shader"); } if (extensions.Contains("gl_AMD_gpu_shader_half_float")) { AMD_gpu_shader_half_float = true; - extensions.Remove("glAMD_gpu_shader_half_float"); + extensions.Remove("gl_AMD_gpu_shader_half_float"); } if (extensions.Contains("gl_AMD_gpu_shader_int16")) { AMD_gpu_shader_int16 = true; - extensions.Remove("glAMD_gpu_shader_int16"); + extensions.Remove("gl_AMD_gpu_shader_int16"); } if (extensions.Contains("gl_AMD_gpu_shader_int64")) { AMD_gpu_shader_int64 = true; - extensions.Remove("glAMD_gpu_shader_int64"); + extensions.Remove("gl_AMD_gpu_shader_int64"); } if (extensions.Contains("gl_AMD_interleaved_elements")) { AMD_interleaved_elements = true; - extensions.Remove("glAMD_interleaved_elements"); + extensions.Remove("gl_AMD_interleaved_elements"); } if (extensions.Contains("gl_AMD_multi_draw_indirect")) { AMD_multi_draw_indirect = true; - extensions.Remove("glAMD_multi_draw_indirect"); + extensions.Remove("gl_AMD_multi_draw_indirect"); } if (extensions.Contains("gl_AMD_name_gen_delete")) { AMD_name_gen_delete = true; - extensions.Remove("glAMD_name_gen_delete"); + extensions.Remove("gl_AMD_name_gen_delete"); } if (extensions.Contains("gl_AMD_occlusion_query_event")) { AMD_occlusion_query_event = true; - extensions.Remove("glAMD_occlusion_query_event"); + extensions.Remove("gl_AMD_occlusion_query_event"); } if (extensions.Contains("gl_AMD_performance_monitor")) { AMD_performance_monitor = true; - extensions.Remove("glAMD_performance_monitor"); + extensions.Remove("gl_AMD_performance_monitor"); } if (extensions.Contains("gl_AMD_pinned_memory")) { AMD_pinned_memory = true; - extensions.Remove("glAMD_pinned_memory"); + extensions.Remove("gl_AMD_pinned_memory"); } if (extensions.Contains("gl_AMD_query_buffer_object")) { AMD_query_buffer_object = true; - extensions.Remove("glAMD_query_buffer_object"); + extensions.Remove("gl_AMD_query_buffer_object"); } if (extensions.Contains("gl_AMD_sample_positions")) { AMD_sample_positions = true; - extensions.Remove("glAMD_sample_positions"); + extensions.Remove("gl_AMD_sample_positions"); } if (extensions.Contains("gl_AMD_seamless_cubemap_per_texture")) { AMD_seamless_cubemap_per_texture = true; - extensions.Remove("glAMD_seamless_cubemap_per_texture"); + extensions.Remove("gl_AMD_seamless_cubemap_per_texture"); } if (extensions.Contains("gl_AMD_shader_atomic_counter_ops")) { AMD_shader_atomic_counter_ops = true; - extensions.Remove("glAMD_shader_atomic_counter_ops"); + extensions.Remove("gl_AMD_shader_atomic_counter_ops"); } if (extensions.Contains("gl_AMD_shader_ballot")) { AMD_shader_ballot = true; - extensions.Remove("glAMD_shader_ballot"); + extensions.Remove("gl_AMD_shader_ballot"); } if (extensions.Contains("gl_AMD_shader_explicit_vertex_parameter")) { AMD_shader_explicit_vertex_parameter = true; - extensions.Remove("glAMD_shader_explicit_vertex_parameter"); + extensions.Remove("gl_AMD_shader_explicit_vertex_parameter"); } if (extensions.Contains("gl_AMD_shader_gpu_shader_half_float_fetch")) { AMD_shader_gpu_shader_half_float_fetch = true; - extensions.Remove("glAMD_shader_gpu_shader_half_float_fetch"); + extensions.Remove("gl_AMD_shader_gpu_shader_half_float_fetch"); } if (extensions.Contains("gl_AMD_shader_image_load_store_lod")) { AMD_shader_image_load_store_lod = true; - extensions.Remove("glAMD_shader_image_load_store_lod"); + extensions.Remove("gl_AMD_shader_image_load_store_lod"); } if (extensions.Contains("gl_AMD_shader_stencil_export")) { AMD_shader_stencil_export = true; - extensions.Remove("glAMD_shader_stencil_export"); + extensions.Remove("gl_AMD_shader_stencil_export"); } if (extensions.Contains("gl_AMD_shader_trinary_minmax")) { AMD_shader_trinary_minmax = true; - extensions.Remove("glAMD_shader_trinary_minmax"); + extensions.Remove("gl_AMD_shader_trinary_minmax"); } if (extensions.Contains("gl_AMD_sparse_texture")) { AMD_sparse_texture = true; - extensions.Remove("glAMD_sparse_texture"); + extensions.Remove("gl_AMD_sparse_texture"); } if (extensions.Contains("gl_AMD_stencil_operation_extended")) { AMD_stencil_operation_extended = true; - extensions.Remove("glAMD_stencil_operation_extended"); + extensions.Remove("gl_AMD_stencil_operation_extended"); } if (extensions.Contains("gl_AMD_texture_gather_bias_lod")) { AMD_texture_gather_bias_lod = true; - extensions.Remove("glAMD_texture_gather_bias_lod"); + extensions.Remove("gl_AMD_texture_gather_bias_lod"); } if (extensions.Contains("gl_AMD_texture_texture4")) { AMD_texture_texture4 = true; - extensions.Remove("glAMD_texture_texture4"); + extensions.Remove("gl_AMD_texture_texture4"); } if (extensions.Contains("gl_AMD_transform_feedback3_lines_triangles")) { AMD_transform_feedback3_lines_triangles = true; - extensions.Remove("glAMD_transform_feedback3_lines_triangles"); + extensions.Remove("gl_AMD_transform_feedback3_lines_triangles"); } if (extensions.Contains("gl_AMD_transform_feedback4")) { AMD_transform_feedback4 = true; - extensions.Remove("glAMD_transform_feedback4"); + extensions.Remove("gl_AMD_transform_feedback4"); } if (extensions.Contains("gl_AMD_vertex_shader_layer")) { AMD_vertex_shader_layer = true; - extensions.Remove("glAMD_vertex_shader_layer"); + extensions.Remove("gl_AMD_vertex_shader_layer"); } if (extensions.Contains("gl_AMD_vertex_shader_tessellator")) { AMD_vertex_shader_tessellator = true; - extensions.Remove("glAMD_vertex_shader_tessellator"); + extensions.Remove("gl_AMD_vertex_shader_tessellator"); } if (extensions.Contains("gl_AMD_vertex_shader_viewport_index")) { AMD_vertex_shader_viewport_index = true; - extensions.Remove("glAMD_vertex_shader_viewport_index"); + extensions.Remove("gl_AMD_vertex_shader_viewport_index"); } if (extensions.Contains("gl_APPLE_aux_depth_stencil")) { @@ -3244,7 +3243,10 @@ namespace StgSharp.Graphics.OpenGL #endregion checkGLextensions } - internal static void CheckCoreVersion(int majorVersion, int minorVersion) + internal static void CheckCoreVersion( + int majorVersion, + int minorVersion + ) { if (majorVersion < 3) { throw new InvalidOperationException( @@ -3410,7 +3412,9 @@ namespace StgSharp.Graphics.OpenGL } } - internal static unsafe string GetExtensions(this OpenglContext context) + internal static unsafe string GetExtensions( + this OpenglContext context + ) { if (context.glGetString == null) { return string.Empty; diff --git a/StgSharp.Graphics/OpenGL/glRenderStream.cs b/StgSharp.Graphics/OpenGL/glRenderStream.cs index e1aa3911..76c56da3 100644 --- a/StgSharp.Graphics/OpenGL/glRenderStream.cs +++ b/StgSharp.Graphics/OpenGL/glRenderStream.cs @@ -50,10 +50,7 @@ namespace StgSharp.Graphics.OpenGL private OpenGLFunction _context; - protected internal OpenGLFunction GL - { - get { return _context; } - } + protected internal OpenGLFunction GL => _context; /// /// Initialize an opengl context and load all opengl functions. @@ -169,29 +166,5 @@ namespace StgSharp.Graphics.OpenGL NativeCamera.SetViewDirection(position, direction, up); } - #region Key Control - - protected KeyStatus CheckKey( - KeyboardKey key - ) - { - return GraphicFramework.glfwGetKey(this.CanvasHandle, (int)key); - } - - protected KeyStatus CheckKey( - Mouse key - ) - { - return GraphicFramework.glfwGetKey(this.CanvasHandle, (int)key); - } - - protected KeyStatus CheckKey( - Joystick key - ) - { - return GraphicFramework.glfwGetKey(this.CanvasHandle, (int)key); - } - - #endregion } } diff --git a/StgSharp.Graphics/glfw.cs b/StgSharp.Graphics/glfw.cs index c1394228..ac6e3c70 100644 --- a/StgSharp.Graphics/glfw.cs +++ b/StgSharp.Graphics/glfw.cs @@ -39,11 +39,18 @@ namespace StgSharp.Graphics public string ModuleName => "Graphic"; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void InitializeModule() + public void InitializeModule( + IModuleInitializeProfile profile + ) { GraphicFramework.LoadGlfw(); } + public void UninitializeModule() + { + GraphicFramework.glfwTerminate(); + } + } internal static unsafe partial class GraphicFramework @@ -702,12 +709,15 @@ namespace StgSharp.Graphics } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe byte* glfwGetKeyName( - int key, - int scancode + internal static unsafe ReadOnlySpan glfwGetKeyName( + int key, + int scancode ) { - return _glfw.glfwGetKeyName(key, scancode); + byte* ptr = _glfw.glfwGetKeyName(key, scancode); + int count = 0; + for (; ptr[count] != 0; count++) { } + return new ReadOnlySpan(ptr, count); } [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -717,15 +727,17 @@ namespace StgSharp.Graphics { return _glfw.glfwGetKeyScancode(key); } + /**/ [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe KeyStatus glfwGetKey( - IntPtr window, - int key + internal static unsafe int glfwGetKey( + IntPtr window, + int key ) { return _glfw.glfwGetKey(window, key); } + /**/ [MethodImpl(MethodImplOptions.AggressiveInlining)] internal static unsafe int glfwGetMouseButton( diff --git a/StgSharp.Graphics/glfw.function.cs b/StgSharp.Graphics/glfw.function.cs index 4dc85105..c82fb862 100644 --- a/StgSharp.Graphics/glfw.function.cs +++ b/StgSharp.Graphics/glfw.function.cs @@ -58,7 +58,7 @@ namespace StgSharp.Internal public delegate* unmanaged[Cdecl] glfwGetJoystickHats; public delegate* unmanaged[Cdecl] glfwGetJoystickName; public delegate* unmanaged[Cdecl] glfwGetJoystickUserPointer; - public delegate* unmanaged[Cdecl] glfwGetKey; + public delegate* unmanaged[Cdecl] glfwGetKey; public delegate* unmanaged[Cdecl] glfwGetKeyName; public delegate* unmanaged[Cdecl] glfwGetKeyScancode; public delegate* unmanaged[Cdecl] glfwGetMonitorContentScale; diff --git a/StgSharp.Mathematics/Geometries/GeometryScaler/Angle.cs b/StgSharp.Mathematics/Geometries/GeometryScaler/Angle.cs index a7b366a8..d927a67f 100644 --- a/StgSharp.Mathematics/Geometries/GeometryScaler/Angle.cs +++ b/StgSharp.Mathematics/Geometries/GeometryScaler/Angle.cs @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="Angle" // Project: StgSharp @@ -37,46 +37,60 @@ namespace StgSharp.Mathematics public static partial class GeometryScaler { - internal const float DegToRad = 180 / Scalar.Pi; + internal const float DegToRad = 180 / MathF.PI; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cos(Radius r) + public static float Cos( + Radius r + ) { return MathF.Cos(r._radius); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cos(Degree r) + public static float Cos( + Degree r + ) { return MathF.Cos(r._degree / DegToRad); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Sin(Radius r) + public static float Sin( + Radius r + ) { return MathF.Sin(r._radius); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Sin(Degree r) + public static float Sin( + Degree r + ) { return MathF.Sin(r._degree / DegToRad); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Tan(Radius r) + public static float Tan( + Radius r + ) { return MathF.Tan(r._radius); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Tan(Degree r) + public static float Tan( + Degree r + ) { return MathF.Tan(r._degree / DegToRad); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Degree ToDegree(float value) + public static Degree ToDegree( + float value + ) { return new Degree(value); } @@ -88,12 +102,16 @@ namespace StgSharp.Mathematics internal float _degree; - public Degree(float dgree) + public Degree( + float dgree + ) { _degree = dgree; } - public static implicit operator Radius(Degree d) + public static implicit operator Radius( + Degree d + ) { return new Radius(d._degree / GeometryScaler.DegToRad); } @@ -108,7 +126,9 @@ namespace StgSharp.Mathematics [Obsolete("Unsafe, you may forget this is radius.", true)] public Radius() { } - public Radius(float radius) + public Radius( + float radius + ) { _radius = radius; } @@ -119,56 +139,81 @@ namespace StgSharp.Mathematics } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Radius operator -(Radius r) + public static Radius operator -( + Radius r + ) { return new Radius(-r._radius); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Radius operator -(Radius left, Radius Right) + public static Radius operator -( + Radius left, + Radius Right + ) { return new Radius(left._radius - Right._radius); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator !=(Radius left, Radius right) + public static bool operator !=( + Radius left, + Radius right + ) { return left._radius != right._radius; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Radius operator *(Radius left, float right) + public static Radius operator *( + Radius left, + float right + ) { return new Radius(left._radius * right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Radius operator /(Radius left, float right) + public static Radius operator /( + Radius left, + float right + ) { return new Radius(left._radius / right); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float operator /(Radius left, Radius right) + public static float operator /( + Radius left, + Radius right + ) { return left._radius / right._radius; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static Radius operator +(Radius left, Radius Right) + public static Radius operator +( + Radius left, + Radius Right + ) { return new Radius(left._radius + Right._radius); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static bool operator ==(Radius left, Radius right) + public static bool operator ==( + Radius left, + Radius right + ) { return left._radius == right._radius; } - public static implicit operator Degree(Radius r) + public static implicit operator Degree( + Radius r + ) { - return new Degree((r._radius * 180) / Scalar.Pi); + return new Degree(r._radius * 180 / MathF.PI); } } diff --git a/StgSharp.Mathematics/Numeric/Scalar/Tan.cs b/StgSharp.Mathematics/Global.cs similarity index 80% rename from StgSharp.Mathematics/Numeric/Scalar/Tan.cs rename to StgSharp.Mathematics/Global.cs index 55bf2cc1..9292f53b 100644 --- a/StgSharp.Mathematics/Numeric/Scalar/Tan.cs +++ b/StgSharp.Mathematics/Global.cs @@ -1,6 +1,6 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- -// file="Tan" +// file="Global" // Project: StgSharp // AuthorGroup: Nitload // Copyright (c) Nitload. All rights reserved. @@ -25,19 +25,12 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- -using System; +global using StgSharp.Internal; +global using StgSharp.Mathematics.Internal; +global using System; + +global using System.Numerics; +global using System.Threading; using System.Runtime.CompilerServices; -namespace StgSharp.Mathematics -{ - public static partial class Scalar - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Tan(float x) - { - return MathF.Tan(x); - } - - } -} +[assembly: InternalsVisibleTo("StgSharp.Graphics")] diff --git a/StgSharp.Mathematics/Internal/MatrixPanel.cs b/StgSharp.Mathematics/Internal/MatrixPanel.cs index 87a94ecb..a5be8589 100644 --- a/StgSharp.Mathematics/Internal/MatrixPanel.cs +++ b/StgSharp.Mathematics/Internal/MatrixPanel.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="MatrixPanel" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,14 +25,14 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- -using StgSharp.Internal; using StgSharp.Mathematics.Internal; +using StgSharp.Mathematics.Numeric; using System; using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -namespace StgSharp.Mathematics +namespace StgSharp.Mathematics.Numeric { public unsafe struct MatrixPanel { @@ -42,37 +42,41 @@ namespace StgSharp.Mathematics private byte Head; // Allocate aligned memory for one panel; caller must free via Destroy. - public static unsafe MatrixPanel* Create() where T: unmanaged, INumber + public static unsafe MatrixPanel* Create() where T : unmanaged, INumber { return (MatrixPanel*)NativeMemory.AlignedAlloc(Size(), AlignmentBytes); } - public static unsafe void Destroy(MatrixPanel* panel) where T: unmanaged, INumber + public static unsafe void Destroy( + MatrixPanel* panel + ) where T : unmanaged, INumber { NativeMemory.AlignedFree(panel); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe Span Elements(ref T head) where T: unmanaged, INumber + public static unsafe Span Elements( + ref T head + ) where T : unmanaged, INumber { void* p = Unsafe.AsPointer(ref head); return new Span(p, MaxElementCount()); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static int ElementSideLength() where T: unmanaged, INumber + public static int ElementSideLength() where T : unmanaged, INumber { return PanelSideLength(); } - public static int MaxElementCount() where T: unmanaged, INumber + public static int MaxElementCount() where T : unmanaged, INumber { int side = ElementSideLength(); return side * side; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static nuint Size() where T: unmanaged, INumber + public static nuint Size() where T : unmanaged, INumber { return (nuint)(MaxElementCount() * sizeof(T)); } @@ -81,7 +85,7 @@ namespace StgSharp.Mathematics /// Number of 4x4 kernels that fit in a panel for the given ISA and element T. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int KernelCapacity() where T: unmanaged, INumber + internal static int KernelCapacity() where T : unmanaged, INumber { int perSide = KernelSideCount(); return perSide * perSide; @@ -91,9 +95,9 @@ namespace StgSharp.Mathematics /// How many 4x4 kernels fit along a single panel dimension for the given ISA. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static int KernelSideCount() where T: unmanaged, INumber + internal static int KernelSideCount() where T : unmanaged, INumber { - SIMDID id = NumericalModule.IntrinsicMask; + SIMDID id = NumericalModule.GlobalIntrinsicMask; switch (id.MaskByte[0] & 0b_00001111) { case 1: @@ -110,31 +114,35 @@ namespace StgSharp.Mathematics } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static unsafe nuint Align64(void* p) + private static unsafe nuint Align64( + void* p + ) { return ((nuint)p + (AlignmentBytes - 1)) & ~(nuint)(AlignmentBytes - 1); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int KernelSideCountAvx2() where T: unmanaged, INumber + private static int KernelSideCountAvx2() where T : unmanaged, INumber { return PanelSideFromBits(256) / 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int KernelSideCountAvx512() where T: unmanaged, INumber + private static int KernelSideCountAvx512() where T : unmanaged, INumber { return PanelSideFromBits(512) / 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int KernelSideCountSse() where T: unmanaged, INumber + private static int KernelSideCountSse() where T : unmanaged, INumber { return PanelSideFromBits(128) / 4; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int PanelSideFromBits(int vectorBits) where T: unmanaged, INumber + private static int PanelSideFromBits( + int vectorBits + ) where T : unmanaged, INumber { int elemBits = sizeof(T) * 8; @@ -146,9 +154,9 @@ namespace StgSharp.Mathematics } [MethodImpl(MethodImplOptions.AggressiveInlining)] - private static int PanelSideLength() where T: unmanaged, INumber + private static int PanelSideLength() where T : unmanaged, INumber { - SIMDID id = NumericalModule.IntrinsicMask; + SIMDID id = NumericalModule.GlobalIntrinsicMask; switch (id.MaskByte[0] & 0b_00001111) { case 1: @@ -167,12 +175,15 @@ namespace StgSharp.Mathematics } // Single POD-style panel: ZMM-compatible size. Alignment handled by allocator, not by the struct. - public unsafe struct MatrixPanel where T: unmanaged, INumber + public unsafe struct MatrixPanel where T : unmanaged, INumber { internal T Head; // first element of the panel buffer - public ref T this[int column, int row] + public ref T this[ + int column, + int row + ] { [MethodImpl(MethodImplOptions.AggressiveInlining)] get => ref Unsafe.Add(ref Head, row * MatrixPanel.ElementSideLength() + column); diff --git a/StgSharp.Mathematics/Internal/MatrixParallelTask.cs b/StgSharp.Mathematics/Internal/MatrixParallelTask.cs index b1ea87d3..32e2a01a 100644 --- a/StgSharp.Mathematics/Internal/MatrixParallelTask.cs +++ b/StgSharp.Mathematics/Internal/MatrixParallelTask.cs @@ -39,14 +39,20 @@ namespace StgSharp.Mathematics.Internal [FieldOffset(0)]public MatrixKernel* Mat1; // 8 [FieldOffset(8)] public MatrixKernel* Mat2; // 8 [FieldOffset(16)] public MatrixKernel* Mat3; // 16 - [FieldOffset(32)] public int CommonX; [FieldOffset(40)] public int Common_k; + [FieldOffset(32)] public int CommonX; [FieldOffset(36)] public int CommonY; [FieldOffset(44)] public int i; [FieldOffset(48)] public int j; [FieldOffset(52)] public int k; [FieldOffset(56)] public MatrixElementType ElementType; // 56 [FieldOffset(24)] public nint Span; // 24 + [FieldOffset(64)] public ScalarPacket Scalar; + + public MatrixParallelTask() + { + Unsafe.SkipInit(out this); + } [MethodImpl(MethodImplOptions.AggressiveInlining)] public static void Copy( diff --git a/StgSharp.Mathematics/Internal/UnsafeCompute.cs b/StgSharp.Mathematics/Internal/UnsafeCompute.cs index 95829078..ded4f415 100644 --- a/StgSharp.Mathematics/Internal/UnsafeCompute.cs +++ b/StgSharp.Mathematics/Internal/UnsafeCompute.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="UnsafeCompute" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,7 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- +using StgSharp.Mathematics.Numeric; using System.Runtime.CompilerServices; namespace StgSharp.Mathematics.Internal @@ -33,19 +34,30 @@ namespace StgSharp.Mathematics.Internal { [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int CityHashSimplify(char* span, int length) + public static unsafe int CityHashSimplify( + char* span, + int length + ) { return NumericalModule.GlobalContext.city_hash_simplify(span, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int CityHashSimplify(char* span, int begin, int length) + public static unsafe int CityHashSimplify( + char* span, + int begin, + int length + ) { return NumericalModule.GlobalContext.city_hash_simplify(span + begin, length); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int IndexOfCharPair(char* source, int pairValue, int length) + public static unsafe int IndexOfCharPair( + char* source, + int pairValue, + int length + ) { return NumericalModule.GlobalContext.index_pair(source, pairValue, length); } diff --git a/StgSharp.Mathematics/Numeric/Graphics/Vector.GetAngle.cs b/StgSharp.Mathematics/Numeric/Graphics/Vector.GetAngle.cs index 18790f93..86db82d0 100644 --- a/StgSharp.Mathematics/Numeric/Graphics/Vector.GetAngle.cs +++ b/StgSharp.Mathematics/Numeric/Graphics/Vector.GetAngle.cs @@ -32,15 +32,21 @@ namespace StgSharp.Mathematics.Graphics public static unsafe partial class Linear { - public static float GetAngle(Vec2 vec1, Vec2 vec2) + public static float GetAngle( + Vec2 vec1, + Vec2 vec2 + ) { - return Scalar.ACos( + return MathF.Acos( 1 / (vec1.GetLength() * vec2.GetLength())); } - public static float GetAngle(Vec3 vec1, Vec3 vec2) + public static float GetAngle( + Vec3 vec1, + Vec3 vec2 + ) { - return Scalar.ACos((vec1 * vec2) / (vec1.GetLength() * vec2.GetLength())); + return MathF.Acos(vec1 * vec2 / (vec1.GetLength() * vec2.GetLength())); } } diff --git a/StgSharp.Mathematics/Numeric/Graphics/Vector.GetLength.cs b/StgSharp.Mathematics/Numeric/Graphics/Vector.GetLength.cs index 19a719d8..f9f0073f 100644 --- a/StgSharp.Mathematics/Numeric/Graphics/Vector.GetLength.cs +++ b/StgSharp.Mathematics/Numeric/Graphics/Vector.GetLength.cs @@ -32,14 +32,18 @@ namespace StgSharp.Mathematics.Graphics public static unsafe partial class Linear { - public static float GetLength(this Vec3 vec) + public static float GetLength( + this Vec3 vec + ) { - return Scalar.Sqrt(vec.Dot(vec)); + return MathF.Sqrt(vec.Dot(vec)); } - public static float GetLength(this Vec2 vec) + public static float GetLength( + this Vec2 vec + ) { - return Scalar.Sqrt(vec.Dot(vec)); + return MathF.Sqrt(vec.Dot(vec)); } } diff --git a/StgSharpDebug/View/NewRender.cs b/StgSharp.Mathematics/Numeric/Linear/Exception.cs similarity index 56% rename from StgSharpDebug/View/NewRender.cs rename to StgSharp.Mathematics/Numeric/Linear/Exception.cs index 585f7d5a..c98cef98 100644 --- a/StgSharpDebug/View/NewRender.cs +++ b/StgSharp.Mathematics/Numeric/Linear/Exception.cs @@ -1,65 +1,65 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="NewRender" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Graphics; -using StgSharp.Internal; - -using StgSharp.Mathematics; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp -{ - public partial class ViewMain - { - - public ParticleRenderStream Stream { get; set; } - - private class NewRender : ViewRender - { - - public NewRender(ViewMain view) : base(view) { } - - public override void CustomizedInitialize() - { - Binding.Stream = CreateRenderStream(); - Render["only".AsLabel()] = Binding.Stream; - } - - public override bool ValidateInitializing() - { - return Binding.Stream != null; - } - - } - - } -} +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="Exception" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Mathematics.Numeric +{ + public class MatrixDimensionMismatchException : Exception where T : unmanaged, INumber + { + + public MatrixDimensionMismatchException( + Matrix right, + Matrix ans + ) + : base($""" + Matrix dimensions must agree but current: + right({right?.ColumnLength ?? 0}×{right?.RowLength ?? 0}), + ans({ans?.ColumnLength ?? 0}×{ans?.RowLength ?? 0}) + """ + ) { } + + public MatrixDimensionMismatchException( + Matrix left, + Matrix right, + Matrix ans + ) + : base($""" + Matrix dimensions must agree but current: + left({left?.ColumnLength ?? 0}×{left?.RowLength ?? 0}), + right({right?.ColumnLength ?? 0}×{right?.RowLength ?? 0}), + ans({ans?.ColumnLength ?? 0}×{ans?.RowLength ?? 0}) + """ + ) { } + + } +} diff --git a/StgSharp.Mathematics/Numeric/Linear/Matrix.cs b/StgSharp.Mathematics/Numeric/Linear/Matrix.cs index d1f15040..8ab28496 100644 --- a/StgSharp.Mathematics/Numeric/Linear/Matrix.cs +++ b/StgSharp.Mathematics/Numeric/Linear/Matrix.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="Matrix" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -29,17 +29,17 @@ using StgSharp.Mathematics; using StgSharp.Mathematics.Numeric; using System; using System.Numerics; -using System.Runtime.CompilerServices; - -// using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle; - +using System.Runtime.CompilerServices; + +// using hlsfHandle = global::StgSharp.HighPerformance.Memory.HybridLayerSegregatedFitAllocationHandle; + namespace StgSharp.Mathematics.Numeric { - public unsafe partial class Matrix where T: unmanaged, INumber + public unsafe partial class Matrix where T : unmanaged, INumber { - private protected static readonly int t_count = 16 / sizeof(T); - + private protected static readonly int t_count = 16 / sizeof(T); + private protected static readonly int t_size = sizeof(T); private readonly MatrixKernelBoarder _boarder; private readonly MatrixSize _size; @@ -48,8 +48,8 @@ namespace StgSharp.Mathematics.Numeric private protected Matrix( MatrixKernelBoarder boarder, MatrixSize size, - MatrixStorage buffer - + MatrixStorage buffer + ) { _boarder = boarder; @@ -57,7 +57,10 @@ namespace StgSharp.Mathematics.Numeric _buffer = buffer; } - public T this[int x, int y] + public T this[ + int x, + int y + ] { get { @@ -78,40 +81,43 @@ namespace StgSharp.Mathematics.Numeric long offset = GetElementOffset(x, y); if (offset < 0) { return; - } + } ((T*)Buffer)[offset] = value; } - } - + } + /// /// Matlab style indexer to generate a new matrix - /// + /// /// /// - /// + /// /// /// - /// + /// /// /// - /// + /// /// /// - /// - public unsafe Matrix this[ReadOnlySpan column, ReadOnlySpan row] + /// + public unsafe Matrix this[ + ReadOnlySpan column, + ReadOnlySpan row + ] { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } - } - + } + /// /// Length of the matrix in columns. - /// - public int ColumnLength => _size.ElementColumnLength; - + /// + public int ColumnLength => _size.ElementColumnLength; + /// /// Length of the matrix in rows. - /// + /// public int RowLength => _size.ElementRowLength; public MatrixLayout Layout { get; init; } @@ -127,49 +133,64 @@ namespace StgSharp.Mathematics.Numeric protected internal int KernelRowLength => _size.KernelRowLength; [MethodImpl(MethodImplOptions.AggressiveInlining)] - public unsafe ref MatrixKernel GetMatrixKernel(int x, int y) + public unsafe ref MatrixKernel GetMatrixKernel( + int x, + int y + ) { return ref _boarder.IsInBuffer(x, y, in _size) ? ref _buffer[_boarder.GetIndexOffset(x, y, in _size)] : ref Unsafe.NullRef>(); } - internal long GetElementOffset(int x, int y) + internal long GetElementOffset( + int x, + int y + ) { - int - k_c = y / 4, - c = y % 4, - k_r = x / 4, + int + k_c = y / 4, + c = y % 4, + k_r = x / 4, r = x % 4; if (!_boarder.IsInBuffer(k_r, k_c, in _size)) { return -1; } - long kernelOffset = _boarder.GetIndexOffset(k_r, k_c, in _size); - + long kernelOffset = _boarder.GetIndexOffset(k_r, k_c, in _size); + return kernelOffset * 16 + 4 * r + c; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal unsafe ref T GetElementUnsafe(int x, int y) + internal unsafe ref T GetElementUnsafe( + int x, + int y + ) { // Caller guarantees: indices in range, layout is dense square. int k_c = y / 4; int k_r = x / 4; int c = y % 4; - int r = x % 4; - + int r = x % 4; + ref MatrixKernel kernel = ref _buffer[_boarder.GetIndexOffset(k_r, k_c, in _size)]; return ref kernel[c, r]; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal unsafe MatrixKernel* GetKernelAddressUnsafe(int x, int y) + internal unsafe MatrixKernel* GetKernelAddressUnsafe( + int x, + int y + ) { return Buffer + _boarder.GetIndexOffset(x, y, in _size); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal unsafe ref MatrixKernel GetKernelUnsafe(int x, int y) + internal unsafe ref MatrixKernel GetKernelUnsafe( + int x, + int y + ) { // Caller guarantees: indices in range, layout is dense square. int k_c = y / 4; @@ -180,4 +201,4 @@ namespace StgSharp.Mathematics.Numeric } } -} +} diff --git a/StgSharp.Mathematics/Numeric/MatrixCompute.Factorize.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Factorize.cs.old similarity index 97% rename from StgSharp.Mathematics/Numeric/MatrixCompute.Factorize.cs rename to StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Factorize.cs.old index 0b4d1d49..f0e01188 100644 --- a/StgSharp.Mathematics/Numeric/MatrixCompute.Factorize.cs +++ b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Factorize.cs.old @@ -1,160 +1,160 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="MatrixCompute.Factorize" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Internal; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics.Numeric -{ - public static partial class MatrixCompute - { - - public static unsafe void FactorizePLU( - Matrix matrix, - Span pivot, - Matrix lower, - Matrix upper - ) - { - if (matrix.ColumnLength != matrix.RowLength) { - throw new InvalidOperationException("Matrix must be square."); - } - if (matrix.Layout != MatrixLayout.DenseRectangle) { - throw new NotSupportedException("Only dense square matrices are supported."); - } - int n = matrix.RowLength; - if (pivot.Length < n) { - throw new ArgumentException("Pivot span length is insufficient.", nameof(pivot)); - } - if (lower.RowLength != n || - lower.ColumnLength != n || - lower.Layout != MatrixLayout.UpperTriangle) { - throw new ArgumentException("Lower matrix must be lower-triangular with same dimensions as input.", nameof(lower)); - } - if (upper.RowLength != n || - upper.ColumnLength != n || - upper.Layout != MatrixLayout.UpperTriangle) { - throw new ArgumentException("Upper matrix must be upper-triangular with same dimensions as input.", nameof(upper)); - } - - int size = matrix.KernelColumnLength * matrix.KernelRowLength; - if (size < 256) - { - for (int i = 0; i < n; i++) - { - pivot[i] = i; // identity permutation - } - - // Aggressive: always call native pivot to fetch four-column candidates - ulong* pivots = stackalloc ulong[4]; - for (int kBlock = 0; kBlock < n; kBlock += 4) - { - NumericalModule.GlobalContext - .mat_sk[(int)MatrixElementType.F32].pivot(matrix.Buffer, - (ulong)(kBlock >> 2), - (ulong)(matrix.KernelRowLength - (kBlock >> 2)), - (ulong)pivots); - int colsInBlock = Math.Min(4, n - kBlock); - for (int offset = 0; offset < colsInBlock; offset++) - { - int k = kBlock + offset; - int pivotRow = k; - float maxAbs; - - int candidateRow = (int)pivots[offset]; - int idx = -1; - for (int r = k; r < n; r++) - { - if (pivot[r] == candidateRow) - { - idx = r; - break; - } - } - - if (idx != -1) - { - pivotRow = idx; - maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[idx], k)); - } else - { - maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[k], k)); - for (int r = k + 1; r < n; r++) - { - float val = MathF.Abs(matrix.GetElementUnsafe(pivot[r], k)); - if (val > maxAbs) - { - maxAbs = val; - pivotRow = r; - } - } - } - - if (maxAbs == 0f) { - throw new InvalidOperationException("Zero pivot encountered in PLU."); - } - if (pivotRow != k) { - (pivot[k], pivot[pivotRow]) = (pivot[pivotRow], pivot[k]); - } - lower[k, k] = 1.0f; // unit diagonal for L - - // Compute U[k, j] for j >= k - for (int j = k; j < n; j++) - { - float sum = 0f; - for (int s = 0; s < k; s++) { - sum += lower[k, s] * upper[s, j]; - } - upper[k, j] = matrix.GetElementUnsafe(pivot[k], j) - sum; - } - - // Compute L[i, k] for i > k - for (int i = k + 1; i < n; i++) - { - float sum = 0f; - for (int s = 0; s < k; s++) { - sum += lower[i, s] * upper[s, k]; - } - float u = upper[k, k]; - if (u == 0f) { - throw new InvalidOperationException("Zero pivot encountered in PLU."); - } - lower[i, k] = (matrix.GetElementUnsafe(pivot[i], k) - sum) / u; - } - } - } - - // TODO: For larger kernels, consider calling native pivot helper to extract 4 pivots at once. - } else if (size < 1024) { } else { } - } - - } -} +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="MatrixCompute.Factorize" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Mathematics.Numeric +{ + public static partial class MatrixCompute + { + + public static unsafe void FactorizePLU( + Matrix matrix, + Span pivot, + Matrix lower, + Matrix upper + ) + { + if (matrix.ColumnLength != matrix.RowLength) { + throw new InvalidOperationException("Matrix must be square."); + } + if (matrix.Layout != MatrixLayout.DenseRectangle) { + throw new NotSupportedException("Only dense square matrices are supported."); + } + int n = matrix.RowLength; + if (pivot.Length < n) { + throw new ArgumentException("Pivot span length is insufficient.", nameof(pivot)); + } + if (lower.RowLength != n || + lower.ColumnLength != n || + lower.Layout != MatrixLayout.UpperTriangle) { + throw new ArgumentException("Lower matrix must be lower-triangular with same dimensions as input.", nameof(lower)); + } + if (upper.RowLength != n || + upper.ColumnLength != n || + upper.Layout != MatrixLayout.UpperTriangle) { + throw new ArgumentException("Upper matrix must be upper-triangular with same dimensions as input.", nameof(upper)); + } + + int size = matrix.KernelColumnLength * matrix.KernelRowLength; + if (size < 256) + { + for (int i = 0; i < n; i++) + { + pivot[i] = i; // identity permutation + } + + // Aggressive: always call native pivot to fetch four-column candidates + ulong* pivots = stackalloc ulong[4]; + for (int kBlock = 0; kBlock < n; kBlock += 4) + { + NumericalModule.GlobalContext + .mat_sk[(int)MatrixElementType.F32].pivot(matrix.Buffer, + (ulong)(kBlock >> 2), + (ulong)(matrix.KernelRowLength - (kBlock >> 2)), + (ulong)pivots); + int colsInBlock = Math.Min(4, n - kBlock); + for (int offset = 0; offset < colsInBlock; offset++) + { + int k = kBlock + offset; + int pivotRow = k; + float maxAbs; + + int candidateRow = (int)pivots[offset]; + int idx = -1; + for (int r = k; r < n; r++) + { + if (pivot[r] == candidateRow) + { + idx = r; + break; + } + } + + if (idx != -1) + { + pivotRow = idx; + maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[idx], k)); + } else + { + maxAbs = MathF.Abs(matrix.GetElementUnsafe(pivot[k], k)); + for (int r = k + 1; r < n; r++) + { + float val = MathF.Abs(matrix.GetElementUnsafe(pivot[r], k)); + if (val > maxAbs) + { + maxAbs = val; + pivotRow = r; + } + } + } + + if (maxAbs == 0f) { + throw new InvalidOperationException("Zero pivot encountered in PLU."); + } + if (pivotRow != k) { + (pivot[k], pivot[pivotRow]) = (pivot[pivotRow], pivot[k]); + } + lower[k, k] = 1.0f; // unit diagonal for L + + // Compute U[k, j] for j >= k + for (int j = k; j < n; j++) + { + float sum = 0f; + for (int s = 0; s < k; s++) { + sum += lower[k, s] * upper[s, j]; + } + upper[k, j] = matrix.GetElementUnsafe(pivot[k], j) - sum; + } + + // Compute L[i, k] for i > k + for (int i = k + 1; i < n; i++) + { + float sum = 0f; + for (int s = 0; s < k; s++) { + sum += lower[i, s] * upper[s, k]; + } + float u = upper[k, k]; + if (u == 0f) { + throw new InvalidOperationException("Zero pivot encountered in PLU."); + } + lower[i, k] = (matrix.GetElementUnsafe(pivot[i], k) - sum) / u; + } + } + } + + // TODO: For larger kernels, consider calling native pivot helper to extract 4 pivots at once. + } else if (size < 1024) { } else { } + } + + } +} diff --git a/StgSharp.Mathematics/Numeric/MatrixCompute.Float.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Float.cs.old similarity index 97% rename from StgSharp.Mathematics/Numeric/MatrixCompute.Float.cs rename to StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Float.cs.old index 68af94b1..eec9ac42 100644 --- a/StgSharp.Mathematics/Numeric/MatrixCompute.Float.cs +++ b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.Float.cs.old @@ -1,314 +1,314 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="MatrixCompute.Float" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Collections; -using StgSharp.Internal; -using StgSharp.Mathematics; -using StgSharp.Mathematics.Internal; -using System; -using System.Collections.Generic; -using System.ComponentModel.DataAnnotations.Schema; -using System.Linq; -using System.Numerics; -using System.Security.AccessControl; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics.Numeric -{ - public static partial class MatrixCompute - { - - public static unsafe void Add( - Matrix left, - Matrix right, - Matrix ans - ) - { - MatrixElementType f32 = MatrixElementType.F32; - if (left.ColumnLength != right.ColumnLength || - left.RowLength != right.RowLength || - left.ColumnLength != ans.ColumnLength || - left.RowLength != ans.RowLength) { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - if (count <= 256) - { - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr, - count); - - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr, - count); - - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Mat1 = (MatrixKernel*)left.Buffer; - package->Mat2 = (MatrixKernel*)right.Buffer; - package->Mat3 = (MatrixKernel*)ans.Buffer; - package->ElementSize = sizeof(float); - package->PrimCount = ans.KernelColumnLength; - package->SecCount = ans.KernelRowLength; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_add; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - return; - } - - public static unsafe void Fill( - Matrix ans, - float value - ) - { - MatrixElementType f32 = MatrixElementType.F32; - long count = (long)ans.KernelColumnLength * ans.KernelRowLength; - ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); - scalar->Data(0) = value; - if (count <= 256) - { - NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count); - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count); - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Answer = (nint)ans.Buffer; - package->ElementSize = sizeof(float); - package->PrimCount = ans.KernelColumnLength; - package->SecCount = ans.KernelRowLength; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_fill; - package->Scalar = scalar; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - taskGroup.LaunchParallel(SleepMode.DeepSleep); - MatrixParallelFactory.Release(scalar); - taskGroup.Dispose(); - } - - public static unsafe void Mul( - Matrix left, - Matrix right, - Matrix ans - ) - { - MatrixElementType f32 = MatrixElementType.F32; - - // For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN - // ColumnLength = number of columns (N), RowLength = number of rows (M) - if (left.ColumnLength != right.RowLength || - ans.ColumnLength != right.ColumnLength || - ans.RowLength != left.RowLength) - { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - if (left.Layout != MatrixLayout.DenseRectangle || - right.Layout != MatrixLayout.DenseRectangle || - ans.Layout != MatrixLayout.DenseRectangle) { - throw new NotSupportedException("Only dense rectangle matrices are supported."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - - if (count <= 1024) - { - MatrixParallelThread[] pool = null; - if (count > 256) { - pool = MatrixParallel.LeadParallel(1); - } - M128* enumeration = stackalloc M128[1]; - enumeration->Member(2) = left.KernelColumnLength; - enumeration->Member(3) = ans.KernelColumnLength; - for (int i = 0; i < ans.KernelRowLength; i++) - { - for (int j = 0; j < ans.KernelColumnLength; j++) - { - enumeration->Member(0) = i; - enumeration->Member(1) = j; - - NumericalModule.GlobalContext - .mat_sk[f32].kernel_tile_fma((MatrixKernel*)left.Buffer, - (MatrixKernel*)right.Buffer, - (MatrixKernel*)ans.Buffer, - enumeration); - } - } - - if (count > 256) { - MatrixParallel.ReturnParallelResources(ref pool!); - } - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Left = (nint)left.Buffer; - package->Right = (nint)right.Buffer; - package->Answer = (nint)ans.Buffer; - package->AnsPrimOffset = ans.KernelRowLength; - package->AnsSecOffset = ans.KernelColumnLength; - package->LeftPrimOffset = left.KernelColumnLength; - package->PrimCount = ans.KernelColumnLength; - package->SecCount = ans.KernelRowLength; - package->ElementSize = (int)MatrixElementType.F32; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA); - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - return; - } - - public static unsafe void Mul( - Matrix left, - float right, - Matrix ans - ) - { - MatrixElementType f32 = MatrixElementType.F32; - if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - if (left.Layout != MatrixLayout.DenseRectangle || - ans.Layout != MatrixLayout.DenseRectangle) { - throw new NotSupportedException("Only dense rectangle matrices are supported."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); - scalar->Data(0) = right; - if (count <= 256) - { - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar, - count); - - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar, - count); - - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Right = (nint)left.Buffer; - package->Answer = (nint)ans.Buffer; - package->ElementSize = sizeof(float); - package->PrimCount = left.KernelColumnLength; - package->SecCount = left.KernelRowLength; - package->Scalar = scalar; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - MatrixParallelFactory.Release(scalar); - return; - } - - public static unsafe void Sub( - Matrix left, - Matrix right, - Matrix ans - ) - { - MatrixElementType f32 = MatrixElementType.F32; - if (left.ColumnLength != right.ColumnLength || - left.RowLength != right.RowLength || - left.ColumnLength != ans.ColumnLength || - left.RowLength != ans.RowLength) { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - if (left.Layout != MatrixLayout.DenseRectangle || - right.Layout != MatrixLayout.DenseRectangle || - ans.Layout != MatrixLayout.DenseRectangle) { - throw new NotSupportedException("Only dense rectangle matrices are supported."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - if (count <= 256) - { - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr, - count); - - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr, - count); - - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Left = (nint)left.Buffer; - package->Right = (nint)right.Buffer; - package->Answer = (nint)ans.Buffer; - package->ElementSize = sizeof(float); - package->PrimCount = left.KernelColumnLength; - package->SecCount = left.KernelRowLength; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_sub; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - return; - } - - } -} +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="MatrixCompute.Float" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.Collections; +using StgSharp.Internal; +using StgSharp.Mathematics; +using StgSharp.Mathematics.Internal; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations.Schema; +using System.Linq; +using System.Numerics; +using System.Security.AccessControl; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Mathematics.Numeric +{ + public static partial class MatrixCompute + { + + public static unsafe void Add( + Matrix left, + Matrix right, + Matrix ans + ) + { + MatrixElementType f32 = MatrixElementType.F32; + if (left.ColumnLength != right.ColumnLength || + left.RowLength != right.RowLength || + left.ColumnLength != ans.ColumnLength || + left.RowLength != ans.RowLength) { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr, + count); + + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_mk[f32].buffer_add(leftPtr, rightPtr, ansPtr, + count); + + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Mat1 = (MatrixKernel*)left.Buffer; + package->Mat2 = (MatrixKernel*)right.Buffer; + package->Mat3 = (MatrixKernel*)ans.Buffer; + package->ElementSize = sizeof(float); + package->PrimCount = ans.KernelColumnLength; + package->SecCount = ans.KernelRowLength; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_add; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + return; + } + + public static unsafe void Fill( + Matrix ans, + float value + ) + { + MatrixElementType f32 = MatrixElementType.F32; + long count = (long)ans.KernelColumnLength * ans.KernelRowLength; + ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); + scalar->Data(0) = value; + if (count <= 256) + { + NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count); + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + NumericalModule.GlobalContext.mat_sk[f32].buffer_fill(ans.Buffer, scalar, count); + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Answer = (nint)ans.Buffer; + package->ElementSize = sizeof(float); + package->PrimCount = ans.KernelColumnLength; + package->SecCount = ans.KernelRowLength; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_fill; + package->Scalar = scalar; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + taskGroup.LaunchParallel(SleepMode.DeepSleep); + MatrixParallelFactory.Release(scalar); + taskGroup.Dispose(); + } + + public static unsafe void Mul( + Matrix left, + Matrix right, + Matrix ans + ) + { + MatrixElementType f32 = MatrixElementType.F32; + + // For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN + // ColumnLength = number of columns (N), RowLength = number of rows (M) + if (left.ColumnLength != right.RowLength || + ans.ColumnLength != right.ColumnLength || + ans.RowLength != left.RowLength) + { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + if (left.Layout != MatrixLayout.DenseRectangle || + right.Layout != MatrixLayout.DenseRectangle || + ans.Layout != MatrixLayout.DenseRectangle) { + throw new NotSupportedException("Only dense rectangle matrices are supported."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + + if (count <= 1024) + { + MatrixParallelThread[] pool = null; + if (count > 256) { + pool = MatrixParallel.LeadParallel(1); + } + M128* enumeration = stackalloc M128[1]; + enumeration->Member(2) = left.KernelColumnLength; + enumeration->Member(3) = ans.KernelColumnLength; + for (int i = 0; i < ans.KernelRowLength; i++) + { + for (int j = 0; j < ans.KernelColumnLength; j++) + { + enumeration->Member(0) = i; + enumeration->Member(1) = j; + + NumericalModule.GlobalContext + .mat_sk[f32].kernel_tile_fma((MatrixKernel*)left.Buffer, + (MatrixKernel*)right.Buffer, + (MatrixKernel*)ans.Buffer, + enumeration); + } + } + + if (count > 256) { + MatrixParallel.ReturnParallelResources(ref pool!); + } + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Left = (nint)left.Buffer; + package->Right = (nint)right.Buffer; + package->Answer = (nint)ans.Buffer; + package->AnsPrimOffset = ans.KernelRowLength; + package->AnsSecOffset = ans.KernelColumnLength; + package->LeftPrimOffset = left.KernelColumnLength; + package->PrimCount = ans.KernelColumnLength; + package->SecCount = ans.KernelRowLength; + package->ElementSize = (int)MatrixElementType.F32; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA); + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + return; + } + + public static unsafe void Mul( + Matrix left, + float right, + Matrix ans + ) + { + MatrixElementType f32 = MatrixElementType.F32; + if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + if (left.Layout != MatrixLayout.DenseRectangle || + ans.Layout != MatrixLayout.DenseRectangle) { + throw new NotSupportedException("Only dense rectangle matrices are supported."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); + scalar->Data(0) = right; + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar, + count); + + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul(leftPtr, ansPtr, scalar, + count); + + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Right = (nint)left.Buffer; + package->Answer = (nint)ans.Buffer; + package->ElementSize = sizeof(float); + package->PrimCount = left.KernelColumnLength; + package->SecCount = left.KernelRowLength; + package->Scalar = scalar; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_scalar_mul; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + MatrixParallelFactory.Release(scalar); + return; + } + + public static unsafe void Sub( + Matrix left, + Matrix right, + Matrix ans + ) + { + MatrixElementType f32 = MatrixElementType.F32; + if (left.ColumnLength != right.ColumnLength || + left.RowLength != right.RowLength || + left.ColumnLength != ans.ColumnLength || + left.RowLength != ans.RowLength) { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + if (left.Layout != MatrixLayout.DenseRectangle || + right.Layout != MatrixLayout.DenseRectangle || + ans.Layout != MatrixLayout.DenseRectangle) { + throw new NotSupportedException("Only dense rectangle matrices are supported."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr, + count); + + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f32].buffer_sub(leftPtr, rightPtr, ansPtr, + count); + + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Left = (nint)left.Buffer; + package->Right = (nint)right.Buffer; + package->Answer = (nint)ans.Buffer; + package->ElementSize = sizeof(float); + package->PrimCount = left.KernelColumnLength; + package->SecCount = left.KernelRowLength; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f32].buffer_sub; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + return; + } + + } +} diff --git a/StgSharp.Mathematics/Numeric/MatrixCompute.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.cs similarity index 97% rename from StgSharp.Mathematics/Numeric/MatrixCompute.cs rename to StgSharp.Mathematics/Numeric/Linear/MatrixCompute.cs index 00beab9c..ae6cbc33 100644 --- a/StgSharp.Mathematics/Numeric/MatrixCompute.cs +++ b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.cs @@ -1,55 +1,55 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="MatrixCompute" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Internal; -using StgSharp.Mathematics; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Numerics; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics.Numeric -{ - public partial class MatrixCompute - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal static unsafe MatrixKernel* GetKernelAddressUnsafe( - MatrixKernel* buffer, - int colLength, - int x, - int y) - where T: unmanaged, INumber - { - return (MatrixKernel*)(buffer + (colLength * x + y)); - } - - } -} +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="MatrixCompute" +// Project: StgSharp +// AuthorGroup: Nitload Space +// Copyright (c) Nitload Space. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.Internal; +using StgSharp.Mathematics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Numerics; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Mathematics.Numeric +{ + public partial class MatrixCompute + { + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal static unsafe MatrixKernel* GetKernelAddressUnsafe( + MatrixKernel* buffer, + int colLength, + int x, + int y) + where T: unmanaged, INumber + { + return (MatrixKernel*)(buffer + (colLength * x + y)); + } + + } +} diff --git a/StgSharp.Mathematics/Numeric/MatrixCompute.double.cs b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.double.cs.old similarity index 92% rename from StgSharp.Mathematics/Numeric/MatrixCompute.double.cs rename to StgSharp.Mathematics/Numeric/Linear/MatrixCompute.double.cs.old index 7c1d6a4a..44399c92 100644 --- a/StgSharp.Mathematics/Numeric/MatrixCompute.double.cs +++ b/StgSharp.Mathematics/Numeric/Linear/MatrixCompute.double.cs.old @@ -1,303 +1,320 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="MatrixCompute.double" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Internal; -using StgSharp.Mathematics; -using StgSharp.Mathematics.Internal; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics.Numeric -{ - public partial class MatrixCompute - { - - public static unsafe void Add( - Matrix left, - Matrix right, - Matrix ans - ) - { - int f64 = (int)MatrixElementType.F64; - if (left.ColumnLength != right.ColumnLength || - left.RowLength != right.RowLength || - left.ColumnLength != ans.ColumnLength || - left.RowLength != ans.RowLength) { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - if (count <= 256) - { - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f64].buffer_add(leftPtr, rightPtr, ansPtr, - count); - - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f64].buffer_add(leftPtr, rightPtr, ansPtr, - count); - - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Left = (nint)left.Buffer; - package->Right = (nint)right.Buffer; - package->Answer = (nint)ans.Buffer; - package->ElementSize = sizeof(double); - package->PrimCount = ans.KernelColumnLength; - package->SecCount = ans.KernelRowLength; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_add; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - return; - } - - public static unsafe void Fill( - Matrix ans, - double value - ) - { - int f64 = (int)MatrixElementType.F64; - long count = (long)ans.KernelColumnLength * ans.KernelRowLength; - ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); - scalar->Data(0) = value; - if (count <= 256) - { - NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count); - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count); - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Answer = (nint)ans.Buffer; - package->ElementSize = sizeof(double); - package->PrimCount = ans.KernelColumnLength; - package->SecCount = ans.KernelRowLength; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_fill; - package->Scalar = scalar; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - taskGroup.LaunchParallel(SleepMode.DeepSleep); - MatrixParallelFactory.Release(scalar); - taskGroup.Dispose(); - } - - public static unsafe void Mul( - Matrix left, - Matrix right, - Matrix ans - ) - { - int f64 = (int)MatrixElementType.F64; - - // For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN - // ColumnLength = number of columns (N), RowLength = number of rows (M) - if (left.ColumnLength != right.RowLength || - ans.ColumnLength != right.ColumnLength || - ans.RowLength != left.RowLength) - { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - if (count <= 1024) - { - MatrixParallelThread[] pool = null; - if (count > 256) { - pool = MatrixParallel.LeadParallel(1); - } - M128* enumeration = stackalloc M128[1]; - enumeration->Member(2) = left.KernelColumnLength; - enumeration->Member(3) = ans.KernelColumnLength; - for (int i = 0; i < ans.KernelRowLength; i++) - { - for (int j = 0; j < ans.KernelColumnLength; j++) - { - enumeration->Member(0) = i; - enumeration->Member(1) = j; - - NumericalModule.GlobalContext - .mat_sk[f64].kernel_tile_fma((MatrixKernel*)left.Buffer, - (MatrixKernel*)right.Buffer, - (MatrixKernel*)ans.Buffer, - enumeration); - } - } - if (count > 256) { - MatrixParallel.ReturnParallelResources(ref pool!); - } - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Left = (nint)left.Buffer; - package->Right = (nint)right.Buffer; - package->Answer = (nint)ans.Buffer; - package->AnsPrimOffset = ans.KernelRowLength; - package->AnsSecOffset = ans.KernelColumnLength; - package->LeftPrimOffset = left.KernelColumnLength; - package->PrimCount = ans.KernelColumnLength; - package->SecCount = ans.KernelRowLength; - package->ElementSize = (int)MatrixElementType.F64; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA); - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - return; - } - - public static unsafe void Mul( - Matrix left, - double right, - Matrix ans - ) - { - int f64 = (int)MatrixElementType.F64; - if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - if (left.Layout != MatrixLayout.DenseRectangle || - ans.Layout != MatrixLayout.DenseRectangle) { - throw new NotSupportedException("Only dense rectangle matrices are supported."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); - scalar->Data(0) = right; - if (count <= 256) - { - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar, - count); - - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar, - count); - - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Right = (nint)left.Buffer; - package->Answer = (nint)ans.Buffer; - package->ElementSize = sizeof(double); - package->PrimCount = left.KernelColumnLength; - package->SecCount = left.KernelRowLength; - package->Scalar = scalar; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - MatrixParallelFactory.Release(scalar); - return; - } - - public static unsafe void Sub( - Matrix left, - Matrix right, - Matrix ans - ) - { - int f64 = (int)MatrixElementType.F64; - if (left.ColumnLength != right.ColumnLength || - left.RowLength != right.RowLength || - left.ColumnLength != ans.ColumnLength || - left.RowLength != ans.RowLength) { - throw new IndexOutOfRangeException("Matrix dimensions must agree."); - } - if (left.Layout != MatrixLayout.DenseRectangle || - right.Layout != MatrixLayout.DenseRectangle || - ans.Layout != MatrixLayout.DenseRectangle) { - throw new NotSupportedException("Only dense rectangle matrices are supported."); - } - long count = (long)left.KernelColumnLength * left.KernelRowLength; - if (count <= 256) - { - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr, - count); - - return; - } else if (count <= 1024) - { - MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); - - MatrixKernel* leftPtr = left.Buffer; - MatrixKernel* rightPtr = right.Buffer; - MatrixKernel* ansPtr = ans.Buffer; - NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr, - count); - - MatrixParallel.ReturnParallelResources(ref pool); - return; - } - MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); - package->Left = (nint)left.Buffer; - package->Right = (nint)right.Buffer; - package->Answer = (nint)ans.Buffer; - package->ElementSize = sizeof(double); - package->PrimCount = left.KernelColumnLength; - package->SecCount = left.KernelRowLength; - package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); - package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_sub; - MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); - - taskGroup.LaunchParallel(SleepMode.DeepSleep); - taskGroup.Dispose(); - return; - } - - } -} +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="MatrixCompute.double" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.Internal; +using StgSharp.Mathematics; +using StgSharp.Mathematics.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +using unsafe MkProc = delegate* unmanaged[Cdecl]; + +namespace StgSharp.Mathematics.Numeric +{ + public partial class MatrixCompute + { + + public static unsafe void Add( + Matrix left, + Matrix right, + Matrix ans + ) + { + MatrixElementType f64 = MatrixElementType.F64; + if (left.ColumnLength != right.ColumnLength || + left.RowLength != right.RowLength || + left.ColumnLength != ans.ColumnLength || + left.RowLength != ans.RowLength) { + throw new MatrixDimensionMismatchException( + left, right, ans + ); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + MkProc add = (MkProc)NumericalModule.GlobalContext. + mat_mk[f64.IntrinsicNode]. + Get(MatrixIntrinsicHandle.Add); + + for (int i = 0; i < count; i++) { + add(new MatrixParallelTask + { + Mat1 = (MatrixKernel*)(leftPtr + i), + Mat2 = (MatrixKernel*)(rightPtr + i), + Mat3 = (MatrixKernel*)(ansPtr + i), + ElementType = MatrixElementType.F64, + }); + } + + // .buffer_add(leftPtr, rightPtr, ansPtr, count); + + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f64].buffer_add(leftPtr, rightPtr, ansPtr, + count); + + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Left = (nint)left.Buffer; + package->Right = (nint)right.Buffer; + package->Answer = (nint)ans.Buffer; + package->ElementSize = sizeof(double); + package->PrimCount = ans.KernelColumnLength; + package->SecCount = ans.KernelRowLength; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_add; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + return; + } + + public static unsafe void Fill( + Matrix ans, + double value + ) + { + int f64 = (int)MatrixElementType.F64; + long count = (long)ans.KernelColumnLength * ans.KernelRowLength; + ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); + scalar->Data(0) = value; + if (count <= 256) + { + NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count); + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + NumericalModule.GlobalContext.mat_sk[f64].buffer_fill(ans.Buffer, scalar, count); + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Answer = (nint)ans.Buffer; + package->ElementSize = sizeof(double); + package->PrimCount = ans.KernelColumnLength; + package->SecCount = ans.KernelRowLength; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.ANS_SCALAR_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_fill; + package->Scalar = scalar; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + taskGroup.LaunchParallel(SleepMode.DeepSleep); + MatrixParallelFactory.Release(scalar); + taskGroup.Dispose(); + } + + public static unsafe void Mul( + Matrix left, + Matrix right, + Matrix ans + ) + { + int f64 = (int)MatrixElementType.F64; + + // For matrix multiplication (left: MxK) * (right: KxN) => ans: MxN + // ColumnLength = number of columns (N), RowLength = number of rows (M) + if (left.ColumnLength != right.RowLength || + ans.ColumnLength != right.ColumnLength || + ans.RowLength != left.RowLength) + { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + if (count <= 1024) + { + MatrixParallelThread[] pool = null; + if (count > 256) { + pool = MatrixParallel.LeadParallel(1); + } + M128* enumeration = stackalloc M128[1]; + enumeration->Member(2) = left.KernelColumnLength; + enumeration->Member(3) = ans.KernelColumnLength; + for (int i = 0; i < ans.KernelRowLength; i++) + { + for (int j = 0; j < ans.KernelColumnLength; j++) + { + enumeration->Member(0) = i; + enumeration->Member(1) = j; + + NumericalModule.GlobalContext + .mat_sk[f64].kernel_tile_fma((MatrixKernel*)left.Buffer, + (MatrixKernel*)right.Buffer, + (MatrixKernel*)ans.Buffer, + enumeration); + } + } + if (count > 256) { + MatrixParallel.ReturnParallelResources(ref pool!); + } + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Left = (nint)left.Buffer; + package->Right = (nint)right.Buffer; + package->Answer = (nint)ans.Buffer; + package->AnsPrimOffset = ans.KernelRowLength; + package->AnsSecOffset = ans.KernelColumnLength; + package->LeftPrimOffset = left.KernelColumnLength; + package->PrimCount = ans.KernelColumnLength; + package->SecCount = ans.KernelRowLength; + package->ElementSize = (int)MatrixElementType.F64; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.SPECIAL, MatrixOperationSpecial.SEQ_FMA); + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + return; + } + + public static unsafe void Mul( + Matrix left, + double right, + Matrix ans + ) + { + int f64 = (int)MatrixElementType.F64; + if (left.ColumnLength != ans.ColumnLength || left.RowLength != ans.RowLength) { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + if (left.Layout != MatrixLayout.DenseRectangle || + ans.Layout != MatrixLayout.DenseRectangle) { + throw new NotSupportedException("Only dense rectangle matrices are supported."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); + scalar->Data(0) = right; + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar, + count); + + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul(leftPtr, ansPtr, scalar, + count); + + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Right = (nint)left.Buffer; + package->Answer = (nint)ans.Buffer; + package->ElementSize = sizeof(double); + package->PrimCount = left.KernelColumnLength; + package->SecCount = left.KernelRowLength; + package->Scalar = scalar; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_scalar_mul; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + MatrixParallelFactory.Release(scalar); + return; + } + + public static unsafe void Sub( + Matrix left, + Matrix right, + Matrix ans + ) + { + int f64 = (int)MatrixElementType.F64; + if (left.ColumnLength != right.ColumnLength || + left.RowLength != right.RowLength || + left.ColumnLength != ans.ColumnLength || + left.RowLength != ans.RowLength) { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + if (left.Layout != MatrixLayout.DenseRectangle || + right.Layout != MatrixLayout.DenseRectangle || + ans.Layout != MatrixLayout.DenseRectangle) { + throw new NotSupportedException("Only dense rectangle matrices are supported."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr, + count); + + return; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NumericalModule.GlobalContext.mat_sk[f64].buffer_sub(leftPtr, rightPtr, ansPtr, + count); + + MatrixParallel.ReturnParallelResources(ref pool); + return; + } + MatrixParallelTask* package = MatrixParallelFactory.CreateBaseTask(); + package->Left = (nint)left.Buffer; + package->Right = (nint)right.Buffer; + package->Answer = (nint)ans.Buffer; + package->ElementSize = sizeof(double); + package->PrimCount = left.KernelColumnLength; + package->SecCount = left.KernelRowLength; + package->ComputeMode = new MatrixOpMode(MatrixIndexStyle.BUFFER_INDEX, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); + package->ComputeHandle = (IntPtr)NumericalModule.GlobalContext.mat_sk[f64].buffer_sub; + MatrixParallelWrap taskGroup = MatrixParallel.ScheduleTask(package); + + taskGroup.LaunchParallel(SleepMode.DeepSleep); + taskGroup.Dispose(); + return; + } + + } +} diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs index 0f8ed03f..577f186d 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Await.cs @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="MatrixParallel.Await" // Project: StgSharp @@ -31,6 +31,7 @@ using System.Collections.Generic; using System.Linq; using System.Runtime.CompilerServices; using System.Text; +using System.Threading; using System.Threading.Tasks; namespace StgSharp.Mathematics.Numeric @@ -43,7 +44,9 @@ namespace StgSharp.Mathematics.Numeric private static volatile int _createGeneration = 0; private static int _sortState; - public static MatrixParallelThread[] LeadParallel(int recommendCount) + public static MatrixParallelThread[] LeadParallel( + int recommendCount + ) { int min = int.Min(recommendCount, _threads.Capacity); min /= 2; @@ -108,7 +111,9 @@ namespace StgSharp.Mathematics.Numeric // return ret; } - public static void ReturnParallelResources(ref MatrixParallelThread[] pool) + public static void ReturnParallelResources( + ref MatrixParallelThread[] pool + ) { while (true) { @@ -123,7 +128,11 @@ namespace StgSharp.Mathematics.Numeric pool = null!; } - private record class WaitHandle(int generation, int least, int best) + private record class WaitHandle( + int generation, + int least, + int best + ) { public int CreateGeneration { get; init; } = generation; @@ -135,7 +144,9 @@ namespace StgSharp.Mathematics.Numeric public int Priority { get; private set; } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void UpdatePriority(int currentGeneration) + public void UpdatePriority( + int currentGeneration + ) { Priority = (currentGeneration - CreateGeneration) * (MatrixParallel._threads.Capacity - LeastCount); } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs index 3988ea09..fbbcc8e1 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.AwaitingQueue.cs @@ -1,4 +1,4 @@ -//----------------------------------------------------------------------- +//----------------------------------------------------------------------- // ----------------------------------------------------------------------- // file="MatrixParallel.AwaitingQueue" // Project: StgSharp @@ -51,19 +51,24 @@ namespace StgSharp.Mathematics.Numeric public AwaitingQueue() { } - public void Enqueue(WaitHandle handle) + public void Enqueue( + WaitHandle handle + ) { if (_count > 7) { _fallback.Enqueue(handle); - Interlocked.Increment(ref _count); + _ = Interlocked.Increment(ref _count); return; } _quickElements[_count] = handle; - Interlocked.Increment(ref _count); + _ = Interlocked.Increment(ref _count); } - public bool TryDequeue(int generation, out WaitHandle handle) + public bool TryDequeue( + int generation, + out WaitHandle handle + ) { if (_count == 0) { @@ -83,7 +88,10 @@ namespace StgSharp.Mathematics.Numeric return true; } - public bool TryPeek(int generation, out WaitHandle handle) + public bool TryPeek( + int generation, + out WaitHandle handle + ) { if (_count == 0) { @@ -99,7 +107,10 @@ namespace StgSharp.Mathematics.Numeric return true; } - public bool TryPopIfRefEqual(int generation, in WaitHandle handle) + public bool TryPopIfRefEqual( + int generation, + in WaitHandle handle + ) { if (_count == 0) { return false; @@ -127,7 +138,9 @@ namespace StgSharp.Mathematics.Numeric private WaitHandle value; - public static void Sort(ref Element e) + public static void Sort( + ref Element e + ) { int maxIdx = 0; WaitHandle first = e[0]; diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs index d3104b5a..52b94b92 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallel.Publish.cs @@ -50,26 +50,22 @@ namespace StgSharp.Mathematics.Numeric MatrixParallelTask* package ) { - switch (package->ComputeMode.OperationStyle) - { - case MatrixIndexStyle.BUFFER_INDEX: - return ScheduleBufferTask(package); - default: - throw new InvalidOperationException($"Unknown mode {package->ComputeMode.OperationStyle}."); - } + return ScheduleBufferTask(package); } private static unsafe MatrixParallelWrap ScheduleBufferTask( MatrixParallelTask* package ) { + /* int primCount = package->PrimCount; int secCount = package->SecCount; long count = (long)primCount * secCount; + /**/ // Console.WriteLine($"amount of kernels is {count}"); - long recommendCount = count / 1024; + long recommendCount = /*count / /**/ 1024; MatrixParallelThread[] pool = LeadParallel((int)recommendCount); MatrixParallelWrap wrap = new MatrixParallelWrap(pool); wrap.TaskQueue = MatrixParallelQueue.Rent(package); diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Fma.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Fma.cs.old similarity index 98% rename from StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Fma.cs rename to StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Fma.cs.old index 986512f3..8b01a9e6 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Fma.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Fma.cs.old @@ -1,106 +1,106 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="MatrixParallelThread.Fma" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Internal; -using StgSharp.Mathematics; -using StgSharp.Mathematics.Internal; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics.Numeric -{ - public partial class MatrixParallelThread - { - - internal static unsafe void ComputeFmaPanelF32( - MatrixParallelTask* p - ) - { - int f32 = MatrixElementType.F32.IntrinsicNode; - MatrixKernel* leftBuffer = (MatrixKernel*)p->Left; - MatrixKernel* rightBuffer = (MatrixKernel*)p->Right; - MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer; - ref long offsetRef = ref Unsafe.As(ref p->PrimTileOffset); - ref long lengthRef = ref Unsafe.As(ref p->PrimCount); - int ansWidth = p->AnsPrimOffset; - int ansHeight = p->AnsSecOffset; +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="MatrixParallelThread.Fma" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.Internal; +using StgSharp.Mathematics; +using StgSharp.Mathematics.Internal; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Runtime.CompilerServices; +using System.Text; +using System.Threading.Tasks; + +namespace StgSharp.Mathematics.Numeric +{ + public partial class MatrixParallelThread + { + + internal static unsafe void ComputeFmaPanelF32( + MatrixParallelTask* p + ) + { + int f32 = MatrixElementType.F32.IntrinsicNode; + MatrixKernel* leftBuffer = (MatrixKernel*)p->Left; + MatrixKernel* rightBuffer = (MatrixKernel*)p->Right; + MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer; + ref long offsetRef = ref Unsafe.As(ref p->PrimTileOffset); + ref long lengthRef = ref Unsafe.As(ref p->PrimCount); + int ansWidth = p->AnsPrimOffset; + int ansHeight = p->AnsSecOffset; int commonK = p->LeftPrimOffset; - M128* enumeration = stackalloc M128[1]; - enumeration->Member(2) = commonK; + M128* enumeration = stackalloc M128[1]; + enumeration->Member(2) = commonK; enumeration->Member(3) = ansHeight; // in this occasion size must be 1 - for (long c = offsetRef; c < offsetRef + lengthRef; c++) - { - int i = (int)(c / ansHeight); - int j = (int)(c % ansHeight); - enumeration->Member(0) = i; - enumeration->Member(1) = j; - NumericalModule.GlobalContext.mat_sk[f32].kernel_tile_fma(leftBuffer, rightBuffer, - ansBuffer, enumeration); - } - } - - internal static unsafe void ComputeFmaPanelF64( - MatrixParallelTask* p - ) - { + for (long c = offsetRef; c < offsetRef + lengthRef; c++) + { + int i = (int)(c / ansHeight); + int j = (int)(c % ansHeight); + enumeration->Member(0) = i; + enumeration->Member(1) = j; + NumericalModule.GlobalContext.mat_sk[f32].kernel_tile_fma(leftBuffer, rightBuffer, + ansBuffer, enumeration); + } + } + + internal static unsafe void ComputeFmaPanelF64( + MatrixParallelTask* p + ) + { int f64 = MatrixElementType.F64.IntrinsicNode; // int size = 1; - MatrixKernel* leftBuffer = (MatrixKernel*)p->Left; - MatrixKernel* rightBuffer = (MatrixKernel*)p->Right; - MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer; - ref long offsetRef = ref Unsafe.As(ref p->PrimTileOffset); - ref long lengthRef = ref Unsafe.As(ref p->PrimCount); - int ansWidth = p->AnsPrimOffset; - int ansHeight = p->AnsSecOffset; + MatrixKernel* leftBuffer = (MatrixKernel*)p->Left; + MatrixKernel* rightBuffer = (MatrixKernel*)p->Right; + MatrixKernel* ansBuffer = (MatrixKernel*)p->Answer; + ref long offsetRef = ref Unsafe.As(ref p->PrimTileOffset); + ref long lengthRef = ref Unsafe.As(ref p->PrimCount); + int ansWidth = p->AnsPrimOffset; + int ansHeight = p->AnsSecOffset; int commonK = p->LeftPrimOffset; - M128* enumeration = stackalloc M128[1]; - enumeration->Member(2) = commonK; + M128* enumeration = stackalloc M128[1]; + enumeration->Member(2) = commonK; enumeration->Member(3) = ansHeight; // in this occasion size must be 1 - for (long c = offsetRef; c < offsetRef + lengthRef; c++) - { - int i = (int)(c / ansHeight); - int j = (int)(c % ansHeight); - enumeration->Member(0) = i; - enumeration->Member(1) = j; - NumericalModule.GlobalContext.mat_sk[f64].kernel_tile_fma(leftBuffer, rightBuffer, - ansBuffer, enumeration); - } - } - - } + for (long c = offsetRef; c < offsetRef + lengthRef; c++) + { + int i = (int)(c / ansHeight); + int j = (int)(c % ansHeight); + enumeration->Member(0) = i; + enumeration->Member(1) = j; + NumericalModule.GlobalContext.mat_sk[f64].kernel_tile_fma(leftBuffer, rightBuffer, + ansBuffer, enumeration); + } + } + + } } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Model.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Model.cs.old similarity index 97% rename from StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Model.cs rename to StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Model.cs.old index 92272fa2..57ed2ac8 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Model.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.Model.cs.old @@ -1,76 +1,76 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="MatrixParallelThread.Model" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Mathematics; -using StgSharp.Mathematics.Internal; -using System; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics.Numeric -{ - public partial class MatrixParallelThread - { - - private const int KernelStealCount = 64; - - internal unsafe void BufferCompute( - MatrixParallelTask* p - ) - { - // while () { } - int size = p->ElementSize * 16; - long count = Unsafe.As(ref p->PrimCount); - long offset = Unsafe.As(ref p->PrimTileOffset) * size; - ScalarPacket* scalar = p->Scalar; +//----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +// file="MatrixParallelThread.Model" +// Project: StgSharp +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. +// +// ----------------------------------------------------------------------- +// ----------------------------------------------------------------------- +using StgSharp.Mathematics; +using StgSharp.Mathematics.Internal; +using System; +using System.Runtime.CompilerServices; + +namespace StgSharp.Mathematics.Numeric +{ + public partial class MatrixParallelThread + { + + private const int KernelStealCount = 64; + + internal unsafe void BufferCompute( + MatrixParallelTask* p + ) + { + // while () { } + int size = p->ElementSize * 16; + long count = Unsafe.As(ref p->PrimCount); + long offset = Unsafe.As(ref p->PrimTileOffset) * size; + ScalarPacket* scalar = p->Scalar; IntPtr computeHandle = _context[p->ComputeHandle]; - ((delegate* unmanaged[Cdecl])computeHandle)((void*)(p->Left + offset), - (void*)(p->Right + offset), - (void*)(p->Answer + offset), - scalar, - count); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - internal unsafe void SpecialBufferCompute( - MatrixParallelTask* p - ) - { - switch ((MatrixElementType)p->ElementSize) - { - case MatrixElementType.F64: - ComputeFmaPanelF64(p); - return; - case MatrixElementType.F32: - ComputeFmaPanelF32(p); - break; - default: - break; - } - } - - } + ((delegate* unmanaged[Cdecl])computeHandle)((void*)(p->Left + offset), + (void*)(p->Right + offset), + (void*)(p->Answer + offset), + scalar, + count); + } + + [MethodImpl(MethodImplOptions.AggressiveInlining)] + internal unsafe void SpecialBufferCompute( + MatrixParallelTask* p + ) + { + switch ((MatrixElementType)p->ElementSize) + { + case MatrixElementType.F64: + ComputeFmaPanelF64(p); + return; + case MatrixElementType.F32: + ComputeFmaPanelF32(p); + break; + default: + break; + } + } + + } } diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs index b5e90a92..a5b9ada9 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixParallelThread.cs @@ -124,9 +124,11 @@ namespace StgSharp.Mathematics.Numeric // Bind OS-thread affinity once when the worker starts running SetThreadAffinity(PoolId); - Thread.Yield(); - SIMDID feature = new(); - feature.Mask = GetSimdId(); + _ = Thread.Yield(); + SIMDID feature = new() + { + Mask = GetSimdId() + }; _context = (nint*)MatrixParallel.GetContext(feature); State = MatrixThreadState.Ready; while (true) @@ -148,6 +150,7 @@ namespace StgSharp.Mathematics.Numeric { MatrixParallelQueue taskQueue = BindedWrap.TaskQueue; MatrixParallelTask* p = taskQueue.Package; + /* if (0 > (int)p ->ComputeHandle) { SpecialBufferCompute(p); } @@ -159,6 +162,7 @@ namespace StgSharp.Mathematics.Numeric default: break; } + /**/ BindedWrap.ReportThreadAccomplished(); } _managedThread.Priority = AfterWork; diff --git a/StgSharp.Mathematics/Numeric/Runtime/MatrixTaskFactory.cs b/StgSharp.Mathematics/Numeric/Runtime/MatrixTaskFactory.cs index 55c51ef2..933ad4d8 100644 --- a/StgSharp.Mathematics/Numeric/Runtime/MatrixTaskFactory.cs +++ b/StgSharp.Mathematics/Numeric/Runtime/MatrixTaskFactory.cs @@ -98,9 +98,6 @@ namespace StgSharp.Mathematics.Numeric MatrixParallelTask* source ) { - if (source->Scalar != null) { - _scalarAllocator.Free((nuint)source->Scalar); - } _wrapAllocator.Free((nuint)source); } diff --git a/StgSharp.Mathematics/Numeric/Scalar/ACos.cs b/StgSharp.Mathematics/Numeric/Scalar/ACos.cs deleted file mode 100644 index efcc8f7a..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/ACos.cs +++ /dev/null @@ -1,107 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="ACos" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float ACos(float x) - { - return MathF.Acos(x); - - /* - int sign = 1; - float y; - - if (x < 0) - { - sign = -1; - y = -x; - } - else - { - y = x; - } - - if (x > 1) - { - throw new ArgumentException(); - } - - float r, s, u, vec = 0.0f; - bool transform = (y >= 0.5f); - - if (transform) - { - r = 0.5f * (1.0f - y); - s = Scaler.Sqrt(r); - y = s; - } - else - { - r = y * y; - } - u = r * (0.184161606965100694821398249421F + - (-0.0565298683201845211985026327361F + - (-0.0133819288943925804214011424456F - - 0.00396137437848476485201154797087F * r) * r) * r) / - (1.10496961524520294485512696706F - - 0.836411276854206731913362287293F * r); - /* - - if (transform) - { - float c, s1, p, q; - uint us; - - us = *(uint*)&s; - uint uss = us & 0xffff0000; - s1 = *(float*)&uss; - - c = (r - s1 * s1) / (s + s1); - p = 2.0F * s * u - (piby2_tail - 2.0F * c); - q = hpiby2_head - 2.0F * s1; - vec = hpiby2_head - (p - q); - } - else - { - vec = y + y * u; - } - - vec = sign * vec; - - return piby2 - vec; - */ - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/ASin.cs b/StgSharp.Mathematics/Numeric/Scalar/ASin.cs deleted file mode 100644 index d8d49908..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/ASin.cs +++ /dev/null @@ -1,119 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="ASin" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - private const float - piby2_tail = 7.5497894159e-08f, /* 0x33a22168 */ - hpiby2_head = 7.8539812565e-01f, /* 0x3f490fda */ - piby2 = 1.5707963705e+00f; /* 0x3fc90fdb */ - - /// - /// Reurns the value of ArcSin(x) - /// - /// - /// The sine value of the angle - /// - /// - /// - /// - /// - /// - /// - public static float ASin(float x) - { - return MathF.Asin(x); - /* - int sign = 1; - float y; - - if (x < 0) - { - sign = -1; - y = -x; - } - else - { - y = x; - } - - if (x > 1) - { - throw new ArgumentException(); - } - - float r, s, u, vec = 0.0f; - bool transform = (y >= 0.5f); - - if (transform) - { - r = 0.5f * (1.0f - y); - s = Scaler.Sqrt(r); - y = s; - } - else - { - r = y * y; - } - u = r * (0.184161606965100694821398249421F + - (-0.0565298683201845211985026327361F + - (-0.0133819288943925804214011424456F - - 0.00396137437848476485201154797087F * r) * r) * r) / - (1.10496961524520294485512696706F - - 0.836411276854206731913362287293F * r); - /* - - if (transform) - { - float c, s1, p, q; - uint us; - - us = *(uint*)&s; - uint uss = us & 0xffff0000; - s1 = *(float*)&uss; - - c = (r - s1 * s1) / (s + s1); - p = 2.0F * s * u - (piby2_tail - 2.0F * c); - q = hpiby2_head - 2.0F * s1; - vec = hpiby2_head - (p - q); - } - else - { - vec = y + y * u; - }/* - - return sign * vec; - */ - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/ATan.cs b/StgSharp.Mathematics/Numeric/Scalar/ATan.cs deleted file mode 100644 index 4097f17a..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/ATan.cs +++ /dev/null @@ -1,116 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="ATan" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float ATan(float x) - { - return MathF.Atan(x); - /* - float sign = 1, angle = 0; - if (x < 0) - { - sign = -1; - x = -x; - } - uint xBit = *(uint*)&x; - int xExp = (int)(xBit >> 23) - 127; - if (xExp >= 26) - { - return 1; - } - if (xExp <= -15) - { - return x; - } - if (xExp >= 0) - { - x = (x - 1) / (x + 1); - angle = 0.7853981634f; - } - - float vec = 0.7853981634f * x + x * (1 - x) * (0.2447f + 0.0663f * x); - vec += angle; - vec *= sign; - - return vec; - - - } - - - public static unsafe float ATan(float x, float y) - { - - - float z = y / x; - - float sign = 1, angle = 0, angle2 = 0; - if (x < 0) - { - angle = -3.1415926535f; - } - if (z < 0) - { - sign = -1; - z = -z; - } - uint zBit = *(uint*)&z; - int zExp = (int)(zBit >> 23) - 127; - if (zExp >= 26) - { - return 1; - } - if (zExp <= -15) - { - return z; - } - if (zExp >= 0) - { - z = (z - 1) / (z + 1); - angle2 = 0.7853981634f; - } - - float vec = 0.7853981634f * z + z * (1 - z) * (0.2447f + 0.0663f * z); - vec *= 57.29577951f; - vec += angle2; - vec += angle; - vec *= sign; - - return vec; - */ - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/BasicOps.cs b/StgSharp.Mathematics/Numeric/Scalar/BasicOps.cs deleted file mode 100644 index 8024f2a8..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/BasicOps.cs +++ /dev/null @@ -1,67 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="BasicOps" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Globalization; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float Abs(float x) - { - uint* a = (uint*)&x; - *a &= 0b_0111_1111_1111_1111_1111_1111_1111_1111; - return *(float*)a; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int Abs(int x) - { - uint* a = (uint*)&x; - *a &= 0b_0111_1111_1111_1111_1111_1111_1111_1111; - return *(int*)a; - } - - internal static string GetListSeparator(IFormatProvider formatProvider) - { - if (formatProvider is CultureInfo cultureInfo) { - return cultureInfo.TextInfo.ListSeparator; - } - - if (formatProvider?.GetFormat(typeof(TextInfo)) is TextInfo textInfo) { - return textInfo.ListSeparator; - } - - return CultureInfo.CurrentCulture.TextInfo.ListSeparator; - } - - } -} \ No newline at end of file diff --git a/StgSharp.Mathematics/Numeric/Scalar/Compare.cs b/StgSharp.Mathematics/Numeric/Scalar/Compare.cs deleted file mode 100644 index 16bb34f4..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Compare.cs +++ /dev/null @@ -1,64 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Compare" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics -{ - public static partial class Scalar - { - - public static float MaxOf(params float[] stream) - { - float ret = stream[0]; - foreach (float num in stream) - { - if (ret < num) { - ret = num; - } - } - return ret; - } - - public static float MinOf(params float[] stream) - { - float ret = stream[0]; - foreach (float num in stream) - { - if (ret > num) { - ret = num; - } - } - return ret; - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Cos.cs b/StgSharp.Mathematics/Numeric/Scalar/Cos.cs deleted file mode 100644 index b37c84c6..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Cos.cs +++ /dev/null @@ -1,57 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Cos" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static partial class Scalar - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Cos(float x) - { - /* - float refer = x / 360.0f; - refer -= (int)refer; - - refer *= 40; - int a = (int)refer; //大分度,查表 - refer -= a; //小分度,拟合 - - float refer2 = refer * refer; - - - return ((-sinData[a]) * ((0.1570796327f * refer) - (6.459640975e-4f * refer * refer2))) - + (cosData[a] * ((1 - (0.0123370055f * refer2)) + (2.536695709e-5f * refer2 * refer2))); - */ - return MathF.Cos(x); - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Ctor.cs b/StgSharp.Mathematics/Numeric/Scalar/Ctor.cs deleted file mode 100644 index f5ce3796..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Ctor.cs +++ /dev/null @@ -1,52 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Ctor" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Runtime.InteropServices; - -namespace StgSharp.Mathematics -{ - public unsafe delegate float ScalarCalcHandler(float* x); - - public static unsafe partial class Scalar - { - - private const uint MEM_COMMIT = 0x1000; - private const uint MEM_RELEASE = 0x8000; - private const uint MEM_RESERVE = 0x2000; - private const uint PAGE_EXECUTE_READWRITE = 0x40; - - static Scalar() { } - - [DllImport("Kernel32.dll", EntryPoint = "VirtualAlloc")] - private static extern IntPtr VirtualAlloc(IntPtr address, int size, uint allocType, uint protect); - - [DllImport("Kernel32.dll", EntryPoint = "VirtualFree")] - private static extern bool VirtualFree(IntPtr address, int size, uint freeType); - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Exp.cs b/StgSharp.Mathematics/Numeric/Scalar/Exp.cs deleted file mode 100644 index 7236b2fc..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Exp.cs +++ /dev/null @@ -1,109 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Exp" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - public const float E = 2.718281828f; - public const double EDouble = System.Math.E; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Exp(float x) - { - return MathF.Exp(x); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Exp(double x) - { - return System.Math.Exp(x); - } - - /// - /// Get the value of E ^ x; - /// - /// - /// - /// - /// - /// - /// - public static unsafe float ExpSlow(float x) - { - if (x == 1) { - return E; - } - if (x == 0) { - return 1; - } - - bool sign = false; - if (x < 0) - { - sign = true; - x = -x; - } - - float z = x, t; - if (x < 0.5f) - { - t = 1.0f + (x * (1.0f + (x * (0.5f + (x * (0.1666666667f + (x * (0.0416666666667f + (x * 8.333333333e-3f))))))))); - } else - { - /* - * define z = n * 2 ^ m - * n is between 0 and 0.5 - */ - uint zBit = *(uint*)&z; - uint zBitAbs = zBit & 0b_0111_1111_1111_1111_1111_1111_1111_1111; - uint uintm = zBitAbs >> 23; - int m = (*(int*)&uintm) - 126; - - - uint nBit = (zBitAbs & 0b_0000_0000_0111_1111_1111_1111_1111_1111) + 0b_0011_1111_0000_0000_0000_0000_0000_0000; - float n = (*(float*)&nBit) - 1; - - t = 2.718281828f + (n * (2.718281828f + (n * (1.359140914f + (n * (0.4530469714f + (n * (0.1132617429f + (n * 0.02265234857f))))))))); - - for (int i = 0; i < m; i++) { - t = t * t; - } - } - - if (sign) { - t = 1 / t; - } - return t; - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Factorial.cs b/StgSharp.Mathematics/Numeric/Scalar/Factorial.cs deleted file mode 100644 index 24b3bfbb..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Factorial.cs +++ /dev/null @@ -1,67 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Factorial" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; - -namespace StgSharp.Mathematics -{ - public static partial class Scalar - { - - private static readonly uint[] factorialResult = [ - 1, - 1, - 2, - 6, - 24, - 120, - 720, - 5040, - 40320, - 362880, - 3628800, - 39916800, - 479001600]; - - public static unsafe ulong Factorial(int n) - { - ArgumentOutOfRangeException.ThrowIfLessThan(n, 0); - if (n < 13) { - return factorialResult[n]; - } - if (n < 30) { - return NumericalModule.GlobalContext.factorial_simd(n); - } - double - dn = n, - stir = Sqrt(2 * PiDouble * dn) * Pow(dn / EDouble, dn), - correction = Exp(1 / (12 * dn)); - return (ulong)(stir * correction); - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Log.cs b/StgSharp.Mathematics/Numeric/Scalar/Log.cs deleted file mode 100644 index c11ed98f..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Log.cs +++ /dev/null @@ -1,80 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Log" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; - -namespace StgSharp.Mathematics -{ - public static partial class Scalar - { - - private static readonly float[] logArray = { - 0f, 0.00995033085316809f, 0.0198026272961797f, 0.0295588022415444f, 0.0392207131532813f, 0.048790164169432f, 0.0582689081239758f, 0.0676586484738149f, 0.0769610411361284f, 0.0861776962410524f, 0.0953101798043249f, 0.104360015324243f, 0.113328685307003f, 0.122217632724249f, 0.131028262406404f, 0.139761942375159f, 0.148420005118273f, 0.157003748809665f, 0.165514438477573f, 0.173953307123438f, 0.182321556793955f, 0.19062035960865f, 0.198850858745165f, 0.207014169384326f, 0.215111379616945f, 0.22314355131421f, 0.231111720963387f, 0.2390169004705f, 0.246860077931526f, 0.254642218373581f, 0.262364264467491f, 0.27002713721306f, 0.27763173659828f, 0.285178942233662f, 0.29266961396282f, 0.300104592450338f, 0.307484699747961f, 0.314810739840034f, 0.322083499169113f, 0.3293037471426f, 0.336472236621213f, 0.343589704390077f, 0.350656871613169f, 0.357674444271816f, 0.364643113587909f, 0.371563556432483f, 0.378436435720245f, 0.385262400790645f, 0.392042087776024f, 0.398776119957368f, 0.405465108108164f, 0.412109650826833f, 0.418710334858185f, 0.425267735404344f, 0.431782416425538f, 0.438254930931155f, 0.444685821261446f, 0.451075619360217f, 0.457424847038875f, 0.46373401623214f, 0.470003629245736f, 0.476234178996372f, 0.482426149244293f, 0.488580014818671f, 0.494696241836107f, 0.500775287912489f, 0.506817602368452f, 0.512823626428664f, 0.518793793415168f, 0.524728528934982f, 0.53062825106217f, 0.536493370514568f, 0.542324290825362f, 0.548121408509688f, 0.553885113226438f, 0.559615787935423f, 0.56531380905006f, 0.570979546585738f, 0.576613364303994f, 0.582215619852664f, 0.587786664902119f, 0.593326845277734f, 0.598836501088704f, 0.60431596685333f, 0.609765571620894f, 0.615185639090233f, 0.62057648772511f, 0.625938430866495f, 0.631271776841858f, 0.636576829071551f, 0.641853886172395f, 0.647103242058538f, 0.65232518603969f, 0.657520002916794f, 0.662687973075237f, 0.667829372575655f, 0.672944473242426f, 0.678033542749897f, 0.683096844706444f, 0.688134638736401f, - }; - - /// - /// - /// - /// - /// - /// - /// - /// Returns the value of ln(x). - /// - public static unsafe float Log(float x) - { - if (x < 0) { - throw new ArgumentOutOfRangeException(); - } - uint input = *(uint*)&x; - - int f = (int)input; - f >>= 23; - f -= 127; - input <<= 9; - input >>= 9; - input += 0b_0011_1111_1000_0000_0000_0000_0000_0000; - float result = *(float*)&input; - uint order = ((uint)(result * 100)) - 100; - - float cache = (result / (1f + (0.01f * order))) - 1; - result = (cache * (-0.25f)) + 0.3333333333333f; - result = (result * cache) - 0.5f; - result = (result * cache) + 1.0f; - result *= cache; - - return - (f * 0.6931471806f) + result + logArray[order]; - } - - public static float Log(float x, float y) - { - return Log(x) / Log(y); - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Pow.cs b/StgSharp.Mathematics/Numeric/Scalar/Pow.cs deleted file mode 100644 index 23075e54..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Pow.cs +++ /dev/null @@ -1,121 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Pow" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float Pow(float x, float y) - { - return System.MathF.Pow(x, y); - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe double Pow(double x, double y) - { - return System.Math.Pow(x, y); - } - - /// - /// calculate the value of x^y - /// - /// - /// - /// - /// - /// - /// - /// - /// Returns the value of x^y - /// - public static unsafe float PowSlow(float x, float y) - { - /* - * x^y = E ^ ( log( x ) * y ) - * Now define z = | log(x) * y | = m * n - * and m is an integer, and 0.5 < |n| < 1 - * then E ^ z = ( E ^ n ) ^ m - * - * - * As a float number can be expressed in (1+e)*(2^f) - * n = (1+e)/2 - * m = 2 ^ (f + 1) - * - */ - float z, t; - if ((x == 1) || (y == 0)) { - return 1; - } - if ((x == 1) && (y == 0)) { - return float.PositiveInfinity; - } - if ((x == 0) && (y != 0)) { - return 0; - } - - z = Scalar.Log(x) * y; - - bool sign = false; - if (z < 0) - { - sign = true; - z = -z; - } - - if (z < 0.5f) - { - t = 1.0f + (z * (1.0f + (z * (0.5f + (z * (0.1666666667f + (z * (0.0416666666667f + (z * 8.333333333e-3f))))))))); - } else - { - uint zBit = *(uint*)&z; - uint zBitAbs = zBit & 0b_0111_1111_1111_1111_1111_1111_1111_1111; - uint uintm = zBitAbs >> 23; - int m = (*(int*)&uintm) - 126; - - - uint nBit = (zBitAbs & 0b_0000_0000_0111_1111_1111_1111_1111_1111) + 0b_0011_1111_0000_0000_0000_0000_0000_0000; - float n = (*(float*)&nBit) - 1; - - t = 2.718281828f + (n * (2.718281828f + (n * (1.359140914f + (n * (0.4530469714f + (n * (0.1132617429f + (n * 0.02265234857f))))))))); - - for (int i = 0; i < m; i++) { - t = t * t; - } - } - if (sign) { - t = 1 / t; - } - - return t; - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Random.cs b/StgSharp.Mathematics/Numeric/Scalar/Random.cs deleted file mode 100644 index d0451621..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Random.cs +++ /dev/null @@ -1,126 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Random" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Mathematics; - -using System; -using System.Collections.Generic; -using System.Data; -using System.Numerics; -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Security.Cryptography; -using System.Text; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - private static byte[] randomSeed; - - internal static float currentSeed -#if DEBUG - = 0.5f; - - #else - = Abs(System.DateTime.UtcNow.GetHashCode()); - #endif - - /// - /// returns a random float number between 0 and 1. - /// - /// - /// - /// - public static unsafe float LowProceisionRandom() - { - float seed = currentSeed; - - float sample = Scalar.Pow(Scalar.SeedSqrt(seed), 2); - float sample2 = (sample - seed) / seed; - sample2 = Scalar.Abs(sample2); - - if (sample == 1) { - sample = sample2; - } - - currentSeed = sample; - sample2 *= 1000000; - - float result = sample2 - ((int)sample2); - if (result == 0) - { - currentSeed = sample2 + 0.1f; - result = Scalar.LowProceisionRandom(); - } - return result; - } - - /// - /// - /// - /// - /// - /// - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static T Random() where T : unmanaged, IConvertible, INumber - - { - if (randomSeed == null) - { - randomSeed = new byte[64]; - string originSeed = - ($"{((Assembly.GetEntryAssembly() == null) ? (Assembly.GetAssembly(typeof(World))!) : - Assembly.GetEntryAssembly())}") + ($"{DateTime.UtcNow.ToString("o")}"); - randomSeed = SHA256.HashData(Encoding.UTF8.GetBytes(originSeed)); - } - randomSeed = SHA256.HashData(randomSeed); - fixed (byte* bptr = randomSeed) { - return *(T*)bptr; - } - } - - /// - /// Generates a random seed in int value. - /// - /// - /// - /// - public static unsafe int RandomSeed() - { - float seedValue1 = LowProceisionRandom(); - float seedValue2 = LowProceisionRandom(); - uint seedValueBits = *(uint*)&seedValue1; - - float seedValue = seedValueBits * seedValue2; - - return *(int*)&seedValue; - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/RandomGenerator.cs b/StgSharp.Mathematics/Numeric/Scalar/RandomGenerator.cs deleted file mode 100644 index 3c4e4ded..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/RandomGenerator.cs +++ /dev/null @@ -1,142 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="RandomGenerator.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the “Software”), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using StgSharp.Mathematics.Internal; - -using System; -using System.IO; -using System.Runtime.CompilerServices; -using System.Text; -using System.Xml.Serialization; - -namespace StgSharp.Mathematics.Numeric.Scalar -{ - public unsafe class RandomGenerator - { - - private byte[] currentKey; - private readonly byte[] originKey; - - public RandomGenerator() : this(DateTime.UtcNow.ToBinary()) { } - - public RandomGenerator(object source) - { - ArgumentNullException.ThrowIfNull(source); - XmlSerializer s = new(source.GetType()); - using (StringWriter sw = new()) - { - s.Serialize(sw, source); - string data = sw.ToString(); - originKey = Encoding.Unicode.GetBytes(data); - } - currentKey = [ 0, 0, 0, 0 ]; - fixed (byte* o = originKey, c = currentKey) { - *(int*)c = UnsafeCompute.CityHashSimplify((char*)o, 0, originKey.Length / 2); - } - TotalGeneratedRandom = 0; - } - - public int TotalGeneratedRandom - { - [MethodImpl(MethodImplOptions.AggressiveInlining)] - get; - [MethodImpl(MethodImplOptions.AggressiveInlining)] - private set; - } - - public unsafe int GenRandomInt() - { - uint source = PrivateRand(); - TotalGeneratedRandom++; - M64 m = new M64(); - m.Member(0) = source; - m.Member(1) = source; - return (m << (TotalGeneratedRandom % 32)).Member(1); - } - - public byte GenRandomInt8() - { - TotalGeneratedRandom++; - if (TotalGeneratedRandom % 4 == 0) { - PrivateRand(); - } - return currentKey[TotalGeneratedRandom % 4]; - } - - public float GenRandomSingle() - { - TotalGeneratedRandom++; - - while (true) - { - uint - temp0 = PrivateRand(), - temp1 = PrivateRand(); - - if (temp0 * temp1 != 0) - { - float ret = temp0 % temp1 * 1.0f / temp1; - if (ret < 0.335f) - { - ret = ret * ((ret * (-0.7811934f)) + 1.4489113f); - } else - { - ret = (ret * ((ret * (-0.1158368f)) + 1.0580600f)) + 0.0590584f; - } - if (ret > 1) - { - continue; - } - return ret; - } - } - } - - public void Reset() - { - currentKey = originKey; - TotalGeneratedRandom = 0; - } - - private unsafe uint PrivateRand() - { - uint ret; - fixed (byte* bptr = currentKey) - { - *(int*)bptr = UnsafeCompute.CityHashSimplify((char*)bptr, currentKey.Length / 2); - ret = *(uint*)bptr; - } - - // Console.WriteLine(ret.ToString(16)); - return ret; - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/SignOf.cs b/StgSharp.Mathematics/Numeric/Scalar/SignOf.cs deleted file mode 100644 index 9bb5a8ba..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/SignOf.cs +++ /dev/null @@ -1,65 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="SignOf" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp.Mathematics -{ - public static unsafe partial class Scalar - { - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int SignOf(float x) - { - if (x == 0) { - return 0; - } - if (x > 0) { - return 1; - } - return -1; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe int SignOf(int x) - { - if (x == 0) { - return 0; - } - if (x > 0) { - return 1; - } - return -1; - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Sin.cs b/StgSharp.Mathematics/Numeric/Scalar/Sin.cs deleted file mode 100644 index b113ddf4..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Sin.cs +++ /dev/null @@ -1,47 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Sin" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Net.NetworkInformation; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static partial class Scalar - { - - public const float Pi = 3.1415926f; - public const double PiDouble = System.Math.PI; - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static unsafe float Sin(float x) - { - return MathF.Sin(x); - } - - } -} diff --git a/StgSharp.Mathematics/Numeric/Scalar/Sqrt.cs b/StgSharp.Mathematics/Numeric/Scalar/Sqrt.cs deleted file mode 100644 index 6f47330b..00000000 --- a/StgSharp.Mathematics/Numeric/Scalar/Sqrt.cs +++ /dev/null @@ -1,74 +0,0 @@ -//----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -// file="Sqrt" -// Project: StgSharp -// AuthorGroup: Nitload -// Copyright (c) Nitload. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. -// -// ----------------------------------------------------------------------- -// ----------------------------------------------------------------------- -using System; -using System.Runtime.CompilerServices; - -namespace StgSharp.Mathematics -{ - public static partial class Scalar - { - - public static unsafe float SeedSqrt(float x) - { - ArgumentOutOfRangeException.ThrowIfNegative(x); - if (x <= 1e-12) { - return 0; - } - uint a = *(uint*)&x; - uint f = a; - f >>= 23; - f /= 2; - f += 64; - a -= 0b_0011_1111_0000_0000_0000_0000_0000_0000; - uint e = a << 8; - e >>= 8; - e *= 0b_1101_0001; - e >>= 24; - e += 0b_0000_0000_0001_0000_1010_1000_1110_0010; - f <<= 23; - e += f; - float result = *(float*)&e; - result = (result + (x / result)) / 2; - return (result + (x / result)) / 2; - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static float Sqrt(float x) - { - return MathF.Sqrt(x); - /**/ - } - - [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static double Sqrt(double x) - { - return System.Math.Sqrt(x); - } - - } -} diff --git a/StgSharp.RegularAnalysis/Abstraction/Token.cs b/StgSharp.RegularAnalysis/Abstraction/Token.cs index d314700a..e35df5e0 100644 --- a/StgSharp.RegularAnalysis/Abstraction/Token.cs +++ b/StgSharp.RegularAnalysis/Abstraction/Token.cs @@ -97,10 +97,10 @@ namespace StgSharp.RegularAnalysis.Abstraction Token right ) { - return left.Value.SequenceEqual(right.Value) && - left.Line == right.Line && - left.Column == right.Column && - left.Flag.Equals(right.Flag); + return !left.Value.SequenceEqual(right.Value) || + left.Line != right.Line || + left.Column != right.Column || + !left.Flag.Equals(right.Flag); } public static bool operator ==( @@ -108,10 +108,10 @@ namespace StgSharp.RegularAnalysis.Abstraction Token right ) { - return left.Value.SequenceEqual(right.Value) || - left.Line != right.Line || - left.Column != right.Column || - !(left.Flag.Equals(right.Flag)); + return left.Value.SequenceEqual(right.Value) && + left.Line == right.Line && + left.Column == right.Column && + left.Flag.Equals(right.Flag); } } diff --git a/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs b/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs index 8ed5fe7a..b4da0e6d 100644 --- a/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs +++ b/StgSharp.RegularAnalysis/TextRegex/RegexAstNode.cs @@ -56,18 +56,18 @@ namespace StgSharp.RegularAnalysis.TextRegex public static RegexAstNode Empty { get; } = new EmptyRegexAstNode(); - public RegexAstNode Previous { get; set; } + public RegexAstNode Previous { get; set; } - public RegexAstNode Next { get; set; } + public RegexAstNode Next { get; set; } - public RegexAstNode Parent { get; set; } + public RegexAstNode Parent { get; set; } public RegexAstNode Left { get; set { - field?.Parent = Empty; + _ = (field?.Parent = Empty); field = value; if (!IsNullOrEmpty(value)) { value.Parent = this; @@ -80,7 +80,7 @@ namespace StgSharp.RegularAnalysis.TextRegex get; set { - field?.Parent = Empty; + _ = (field?.Parent = Empty); field = value; if (!IsNullOrEmpty(value)) { value.Parent = this; @@ -88,10 +88,7 @@ namespace StgSharp.RegularAnalysis.TextRegex } } - public RegexElementLabel EqualityTypeConvert - { - get => Source.Flag; - } + public RegexElementLabel EqualityTypeConvert => Source.Flag; public string Value => Source.Value; @@ -108,9 +105,9 @@ namespace StgSharp.RegularAnalysis.TextRegex } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public static (bool Valid,int Value) ComparePrecedence( - RegexElementLabel left, - RegexElementLabel right + public static (bool Valid, int Value) ComparePrecedence( + RegexElementLabel left, + RegexElementLabel right ) { left &= RegexElementLabel.OPERATOR; diff --git a/StgSharpDebug/MatrixTest.cs b/StgSharpDebug/MatrixTest.cs index 482562ae..dc5ca60c 100644 --- a/StgSharpDebug/MatrixTest.cs +++ b/StgSharpDebug/MatrixTest.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="MatrixTest" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -25,7 +25,6 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- -using Microsoft.CodeAnalysis.CSharp.Syntax; using StgSharp.Mathematics.Memory; using StgSharp.Mathematics.Numeric; using System; @@ -55,12 +54,18 @@ namespace StgSharp unchecked { hlsf = new((nuint)size, 32, size); } - Matrix m = Matrix.Create(sideLength, sideLength, MatrixLayout.DenseRectangle, hlsf); - MatrixCompute.Fill(m, 1.0f); - Matrix n = Matrix.Create(sideLength, sideLength, MatrixLayout.DenseRectangle, hlsf); - MatrixCompute.Fill(n, 1.0f); - Matrix p = Matrix.Create(sideLength, sideLength, MatrixLayout.DenseRectangle, hlsf); - MatrixCompute.Fill(p, 0.0f); + Matrix m = Matrix.Create(sideLength, sideLength, MatrixLayout.DenseRectangle, + hlsf); + + // MatrixCompute.Fill(m, 1.0f); + Matrix n = Matrix.Create(sideLength, sideLength, MatrixLayout.DenseRectangle, + hlsf); + + // MatrixCompute.Fill(n, 1.0f); + Matrix p = Matrix.Create(sideLength, sideLength, MatrixLayout.DenseRectangle, + hlsf); + + // MatrixCompute.Fill(p, 0.0f); /* for (int j = 0; j < 20; j++) @@ -73,7 +78,8 @@ namespace StgSharp /**/ Console.WriteLine("==================================================="); - MatrixCompute.Mul(n, m, p); + + // MatrixCompute.Mul(n, m, p); /**/ for (int i = 0; i < 20; i++) { diff --git a/StgSharpDebug/RenderStream/Partical.cs b/StgSharpDebug/RenderStream/Partical.cs index 9d82f644..1d791f3a 100644 --- a/StgSharpDebug/RenderStream/Partical.cs +++ b/StgSharpDebug/RenderStream/Partical.cs @@ -25,7 +25,6 @@ // // ----------------------------------------------------------------------- // ----------------------------------------------------------------------- -using StgSharp.Controls; using StgSharp.Geometries; using StgSharp.Graphics; using StgSharp.Graphics.OpenGL; @@ -192,6 +191,7 @@ namespace StgSharp GL.Assert(false); } + /* public void RenderButton( ButtonStatus status, float statusBegin, @@ -200,7 +200,7 @@ namespace StgSharp { provider.UpdateFromImage(i); } - + /**/ internal static Vec3 DefaultRotation( TimeSpanProvider provider, out float rotation @@ -208,7 +208,7 @@ namespace StgSharp { rotation = 1.0f / 60; float angle = (float)provider.CurrentSecond * 2; - return (new Vec3(Scalar.Cos(angle), Scalar.Sin(angle), + return (new Vec3(MathF.Cos(angle), MathF.Sin(angle), 0)) * rotation; } @@ -222,16 +222,16 @@ namespace StgSharp buffer = new PlainInstancingBuffer(); for (int i = 0; i < 10; i++) { - float ai = Scalar.Abs(i - 5.0f); + float ai = MathF.Abs(i - 5.0f); for (int t = 0; t < 10; t++) { - float at = Scalar.Abs(t - 5.0f); + float at = MathF.Abs(t - 5.0f); ParticleOnPlain p = new ParticleOnPlain(buffer); ((IInstancing)p).Coord = new Vec3( (((-5) + i) * 0.2f) + 0.1f, (((-5) + t) * 0.2f) + 0.1f, 0); ((IInstancing)p).Scale = - Scalar.MinOf(i, t) * 0.15f; + float.Min(i, t) * 0.15f; ((IInstancing)p).Motion = new GeometryMotion( true, TimeProvider, DefaultRotation); } diff --git a/StgSharpDebug/Shader/ControlItemRender.frag b/StgSharpDebug/Shader/ControlItemRender.frag deleted file mode 100644 index 02707466..00000000 --- a/StgSharpDebug/Shader/ControlItemRender.frag +++ /dev/null @@ -1,12 +0,0 @@ -#version 430 core - -in vec3 texCoord; - -out vec4 fragColor; - -uniform sampler2D tex; - -void main() -{ - fragColor = texture(tex, texCoord.xy); -} \ No newline at end of file diff --git a/StgSharpDebug/Shader/ControlItemRender.vert b/StgSharpDebug/Shader/ControlItemRender.vert deleted file mode 100644 index 01282a55..00000000 --- a/StgSharpDebug/Shader/ControlItemRender.vert +++ /dev/null @@ -1,12 +0,0 @@ -#version 430 core - -layout(location = 0)in vec3 coord; -layout(location = 1)in vec3 tCoord; - -out vec3 texCoord; - -void main() -{ - gl_Position = vec4(coord.xyz,1.0f); - texCoord = tCoord; -} \ No newline at end of file diff --git a/StgSharpDebug/Shader/Image1.png b/StgSharpDebug/Shader/Image1.png deleted file mode 100644 index 5e95b0720a307130a5af4df80b7c62910803dc5c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 29445 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%0Ak?foFu+6q1@%MS6aJWkbC~r zY5;jAHC%>S#+Y|(j{jv5_1b+9m6o$tOG(dAxbE2P;gWNErU`I~kJG^RHKP_q0+Q56 zU%FEmu#mZNqX0&UX7ep6N~)xNbPh$&dKrezQOZ*D+9Z0z$iEqso>9g}7SdI@LD(On ziS*deQ!f=w?v%boKF`29x-?`42Q>s-HSA1b+F?WE88m|H zT*}iQq6$fGxJyd9`7ipN9_$2hUM~k<#q9@QBCnG!=CAv%pIjeGUwON&f4t=9d#<(F zIzHmukuV5bvwXB7<{^KRus}0?GX2yGqt5{K$;9o+8c|lL$KPwTqU#a9V zS;`PMz37Tf6t)V2!gxRR3xMnd&pxkBe}1X>FIj%&x#~S+kV+kL+933S9hJ}D^0rZ} z+zjF^Tn=|XKb|t;b2=@{!x`xYwbWuwCx{wOZ^`9*!A$;N+`6dlM<21LKF|NioWhJs z-X6LWUJX5rydg!Qz;5u*ZaN%%tJz;a53Y_j^XzgLgry66xxeaAP>qJZcc#uV&<(4p z9ozR4!UDPSmDPO&!+s}nzM`B>%T{a!zVbU4M9TywGPF8l8OzFa8VZEoc#E9Re|;ZW z7-?0E#PE<~2KB0cO{j3aYMRPLgpW{m7M=J#u=V{l*xT784zaeC>R-f*VJ!(hIp1#D zoAI6UISM1vw%>u|g0xtH`1&u8$WM+L=KrAj{qVo?mqq;`7e^m0;NXs5RhcgFGWUB; z=^I7|v_)Z^46B_RLYL?-Ax^gvMvCvoT-rbLZb8oucGcf8(08+CG*NA3{%a_gKUzZ> z+qF>*W(WBIx>|ZNLr87p@&bav?TuCBEN8x}!xemrM-r#?^%1P}dyW`=?csJ%8{0G% z!WcD~aV15yi;)bGyf`KR)5&?fLBbK*6e+5v+V-Ts-+EE~-siS*4)yuT19JZIs;#a~ zDkgtAv2b4@plPGg`4_bcJ6(`M?lh0N@yfU5Y-Hn52ig)3Jetsuszii{~ z3{PXVrQyOXG;SVu;i|Sf94iNmnw}%puBApKd0(tcT;Fh%&QbmHn2}N7a_N%sr5CI6 zmfVtvEM$Jd_;!NXRg75a@}a$8+%}PO-!fk4K&C^%0a1H!n)Q3`)HK|6kcjh+AyBLW zZAU=me~g%mCv6K{;d7>!Fm?vmbHdbt7fkQB&2TeYANS0$}&8|kf zs{dXP;}~+{V-07#Bx*$5uK~PoeObg=eTb)-3OFk-|L)bX{T6z4PHW*vnsAlDcs*M> zzI!HkD{uf0d%gqTOW|Ca160x7vn#F?Hrz(F+h)Y~Ty97rTdq08A2}^0-h@6u3hjfrUys!PAk!_*m##Ah4s18M6y_`)*xx;<@eETtuD|Rp$N?0WI32AZ+owN6tGtZM1WE;Y}aGwx$_tn zs|;Uf&z0Xf8rZZ%Jxh!_vm}T7d=^aBeKht}=t~shuJZbU1Za-E_RtKe4wO8Vw4>~CgM+VCwlT0w2U2C9~i zBI<o3 zigF}OiJsGnjBWq{`mcWzX?A@mREcUGi*-wKxO1NLg|i-PG?Oa~l?Rd_|h_inRJo0XcE4ZURzG#^UT?Cj>5gOHicC5-M|1c zN5-n96oMF7HwZv-ULUJun&iOcsotH5CS6*II1om?YMOO))Z?}~ z#3mu;{HKi9M|zfw>^XD=k85ikeoT`%JRL-MzarT=@pIF7qH1obOt?NALbJV(vUs9b z3##Xab*#+XoQk!|C#qGUPKrp`gtdLQAxw)2S~;F(Oldqdwrz&uBkZUE_C%RGed-M(7I7jeog}$8lT)YW%ikdEcO0VB4Z$|4WOYUiP|#{{sL$zNKhYlwuI^>) z0l~a4Z6H>qkB+c~grDChNW= z)s9{z&l4hS`gt=byA-J&?`WM*6rx5NXD#RfN!FMO?`P`GlpwmHLUi7KH!{|D?kNdl7j`4ynh5=SHJ2wi+MQM&6mO(-3||9`zE=rKIM7i9U#kcW$FgJ+54j> zZt%Ucf#ne>Uy~U2Shj21@=}2r5^sF{d#^b#g^zO`(Sfq&^b;?bf*22u5tUs-i=w`|9GJuc<~@8=y6tz3pM;VKwKN4K zQMYqJuDd$*M4Sb6MD4aT-bYJ^WLaZOCbwKot7)Nb8dL@qXcBe${zf1bG;1So`YO6L zRyMvFtD*XjTT8z;EI9mjhp=2l>zTa(AA{^+#-^mpV-m-?yP+jN<-4LT1)Lw~4`oSC z%~&wq_uD({;~3RdNG{;+=UeERzN)HTf;7wQCAJw8p8B)%V;mVPT19A_+R;F~06U|s ztsa#cAd9>qobqU5chnNTKv=eqcT3|trs;D|hqim_vaR&CCdu5uvX;bz!XDbXR_R<=aS;;P@_UZ+k>HS*{WII<^ zn0#Ky!+ikw#kHuoFtV4>_TEwvHjoY8bE?%vN01%=>)+gl7>`NP@L{$VQ5Qy8-+0N; zA9S~2Kw+7pq8w`enIt=tkRzsB?^B%^Y1DD(Q6r9g_`dP*L${zr=;OT`J`C35MdLNa z#Whk~Aib@6CqaLBRrSK5!RGP~{4_UuNH+!w@^A=X@@p$K>qnq3H_VHK^4#~@|4~o6 z*%k@H8m?H>%(3rMk<%v=D}(O7;!0CB`XgJ0*e&jth`)SqJAVd^)V{9zV}cyT=@Qvgo0E&h7Q*BDe+EDt z1Hj6X`10_RN&+R)Tmw%8)7#cMDGNW0Z4JsjdKy}-d{awgFrVnL$X_LM7yhq9|8CN2F7_h8;@;Sn0> zETxN?Ws|qZg>g--!z0U6p9VP-%R3fXS%o|d#~Wq#Ql1Jo%k|dbF@@4W-D%r73YEDE zm9oYe`gcQ>8w^aaM?oY(h0D0z4yORlAtGEW^I2BgG);s1Y*w5=LGOP zZ{)aN*`@RP<+sRyYfs(`O>kfcN8b5vY1a+di1-_KLi>=%LA_yK{_oTmz%|;;CZ=%L zVlmxtLVDtcyrot1%Ntnb2X!#pz1AM1ZpiiC`k@*h5HSKca2D4wXY4-?LczE^4lufz#H$F(M}|p-90K>W6_D# zhp`#|GG{Dj`NGAW*gvJ3m_Yh~#{SY?T^G=7Qd1 z@l=8~Jj|z5YuIZ{<3T9(EQ#ZE6>}sl*JUr3`Lr>?Ia|d?qP%8Y93~>{`hf_9R~#f4trVs)N5r3kLAv-ko2^8slLL9b=MgF+$`*DMGxKJE z_)sX|`2F-`ec@NGZ)WoLRekD{H-xymo%dE?PgZaX{UlU0U zW3*3;D_Er7r0LydTRoEI#*4mq49@u_V~J}+?PesM106PX+kOY*Vmt75qs0pH?r#??%BfFEvbxWZ>{(jQSpGrQD-@NQ0DGSRz8R*FNivYQ9B}+H+H8y9WHmI1y7uP zxn{WWJUKY|__UU8fSdheu=gu66!GPtzJswRB1=TD^Qcu@@ipy#jja=5Tz+5 zJvI1MZLVkqyTKUl_UXGv`CxW&qh&YSBz3x-KUVj1hx*}X0o5)jS zOkVR0-kS*?eC^#$bweb?P&H|Uufn*T(PH7?8BSSn;0se%>Z$nD6koEZeS)^A0e{`+ zFmFM4O;|p|nrorNOrWy*U->Wig-T!YMy_yyO3$}4kz-vse(HTj8Ph}HpdYeDq1TWv7DfD}CW6|SQQobg-vM}An(}5w>RGt=f8_~y zO1w8NYusRwhV=g!CnfGpIz2|uZ~b6GbR-_@j79Meqeuq52b9JI+gjep`&JV;aBRv{&{bgDH%*;rjs@*#>p$7SJBr=UnrwjLe z$magcI%qNNHdJFwpPICX`veMJIX&0lvKSjvF-I4Qc-$$)!Y#eAiLrDAYNr8@b<41k zeSWhaS9b7WTMxQ!wL>d?N}oPtqoYdF>tC59gvHc_S@9Qm;F z`eQ|1J2G*8seS4<87oCn=!!@<3i=w`SFV=iZbVsByxU^9ON5HcDC}p5YUK^~HX=)APT#WHFTFB4Zb4D{#Xs!5v^5ybBh|cONCab^H z7#X8_;AM)>h(CthGh@O2NtSv<(@qBYO_JLCE_Q`c$T+Sq-*Re0JV2M^o#$WaC-5W!zt!FV5YRr7W#5 zj2sS#8-Q5YSM!qaS0Q~?a!qFD&rO3%1O*dwa?6#hQfwD^Cq?NX!SSy!=w5ED+&G(^ z+&;?{p)%`2oAqB7*fFAkYs;-;zJU)B)zHO+N1cLn(p8z#W=H4!jlifN7Gy;a5L4=N zDO6gy%OTW{y0deSdS!ecy0*uEq!lI7F0~eCq3XCK^7NgjGAB#SxVusO3)KCdD5g?EK>VARMa_Yckn`_T_}HoL5;?c;xdkQFe@P zn}UNUi3{@XvtA#$w&(Sc>j$BH1pqzqtih4b)R7yn&V!i~H%#5|RXQNAc_{GciZYqh zD5*1DzG8BR29d&Wz4}UbkbYfhYVfD?nBAlc+gjN|ORP^`mUF}UtIcSxp!K~tF`^?& z=D1{&z9AuLA-qGjxCnj931_72dD4YVl!@^6Z%}WKUK>VctPd?Y`WyYIGh2RDY>FMsQp(B@L@&>ALOH%`fv4U6GHe02-wcCEB1%|ztIq-0DNLJD< zIO=m*-?3}|ijU;CharNz&!U%o5v#B#9;|dTLHoYGEJ-Zz-iUFAKM}Db{Sge%Ny}ez z=k~@}K3d`CA;ZT+L2XSS?*&6S!>g3KDD^6*U>-B%eXV$|O;u7pb^2x#a=(4s{;xcA zf^A!=ZfhU*Bd6Mo%i*yMmtRSo_NR}9tbrwn)dW$qWFg2ecEUek#J;TqVKFM|$X>fB z*ztu6naXiYX$5EW^DhTY(?l7q1AOy^iEbJiziohmdqp7KC}_x-#CS*WC4tV&rNUy> zI%AnirH&#Jzq3lW9Un$G zH904)pojl4-i1d{m@Wr-KPOuGp^FRv|~HwfjvatD|ionpU_^<)gl(F`Yo=wDq@vh>BIri4e{}=kc$8 z{TCTKK@q&zqech7pyxb;!UB<@WW!#N1}n;M^%dDB4TMSy26 z=t0M$NTb=x2dG~MbyfTY^J0E$Bd#KE9EOxhqQXE*eMd~bog1+~*+|{&%H;<*n2DcX zWrmL0kBWQhjS?@YhpO1+y9GXpD?^xZZZ7tWH#|WGhszmGH_<}U7zl_VH~QJln%~vX zF;51UXg&8>`4~dWA+k0s_^5W?Z*hVGL9?$o0xd1Om>Qwg3-h;*$g>huY zOuZ(F^wj=bz{WAslnY_s?+Wbk=Pb*PU(<1S!81kw)e-Vyk| z0a%EKHTOVX|1s^s9oLTwgJ;mcqjnyR$(COAkoimP!jRWWhEl791a(Y}t1_094I49J zvh2V0Us?AylFOnrP(-dnh>7oo=9lCBiGs!eF2C{c!^MQ(U_B}4&WIGtv>n1AZZKAx z2rKMZ?Wbl0RU;K!8?2;l4@-63KgQNPE$a*K4HEr+5-S{&dXi?d-9J{oy5+xKFUKys zXRyH^spI39GjVUd#$R_d#yC+I&zw7`8=}ofE$2pC!ok+FzR9vd%9>nCN`!|%Y#nt9 z$R7Io_6q2iq3Tz~i3X{xR4kT+A{{24*`fLqLG|F4DI9zHYp&kjGawdz=S7tAtXDsU z%)rJIt0uR=%l>je8CWpH{RWVlx51ff0aLF^_E@8o6_j=Jg<}5 zG($siJN2r}4t+sLAEjCu#FSuNUgRoyM=`@|H1%mFy)haB^sx5y| zm$8nBA?3@#LS~TK5<>o8CkoGPS#;Tw0WD2$7u>;RLC={n!v7{;8)Pz%aAo&xlK+mQ zCsfYh*c-44GYo$F_4apSR}1flqK{Tq^LnHmXD)KhJVpguoQ7ja2_Un8r({a7)^8Bm zkt*L55vT22*NsN88e7RzGH0K<>e~$Uto{zIs`<sYZye2+}MM($(Yo*cbDQL9@oCo3>2VDcFVcZ0eG$y;>yGSFYV#Uipcr_JRBX_fn zuot3IfAlSXTHTVtGk@@Mr_|3LsE0NT@R^usH{Nfbpevh8T%0hr9mq(`k$d|#SSy<2 zj-$DXuUN_L>srb{OxM|hAo3aO3Ob~d6*9lArNUMIdLJ?}TAh66yH+@)z&Q5X&e@+s z-OACfwV}_txZ*GBGgSKYxN0;K+KgnBf6BRCfdf*u|fJ<}fakf1C@2tkmPS2h$8 zq5ztHKt3QM{^c#DSKTQF*#-pVNGuVjsS?~#h$!sp;= zc*hT>K}6U5l^V6*exd#K2DSyIFZ;~k*g)qeC?faN%6w{)!;xff=RI|l%FV+ub4hc< zDe+g&XrTxQWc$6pJcM5gdjHw>F~=-J5*{);S{iTnz>t%EJ36I*;6tCfmpIq=c8y1F zJ}#$$BQSR~`rL@`}iT*-V%A>^IGfbDZhWw3d&>WE5KhJ@5FYYN%cf5G)pr2pMZ=vq$01Dn zt+$w6K*``Jd0iwnr+=kcvlmH0n%*Zzo0}ySwevB6J$k1Kpf-> zuxY6x3yW}Y5y~AxKYTVP$+-jQCh5cZ-8!yNB=%i@l0d1FPcb*3=%aWI;{$C)MM@1hQ z!gkZH)*2H)o-%=p%G1-OKjr`4_wi%iOV+ET@Qp7^l02zZ(9R&3yd~9F~sDt+l@-aU#quv?n&Y}1#IZVH*2%+dL%>gM`CYs6JA{hDG0(&y87le~y zoiC?mTsp4f?~K2M!0mHMcl+2JRQUf&Z_V|({}D=QGhDR3nU8%&R(0ZZ_?D+pGA`b$ z9>0&28yqQx2IB zUH;#L#vRNEW!arfG`7b{u$SJMq_<0Q`l+8gOce9G0_){y3@v{2HYI>bpZ_ldahCn$ zL)6LON2Ak@3OOyDm7cDu@FV!6P(%!eVZmKVh3I9X0jkA|l!EZY=3__S)o>I2(YO&cRO0SZM3T9JX)C2U3 z=0Kc;zBjHm>^Tqq6mJuQQ%u#`+7{~Jpk_zKM8!+Rz{Liz2vH!0%=Qy*G9JDQsBR$o z0im+Ukzg4H=qr-t*|d?}kvgZ2wLM?nS?i}04_EWVo8jF8Ykxht1A+9s2Z!4+q!;I8 z6K^ib0SrI@oZkT8`T;ziV~7MdNuvqn&`x410U8P}TH3emty#U}p*$6=5QsGB9LhgP zJ*pgkdS`6LqU)0_G~j$pP#3=357Zdei$mL65BoT$rZ_DLRq88-w#;Q~fqB=*yYV+<1|F#EDVimb(?Sx< z`#sWuD!ohf2(aJ(q20-gtNemMvdO#74~`lO94LZnhx92h;_kbgbR-@a5a0Aq3Wo@I z3rhrY-9j0iFU&IL)O;(Qm<~+2nIMd&D<5byxXFLP=(weyu+#nFCY~z*ue^YZ zynJ9~(6U-_VIq+S8NPRylc_f&8Kd%E)y-$J^vHCD2okhWPD0!i(yvg-Mi zTy53-xFoIbX+7~1_&`I#aW!V#Q1*Ip;IBJJ16G6@b0t$>Fh8E*6?nJQQ%(FY_9!L* zx3a;WH}KCVWcn_Gy4gYf6FKAc4V{}hLU|0aRc>utm;v9T()#UHV0~%rqRoKQWgW9D zfCHEW2{Y5?bp>S!!gS1fe1Z^bTsh{!2YlbP;?I=V1Gx$|w#rq^GVJKbYj3)H-^yih zc|jmgtrATM^j=E^jRpHj0>0M%yD&57c*Pt^beZ1%ocIyD=zVUPYHVliKr{fq;PfLj z(i3M-k2urSRQd3Gtu-Sd4x;nP9suU-Sfd$n4)E@VTjg7hsbdZIc&B6Px$+)vO4Th$ zu$uudx_%K8c^ca*D`~w|0`P7yaOz*HC1>0D&PH7&YNaCd_2r}^R~3A^Xw0mcE5Z;S zLUx^DJtZTlk{*#VzmowTa#Jh1fW1jc1%c>!fnnZj^TzfhgLDc8yq!z{%=r)Vn69ln z8UH~XD(>}ei{*H>E#w5JXjp{FJZNE{rMj^KKs=Kkjk5O_<6-P-#Sn<~ZTtf38?vg2jjr|e_ls`G7Wqr!Sn$B%u|9@4FnP- z0(J~Oz2NZ)KL7jY|4zdHM#BGYhyVZQgf~AfXda-6Gr2Zjcfrr9+So>1Mx&_viT! zo*#If^V+@lj+wbw3D@*PC!O7~qy(Iv6E@Zy3)_Su`B!0DW zF7qlJmh{R=^En!|rc5M^FrJZ>1|3&9oF;evxkfjhoE#GQU`{wI=mB>)ytp)w)8(80b zDHVW0?+oCg)mhNEKF~pcYd|!h%*{3cbq>IU$$x7KfMs5%dP4xiB%0@toOpnm zz%m>P*oXq<<2s+^06i{%(CSs6Ffhjfa4G3pDFW5sfvz!J%vt~q3*gcS4`Bh2yaAIz zIyz4vI29n2Kh+gGVXMU5W(6gcS}WE}FDw^eh{oZ9s;m2wl6g#tn2k`t6u~r2>SfQT zR8pP*zGrJ^qX3W-{~SE+*@Nd8PUYB`KujZ!F~?pf3Y^x=Y~%6oc$u>l0Ia+DO+2!5 z){((PQD6>_c??HLHb$5^?pKjkwa=s)fSlb0-81JW*~sO_HP6rg-Q1j0?vpVz9oF@I zwC*wP(tWVM@e{khx>)P@Lm$BNEsKfOyAq6u&b^ynMxktLN7B z=L!H$Tb;V6nb8noHbLv-9`Iwy2ZbC40A{6>-~s?fQ2Liz!*!BB&;S6M6Tn(6O@7`@ z!rq1Qq8oXs8}r^oAXtXJuSW(~2EzjO;)4lGd7un)=+9~jRuj%?DGI(W4V%zJXPlQk z+D$m(&d+X5(XzUk+XB#$qzBOmOlcOvA!eWT=wi@_Q$wz4x)qV|Bk8G!!U;8KU&Zq) za%+CpqSjWVI2HeZARP8qz9n9C5a0>C4{cN6P70{i5TC|skZmp&Bny_$!~A98#+?>R zl#~AJLp_;zltAwGuQHow3$YTiKe)PfNKkqE?73bJ^vcu-v7;xNkJQkXW0eh%RqK=^ zwnki-kJor0;Rncdp$i~+$WWV7N-OHA=&8;r7E`~V=fhh-7eq%4*63lPO)P#@&)9-@ z(??>)!yTrl$WAwlA4|ZA>m4rJCrFPUAk2R2~$ZgcD(g-Ui;B!wC{uxB1^s1mDFL{d0hS=unebtUz3*K@vrRvvT zx|1Wj3OiqS5YIiZutT2*{Rp>aCQTkbqCCI&>vYq-Y)k#~A zwUO25dHgU&vT`zGGC3=!R!M1L=}IZ4_L=sGR&0sU8{bNKZQeHA#tyqI)IET|kFnexFwek6He(kQef) zG;>?NwJZJd^^0DaVwpyn!hX9z+Y0sQbSyeb$?7nIWvMt7t$b?VzJ1}#`JnaSa9ebtfTf30heeOF zh&4tc*3a+aBu2scWAQ{o_Fb=(Y=LRA>DTq(_~r?*{2BRZ`Dan@2i|VbZ#WD%4CFJS zFw!u-dcF7hC{6Qqb0JHisEVk{kDsGI^M1~z@~4Y)|K{0F-%kIXzWUw7z|(-evAD6x zQmJ;+piuv)vCT2WKv=&(Put*KoqR=R1;cD>MQagWQL}2IYFXB-b#L`a<4|MCchc&= zb0~|IjSh{zrq*V}*5CUpdyf*^6Mb8JqaVakvBTzZ$|wvd{9Nll5Q^xCtfY-)97+22 zpMTlqwALHP9iQXfXe1b6>3g5~CVfi5n%KJ8HRvonGU8R>$jh%1FVo2fmIvE6mEA5} z-mQC0USy`%rS}{bFIF819KAmZTgo2g%Vx>a=XL$nJ1D!R@pnQJGdr2fZnfM`O;#>^)A1y5G+1FI3Yl)5u;wET)jK5ZzG880T<3vI*|5{2miavaYMpTj&?) zO1d?-ns60|GC!+C=}TL&1;G}+7RiB^R{EnedYO7k_OD(DzhtcxaJ27Oy+1q)`;++x zbHkfBg>&$o^QYXgp7W3*qLP>R>>^*JRKit-lKx5KvKA9XF`N>3FvMVd>Y?bdrsbRv zmOE|bdfBgw2#ydJmMnl+(8NP zaV|2YG_MmIt@o_AtUivETZYs=_B%#?=cG(V9kQ#7D@WGnz-W{y+|e>%{>_S7Yi+4( z)%i1GSolj>7TeFm(YoQqIKhnLZ1^F55B_>WV?pRET@DJpt@d(T;aV}5Pm35E&ym?e zbx_L1nm#wOI?Sk*9qN9q^lNAIdTkeA)IA*7-2k!M$JEC78{)ga^!xCgnjWYAYJ=%* zXePPD^N7!tgp0&qpZm`-FM0kY4|5vsOkGNnn~U z_WVLU_Nq?(;l-ugBInni%!{o-jk3-8onlRGmPJEjKSd?AzG{=Rmc zI3o9MyW~5VSu||BdXO0ESk#7Szn-z0vAk2dtGkk{j40i`{&MH=u0qwp|C92W*3kQf-N30t z>(lY5%;Zd8zn3>lCX0EE-rMG5tG3Uaj$3fu)+goQk=vqeqGNAQo7_%o7ylCIHtD8S zi5NTVx$TKPCQhmSXw7I%t89L2*L>vF-r#L@wM(8QIJSJ={^^7WK0A{oEWX@+=H+zN ze|51+wCwkR>0xZ7b>4&NsG?1+&G=mEPGH zzn*?g>~!!cc-ZUOC#_l>=oz5w81m%hHage2JM8vY@}M}*Uwx*w=|k<$47a(dxp?!d z=q`~oF%gc0m~wV+&dad~;!SFEMa|a$;Kcv{upj`qfrHOo0C495fISlc5J>?5Vy6V- zet7^$>QRD9Yk4jl_JwXEEj_8JxbS{p`Qf3Fkr#FU~#{yk+sPqQGll%o~7Oyn>?K zE0ILqLNEao+3#yoP>Kkf>Phr4{E0|teOkBx?!*shePnnHu7(I+0lvmdyytBCs!;WK z?Pm{HR9hUh!|IRnp{G}VGJKwjI6`ciOH>n>PX7lz|Sk9gwgCPoo!tk?}4xvor-0 zaaTHijv4H01ihubO$cU7lESYfQ1Sf4qX#@~op1NwUA(h#XJq(?ImoLo#1S@-Y4E2BxUr{6!jn{K62c{@^E&6> z@9{+{4YGJfhY#S!({cKvU;;z{)`N^ce(hN-fd;aue7hwn`frq1;e%npC<<8r`<^0@ z1%1ejO>vOjdi#eDA!hiF9j#YPaAny4`<}EXEjU#4I9}au3@4_9RSkcF7XKEXQIWedPjGl-^35M}Y;U?b9nzELf&7a<*27_~;mjGH3p7EXiRSXKhckZ(|5(RsI-K$~+(sDhVvXbHlX}HSUq{&B zxUBjX9=QnOh2X34T0BYXF@OeoPJ^dimv6EsR2O0M(xr|D6hmm1xftG|Wl`6(tPa7% zNBjj`UQm}LUJ%hIv-7VZFyTRmx+Mi?5UY|s&9g(Fk(4`*AaGqeu{4S{JInabxdD1N zE3mV;jOW`T&^IXkl04-@^CrFmmvW8} z@m3_)o!2fUjpX!7J6l(Ahh=SeD+tsdjRF$E#54O*bfPW!ow+fb&)l#7{ei048!Zup zNl<>SyOUpEpfV4*N6QhzDOLsI*sB?(o#z<1yP|E@Y`?8tW75K2t#|!(rWV8+)IrP3 zX&lu7KAHCT!!?ECs9vH4B%~aN^c zI#8?Pf8VWH`sEsB!c~))^9hnqluh#qu{}0mBkRnT#2G%X<%Gg-kg$A`DKOD^#h{uNxt)Yc^41u^zqSr$>;BZ*uo~5p#I@WFc|5 zv-sj7B3+}SirFDuZ}C}e|L5}RKLmQP6 zyQ>idJV(5;H^H1?iqeiLxD3S_j4xI`%a1upU%Scre+&K&ZEbA4rAF$Y&C9Z{{Ll5; zAQ(ZH0>Vf$NFa|HhP^EHbe)t#+9Z zEnT__oF&%xJ>7D)%yuM4xFXHt{KSC$FBbzg#)2vPRy?K=kt2%96bmo&OKbNT#h*a;5ih#q*qUJiUg^W%`O97IphEtwV@W@4<;)4mdL{Vya^%G=T2s*DX(_!=6vakuk6 zN{GnYv<1<37hAhTP`(L)_LPV9Nm(M)sv?=~+P#}7O3$whhq2R=jWEVO9SS9$%Xu^A zMRaOK13IJp_kq}KtmngLaqJfVtl88P$C!MrDCiLNG5+#PV>okQFm+G_5GRO(aY&Om zxa$r&o${0F=|H#WRJ6CRVg~H={H^VcX32k#MG>poDiR_A+2^Tdn^+dij{hb>eBFj=zppzsd@%ks-P0CYqSf)0gDlK5z^fYG@XBj_ z;0FCFu|AG`Ks8$*ZbrQ=ZMZ|e&1CX0X|%I2Bwb0H6BkZsPy65U;(YXZ9-9_%f%oG7 zW-hyX`h>or>EHV-Sc9paGo3-W^1H~su?j@)4=H7DL%MYSC_|nM%MAsiIpdamA$|St z5QX#64hb-v_As&zFr9P%?K;ObZKuU6j{0F7reLn=L!Od8T)AO_f){Nv1%gRrn9l?( zym7F5O-MA&yq|noxj$}I1aX`_|R-=e`ZiGk2rwcR&h8w2@r)0Q1tgM?x%A)>};5Aq# z4nHj@RxPzB-#-ZBI-JL077>(ozW<&VG9@AES6DelJBX$sK%y-F-imo8W0ArkjXy3D zjhT*;fAr~>-zL6<$0#nR(91XWgb)M-Zg9rn9bL_z@Ln*Qav?R5AyXss->mC#ccL!6 zvmn6J8@KxMWLdj3$|aKwc47muj)9WTZZRW#JvM}<$2Y|S%Hn09)UN^rx81_*%w2`U zVaDOb&(q&N$@E*m1^tQ0<1!UC9#4K5z9;pw#2aTQwK!4}BNWNeGT3ZuI;OgY?@J3> zlPnZs@Aag2b+mlqZu>R38#d+Kqw>u_#NQ*&1N}u2Pc84Swg)hDZ?K&+u z!Tbrw5OL|24sEoB!1?&iu;l+sQ zRv$-wk^fP9F3y9k%EEFECmf?+2 zJOjA!n#hLM{TS;cs*qoXA*O`)Oq=wD@_o%iYm$Oi+7IgkT(-~HXhoPC-oR_;mxKSA zyCZx*w&W?8mds(tk)r+R%SBR=rs&ww#X!3^Y?X-&Y;;Z}1SgOU*{|h3WH>)s|1If^ zQ+rS;bSpzn(8!_!-3`N6dOc}q?_3+GI5A4!@SU_Ifulg(7PQw&w%60+7Q=rGq=a3Z zS9Lpf<_2_ZWu&^TvcP%a>zoDA3ndjCsz(yV4P_;ZE5R*wtyD1GgAU0d7FIV~ zL%KX+HY^UmtnnA}Zk4~qt&bDjrKsG7 z1dgvz(DR+I3v{RyIzka^2?J9)@j_UX63DpflYUBK0=@&0n)6X~s6sTy2cF$G)~@d) z6H8ntVB|86U6ofTy%q7zTF@@CkBIERIUZ)gpZnF6SyJX$MAnTEN52=R);#XKWN{qz z2OX&uQrB}qwz%wd|E>h%eCNvtjis?NwxdP*xSZEhRZsb~sF#>l^SUw@N>*L2~?7-Yj#^k}tcAnZ5w=eDu3fvGiO5z0KuJ#8>`*ruz2 z8DP0~TcqaW;{CJ#U$k`_y7_MB7|r_wL1-j<$U=ff+L@Nek1Dd`9r=IrAV?8s_=k6* zvQ|RTHe{PKITMF`Mw5X_8CWS&4j&39{ipv8%fU&}Umb%t5Vs-yFeZyk(~`L0O&wkE zz`ZwdkR+L{!Zz%73`T~%&^UhWC!x2hCfv;#czg%u@V2@L&8C2+^H$NsKil`c6o~)1 z2!_Jhq74rhuHG7|q#&OUJ=Y!J=1M&n;wTZQ(f@w!<@O6U^!*Ieov)|{;tqpoB{P%JjG{v^M%GcipCdl95Q@91Wa`76s9=7>luUYc)@Tk!M`Vh-Y+BB)YO zMl-4sU05F9&pp%uarg@a8lQZH;UT=OfFeqzLd_W{>OUUOpcojONcqMO7nnQ$1rWkD zDD?N<$c>ZXUk>`azpjN(YyU}p@=Hb&p^G>eeCgqB9}@;>Can|1Y*O z((d)%e7~rcSzql25}Jy@Z6>LIFhPsU2mTSxjvZ=H(VFl-1@Hx!wXYDo(!s&y!i*UP zRlPLlNu7*BdW(S?7sxOr@;eO86TH@#05=#pPwU&Oy}jo*98Hnb6T{P{O$7K<7~ize zQcEIqK~>aBzP=AM|8MowZ=D^P6zWE}5Uqi_CrO^-LUd^%^c$)FzAO*{{LtyoPjkNB zz^)L5tKxM1w8_cHeA=SEd)EaspoB*CH`f6#P60ambZQ%n$AyoN;tTWZj?zf#lwoOF z9Zz%e91y7EBPR8mLXDXmB4OE281@&^+lXT2GLJ`!1LW;-Q-8)p7CSs#tfdG;DA#+~4+Y)7Xe)XbiN-y%@A&<*o{QeLF^U}EcrszL4+|F@uq0{s(*K;5k)PNrApOX;o1cd`fkJ|4G zL@>w@6Pf3CfirQi{L{fwCyE4>SkD5yd~$C8oDODY5#I8*lEVn8nWFwX>G5gTXHPV*F(fQM=fy$k9C&(aw|9Eli=Muz!e!loAV>{l{hz-sk!ghF|r<~lR}8=(FL zwS&JdQb4Xt2?W4wz?PkPd^10ff>I+warm~pBuE?HG@W*VfG{DRt1=ZF2O^wXCZNUE zE+A8Mb3ED)5}eFo(^X*tBIsFu(20n zGG~}>^9mrukH-T?;R3H3YKo0~p9*K$`D-5}L1I!%4vCtSsgu0qCvz7L2#GlX5j%5k z?Bhkf!RyW*QaHG!5}bety`tq*2!S53(+J>-pC8Z8y?FkW4vZolSD-PgxU(Ui_5dn< zo8ey;*sOYupZpV4YhHxTOgQcJUkR_VF@a?Q;IN^_b47oN zpzBTXkjaw~q>>Gx7JvRR<4R!SU^)5*bi;~u>uM?{Z-61GtS0ft_yVBzd5_}HJjFG6 zK6Nt0rI_cBb?ijN;r=`$AS#!3L}SuYx_y}Ylo34=%rTHtI`t1$VlOEvqu;E?cI|@f z$;m&PB@uBW+)=@Nss-Mm9=Hz&#vo=Vocz9$f0^YUOWUQJs6zzINgo(A2KZ(M%$hyz zv0!~It9RDH2*k3;+lI;1Bn9LeO^@4p2XGta+41857IX*h58;?C9&SRo@ZKJaYid|VO4C@7)nDM3{VTpPqD7$D|N z{U9>48kzPSil*9P&|EcarjeL0weBP>bRY4ok^Lw{&}b)o4*e(hw`_uzkJVx6b;v5O zv5t>P-w?<)2{giV$qljgrbsk4(o9#TW9DvkoHFjcgg%c)5%=-oBY)|~SUwa|&Pnxw z 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 BeDDAO diff --git a/StgSharpDebug/Shader/fbo.frag b/StgSharpDebug/Shader/fbo.frag deleted file mode 100644 index db80c8b4..00000000 --- a/StgSharpDebug/Shader/fbo.frag +++ /dev/null @@ -1,13 +0,0 @@ -#version 430 core - -in vec3 texCoord; - -out vec4 fragColor; - -uniform sampler2D tex; - -void main() -{ - fragColor = texture(tex, texCoord.xy); - //fragColor = vec4(0.099f,0.226f,0.335f,0.0f); -} \ No newline at end of file diff --git a/StgSharpDebug/Shader/fbo.vert b/StgSharpDebug/Shader/fbo.vert deleted file mode 100644 index 38c409ea..00000000 --- a/StgSharpDebug/Shader/fbo.vert +++ /dev/null @@ -1,13 +0,0 @@ -#version 330 core - -layout(location = 0)in vec3 coord; -layout(location = 1)in vec3 tCoord; - -out vec3 texCoord; - -void main() -{ - gl_Position = vec4(coord.xyz,1.0f); - texCoord = tCoord; -} - diff --git a/StgSharpDebug/Shader/main.frag b/StgSharpDebug/Shader/main.frag deleted file mode 100644 index dc073217..00000000 --- a/StgSharpDebug/Shader/main.frag +++ /dev/null @@ -1,17 +0,0 @@ -#version 330 core - -in vec2 TexCoord; - -out vec4 FragColor; - -uniform vec4 color; -uniform sampler2D ourTexture; -uniform sampler2D ourTexture2; - -void main() -{ - vec4 tex1 = texture(ourTexture, TexCoord); - vec4 tex2 = texture(ourTexture2,TexCoord); - FragColor = mix(tex1 * vec4( color.xyz, 1.0), tex2, 0.2) /* *vec4( TexColor,1.0) /**/; -} - diff --git a/StgSharpDebug/Shader/main.vert b/StgSharpDebug/Shader/main.vert deleted file mode 100644 index c93f1202..00000000 --- a/StgSharpDebug/Shader/main.vert +++ /dev/null @@ -1,22 +0,0 @@ -#version 330 core - -layout(location = 0) in vec3 aPos; -layout(location = 1) in vec3 aColor; -layout(location = 2) in vec2 aTextCoord; - -out vec2 TexCoord; - -uniform mat4x4 camera; - -void main() -{ - - TexCoord = aTextCoord; - vec4 temp = vec4(aPos.xyz,1.0); - gl_Position = /**/ camera * /**/ temp; -} - -//struct - - - diff --git a/StgSharpDebug/Shader/particle.frag b/StgSharpDebug/Shader/particle.frag deleted file mode 100644 index 429276de..00000000 --- a/StgSharpDebug/Shader/particle.frag +++ /dev/null @@ -1,12 +0,0 @@ -#version 460 core - -uniform float time; - -out vec3 fragColor; - -void main() -{ - - fragColor = vec3( 0.5f,0.336f,mod( (0.9961f + time),1.0f) ); - -} \ No newline at end of file diff --git a/StgSharpDebug/Shader/particle.vert b/StgSharpDebug/Shader/particle.vert deleted file mode 100644 index 6c00dbc2..00000000 --- a/StgSharpDebug/Shader/particle.vert +++ /dev/null @@ -1,36 +0,0 @@ -#version 460 core - - -layout(location = 0) in vec3 singleCoord; -layout(location = 1) in vec3 locations; -layout(location = 2) in float rotation; -layout(location = 3) in float scale; - -uniform mat4x4 Camera; - -void main() -{ - /**/ - mat4x4 scalingMat = mat4x4 - ( - scale,0,0,0, - 0,scale,0,0, - 0,0,scale,0, - 0,0,0,1 - ); - /**/ - /**/ - - mat4x4 rotationMat = mat4x4 - ( - cos(rotation),-sin(rotation),0,0, - sin(rotation),cos(rotation),0,0, - 0,0,1,0, - 0,0,0,1 - ); - - /**/ - - gl_Position = Camera * ( rotationMat * scalingMat * vec4( singleCoord.xyz , 1) + vec4( locations.xyz , 0)); - -} diff --git a/StgSharpDebug/StgSharpDebug.csproj b/StgSharpDebug/StgSharpDebug.csproj index d6f145c9..7ad41b90 100644 --- a/StgSharpDebug/StgSharpDebug.csproj +++ b/StgSharpDebug/StgSharpDebug.csproj @@ -17,32 +17,5 @@ - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - Always - - - diff --git a/StgSharpDebug/TestSwiss.cs b/StgSharpDebug/TestSwiss.cs index a69c095a..2d0df795 100644 --- a/StgSharpDebug/TestSwiss.cs +++ b/StgSharpDebug/TestSwiss.cs @@ -2,8 +2,8 @@ // ----------------------------------------------------------------------- // file="TestSwiss" // Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. +// AuthorGroup: Nitload +// Copyright (c) Nitload. All rights reserved. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -41,21 +41,23 @@ namespace StgSharp public static void TestSwiss() { SwissTable swiss = SwissTable.Create(); - for (int i = 0; i < 10000; i++) + for (int i = 0; i < 5000; i++) { + Console.Write($"Set {i}: "); _ = swiss.TryAddOrSet(i, i * 2, out _); Console.WriteLine($"Set a kvp of ({i},{i * 2})"); } Random rand = new Random(); - for (int i = 0; i < 10000; i++) + for (int i = 0; i < 100; i++) { - int key = rand.Next(0, 10000); + Console.Write($"Get {i}: "); + int key = rand.Next(4000, 5000); if (swiss.TryGet(key, out nint value)) { - Console.WriteLine($"Get a kvp of ({key},{value})"); + Console.WriteLine($"Success in get a kvp of ({key},{value})"); } else { - Console.WriteLine($"Failed to get a kvp of ({key},?)"); + Console.WriteLine($"Failed to get a kvp of ({key},?)"); } } } diff --git a/StgSharpDebug/View/Control.cs b/StgSharpDebug/View/Control.cs deleted file mode 100644 index fdc0fd02..00000000 --- a/StgSharpDebug/View/Control.cs +++ /dev/null @@ -1,61 +0,0 @@ -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -// file="Control.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the “Software”), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -using StgSharp.Controlling.UsrActivity; -using StgSharp.MVVM; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp -{ - public partial class ViewMain - { - - protected class Control : ViewResponder - { - - public Control( ViewMain view ) : base( view ) { } - - public override void CustomizedInitialize( - Func keyRegister ) { } - - public override bool ValidateInitializing() - { - return true; - } - - } - - } -} diff --git a/StgSharpDebug/View/Design.cs b/StgSharpDebug/View/Design.cs deleted file mode 100644 index 2d7adb6f..00000000 --- a/StgSharpDebug/View/Design.cs +++ /dev/null @@ -1,91 +0,0 @@ -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -// file="Design.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the “Software”), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -using StgSharp.Controlling; -using StgSharp.Controlling.UsrActivity; -using StgSharp.Controls; - -using StgSharp.Geometries; -using StgSharp.Graphics; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.CompilerServices; -using System.Text; -using System.Text.RegularExpressions; -using System.Threading.Tasks; - -namespace StgSharp -{ - public partial class ViewMain - { - - internal DemoButtonGroup Group { get; set; } - - internal TriggerButton OnlyButton { get; set; } - - internal class Design : ViewDesigner - { - - public Design( ViewMain view ) : base( view ) { } - - public override sealed void CustomizedInitialize() - { - Binding.Group = CreateKeyboardButtonGroup( - new KeyTrigger( KeyboardKey.Left, KeyStatus.PRESS ), - new KeyTrigger( KeyboardKey.Right, KeyStatus.PRESS ), - new KeyTrigger( KeyboardKey.Up, KeyStatus.PRESS ), - new KeyTrigger( KeyboardKey.Down, KeyStatus.PRESS ), - new KeyTrigger( KeyboardKey.Enter, KeyStatus.PRESS ) ); - Binding.OnlyButton = CreateKeyboardButton( - Binding.Stream.ButtonBounding, Binding.Stream.ButtonTextureProvider, true ); - Binding.OnlyButton.RenderButtonTexture += Binding.Stream.RenderButton; - } - - public override bool ValidateInitializing() - { - return true; - } - - } - - } - - public class DemoButtonGroup : KeyboardButtonGroup - { - - public override sealed void Confirm() - { - return; - } - - } -} diff --git a/StgSharpDebug/View/ViewMain.cs b/StgSharpDebug/View/ViewMain.cs deleted file mode 100644 index f22931a1..00000000 --- a/StgSharpDebug/View/ViewMain.cs +++ /dev/null @@ -1,98 +0,0 @@ -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -// file="ViewMain.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the “Software”), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -using StgSharp.Graphics; -using StgSharp.MVVM; -using StgSharp.MVVM.ViewModel; - -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Diagnostics.CodeAnalysis; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp -{ - public partial class ViewMain : ViewBase - { - - private Dictionary _databindingIndexMap; - - public ViewMain() - { - _databindingIndexMap = new Dictionary(); - } - - public override void CustomizedInitialize( [NotNull]ViewModelBase viewModelBinding ) - { - Designer = new Design( this ); - Responder = new Control( this ); - Render = new NewRender( this ); - - Render.Initialize(); - Designer.Initialize(); - Responder.Initialize( viewModelBinding.MethodLookup ); - } - - public override bool TryGetObjectReference( string name, out DataBindingEntry entry ) - { - if( _databindingIndexMap.TryGetValue( name, out entry ) ) { - return true; - } - try - { - entry = name switch - { - _ => default( DataBindingEntry ), - }; - return !entry.ExactEqual( default( DataBindingEntry ) ); - } - catch( Exception ) - { - entry = default( DataBindingEntry ); - return false; - } - } - - protected override void Show() - { - Stream.RenderStart(); - - //Stream.NothingMain(); - - Stream.Main(); - Stream.ButtonMain( OnlyButton ); - Stream.RenderEnd(); - } - - } -} diff --git a/StgSharpDebug/ViewModelMain.cs b/StgSharpDebug/ViewModelMain.cs deleted file mode 100644 index d15fa201..00000000 --- a/StgSharpDebug/ViewModelMain.cs +++ /dev/null @@ -1,75 +0,0 @@ -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -// file="ViewModelMain.cs" -// Project: StgSharp -// AuthorGroup: Nitload Space -// Copyright (c) Nitload Space. All rights reserved. -// -// Permission is hereby granted, free of charge, to any person -// obtaining a copy of this software and associated documentation -// files (the “Software”), to deal in the Software without restriction, -// including without limitation the rights to use, copy, modify, merge, -// publish, distribute, sublicense, and/or sell copies of the Software, -// and to permit persons to whom the Software is furnished to do so, -// subject to the following conditions: -// -// The above copyright notice and -// this permission notice shall be included in all copies -// or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED “AS IS”, -// WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, -// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -// IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, -// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, -// ARISING FROM, OUT OF OR IN CONNECTION WITH -// THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -// -//----------------------------------------------------------------------- -//----------------------------------------------------------------------- -using StgSharp.Graphics; - -using StgSharp.MVVM; -using StgSharp.MVVM.ViewModel; - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace StgSharp -{ - public class ViewModelMain : ViewModelBase - { - - private Dictionary dataBindingEntryIndexMap; - - public ViewModelMain( ViewPort vp ) - : base( vp, 60 ) - { - dataBindingEntryIndexMap = new Dictionary(); - } - - public override void CustomizeInitialize() { } - - public override bool TryGetObjectReference( string name, out DataBindingEntry entry ) - { - if( dataBindingEntryIndexMap.TryGetValue( name, out entry ) ) { - return true; - } - entry = name switch - { - _ => DataBindingEntry.NullBinding, - }; - - if( entry.ExactEqual( DataBindingEntry.NullBinding ) ) { - return false; - } - dataBindingEntryIndexMap.Add( name, entry ); - return true; - } - - }//------------------------------------- End of Class ------------------------------------------ -} diff --git a/StgSharpDevelop.slnLaunch.user b/StgSharpDevelop.slnLaunch.user new file mode 100644 index 00000000..089714f2 --- /dev/null +++ b/StgSharpDevelop.slnLaunch.user @@ -0,0 +1,6 @@ +[ + { + "Name": "新建配置文件", + "Projects": [] + } +] \ No newline at end of file