Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 19 additions & 3 deletions ggml/src/ggml-hrx/dispatch_registration/common/dispatch-copy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,17 @@ static bool match_copy_f32_dispatch(const DispatchMatchContext & context, Dispat
return true;
}

static bool match_cont_f32_dispatch(const DispatchMatchContext & context, DispatchMatch & match) {
static bool match_cont_or_dup_f32_dispatch(const DispatchMatchContext & context, DispatchMatch & match) {
const GraphNode * node = context.root_node;
if (node == nullptr || node->op != GGML_OP_CONT || node->inputs.size() != 1) {
if (node == nullptr) {
return false;
}
const bool is_cont = node->op == GGML_OP_CONT;
const bool is_dup = node->op == GGML_OP_DUP;
const bool is_copy = is_cont || is_dup;
const bool has_source = node->inputs.size() == 1;
const bool matches = is_copy && has_source;
if (!matches) {
return false;
}

Expand Down Expand Up @@ -216,7 +224,15 @@ void register_copy_dispatch(DispatchRegistryBuilder & registry) {
DispatchMatchKind::SingleOp,
0,
DispatchSource::Common,
match_cont_f32_dispatch,
match_cont_or_dup_f32_dispatch,
});
registry.add({
"common.dup_f32",
GGML_OP_DUP,
DispatchMatchKind::SingleOp,
0,
DispatchSource::Common,
match_cont_or_dup_f32_dispatch,
});
registry.add({
"common.concat_dim0_f32",
Expand Down
17 changes: 17 additions & 0 deletions ggml/src/ggml-hrx/ggml-hrx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1032,6 +1032,23 @@ static bool device_supports_op(ggml_backend_dev_t device, const ggml_tensor * op
if (zero_output_elision_supported(op)) {
return true;
}
if (op->op == GGML_OP_DUP) {
const ggml_tensor * source = op->src[0];
if (source == nullptr) {
return false;
}
const bool source_f32 = source->type == GGML_TYPE_F32;
const bool output_f32 = op->type == GGML_TYPE_F32;
const bool source_contiguous = ggml_is_contiguous(source);
const bool output_contiguous = ggml_is_contiguous(op);
const bool same_shape = ggml_are_same_shape(source, op);
const bool separate_output = op->view_src == nullptr;
const int64_t elements = ggml_nelements(op);
const bool nonempty = elements > 0;
const bool bounded = elements <= (int64_t{ 1 } << 30);
return source_f32 && output_f32 && source_contiguous && output_contiguous && same_shape &&
separate_output && nonempty && bounded;
}
const bool supported_binary = supported_binary_f32_tensor(op);
if (supported_binary) {
return true;
Expand Down
10 changes: 9 additions & 1 deletion tests/hrx-ops-test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3639,6 +3639,8 @@ static void run_dynamic_generic_ops_cpu_reference_case() {
ggml_tensor * hrx_copy_target = ggml_new_tensor_1d(hrx_ctx, GGML_TYPE_F32, element_count);
ggml_tensor * cpu_copy = ggml_cpy(cpu_ctx, cpu_input, cpu_copy_target);
ggml_tensor * hrx_copy = ggml_cpy(hrx_ctx, hrx_input, hrx_copy_target);
ggml_tensor * cpu_dup = ggml_dup(cpu_ctx, cpu_input);
ggml_tensor * hrx_dup = ggml_dup(hrx_ctx, hrx_input);
ggml_tensor * cpu_concat_lhs = ggml_new_tensor_2d(cpu_ctx, GGML_TYPE_F32, 64, 7);
ggml_tensor * cpu_concat_rhs = ggml_new_tensor_2d(cpu_ctx, GGML_TYPE_F32, 32, 7);
ggml_tensor * hrx_concat_lhs = ggml_new_tensor_2d(hrx_ctx, GGML_TYPE_F32, 64, 7);
Expand All @@ -3647,20 +3649,25 @@ static void run_dynamic_generic_ops_cpu_reference_case() {
ggml_tensor * hrx_concat = ggml_concat(hrx_ctx, hrx_concat_lhs, hrx_concat_rhs, 0);
REQUIRE(cpu_unary != nullptr && hrx_unary != nullptr);
REQUIRE(cpu_copy != nullptr && hrx_copy != nullptr);
REQUIRE(cpu_dup != nullptr);
REQUIRE(hrx_dup != nullptr);
REQUIRE(ggml_backend_supports_op(hrx_backend, hrx_dup));
REQUIRE(cpu_concat != nullptr && hrx_concat != nullptr);

ggml_cgraph * cpu_graph = ggml_new_graph(cpu_ctx);
ggml_cgraph * hrx_graph = ggml_new_graph(hrx_ctx);
REQUIRE(cpu_graph != nullptr && hrx_graph != nullptr);
ggml_build_forward_expand(cpu_graph, cpu_unary);
ggml_build_forward_expand(cpu_graph, cpu_copy);
ggml_build_forward_expand(cpu_graph, cpu_dup);
ggml_build_forward_expand(cpu_graph, cpu_concat);
ggml_build_forward_expand(hrx_graph, hrx_unary);
ggml_build_forward_expand(hrx_graph, hrx_copy);
ggml_build_forward_expand(hrx_graph, hrx_dup);
ggml_build_forward_expand(hrx_graph, hrx_concat);

require_kernel_subsequence(scheduled_kernel_sequence(hrx_graph),
{ "loom_libs:ggml_unary_f32", "loom_libs:ggml_copy_f32",
{ "loom_libs:ggml_unary_f32", "loom_libs:ggml_copy_f32", "loom_libs:ggml_copy_f32",
"loom_libs:ggml_concat_dim0_f32" });
for (const char * kernel_name :
{ "loom_libs:ggml_unary_f32", "loom_libs:ggml_copy_f32", "loom_libs:ggml_concat_dim0_f32" }) {
Expand All @@ -3687,6 +3694,7 @@ static void run_dynamic_generic_ops_cpu_reference_case() {
ggml_backend_synchronize(hrx_backend);
require_close(get_f32_tensor(hrx_backend, hrx_unary), get_f32_tensor(cpu_backend, cpu_unary), 0.0f);
require_close(get_f32_tensor(hrx_backend, hrx_copy), get_f32_tensor(cpu_backend, cpu_copy), 0.0f);
require_close(get_f32_tensor(hrx_backend, hrx_dup), get_f32_tensor(cpu_backend, cpu_dup), 0.0f);
require_close(get_f32_tensor(hrx_backend, hrx_concat), get_f32_tensor(cpu_backend, cpu_concat), 0.0f);

ggml_backend_buffer_free(cpu_buffer);
Expand Down
Loading