mirror of
https://github.com/leejet/stable-diffusion.cpp.git
synced 2026-11-11 03:24:30 +00:00
perf: optimize Vulkan kernels, graph fusion, and workspace reuse (#2251)
This commit is contained in:
1 parent
e239e4b0fd
commit
0a067120b3
6 files changed
+89
-17
No files matched your search
@@ -92,7 +92,8 @@ namespace sd {
|
||||
ComputeWorkspace::Measurement ComputeWorkspace::measure(
|
||||
ggml_cgraph* graph,
|
||||
const std::function<ggml_backend_t(const ggml_tensor*)>& external_backend,
|
||||
const AssignNodes& assign_nodes) {
|
||||
const AssignNodes& assign_nodes,
|
||||
bool cache_measurement) {
|
||||
std::vector<const ggml_tensor*> tensors;
|
||||
std::unordered_set<const ggml_tensor*> seen;
|
||||
auto visit = [&](const ggml_tensor* tensor) {
|
||||
@@ -112,6 +113,52 @@ namespace sd {
|
||||
visit(source);
|
||||
}
|
||||
}
|
||||
std::vector<uint8_t> key;
|
||||
if (cache_measurement) {
|
||||
key.reserve(tensors.size() * sizeof(ggml_tensor));
|
||||
auto append = [&](const auto& value) {
|
||||
const auto* bytes = reinterpret_cast<const uint8_t*>(&value);
|
||||
key.insert(key.end(), bytes, bytes + sizeof(value));
|
||||
};
|
||||
append(graph->n_nodes);
|
||||
append(graph->n_leafs);
|
||||
append(graph->order);
|
||||
for (auto tensor : tensors) {
|
||||
append(tensor);
|
||||
append(tensor->type);
|
||||
append(tensor->ne);
|
||||
append(tensor->nb);
|
||||
append(tensor->op);
|
||||
append(tensor->op_params);
|
||||
append(tensor->flags);
|
||||
append(tensor->src);
|
||||
append(tensor->view_src);
|
||||
append(tensor->view_offs);
|
||||
append(tensor->name);
|
||||
const auto external = external_backend(tensor);
|
||||
append(external);
|
||||
if (external == nullptr || tensor->view_src != nullptr) {
|
||||
append(tensor->buffer);
|
||||
append(tensor->data);
|
||||
append(tensor->extra);
|
||||
if (tensor->buffer != nullptr) {
|
||||
const auto usage = ggml_backend_buffer_get_usage(tensor->buffer);
|
||||
const auto type = ggml_backend_buffer_get_type(tensor->buffer);
|
||||
append(usage);
|
||||
append(type);
|
||||
}
|
||||
}
|
||||
const size_t index = ggml_hash_find(&graph->visited_hash_set, tensor);
|
||||
const int32_t uses = index != GGML_HASHSET_FULL && ggml_bitset_get(graph->visited_hash_set.used, index)
|
||||
? graph->use_counts[index]
|
||||
: 0;
|
||||
append(uses);
|
||||
}
|
||||
// Match the full allocation metadata, including topology and external placement.
|
||||
if (key == measurement_key_) {
|
||||
return {measured_buffers_};
|
||||
}
|
||||
}
|
||||
const size_t graph_size = tensors.size() + 8;
|
||||
auto context = ggml_init({tensors.size() * ggml_tensor_overhead() + ggml_graph_overhead_custom(graph_size, false), nullptr, true});
|
||||
if (context == nullptr) {
|
||||
@@ -178,6 +225,10 @@ namespace sd {
|
||||
ggml_backend_buffer_free(entry.second);
|
||||
}
|
||||
ggml_free(context);
|
||||
if (cache_measurement && !result.buffers.empty()) {
|
||||
measurement_key_ = std::move(key);
|
||||
measured_buffers_ = result.buffers;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -212,6 +263,8 @@ namespace sd {
|
||||
if (active_) {
|
||||
return false;
|
||||
}
|
||||
measurement_key_.clear();
|
||||
measured_buffers_.clear();
|
||||
ggml_backend_sched_free(scheduler_);
|
||||
scheduler_ = nullptr;
|
||||
scheduler_capacity_ = 0;
|
||||
|
||||
Reference in new issue
Block a user