55#include " adaptor.h"
66#include " alloc.h"
77#include " param.h"
8+ #include < mutex>
89#include < unistd.h>
10+ #include < unordered_map>
11+
12+ static std::mutex gVmmHandleMapMtx ;
13+ static std::unordered_map<void *, CUmemGenericAllocationHandle> gVmmHandleMap ;
914
1015std::map<flagcxMemcpyType_t, cudaMemcpyKind> memcpy_type_map = {
1116 {flagcxMemcpyHostToDevice, cudaMemcpyHostToDevice},
@@ -145,22 +150,31 @@ flagcxResult_t cudaAdaptorGdrMemAlloc(void **ptr, size_t size,
145150 DEVCHECK (cuDeviceGetAttribute (
146151 &flag, CU_DEVICE_ATTRIBUTE_GPU_DIRECT_RDMA_WITH_CUDA_VMM_SUPPORTED ,
147152 currentDev));
153+ INFO (FLAGCX_INIT ,
154+ " [gdrMemAlloc] dev=%d GPU_DIRECT_RDMA_WITH_CUDA_VMM_SUPPORTED=%d "
155+ " size=%zu" ,
156+ cudaDev, flag, size);
148157 if (flag)
149158 memprop.allocFlags .gpuDirectRDMACapable = 1 ;
150159 DEVCHECK (cuMemGetAllocationGranularity (&memGran, &memprop,
151160 CU_MEM_ALLOC_GRANULARITY_RECOMMENDED ));
152161 ALIGN_SIZE (handleSize, memGran);
162+ INFO (FLAGCX_INIT ,
163+ " [gdrMemAlloc] memGran=%zu handleSize=%zu gpuDirectRDMACapable=%d" ,
164+ memGran, handleSize, (int )memprop.allocFlags .gpuDirectRDMACapable );
153165 /* Allocate the physical memory on the device */
154166 DEVCHECK (cuMemCreate (&handle, handleSize, &memprop, 0 ));
155167 /* Reserve a virtual address range */
156168 cuRes = cuMemAddressReserve ((CUdeviceptr *)ptr, handleSize, memGran, 0 , 0 );
157169 if (cuRes != CUDA_SUCCESS ) {
170+ WARN (" [gdrMemAlloc] cuMemAddressReserve FAILED: %d" , (int )cuRes);
158171 cuMemRelease (handle);
159172 return flagcxUnhandledDeviceError;
160173 }
161174 /* Map the virtual address range to the physical allocation */
162175 cuRes = cuMemMap ((CUdeviceptr)*ptr, handleSize, 0 , handle, 0 );
163176 if (cuRes != CUDA_SUCCESS ) {
177+ WARN (" [gdrMemAlloc] cuMemMap FAILED: %d" , (int )cuRes);
164178 cuMemAddressFree ((CUdeviceptr)*ptr, handleSize);
165179 cuMemRelease (handle);
166180 *ptr = NULL ;
@@ -173,14 +187,21 @@ flagcxResult_t cudaAdaptorGdrMemAlloc(void **ptr, size_t size,
173187 accessDesc.flags = CU_MEM_ACCESS_FLAGS_PROT_READWRITE ;
174188 cuRes = cuMemSetAccess ((CUdeviceptr)*ptr, handleSize, &accessDesc, 1 );
175189 if (cuRes != CUDA_SUCCESS ) {
190+ WARN (" [gdrMemAlloc] cuMemSetAccess FAILED: %d" , (int )cuRes);
176191 cuMemUnmap ((CUdeviceptr)*ptr, handleSize);
177192 cuMemAddressFree ((CUdeviceptr)*ptr, handleSize);
178193 cuMemRelease (handle);
179194 *ptr = NULL ;
180195 return flagcxUnhandledDeviceError;
181196 }
182- /* Release the create-time handle reference; the mapping holds its own. */
183- cuMemRelease (handle);
197+ INFO (FLAGCX_INIT , " [gdrMemAlloc] VMM alloc OK: ptr=%p size=%zu" , *ptr,
198+ handleSize);
199+ /* Retain the handle so cuMemGetHandleForAddressRange can export DMA-BUF fds.
200+ Released in cudaAdaptorGdrMemFree. */
201+ {
202+ std::lock_guard<std::mutex> lk (gVmmHandleMapMtx );
203+ gVmmHandleMap [*ptr] = handle;
204+ }
184205#else
185206 DEVCHECK (cudaMalloc (ptr, size));
186207 cudaPointerAttributes attrs;
@@ -206,6 +227,16 @@ flagcxResult_t cudaAdaptorGdrMemFree(void *ptr, void *memHandle) {
206227 DEVCHECK (cuMemGetAddressRange (NULL , &size, (CUdeviceptr)ptr));
207228 DEVCHECK (cuMemUnmap ((CUdeviceptr)ptr, size));
208229 DEVCHECK (cuMemAddressFree ((CUdeviceptr)ptr, size));
230+
231+ // Release the VMM handle we retained at alloc time
232+ {
233+ std::lock_guard<std::mutex> lk (gVmmHandleMapMtx );
234+ auto it = gVmmHandleMap .find (ptr);
235+ if (it != gVmmHandleMap .end ()) {
236+ cuMemRelease (it->second );
237+ gVmmHandleMap .erase (it);
238+ }
239+ }
209240#else
210241 DEVCHECK (cudaFree (ptr));
211242#endif
@@ -509,8 +540,11 @@ flagcxResult_t
509540cudaAdaptorMemGetHandleForAddressRange (void *handleOut, void *buffer,
510541 size_t size, unsigned long long flags) {
511542 CUdeviceptr dptr = (CUdeviceptr)buffer;
512- DEVCHECK (cuMemGetHandleForAddressRange (
513- handleOut, dptr, size, CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD , flags));
543+ CUresult err = cuMemGetHandleForAddressRange (
544+ handleOut, dptr, size, CU_MEM_RANGE_HANDLE_TYPE_DMA_BUF_FD , flags);
545+ if (err != CUDA_SUCCESS ) {
546+ return flagcxUnhandledDeviceError;
547+ }
514548 return flagcxSuccess;
515549}
516550
@@ -544,7 +578,13 @@ flagcxResult_t cudaAdaptorSymPhysAlloc(void *ptr, size_t size,
544578 return flagcxSystemError;
545579
546580 // Retain the physical allocation handle from the VMM-backed pointer
547- DEVCHECK (cuMemRetainAllocationHandle (cuHandle, ptr));
581+ CUresult retainRes = cuMemRetainAllocationHandle (cuHandle, ptr);
582+ if (retainRes != CUDA_SUCCESS ) {
583+ WARN (" [symPhysAlloc] cuMemRetainAllocationHandle FAILED: %d ptr=%p" ,
584+ (int )retainRes, ptr);
585+ free (cuHandle);
586+ return flagcxUnhandledDeviceError;
587+ }
548588
549589 // Discover actual physical allocation size (already granularity-aligned)
550590 size_t actualAllocSize = 0 ;
@@ -556,8 +596,16 @@ flagcxResult_t cudaAdaptorSymPhysAlloc(void *ptr, size_t size,
556596 free (cuHandle);
557597 return flagcxInvalidArgument;
558598 }
559- DEVCHECK (cuMemExportToShareableHandle (
560- shareableHandle, *cuHandle, CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR , 0 ));
599+ CUresult exportRes = cuMemExportToShareableHandle (
600+ shareableHandle, *cuHandle, CU_MEM_HANDLE_TYPE_POSIX_FILE_DESCRIPTOR , 0 );
601+ if (exportRes != CUDA_SUCCESS ) {
602+ WARN (" [symPhysAlloc] cuMemExportToShareableHandle FAILED: %d" ,
603+ (int )exportRes);
604+ free (cuHandle);
605+ return flagcxUnhandledDeviceError;
606+ }
607+ INFO (FLAGCX_INIT , " [symPhysAlloc] ptr=%p allocSize=%zu fd=%d" , ptr,
608+ actualAllocSize, *(int *)shareableHandle);
561609 *handleSize = sizeof (int ); // POSIX fd is an int
562610 *physHandle = cuHandle;
563611 return flagcxSuccess;
0 commit comments