Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions cuda_core/cuda/core/_cpp/resource_handles.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,14 @@
#include <cstdint>
#include <cstring>
#include <mutex>
#include <stdexcept>
#include <unordered_map>
#include <vector>

#ifndef _WIN32
#include <unistd.h>
#endif

namespace cuda_core {

// ============================================================================
Expand Down Expand Up @@ -1116,4 +1121,27 @@ CuLinkHandle create_culink_handle_ref(CUlinkState state) {
return CuLinkHandle(box, &box->resource);
}

// ============================================================================
// File Descriptor Handles
// ============================================================================

FileDescriptorHandle create_fd_handle(int fd) {
#ifdef _WIN32
throw std::runtime_error("create_fd_handle is not supported on Windows");
#else
return FileDescriptorHandle(
new int(fd),
[](const int* p) { ::close(*p); delete p; }
);
#endif
}

FileDescriptorHandle create_fd_handle_ref(int fd) {
#ifdef _WIN32
throw std::runtime_error("create_fd_handle_ref is not supported on Windows");
#else
return std::make_shared<const int>(fd);
#endif
}

} // namespace cuda_core
20 changes: 20 additions & 0 deletions cuda_core/cuda/core/_cpp/resource_handles.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ using NvrtcProgramHandle = std::shared_ptr<const nvrtcProgram>;
using NvvmProgramHandle = std::shared_ptr<const NvvmProgramValue>;
using NvJitLinkHandle = std::shared_ptr<const NvJitLinkValue>;
using CuLinkHandle = std::shared_ptr<const CUlinkState>;
using FileDescriptorHandle = std::shared_ptr<const int>;


// ============================================================================
Expand Down Expand Up @@ -477,6 +478,17 @@ CuLinkHandle create_culink_handle(CUlinkState state);
// The handle will NOT be destroyed when the last reference is released.
CuLinkHandle create_culink_handle_ref(CUlinkState state);

// ============================================================================
// File descriptor handle functions
// ============================================================================

// Create an owning file descriptor handle.
// When the last reference is released, POSIX close() is called.
FileDescriptorHandle create_fd_handle(int fd);

// Create a non-owning file descriptor handle (caller manages the fd).
FileDescriptorHandle create_fd_handle_ref(int fd);

// ============================================================================
// Overloaded helper functions to extract raw resources from handles
// ============================================================================
Expand Down Expand Up @@ -596,6 +608,10 @@ inline std::intptr_t as_intptr(const CuLinkHandle& h) noexcept {
return reinterpret_cast<std::intptr_t>(as_cu(h));
}

inline std::intptr_t as_intptr(const FileDescriptorHandle& h) noexcept {
return h ? static_cast<std::intptr_t>(*h) : -1;
}

// as_py() - convert handle to Python wrapper object (returns new reference)
#if PY_VERSION_HEX < 0x030D0000
extern "C" int _Py_IsFinalizing(void);
Expand Down Expand Up @@ -687,4 +703,8 @@ inline PyObject* as_py(const GraphicsResourceHandle& h) noexcept {
return detail::make_py("cuda.bindings.driver", "CUgraphicsResource", as_intptr(h));
}

inline PyObject* as_py(const FileDescriptorHandle& h) noexcept {
return PyLong_FromSsize_t(as_intptr(h));
}

} // namespace cuda_core
5 changes: 3 additions & 2 deletions cuda_core/cuda/core/_memory/_ipc.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from cuda.bindings cimport cydriver
from cuda.core._memory._buffer cimport Buffer
from cuda.core._memory._memory_pool cimport _MemPool
from cuda.core._resource_handles cimport FileDescriptorHandle


# Holds _MemPool objects imported by this process. This enables
Expand Down Expand Up @@ -46,8 +47,8 @@ cdef class IPCBufferDescriptor:

cdef class IPCAllocationHandle:
cdef:
int _handle
object _uuid
FileDescriptorHandle _h_fd
object _uuid

cpdef close(self)

