Skip to main content

EagerTensor

Struct EagerTensor 

Source
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

Source

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]);
Source

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());
Source

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());
Source

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());
Source

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]);
Source

pub fn dtype(&self) -> DType

Return this tensor’s scalar dtype without materializing through materialized.

Source

pub fn shape(&self) -> &[usize]

Return this tensor’s logical shape without materializing through materialized.

Source

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.

Source

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.

Source

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]);
Source

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());
Source

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());
Source

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());
Source

pub fn runtime(&self) -> &Arc<EagerRuntime>

Borrow the eager runtime context that owns this tensor.

Source

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));
Source

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

Source

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]);
Source

pub fn sub(&self, other: &Self) -> Result<Self>

Elementwise subtraction.

Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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.

Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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.

Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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

Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

pub fn compare(&self, other: &Self, dir: CompareDir) -> Result<Self>

Elementwise comparison.

Source

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]);
Source

pub fn where_select( condition: &Self, on_true: &Self, on_false: &Self, ) -> Result<Self>

Select values from on_true or on_false using condition.

Source

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

Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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]);
Source

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

Source§

type Output = Result<EagerTensor, Error>

The resulting type after applying the + operator.
Source§

fn add(self, rhs: &EagerTensor) -> Result<EagerTensor>

Performs the + operation. Read more
Source§

impl Clone for EagerTensor

Source§

fn clone(&self) -> EagerTensor

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for EagerTensor

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Div for &EagerTensor

Source§

type Output = Result<EagerTensor, Error>

The resulting type after applying the / operator.
Source§

fn div(self, rhs: &EagerTensor) -> Result<EagerTensor>

Performs the / operation. Read more
Source§

impl Mul for &EagerTensor

Source§

type Output = Result<EagerTensor, Error>

The resulting type after applying the * operator.
Source§

fn mul(self, rhs: &EagerTensor) -> Result<EagerTensor>

Performs the * operation. Read more
Source§

impl Neg for &EagerTensor

Source§

type Output = Result<EagerTensor, Error>

The resulting type after applying the - operator.
Source§

fn neg(self) -> Result<EagerTensor>

Performs the unary - operation. Read more
Source§

impl Sub for &EagerTensor

Source§

type Output = Result<EagerTensor, Error>

The resulting type after applying the - operator.
Source§

fn sub(self, rhs: &EagerTensor) -> Result<EagerTensor>

Performs the - operation. Read more

Auto Trait Implementations§

Blanket Implementations§

§

impl<Rhs, Lhs, Output> AddByRef<Rhs> for Lhs
where &'a Lhs: for<'a> Add<&'a Rhs, Output = Output>,

§

type Output = Output

§

fn add_by_ref(&self, rhs: &Rhs) -> <Lhs as AddByRef<Rhs>>::Output

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
§

impl<T> ByRef<T> for T

§

fn by_ref(&self) -> &T

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
§

impl<T> DistributionExt for T
where T: ?Sized,

§

fn rand<T>(&self, rng: &mut (impl Rng + ?Sized)) -> T
where Self: Distribution<T>,

§

impl<Rhs, Lhs, Output> DivByRef<Rhs> for Lhs
where &'a Lhs: for<'a> Div<&'a Rhs, Output = Output>,

§

type Output = Output

§

fn div_by_ref(&self, rhs: &Rhs) -> <Lhs as DivByRef<Rhs>>::Output

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<Rhs, Lhs, Output> MulByRef<Rhs> for Lhs
where &'a Lhs: for<'a> Mul<&'a Rhs, Output = Output>,

§

type Output = Output

§

fn mul_by_ref(&self, rhs: &Rhs) -> <Lhs as MulByRef<Rhs>>::Output

§

impl<T, Output> NegByRef for T
where &'a T: for<'a> Neg<Output = Output>,

§

type Output = Output

§

fn neg_by_ref(&self) -> <T as NegByRef>::Output

§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

impl<Rhs, Lhs, Output> SubByRef<Rhs> for Lhs
where &'a Lhs: for<'a> Sub<&'a Rhs, Output = Output>,

§

type Output = Output

§

fn sub_by_ref(&self, rhs: &Rhs) -> <Lhs as SubByRef<Rhs>>::Output

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

§

impl<T, U> Imply<T> for U
where T: ?Sized, U: ?Sized,

§

impl<T> MaybeSend for T
where T: Send,

§

impl<T> MaybeSendSync for T
where T: Send + Sync,

§

impl<T> MaybeSync for T
where T: Sync,

§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,