diff --git a/Src/ILGPU.Algorithms/Random/RandomExtensions.cs b/Src/ILGPU.Algorithms/Random/RandomExtensions.cs
index 579ed86fb..7d6ade8d9 100644
--- a/Src/ILGPU.Algorithms/Random/RandomExtensions.cs
+++ b/Src/ILGPU.Algorithms/Random/RandomExtensions.cs
@@ -10,8 +10,10 @@
// ---------------------------------------------------------------------------------------
using ILGPU.Runtime;
+using ILGPU.Util;
using System;
using System.Diagnostics;
+using System.Numerics;
using System.Runtime.CompilerServices;
namespace ILGPU.Algorithms.Random
@@ -49,7 +51,7 @@ internal static uint MergeULong(ulong nextULong) =>
///
/// Separates the given unsigned int into an unsigned long.
///
- internal static ulong SeperateUInt(uint nextUInt) =>
+ internal static ulong SeparateUInt(uint nextUInt) =>
((ulong)nextUInt << 32) | nextUInt;
///
@@ -91,8 +93,8 @@ internal static ulong ShiftState(ulong state, int laneShift)
/// Generates a random int in [minValue..maxValue).
///
/// The random provider.
- /// The minimum value (inclusive)
- /// The maximum values (exclusive)
+ /// The minimum value (inclusive).
+ /// The maximum values (exclusive).
/// A random int in [minValue..maxValue).
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Next(
@@ -112,8 +114,8 @@ public static float Next(
/// Generates a random int in [minValue..maxValue).
///
/// The random provider.
- /// The minimum value (inclusive)
- /// The maximum values (exclusive)
+ /// The minimum value (inclusive).
+ /// The maximum values (exclusive).
/// A random int in [minValue..maxValue).
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Next(
@@ -133,8 +135,8 @@ public static double Next(
/// Generates a random int in [minValue..maxValue).
///
/// The random provider.
- /// The minimum value (inclusive)
- /// The maximum values (exclusive)
+ /// The minimum value (inclusive).
+ /// The maximum values (exclusive).
/// A random int in [minValue..maxValue).
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Next(
@@ -154,8 +156,8 @@ public static int Next(
/// Generates a random long in [minValue..maxValue).
///
/// The random provider.
- /// The minimum value (inclusive)
- /// The maximum values (exclusive)
+ /// The minimum value (inclusive).
+ /// The maximum values (exclusive).
/// A random long in [minValue..maxValue).
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long Next(
@@ -174,6 +176,74 @@ public static long Next(
return Math.Min(intermediate + minValue, maxValue - 1);
}
+#if NET7_0_OR_GREATER
+ ///
+ /// Generates a new random vector containing provided RNG-based values.
+ ///
+ /// The vector element type.
+ /// The RNG provider type.
+ /// The generic RNG value range.
+ /// The random provider instance to use.
+ /// The generic range instance to use.
+ /// The created random vector.
+ [CLSCompliant(false)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe Vector NextVector(
+ ref TRandomProvider randomProvider,
+ TRange range)
+ where T : unmanaged
+ where TRandomProvider : struct, IRandomProvider
+ where TRange : struct, IRandomRange
+ {
+ int vectorLength = Vector.Count;
+ int length = Interop.SizeOf() * vectorLength;
+
+ // Allocate temporary buffers
+ var source = stackalloc byte[length + vectorLength];
+ var span = new Span(
+ (void*)Interop.Align((long)source, length, vectorLength),
+ vectorLength);
+
+ // Generated random numbers
+ for (int i = 0; i < vectorLength; ++i)
+ span[i] = range.Next(ref randomProvider);
+
+ // Load aligned vector
+ return span.LoadAlignedVectorUnsafe();
+ }
+
+ ///
+ /// Generates a new random vector containing provided RNG-based values.
+ ///
+ /// The vector element type.
+ /// The RNG range provider.
+ /// The range provider instance to use.
+ /// The created random vector.
+ [CLSCompliant(false)]
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public static unsafe Vector NextVector(
+ ref TRangeProvider rangeProvider)
+ where T : unmanaged
+ where TRangeProvider : struct, IRandomRangeProvider
+ {
+ int vectorLength = Vector.Count;
+ int length = Interop.SizeOf() * vectorLength;
+
+ // Allocate temporary buffers
+ var source = stackalloc byte[length + vectorLength];
+ var span = new Span(
+ (void*)Interop.Align((long)source, length, vectorLength),
+ vectorLength);
+
+ // Generated random numbers
+ for (int i = 0; i < vectorLength; ++i)
+ span[i] = rangeProvider.Next();
+
+ // Load aligned vector
+ return span.LoadAlignedVectorUnsafe();
+ }
+#endif
+
///
/// Constructs an RNG using the given provider instance.
///
@@ -220,7 +290,7 @@ internal static void InitializeRNGKernel(
{
randomProvider[i] = default(TRandomProvider).CreateProvider(ref provider);
}
-
+
// Update provider state for future iterations
sourceProviders[index] = provider;
}
diff --git a/Src/ILGPU.Algorithms/Random/XorShift128.cs b/Src/ILGPU.Algorithms/Random/XorShift128.cs
index 71e1a7c03..b867b556c 100644
--- a/Src/ILGPU.Algorithms/Random/XorShift128.cs
+++ b/Src/ILGPU.Algorithms/Random/XorShift128.cs
@@ -113,7 +113,7 @@ public uint NextUInt()
/// Generates a random ulong in [0..ulong.MaxValue].
///
/// A random ulong in [0..ulong.MaxValue].
- public ulong NextULong() => SeperateUInt(NextUInt());
+ public ulong NextULong() => SeparateUInt(NextUInt());
///
public int Next() => ToInt(NextUInt());
diff --git a/Src/ILGPU.Algorithms/Random/XorShift32.cs b/Src/ILGPU.Algorithms/Random/XorShift32.cs
index 72730de71..addb035aa 100644
--- a/Src/ILGPU.Algorithms/Random/XorShift32.cs
+++ b/Src/ILGPU.Algorithms/Random/XorShift32.cs
@@ -84,7 +84,7 @@ public uint NextUInt()
/// Generates a random ulong in [0..ulong.MaxValue].
///
/// A random ulong in [0..ulong.MaxValue].
- public ulong NextULong() => SeperateUInt(NextUInt());
+ public ulong NextULong() => SeparateUInt(NextUInt());
///
public int Next() => ToInt(NextUInt());