1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
// RLX — versatile ML compiler + runtime.
// Copyright (C) 2026 Eugene Hauptmann, Nataliya Kosmyna.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 3.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
//! **MIR** — mid-level IR.
//!
//! The fused, backend-neutral tensor DAG that [`rlx_opt`] runs fusion,
//! precision, and legalization passes on. Today MIR is structurally
//! identical to [`Graph`]; the newtype marks pipeline stage and gives
//! us room to attach MIR-only metadata later (alias sets, layout hints).
use crate::{Graph, Node, NodeId, Op};
/// Mid-level module — optimizer input.
#[cfg_attr(feature = "serialize", derive(serde::Serialize, serde::Deserialize))]
#[derive(Debug, Clone, PartialEq)]
pub struct MirModule {
inner: Graph,
}
/// MIR node / op aliases (same types as the legacy graph API).
pub type MirNode = Node;
pub type MirNodeId = NodeId;
pub type MirOp = Op;
impl MirModule {
pub fn new(name: impl Into<String>) -> Self {
Self {
inner: Graph::new(name),
}
}
pub fn from_graph(graph: Graph) -> Self {
Self { inner: graph }
}
pub fn into_graph(self) -> Graph {
self.inner
}
pub fn as_graph(&self) -> &Graph {
&self.inner
}
pub fn as_graph_mut(&mut self) -> &mut Graph {
&mut self.inner
}
pub fn name(&self) -> &str {
&self.inner.name
}
pub fn len(&self) -> usize {
self.inner.len()
}
pub fn is_empty(&self) -> bool {
self.inner.is_empty()
}
pub fn outputs(&self) -> &[NodeId] {
&self.inner.outputs
}
pub fn set_outputs(&mut self, outputs: Vec<NodeId>) {
self.inner.set_outputs(outputs);
}
}
impl From<Graph> for MirModule {
fn from(graph: Graph) -> Self {
Self::from_graph(graph)
}
}
impl From<MirModule> for Graph {
fn from(mir: MirModule) -> Self {
mir.into_graph()
}
}
impl std::fmt::Display for MirModule {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "mir @{}", self.inner)
}
}