pub struct WengertList<T> { /* private fields */ }
Expand description

A list of operations performed in a forward pass of a dynamic computational graph, used for Reverse Mode Automatic Differentiation.

This is dynamic, as in, you build the Wengert list at runtime by performing operations like addition and multiplication on Records that were created with that Wengert list.

When you perform a backward pass to obtain the gradients you travel back up the computational graph using the stored intermediate values from this list to compute all the gradients of the inputs and every intermediate step with respect to an output.

Although sophisticated implementations can make the Wengert list only log(N) in length by storing only some of the intermediate steps of N computational steps, this implementation is not as sophisticated, and will store all of them.

Panics

Every operation and nearly every method a Record has involves manipulating the record’s history on its referenced WengertList. This WengertList itself maintains a RefCell which tracks borrows at runtime rather than compile time. This is neccessary to maintain the illusion that Records are just ordinary numbers, and the side effects of doing arithmetic with Records are limited to their referenced WengertList. Hence, the Rust compiler infers that it is not safe to share references to WengertLists between threads, nor transfer Records across threads. If you called a method on two Records that both mutably borrowed from the same WengertList at once, which could be trivially done with multiple threads, then the code would panic. Easy ML shouldn’t allow you to do this in safe Rust because each mutable borrow of the WengertList is dropped at the end of each Record method call, and you can’t call two methods simulatenously without threading.

Implementations§

source§

impl<T: Primitive> WengertList<T>

source

pub fn new() -> WengertList<T>

Creates a new empty WengertList from which Records can be constructed.

source§

impl<T> WengertList<T>

source

pub fn clear(&self)

Clears a WengertList to make it empty again. After clearing a WengertList you must reset all the Records still using that list. Then you can perform another computation and get new gradients.

source§

impl<T: Numeric + Primitive> WengertList<T>

source

pub fn variable(&self, x: T) -> Record<'_, T>

Creates a record backed by this WengertList.

You can alternatively use the record constructor on the Record type.

Trait Implementations§

source§

impl<T: Clone + Primitive> Clone for WengertList<T>

Any Wengert list of a Cloneable type implements clone

source§

fn clone(&self) -> Self

Returns a copy 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<T: Debug> Debug for WengertList<T>

source§

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

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

impl<T: Primitive> Default for WengertList<T>

source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<T> !RefUnwindSafe for WengertList<T>

§

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

§

impl<T> !Sync for WengertList<T>

§

impl<T> Unpin for WengertList<T>where
    T: Unpin,

§

impl<T> UnwindSafe for WengertList<T>where
    T: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

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

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

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

const: unstable · source§

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

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

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

const: unstable · 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> ToOwned for Twhere
    T: Clone,

§

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 Twhere
    U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.
source§

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

§

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

The type returned in the event of a conversion error.
const: unstable · source§

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

Performs the conversion.