Open
Description
Bottom line - there's tons of overhead in run()
currently:
- It allocates something like 15
Vec
instances and a bunch of strings, there's tons of allocations all over the place (so for small inputs and graphs this is noticeable) - For big inputs, you are currently required to copy the data in
- There's a lot of overhead like building names vecs (should be done upon model load?) and shapes (if there's no dynamic axes, no need to do that repeatedly)
- There's allocations for outputs as well
Here's one idea, what if you could do something like this (I think this way you could bring the overhead down to almost zero).
// maybe I've missed something, would like to hear your thoughts, @nbigaouette :)
// note that this is all simplified, as it may require e.g. Pin<> in a few places
struct Runner {
session: Session,
inputs: Vec<Array<...>>>,
// owned preallocated outputs as well?
input_names: Vec<CString>,
output_names: Vec<CString>,
}
impl Runner {
fn from_session(session: Session) -> Self { ... }
pub fn execute(&mut self) { ... }
pub fn outputs(&self) -> &[Array<...>] { ... }
pub fn inputs(&mut self) -> &mut [Array<...>] { ... }
}
let mut Session: session = ...;
let input_arrays: Vec<...> = ...;
// this executes most of what `run()` currently does, all the way up to the actual .Run() call
let runner = session.into_runner(input_arrays);
runner.execute()?; // this just calls Run() and converts the status
// if outputs are preallocated, no extra allocations here either
for out in runner.outputs() {
dbg!(out);
}
// no allocations, no boilerplate, we're just updating the inputs
runner.inputs()[0].fill(42.0);
// no allocations, no boilerplate, just a .Run() call
runner.execute()?;
Metadata
Metadata
Assignees
Labels
No labels