Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions crates/total-viewsheds/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,10 @@ pub struct Compute {
/// Controls line of sight and total viewshed image generation
#[arg(long, value_name = "render image", default_value = "false")]
pub disable_image_render: bool,

/// Subdivides 360 degrees into a `angle_subdivisions` number of subdivisions
#[arg(long, value_name = "number of angle divisions", default_value = "1")]
pub angle_subdivisions: u8,
}

#[derive(clap::Parser, Debug)]
Expand Down
14 changes: 14 additions & 0 deletions crates/total-viewsheds/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,19 @@ fn setup_logging() -> Result<()> {

/// Run computations
fn compute(config: &config::Compute) -> Result<()> {
// for now, only the CPU backend knows how to interpret more than one angle division
if !matches!(config.backend, config::Backend::CPU) && config.angle_subdivisions > 1 {
color_eyre::eyre::bail!(
"An angle division higher than 1 is only supported on the `cpu` backend"
)
}

// we can't subdivide rotation into more than 182 rotations or else we overflow the u16
// we use for angles, so 100 is an artificial limit
if config.angle_subdivisions > 100 {
color_eyre::eyre::bail!("The maximum angle divisions is 100")
}

let tile = bt::BinaryTerrain::read(&config.input)?;
let scale = config.scale.unwrap_or_else(|| tile.scale());

Expand Down Expand Up @@ -142,6 +155,7 @@ fn compute(config: &config::Compute) -> Result<()> {
refraction: config.refraction,
thread_count: config.thread_count,
disable_render_image: config.disable_image_render,
angle_subdivisions: config.angle_subdivisions,
};
let mut compute = run::compute::Compute::new(compute_config, &mut dem)?;
compute.run()?;
Expand Down
5 changes: 4 additions & 1 deletion crates/total-viewsheds/src/run/compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,14 @@ pub struct Config {
pub rings_per_km: f32,
/// How to normalise the heatmap data.
pub heatmap: crate::config::HeatmapNormalisation,
/// Refractoin coefficient
/// Refraction coefficient
pub refraction: f32,
/// Number of threads for computation
pub thread_count: usize,
/// Disables the rendering of PNG images (good for long runs)
pub disable_render_image: bool,
/// Subdivides 360 degrees into a `angle_subdivisions` number of subdivisions
pub angle_subdivisions: u8,
}

impl<'compute> Compute<'compute> {
Expand Down Expand Up @@ -320,6 +322,7 @@ pub mod test {
refraction: refraction_override.unwrap_or(0.13f32),
thread_count: 1, // single thread it for consistency
disable_render_image: false,
angle_subdivisions: 1,
};

let mut compute = Compute::new(config, dem).unwrap();
Expand Down
14 changes: 10 additions & 4 deletions crates/total-viewsheds/src/run/parallel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,25 +43,31 @@ impl super::compute::Compute<'_> {
let refraction = self.config.refraction;
let scale = self.config.scale;
let observer_height = self.config.observer_height;
let angle_subdivisions = u16::from(self.config.angle_subdivisions);

pool.install(move || {
(0u16..360u16)
(0u16..360u16 * angle_subdivisions)
.into_par_iter()
.map(|angle| {
let start = std::time::Instant::now();
tracing::info!("starting angle: {angle}");
tracing::info!(
"starting angle: {}",
f32::from(angle) / f32::from(angle_subdivisions)
);

let output = crate::cpu::kernel(
elevations,
max_los,
f32::from(angle),
f32::from(angle) / f32::from(angle_subdivisions),
refraction,
scale,
observer_height,
);

tracing::info!("finished angle in {:?}", start.elapsed());
(angle, output)

#[expect(clippy::integer_division, reason = "truncating the angle is fine")]
(angle / angle_subdivisions, output)
})
.for_each(|(angle, output)| {
let result = accumulating.handle_parallel_per_angle_output(angle, output);
Expand Down