1use crate::CompileOptions;
15use crate::compiled::CompiledGraph;
16use crate::session::Session;
17use anyhow::{Context, Result};
18use rlx_ir::Graph;
19use rlx_pkg::{Package, Placement};
20use std::path::Path;
21
22pub fn load_rlxp_graph(path: impl AsRef<Path>) -> Result<Graph> {
26 let pack = Package::open(path.as_ref())
27 .with_context(|| format!("open package {}", path.as_ref().display()))?;
28 pack.graph()
29}
30
31pub fn open_rlxp(path: impl AsRef<Path>) -> Result<Package> {
33 Package::open(path.as_ref())
34 .with_context(|| format!("open package {}", path.as_ref().display()))
35}
36
37pub fn compile_rlxp(session: &Session, path: impl AsRef<Path>) -> Result<CompiledGraph> {
41 let graph = load_rlxp_graph(path)?;
42 Ok(session.compile(graph))
43}
44
45pub fn compile_rlxp_bind_params(
51 session: &Session,
52 path: impl AsRef<Path>,
53) -> Result<CompiledGraph> {
54 let pack = open_rlxp(path.as_ref())?;
55 let graph = pack
56 .graph_with(rlx_pkg::MaterializeMode::HotOnly)
57 .with_context(|| format!("graph {}", path.as_ref().display()))?;
58 let mut compiled = session.compile(graph);
59 for (name, bytes, dtype) in pack.typed_weight_bindings()? {
60 compiled.set_param_typed(&name, &bytes, dtype);
61 }
62 Ok(compiled)
63}
64
65pub fn compile_rlxp_with(
67 session: &Session,
68 path: impl AsRef<Path>,
69 options: &CompileOptions,
70) -> Result<CompiledGraph> {
71 let graph = load_rlxp_graph(path)?;
72 Ok(session.compile_with(graph, options))
73}
74
75pub fn load_rlxp_placement(path: impl AsRef<Path>) -> Result<Option<Placement>> {
77 let pack = open_rlxp(path)?;
78 Ok(pack.placement().cloned())
79}
80
81pub fn tensors_for_rank(placement: &Placement, rank: u32, all_names: &[&str]) -> Vec<String> {
86 all_names
87 .iter()
88 .filter_map(|name| match placement.ranks_for(name) {
89 Some(ranks) if ranks.contains(&rank) => Some((*name).to_string()),
90 Some(_) => None,
91 None => Some((*name).to_string()),
92 })
93 .collect()
94}
95
96pub fn weight_names_for_rank(pack: &Package, rank: u32) -> Vec<String> {
99 if pack.rank_root(rank).is_some() {
100 return pack
101 .tensors_for_rank(rank)
102 .into_iter()
103 .filter(|e| e.rank == Some(rank))
104 .map(|e| e.name.clone())
105 .collect();
106 }
107 let Some(idx) = pack.weights_index() else {
108 return Vec::new();
109 };
110 let names: Vec<&str> = idx.names().collect();
111 match pack.placement() {
112 Some(pl) => tensors_for_rank(pl, rank, &names),
113 None => names.into_iter().map(str::to_string).collect(),
114 }
115}