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:
co-authored by
Claude Opus 5.5
parent
f5f0ffdd2a
commit
91fbf86026
@@ -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
|
||||
|
||||
+32
-3
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user