Repository navigation
Make memory hooks work with static libcudart, by using bistro hooks for cuda driver API - #6038
Conversation
| } | ||
|
|
||
| /* check the opcode */ | ||
| if (((rex == 0) || rex == 0x41) && ((opcode & 0xF0) == 0x50)) { |
There was a problem hiding this comment.
((rex == 0) || rex == 0x41) is this correct?
There was a problem hiding this comment.
rex == 0 is pushing IA32 register and rex==0x41 is pushing rN register
| } | ||
| } | ||
|
|
||
| /* unsupported instruction - bail */ |
|
|
||
| pthread_mutex_lock(&mutex); | ||
|
|
||
| if (page == MAP_FAILED) { |
There was a problem hiding this comment.
this condition is always true
| } | ||
| } | ||
|
|
||
| if (size + offset > ucm_get_page_size()) { |
There was a problem hiding this comment.
offset is 0 here... and wrap size + offset by ()
|
|
||
| /* allocate space in the page */ | ||
| result = UCS_PTR_BYTE_OFFSET(page, offset); | ||
| offset += size; |
There was a problem hiding this comment.
it seems body of this function was in loop :)
76d2862 to
ee105b1
Compare
| * Set library function call hook using Binary Instrumentation | ||
| * method (BISTRO): replace function body by user defined call | ||
| * | ||
| * @param symbol function name to replace |
| ucm_event_enter(); | ||
|
|
||
| ucm_trace("ucm_cuMemFree(dptr=%p)",(void*)dptr); | ||
| ucm_diag("ucm_cuMemFree(dptr=%p)",(void*)dptr); |
|
|
||
| ucm_event_enter(); | ||
|
|
||
| ucm_diag("ucm_cuMemFree_v2(dptr=%p)",(void*)dptr); |
| ret = ucm_orig_cuMemAlloc(dptr, size); | ||
| if (ret == CUDA_SUCCESS) { | ||
| ucm_trace("ucm_cuMemAlloc(dptr=%p size:%lu)",(void *)*dptr, size); | ||
| ucm_diag("ucm_cuMemAlloc(dptr=%p size:%lu)",(void *)*dptr, size); |
There was a problem hiding this comment.
would not diag be too flooding?
| ret = ucm_orig_cuMemAlloc(dptr, size); | ||
| if (ret == CUDA_SUCCESS) { | ||
| ucm_trace("ucm_cuMemAlloc(dptr=%p size:%lu)",(void *)*dptr, size); | ||
| ucm_diag("ucm_cuMemAlloc(dptr=%p size:%lu)",(void *)*dptr, size); |
|
|
||
| ret = ucm_orig_cuMemAlloc_v2(dptr, size); | ||
| if (ret == CUDA_SUCCESS) { | ||
| ucm_diag("ucm_cuMemAlloc_v2(dptr=%p size:%lu)",(void *)*dptr, size); |
| ElementSizeBytes); | ||
| if (ret == CUDA_SUCCESS) { | ||
| ucm_trace("ucm_cuMemHostGetDevicePointer(pdptr=%p p=%p)",(void *)*pdptr, p); | ||
| ucm_trace("ucm_cuMemAllocPitch_v2(dptr=%p size:%lu)",(void *)*dptr, |
| continue; | ||
| } | ||
|
|
||
| ucm_debug("failed to install bistro hook for '%s', fallback to reloc", |
There was a problem hiding this comment.
better print status here than in previous ucs_debug, where it is always OK
ee105b1 to
79c12b7
Compare
79c12b7 to
d87b139
Compare
8595659 to
1b69f10
Compare
|
bot:pipe:retest |
|
/azp run |
|
bot:pipe:retest |
|
Azure Pipelines successfully started running 1 pipeline(s). |
|
/azp run |
|
Azure Pipelines successfully started running 1 pipeline(s). |
1b69f10 to
80693f4
Compare
|
@Akshay-Venkatesh @bureddy can you pls take a look? |
| * optional, may be NULL | ||
| * @param func_ptr Pointer to function to patch. | ||
| * @param hook User-defined function-replacer. | ||
| * @param symbol Function name to replace. |
There was a problem hiding this comment.
should we we add @PARAM orig_func_p documentation here?
| UCM_CUDA_FREE_FUNC(cuMemFree, CUresult, CUdeviceptr) | ||
| UCM_CUDA_FREE_FUNC(cuMemFree_v2, CUresult, CUdeviceptr) | ||
| UCM_CUDA_FREE_FUNC(cuMemFreeHost, CUresult, void*) | ||
| UCM_CUDA_FREE_FUNC(cuMemFreeHost_v2, CUresult, void*) |
There was a problem hiding this comment.
cuMemFreeHost is also dispatching UCS_MEMORY_TYPE_CUDA memtype free event. it is not an issue today as we don't care if it not find in the mem type cache. but, should we differentiate cuMemFree and cuMemFreeHost?
| if (status == UCS_OK) { | ||
| ucm_debug("installed cuda memory bistro hooks on driver API"); | ||
| ucm_cudamem_installed = 1; | ||
| } else { |
There was a problem hiding this comment.
we also have to install reloc for driver funcs if bistro fails. application might be using driver API directly.
can we update test_cuda_hook.c with driver api test as well?
|
@bureddy fixed |
Some high-level questions/requests:
|
Added
Memory before ucp_init is not a problem: we set suspicious regions to UNKNOWN and force detection during runtime
Added note: if other library is hooking .plt it would work, if using bistro - no |
| return ret; | ||
| event.mem_type.address = (void*)ptr; | ||
| event.mem_type.size = length; | ||
| event.mem_type.mem_type = UCS_MEMORY_TYPE_CUDA; |
There was a problem hiding this comment.
should this be "event.mem_type.mem_type = mem_type" ?
| cudaError_t ucm_cudaHostGetDevicePointer(void **pDevice, void *pHost, unsigned int flags) | ||
| { | ||
| cudaError_t ret; | ||
| if (ucm_mmap_hook_mode() == UCM_MMAP_HOOK_BISTRO) { |
There was a problem hiding this comment.
@yosefe should we detach cuda hooks from ucm_mmap_hook_mode() flag? may be we have a case where we need to to disable malloc bistro hooks but not cuda hooks ( for ex: on summit with spectrum mpi).
how about controlling cuda hooks with new flag "ucm_cuda_hook_mode: and "remove ucm_global_opts.enable_cuda_reloc" ?
|
|
||
| if (!ucm_global_opts.enable_cuda_reloc) { | ||
| if (ucm_cuda_hook_mode() == UCM_MMAP_HOOK_NONE) { | ||
| ucm_debug("cudamem relocations are disabled by configuration"); |
| " reloc - Use ELF relocation table to set hooks.\n" | ||
| #if UCM_BISTRO_HOOKS | ||
| " bistro - Use binary instrumentation to set hooks. In this mode, calls to\n" | ||
| " statically a statically Cuda runtime can be hooked on the the\n" |
| status = ucm_cuda_install_hooks(ucm_cuda_runtime_funcs, &used_reloc); | ||
| if (status == UCS_OK) { | ||
| ucm_debug("installed cuda memory %s hooks on runtime API", | ||
| used_reloc ? "reloc" : "bistro"); |
There was a problem hiding this comment.
seems "ucm_cuda_install_hooks" can do bistro for some funcs if it is possible and reloc for others. is this debug msg accurate?
In order to catch cuda memory events even when Cuda is statically linked, use bistro.
9502681 to
705eb62
Compare
Why
Support Cuda memory allocate/release hooks also for applications which are linked to libcudart statically, or use directly the driver API.
Fixed #3210
How
Use binary instrumentation (bistro) hooks for Cuda Driver APIs, which work regardless of how a function is called (from .plt or by function pointer).
If any other library is intercepting the same function by .plt hooks, it can work alongside with bistro hooks. However, if the other library is also using binary patching, in will probably be incompatible with the UCX hooks.
Binary instrumentation hook method: