|
44 | 44 | os.path.join(os.path.dirname(__file__), "../../flagcx/include"), |
45 | 45 | ) |
46 | 46 |
|
| 47 | +# FlagCX library path for linking |
| 48 | +FLAGCX_LIB_PATH = os.environ.get( |
| 49 | + "FLAGCX_LIB_PATH", |
| 50 | + os.path.join(os.path.dirname(__file__), "../../build/lib"), |
| 51 | +) |
| 52 | + |
47 | 53 | # ============================================================ |
48 | 54 | # FlagCX pluggable allocator (wraps flagcxMemAlloc/flagcxMemFree) |
49 | 55 | # ============================================================ |
|
70 | 76 | } |
71 | 77 | """ |
72 | 78 |
|
| 79 | +_allocator = None |
| 80 | +_allocator_wrapper = None |
| 81 | +_mem_pool = None |
| 82 | +_flagcx_allocator_failed_to_compile = False |
| 83 | + |
| 84 | + |
| 85 | +def compile_flagcx_allocator(): |
| 86 | + """Compile the FlagCX allocator extension. Called once, result cached.""" |
| 87 | + global _allocator, _allocator_wrapper, _flagcx_allocator_failed_to_compile |
| 88 | + try: |
| 89 | + out_dir = tempfile.gettempdir() |
| 90 | + lib_name = "flagcx_allocator" |
| 91 | + |
| 92 | + load_inline( |
| 93 | + name=lib_name, |
| 94 | + cpp_sources=flagcx_allocator_source, |
| 95 | + with_cuda=True, |
| 96 | + extra_ldflags=[f"-L{FLAGCX_LIB_PATH}", "-lflagcx", |
| 97 | + f"-Wl,-rpath,{FLAGCX_LIB_PATH}"], |
| 98 | + verbose=False, |
| 99 | + is_python_module=False, |
| 100 | + build_directory=out_dir, |
| 101 | + extra_include_paths=[FLAGCX_INCLUDE_PATH], |
| 102 | + ) |
| 103 | + |
| 104 | + _allocator_wrapper = CUDAPluggableAllocator( |
| 105 | + f"{out_dir}/{lib_name}.so", |
| 106 | + "flagcx_alloc_plug", |
| 107 | + "flagcx_free_plug", |
| 108 | + ) |
| 109 | + _allocator = _allocator_wrapper.allocator() |
| 110 | + except Exception as e: |
| 111 | + _flagcx_allocator_failed_to_compile = True |
| 112 | + print( |
| 113 | + f"[WARNING] Failed to compile FlagCX memory allocator: {e}\n" |
| 114 | + f" Ensure FLAGCX_LIB_PATH ({FLAGCX_LIB_PATH}) contains libflagcx.so\n" |
| 115 | + f" and FLAGCX_INCLUDE_PATH ({FLAGCX_INCLUDE_PATH}) contains flagcx.h" |
| 116 | + ) |
| 117 | + |
73 | 118 |
|
74 | 119 | def get_flagcx_mem_pool(): |
75 | | - """Compile and return a PyTorch MemPool that uses flagcxMemAlloc.""" |
76 | | - out_dir = tempfile.gettempdir() |
77 | | - lib_name = "flagcx_allocator" |
78 | | - |
79 | | - load_inline( |
80 | | - name=lib_name, |
81 | | - cpp_sources=flagcx_allocator_source, |
82 | | - with_cuda=True, |
83 | | - extra_ldflags=["-lflagcx"], |
84 | | - verbose=False, |
85 | | - is_python_module=False, |
86 | | - build_directory=out_dir, |
87 | | - extra_include_paths=[FLAGCX_INCLUDE_PATH], |
88 | | - ) |
| 120 | + """Return a cached PyTorch MemPool backed by flagcxMemAlloc.""" |
| 121 | + global _mem_pool, _flagcx_allocator_failed_to_compile |
| 122 | + if _mem_pool is None and not _flagcx_allocator_failed_to_compile: |
| 123 | + compile_flagcx_allocator() |
| 124 | + if _allocator is not None: |
| 125 | + _mem_pool = torch.cuda.MemPool(_allocator) |
| 126 | + return _mem_pool |
89 | 127 |
|
90 | | - allocator_wrapper = CUDAPluggableAllocator( |
91 | | - f"{out_dir}/{lib_name}.so", |
92 | | - "flagcx_alloc_plug", |
93 | | - "flagcx_free_plug", |
94 | | - ) |
95 | | - return torch.cuda.MemPool(allocator_wrapper.allocator()) |
| 128 | + |
| 129 | +def _cleanup_flagcx_mem_pool(): |
| 130 | + global _mem_pool |
| 131 | + _mem_pool = None |
| 132 | + |
| 133 | + |
| 134 | +def _cleanup_flagcx_allocator_wrapper(): |
| 135 | + global _allocator_wrapper |
| 136 | + _allocator_wrapper = None |
| 137 | + |
| 138 | + |
| 139 | +import atexit |
| 140 | +atexit.register(_cleanup_flagcx_mem_pool) |
| 141 | +atexit.register(_cleanup_flagcx_allocator_wrapper) |
96 | 142 |
|
97 | 143 |
|
98 | 144 | # ============================================================ |
@@ -181,6 +227,11 @@ def main(): |
181 | 227 | buf_size = N * 4 # float32 |
182 | 228 |
|
183 | 229 | flagcx_pool = get_flagcx_mem_pool() |
| 230 | + if flagcx_pool is None: |
| 231 | + raise RuntimeError( |
| 232 | + "Failed to initialize FlagCX memory pool. " |
| 233 | + "Check compilation warnings above." |
| 234 | + ) |
184 | 235 | with torch.cuda.use_mem_pool(flagcx_pool): |
185 | 236 | buf_tensor = torch.full((N,), float(rank), dtype=torch.float32, device="cuda") |
186 | 237 |
|
|
0 commit comments