Skip to content

Commit db00748

Browse files
committed
metal: update AllocVTable implementation for multi-device routing
1 parent eb1f592 commit db00748

1 file changed

Lines changed: 40 additions & 7 deletions

File tree

src/metal/tensor.mm

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void pool_release(void* data_ptr) {
117117

118118
namespace detail::metal {
119119

120-
void* metal_alloc(std::size_t bytes) {
120+
void* metal_alloc(std::size_t bytes, int) {
121121
if (bytes == 0) return nullptr;
122122
::brotensor::cuda_init();
123123
@autoreleasepool {
@@ -133,7 +133,7 @@ void pool_release(void* data_ptr) {
133133
}
134134
}
135135

136-
void metal_free(void* ptr) {
136+
void metal_free(void* ptr, int) {
137137
if (ptr) metal_impl::pool_release(ptr);
138138
}
139139

@@ -142,31 +142,60 @@ void metal_free(void* ptr) {
142142
// command buffers asynchronously (see metal_impl::submit), so each transfer
143143
// flushes first: a device->host read must observe completed GPU writes, and a
144144
// host write must not race a kernel still reading or writing the same buffer.
145-
void metal_memcpy_h2d(void* dst, const void* src, std::size_t n) {
145+
void metal_memcpy_h2d(void* dst, const void* src, std::size_t n, int) {
146146
if (!n) return;
147147
metal_impl::flush();
148148
std::memcpy(dst, src, n);
149149
}
150-
void metal_memcpy_d2h(void* dst, const void* src, std::size_t n) {
150+
void metal_memcpy_d2h(void* dst, const void* src, std::size_t n, int) {
151151
if (!n) return;
152152
metal_impl::flush();
153153
std::memcpy(dst, src, n);
154154
}
155-
void metal_memcpy_d2d(void* dst, const void* src, std::size_t n) {
155+
void metal_memcpy_d2d(void* dst, const void* src, std::size_t n, int) {
156+
if (!n) return;
157+
metal_impl::flush();
158+
std::memcpy(dst, src, n);
159+
}
160+
void metal_memcpy_peer(void* dst, int, const void* src, int, std::size_t n) {
156161
if (!n) return;
157162
metal_impl::flush();
158163
std::memcpy(dst, src, n);
159164
}
160165

161-
void metal_memset_zero(void* dst, std::size_t n) {
166+
void metal_memset_zero(void* dst, std::size_t n, int) {
162167
if (!n) return;
163168
metal_impl::flush();
164169
std::memset(dst, 0, n);
165170
}
166171

167172
// Drain the asynchronous submission queue — wait on the most recent pending
168173
// command buffer, which (serial queue) implies all earlier ones are done.
169-
void metal_sync() { metal_impl::flush(); }
174+
void metal_sync(int) { metal_impl::flush(); }
175+
176+
bool metal_mem_info(std::size_t* free_bytes, std::size_t* total_bytes, int) {
177+
@autoreleasepool {
178+
id<MTLDevice> dev = metal_impl::device();
179+
if (!dev) return false;
180+
uint64_t allocated = [dev currentAllocatedSize];
181+
uint64_t total = [dev recommendedMaxWorkingSetSize];
182+
if (free_bytes) *free_bytes = (total > allocated) ? (total - allocated) : 0;
183+
if (total_bytes) *total_bytes = total;
184+
return true;
185+
}
186+
}
187+
188+
bool metal_device_name(char* out, std::size_t cap, int) {
189+
if (!out || cap == 0) return false;
190+
@autoreleasepool {
191+
id<MTLDevice> dev = metal_impl::device();
192+
if (!dev) return false;
193+
const char* name = [[dev name] UTF8String];
194+
if (!name) return false;
195+
std::snprintf(out, cap, "%s", name);
196+
return true;
197+
}
198+
}
170199

171200
const ::brotensor::detail::AllocVTable& metal_alloc_table() {
172201
static const ::brotensor::detail::AllocVTable t = {
@@ -175,8 +204,12 @@ void metal_memset_zero(void* dst, std::size_t n) {
175204
&metal_memcpy_h2d,
176205
&metal_memcpy_d2h,
177206
&metal_memcpy_d2d,
207+
&metal_memcpy_peer,
178208
&metal_memset_zero,
179209
&metal_sync,
210+
&metal_mem_info,
211+
nullptr, // mem_trim
212+
&metal_device_name,
180213
};
181214
return t;
182215
}

0 commit comments

Comments
 (0)