Skip to content

Commit

Permalink
Added convenience methods for IPC memory handles and checking for IPC…
Browse files Browse the repository at this point in the history
… support
  • Loading branch information
Deneas committed Jun 1, 2024
1 parent 6cdac42 commit 76a55cd
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 2 deletions.
61 changes: 59 additions & 2 deletions Src/ILGPU/Runtime/Cuda/CudaAccelerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -488,16 +488,73 @@ protected override MemoryBuffer AllocateRawInternal(
/// <param name="ipcMemHandle">A IPC memory handle from another process.</param>
/// <param name="length">The number of elements to allocate.</param>
/// <param name="elementSize">The size of a single element in bytes.</param>
/// <param name="flags">The flags to use</param>
/// <returns>A mapped buffer of shared memory on this accelerator.</returns>
public CudaIpcMemoryBuffer MapRaw(CudaIpcMemHandle ipcMemHandle, long length, int elementSize)
/// <remarks>
/// In case of multi GPU setups like SLI it may require <see cref="CudaIpcMemFlags.LazyEnablePeerAccess"/>
/// even when using the same device.
/// </remarks>
public MemoryBuffer MapFromIpcMemHandle(CudaIpcMemHandle ipcMemHandle, long length, int elementSize, CudaIpcMemFlags flags)
{
if (length < 0)
throw new ArgumentOutOfRangeException(nameof(length));
if (elementSize < 1)
throw new ArgumentOutOfRangeException(nameof(elementSize));

Bind();
return new CudaIpcMemoryBuffer(this, ipcMemHandle, length, elementSize, CudaIpcMemFlags.None);
return new CudaIpcMemoryBuffer(this, ipcMemHandle, length, elementSize, flags);
}

/// <summary>
/// Exports memory for use in another process
/// </summary>
/// <param name="memoryBuffer">The <see cref="CudaMemoryBuffer"/> to export.</param>
/// <returns>The IPC memory handle for other processes.</returns>
/// <remarks>This will zero the memory in the buffer and
/// in case of small allocations under 1 MB even neighboring memory will be zeroed.<br />
/// A buffer can only have one IPC memory handle, but multiple processes can use the same handle.
/// </remarks>
/// <exception cref="NotSupportedException">Only <see cref="CudaMemoryBuffer"/> supports CUDA IPC.</exception>
public CudaIpcMemHandle GetIpcMemoryHandle(MemoryBuffer memoryBuffer)
{
if (memoryBuffer is not CudaMemoryBuffer)
{
throw new NotSupportedException(
string.Format(ErrorMessages.NotSupportedType,
memoryBuffer.GetType()));
}
Bind();
CudaException.ThrowIfFailed(
CurrentAPI.GetIpcMemoryHandle(out var ipcMemHandle, memoryBuffer.NativePtr)
);
return ipcMemHandle;
}

/// <summary>
/// Exports memory for use in another process
/// </summary>
/// <param name="memoryBuffer">The memory buffer with an underlying <see cref="CudaMemoryBuffer"/> to export.</param>
/// <returns>The IPC memory handle for other processes.</returns>
/// <remarks>This will zero the memory in the buffer and
/// in case of small allocations under 1 MB even neighboring memory will be zeroed.<br />
/// A buffer can only have one IPC memory handle, but multiple processes can use the same handle.
/// </remarks>
/// <exception cref="NotSupportedException">Only <see cref="CudaMemoryBuffer"/> supports CUDA IPC.</exception>
public CudaIpcMemHandle GetIpcMemoryHandle<TView>(MemoryBuffer<TView> memoryBuffer)
where TView : struct, IArrayView
{
MemoryBuffer underlyingBuffer = memoryBuffer.View.Buffer;
if (underlyingBuffer is not CudaMemoryBuffer cudaMemoryBuffer)
{
throw new NotSupportedException(
string.Format(ErrorMessages.NotSupportedType,
underlyingBuffer.GetType()));
}
Bind();
CudaException.ThrowIfFailed(
CurrentAPI.GetIpcMemoryHandle(out var ipcMemHandle, cudaMemoryBuffer.NativePtr)
);
return ipcMemHandle;
}

#endregion
Expand Down
10 changes: 10 additions & 0 deletions Src/ILGPU/Runtime/Cuda/CudaDevice.cs
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,11 @@ private void InitMiscInfo()
DeviceAttributeKind.
CU_DEVICE_ATTRIBUTE_CAN_USE_HOST_POINTER_FOR_REGISTERED_MEM,
DeviceId) != 0;

// Resolve whether this device has IPC support
HasIpcSupport = CurrentAPI.GetDeviceAttribute(
DeviceAttributeKind.CU_DEVICE_ATTRIBUTE_IPC_EVENT_SUPPORT,
DeviceId) != 0;
}

/// <summary>
Expand Down Expand Up @@ -461,6 +466,11 @@ private void InitPCIInfo()
/// </summary>
public bool SupportsUsingHostPointerForRegisteredMemory { get; private set; }

/// <summary>
/// Returns true if this device supports inter process communication for memory and events.
/// </summary>
public bool HasIpcSupport { get; private set; }

/// <summary>
/// Returns the current device driver mode.
/// </summary>
Expand Down

0 comments on commit 76a55cd

Please sign in to comment.