diff --git a/StgSharp.Mathematics/Numeric/MatrixCompute.Basic.cs b/StgSharp.Mathematics/Numeric/MatrixCompute.Basic.cs index ffa2731e..c70b7711 100644 --- a/StgSharp.Mathematics/Numeric/MatrixCompute.Basic.cs +++ b/StgSharp.Mathematics/Numeric/MatrixCompute.Basic.cs @@ -110,9 +110,93 @@ namespace StgSharp.Mathematics.Numeric package->Scalar = scalar; MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package); MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep); - + MatrixParallelFactory.Release(scalar); taskGroup.Dispose(); } + public static unsafe Matrix Mul(this Matrix left, float right) + { + long count = (long)left.KernelColumnLength * left.KernelRowLength; + Matrix ans = Matrix.FromDefault(left.ColumnLength, left.RowLength); + ScalarPacket* scalar = MatrixParallelFactory.CreateScalarPacket(); + scalar->Data(0) = right; + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NativeIntrinsic.Intrinsic.f32_scalar_mul(leftPtr, ansPtr, scalar, count); + + return ans; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NativeIntrinsic.Intrinsic.f32_scalar_mul(leftPtr, ansPtr, scalar, count); + + MatrixParallel.ReturnParallelResources(ref pool); + return ans; + } + MatrixParallelTaskPackage* package = MatrixParallelFactory.CreateBaseTask(); + package->Right = (nint)left.Buffer; + package->Result = (nint)ans.Buffer; + package->ElementSize = sizeof(float); + package->PrimCount = left.KernelColumnLength; + package->SecCount = left.KernelRowLength; + package->Scalar = scalar; + package->ComputeMode = new MatrixOpMode(MatrixOperationStyle.BUFFER_OP, MatrixOperationParam.RIGHT_ANS_SCALAR_PARAM); + package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_scalar_mul; + MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package); + + MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep); + taskGroup.Dispose(); + MatrixParallelFactory.Release(scalar); + return ans; + } + + public static unsafe Matrix Sub(this Matrix left, Matrix right) + { + if (left.ColumnLength != right.ColumnLength || left.RowLength != right.RowLength) { + throw new IndexOutOfRangeException("Matrix dimensions must agree."); + } + long count = (long)left.KernelColumnLength * left.KernelRowLength; + Matrix ans = Matrix.FromDefault(left.ColumnLength, left.RowLength); + if (count <= 256) + { + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NativeIntrinsic.Intrinsic.f32_sub(leftPtr, rightPtr, ansPtr, count); + + return ans; + } else if (count <= 1024) + { + MatrixParallelThread[] pool = MatrixParallel.LeadParallel(1); + + MatrixKernel* leftPtr = left.Buffer; + MatrixKernel* rightPtr = right.Buffer; + MatrixKernel* ansPtr = ans.Buffer; + NativeIntrinsic.Intrinsic.f32_sub(leftPtr, rightPtr, ansPtr, count); + + MatrixParallel.ReturnParallelResources(ref pool); + return ans; + } + MatrixParallelTaskPackage* package = MatrixParallelFactory.CreateBaseTask(); + package->Left = (nint)left.Buffer; + package->Right = (nint)right.Buffer; + package->Result = (nint)ans.Buffer; + package->ElementSize = sizeof(float); + package->PrimCount = left.KernelColumnLength; + package->SecCount = left.KernelRowLength; + package->ComputeMode = new MatrixOpMode(MatrixOperationStyle.BUFFER_OP, MatrixOperationParam.LEFT_RIGHT_ANS_PARAM); + package->ComputeHandle = (IntPtr)NativeIntrinsic.Intrinsic.f32_sub; + MatrixParallelHandle taskGroup = MatrixParallel.ScheduleTask(package); + + MatrixParallel.LaunchParallel(taskGroup, SleepMode.DeepSleep); + taskGroup.Dispose(); + return ans; + } + } } diff --git a/StgSharp.Native/sn-src/k_bufop.c b/StgSharp.Native/sn-src/k_bufop.c index 62a881b4..ce3d29ad 100644 --- a/StgSharp.Native/sn-src/k_bufop.c +++ b/StgSharp.Native/sn-src/k_bufop.c @@ -97,12 +97,12 @@ DECLARE_BUF_PROC_LEFT_RIGHT_ANS(float, 512, sub) DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, sse, scalar_mul) { - register __m128 scalar_vec = ((__m128 *)(scalar->data))[0]; + register __m128 vec = _mm_set_ps1(((float *)(scalar->data))[0]); for (size_t i = 0; i < count; i++) { - register __m128 c0 = _mm_mul_ps(right[i].xmm[0], scalar_vec); - register __m128 c1 = _mm_mul_ps(right[i].xmm[1], scalar_vec); - register __m128 c2 = _mm_mul_ps(right[i].xmm[2], scalar_vec); - register __m128 c3 = _mm_mul_ps(right[i].xmm[3], scalar_vec); + register __m128 c0 = _mm_mul_ps(right[i].xmm[0], vec); + register __m128 c1 = _mm_mul_ps(right[i].xmm[1], vec); + register __m128 c2 = _mm_mul_ps(right[i].xmm[2], vec); + register __m128 c3 = _mm_mul_ps(right[i].xmm[3], vec); ans[i].xmm[0] = c0; ans[i].xmm[1] = c1; @@ -113,10 +113,10 @@ DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, sse, scalar_mul) DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, avx, scalar_mul) { - register __m256 scalar_vec = ((__m256 *)(scalar->data))[0]; + register __m256 vec = _mm256_broadcast_ss(((float *)(scalar->data))); for (size_t i = 0; i < count; i++) { - register __m256 c0 = _mm256_mul_ps(right[i].ymm[0], scalar_vec); - register __m256 c1 = _mm256_mul_ps(right[i].ymm[1], scalar_vec); + register __m256 c0 = _mm256_mul_ps(right[i].ymm[0], vec); + register __m256 c1 = _mm256_mul_ps(right[i].ymm[1], vec); ans[i].ymm[0] = c0; ans[i].ymm[1] = c1; @@ -125,9 +125,9 @@ DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, avx, scalar_mul) DECLARE_BUF_PROC_RIGHT_ANS_SCALAR(float, 512, scalar_mul) { - register __m512 scalar_vec = ((__m512 *)(scalar->data))[0]; + register __m512 vec = _mm512_broadcastss_ps(((__m128 *)(scalar->data))[0]); for (size_t i = 0; i < count; i++) { - register __m512 c0 = _mm512_mul_ps(right[i].zmm[0], scalar_vec); + register __m512 c0 = _mm512_mul_ps(right[i].zmm[0], vec); ans[i].zmm[0] = c0; } diff --git a/StgSharpDebug/Program.cs b/StgSharpDebug/Program.cs index 0da9b457..38534e38 100644 --- a/StgSharpDebug/Program.cs +++ b/StgSharpDebug/Program.cs @@ -85,6 +85,7 @@ namespace StgSharp } GC.Collect(); } + n = n.Mul(12); for (int i = 0; i < 20; i++) { for (int j = 0; j < 20; j++) {