MLX
 
Loading...
Searching...
No Matches
allocator.h
Go to the documentation of this file.
1// Copyright © 2023-2024 Apple Inc.
2
3#pragma once
4
5#include <map>
6#include <mutex>
7#include <vector>
8
9#include "mlx/allocator.h"
12
14
16
17namespace {
18
19class BufferCache {
20 public:
21 BufferCache(MTL::Device* device);
22 ~BufferCache();
23
24 MTL::Buffer* reuse_from_cache(size_t size);
25 void recycle_to_cache(MTL::Buffer* buf);
26 int release_cached_buffers(size_t min_bytes_to_free);
27 size_t cache_size() {
28 return pool_size_;
29 }
30 int clear();
31
32 private:
33 struct BufferHolder {
34 public:
35 BufferHolder(MTL::Buffer* buf_) : buf(buf_), prev(nullptr), next(nullptr) {}
36
37 BufferHolder* prev;
38 BufferHolder* next;
39 MTL::Buffer* buf;
40 };
41
42 void add_at_head(BufferHolder* to_add);
43 void remove_from_list(BufferHolder* to_remove);
44
45 MTL::Device* device_;
46 MTL::Heap* heap_{nullptr};
47
48 std::multimap<size_t, BufferHolder*> buffer_pool_;
49 BufferHolder* head_;
50 BufferHolder* tail_;
51 size_t pool_size_;
52};
53
54} // namespace
55
56class MetalAllocator : public allocator::Allocator {
58 public:
59 virtual Buffer malloc(size_t size, bool allow_swap = false) override;
60 virtual void free(Buffer buffer) override;
61 virtual size_t size(Buffer buffer) const override;
63 return active_memory_;
64 };
65 size_t get_peak_memory() {
66 return peak_memory_;
67 };
69 std::unique_lock lk(mutex_);
70 peak_memory_ = 0;
71 };
73 return buffer_cache_.cache_size();
74 };
75 size_t set_cache_limit(size_t limit);
76 size_t set_memory_limit(size_t limit, bool relaxed);
77 size_t set_wired_limit(size_t limit);
79
80 private:
81 MTL::Device* device_;
82
83 // The size of allocations which go on the heap until it is full. This size
84 // is chosen because it is the actual minimum size of a buffer allocated from
85 // the heap, a heap can have at most heap.size() / 256 buffers.
86 static constexpr int small_size_ = 256;
87 static constexpr int heap_size_ = 1 << 20;
88 MTL::Heap* heap_;
89 MetalAllocator();
90 ~MetalAllocator();
91 friend MetalAllocator& allocator();
92
93 // Caching allocator
94 BufferCache buffer_cache_;
95
96 ResidencySet residency_set_;
97
98 // Allocation stats
99 size_t block_limit_;
100 size_t gc_limit_;
101 size_t active_memory_{0};
102 size_t peak_memory_{0};
103 size_t max_pool_size_;
104 size_t wired_limit_{0};
105 bool relaxed_{true};
106 size_t num_resources_{0};
107 size_t resource_limit_{0};
108
109 std::mutex mutex_;
110};
111
113
114} // namespace mlx::core::metal
Definition allocator.h:39
Definition allocator.h:12
Definition allocator.h:56
virtual void free(Buffer buffer) override
size_t set_memory_limit(size_t limit, bool relaxed)
void reset_peak_memory()
Definition allocator.h:68
virtual size_t size(Buffer buffer) const override
virtual Buffer malloc(size_t size, bool allow_swap=false) override
Allocator for Metal GPUs.
size_t get_active_memory()
Definition allocator.h:62
size_t set_wired_limit(size_t limit)
size_t get_peak_memory()
Definition allocator.h:65
size_t get_cache_memory()
Definition allocator.h:72
size_t set_cache_limit(size_t limit)
friend MetalAllocator & allocator()
Definition resident.h:9
Definition allocator.h:13
MetalAllocator & allocator()
Device & device(mlx::core::Device)