#ifndef CANN_COMMON_H
#define CANN_COMMON_H
#include <acl/acl.h>
#include <cstdio>
#include <iostream>
#include <map>
#include <memory>
#include <string>
#include <vector>
#include "../include/ggml-cann.h"
#include "../include/ggml.h"
#define MATRIX_ROW_PADDING 512
#define GGML_CANN_MAX_STREAMS 8
[[noreturn]] void ggml_cann_error(const char* stmt, const char* func,
const char* file, int line, const char* msg);
#define ACL_CHECK_GEN(stmt, success, error_fn) \
do { \
int err_code = (stmt); \
if (err_code != (success)) { \
ggml_cann_error(#stmt, __func__, __FILE__, __LINE__, error_fn()); \
} \
} while (0);
#define ACL_CHECK(stmt) ACL_CHECK_GEN(stmt, 0, aclGetRecentErrMsg)
struct ggml_cann_device_info {
int32_t device_count;
struct cann_device_info {
int cc;
size_t smpb;
bool vmm;
size_t vmm_granularity;
size_t total_vram;
};
cann_device_info devices[GGML_CANN_MAX_DEVICES] =
{};
};
const ggml_cann_device_info& ggml_cann_info();
void ggml_cann_set_device(int32_t device);
int32_t ggml_cann_get_device();
struct ggml_cann_pool {
virtual ~ggml_cann_pool() = default;
virtual void* alloc(size_t size, size_t* actual_size) = 0;
virtual void free(void* ptr, size_t size) = 0;
};
struct ggml_cann_pool_alloc {
ggml_cann_pool* pool = nullptr;
void* ptr = nullptr;
size_t actual_size = 0;
ggml_cann_pool_alloc() = default;
explicit ggml_cann_pool_alloc(ggml_cann_pool& pool) : pool(&pool) {}
ggml_cann_pool_alloc(ggml_cann_pool& pool, size_t size) : pool(&pool) {
alloc(size);
}
~ggml_cann_pool_alloc() {
if (ptr != nullptr) {
pool->free(ptr, actual_size);
}
}
void* alloc(size_t size) {
GGML_ASSERT(pool != nullptr);
GGML_ASSERT(ptr == nullptr);
ptr = pool->alloc(size, &this->actual_size);
return ptr;
}
void* alloc(ggml_cann_pool& pool, size_t size) {
this->pool = &pool;
return alloc(size);
}
void* get() { return ptr; }
ggml_cann_pool_alloc(const ggml_cann_pool_alloc&) = delete;
ggml_cann_pool_alloc(ggml_cann_pool_alloc&&) = delete;
ggml_cann_pool_alloc& operator=(const ggml_cann_pool_alloc&) = delete;
ggml_cann_pool_alloc& operator=(ggml_cann_pool_alloc&&) = delete;
};
struct ggml_backend_cann_context {
int32_t device;
std::string name;
aclrtEvent copy_event = nullptr;
aclrtStream streams[GGML_CANN_MAX_STREAMS] = {
{nullptr}};
explicit ggml_backend_cann_context(int device)
: device(device), name("CANN" + std::to_string(device)) {}
~ggml_backend_cann_context() {
if (copy_event != nullptr) {
ACL_CHECK(aclrtDestroyEvent(copy_event));
}
for (int i = 0; i < GGML_CANN_MAX_STREAMS; ++i) {
if (streams[i] != nullptr) {
ACL_CHECK(aclrtDestroyStream(streams[i]));
}
}
}
aclrtStream stream(int stream) {
if (streams[stream] == nullptr) {
ggml_cann_set_device(device);
ACL_CHECK(aclrtCreateStream(&streams[stream]));
}
return streams[stream];
}
aclrtStream stream() { return stream(0); }
std::unique_ptr<ggml_cann_pool>
mem_pool;
static std::unique_ptr<ggml_cann_pool> new_pool_for_device(int device);
ggml_cann_pool& pool() {
if (mem_pool == nullptr) {
mem_pool = new_pool_for_device(device);
}
return *mem_pool;
}
};
#endif