Skip to content

Commit

Permalink
Simplified API for copying to/from page locked memory.
Browse files Browse the repository at this point in the history
  • Loading branch information
MoFtZ committed Aug 31, 2023
1 parent f09ef67 commit 955aaee
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 413 deletions.
8 changes: 4 additions & 4 deletions Samples/PinnedMemoryCopy/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ static void PerformPinnedCopyUsingGCHandle(Accelerator accelerator, int dataSize

// Page locked buffers enable async memory transfers
using var scope = accelerator.CreatePageLockFromPinned(array);
bufferOnGPU.View.CopyFromPageLockedAsync(stream, scope);
bufferOnGPU.View.CopyFrom(stream, scope.ArrayView);

//
// Perform other operations...
Expand Down Expand Up @@ -67,7 +67,7 @@ static void PerformPinnedCopyUsingGCAllocateArray(Accelerator accelerator, int d

// Page locked buffers enable async memory transfers
using var scope = accelerator.CreatePageLockFromPinned(array);
bufferOnGPU.View.CopyFromPageLockedAsync(stream, scope);
bufferOnGPU.View.CopyFrom(stream, scope.ArrayView);

//
// Perform other operations...
Expand All @@ -91,7 +91,7 @@ static void PerformPinnedCopyUsingAllocatePageLockedArray(Accelerator accelerato
using var bufferOnGPU = accelerator.Allocate1D<int>(array.Length);
var stream = accelerator.DefaultStream;

bufferOnGPU.View.CopyFromPageLockedAsync(stream, array);
bufferOnGPU.View.CopyFrom(stream, array.ArrayView);

//
// Perform other operations...
Expand All @@ -101,7 +101,7 @@ static void PerformPinnedCopyUsingAllocatePageLockedArray(Accelerator accelerato
stream.Synchronize();

// Retrieve the results into an existing page locked array
bufferOnGPU.View.CopyToPageLockedAsync(stream, array);
bufferOnGPU.View.CopyTo(stream, array.ArrayView);

// Retrieve the results into a new array
// Rely on disabled (default) or automatic page locking behavior
Expand Down
16 changes: 8 additions & 8 deletions Src/ILGPU.Tests/PageLockedMemory.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ---------------------------------------------------------------------------------------
// ILGPU
// Copyright (c) 2021 ILGPU Project
// Copyright (c) 2021-2023 ILGPU Project
// www.ilgpu.net
//
// File: PageLockedMemory.cs
Expand Down Expand Up @@ -59,10 +59,10 @@ public unsafe void PinnedUsingGCHandle()
using var buffer = Accelerator.Allocate1D<int>(array.Length);
using var scope = Accelerator.CreatePageLockFromPinned(array);

buffer.View.CopyFromPageLockedAsync(scope);
buffer.View.CopyFrom(scope.ArrayView);
Execute(buffer.Length, buffer.View);

buffer.View.CopyToPageLockedAsync(scope);
buffer.View.CopyTo(scope.ArrayView);
Accelerator.Synchronize();
Verify1D(array, expected);
}
Expand All @@ -82,10 +82,10 @@ public void PinnedUsingGCAllocateArray()
using var buffer = Accelerator.Allocate1D<int>(array.Length);
using var scope = Accelerator.CreatePageLockFromPinned(array);

buffer.View.CopyFromPageLockedAsync(scope);
buffer.View.CopyFrom(scope.ArrayView);
Execute(buffer.Length, buffer.View);

buffer.View.CopyToPageLockedAsync(scope);
buffer.View.CopyTo(scope.ArrayView);
Accelerator.Synchronize();
Verify1D(array, expected);
}
Expand All @@ -109,14 +109,14 @@ public void Copy(long constant)
using var buff = Accelerator.Allocate1D<long>(Length);

// Start copying, create the expected array in the meantime
buff.View.CopyFromPageLockedAsync(array);
buff.View.CopyFrom(array.ArrayView);
var expected = Enumerable.Repeat(constant - 5, Length).ToArray();
Accelerator.Synchronize();

Execute(array.Extent.ToIntIndex(), buff.View);
Accelerator.Synchronize();

buff.View.CopyToPageLockedAsync(array);
buff.View.CopyTo(array.ArrayView);
Accelerator.Synchronize();

Assert.Equal(expected.Length, array.Length);
Expand All @@ -134,7 +134,7 @@ public void GetAsArrayPageLocked()
array[i] = 10;

using var buff = Accelerator.Allocate1D<long>(Length);
buff.View.CopyFromPageLockedAsync(array);
buff.View.CopyFrom(array.ArrayView);

var expected = new int[Length];
for (int i = 0; i < Length; i++)
Expand Down
170 changes: 2 additions & 168 deletions Src/ILGPU/Runtime/ArrayViewExtensions.Generated.tt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ---------------------------------------------------------------------------------------
// ILGPU
// Copyright (c) 2016-2021 ILGPU Project
// Copyright (c) 2016-2023 ILGPU Project
// www.ilgpu.net
//
// File: ArrayViewExtensions.Generated.tt/ArrayViewExtensions.Generated.cs
Expand Down Expand Up @@ -700,172 +700,6 @@ namespace ILGPU.Runtime

#endregion

#region Copy to/from Page Locked

<# foreach (var viewName in basicFunctions) { #>
/// <summary>
/// Copies from the source view into the given page locked memory without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The source view instance.</param>
/// <param name="pageLockScope">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyToPageLockedAsync<T>(
this <#= viewName #> source,
PageLockScope<T> pageLockScope)
where T : unmanaged =>
source.BaseView.CopyToPageLockedAsync(pageLockScope);

/// <summary>
/// Copies from the source view into the given page locked memory without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The source view instance.</param>
/// <param name="stream">The used accelerator stream.</param>
/// <param name="pageLockScope">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyToPageLockedAsync<T>(
this <#= viewName #> source,
AcceleratorStream stream,
PageLockScope<T> pageLockScope)
where T : unmanaged =>
source.BaseView.CopyToPageLockedAsync(stream, pageLockScope);