Expand Down
20 changes: 8 additions & 12 deletions cuda_core/cuda/core/_memory/_ipc.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,13 @@ from cuda.core._memory._memory_pool cimport _MemPool
from cuda.core._stream cimport Stream
from cuda.core._resource_handles cimport (
DevicePtrHandle,
create_fd_handle,
create_mempool_handle_ipc,
deviceptr_import_ipc,
get_last_error,
as_cu,
as_intptr,
as_py,
)

from cuda.core._stream cimport default_stream
Expand Down Expand Up @@ -110,31 +113,24 @@ cdef class IPCAllocationHandle:
def _init(cls, handle: int, uuid): # no-cython-lint
cdef IPCAllocationHandle self = IPCAllocationHandle.__new__(cls)
assert handle >= 0
self._handle = handle
self._h_fd = create_fd_handle(handle)
self._uuid = uuid
return self

cpdef close(self):
"""Close the handle."""
if self._handle >= 0:
try:
os.close(self._handle)
finally:
self._handle = -1

def __dealloc__(self):
self.close()
self._h_fd.reset()

def __int__(self) -> int:
if self._handle < 0:
if not self._h_fd or as_intptr(self._h_fd) < 0:
raise ValueError(
f"Cannot convert IPCAllocationHandle to int: the handle (id={id(self)}) is closed."
)
return self._handle
return as_py(self._h_fd)

@property
def handle(self) -> int:
return self._handle
return as_py(self._h_fd)

@property
def uuid(self) -> uuid.UUID:
Expand Down
7 changes: 7 additions & 0 deletions cuda_core/cuda/core/_resource_handles.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core":
ctypedef shared_ptr[const NvJitLinkValue] NvJitLinkHandle

ctypedef shared_ptr[const cydriver.CUlinkState] CuLinkHandle
ctypedef shared_ptr[const int] FileDescriptorHandle

# as_cu() - extract the raw CUDA handle (inline C++)
cydriver.CUcontext as_cu(ContextHandle h) noexcept nogil
Expand Down Expand Up @@ -73,6 +74,7 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core":
intptr_t as_intptr(NvvmProgramHandle h) noexcept nogil
intptr_t as_intptr(NvJitLinkHandle h) noexcept nogil
intptr_t as_intptr(CuLinkHandle h) noexcept nogil
intptr_t as_intptr(FileDescriptorHandle h) noexcept nogil

# as_py() - convert handle to Python wrapper object (inline C++; requires GIL)
object as_py(ContextHandle h)
Expand All @@ -89,6 +91,7 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core":
object as_py(NvvmProgramHandle h)
object as_py(NvJitLinkHandle h)
object as_py(CuLinkHandle h)
object as_py(FileDescriptorHandle h)


# =============================================================================
Expand Down Expand Up @@ -203,3 +206,7 @@ cdef NvJitLinkHandle create_nvjitlink_handle_ref(cynvjitlink.nvJitLinkHandle han
# cuLink handles
cdef CuLinkHandle create_culink_handle(cydriver.CUlinkState state) except+ nogil
cdef CuLinkHandle create_culink_handle_ref(cydriver.CUlinkState state) except+ nogil

# File descriptor handles
cdef FileDescriptorHandle create_fd_handle(int fd) except+ nogil
cdef FileDescriptorHandle create_fd_handle_ref(int fd) except+ nogil
6 changes: 6 additions & 0 deletions cuda_core/cuda/core/_resource_handles.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,12 @@ cdef extern from "_cpp/resource_handles.hpp" namespace "cuda_core":
CuLinkHandle create_culink_handle_ref "cuda_core::create_culink_handle_ref" (
cydriver.CUlinkState state) except+ nogil

# File descriptor handles
FileDescriptorHandle create_fd_handle "cuda_core::create_fd_handle" (
int fd) except+ nogil
FileDescriptorHandle create_fd_handle_ref "cuda_core::create_fd_handle_ref" (
int fd) except+ nogil


# =============================================================================
# CUDA Driver API capsule
Expand Down
Loading