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
|
self
|
||||||
}
|
}
|
||||||
|
|
||||||
/// R6-1: attach the device form of φ (`RTX_E3_GEOM_DEVICE=1` evaluates
|
/// R6-1: attach the device form of φ (the device geometry, default ON,
|
||||||
/// it on the band instead of the host closure; the caller guarantees
|
/// evaluates it on the band instead of the host closure; the caller
|
||||||
/// the two are the same arithmetic).
|
/// guarantees the two are the same arithmetic). A body without one
|
||||||
|
/// falls back to the host build.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn with_device_sdf<F>(mut self, f: F) -> Self
|
pub fn with_device_sdf<F>(mut self, f: F) -> Self
|
||||||
where
|
where
|
||||||
@@ -165,6 +166,12 @@ impl Body {
|
|||||||
self
|
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.
|
/// The device form of φ at `t`, when the body has one.
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn device_sdf(&self, t: f64) -> Option<DeviceSdf> {
|
pub fn device_sdf(&self, t: f64) -> Option<DeviceSdf> {
|
||||||
|
|||||||
@@ -163,7 +163,7 @@ pub struct DeviceStep {
|
|||||||
cut: Option<cut::DeviceCut>,
|
cut: Option<cut::DeviceCut>,
|
||||||
/// Steps since the multigrid hierarchy was last rebuilt (moving bodies).
|
/// Steps since the multigrid hierarchy was last rebuilt (moving bodies).
|
||||||
steps_since_hierarchy: usize,
|
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>,
|
geom: Option<geom::DeviceGeom>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -746,10 +746,20 @@ impl DeviceStep {
|
|||||||
let mut field = self.host_field.take().unwrap_or_else(|| Field::new(g));
|
let mut field = self.host_field.take().unwrap_or_else(|| Field::new(g));
|
||||||
self.download_for_rebuild(&mut field);
|
self.download_for_rebuild(&mut field);
|
||||||
let l_down = lap.elapsed();
|
let l_down = lap.elapsed();
|
||||||
// R6-1 (`RTX_E3_GEOM_DEVICE=1`): the end-of-step cut geometry on
|
// R6-1 (default ON, `RTX_E3_GEOM_DEVICE=0` off): the end-of-step
|
||||||
// the device, its face tables written into the persistent
|
// cut geometry on the device, its face tables written into the
|
||||||
// predictor set; the host classifies the mirror.
|
// persistent predictor set; the host classifies the mirror. A
|
||||||
if super::geom::enabled() {
|
// 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() {
|
if let Some(dc) = self.cut.as_mut() {
|
||||||
let geom = self
|
let geom = self
|
||||||
.geom
|
.geom
|
||||||
|
|||||||
+32
-3
@@ -1,5 +1,7 @@
|
|||||||
//! R6-1: the body's φ and the cut geometry on the device (`e3_geom.cu`),
|
//! 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
|
//! keep-or-evaluate, φ from the body's `DeviceSdf` polyline), the face
|
||||||
//! apertures and face-centre φ (written straight into the persistent
|
//! apertures and face-centre φ (written straight into the persistent
|
||||||
//! `DeviceCut` predictor apertures and distances), the cell volumes and
|
//! `DeviceCut` predictor apertures and distances), the cell volumes and
|
||||||
@@ -82,9 +84,36 @@ struct GeomGrid {
|
|||||||
unsafe impl DeviceRepr for GeomGrid {}
|
unsafe impl DeviceRepr for GeomGrid {}
|
||||||
unsafe impl ValidAsZeroBits 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 {
|
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
|
/// The persistent device geometry: corner φ and bound, the evaluated
|
||||||
|
|||||||
@@ -297,7 +297,7 @@ pub struct Solver {
|
|||||||
/// `(setup ns, iterate ns, solves, CG iterations)` summed.
|
/// `(setup ns, iterate ns, solves, CG iterations)` summed.
|
||||||
poisson_profile: (u64, u64, u64, u64),
|
poisson_profile: (u64, u64, u64, u64),
|
||||||
/// R6-1: the next moving rebuild's cut geometry, built on the device
|
/// 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.
|
/// evaluating φ on the host.
|
||||||
pub(super) pending_cut: Option<CutGeometry>,
|
pub(super) pending_cut: Option<CutGeometry>,
|
||||||
/// R6-1: retired device-built geometry arrays (empty on the host path)
|
/// R6-1: retired device-built geometry arrays (empty on the host path)
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ fn flag_wake_on_the_device() {
|
|||||||
(0.0, 0.0, 0.0)
|
(0.0, 0.0, 0.0)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// R6-1: the same φ in the device's form (`RTX_E3_GEOM_DEVICE=1`): the
|
// R6-1: the same φ in the device's form (the device geometry, default ON): the
|
||||||
// circle, the capsule around the step's centreline, the span cuts.
|
// circle, the capsule around the step's centreline, the span cuts.
|
||||||
let body = body.with_device_sdf(move |t| DeviceSdf {
|
let body = body.with_device_sdf(move |t| DeviceSdf {
|
||||||
cyl: [CX, cy, R_CYL],
|
cyl: [CX, cy, R_CYL],
|
||||||
|
|||||||
Reference in New Issue
Block a user