Skip to content

Commit

Permalink
Random ranges. (m4rs-mt#1038)
Browse files Browse the repository at this point in the history
* Added new random ranges to create random numbers in certain intervals.
* Added vector-specific random extensions.
  • Loading branch information
m4rs-mt authored and MoFtZ committed Apr 24, 2024
1 parent e65fbe2 commit 25968c7
Show file tree
Hide file tree
Showing 6 changed files with 482 additions and 11 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ Src/ILGPU.Algorithms/IL/ILContext.Generated.cs
Src/ILGPU.Algorithms/PTX/PTXContext.Generated.cs
Src/ILGPU.Algorithms/RadixSortOperations.cs
Src/ILGPU.Algorithms/Vectors/VectorTypes.cs
Src/ILGPU.Algorithms/Random/RandomRanges.cs
Src/ILGPU.Algorithms/Runtime/Cuda/API/CuBlasNativeMethods.cs
Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTAPI.Generated.cs
Src/ILGPU.Algorithms/Runtime/Cuda/API/CuFFTNativeMethods.cs
Expand Down
9 changes: 9 additions & 0 deletions Src/ILGPU.Algorithms/ILGPU.Algorithms.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>RadixSortOperations.cs</LastGenOutput>
</None>
<None Update="Random\RandomRanges.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>RandomRanges.cs</LastGenOutput>
</None>
<None Update="Runtime\Cuda\API\CuFFTAPI.Generated.tt">
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>CuFFTAPI.Generated.cs</LastGenOutput>
Expand Down Expand Up @@ -252,6 +256,11 @@
<AutoGen>True</AutoGen>
<DependentUpon>RadixSortOperations.tt</DependentUpon>
</Compile>
<Compile Update="Random\RandomRanges.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>RandomRanges.tt</DependentUpon>
</Compile>
<Compile Update="Resources\ErrorMessages.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
Expand Down
86 changes: 77 additions & 9 deletions Src/ILGPU.Algorithms/Random/RandomExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -49,7 +51,7 @@ internal static uint MergeULong(ulong nextULong) =>
/// <summary>
/// Separates the given unsigned int into an unsigned long.
/// </summary>
internal static ulong SeperateUInt(uint nextUInt) =>
internal static ulong SeparateUInt(uint nextUInt) =>
((ulong)nextUInt << 32) | nextUInt;

/// <summary>
Expand Down Expand Up @@ -91,8 +93,8 @@ internal static ulong ShiftState(ulong state, int laneShift)
/// Generates a random int in [minValue..maxValue).
/// </summary>
/// <param name="randomProvider">The random provider.</param>
/// <param name="minValue">The minimum value (inclusive)</param>
/// <param name="maxValue">The maximum values (exclusive)</param>
/// <param name="minValue">The minimum value (inclusive).</param>
/// <param name="maxValue">The maximum values (exclusive).</param>
/// <returns>A random int in [minValue..maxValue).</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static float Next<TRandomProvider>(
Expand All @@ -112,8 +114,8 @@ public static float Next<TRandomProvider>(
/// Generates a random int in [minValue..maxValue).
/// </summary>
/// <param name="randomProvider">The random provider.</param>
/// <param name="minValue">The minimum value (inclusive)</param>
/// <param name="maxValue">The maximum values (exclusive)</param>
/// <param name="minValue">The minimum value (inclusive).</param>
/// <param name="maxValue">The maximum values (exclusive).</param>
/// <returns>A random int in [minValue..maxValue).</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Next<TRandomProvider>(
Expand All @@ -133,8 +135,8 @@ public static double Next<TRandomProvider>(
/// Generates a random int in [minValue..maxValue).
/// </summary>
/// <param name="randomProvider">The random provider.</param>
/// <param name="minValue">The minimum value (inclusive)</param>
/// <param name="maxValue">The maximum values (exclusive)</param>
/// <param name="minValue">The minimum value (inclusive).</param>
/// <param name="maxValue">The maximum values (exclusive).</param>
/// <returns>A random int in [minValue..maxValue).</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static int Next<TRandomProvider>(
Expand All @@ -154,8 +156,8 @@ public static int Next<TRandomProvider>(
/// Generates a random long in [minValue..maxValue).
/// </summary>
/// <param name="randomProvider">The random provider.</param>
/// <param name="minValue">The minimum value (inclusive)</param>
/// <param name="maxValue">The maximum values (exclusive)</param>
/// <param name="minValue">The minimum value (inclusive).</param>
/// <param name="maxValue">The maximum values (exclusive).</param>
/// <returns>A random long in [minValue..maxValue).</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static long Next<TRandomProvider>(
Expand All @@ -174,6 +176,72 @@ public static long Next<TRandomProvider>(
return Math.Min(intermediate + minValue, maxValue - 1);
}

#if NET7_0_OR_GREATER
/// <summary>
/// Generates a new random vector containing provided RNG-based values.
/// </summary>
/// <typeparam name="T">The vector element type.</typeparam>
/// <typeparam name="TRandomProvider">The RNG provider type.</typeparam>
/// <typeparam name="TRange">The generic RNG value range.</typeparam>
/// <param name="randomProvider">The random provider instance to use.</param>
/// <param name="range">The generic range instance to use.</param>
/// <returns>The created random vector.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Vector<T> NextVector<T, TRandomProvider, TRange>(
ref TRandomProvider randomProvider,
TRange range)
where T : unmanaged
where TRandomProvider : struct, IRandomProvider
where TRange : struct, IRandomRange<T>
{
int vectorLength = Vector<T>.Count;
int length = Interop.SizeOf<T>() * vectorLength;

// Allocate temporary buffers
var source = stackalloc byte[length + vectorLength];
var span = new Span<T>(
(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();
}

/// <summary>
/// Generates a new random vector containing provided RNG-based values.
/// </summary>
/// <typeparam name="T">The vector element type.</typeparam>
/// <typeparam name="TRangeProvider">The RNG range provider.</typeparam>
/// <param name="rangeProvider">The range provider instance to use.</param>
/// <returns>The created random vector.</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe Vector<T> NextVector<T, TRangeProvider>(
ref TRangeProvider rangeProvider)
where T : unmanaged
where TRangeProvider : struct, IRandomRangeProvider<TRangeProvider, T>
{
int vectorLength = Vector<T>.Count;
int length = Interop.SizeOf<T>() * vectorLength;

// Allocate temporary buffers
var source = stackalloc byte[length + vectorLength];
var span = new Span<T>(
(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

/// <summary>
/// Constructs an RNG using the given provider instance.
/// </summary>
Expand Down
Loading

0 comments on commit 25968c7

Please sign in to comment.