Denoise a whole frame in one call where the GPU takes any size
A fixed 1408 tile is exact only in its centre, and Best keeps 896 of every 1408 it computes: 2.47 photosites of work for each one kept. The tiler now takes a network of any size as well as a square one, and plans the frame as the fewest equal tiles under the rung's limit -- one tile, the whole frame and its reflected border, whenever it fits. If the first call of a plan fails, as a GPU out of memory does, the kept centre is halved and the frame planned again. Each shipped network names its any-size sibling (mosaic-best.onnx beside mosaic-best-1408.onnx). OnnxNet::open takes it where the engine runs whole frames and the file is installed, and the 1408 tiles otherwise; open_tiled forces the tiles, and denoise_raw's DR_PLAN=tiles uses it to compare. The cache key stays on the fixed model: the output is the same network's. Tests hold any-size tiles, a grid of them and a plan rebuilt after a failure to the square tiles' answer in every Bayer phase.
This commit is contained in:
@@ -179,7 +179,7 @@ impl DevelopSession {
|
||||
iso: self.denoise.iso,
|
||||
cache_key: self.denoise.file_hash.as_ref().map(|h| h.key(&model)),
|
||||
model,
|
||||
halo: net.halo,
|
||||
net,
|
||||
cancel,
|
||||
})
|
||||
}
|
||||
@@ -316,8 +316,8 @@ struct Work {
|
||||
profile: Option<Vec<(f32, f32)>>,
|
||||
iso: Option<u32>,
|
||||
model: std::path::PathBuf,
|
||||
/// The context `model` needs past a tile's kept centre.
|
||||
halo: usize,
|
||||
/// The network `model` is: its context and its whole-frame sibling.
|
||||
net: dr_denoise::Shipped,
|
||||
cancel: Arc<AtomicBool>,
|
||||
cache_key: Option<String>,
|
||||
}
|
||||
@@ -351,8 +351,8 @@ impl Work {
|
||||
.map_err(|e| e.to_string())?;
|
||||
let noise = dr_denoise::noise::for_frame_with(&raw, self.profile.as_deref(), self.iso)
|
||||
.ok_or("this photograph gives no way to measure its noise")?;
|
||||
let mut net = dr_denoise::onnx::OnnxNet::from_path(&self.model, self.halo)
|
||||
.map_err(|e| e.to_string())?;
|
||||
let mut net =
|
||||
dr_denoise::onnx::OnnxNet::open(&self.model, self.net).map_err(|e| e.to_string())?;
|
||||
let rung = net
|
||||
.rung()
|
||||
.map(|r| r.label().to_string())
|
||||
|
||||
@@ -35,9 +35,11 @@ pub fn init(runtime_dirs: Vec<PathBuf>) {
|
||||
(Role::EyeClassifier, crate::library::SUNGLASSES_MODEL),
|
||||
(Role::Inpainter, crate::library::INPAINT_MODEL),
|
||||
]);
|
||||
wanted.extend(
|
||||
[dr_denoise::FAST, dr_denoise::MEDIUM, dr_denoise::BEST].map(|n| (Role::Denoiser, n.file)),
|
||||
);
|
||||
let denoisers = [dr_denoise::FAST, dr_denoise::MEDIUM, dr_denoise::BEST];
|
||||
wanted.extend(denoisers.map(|n| (Role::Denoiser, n.file)));
|
||||
// Their any-size siblings, which the engine compiles only on a rung
|
||||
// that runs whole frames (TensorRT; denoise.md §14).
|
||||
wanted.extend(denoisers.map(|n| (Role::WholeDenoiser, n.whole)));
|
||||
let models: Vec<(Role, PathBuf)> = wanted
|
||||
.into_iter()
|
||||
.filter_map(|(role, name)| Some((role, crate::library::shared_model(name)?)))
|
||||
|
||||
Reference in New Issue
Block a user