Loading files
using System;
using System.Diagnostics.CodeAnalysis;
namespace Hast.Common.Numerics;
/// <summary>
/// Special Hastlayer-supported SIMD (Single Instruction Multiple Data) operations that can be utilized to execute an
/// operation on multiple elements at once.
/// </summary>
/// <remarks>
/// <para>
/// These operations are transformed into SIMD-like operations but currently they are plainly sequential in .NET.
/// </para>
/// </remarks>
[SuppressMessage(
"Usage",
"CA1801:Review unused parameters",
Justification = "TODO: parallelize these to SIMD in .NET too. (https://github.com/Lombiq/Hastlayer-SDK/issues/64)")]
public static class SimdOperations
{
public static int[] AddVectors(int[] vector1, int[] vector2, int maxDegreeOfParallelism) =>
RunInt32VectorOperation(vector1, vector2, (element1, element2) => element1 + element2);
public static uint[] AddVectors(uint[] vector1, uint[] vector2, int maxDegreeOfParallelism) =>
RunUInt32VectorOperation(vector1, vector2, (element1, element2) => element1 + element2);
public static long[] AddVectors(long[] vector1, long[] vector2, int maxDegreeOfParallelism) =>
RunInt64VectorOperation(vector1, vector2, (element1, element2) => element1 + element2);
public static ulong[] AddVectors(ulong[] vector1, ulong[] vector2, int maxDegreeOfParallelism) =>
RunUInt64VectorOperation(vector1, vector2, (element1, element2) => element1 + element2);
public static int[] SubtractVectors(int[] vector1, int[] vector2, int maxDegreeOfParallelism) =>
RunInt32VectorOperation(vector1, vector2, (element1, element2) => element1 - element2);
public static uint[] SubtractVectors(uint[] vector1, uint[] vector2, int maxDegreeOfParallelism) =>
RunUInt32VectorOperation(vector1, vector2, (element1, element2) => element1 - element2);
public static long[] SubtractVectors(long[] vector1, long[] vector2, int maxDegreeOfParallelism) =>
RunInt64VectorOperation(vector1, vector2, (element1, element2) => element1 - element2);
public static ulong[] SubtractVectors(ulong[] vector1, ulong[] vector2, int maxDegreeOfParallelism) =>
RunUInt64VectorOperation(vector1, vector2, (element1, element2) => element1 - element2);
public static int[] MultiplyVectors(int[] vector1, int[] vector2, int maxDegreeOfParallelism) =>
RunInt32VectorOperation(vector1, vector2, (element1, element2) => element1 * element2);
public static uint[] MultiplyVectors(uint[] vector1, uint[] vector2, int maxDegreeOfParallelism) =>
RunUInt32VectorOperation(vector1, vector2, (element1, element2) => element1 * element2);
public static long[] MultiplyVectors(long[] vector1, long[] vector2, int maxDegreeOfParallelism) =>
RunInt64VectorOperation(vector1, vector2, (element1, element2) => element1 * element2);
public static ulong[] MultiplyVectors(ulong[] vector1, ulong[] vector2, int maxDegreeOfParallelism) =>
RunUInt64VectorOperation(vector1, vector2, (element1, element2) => element1 * element2);
public static int[] DivideVectors(int[] vector1, int[] vector2, int maxDegreeOfParallelism) =>
RunInt32VectorOperation(vector1, vector2, (element1, element2) => element1 / element2);
public static uint[] DivideVectors(uint[] vector1, uint[] vector2, int maxDegreeOfParallelism) =>
RunUInt32VectorOperation(vector1, vector2, (element1, element2) => element1 / element2);
public static long[] DivideVectors(long[] vector1, long[] vector2, int maxDegreeOfParallelism) =>
RunInt64VectorOperation(vector1, vector2, (element1, element2) => element1 / element2);
public static ulong[] DivideVectors(ulong[] vector1, ulong[] vector2, int maxDegreeOfParallelism) =>
RunUInt64VectorOperation(vector1, vector2, (element1, element2) => element1 / element2);
public static void ThrowIfVectorsNotEquallyLong<T>(T[] vector1, T[] vector2)
{
if (vector1.Length != vector2.Length)
{
throw new InvalidOperationException("The two vectors must have the same number of elements.");
}
}
private static int[] RunInt32VectorOperation(int[] vector1, int[] vector2, Func<int, int, int> operation)
{
ThrowIfVectorsNotEquallyLong(vector1, vector2);
var result = new int[vector1.Length];
for (int i = 0; i < vector1.Length; i++)
{
result[i] = operation(vector1[i], vector2[i]);
}
return result;
}
private static uint[] RunUInt32VectorOperation(uint[] vector1, uint[] vector2, Func<uint, uint, uint> operation)
{
ThrowIfVectorsNotEquallyLong(vector1, vector2);
var result = new uint[vector1.Length];
for (int i = 0; i < vector1.Length; i++)
{
result[i] = operation(vector1[i], vector2[i]);
}
return result;
}
private static long[] RunInt64VectorOperation(long[] vector1, long[] vector2, Func<long, long, long> operation)
{
ThrowIfVectorsNotEquallyLong(vector1, vector2);
var result = new long[vector1.Length];
for (int i = 0; i < vector1.Length; i++)
{
result[i] = operation(vector1[i], vector2[i]);
}
return result;
}
private static ulong[] RunUInt64VectorOperation(ulong[] vector1, ulong[] vector2, Func<ulong, ulong, ulong> operation)
{
ThrowIfVectorsNotEquallyLong(vector1, vector2);
var result = new ulong[vector1.Length];
for (int i = 0; i < vector1.Length; i++)
{
result[i] = operation(vector1[i], vector2[i]);
}
return result;
}
}
7f9864208This file is pinned to the selected release. Download the original to open it in your design tool.