embedded3 R6-1: the device geometry default ON (RTX_E3_GEOM_DEVICE=0 restores the host build); a body without a device form of φ falls back to the host, logged once, nothing allocated

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
Omar Sobh
2026-09-24 18:08:50 -05:00
co-authored by Claude Opus 5.5
parent f5f0ffdd2a
commit 91fbf86026
6 changed files with 59 additions and 13 deletions
@@ -153,9 +153,10 @@ impl Body {
self
}
/// R6-1: attach the device form of φ (`RTX_E3_GEOM_DEVICE=1` evaluates
/// it on the band instead of the host closure; the caller guarantees
/// the two are the same arithmetic).
/// R6-1: attach the device form of φ (the device geometry, default ON,
/// evaluates it on the band instead of the host closure; the caller
/// guarantees the two are the same arithmetic). A body without one
/// falls back to the host build.
#[must_use]
pub fn with_device_sdf<F>(mut self, f: F) -> Self
where
@@ -165,6 +166,12 @@ impl Body {
self
}
/// Whether the body carries a device form of φ.
#[must_use]
pub fn has_device_sdf(&self) -> bool {
self.device_sdf.is_some()
}
/// The device form of φ at `t`, when the body has one.
#[must_use]
pub fn device_sdf(&self, t: f64) -> Option<DeviceSdf> {
@@ -163,7 +163,7 @@ pub struct DeviceStep {
cut: Option<cut::DeviceCut>,
/// Steps since the multigrid hierarchy was last rebuilt (moving bodies).
steps_since_hierarchy: usize,
/// R6-1: the persistent device cut geometry (`RTX_E3_GEOM_DEVICE=1`).
/// R6-1: the persistent device cut geometry (default ON; `RTX_E3_GEOM_DEVICE=0` off).
geom: Option<geom::DeviceGeom>,
}
@@ -746,10 +746,20 @@ impl DeviceStep {
let mut field = self.host_field.take().unwrap_or_else(|| Field::new(g));
self.download_for_rebuild(&mut field);
let l_down = lap.elapsed();
// R6-1 (`RTX_E3_GEOM_DEVICE=1`): the end-of-step cut geometry on
// the device, its face tables written into the persistent
// predictor set; the host classifies the mirror.
if super::geom::enabled() {
// R6-1 (default ON, `RTX_E3_GEOM_DEVICE=0` off): the end-of-step
// cut geometry on the device, its face tables written into the
// persistent predictor set; the host classifies the mirror. A
// body the device cannot build falls back to the host (logged
// once, nothing allocated).
let geom_on = super::geom::enabled()
&& match super::geom::unsupported(&self.solver) {
Some(reason) => {
super::geom::log_fallback(reason);
false
}
None => true,
};
if geom_on {
if let Some(dc) = self.cut.as_mut() {
let geom = self
.geom
@@ -1,5 +1,7 @@
//! R6-1: the body's φ and the cut geometry on the device (`e3_geom.cu`),
//! behind `RTX_E3_GEOM_DEVICE=1`. The corner φ (the narrow band's
//! default ON since 2026-09-24 (`RTX_E3_GEOM_DEVICE=0` restores the host
//! build; a body without a device form of φ falls back to the host, logged
//! once). The corner φ (the narrow band's
//! keep-or-evaluate, φ from the body's `DeviceSdf` polyline), the face
//! apertures and face-centre φ (written straight into the persistent
//! `DeviceCut` predictor apertures and distances), the cell volumes and
@@ -82,9 +84,36 @@ struct GeomGrid {
unsafe impl DeviceRepr for GeomGrid {}
unsafe impl ValidAsZeroBits for GeomGrid {}
/// `RTX_E3_GEOM_DEVICE=1`.
/// The device geometry: default ON (R6-1's two-period 3D gate held
/// 2026-09-24); `RTX_E3_GEOM_DEVICE=0` restores the host build.
pub(super) fn enabled() -> bool {
std::env::var("RTX_E3_GEOM_DEVICE").is_ok_and(|v| v == "1")
!std::env::var("RTX_E3_GEOM_DEVICE").is_ok_and(|v| v == "0")
}
/// Why the device geometry cannot build this solver's body (the host
/// builds it instead), or `None` when it can.
pub(super) fn unsupported(solver: &Solver) -> Option<&'static str> {
if solver.params.wall_scheme != WallScheme::CutCell {
return Some("the wall scheme is not the cut cell");
}
if solver.params.aperture_substeps != 0 {
return Some("aperture substeps are on");
}
match solver.body() {
None => Some("no body"),
Some(b) if !b.has_device_sdf() => Some("the body has no device form of φ"),
Some(_) => None,
}
}
/// The host fallback, logged once per process.
pub(super) fn log_fallback(reason: &str) {
static LOGGED: std::sync::Once = std::sync::Once::new();
LOGGED.call_once(|| {
eprintln!(
" R6-1 device geometry: host fallback ({reason}); the cut geometry is built on the host"
);
});
}
/// The persistent device geometry: corner φ and bound, the evaluated
@@ -297,7 +297,7 @@ pub struct Solver {
/// `(setup ns, iterate ns, solves, CG iterations)` summed.
poisson_profile: (u64, u64, u64, u64),
/// R6-1: the next moving rebuild's cut geometry, built on the device
/// (`RTX_E3_GEOM_DEVICE=1`); `build_mask` classifies it instead of
/// (default ON, `RTX_E3_GEOM_DEVICE=0` off); `build_mask` classifies it instead of
/// evaluating φ on the host.
pub(super) pending_cut: Option<CutGeometry>,
/// R6-1: retired device-built geometry arrays (empty on the host path)