6
6
#include < cstdio>
7
7
#include < iostream>
8
8
#include < map>
9
+ #include < memory>
9
10
#include < string>
10
11
#include < vector>
11
- #include < memory>
12
12
13
13
#include " ../include/ggml-cann.h"
14
14
#include " ../include/ggml.h"
15
15
16
16
#define MATRIX_ROW_PADDING 512
17
17
#define GGML_CANN_MAX_STREAMS 8
18
18
19
+ /* *
20
+ * @brief Handles CANN-related errors by printing an error message and
21
+ * terminating the program.
22
+ * @param stmt The statement that caused the error.
23
+ * @param func The function in which the error occurred.
24
+ * @param file The file in which the error occurred.
25
+ * @param line The line number at which the error occurred.
26
+ * @param msg The error message.
27
+ */
19
28
[[noreturn]] void ggml_cann_error (const char * stmt, const char * func,
20
29
const char * file, int line, const char * msg);
21
30
22
- // Error handling macro
31
+ /* *
32
+ * @brief Checks the result of a CANN function call and invokes the error
33
+ * handler if the call fails.
34
+ * @param stmt The CANN function call to check.
35
+ * @param success The success code that indicates the call was successful.
36
+ * @param error_fn The function to call to retrieve the error message.
37
+ */
23
38
#define ACL_CHECK_GEN (stmt, success, error_fn ) \
24
39
do { \
25
40
int err_code = (stmt); \
30
45
31
46
#define ACL_CHECK (stmt ) ACL_CHECK_GEN(stmt, 0 , aclGetRecentErrMsg)
32
47
48
+ /* *
49
+ * @brief Contains information about CANN devices.
50
+ */
33
51
struct ggml_cann_device_info {
52
+ /* *
53
+ * @brief Number of CANN devices available.
54
+ */
34
55
int32_t device_count;
35
56
57
+ /* *
58
+ * @brief Information about a single CANN device.
59
+ */
36
60
struct cann_device_info {
37
- int cc; // compute capability
38
- size_t smpb; // max. shared memory per block
39
- bool vmm; // virtual memory support
40
- size_t vmm_granularity; // granularity of virtual memory
41
- size_t total_vram;
61
+ int cc; /* *< Compute capability. */
62
+ size_t smpb; /* *< Maximum shared memory per block. */
63
+ bool vmm; /* *< Virtual memory support. */
64
+ size_t vmm_granularity; /* *< Granularity of virtual memory. */
65
+ size_t total_vram; /* *< Total video RAM available on the device. */
42
66
};
43
67
44
- cann_device_info devices[GGML_CANN_MAX_DEVICES] = {};
68
+ cann_device_info devices[GGML_CANN_MAX_DEVICES] =
69
+ {}; /* *< Array of CANN device information. */
45
70
};
46
71
47
72
const ggml_cann_device_info& ggml_cann_info ();
48
73
49
74
void ggml_cann_set_device (int32_t device);
50
75
int32_t ggml_cann_get_device ();
51
76
77
+ /* *
78
+ * @brief Abstract base class for memory pools used by CANN.
79
+ */
52
80
struct ggml_cann_pool {
81
+ /* *
82
+ * @brief Virtual destructor for the memory pool.
83
+ */
53
84
virtual ~ggml_cann_pool () = default ;
54
85
55
- virtual void * alloc (size_t size, size_t * actual_size) = 0;
56
- virtual void free (void * ptr, size_t size) = 0;
86
+ /* *
87
+ * @brief Allocates memory from the pool.
88
+ *
89
+ * @param size The size of the memory block to allocate.
90
+ * @param actual_size Pointer to a variable where the actual allocated size
91
+ * will be stored.
92
+ * @return Pointer to the allocated memory block.
93
+ */
94
+ virtual void * alloc (size_t size, size_t * actual_size) = 0;
95
+
96
+ /* *
97
+ * @brief Frees a previously allocated memory block.
98
+ *
99
+ * @param ptr Pointer to the memory block to free.
100
+ * @param size Size of the memory block to free.
101
+ * @note Note that all CANN opertors are running async. Make sure memory is
102
+ * still avaiable before this operator finished.
103
+ */
104
+ virtual void free (void * ptr, size_t size) = 0;
57
105
};
58
106
107
+ /* *
108
+ * @brief RAII wrapper for managing memory allocations from a CANN memory pool.
109
+ */
59
110
struct ggml_cann_pool_alloc {
60
- ggml_cann_pool * pool = nullptr ;
61
- void * ptr = nullptr ;
62
- size_t actual_size = 0 ;
111
+ ggml_cann_pool* pool = nullptr ; /* *< Pointer to the memory pool. */
112
+ void * ptr = nullptr ; /* *< Pointer to the allocated memory block. */
113
+ size_t actual_size = 0 ; /* *< Actual size of the allocated memory block. */
63
114
115
+ /* *
116
+ * @brief Default constructor.
117
+ */
64
118
ggml_cann_pool_alloc () = default ;
65
119
66
- explicit ggml_cann_pool_alloc (ggml_cann_pool & pool) : pool(&pool) {
67
- }
68
-
69
- ggml_cann_pool_alloc (ggml_cann_pool & pool, size_t size) : pool(&pool) {
120
+ /* *
121
+ * @brief Constructor that initializes the memory pool.
122
+ * @param pool Reference to the memory pool.
123
+ */
124
+ explicit ggml_cann_pool_alloc (ggml_cann_pool& pool) : pool(&pool) {}
125
+
126
+ /* *
127
+ * @brief Constructor that initializes the memory pool and allocates memory.
128
+ * @param pool Reference to the memory pool.
129
+ * @param size Size of the memory block to allocate.
130
+ */
131
+ ggml_cann_pool_alloc (ggml_cann_pool& pool, size_t size) : pool(&pool) {
70
132
alloc (size);
71
133
}
72
134
135
+ /* *
136
+ * @brief Destructor that frees the allocated memory block.
137
+ */
73
138
~ggml_cann_pool_alloc () {
74
139
if (ptr != nullptr ) {
75
140
pool->free (ptr, actual_size);
76
141
}
77
142
}
78
143
79
- // size is in number of elements
80
- void * alloc (size_t size) {
144
+ /* *
145
+ * @brief Allocates memory from the pool.
146
+ * @param size Size of the memory block to allocate.
147
+ * @return Pointer to the allocated memory block.
148
+ */
149
+ void * alloc (size_t size) {
81
150
GGML_ASSERT (pool != nullptr );
82
151
GGML_ASSERT (ptr == nullptr );
83
152
ptr = pool->alloc (size, &this ->actual_size );
84
153
return ptr;
85
154
}
86
155
87
- void * alloc (ggml_cann_pool & pool, size_t size) {
156
+ /* *
157
+ * @brief Allocates memory from a specific memory pool.
158
+ * @param pool Reference to the memory pool.
159
+ * @param size Size of the memory block to allocate.
160
+ * @return Pointer to the allocated memory block.
161
+ */
162
+ void * alloc (ggml_cann_pool& pool, size_t size) {
88
163
this ->pool = &pool;
89
164
return alloc (size);
90
165
}
91
166
92
- void * get () {
93
- return ptr;
94
- }
167
+ /* *
168
+ * @brief Gets the pointer to the allocated memory block.
169
+ * @return Pointer to the allocated memory block.
170
+ */
171
+ void * get () { return ptr; }
172
+
173
+ // Deleted copy constructor
174
+ ggml_cann_pool_alloc (const ggml_cann_pool_alloc&) = delete ;
175
+
176
+ // Deleted move constructor
177
+ ggml_cann_pool_alloc (ggml_cann_pool_alloc&&) = delete ;
95
178
96
- ggml_cann_pool_alloc (const ggml_cann_pool_alloc &) = delete ;
97
- ggml_cann_pool_alloc (ggml_cann_pool_alloc &&) = delete ;
98
- ggml_cann_pool_alloc& operator =(const ggml_cann_pool_alloc &) = delete ;
99
- ggml_cann_pool_alloc& operator =(ggml_cann_pool_alloc &&) = delete ;
179
+ // Deleted copy assignment operator
180
+ ggml_cann_pool_alloc& operator =(const ggml_cann_pool_alloc&) = delete ;
181
+
182
+ // Deleted move assignment operator
183
+ ggml_cann_pool_alloc& operator =(ggml_cann_pool_alloc&&) = delete ;
100
184
};
101
185
186
+ /* *
187
+ * @brief Context for managing CANN backend operations.
188
+ */
102
189
struct ggml_backend_cann_context {
103
- int32_t device;
104
- std::string name;
105
- aclrtEvent copy_event = nullptr ;
106
-
107
- uint64_t aclnn_workspace_size = 0 ;
108
- void * aclnn_buffer;
190
+ int32_t device; /* *< Device ID. */
191
+ std::string name; /* *< Name of the device. */
192
+ aclrtEvent copy_event = nullptr ; /* *< Event for managing copy operations. */
109
193
110
- aclrtStream streams[GGML_CANN_MAX_STREAMS] = {{nullptr }};
194
+ aclrtStream streams[GGML_CANN_MAX_STREAMS] = {
195
+ {nullptr }}; /* *< Array of streams for the device. */
111
196
197
+ /* *
198
+ * @brief Constructor for initializing the context with a given device.
199
+ * @param device Device ID.
200
+ */
112
201
explicit ggml_backend_cann_context (int device)
113
202
: device(device), name(GGML_CANN_NAME + std::to_string(device)) {}
114
203
204
+ /* *
205
+ * @brief Destructor for cleaning up resources.
206
+ */
115
207
~ggml_backend_cann_context () {
116
208
if (copy_event != nullptr ) {
117
209
ACL_CHECK (aclrtDestroyEvent (copy_event));
@@ -121,9 +213,13 @@ struct ggml_backend_cann_context {
121
213
ACL_CHECK (aclrtDestroyStream (streams[i]));
122
214
}
123
215
}
124
- aclrtFree (aclnn_buffer);
125
216
}
126
217
218
+ /* *
219
+ * @brief Get or create a stream for a given index.
220
+ * @param stream Index of the stream.
221
+ * @return The stream corresponding to the given index.
222
+ */
127
223
aclrtStream stream (int stream) {
128
224
if (streams[stream] == nullptr ) {
129
225
ggml_cann_set_device (device);
@@ -132,14 +228,29 @@ struct ggml_backend_cann_context {
132
228
return streams[stream];
133
229
}
134
230
231
+ /* *
232
+ * @brief Get or create the default stream (index 0).
233
+ * @return The default stream.
234
+ */
135
235
aclrtStream stream () { return stream (0 ); }
136
236
137
- std::unique_ptr<ggml_cann_pool> mem_pool;
237
+ // TODO: each stream should have a memory pool.
238
+ std::unique_ptr<ggml_cann_pool>
239
+ mem_pool; /* *< Memory pool for the device. */
138
240
241
+ /* *
242
+ * @brief Create a new memory pool for a given device.
243
+ * @param device Device ID.
244
+ * @return A unique pointer to the new memory pool.
245
+ */
139
246
static std::unique_ptr<ggml_cann_pool> new_pool_for_device (int device);
140
247
141
- ggml_cann_pool & pool () {
142
- if (mem_pool == nullptr ) {
248
+ /* *
249
+ * @brief Get or create the memory pool for the context.
250
+ * @return Reference to the memory pool.
251
+ */
252
+ ggml_cann_pool& pool () {
253
+ if (mem_pool == nullptr ) {
143
254
mem_pool = new_pool_for_device (device);
144
255
}
145
256
return *mem_pool;
0 commit comments