pub struct EagerTensor { /* private fields */ }Expand description
Eager tensor with reverse-mode autodiff over concrete tensor values.
This executes each primitive immediately and records a lightweight reverse
DAG for backward(). Gradients accumulate across repeated backward()
calls until they are cleared explicitly.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![3], vec![1.0_f64, 2.0, 3.0]).unwrap(), ctx)?;
let loss = x.mul(&x).unwrap().reduce_sum(&[0]).unwrap();
let _cotangents = loss.backward().unwrap();
let loss = x.mul(&x).unwrap().reduce_sum(&[0]).unwrap();
let _cotangents = loss.backward().unwrap();
assert_eq!(x.grad().unwrap().unwrap().as_slice::<f64>().unwrap(), &[4.0, 8.0, 12.0]);
x.clear_grad();
assert!(x.grad().unwrap().is_none());Implementations§
Source§impl EagerTensor
impl EagerTensor
Sourcepub fn from_tensor_in(tensor: Tensor, ctx: Arc<EagerRuntime>) -> Result<Self>
pub fn from_tensor_in(tensor: Tensor, ctx: Arc<EagerRuntime>) -> Result<Self>
Create an untracked eager tensor inside an existing eager context.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx)?;
assert_eq!(x.materialized()?.as_slice::<f64>().unwrap(), &[1.0, 2.0]);Sourcepub fn requires_grad_in(tensor: Tensor, ctx: Arc<EagerRuntime>) -> Result<Self>
pub fn requires_grad_in(tensor: Tensor, ctx: Arc<EagerRuntime>) -> Result<Self>
Create a tracked eager leaf inside an existing eager context.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx)?;
assert!(x.grad().unwrap().is_none());Sourcepub fn detach(&self) -> Self
pub fn detach(&self) -> Self
Detach this tensor from the reverse graph.
The returned tensor keeps the concrete value but no longer contributes gradients to the original graph.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx)?;
let y = x.detach();
assert_eq!(y.materialized()?.as_slice::<f64>().unwrap(), &[1.0, 2.0]);
assert!(y.grad().unwrap().is_none());Sourcepub fn detach_into(&self, ctx: &Arc<EagerRuntime>) -> Result<Self>
pub fn detach_into(&self, ctx: &Arc<EagerRuntime>) -> Result<Self>
Detach this tensor from its graph and re-register it in a different context as an untracked leaf.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx_a = EagerRuntime::with_cpu_backend(CpuBackend::new());
let ctx_b = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx_a)?;
let d = x.detach_into(&ctx_b)?;
assert!(!d.tracks_grad());
assert_eq!(d.ctx_id(), ctx_b.id());Sourcepub fn materialized(&self) -> Result<Arc<Tensor>>
pub fn materialized(&self) -> Result<Arc<Tensor>>
Materialize and share the concrete tensor value.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![3.0_f64]).unwrap(), ctx)?;
assert_eq!(x.materialized()?.as_slice::<f64>().unwrap(), &[3.0]);Sourcepub fn dtype(&self) -> DType
pub fn dtype(&self) -> DType
Return this tensor’s scalar dtype without materializing through
materialized.
Sourcepub fn shape(&self) -> &[usize]
pub fn shape(&self) -> &[usize]
Return this tensor’s logical shape without materializing through
materialized.
Sourcepub fn tensor_read(&self) -> TensorRead<'_>
pub fn tensor_read(&self) -> TensorRead<'_>
Borrow this tensor value as a TensorRead.
This is the preferred borrowed input boundary for executor calls. It
preserves the option to replace eager storage with non-contiguous views
without forcing callers through materialized.
Sourcepub fn to_tensor(&self) -> Result<Tensor>
pub fn to_tensor(&self) -> Result<Tensor>
Materialize this eager tensor as an owned Tensor.
This is the owned materialization boundary for callers that need a standalone compact tensor. The operation is fallible because eager values may be backed by lazy or backend-resident storage.
Sourcepub fn grad(&self) -> Result<Option<Arc<Tensor>>>
pub fn grad(&self) -> Result<Option<Arc<Tensor>>>
Return the accumulated gradient currently stored for this tensor.
The stored gradient accumulates across repeated backward() calls
until it is cleared explicitly.
For complex scalar losses, stored gradients use tenferro’s Hermitian-adjoint cotangent convention. See https://tensor4all.org/tenferro-rs/guides/complex-ad.html.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx).unwrap();
let loss = x.exp().unwrap().reduce_sum(&[0]).unwrap();
let _cotangents = loss.backward().unwrap();
let grad = x.grad()?.unwrap();
assert_eq!(grad.shape(), &[2]);Sourcepub fn clear_grad(&self) -> Result<()>
pub fn clear_grad(&self) -> Result<()>
Clear the accumulated gradient stored for this tensor.
This only affects this tensor’s gradient slot. Other tensors in the same context retain their gradients until they are cleared explicitly or overwritten by later accumulation.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![3], vec![1.0_f64, 2.0, 3.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![3], vec![4.0_f64, 5.0, 6.0]).unwrap(), ctx).unwrap();
let loss = x.mul(&y).unwrap().reduce_sum(&[0]).unwrap();
let _ = loss.backward().unwrap();
x.clear_grad()?;
assert!(x.grad()?.is_none());
assert!(y.grad()?.is_some());Sourcepub fn tracks_grad(&self) -> bool
pub fn tracks_grad(&self) -> bool
Report whether this tensor participates in gradient tracking.
Tracked tensors keep a gradient slot in their eager context; untracked tensors and detached tensors do not.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let plain = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let tracked = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 4.0]).unwrap(), ctx.clone()).unwrap();
let detached = tracked.detach();
assert!(!plain.tracks_grad());
assert!(tracked.tracks_grad());
assert!(!detached.tracks_grad());Sourcepub fn ctx_id(&self) -> ContextId
pub fn ctx_id(&self) -> ContextId
Return the opaque identifier of the context this tensor belongs to.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![1.0_f64]).unwrap(), ctx.clone()).unwrap();
assert_eq!(x.ctx_id(), ctx.id());Sourcepub fn runtime(&self) -> &Arc<EagerRuntime>
pub fn runtime(&self) -> &Arc<EagerRuntime>
Borrow the eager runtime context that owns this tensor.
Sourcepub fn same_context(&self, other: &Self) -> bool
pub fn same_context(&self, other: &Self) -> bool
Check whether two tensors belong to the same eager context.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![1.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![2.0_f64]).unwrap(), ctx).unwrap();
assert!(x.same_context(&y));Sourcepub fn backward(&self) -> Result<HashMap<ValueKey<StdTensorOp>, Arc<Tensor>>>
pub fn backward(&self) -> Result<HashMap<ValueKey<StdTensorOp>, Arc<Tensor>>>
Run reverse-mode AD from this scalar output.
Returns the full cotangent map produced by the reverse pass and also
accumulates into grad() for tracked eager tensors reachable from this
output.
For complex scalar outputs, cotangents use tenferro’s Hermitian real-inner-product convention. See https://tensor4all.org/tenferro-rs/guides/complex-ad.html.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::requires_grad_in(Tensor::from_vec_col_major(vec![3], vec![1.0_f64, 2.0, 3.0]).unwrap(), ctx).unwrap();
let loss = x.add(&x).unwrap().reduce_sum(&[0]).unwrap();
let _cotangents = loss.backward().unwrap();
let loss = x.add(&x).unwrap().reduce_sum(&[0]).unwrap();
let _cotangents = loss.backward().unwrap();
assert_eq!(x.grad().unwrap().unwrap().as_slice::<f64>().unwrap(), &[4.0, 4.0, 4.0]);Source§impl EagerTensor
impl EagerTensor
Sourcepub fn add(&self, other: &Self) -> Result<Self>
pub fn add(&self, other: &Self) -> Result<Self>
Elementwise addition.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 4.0]).unwrap(), ctx.clone()).unwrap();
let z = x.add(&y).unwrap();
assert_eq!(z.materialized().unwrap().as_slice::<f64>().unwrap(), &[4.0, 6.0]);Sourcepub fn mul(&self, other: &Self) -> Result<Self>
pub fn mul(&self, other: &Self) -> Result<Self>
Elementwise multiplication.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 4.0]).unwrap(), ctx.clone()).unwrap();
let z = x.mul(&y).unwrap();
assert_eq!(z.materialized().unwrap().as_slice::<f64>().unwrap(), &[3.0, 8.0]);Sourcepub fn neg(&self) -> Result<Self>
pub fn neg(&self) -> Result<Self>
Negate the tensor.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, -2.0]).unwrap(), ctx.clone()).unwrap();
let y = x.neg().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[-1.0, 2.0]);Sourcepub fn exp(&self) -> Result<Self>
pub fn exp(&self) -> Result<Self>
Elementwise exponential.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![0.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.exp().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0]);Sourcepub fn reduce_sum(&self, axes: &[usize]) -> Result<Self>
pub fn reduce_sum(&self, axes: &[usize]) -> Result<Self>
Reduce sum over the requested axes.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.reduce_sum(&[0, 1]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[10.0]);Sourcepub fn dot_general(
&self,
other: &Self,
config: DotGeneralConfig,
) -> Result<Self>
pub fn dot_general( &self, other: &Self, config: DotGeneralConfig, ) -> Result<Self>
Execute a dot-general contraction eagerly.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{DotGeneralConfig, EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let a = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 3], vec![1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0]).unwrap(), ctx.clone()).unwrap();
let b = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3, 2], vec![1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0]).unwrap(), ctx.clone()).unwrap();
let c = a.dot_general(&b, DotGeneralConfig {
lhs_contracting_dims: vec![1],
rhs_contracting_dims: vec![0],
lhs_batch_dims: vec![],
rhs_batch_dims: vec![],
}).unwrap();
assert_eq!(c.shape(), &[2, 2]);Sourcepub fn dot_general_with_conj(
&self,
other: &Self,
config: &DotGeneralConfig,
lhs_conj: bool,
rhs_conj: bool,
) -> Result<Self>
pub fn dot_general_with_conj( &self, other: &Self, config: &DotGeneralConfig, lhs_conj: bool, rhs_conj: bool, ) -> Result<Self>
Execute a dot-general contraction, optionally conjugating either operand.
Untracked tensors route the conjugation flags directly to the backend so
the conjugated operand does not need to be materialized. Tracked tensors
fall back to explicit Conj plus DotGeneral so reverse-mode AD keeps
the same graph semantics as the standard eager ops.
Sourcepub fn matmul(&self, other: &Self) -> Result<Self>
pub fn matmul(&self, other: &Self) -> Result<Self>
Matrix multiplication for rank-2 tensors.
This is a convenience wrapper over Self::dot_general that
contracts the left matrix’s column axis with the right matrix’s row
axis.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let a = EagerTensor::from_tensor_in(
Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(),
ctx.clone(),
).unwrap();
let b = EagerTensor::from_tensor_in(
Tensor::from_vec_col_major(vec![2, 1], vec![5.0_f64, 6.0]).unwrap(),
ctx,
).unwrap();
let c = a.matmul(&b).unwrap();
assert_eq!(c.shape(), &[2, 1]);
assert_eq!(c.materialized().unwrap().as_slice::<f64>().unwrap(), &[23.0, 34.0]);Sourcepub fn transpose(&self, perm: &[usize]) -> Result<Self>
pub fn transpose(&self, perm: &[usize]) -> Result<Self>
Permute tensor axes.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(
vec![2, 3],
vec![1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0],
).unwrap(), ctx.clone()).unwrap();
let y = x.transpose(&[1, 0]).unwrap();
assert_eq!(y.shape(), &[3, 2]);
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 3.0, 5.0, 2.0, 4.0, 6.0]);Sourcepub fn reshape(&self, shape: &[usize]) -> Result<Self>
pub fn reshape(&self, shape: &[usize]) -> Result<Self>
Reshape without changing element order.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(
vec![2, 3],
vec![1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0],
).unwrap(), ctx.clone()).unwrap();
let y = x.reshape(&[6]).unwrap();
assert_eq!(y.shape(), &[6]);
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 2.0, 3.0, 4.0, 5.0, 6.0]);Sourcepub fn slice(&self, config: SliceConfig) -> Result<Self>
pub fn slice(&self, config: SliceConfig) -> Result<Self>
Slice with explicit start, limit, and stride per axis.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, SliceConfig, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![4], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x
.slice(SliceConfig {
starts: vec![1],
limits: vec![3],
strides: vec![1],
})
.unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[2.0, 3.0]);Sourcepub fn broadcast_in_dim(&self, shape: &[usize], dims: &[usize]) -> Result<Self>
pub fn broadcast_in_dim(&self, shape: &[usize], dims: &[usize]) -> Result<Self>
Broadcast into a larger shape with explicit dimension placement.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![1.0_f64, 2.0, 3.0]).unwrap(), ctx.clone()).unwrap();
let y = x.broadcast_in_dim(&[3, 2], &[0]).unwrap();
assert_eq!(y.shape(), &[3, 2]);Sourcepub fn convert(&self, to: DType) -> Result<Self>
pub fn convert(&self, to: DType) -> Result<Self>
Convert the tensor to a different dtype using checked conversion.
Use cast when a lossy dtype projection is intended.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{DType, EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, -2.0]).unwrap(), ctx.clone()).unwrap();
let y = x.convert(DType::C64).unwrap();
assert_eq!(y.dtype(), DType::C64);
assert_eq!(y.shape(), &[2]);§Errors
Returns an error when the requested conversion is outside tenferro’s
checked dtype-promotion lattice. Use cast for explicit
lossy dtype projection.
Sourcepub fn cast(&self, to: DType) -> Result<Self>
pub fn cast(&self, to: DType) -> Result<Self>
Cast the tensor to a different dtype using explicit dtype projection.
cast may truncate, narrow precision, project complex values to their
real component, or use boolean truthiness where the backend supports the
requested projection.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{DType, EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.2_f64, -2.8]).unwrap(), ctx.clone()).unwrap();
let y = x.cast(DType::I32).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<i32>().unwrap(), &[1, -2]);Sourcepub fn pad(&self, config: PadConfig) -> Result<Self>
pub fn pad(&self, config: PadConfig) -> Result<Self>
Pad with zeros using StableHLO-style edge and interior padding.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, PadConfig, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let y = x
.pad(PadConfig {
edge_padding_low: vec![1],
edge_padding_high: vec![1],
interior_padding: vec![1],
})
.unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.0, 1.0, 0.0, 2.0, 0.0]);Sourcepub fn reverse(&self, axes: &[usize]) -> Result<Self>
pub fn reverse(&self, axes: &[usize]) -> Result<Self>
Reverse the order of elements along the requested axes.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![4], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.reverse(&[0]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[4.0, 3.0, 2.0, 1.0]);Sourcepub fn gather(&self, indices: &Self, config: GatherConfig) -> Result<Self>
pub fn gather(&self, indices: &Self, config: GatherConfig) -> Result<Self>
Gather slices from self using integer start indices.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, GatherConfig, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(
vec![5],
vec![10.0_f64, 20.0, 30.0, 40.0, 50.0],
).unwrap(), ctx.clone()).unwrap();
let indices = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![4_i64, 1, 0]).unwrap(), ctx.clone()).unwrap();
let y = x
.gather(
&indices,
GatherConfig {
offset_dims: vec![],
collapsed_slice_dims: vec![0],
start_index_map: vec![0],
index_vector_dim: 1,
slice_sizes: vec![1],
},
)
.unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[50.0, 20.0, 10.0]);Sourcepub fn scatter(
&self,
indices: &Self,
updates: &Self,
config: ScatterConfig,
) -> Result<Self>
pub fn scatter( &self, indices: &Self, updates: &Self, config: ScatterConfig, ) -> Result<Self>
Scatter updates into self using StableHLO scatter semantics.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, ScatterConfig, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let operand = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![4], vec![0.0_f64, 0.0, 0.0, 0.0]).unwrap(), ctx.clone()).unwrap();
let indices = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 1], vec![1_i64, 3]).unwrap(), ctx.clone()).unwrap();
let updates = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![5.0_f64, 7.0]).unwrap(), ctx.clone()).unwrap();
let result = operand
.scatter(
&indices,
&updates,
ScatterConfig {
update_window_dims: vec![],
inserted_window_dims: vec![0],
scatter_dims_to_operand_dims: vec![0],
index_vector_dim: 1,
},
)
.unwrap();
assert_eq!(result.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.0, 5.0, 0.0, 7.0]);Sourcepub fn dynamic_slice(&self, starts: &Self, sizes: &[usize]) -> Result<Self>
pub fn dynamic_slice(&self, starts: &Self, sizes: &[usize]) -> Result<Self>
Slice using runtime start indices.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![5], vec![1.0_f64, 2.0, 3.0, 4.0, 5.0]).unwrap(), ctx.clone()).unwrap();
let starts = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![2_i64]).unwrap(), ctx.clone()).unwrap();
let y = x.dynamic_slice(&starts, &[2]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[3.0, 4.0]);Sourcepub fn concatenate(tensors: &[&Self], axis: usize) -> Result<Self>
pub fn concatenate(tensors: &[&Self], axis: usize) -> Result<Self>
Concatenate tensors along one axis.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 4.0]).unwrap(), ctx.clone()).unwrap();
let z = EagerTensor::concatenate(&[&x, &y], 0).unwrap();
assert_eq!(z.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 2.0, 3.0, 4.0]);Sourcepub fn extract_diag(&self, axis_a: usize, axis_b: usize) -> Result<Self>
pub fn extract_diag(&self, axis_a: usize, axis_b: usize) -> Result<Self>
Extract the diagonal along two axes.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(
vec![3, 3],
vec![1.0_f64, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0],
).unwrap(), ctx.clone()).unwrap();
let y = x.extract_diag(0, 1).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 5.0, 9.0]);Sourcepub fn embed_diag(&self, axis_a: usize, axis_b: usize) -> Result<Self>
pub fn embed_diag(&self, axis_a: usize, axis_b: usize) -> Result<Self>
Embed a vector or lower-rank tensor along a diagonal.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![1.0_f64, 2.0, 3.0]).unwrap(), ctx.clone()).unwrap();
let y = x.embed_diag(0, 1).unwrap();
assert_eq!(y.shape(), &[3, 3]);
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 0.0, 0.0, 0.0, 2.0, 0.0, 0.0, 0.0, 3.0]);Sourcepub fn tril(&self, k: i64) -> Result<Self>
pub fn tril(&self, k: i64) -> Result<Self>
Keep the lower triangle and zero the rest.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.tril(0).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 2.0, 0.0, 4.0]);Sourcepub fn triu(&self, k: i64) -> Result<Self>
pub fn triu(&self, k: i64) -> Result<Self>
Keep the upper triangle and zero the rest.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.triu(0).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 0.0, 3.0, 4.0]);Sourcepub fn reduce_prod(&self, axes: &[usize]) -> Result<Self>
pub fn reduce_prod(&self, axes: &[usize]) -> Result<Self>
Reduce product over the requested axes.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.reduce_prod(&[0, 1]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[24.0]);Sourcepub fn reduce_max(&self, axes: &[usize]) -> Result<Self>
pub fn reduce_max(&self, axes: &[usize]) -> Result<Self>
Reduce maximum over the requested axes.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.reduce_max(&[0, 1]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[4.0]);Sourcepub fn reduce_min(&self, axes: &[usize]) -> Result<Self>
pub fn reduce_min(&self, axes: &[usize]) -> Result<Self>
Reduce minimum over the requested axes.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.reduce_min(&[0, 1]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0]);Source§impl EagerTensor
impl EagerTensor
Sourcepub fn abs(&self) -> Result<Self>
pub fn abs(&self) -> Result<Self>
Elementwise absolute value.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![-1.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let y = x.abs().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 2.0]);Sourcepub fn conj(&self) -> Result<Self>
pub fn conj(&self) -> Result<Self>
Elementwise complex conjugate.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, -2.0]).unwrap(), ctx.clone()).unwrap();
let y = x.conj().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, -2.0]);Sourcepub fn sign(&self) -> Result<Self>
pub fn sign(&self) -> Result<Self>
Elementwise sign.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![-2.0_f64, 3.0]).unwrap(), ctx.clone()).unwrap();
let y = x.sign().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[-1.0, 1.0]);Sourcepub fn log(&self) -> Result<Self>
pub fn log(&self) -> Result<Self>
Elementwise natural logarithm.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![1.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.log().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.0]);Sourcepub fn sqrt(&self) -> Result<Self>
pub fn sqrt(&self) -> Result<Self>
Elementwise square root.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![4.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.sqrt().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[2.0]);Sourcepub fn rsqrt(&self) -> Result<Self>
pub fn rsqrt(&self) -> Result<Self>
Elementwise reciprocal square root.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![4.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.rsqrt().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.5]);Sourcepub fn sin(&self) -> Result<Self>
pub fn sin(&self) -> Result<Self>
Elementwise sine.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![0.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.sin().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.0]);Sourcepub fn cos(&self) -> Result<Self>
pub fn cos(&self) -> Result<Self>
Elementwise cosine.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![0.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.cos().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0]);Sourcepub fn tanh(&self) -> Result<Self>
pub fn tanh(&self) -> Result<Self>
Elementwise hyperbolic tangent.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![0.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.tanh().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.0]);Sourcepub fn expm1(&self) -> Result<Self>
pub fn expm1(&self) -> Result<Self>
Elementwise exp(x) - 1.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![0.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.expm1().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.0]);Sourcepub fn log1p(&self) -> Result<Self>
pub fn log1p(&self) -> Result<Self>
Elementwise log(1 + x).
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![1], vec![0.0_f64]).unwrap(), ctx.clone()).unwrap();
let y = x.log1p().unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[0.0]);Sourcepub fn div(&self, other: &Self) -> Result<Self>
pub fn div(&self, other: &Self) -> Result<Self>
Elementwise division.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![8.0_f64, -6.0, 9.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![2.0_f64, 3.0, 3.0]).unwrap(), ctx.clone()).unwrap();
let z = x.div(&y).unwrap();
assert_eq!(z.materialized().unwrap().as_slice::<f64>().unwrap(), &[4.0, -2.0, 3.0]);Sourcepub fn pow(&self, other: &Self) -> Result<Self>
pub fn pow(&self, other: &Self) -> Result<Self>
Elementwise power.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let base = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![2.0_f64, 3.0]).unwrap(), ctx.clone()).unwrap();
let exp = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let y = base.pow(&exp).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[8.0, 9.0]);Sourcepub fn maximum(&self, other: &Self) -> Result<Self>
pub fn maximum(&self, other: &Self) -> Result<Self>
Elementwise maximum.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 5.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 4.0]).unwrap(), ctx.clone()).unwrap();
let z = x.maximum(&y).unwrap();
assert_eq!(z.materialized().unwrap().as_slice::<f64>().unwrap(), &[3.0, 5.0]);Sourcepub fn minimum(&self, other: &Self) -> Result<Self>
pub fn minimum(&self, other: &Self) -> Result<Self>
Elementwise minimum.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 5.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![3.0_f64, 4.0]).unwrap(), ctx.clone()).unwrap();
let z = x.minimum(&y).unwrap();
assert_eq!(z.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 4.0]);Sourcepub fn compare(&self, other: &Self, dir: CompareDir) -> Result<Self>
pub fn compare(&self, other: &Self, dir: CompareDir) -> Result<Self>
Elementwise comparison.
Sourcepub fn select(condition: &Self, on_true: &Self, on_false: &Self) -> Result<Self>
pub fn select(condition: &Self, on_true: &Self, on_false: &Self) -> Result<Self>
Select values from on_true or on_false using condition.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let condition = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![false, true]).unwrap(), ctx.clone()).unwrap();
let on_true = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![10.0_f64, 20.0]).unwrap(), ctx.clone()).unwrap();
let on_false = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![2], vec![1.0_f64, 2.0]).unwrap(), ctx.clone()).unwrap();
let y = EagerTensor::select(&condition, &on_true, &on_false).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 20.0]);Sourcepub fn where_select(
condition: &Self,
on_true: &Self,
on_false: &Self,
) -> Result<Self>
pub fn where_select( condition: &Self, on_true: &Self, on_false: &Self, ) -> Result<Self>
Select values from on_true or on_false using condition.
Sourcepub fn clamp(&self, lower: &Self, upper: &Self) -> Result<Self>
pub fn clamp(&self, lower: &Self, upper: &Self) -> Result<Self>
Clamp values elementwise between lower and upper bounds.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![-2.0_f64, 0.5, 5.0]).unwrap(), ctx.clone()).unwrap();
let lower = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![-1.0_f64, 0.0, 1.0]).unwrap(), ctx.clone()).unwrap();
let upper = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![3], vec![1.0_f64, 2.0, 4.0]).unwrap(), ctx.clone()).unwrap();
let y = x.clamp(&lower, &upper).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[-1.0, 0.5, 4.0]);Source§impl EagerTensor
impl EagerTensor
Sourcepub fn take_axis(&self, axis: usize, indices: &[usize]) -> Result<Self>
pub fn take_axis(&self, axis: usize, indices: &[usize]) -> Result<Self>
Select entries from one axis using host-known indices.
The index list is primal metadata: gradients flow to self, including
accumulation for repeated indices, but not to the selected positions.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(
Tensor::from_vec_col_major(vec![3], vec![10.0_f64, 20.0, 30.0]).unwrap(),
ctx,
).unwrap();
let y = x.take_axis(0, &[2, 0]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[30.0, 10.0]);Sourcepub fn take_rows(&self, rows: &[usize]) -> Result<Self>
pub fn take_rows(&self, rows: &[usize]) -> Result<Self>
Select matrix rows using host-known row indices.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(
Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(),
ctx,
).unwrap();
let y = x.take_rows(&[1]).unwrap();
assert_eq!(y.shape(), &[1, 2]);
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[2.0, 4.0]);Sourcepub fn take_cols(&self, cols: &[usize]) -> Result<Self>
pub fn take_cols(&self, cols: &[usize]) -> Result<Self>
Select matrix columns using host-known column indices.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(
Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(),
ctx,
).unwrap();
let y = x.take_cols(&[1]).unwrap();
assert_eq!(y.shape(), &[2, 1]);
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[3.0, 4.0]);Sourcepub fn take_block(&self, rows: &[usize], cols: &[usize]) -> Result<Self>
pub fn take_block(&self, rows: &[usize], cols: &[usize]) -> Result<Self>
Select a matrix block using host-known row and column indices.
This is a convenience wrapper over row selection followed by column selection. The row and column lists, plus the approximation rank implied by their lengths, are fixed primal metadata.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(
Tensor::from_vec_col_major(vec![2, 2], vec![1.0_f64, 2.0, 3.0, 4.0]).unwrap(),
ctx,
).unwrap();
let y = x.take_block(&[1], &[0]).unwrap();
assert_eq!(y.shape(), &[1, 1]);
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[2.0]);Sourcepub fn index_select(&self, axis: isize, positions: &[usize]) -> Result<Self>
pub fn index_select(&self, axis: isize, positions: &[usize]) -> Result<Self>
Select entries from one axis using host-known positions.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let x = EagerTensor::from_tensor_in(
Tensor::from_vec_col_major(vec![3], vec![10.0_f64, 20.0, 30.0]).unwrap(),
ctx,
).unwrap();
let y = x.index_select(-1, &[2, 0]).unwrap();
assert_eq!(y.materialized().unwrap().as_slice::<f64>().unwrap(), &[30.0, 10.0]);Sourcepub fn stack(tensors: &[&Self], dim: isize) -> Result<Self>
pub fn stack(tensors: &[&Self], dim: isize) -> Result<Self>
Stack tensors along a newly inserted axis.
The returned tensor uses the context of the first input, matching
Self::concatenate. All inputs must belong to that same context.
§Examples
use tenferro_cpu::CpuBackend;
use tenferro_ad::{EagerRuntime, EagerTensor, Tensor};
let ctx = EagerRuntime::with_cpu_backend(CpuBackend::new());
let a = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![], vec![1.0_f64]).unwrap(), ctx.clone()).unwrap();
let b = EagerTensor::from_tensor_in(Tensor::from_vec_col_major(vec![], vec![2.0_f64]).unwrap(), ctx).unwrap();
let out = EagerTensor::stack(&[&a, &b], -1).unwrap();
assert_eq!(out.shape(), &[2]);
assert_eq!(out.materialized().unwrap().as_slice::<f64>().unwrap(), &[1.0, 2.0]);Trait Implementations§
Source§impl Add for &EagerTensor
impl Add for &EagerTensor
Source§fn add(self, rhs: &EagerTensor) -> Result<EagerTensor>
fn add(self, rhs: &EagerTensor) -> Result<EagerTensor>
+ operation. Read moreSource§impl Clone for EagerTensor
impl Clone for EagerTensor
Source§fn clone(&self) -> EagerTensor
fn clone(&self) -> EagerTensor
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for EagerTensor
impl Debug for EagerTensor
Source§impl Div for &EagerTensor
impl Div for &EagerTensor
Source§fn div(self, rhs: &EagerTensor) -> Result<EagerTensor>
fn div(self, rhs: &EagerTensor) -> Result<EagerTensor>
/ operation. Read moreSource§impl Mul for &EagerTensor
impl Mul for &EagerTensor
Source§fn mul(self, rhs: &EagerTensor) -> Result<EagerTensor>
fn mul(self, rhs: &EagerTensor) -> Result<EagerTensor>
* operation. Read moreSource§impl Neg for &EagerTensor
impl Neg for &EagerTensor
Source§impl Sub for &EagerTensor
impl Sub for &EagerTensor
Source§fn sub(self, rhs: &EagerTensor) -> Result<EagerTensor>
fn sub(self, rhs: &EagerTensor) -> Result<EagerTensor>
- operation. Read moreAuto Trait Implementations§
impl Freeze for EagerTensor
impl !RefUnwindSafe for EagerTensor
impl Send for EagerTensor
impl Sync for EagerTensor
impl Unpin for EagerTensor
impl UnsafeUnpin for EagerTensor
impl !UnwindSafe for EagerTensor
Blanket Implementations§
§impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
type Output = Output
fn add_by_ref(&self, rhs: &Rhs) -> <Lhs as AddByRef<Rhs>>::Output
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> DistributionExt for Twhere
T: ?Sized,
impl<T> DistributionExt for Twhere
T: ?Sized,
fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> Twhere
Self: Distribution<T>,
§impl<Rhs, Lhs, Output> DivByRef<Rhs> for Lhs
impl<Rhs, Lhs, Output> DivByRef<Rhs> for Lhs
type Output = Output
fn div_by_ref(&self, rhs: &Rhs) -> <Lhs as DivByRef<Rhs>>::Output
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more