2023-12-01 03:12:53 +08:00
|
|
|
// Copyright © 2023 Apple Inc.
|
|
|
|
|
2023-11-30 02:30:41 +08:00
|
|
|
#include <cstdlib>
|
|
|
|
#include <sstream>
|
|
|
|
|
|
|
|
#include "mlx/allocator.h"
|
|
|
|
#include "mlx/scheduler.h"
|
|
|
|
|
|
|
|
namespace mlx::core::allocator {
|
|
|
|
|
|
|
|
Buffer malloc(size_t size) {
|
2024-01-03 03:59:19 +08:00
|
|
|
auto buffer = allocator().malloc(size, /* allow_swap */ true);
|
2023-11-30 02:30:41 +08:00
|
|
|
if (size && !buffer.ptr()) {
|
|
|
|
std::ostringstream msg;
|
|
|
|
msg << "[malloc] Unable to allocate " << size << " bytes.";
|
|
|
|
throw std::runtime_error(msg.str());
|
|
|
|
}
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
void free(Buffer buffer) {
|
2024-11-19 11:17:01 +08:00
|
|
|
allocator().free(buffer);
|
2023-11-30 02:30:41 +08:00
|
|
|
}
|
|
|
|
|
2024-01-03 03:59:19 +08:00
|
|
|
Buffer CommonAllocator::malloc(size_t size, bool) {
|
2024-09-12 12:02:16 +08:00
|
|
|
void* ptr = std::malloc(size + sizeof(size_t));
|
|
|
|
if (ptr != nullptr) {
|
|
|
|
*static_cast<size_t*>(ptr) = size;
|
|
|
|
}
|
|
|
|
return Buffer{ptr};
|
2023-11-30 02:30:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void CommonAllocator::free(Buffer buffer) {
|
2024-09-12 12:02:16 +08:00
|
|
|
std::free(buffer.ptr());
|
|
|
|
}
|
|
|
|
|
|
|
|
size_t CommonAllocator::size(Buffer buffer) const {
|
|
|
|
if (buffer.ptr() == nullptr) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return *static_cast<size_t*>(buffer.ptr());
|
2023-11-30 02:30:41 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
Buffer malloc_or_wait(size_t size) {
|
|
|
|
auto buffer = allocator().malloc(size);
|
|
|
|
|
|
|
|
while (size && !buffer.ptr() && scheduler::n_active_tasks() > 0) {
|
|
|
|
scheduler::wait_for_one();
|
|
|
|
buffer = allocator().malloc(size);
|
|
|
|
}
|
|
|
|
|
2024-01-03 03:59:19 +08:00
|
|
|
// Try swapping if needed
|
|
|
|
if (size && !buffer.ptr()) {
|
|
|
|
buffer = allocator().malloc(size, /* allow_swap = */ true);
|
|
|
|
}
|
|
|
|
|
2023-11-30 02:30:41 +08:00
|
|
|
if (size && !buffer.ptr()) {
|
|
|
|
std::ostringstream msg;
|
|
|
|
msg << "[malloc_or_wait] Unable to allocate " << size << " bytes.";
|
|
|
|
throw std::runtime_error(msg.str());
|
|
|
|
}
|
|
|
|
|
|
|
|
return buffer;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace mlx::core::allocator
|