spirv_backend: split the array operations out of sim.rs -> adapt.rs

This commit is contained in:
2022-07-25 00:28:03 -07:00
parent 8ab89640f2
commit 9c7ef7ec88
4 changed files with 181 additions and 184 deletions

View File

@@ -1,5 +1,5 @@
use crate::sim::{SerializedSimMeta, SerializedStepE, SerializedStepH};
use crate::support::UnsizedArray;
use crate::sim::{StepEContext, StepHContext, VolumeSampleNeg, VolumeSamplePos};
use crate::support::{Array3, Array3Mut, Optional, UnsizedArray};
use coremem_types::mat::Material;
use coremem_types::real::Real;
use coremem_types::vec::{Vec3, Vec3u};
@@ -38,3 +38,155 @@ pub(crate) fn step_e<R: Real, M: Material<R>>(
}
}
#[derive(Copy, Clone)]
pub struct SerializedSimMeta<R> {
pub dim: Vec3u,
pub inv_feature_size: R,
pub time_step: R,
pub feature_size: R,
}
/// Whatever data we received from the host in their call to step_h
struct SerializedStepH<'a, R, M> {
meta: &'a SerializedSimMeta<R>,
stimulus_h: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a UnsizedArray<Vec3<R>>,
h: &'a mut UnsizedArray<Vec3<R>>,
m: &'a mut UnsizedArray<Vec3<R>>,
}
impl<'a, R, M> SerializedStepH<'a, R, M> {
fn new(
meta: &'a SerializedSimMeta<R>,
stimulus_h: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a UnsizedArray<Vec3<R>>,
h: &'a mut UnsizedArray<Vec3<R>>,
m: &'a mut UnsizedArray<Vec3<R>>,
) -> Self {
Self {
meta, stimulus_h, material, e, h, m
}
}
}
impl<'a, R: Real, M> SerializedStepH<'a, R, M> {
/// returns a context which the user can call `step_h` on
fn index(&self, idx: Vec3u) -> StepHContext<'a, R, M> {
let dim = self.meta.dim;
let stim_h_matrix = Array3::new(self.stimulus_h, dim);
let mat_matrix = Array3::new(self.material, dim);
let e = Array3::new(self.e, dim);
let h = Array3::new(self.h, dim);
let m = Array3::new(self.m, dim);
let in_e = VolumeSamplePos {
mid: e.get(idx).unwrap(),
xp1: e.get(idx + Vec3u::unit_x()),
yp1: e.get(idx + Vec3u::unit_y()),
zp1: e.get(idx + Vec3u::unit_z()),
};
let in_h = h.get(idx).unwrap();
let in_m = m.get(idx).unwrap();
let mat = mat_matrix.into_ref(idx);
StepHContext {
inv_feature_size: self.meta.inv_feature_size,
time_step: self.meta.time_step,
stim_h: stim_h_matrix.get(idx).unwrap(),
mat,
in_e,
in_h,
in_m,
}
}
fn write_output(self, idx: Vec3u, h: Vec3<R>, m: Vec3<R>) {
let dim = self.meta.dim;
let arr_h = Array3Mut::new(self.h, dim);
let arr_m = Array3Mut::new(self.m, dim);
let mut out_h = arr_h.into_mut_handle(idx);
let mut out_m = arr_m.into_mut_handle(idx);
out_h.write(h);
out_m.write(m);
}
}
/// Whatever data we received from the host in their call to step_e
struct SerializedStepE<'a, R, M> {
meta: &'a SerializedSimMeta<R>,
stimulus_e: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a mut UnsizedArray<Vec3<R>>,
h: &'a UnsizedArray<Vec3<R>>,
}
impl<'a, R, M> SerializedStepE<'a, R, M> {
pub fn new(
meta: &'a SerializedSimMeta<R>,
stimulus_e: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a mut UnsizedArray<Vec3<R>>,
h: &'a UnsizedArray<Vec3<R>>,
) -> Self {
Self {
meta, stimulus_e, material, e, h
}
}
}
impl<'a, R: Real, M> SerializedStepE<'a, R, M> {
fn index(&self, idx: Vec3u) -> StepEContext<'a, R, M> {
let dim = self.meta.dim;
let stim_e_matrix = Array3::new(self.stimulus_e, dim);
let mat_matrix = Array3::new(self.material, dim);
let e = Array3::new(self.e, dim);
let h = Array3::new(self.h, dim);
let xm1 = if idx.x() == 0 {
Optional::none()
} else {
h.get(idx - Vec3u::unit_x())
};
let ym1 = if idx.y() == 0 {
Optional::none()
} else {
h.get(idx - Vec3u::unit_y())
};
let zm1 = if idx.z() == 0 {
Optional::none()
} else {
h.get(idx - Vec3u::unit_z())
};
let in_h = VolumeSampleNeg {
mid: h.get(idx).unwrap(),
xm1,
ym1,
zm1,
};
let in_e = e.get(idx).unwrap();
let mat = mat_matrix.into_ref(idx);
StepEContext {
inv_feature_size: self.meta.inv_feature_size,
time_step: self.meta.time_step,
stim_e: stim_e_matrix.get(idx).unwrap(),
mat,
in_h,
in_e,
}
}
fn write_output(self, idx: Vec3u, e: Vec3<R>) {
let dim = self.meta.dim;
let arr_e = Array3Mut::new(self.e, dim);
let mut out_e = arr_e.into_mut_handle(idx);
out_e.write(e);
}
}

