reformat
This commit is contained in:
parent
13dc3a02c3
commit
58cec14092
2 changed files with 203 additions and 252 deletions
|
@ -1,39 +1,39 @@
|
||||||
|
#include "ggml-qnn.h"
|
||||||
|
|
||||||
|
#include <stdatomic.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdatomic.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <set>
|
|
||||||
#include <tuple>
|
|
||||||
#include <queue>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <chrono>
|
|
||||||
#include <memory>
|
|
||||||
#include <regex>
|
|
||||||
#include <random>
|
|
||||||
#include <functional>
|
|
||||||
#include <condition_variable>
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <chrono>
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <iostream>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
#include <random>
|
||||||
|
#include <regex>
|
||||||
|
#include <set>
|
||||||
|
#include <sstream>
|
||||||
|
#include <thread>
|
||||||
|
#include <tuple>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
#include <vector>
|
||||||
#include "ggml-qnn.h"
|
|
||||||
|
|
||||||
#include "ggml-backend-impl.h"
|
#include "ggml-backend-impl.h"
|
||||||
|
|
||||||
#include "ggml-qnn/logger.hpp"
|
|
||||||
#include "ggml-qnn/utils.hpp"
|
|
||||||
#include "ggml-qnn/tensor.hpp"
|
|
||||||
#include "ggml-qnn/backend.hpp"
|
|
||||||
#include "ggml-qnn/backend-ops.hpp"
|
#include "ggml-qnn/backend-ops.hpp"
|
||||||
|
#include "ggml-qnn/backend.hpp"
|
||||||
|
#include "ggml-qnn/logger.hpp"
|
||||||
|
#include "ggml-qnn/tensor.hpp"
|
||||||
|
#include "ggml-qnn/utils.hpp"
|
||||||
|
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
//
|
//
|
||||||
|
@ -57,28 +57,16 @@ static int free_qnn_tensor(Qnn_Tensor_t & tensor);
|
||||||
|
|
||||||
static struct qnn::qcom_socinfo g_qnn_soc_info_table[] = {
|
static struct qnn::qcom_socinfo g_qnn_soc_info_table[] = {
|
||||||
/* Qualcomm SnapDragon 8 Gen 1 */
|
/* Qualcomm SnapDragon 8 Gen 1 */
|
||||||
[qnn::SM8450] = {
|
[qnn::SM8450] = { .soc_model = qnn::SM8450, .htp_arch = qnn::V69, .vtcm_size_in_mb = 8 },
|
||||||
.soc_model = qnn::SM8450,
|
|
||||||
.htp_arch = qnn::V69,
|
|
||||||
.vtcm_size_in_mb = 8},
|
|
||||||
|
|
||||||
/* Qualcomm SnapDragon 8 Gen 1+ */
|
/* Qualcomm SnapDragon 8 Gen 1+ */
|
||||||
[qnn::SM8475] = {
|
[qnn::SM8475] = { .soc_model = qnn::SM8475, .htp_arch = qnn::V69, .vtcm_size_in_mb = 8 },
|
||||||
.soc_model = qnn::SM8475,
|
|
||||||
.htp_arch = qnn::V69,
|
|
||||||
.vtcm_size_in_mb = 8},
|
|
||||||
|
|
||||||
/* Qualcomm SnapDragon 8 Gen 2 */
|
/* Qualcomm SnapDragon 8 Gen 2 */
|
||||||
[qnn::SM8550] = {
|
[qnn::SM8550] = { .soc_model = qnn::SM8550, .htp_arch = qnn::V73, .vtcm_size_in_mb = 8 },
|
||||||
.soc_model = qnn::SM8550,
|
|
||||||
.htp_arch = qnn::V73,
|
|
||||||
.vtcm_size_in_mb = 8},
|
|
||||||
|
|
||||||
/* Qualcomm SnapDragon 8 Gen 3 */
|
/* Qualcomm SnapDragon 8 Gen 3 */
|
||||||
[qnn::SM8650] = {
|
[qnn::SM8650] = { .soc_model = qnn::SM8650, .htp_arch = qnn::V75, .vtcm_size_in_mb = 8 },
|
||||||
.soc_model = qnn::SM8650,
|
|
||||||
.htp_arch = qnn::V75,
|
|
||||||
.vtcm_size_in_mb = 8},
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -128,9 +116,7 @@ static struct ggml_backend_qnn_context g_qnn_mgr[GGML_QNN_MAX_DEVICES] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ggml_backend_qnn_buffer_context {
|
struct ggml_backend_qnn_buffer_context {
|
||||||
ggml_backend_qnn_buffer_context(size_t device)
|
ggml_backend_qnn_buffer_context(size_t device) : device(device), name(QNN_BACKEND_NAME + std::to_string(device)) {}
|
||||||
: device(device)
|
|
||||||
, name(QNN_BACKEND_NAME + std::to_string(device)) {}
|
|
||||||
|
|
||||||
~ggml_backend_qnn_buffer_context() {
|
~ggml_backend_qnn_buffer_context() {
|
||||||
if (buffer) {
|
if (buffer) {
|
||||||
|
@ -185,8 +171,7 @@ static int deep_copy_qnn_tensors(Qnn_Tensor_t & src, Qnn_Tensor_t & dst) {
|
||||||
VALIDATE_TENSOR_VERSION(src, err);
|
VALIDATE_TENSOR_VERSION(src, err);
|
||||||
|
|
||||||
dst.version = src.version;
|
dst.version = src.version;
|
||||||
QNN_TENSOR_SET_NAME(
|
QNN_TENSOR_SET_NAME(dst, ::strndup(QNN_TENSOR_GET_NAME(src), std::string(QNN_TENSOR_GET_NAME(src)).size()));
|
||||||
dst, ::strndup(QNN_TENSOR_GET_NAME(src),std::string(QNN_TENSOR_GET_NAME(src)).size()));
|
|
||||||
if (nullptr == QNN_TENSOR_GET_NAME(dst)) {
|
if (nullptr == QNN_TENSOR_GET_NAME(dst)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -213,9 +198,7 @@ static int deep_copy_qnn_tensors(Qnn_Tensor_t & src, Qnn_Tensor_t & dst) {
|
||||||
Qnn_ScaleOffset_t **scaleOffset = &axis_scale_offset.scaleOffset;
|
Qnn_ScaleOffset_t **scaleOffset = &axis_scale_offset.scaleOffset;
|
||||||
size_t scaleOffsetSize = axis_scale_offset.numScaleOffsets * sizeof(Qnn_ScaleOffset_t);
|
size_t scaleOffsetSize = axis_scale_offset.numScaleOffsets * sizeof(Qnn_ScaleOffset_t);
|
||||||
*scaleOffset = (Qnn_ScaleOffset_t *)malloc(scaleOffsetSize);
|
*scaleOffset = (Qnn_ScaleOffset_t *)malloc(scaleOffsetSize);
|
||||||
memscpy(*scaleOffset, scaleOffsetSize,
|
memscpy(*scaleOffset, scaleOffsetSize, src_qparam.axisScaleOffsetEncoding.scaleOffset, scaleOffsetSize);
|
||||||
src_qparam.axisScaleOffsetEncoding.scaleOffset,
|
|
||||||
scaleOffsetSize);
|
|
||||||
QNN_TENSOR_SET_QUANT_PARAMS(dst, src_qparam_cpy);
|
QNN_TENSOR_SET_QUANT_PARAMS(dst, src_qparam_cpy);
|
||||||
} else if (encoding == QNN_QUANTIZATION_ENCODING_BW_AXIS_SCALE_OFFSET) {
|
} else if (encoding == QNN_QUANTIZATION_ENCODING_BW_AXIS_SCALE_OFFSET) {
|
||||||
Qnn_QuantizeParams_t src_qparam_cpy = src_qparam;
|
Qnn_QuantizeParams_t src_qparam_cpy = src_qparam;
|
||||||
|
@ -224,14 +207,12 @@ static int deep_copy_qnn_tensors(Qnn_Tensor_t & src, Qnn_Tensor_t & dst) {
|
||||||
float **scales = &bwaxis_scale_offset.scales;
|
float **scales = &bwaxis_scale_offset.scales;
|
||||||
int32_t **offsets = &bwaxis_scale_offset.offsets;
|
int32_t **offsets = &bwaxis_scale_offset.offsets;
|
||||||
*scales = (float *)malloc(scaleSize);
|
*scales = (float *)malloc(scaleSize);
|
||||||
memscpy(*scales, scaleSize, src_qparam.bwAxisScaleOffsetEncoding.scales,
|
memscpy(*scales, scaleSize, src_qparam.bwAxisScaleOffsetEncoding.scales, scaleSize);
|
||||||
scaleSize);
|
|
||||||
|
|
||||||
if (bwaxis_scale_offset.offsets != nullptr) {
|
if (bwaxis_scale_offset.offsets != nullptr) {
|
||||||
size_t offsetSize = bwaxis_scale_offset.numElements * sizeof(int32_t);
|
size_t offsetSize = bwaxis_scale_offset.numElements * sizeof(int32_t);
|
||||||
*offsets = (int32_t *)malloc(offsetSize);
|
*offsets = (int32_t *)malloc(offsetSize);
|
||||||
memscpy(*offsets, offsetSize,
|
memscpy(*offsets, offsetSize, src_qparam.bwAxisScaleOffsetEncoding.offsets, offsetSize);
|
||||||
src_qparam.bwAxisScaleOffsetEncoding.offsets, offsetSize);
|
|
||||||
}
|
}
|
||||||
QNN_TENSOR_SET_QUANT_PARAMS(dst, src_qparam_cpy);
|
QNN_TENSOR_SET_QUANT_PARAMS(dst, src_qparam_cpy);
|
||||||
} else {
|
} else {
|
||||||
|
@ -243,7 +224,8 @@ static int deep_copy_qnn_tensors(Qnn_Tensor_t & src, Qnn_Tensor_t & dst) {
|
||||||
size_t dim_size = rank * sizeof(uint32_t);
|
size_t dim_size = rank * sizeof(uint32_t);
|
||||||
uint32_t *dimensions = (uint32_t *)malloc(dim_size);
|
uint32_t *dimensions = (uint32_t *)malloc(dim_size);
|
||||||
if (dimensions == nullptr) {
|
if (dimensions == nullptr) {
|
||||||
QNN_LOG_WARN("deep_copy_qnn_tensors() allocation error while copying "
|
QNN_LOG_WARN(
|
||||||
|
"deep_copy_qnn_tensors() allocation error while copying "
|
||||||
"tensor %s\n",
|
"tensor %s\n",
|
||||||
QNN_TENSOR_GET_NAME(src));
|
QNN_TENSOR_GET_NAME(src));
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -269,8 +251,7 @@ static int free_qnn_tensor(Qnn_Tensor_t & tensor) {
|
||||||
// implementation of QNN backend for GGML
|
// implementation of QNN backend for GGML
|
||||||
//
|
//
|
||||||
// =================================================================================================
|
// =================================================================================================
|
||||||
static bool ggml_qnn_can_handle_op(ggml_backend_qnn_context * ctx,
|
static bool ggml_qnn_can_handle_op(ggml_backend_qnn_context *ctx, const struct ggml_tensor *tensor,
|
||||||
const struct ggml_tensor * tensor,
|
|
||||||
bool b_dump_tensor_info) {
|
bool b_dump_tensor_info) {
|
||||||
if (ggml_is_empty(tensor) || !qnn::ggml_qnn_op_array()[tensor->op]) {
|
if (ggml_is_empty(tensor) || !qnn::ggml_qnn_op_array()[tensor->op]) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -353,8 +334,7 @@ GGML_CALL static void * ggml_backend_qnn_buffer_get_base(ggml_backend_buffer_t b
|
||||||
return ctx->buffer;
|
return ctx->buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static void ggml_backend_qnn_buffer_init_tensor(ggml_backend_buffer_t buffer,
|
GGML_CALL static void ggml_backend_qnn_buffer_init_tensor(ggml_backend_buffer_t buffer, ggml_tensor *tensor) {
|
||||||
ggml_tensor * tensor) {
|
|
||||||
Qnn_ErrorHandle_t error = QNN_SUCCESS;
|
Qnn_ErrorHandle_t error = QNN_SUCCESS;
|
||||||
ggml_backend_qnn_buffer_context *ctx = (ggml_backend_qnn_buffer_context *)buffer->context;
|
ggml_backend_qnn_buffer_context *ctx = (ggml_backend_qnn_buffer_context *)buffer->context;
|
||||||
|
|
||||||
|
@ -362,11 +342,9 @@ GGML_CALL static void ggml_backend_qnn_buffer_init_tensor(ggml_backend_buffer_t
|
||||||
char tensor_name[GGML_MAX_NAME] = { 0 };
|
char tensor_name[GGML_MAX_NAME] = { 0 };
|
||||||
snprintf(tensor_name, GGML_MAX_NAME, "tensor_%04d", idx++);
|
snprintf(tensor_name, GGML_MAX_NAME, "tensor_%04d", idx++);
|
||||||
|
|
||||||
uint32_t dimensions[] = {(uint32_t) tensor->ne[0], (uint32_t) tensor->ne[1],
|
uint32_t dimensions[] = { (uint32_t)tensor->ne[0], (uint32_t)tensor->ne[1], (uint32_t)tensor->ne[2],
|
||||||
(uint32_t) tensor->ne[2],
|
|
||||||
(uint32_t)tensor->ne[3] };
|
(uint32_t)tensor->ne[3] };
|
||||||
Qnn_DataType_t qnn_data_type =
|
Qnn_DataType_t qnn_data_type = qnn::datatype_from_ggml_datatype(tensor->type);
|
||||||
qnn::datatype_from_ggml_datatype(tensor->type);
|
|
||||||
Qnn_TensorType_t qnn_tensor_type = QNN_TENSOR_TYPE_APP_WRITE;
|
Qnn_TensorType_t qnn_tensor_type = QNN_TENSOR_TYPE_APP_WRITE;
|
||||||
|
|
||||||
if (tensor->flags & GGML_TENSOR_FLAG_INPUT) {
|
if (tensor->flags & GGML_TENSOR_FLAG_INPUT) {
|
||||||
|
@ -381,25 +359,22 @@ GGML_CALL static void ggml_backend_qnn_buffer_init_tensor(ggml_backend_buffer_t
|
||||||
qnn_mem_type = QNN_TENSORMEMTYPE_MEMHANDLE;
|
qnn_mem_type = QNN_TENSORMEMTYPE_MEMHANDLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
qnn_tensor = {
|
qnn_tensor = { .version = QNN_TENSOR_VERSION_1,
|
||||||
.version = QNN_TENSOR_VERSION_1,
|
{ .v1 = {
|
||||||
{.v1 = {.id = 0,
|
.id = 0,
|
||||||
.name = tensor_name,
|
.name = tensor_name,
|
||||||
.type = qnn_tensor_type,
|
.type = qnn_tensor_type,
|
||||||
.dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER,
|
.dataFormat = QNN_TENSOR_DATA_FORMAT_FLAT_BUFFER,
|
||||||
.dataType = qnn_data_type,
|
.dataType = qnn_data_type,
|
||||||
.quantizeParams =
|
.quantizeParams = { QNN_DEFINITION_UNDEFINED,
|
||||||
{QNN_DEFINITION_UNDEFINED,
|
|
||||||
QNN_QUANTIZATION_ENCODING_UNDEFINED,
|
QNN_QUANTIZATION_ENCODING_UNDEFINED,
|
||||||
{.scaleOffsetEncoding = {.scale = 0.0000000000000000f,
|
{ .scaleOffsetEncoding = { .scale = 0.0000000000000000f, .offset = 0 } } },
|
||||||
.offset = 0}}},
|
|
||||||
.rank = qnn::get_ggml_tensor_rank(tensor),
|
.rank = qnn::get_ggml_tensor_rank(tensor),
|
||||||
.dimensions = dimensions,
|
.dimensions = dimensions,
|
||||||
.memType = qnn_mem_type,
|
.memType = qnn_mem_type,
|
||||||
{ .clientBuf = { .data = nullptr, .dataSize = 0 } } } } };
|
{ .clientBuf = { .data = nullptr, .dataSize = 0 } } } } };
|
||||||
|
|
||||||
Qnn_Tensor_t * p_qnn_tensor =
|
Qnn_Tensor_t *p_qnn_tensor = (Qnn_Tensor_t *)calloc(1, sizeof(Qnn_Tensor_t));
|
||||||
(Qnn_Tensor_t *)calloc(1, sizeof(Qnn_Tensor_t));
|
|
||||||
if (nullptr == p_qnn_tensor) {
|
if (nullptr == p_qnn_tensor) {
|
||||||
QNN_LOG_WARN("calloc failed");
|
QNN_LOG_WARN("calloc failed");
|
||||||
return;
|
return;
|
||||||
|
@ -414,23 +389,20 @@ GGML_CALL static void ggml_backend_qnn_buffer_init_tensor(ggml_backend_buffer_t
|
||||||
ctx->qnn_tensors.push_back(p_qnn_tensor);
|
ctx->qnn_tensors.push_back(p_qnn_tensor);
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static void ggml_backend_qnn_buffer_set_tensor(ggml_backend_buffer_t buffer,
|
GGML_CALL static void ggml_backend_qnn_buffer_set_tensor(ggml_backend_buffer_t buffer, ggml_tensor *tensor,
|
||||||
ggml_tensor * tensor, const void * data,
|
const void *data, size_t offset, size_t size) {
|
||||||
size_t offset, size_t size) {
|
|
||||||
GGML_UNUSED(buffer);
|
GGML_UNUSED(buffer);
|
||||||
|
|
||||||
memcpy((char *)tensor->data + offset, data, size);
|
memcpy((char *)tensor->data + offset, data, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static void ggml_backend_qnn_buffer_get_tensor(ggml_backend_buffer_t buffer,
|
GGML_CALL static void ggml_backend_qnn_buffer_get_tensor(ggml_backend_buffer_t buffer, const ggml_tensor *tensor,
|
||||||
const ggml_tensor * tensor, void * data,
|
void *data, size_t offset, size_t size) {
|
||||||
size_t offset, size_t size) {
|
|
||||||
GGML_UNUSED(buffer);
|
GGML_UNUSED(buffer);
|
||||||
memcpy(data, (const char *)tensor->data + offset, size);
|
memcpy(data, (const char *)tensor->data + offset, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static bool ggml_backend_qnn_buffer_cpy_tensor(ggml_backend_buffer_t buffer,
|
GGML_CALL static bool ggml_backend_qnn_buffer_cpy_tensor(ggml_backend_buffer_t buffer, const struct ggml_tensor *src,
|
||||||
const struct ggml_tensor * src,
|
|
||||||
struct ggml_tensor *dst) {
|
struct ggml_tensor *dst) {
|
||||||
GGML_UNUSED(buffer);
|
GGML_UNUSED(buffer);
|
||||||
if (ggml_backend_buffer_is_host(src->buffer)) {
|
if (ggml_backend_buffer_is_host(src->buffer)) {
|
||||||
|
@ -459,9 +431,7 @@ static ggml_backend_buffer_i ggml_backend_qnn_buffer_interface = {
|
||||||
/* .reset = */ nullptr,
|
/* .reset = */ nullptr,
|
||||||
};
|
};
|
||||||
|
|
||||||
GGML_CALL static const char * ggml_backend_qnn_buffer_type_name(ggml_backend_buffer_type_t buft) {
|
GGML_CALL static const char *ggml_backend_qnn_buffer_type_name(ggml_backend_buffer_type_t buft) { return "QNN"; }
|
||||||
return "QNN";
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *ggml_qnn_host_malloc(size_t n) {
|
static void *ggml_qnn_host_malloc(size_t n) {
|
||||||
void *data = nullptr;
|
void *data = nullptr;
|
||||||
|
@ -474,8 +444,8 @@ static void * ggml_qnn_host_malloc(size_t n) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static ggml_backend_buffer_t ggml_backend_qnn_buffer_type_alloc_buffer(
|
GGML_CALL static ggml_backend_buffer_t ggml_backend_qnn_buffer_type_alloc_buffer(ggml_backend_buffer_type_t buft,
|
||||||
ggml_backend_buffer_type_t buft, size_t size) {
|
size_t size) {
|
||||||
ggml_backend_qnn_buffer_type_context *buft_ctx = (ggml_backend_qnn_buffer_type_context *)buft->context;
|
ggml_backend_qnn_buffer_type_context *buft_ctx = (ggml_backend_qnn_buffer_type_context *)buft->context;
|
||||||
ggml_backend_qnn_buffer_context *ctx = new ggml_backend_qnn_buffer_context(buft_ctx->device);
|
ggml_backend_qnn_buffer_context *ctx = new ggml_backend_qnn_buffer_context(buft_ctx->device);
|
||||||
|
|
||||||
|
@ -500,8 +470,7 @@ GGML_CALL static ggml_backend_buffer_t ggml_backend_qnn_buffer_type_alloc_buffer
|
||||||
return ggml_backend_buffer_init(buft, ggml_backend_qnn_buffer_interface, ctx, size);
|
return ggml_backend_buffer_init(buft, ggml_backend_qnn_buffer_interface, ctx, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static size_t ggml_backend_qnn_buffer_type_get_alignment(
|
GGML_CALL static size_t ggml_backend_qnn_buffer_type_get_alignment(ggml_backend_buffer_type_t buft) {
|
||||||
ggml_backend_buffer_type_t buft) {
|
|
||||||
GGML_UNUSED(buft);
|
GGML_UNUSED(buft);
|
||||||
return 32;
|
return 32;
|
||||||
}
|
}
|
||||||
|
@ -518,9 +487,7 @@ GGML_CALL static bool ggml_backend_qnn_buffer_is_host(ggml_backend_buffer_type_t
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static const char * ggml_backend_qnn_name(ggml_backend_t backend) {
|
GGML_CALL static const char *ggml_backend_qnn_name(ggml_backend_t backend) { return "QNN"; }
|
||||||
return "QNN";
|
|
||||||
}
|
|
||||||
|
|
||||||
GGML_CALL static void ggml_backend_qnn_free(ggml_backend_t backend) {
|
GGML_CALL static void ggml_backend_qnn_free(ggml_backend_t backend) {
|
||||||
QNN_LOG_INFO("enter %s", __func__);
|
QNN_LOG_INFO("enter %s", __func__);
|
||||||
|
@ -560,9 +527,8 @@ GGML_CALL static ggml_status ggml_backend_qnn_graph_compute(ggml_backend_t backe
|
||||||
|
|
||||||
for (int i = 0; i < cgraph->n_nodes; i++) {
|
for (int i = 0; i < cgraph->n_nodes; i++) {
|
||||||
ggml_tensor *node = cgraph->nodes[i];
|
ggml_tensor *node = cgraph->nodes[i];
|
||||||
if (ggml_is_empty(node) || node->op == GGML_OP_RESHAPE ||
|
if (ggml_is_empty(node) || node->op == GGML_OP_RESHAPE || node->op == GGML_OP_TRANSPOSE ||
|
||||||
node->op == GGML_OP_TRANSPOSE || node->op == GGML_OP_VIEW ||
|
node->op == GGML_OP_VIEW || node->op == GGML_OP_PERMUTE || node->op == GGML_OP_NONE) {
|
||||||
node->op == GGML_OP_PERMUTE || node->op == GGML_OP_NONE) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bool ok = ggml_qnn_compute_forward(ctx, node);
|
bool ok = ggml_qnn_compute_forward(ctx, node);
|
||||||
|
@ -574,8 +540,7 @@ GGML_CALL static ggml_status ggml_backend_qnn_graph_compute(ggml_backend_t backe
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
GGML_CALL static bool ggml_backend_qnn_supports_op(ggml_backend_t backend,
|
GGML_CALL static bool ggml_backend_qnn_supports_op(ggml_backend_t backend, const ggml_tensor *op) {
|
||||||
const ggml_tensor * op) {
|
|
||||||
ggml_backend_qnn_context *ctx = (ggml_backend_qnn_context *)backend->context;
|
ggml_backend_qnn_context *ctx = (ggml_backend_qnn_context *)backend->context;
|
||||||
|
|
||||||
return (ggml_qnn_can_handle_op(ctx, op, false));
|
return (ggml_qnn_can_handle_op(ctx, op, false));
|
||||||
|
@ -611,10 +576,8 @@ static ggml_backend_i ggml_backend_qnn_interface = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static ggml_guid_t ggml_backend_qnn_guid() {
|
static ggml_guid_t ggml_backend_qnn_guid() {
|
||||||
static ggml_guid guid = {
|
static ggml_guid guid = { 0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81,
|
||||||
0x1a, 0x2b, 0x3c, 0x4d, 0x5e, 0x6f, 0x70, 0x81,
|
0x92, 0xa3, 0xb4, 0xc5, 0xd6, 0xe7, 0xf8, 0x09 };
|
||||||
0x92, 0xa3, 0xb4, 0xc5, 0xd6, 0xe7, 0xf8, 0x09
|
|
||||||
};
|
|
||||||
return &guid;
|
return &guid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -641,13 +604,9 @@ void ggml_backend_qnn_set_n_threads(ggml_backend_t backend, int n_threads) {
|
||||||
ctx->threads = n_threads;
|
ctx->threads = n_threads;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * ggml_backend_qnn_get_name(ggml_backend_t backend) {
|
const char *ggml_backend_qnn_get_name(ggml_backend_t backend) { return backend->iface.get_name(backend); }
|
||||||
return backend->iface.get_name(backend);
|
|
||||||
}
|
|
||||||
|
|
||||||
int ggml_backend_qnn_get_device_count() {
|
int ggml_backend_qnn_get_device_count() { return GGML_QNN_MAX_DEVICES; }
|
||||||
return GGML_QNN_MAX_DEVICES;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ggml_backend_qnn_get_device_description(size_t dev_num, char *description, size_t description_size) {
|
void ggml_backend_qnn_get_device_description(size_t dev_num, char *description, size_t description_size) {
|
||||||
if (nullptr == description || 0 == description_size) {
|
if (nullptr == description || 0 == description_size) {
|
||||||
|
@ -665,7 +624,8 @@ void ggml_backend_qnn_get_device_description(size_t dev_num, char * description,
|
||||||
|
|
||||||
ggml_backend_buffer_type_t ggml_backend_qnn_buffer_type(size_t device) {
|
ggml_backend_buffer_type_t ggml_backend_qnn_buffer_type(size_t device) {
|
||||||
if (device >= GGML_QNN_MAX_DEVICES) {
|
if (device >= GGML_QNN_MAX_DEVICES) {
|
||||||
QNN_LOG_DEBUG("ggml_backend_qnn_buffer_type error: device_index:%d is "
|
QNN_LOG_DEBUG(
|
||||||
|
"ggml_backend_qnn_buffer_type error: device_index:%d is "
|
||||||
"out of range [0, %d]\n",
|
"out of range [0, %d]\n",
|
||||||
device, GGML_QNN_MAX_DEVICES - 1);
|
device, GGML_QNN_MAX_DEVICES - 1);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -679,14 +639,12 @@ ggml_backend_buffer_type_t ggml_backend_qnn_buffer_type(size_t device) {
|
||||||
auto &context = ggml_backend_qnn_buffer_type_contexts[i];
|
auto &context = ggml_backend_qnn_buffer_type_contexts[i];
|
||||||
context = { i, std::string(QNN_BACKEND_NAME) + std::to_string(i) };
|
context = { i, std::string(QNN_BACKEND_NAME) + std::to_string(i) };
|
||||||
ggml_backend_qnn_buffer_types[i] = {
|
ggml_backend_qnn_buffer_types[i] = {
|
||||||
/* .iface = */ {
|
/* .iface = */ { /* .get_name = */ ggml_backend_qnn_buffer_type_name,
|
||||||
/* .get_name = */ ggml_backend_qnn_buffer_type_name,
|
|
||||||
/* .alloc_buffer = */ ggml_backend_qnn_buffer_type_alloc_buffer,
|
/* .alloc_buffer = */ ggml_backend_qnn_buffer_type_alloc_buffer,
|
||||||
/* .get_alignment = */ ggml_backend_qnn_buffer_type_get_alignment,
|
/* .get_alignment = */ ggml_backend_qnn_buffer_type_get_alignment,
|
||||||
/* .get_max_size = */ ggml_backend_qnn_buffer_type_get_max_size,
|
/* .get_max_size = */ ggml_backend_qnn_buffer_type_get_max_size,
|
||||||
/* .get_alloc_size = */ nullptr, // defaults to ggml_nbytes
|
/* .get_alloc_size = */ nullptr, // defaults to ggml_nbytes
|
||||||
/* .is_host = */ ggml_backend_qnn_buffer_is_host
|
/* .is_host = */ ggml_backend_qnn_buffer_is_host },
|
||||||
},
|
|
||||||
/* .context = */ &context,
|
/* .context = */ &context,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -729,8 +687,7 @@ ggml_backend_t ggml_backend_qnn_init(size_t device, const char * qnn_lib_path) {
|
||||||
QNN_LOG_ERROR("QNN NPU backend setenv failure");
|
QNN_LOG_ERROR("QNN NPU backend setenv failure");
|
||||||
}
|
}
|
||||||
if (0 == setenv("ADSP_LIBRARY_PATH",
|
if (0 == setenv("ADSP_LIBRARY_PATH",
|
||||||
(path +
|
(path + ";/vendor/dsp/cdsp;/vendor/lib/rfsa/adsp;/system/lib/"
|
||||||
";/vendor/dsp/cdsp;/vendor/lib/rfsa/adsp;/system/lib/"
|
|
||||||
"rfsa/adsp;/vendor/dsp/dsp;/vendor/dsp/images;/dsp")
|
"rfsa/adsp;/vendor/dsp/dsp;/vendor/dsp/images;/dsp")
|
||||||
.c_str(),
|
.c_str(),
|
||||||
1)) {
|
1)) {
|
||||||
|
@ -740,20 +697,16 @@ ggml_backend_t ggml_backend_qnn_init(size_t device, const char * qnn_lib_path) {
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (0 == setenv("LD_LIBRARY_PATH", path.c_str(), 1)) {
|
if (0 == setenv("LD_LIBRARY_PATH", path.c_str(), 1)) {
|
||||||
QNN_LOG_INFO("%s backend setenv successfully\n",
|
QNN_LOG_INFO("%s backend setenv successfully\n", qnn::get_backend_name(device));
|
||||||
qnn::get_backend_name(device));
|
|
||||||
} else {
|
} else {
|
||||||
QNN_LOG_ERROR("%s backend setenv failure\n",
|
QNN_LOG_ERROR("%s backend setenv failure\n", qnn::get_backend_name(device));
|
||||||
qnn::get_backend_name(device));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *instance = new qnn::qnn_instance(qnn_lib_path, g_qnn_mgr[device].lib, "");
|
auto *instance = new qnn::qnn_instance(qnn_lib_path, g_qnn_mgr[device].lib, "");
|
||||||
result = instance->qnn_init(nullptr);
|
result = instance->qnn_init(nullptr);
|
||||||
if (0 != result) {
|
if (0 != result) {
|
||||||
QNN_LOG_WARN(
|
QNN_LOG_WARN("init qnn subsystem failed with qnn backend %s, pls check why\n", qnn::get_backend_name(device));
|
||||||
"init qnn subsystem failed with qnn backend %s, pls check why\n",
|
|
||||||
qnn::get_backend_name(device));
|
|
||||||
delete instance;
|
delete instance;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -771,8 +724,7 @@ ggml_backend_t ggml_backend_qnn_init(size_t device, const char * qnn_lib_path) {
|
||||||
g_qnn_mgr[device].raw_system_interface = instance->get_qnn_raw_system_interface();
|
g_qnn_mgr[device].raw_system_interface = instance->get_qnn_raw_system_interface();
|
||||||
g_qnn_mgr[device].socinfo = instance->get_soc_info();
|
g_qnn_mgr[device].socinfo = instance->get_soc_info();
|
||||||
|
|
||||||
ggml_backend_t qnn_backend =
|
ggml_backend_t qnn_backend = new ggml_backend{ /* .guid = */ ggml_backend_qnn_guid(),
|
||||||
new ggml_backend{/* .guid = */ ggml_backend_qnn_guid(),
|
|
||||||
/* .iface = */ ggml_backend_qnn_interface,
|
/* .iface = */ ggml_backend_qnn_interface,
|
||||||
/* .context = */ &g_qnn_mgr[device] };
|
/* .context = */ &g_qnn_mgr[device] };
|
||||||
g_qnn_mgr[device].backend = qnn_backend;
|
g_qnn_mgr[device].backend = qnn_backend;
|
||||||
|
@ -786,8 +738,7 @@ GGML_CALL int ggml_backend_qnn_reg_devices() {
|
||||||
for (size_t idx = 0; idx < GGML_QNN_MAX_DEVICES; idx++) {
|
for (size_t idx = 0; idx < GGML_QNN_MAX_DEVICES; idx++) {
|
||||||
char name[GGML_MAX_NAME];
|
char name[GGML_MAX_NAME];
|
||||||
ggml_backend_qnn_get_device_description(idx, name, GGML_MAX_NAME);
|
ggml_backend_qnn_get_device_description(idx, name, GGML_MAX_NAME);
|
||||||
ggml_backend_register(name, ggml_backend_qnn_reg_init,
|
ggml_backend_register(name, ggml_backend_qnn_reg_init, ggml_backend_qnn_buffer_type(idx),
|
||||||
ggml_backend_qnn_buffer_type(idx),
|
|
||||||
(void *)(intptr_t)idx);
|
(void *)(intptr_t)idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ Fn load_qnn_functionpointers(void *handle, const char *function_name) {
|
||||||
return reinterpret_cast<Fn>(dlsym(handle, function_name));
|
return reinterpret_cast<Fn>(dlsym(handle, function_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int validate_tensor_version(Qnn_Tensor_t tensor) {
|
inline int validate_tensor_version(const Qnn_Tensor_t &tensor) {
|
||||||
if (tensor.version != QNN_TENSOR_VERSION_1) {
|
if (tensor.version != QNN_TENSOR_VERSION_1) {
|
||||||
QNN_LOG_WARN("validate_tensor_version() tensor %s, got unsupported version %d\n", tensor.v1.name,
|
QNN_LOG_WARN("validate_tensor_version() tensor %s, got unsupported version %d\n", tensor.v1.name,
|
||||||
tensor.version);
|
tensor.version);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue