Skip to content

Commit eef7dc2

Browse files
authored
refactor(qwen3.5): register stateful GDN runtime ops (#704)
* refactor(qwen3.5): register stateful GDN runtime ops * test(cpu): align GDN kernels with unified suite * test(cpu): expose GDN kernel case matrices * fix(test): avoid cross-running Android test binaries
1 parent ea8fa36 commit eef7dc2

33 files changed

Lines changed: 716 additions & 211 deletions

mllm/backends/cpu/CPUBackend.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "mllm/backends/cpu/ops/FlashAttn2WithSinkAndSwaOp.hpp"
2626
#include "mllm/backends/cpu/ops/GELUOp.hpp"
2727
#include "mllm/backends/cpu/ops/GatherOp.hpp"
28+
#include "mllm/backends/cpu/ops/GatedDeltaRuleOp.hpp"
2829
#include "mllm/backends/cpu/ops/GroupedQueryAttentionOp.hpp"
2930
#include "mllm/backends/cpu/ops/InterpolateOp.hpp"
3031
#include "mllm/backends/cpu/ops/LayerNorm2DOp.hpp"
@@ -86,7 +87,7 @@ CPUBackend::CPUBackend() : Backend(kCPU, createCPUAllocator()) {
8687
CPUConv2DOpFactory, CPULayerNorm2DOpFactory, CPUInterpolateOpFactory, CPUPadOpFactory, CPUMaskedScatterOpFactory,
8788
CPUArgsortOpFactory, CPUCloneOpFactory, CPUAvgPool1dOpFactory, CPUFlashAttention2SwaSinkOpFactory,
8889
CPURadixAttnRelaxOpFactory, CPURadixAttnSwaSinkOpFactory, CPUEqualOpFactory, CPUWhereOpFactory,
89-
CPUGatherOpFactory, CPUCausalDepthwiseConv1DOpFactory,
90+
CPUGatherOpFactory, CPUCausalDepthwiseConv1DOpFactory, CPUGatedDeltaRuleOpFactory,
9091
CPUGroupedQueryAttentionOpFactory, CPUParallelLinearOpFactory>();
9192
}
9293

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Copyright (c) MLLM Team.
2+
// Licensed under the MIT License.
3+
4+
#include "mllm/backends/cpu/ops/GatedDeltaRuleOp.hpp"
5+
6+
#include <cstring>
7+
8+
#include "mllm/backends/cpu/kernels/common/gdn/gated_delta_net.hpp"
9+
#include "mllm/utils/Common.hpp"
10+
11+
namespace mllm::cpu {
12+
13+
CPUGatedDeltaRuleOp::CPUGatedDeltaRuleOp(const aops::GatedDeltaRuleOpOptions& options) : aops::GatedDeltaRuleOp(options) {}
14+
15+
void CPUGatedDeltaRuleOp::forward(const std::vector<Tensor>& inputs, std::vector<Tensor>& outputs) {
16+
for (const auto& input : inputs) { MLLM_RT_ASSERT(input.isContiguous()); }
17+
const auto& q = inputs[0];
18+
const auto& v = inputs[2];
19+
auto& output = outputs[0];
20+
auto& updated_state = outputs[1];
21+
if (!options_.state_inplace) { std::memcpy(updated_state.ptr<float>(), inputs[7].ptr<float>(), inputs[7].bytes()); }
22+
gdn::gatedDeltaRuleF32(inputs[0].ptr<float>(), inputs[1].ptr<float>(), inputs[2].ptr<float>(), inputs[3].ptr<float>(),
23+
inputs[4].ptr<float>(), inputs[5].ptr<float>(), inputs[6].ptr<float>(), updated_state.ptr<float>(),
24+
output.ptr<float>(), q.shape()[0], q.shape()[1], q.shape()[2], v.shape()[2], q.shape()[3],
25+
v.shape()[3], options_.getThreads());
26+
}
27+
28+
} // namespace mllm::cpu
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Copyright (c) MLLM Team.
2+
// Licensed under the MIT License.
3+
4+
#pragma once
5+
6+
#include "mllm/core/aops/GatedDeltaRuleOp.hpp"
7+
8+
namespace mllm::cpu {
9+
10+
class CPUGatedDeltaRuleOp final : public aops::GatedDeltaRuleOp {
11+
public:
12+
explicit CPUGatedDeltaRuleOp(const aops::GatedDeltaRuleOpOptions& options);
13+
void forward(const std::vector<Tensor>& inputs, std::vector<Tensor>& outputs) override;
14+
};
15+
16+
class CPUGatedDeltaRuleOpFactory : public TypedOpFactory<OpTypes::kGatedDeltaRule, aops::GatedDeltaRuleOpOptions> {
17+
protected:
18+
std::shared_ptr<BaseOp> createOpImpl(const aops::GatedDeltaRuleOpOptions& options) override {
19+
return std::make_shared<CPUGatedDeltaRuleOp>(options);
20+
}
21+
};
22+
23+
} // namespace mllm::cpu

mllm/compile/ir/GeneratedRTTIKind.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ enum NodeKind : uint32_t {
4444
RK_Op_LinalgIROp_CausalDepthwiseConv1DOp,
4545
RK_Op_LinalgIROp_GroupedQueryAttentionOp,
4646
RK_Op_LinalgIROp_ParallelLinearOp,
47+
RK_Op_LinalgIROp_GatedDeltaRuleOp,
4748
RK_Op_LinalgIROp_RepeatOp,
4849
RK_Op_LinalgIROp_PermuteOp,
4950
RK_Op_LinalgIROp_Conv1DOp,

mllm/compile/ir/NodeRTTIClassOfImpl.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ struct NodeRTTIClassOfImpl {
104104
#define RTTI_RK_OP_LINALGIROP_PARALLELLINEAROP_IMPL(v) \
105105
return (v)->getKind() >= RK_Op_LinalgIROp_ParallelLinearOp && (v)->getKind() <= RK_Op_LinalgIROp_ParallelLinearOp
106106

107+
#define RTTI_RK_OP_LINALGIROP_GATEDDELTARULEOP_IMPL(v) \
108+
return (v)->getKind() >= RK_Op_LinalgIROp_GatedDeltaRuleOp && (v)->getKind() <= RK_Op_LinalgIROp_GatedDeltaRuleOp
109+
107110
#define RTTI_RK_OP_LINALGIROP_REPEATOP_IMPL(v) \
108111
return (v)->getKind() >= RK_Op_LinalgIROp_RepeatOp && (v)->getKind() <= RK_Op_LinalgIROp_RepeatOp
109112

mllm/compile/ir/linalg/Op.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ LINALG_AOPS_DECL(OpTypes::kFlashAttention2, FlashAttention2Op);
6969
LINALG_AOPS_DECL(OpTypes::kCausalDepthwiseConv1D, CausalDepthwiseConv1DOp);
7070
LINALG_AOPS_DECL(OpTypes::kGroupedQueryAttention, GroupedQueryAttentionOp);
7171
LINALG_AOPS_DECL(OpTypes::kParallelLinear, ParallelLinearOp);
72+
LINALG_AOPS_DECL(OpTypes::kGatedDeltaRule, GatedDeltaRuleOp);
7273
LINALG_AOPS_DECL(OpTypes::kRepeat, RepeatOp);
7374
LINALG_AOPS_DECL(OpTypes::kPermute, PermuteOp);
7475

mllm/compile/ir/linalg/Op.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ class FlashAttention2Op;
3838
class CausalDepthwiseConv1DOp;
3939
class GroupedQueryAttentionOp;
4040
class ParallelLinearOp;
41+
class GatedDeltaRuleOp;
4142
class RepeatOp;
4243
class PermuteOp;
4344
class Conv1DOp;
@@ -203,6 +204,7 @@ LINALG_AOPS_DEFINE(FlashAttention2Op, FLASHATTENTION2OP);
203204
LINALG_AOPS_DEFINE(CausalDepthwiseConv1DOp, CAUSALDEPTHWISECONV1DOP);
204205
LINALG_AOPS_DEFINE(GroupedQueryAttentionOp, GROUPEDQUERYATTENTIONOP);
205206
LINALG_AOPS_DEFINE(ParallelLinearOp, PARALLELLINEAROP);
207+
LINALG_AOPS_DEFINE(GatedDeltaRuleOp, GATEDDELTARULEOP);
206208
LINALG_AOPS_DEFINE(RepeatOp, REPEATOP);
207209
LINALG_AOPS_DEFINE(PermuteOp, PERMUTEOP);
208210

mllm/compile/ir/rtti_kind_gen.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,7 @@ def define_lianlg_ir(ir: dict):
250250
op.derive(Cls("CausalDepthwiseConv1DOp"))
251251
op.derive(Cls("GroupedQueryAttentionOp"))
252252
op.derive(Cls("ParallelLinearOp"))
253+
op.derive(Cls("GatedDeltaRuleOp"))
253254
op.derive(Cls("RepeatOp"))
254255
op.derive(Cls("PermuteOp"))
255256
op.derive(Cls("Conv1DOp"))

mllm/compile/jit/binary/LinalgIRSerialization.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "mllm/core/aops/CausalDepthwiseConv1DOp.hpp"
1515
#include "mllm/core/aops/GroupedQueryAttentionOp.hpp"
1616
#include "mllm/core/aops/ParallelLinearOp.hpp"
17+
#include "mllm/core/aops/GatedDeltaRuleOp.hpp"
1718
#include "mllm/core/aops/KVCacheOp.hpp"
1819
#include "mllm/core/aops/MultimodalRoPEOp.hpp"
1920
#include "mllm/core/aops/VisionRoPEOp.hpp"
@@ -75,6 +76,7 @@ nlohmann::json dumpLinalgIROptions(const ir::linalg::LinalgIROp::ptr_t& op) {
7576
CASE(CausalDepthwiseConv1D)
7677
CASE(GroupedQueryAttention)
7778
CASE(ParallelLinear)
79+
CASE(GatedDeltaRule)
7880
CASE(Repeat)
7981
CASE(Permute)
8082
CASE(Conv1D)
@@ -155,6 +157,11 @@ nlohmann::json dumpCausalDepthwiseConv1DOpIROptions(const ir::linalg::LinalgIROp
155157
{"accumulation_order", aops::causalDepthwiseConv1DAccumulationOrder2Str(options.accumulation_order)}};
156158
}
157159

160+
nlohmann::json dumpGatedDeltaRuleOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op) {
161+
const auto options = static_cast<aops::GatedDeltaRuleOp*>(op->getAOp())->options();
162+
return {{"state_inplace", options.state_inplace}};
163+
}
164+
158165
nlohmann::json dumpGroupedQueryAttentionOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op) {
159166
const auto options = static_cast<aops::GroupedQueryAttentionOp*>(op->getAOp())->options();
160167
return {{"implementation", aops::groupedQueryAttentionImplementation2Str(options.implementation)}};

mllm/compile/jit/binary/LinalgIRSerialization.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ nlohmann::json dumpFlashAttention2OpIROptions(const ir::linalg::LinalgIROp::ptr_
4040
nlohmann::json dumpCausalDepthwiseConv1DOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op);
4141
nlohmann::json dumpGroupedQueryAttentionOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op);
4242
nlohmann::json dumpParallelLinearOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op);
43+
nlohmann::json dumpGatedDeltaRuleOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op);
4344
nlohmann::json dumpRepeatOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op);
4445
nlohmann::json dumpPermuteOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op);
4546
nlohmann::json dumpConv1DOpIROptions(const ir::linalg::LinalgIROp::ptr_t& op);

0 commit comments

Comments
 (0)