/// <summary> /// Allocates a new exchange buffer that allocates the specified amount of elements /// on the current accelerator. Furthermore, it keeps a buffer of the same size in pinned /// CPU memory to enable async memory transfers between the CPU and the GPU. /// </summary> /// <typeparam name="T">The element type.</typeparam> /// <param name="accelerator">The associated acclerator to use.</param> /// <param name="extent">The extent (number of elements to allocate).</param> /// <param name="mode">The current allocation mode.</param> /// <returns>The allocated exchange buffer.</returns> public static ExchangeBuffer <T> AllocateExchangeBuffer <T>( this Accelerator accelerator, Index extent, ExchangeBufferMode mode) where T : struct { var gpuBuffer = accelerator.Allocate <T>(extent); return(new ExchangeBuffer <T>(gpuBuffer, mode)); }
/// <summary> /// Constructs the base class for all exchange buffer implementations. /// </summary> /// <param name="buffer">The memory buffer to use.</param> /// <param name="mode">The exchange buffer mode to use.</param> internal ExchangeBufferBase(MemoryBuffer <T, TIndex> buffer, ExchangeBufferMode mode) : base(buffer.Accelerator, buffer.Extent.Size) { cpuMemory = buffer.Accelerator is CudaAccelerator && mode == ExchangeBufferMode.PreferPagedLockedMemory ? CudaViewSource.Create(buffer.LengthInBytes) : (ViewPointerWrapper)UnmanagedMemoryViewSource.Create( buffer.LengthInBytes); cpuMemoryPointer = cpuMemory.NativePtr.ToPointer(); }
/// <summary> /// Constructs the base class for all exchange buffer implementations. /// </summary> /// <param name="accelerator">The associated accelerator.</param> /// <param name="extent">The extent (number of elements).</param> /// <param name="mode">The exchange buffer mode to use.</param> protected ExchangeBufferBase( Accelerator accelerator, TIndex extent, ExchangeBufferMode mode) : base(accelerator, extent) { CPUMemory = Accelerator is CudaAccelerator && mode == ExchangeBufferMode.PreferPageLockedMemory ? CudaViewSource.Create(LengthInBytes) : (ViewPointerWrapper)UnmanagedMemoryViewSource.Create(LengthInBytes); var baseView = new ArrayView <T>(CPUMemory, 0, Length); CPUView = new ArrayView <T, TIndex>(baseView, extent); }
/// <summary> /// Initializes a new basic exchange buffer. /// </summary> /// <param name="gpuBuffer">The parent GPU buffer to use.</param> /// <param name="mode">The exchange buffer mode to use.</param> /// <remarks> /// CAUTION: The ownership of the <paramref name="gpuBuffer"/> is transferred to /// this instance. /// </remarks> protected internal ExchangeBuffer( MemoryBuffer <ArrayView1D <T, Stride1D.Dense> > gpuBuffer, ExchangeBufferMode mode) : base(gpuBuffer.Accelerator) { GPUBuffer = gpuBuffer; CPUBuffer = Accelerator is CudaAccelerator && mode == ExchangeBufferMode.PreferPageLockedMemory ? CPUMemoryBuffer.CreatePinned( Accelerator, gpuBuffer.LengthInBytes, gpuBuffer.ElementSize) : CPUMemoryBuffer.Create(gpuBuffer.LengthInBytes, gpuBuffer.ElementSize); CPUView = new ArrayView <T>(CPUBuffer, 0, gpuBuffer.Length); }
/// <summary> /// Allocates an exchange buffer using the given mode. /// </summary> /// <typeparam name="T">The element type.</typeparam> /// <param name="accelerator">The accelerator instance.</param> /// <param name="length">The number of elements to allocate.</param> /// <param name="mode">The buffer mode to use.</param> /// <returns>The allocated exchange mode.</returns> public static ExchangeBuffer <T> AllocateExchangeBuffer <T>( this Accelerator accelerator, long length, ExchangeBufferMode mode) where T : unmanaged => new ExchangeBuffer <T>(accelerator.Allocate1D <T>(length), mode);