FEAT: improve debug capability

This commit is contained in:
Yu, Zijun 2025-04-30 13:40:43 +08:00 committed by Mustafa Cavus
parent 0a8cc9ab03
commit 7d5e234254
5 changed files with 42 additions and 16 deletions

View File

@ -1,6 +1,6 @@
#pragma once #pragma once
#include <unordered_map> #include <map>
#include "openvino/core/node.hpp" #include "openvino/core/node.hpp"
#include "openvino/frontend/decoder.hpp" #include "openvino/frontend/decoder.hpp"
@ -57,8 +57,8 @@ public:
virtual bool check_if_continuous() const = 0; virtual bool check_if_continuous() const = 0;
virtual const std::unordered_map<std::string, std::shared_ptr<ov::Node>>& get_model_inputs() const = 0; virtual const std::map<std::string, std::shared_ptr<ov::Node>>& get_model_inputs() const = 0;
virtual const std::unordered_map<std::string, std::shared_ptr<ov::Node>>& get_model_weights() const = 0; virtual const std::map<std::string, std::shared_ptr<ov::Node>>& get_model_weights() const = 0;
virtual const std::vector<std::string>& get_model_output_names() const = 0; virtual const std::vector<std::string>& get_model_output_names() const = 0;
}; };

View File

@ -8,12 +8,14 @@
#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iomanip> #include <iomanip>
#include <map>
#include <memory> #include <memory>
#include <openvino/core/node.hpp> #include <openvino/core/node.hpp>
#include <openvino/core/type/float16.hpp> #include <openvino/core/type/float16.hpp>
#include <openvino/op/constant.hpp> #include <openvino/op/constant.hpp>
#include <ostream>
#include <set>
#include <string> #include <string>
#include <unordered_map>
#include "ggml-backend-impl.h" #include "ggml-backend-impl.h"
#include "ggml-backend.h" #include "ggml-backend.h"
@ -22,16 +24,24 @@ GgmlOvDecoder::GgmlOvDecoder(struct ggml_tensor* node, struct ggml_cgraph* cgrap
: m_cgraph(cgraph), : m_cgraph(cgraph),
m_node(node), m_node(node),
m_op_name(m_node ? std::string(m_node->name) : "NONE_OP") { m_op_name(m_node ? std::string(m_node->name) : "NONE_OP") {
static std::unordered_map<std::string, std::shared_ptr<ov::Node>> model_weights; static std::map<std::string, std::shared_ptr<ov::Node>> model_weights;
if (m_node) { if (m_node) {
set_input_output(m_node, model_weights); set_input_output(m_node, model_weights);
} else { } else {
static bool printed = false;
if (!printed && getenv("GGML_OPENVINO_PRINT_CGRAPH_TENSOR_ADDRESS")) {
print_tensor_address_map(m_cgraph);
printed = true;
}
for (int node_n = 0; node_n < m_cgraph->n_nodes; node_n++) { for (int node_n = 0; node_n < m_cgraph->n_nodes; node_n++) {
auto* cur_node = m_cgraph->nodes[node_n]; auto* cur_node = m_cgraph->nodes[node_n];
m_nodes.push_back(cur_node); m_nodes.push_back(cur_node);
set_input_output(cur_node, model_weights); set_input_output(cur_node, model_weights);
} }
m_model_weights = model_weights; m_model_weights = model_weights;
if (getenv("GGML_OPENVINO_DUMP_CGRAPH")) { if (getenv("GGML_OPENVINO_DUMP_CGRAPH")) {
dump_cgraph(m_cgraph); dump_cgraph(m_cgraph);
} }
@ -41,7 +51,7 @@ GgmlOvDecoder::GgmlOvDecoder(struct ggml_tensor* node, struct ggml_cgraph* cgrap
// Called in GgmlOvDecoder constructor. Two cases: 1. constructing a decoder for the whole graph; // Called in GgmlOvDecoder constructor. Two cases: 1. constructing a decoder for the whole graph;
// 2. constructing a decoder for a node. // 2. constructing a decoder for a node.
void GgmlOvDecoder::set_input_output(ggml_tensor* node, void GgmlOvDecoder::set_input_output(ggml_tensor* node,
std::unordered_map<std::string, std::shared_ptr<ov::Node>>& model_weights) { std::map<std::string, std::shared_ptr<ov::Node>>& model_weights) {
std::string node_name; std::string node_name;
if (node->op == GGML_OP_CPY) { if (node->op == GGML_OP_CPY) {
// CPY updates the input tensor in place. For later ov op that uses the // CPY updates the input tensor in place. For later ov op that uses the
@ -100,9 +110,10 @@ void GgmlOvDecoder::set_input_output(ggml_tensor* node,
} }
if (!m_node) { if (!m_node) {
static std::set<std::string> debug_output_names = {};
// Workaround: the final tensor "result_output" does not have GGML_TENSOR_FLAG_OUTPUT flag set in cgraph // Workaround: the final tensor "result_output" does not have GGML_TENSOR_FLAG_OUTPUT flag set in cgraph
if (node->buffer->usage == GGML_BACKEND_BUFFER_USAGE_ANY || node->flags & GGML_TENSOR_FLAG_OUTPUT || if (node->buffer->usage == GGML_BACKEND_BUFFER_USAGE_ANY || node->flags & GGML_TENSOR_FLAG_OUTPUT ||
std::string(node->name).find("result") == 0) { std::string(node->name).find("result") == 0 || debug_output_names.count(node->name)) {
auto name = node->view_src ? std::string(node->view_src->name) : std::string(node->name); auto name = node->view_src ? std::string(node->view_src->name) : std::string(node->name);
if (node->buffer->usage == GGML_BACKEND_BUFFER_USAGE_ANY) { if (node->buffer->usage == GGML_BACKEND_BUFFER_USAGE_ANY) {
assert(name.find("cache_k") == 0 || name.find("cache_v") == 0); assert(name.find("cache_k") == 0 || name.find("cache_v") == 0);
@ -249,7 +260,7 @@ void GgmlOvDecoder::dump_cgraph(const struct ggml_cgraph* cgraph) {
void print_tensor_address_map(const struct ggml_cgraph* cgraph) { void print_tensor_address_map(const struct ggml_cgraph* cgraph) {
std::map<void*, std::vector<std::string>> address_map; std::map<void*, std::vector<std::string>> address_map;
for (int node_n = 0; node_n <= cgraph->n_nodes; node_n++) { for (int node_n = 0; node_n < cgraph->n_nodes; node_n++) {
auto* node = cgraph->nodes[node_n]; auto* node = cgraph->nodes[node_n];
if (node->data) { if (node->data) {
auto it = address_map.find(node->data); auto it = address_map.find(node->data);

View File

@ -1,7 +1,7 @@
#pragma once #pragma once
#include <map>
#include <memory> #include <memory>
#include <unordered_map>
#include <vector> #include <vector>
#include "decoder.h" #include "decoder.h"
@ -76,10 +76,10 @@ public:
return m_continuous; return m_continuous;
} }
virtual const std::unordered_map<std::string, std::shared_ptr<ov::Node>>& get_model_inputs() const override { virtual const std::map<std::string, std::shared_ptr<ov::Node>>& get_model_inputs() const override {
return m_model_inputs; return m_model_inputs;
} }
virtual const std::unordered_map<std::string, std::shared_ptr<ov::Node>>& get_model_weights() const override { virtual const std::map<std::string, std::shared_ptr<ov::Node>>& get_model_weights() const override {
return m_model_weights; return m_model_weights;
} }
virtual const std::vector<std::string>& get_model_output_names() const override { virtual const std::vector<std::string>& get_model_output_names() const override {
@ -87,7 +87,7 @@ public:
} }
private: private:
void set_input_output(ggml_tensor* node, std::unordered_map<std::string, std::shared_ptr<ov::Node>>& model_weights); void set_input_output(ggml_tensor* node, std::map<std::string, std::shared_ptr<ov::Node>>& model_weights);
static void dump_cgraph(const struct ggml_cgraph* cgraph); static void dump_cgraph(const struct ggml_cgraph* cgraph);
static std::vector<size_t> get_shape(const ggml_tensor* tensor); static std::vector<size_t> get_shape(const ggml_tensor* tensor);
static std::vector<size_t> get_stride(const ggml_tensor* tensor); static std::vector<size_t> get_stride(const ggml_tensor* tensor);
@ -105,7 +105,9 @@ private:
mutable std::string m_name; mutable std::string m_name;
bool m_continuous; bool m_continuous;
std::vector<std::pair<std::string, std::string>> m_op_node_name; std::vector<std::pair<std::string, std::string>> m_op_node_name;
std::unordered_map<std::string, std::shared_ptr<ov::Node>> m_model_inputs; std::map<std::string, std::shared_ptr<ov::Node>> m_model_inputs;
std::unordered_map<std::string, std::shared_ptr<ov::Node>> m_model_weights; std::map<std::string, std::shared_ptr<ov::Node>> m_model_weights;
std::vector<std::string> m_model_output_names; std::vector<std::string> m_model_output_names;
}; };
void print_tensor_address_map(const struct ggml_cgraph* cgraph);

View File

@ -135,10 +135,12 @@ enum ggml_status openvino_frontend_compute(ggml_backend_t backend, struct ggml_c
<< ", Address: " << output_tensors[output_names[i]] << std::endl; << ", Address: " << output_tensors[output_names[i]] << std::endl;
switch (output_tensor.get_element_type()) { switch (output_tensor.get_element_type()) {
case ov::element::f32: case ov::element::f32:
std::cout << *(float*)(output_tensors[output_names[i]]) << std::endl; std::cout << *(float*)(output_tensor.data()) << std::endl;
std::cout << checksum(output_tensor.data(), output_tensor.get_byte_size()) << std::endl;
break; break;
case ov::element::f16: case ov::element::f16:
std::cout << ov::float16::from_bits(*(uint16_t*)(output_tensors[output_names[i]])) << std::endl; std::cout << ov::float16::from_bits(*(uint16_t*)(output_tensor.data())) << std::endl;
std::cout << checksum(output_tensor.data(), output_tensor.get_byte_size()) << std::endl;
break; break;
default: default:
break; break;
@ -161,3 +163,12 @@ enum ggml_status openvino_frontend_compute(ggml_backend_t backend, struct ggml_c
return GGML_STATUS_SUCCESS; return GGML_STATUS_SUCCESS;
GGML_UNUSED(backend); GGML_UNUSED(backend);
} }
size_t checksum(const void* data, size_t size) {
const uint8_t* bytes = static_cast<const uint8_t*>(data);
size_t sum = 0;
for (size_t i = 0; i < size; ++i) {
sum += bytes[i];
}
return sum;
}

View File

@ -2,3 +2,5 @@
#include "ggml-backend-impl.h" #include "ggml-backend-impl.h"
enum ggml_status openvino_frontend_compute(ggml_backend_t backend, struct ggml_cgraph* cgraph); enum ggml_status openvino_frontend_compute(ggml_backend_t backend, struct ggml_cgraph* cgraph);
size_t checksum(const void* data, size_t size);