View File

@@ -16,7 +16,7 @@ mod adapt;
pub mod sim;
pub mod support;
pub use sim::SerializedSimMeta;
pub use adapt::SerializedSimMeta;
pub use support::{Optional, UnsizedArray};
use coremem_types::mat::{Ferroxcube3R1MH, FullyGenericMaterial, IsoConductorOr};

View File

@@ -1,172 +1,18 @@
// use spirv_std::RuntimeArray;
use crate::support::{
Array3, Array3Mut, Optional, UnsizedArray
};
use crate::support::Optional;
use coremem_types::mat::Material;
use coremem_types::real::Real;
use coremem_types::vec::{Vec3, Vec3u};
#[derive(Copy, Clone)]
pub struct SerializedSimMeta<R> {
pub dim: Vec3u,
pub inv_feature_size: R,
pub time_step: R,
pub feature_size: R,
}
/// Whatever data we received from the host in their call to step_h
pub struct SerializedStepH<'a, R, M> {
meta: &'a SerializedSimMeta<R>,
stimulus_h: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a UnsizedArray<Vec3<R>>,
h: &'a mut UnsizedArray<Vec3<R>>,
m: &'a mut UnsizedArray<Vec3<R>>,
}
impl<'a, R, M> SerializedStepH<'a, R, M> {
pub fn new(
meta: &'a SerializedSimMeta<R>,
stimulus_h: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a UnsizedArray<Vec3<R>>,
h: &'a mut UnsizedArray<Vec3<R>>,
m: &'a mut UnsizedArray<Vec3<R>>,
) -> Self {
Self {
meta, stimulus_h, material, e, h, m
}
}
}
impl<'a, R: Real, M> SerializedStepH<'a, R, M> {
/// returns a context which the user can call `step_h` on
pub fn index(&self, idx: Vec3u) -> StepHContext<'a, R, M> {
let dim = self.meta.dim;
let stim_h_matrix = Array3::new(self.stimulus_h, dim);
let mat_matrix = Array3::new(self.material, dim);
let e = Array3::new(self.e, dim);
let h = Array3::new(self.h, dim);
let m = Array3::new(self.m, dim);
let in_e = VolumeSamplePos {
mid: e.get(idx).unwrap(),
xp1: e.get(idx + Vec3u::unit_x()),
yp1: e.get(idx + Vec3u::unit_y()),
zp1: e.get(idx + Vec3u::unit_z()),
};
let in_h = h.get(idx).unwrap();
let in_m = m.get(idx).unwrap();
let mat = mat_matrix.into_ref(idx);
StepHContext {
inv_feature_size: self.meta.inv_feature_size,
time_step: self.meta.time_step,
stim_h: stim_h_matrix.get(idx).unwrap(),
mat,
in_e,
in_h,
in_m,
}
}
pub fn write_output(self, idx: Vec3u, h: Vec3<R>, m: Vec3<R>) {
let dim = self.meta.dim;
let arr_h = Array3Mut::new(self.h, dim);
let arr_m = Array3Mut::new(self.m, dim);
let mut out_h = arr_h.into_mut_handle(idx);
let mut out_m = arr_m.into_mut_handle(idx);
out_h.write(h);
out_m.write(m);
}
}
/// Whatever data we received from the host in their call to step_e
pub struct SerializedStepE<'a, R, M> {
meta: &'a SerializedSimMeta<R>,
stimulus_e: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a mut UnsizedArray<Vec3<R>>,
h: &'a UnsizedArray<Vec3<R>>,
}
impl<'a, R, M> SerializedStepE<'a, R, M> {
pub fn new(
meta: &'a SerializedSimMeta<R>,
stimulus_e: &'a UnsizedArray<Vec3<R>>,
material: &'a UnsizedArray<M>,
e: &'a mut UnsizedArray<Vec3<R>>,
h: &'a UnsizedArray<Vec3<R>>,
) -> Self {
Self {
meta, stimulus_e, material, e, h
}
}
}
impl<'a, R: Real, M> SerializedStepE<'a, R, M> {
pub fn index(&self, idx: Vec3u) -> StepEContext<'a, R, M> {
let dim = self.meta.dim;
let stim_e_matrix = Array3::new(self.stimulus_e, dim);
let mat_matrix = Array3::new(self.material, dim);
let e = Array3::new(self.e, dim);
let h = Array3::new(self.h, dim);
let xm1 = if idx.x() == 0 {
Optional::none()
} else {
h.get(idx - Vec3u::unit_x())
};
let ym1 = if idx.y() == 0 {
Optional::none()
} else {
h.get(idx - Vec3u::unit_y())
};
let zm1 = if idx.z() == 0 {
Optional::none()
} else {
h.get(idx - Vec3u::unit_z())
};
let in_h = VolumeSampleNeg {
mid: h.get(idx).unwrap(),
xm1,
ym1,
zm1,
};
let in_e = e.get(idx).unwrap();
let mat = mat_matrix.into_ref(idx);
StepEContext {
inv_feature_size: self.meta.inv_feature_size,
time_step: self.meta.time_step,
stim_e: stim_e_matrix.get(idx).unwrap(),
mat,
in_h,
in_e,
}
}
pub fn write_output(self, idx: Vec3u, e: Vec3<R>) {
let dim = self.meta.dim;
let arr_e = Array3Mut::new(self.e, dim);
let mut out_e = arr_e.into_mut_handle(idx);
out_e.write(e);
}
}
use coremem_types::vec::Vec3;
/// Package the field vectors adjacent to some particular location.
/// Particular those at negative offsets from the midpoint.
/// This is used in step_e when looking at the H field deltas.
#[derive(Copy, Clone)]
struct VolumeSampleNeg<R> {
mid: Vec3<R>,
xm1: Optional<Vec3<R>>,
ym1: Optional<Vec3<R>>,
zm1: Optional<Vec3<R>>,
pub struct VolumeSampleNeg<R> {
pub mid: Vec3<R>,
pub xm1: Optional<Vec3<R>>,
pub ym1: Optional<Vec3<R>>,
pub zm1: Optional<Vec3<R>>,
}
impl<R: Real> VolumeSampleNeg<R> {
@@ -219,11 +65,11 @@ impl<R: Real> VolumeSampleNeg<R> {
/// Particular those at positive offsets from the midpoint.
/// This is used in step_h when looking at the E field deltas.
#[derive(Copy, Clone)]
struct VolumeSamplePos<R> {
mid: Vec3<R>,
xp1: Optional<Vec3<R>>,
yp1: Optional<Vec3<R>>,
zp1: Optional<Vec3<R>>
pub struct VolumeSamplePos<R> {
pub mid: Vec3<R>,
pub xp1: Optional<Vec3<R>>,
pub yp1: Optional<Vec3<R>>,
pub zp1: Optional<Vec3<R>>
}
impl<R: Real> VolumeSamplePos<R> {
@@ -291,13 +137,13 @@ impl<R: Real> FieldDeltas<R> {
}
pub struct StepEContext<'a, R, M> {
inv_feature_size: R,
time_step: R,
stim_e: Vec3<R>,
mat: &'a M,
pub inv_feature_size: R,
pub time_step: R,
pub stim_e: Vec3<R>,
pub mat: &'a M,
/// Input field sampled near this location
in_h: VolumeSampleNeg<R>,
in_e: Vec3<R>,
pub in_h: VolumeSampleNeg<R>,
pub in_e: Vec3<R>,
}
impl<'a, R: Real, M: Material<R>> StepEContext<'a, R, M> {
@@ -321,14 +167,14 @@ impl<'a, R: Real, M: Material<R>> StepEContext<'a, R, M> {
pub struct StepHContext<'a, R, M> {
inv_feature_size: R,
time_step: R,
stim_h: Vec3<R>,
mat: &'a M,
pub inv_feature_size: R,
pub time_step: R,
pub stim_h: Vec3<R>,
pub mat: &'a M,
/// Input field sampled near this location
in_e: VolumeSamplePos<R>,
in_h: Vec3<R>,
in_m: Vec3<R>,
pub in_e: VolumeSamplePos<R>,
pub in_h: Vec3<R>,
pub in_m: Vec3<R>,
}
impl<'a, R: Real, M: Material<R>> StepHContext<'a, R, M> {