/// <summary>
/// Copies from the page locked memory into the given target view without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="target">The target view instance.</param>
/// <param name="pageLockScope">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFromPageLockedAsync<T>(
this <#= viewName #> target,
PageLockScope<T> pageLockScope)
where T : unmanaged =>
target.BaseView.CopyFromPageLockedAsync(pageLockScope);

/// <summary>
/// Copies from the page locked memory into the given target view without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="target">The target view instance.</param>
/// <param name="stream">The used accelerator stream.</param>
/// <param name="pageLockScope">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFromPageLockedAsync<T>(
this <#= viewName #> target,
AcceleratorStream stream,
PageLockScope<T> pageLockScope)
where T : unmanaged =>
target.BaseView.CopyFromPageLockedAsync(stream, pageLockScope);

<# } #>
#endregion

#region Copy to/from Page Locked Array

<# foreach (var (dimension, strideName, needsTranspose) in generalDimensionStrides) { #>
<# if (needsTranspose) continue; #>
<# var typeName = $"ArrayView{dimension}D"; #>
<# var strideTypeName = $"Stride{dimension}D"; #>
/// <summary>
/// Copies from the source view into the given page locked memory without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The source view instance.</param>
/// <param name="pageLockedArray">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
/// <remarks>
/// This method is not supported on accelerators.
/// </remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyToPageLockedAsync<T>(
this <#= typeName #><T, <#= strideTypeName #>.<#= strideName #>> source,
PageLockedArray<#= dimension #>D<T> pageLockedArray)
where T : unmanaged =>
source.CopyToPageLockedAsync(source.GetDefaultStream(), pageLockedArray);

/// <summary>
/// Copies from the source view into the given page locked memory without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="source">The source view instance.</param>
/// <param name="stream">The used accelerator stream.</param>
/// <param name="pageLockedArray">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
/// <remarks>
/// This method is not supported on accelerators.
/// </remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyToPageLockedAsync<T>(
this <#= typeName #><T, <#= strideTypeName #>.<#= strideName #>> source,
AcceleratorStream stream,
PageLockedArray<#= dimension #>D<T> pageLockedArray)
where T : unmanaged =>
source.BaseView.CopyToPageLockedAsync(stream, pageLockedArray);

/// <summary>
/// Copies from the page locked memory into the given target view without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="target">The target view instance.</param>
/// <param name="pageLockedArray">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
/// <remarks>
/// This method is not supported on accelerators.
/// </remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFromPageLockedAsync<T>(
this <#= typeName #><T, <#= strideTypeName #>.<#= strideName #>> target,
PageLockedArray<#= dimension #>D<T> pageLockedArray)
where T : unmanaged =>
target.CopyFromPageLockedAsync(target.GetDefaultStream(), pageLockedArray);

/// <summary>
/// Copies from the page locked memory into the given target view without
/// synchronizing the current accelerator stream.
/// </summary>
/// <typeparam name="T">The element type.</typeparam>
/// <param name="target">The target view instance.</param>
/// <param name="stream">The used accelerator stream.</param>
/// <param name="pageLockedArray">The page locked memory.</param>
/// <remarks>This method is not supported on accelerators.</remarks>
/// <remarks>
<# if (needsTranspose) { #>
/// CAUTION: this method transposes the data on the CPU.
<# } #>
/// This method is not supported on accelerators.
/// </remarks>
[NotInsideKernel]
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyFromPageLockedAsync<T>(
this <#= typeName #><T, <#= strideTypeName #>.<#= strideName #>> target,
AcceleratorStream stream,
PageLockedArray<#= dimension #>D<T> pageLockedArray)
where T : unmanaged =>
target.BaseView.CopyFromPageLockedAsync(stream, pageLockedArray);

<# } #>
#endregion

#region GetAsPageLocked

<# foreach (var (dimension, strideName, needsTranspose) in generalDimensionStrides) { #>
Expand Down Expand Up @@ -915,7 +749,7 @@ namespace ILGPU.Runtime
.AllocatePageLocked<#= dimension #>D<T>(view.Extent);

// Copy the data
view.CopyToPageLockedAsync(stream, result);
view.BaseView.CopyTo(stream, result.ArrayView);
stream.Synchronize();

return result;
Expand Down
Loading

0 comments on commit 955aaee

Please sign in to comment.