Skip to content

Commit

Permalink
WIP: Layout Doc
Browse files Browse the repository at this point in the history
  • Loading branch information
tbetcke committed Aug 23, 2022
1 parent 0b4c654 commit 521eeb4
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 14 deletions.
16 changes: 16 additions & 0 deletions katex-header.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.css" integrity="sha384-9eLZqc9ds8eNjO3TmqPeYcDj8n+Qfa4nuSiGYa6DjLNcv9BtN69ZIulL9+8CqC9Y" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/katex.min.js" integrity="sha384-K3vbOmF2BtaVai+Qk37uypf7VrgBubhQreNQe9aGsz9lB63dIFiQVlJbr92dw2Lx" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/contrib/auto-render.min.js" integrity="sha384-kmZOZB5ObwgQnS/DuDg6TScgOiWWBiVt0plIRkZCmE6rDZGrEOQeHM5PcHi+nyqe" crossorigin="anonymous"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(document.body, {
delimiters: [
{left: "$$", right: "$$", display: true},
{left: "\\(", right: "\\)", display: false},
{left: "$", right: "$", display: false},
{left: "\\[", right: "\\]", display: true}
]
});
});
</script>
73 changes: 73 additions & 0 deletions src/traits/layout.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,76 @@
//! Layout Definitions
//!
//! The traits in this module determine the memory layout of a matrix.
//! Consider a simple matrix of the form
//! \\[
//! A = \begin{bmatrix}1 & 2\\\\
//! 3 & 4
//! \end{bmatrix}
//! \\]
//!
//! In **row-major** form this matrix is stored in memory in the order
//! $\begin{bmatrix}1 & 2 & 3 & 4\end{bmatrix}$ In **column-major** form the matrix is stored in memory
//! as $\begin{bmatrix}1 & 3 & 2 & 4\end{bmatrix}$. These are the two most commonly used
//! storage formats for matrices. A more general way of describing the memory ordering of matrix
//! elements is to introduce a stride tuple `(r, c)`. The meaning is that in memory we have
//! to walk `r` positions to go from one row to the next, and `c` positions to walk from one
//! column to the next. For the matrix $A$ the stride tuple is `(2, 1)` in **row-major**
//! and `(1, 2)` in **column-major** form.
//!
//! Strides arise naturally in the description of submatrices.
//! Imagine that the matrix $A$ is a submatrix of the bigger matrix.
//! \\[
//! B = \begin{bmatrix}1 & 2 & x\\\\
//! 3 & 4 & x\\\\
//! x & x & x
//! \end{bmatrix},
//! \\]
//! where the $x$ are placeholders for some arbitrary numbers. A **row-major** layout of this matrix
//! is given as
//! \\[
//! \begin{bmatrix}1 & 2 & x & 3 & 4 & x & x & x & x\end{bmatrix}
//! \\]
//! If we wanted to describe the submatrix $A$ we could take the elements
//! $\begin{bmatrix}1 & 2 & x & 3 & 4\end{bmatrix}$. The stride tuple associated with this
//! layout is `(3, 1)`. The distance of elements within each row is `1` and the distance within
//! each column is `3`.
//!
//! However, more complicated layouts are possible (e.g. a storage layout for upper triangular
//! matrices). The trait here ensures as much generality as possible in defining memory
//! layouts.
//!
//! Each matrix is assigned with a logical indexing that is either **row-major** or **column-major**
//! and a physical layout. The logial indexing just determines whether a one-dimensional iterator
//! iterates through the matrix elements by row or by column. Consider again that $A$ is submatrix
//! of a larger $3\times 3$ matrix stored in **row-major** form. A logical **row-major** traversal
//! of $A$ will always return *\begin{bmatrix}1 & 2 & 3 & 4\end{bmatrix}$ independent of the
//! underlying physical layout.
//!
//! The logical indexing is determined by the two methods [convert_1d_2d](crate::traits::LayoutType::convert_1d_2d)
//! and [convert_2d_1d](crate::traits::LayoutType::convert_2d_1d). These methods map between
//! logical `(row, col)` index tuples and one dimensional indices. The translation to the
//! underlying physical memory locations is handled by the routines [convert_1d_raw](crate::traits::LayoutType::convert_1d_raw)
//! and [convert_2d_raw](crate::traits::LayoutType::convert_2d_raw), which convert either
//! a two dimensional `(row, col)` index or a one-dimensional index to the raw physical location.
//! For base **row-major** and **column-major** storage types the physical and logical layout
//! are typical identical. But for more complex types (e.g. with arbitrary stride vectors) they
//! are typically different from each other.
//!
//! The main trait in this module is the [LayoutType](crate::traits::LayoutType) trait.
//! If this is implemented for a matrix the [Layout](crate::traits::Layout) is auto-implemented.
//! This latter trait only provides a method to return the [LayoutType] implementation.
//! This crate also provides a number of other traits.
//! - [BaseLayoutType]: Derives from [LayoutType]
//! and marks simple base traits that are suitable
//! for logical indexing. Instantiations only depend on the matrix
//! dimension and not e.g. non-standard strides.
//! - [VectorBaseLayoutType]: Derives from [BaseLayoutType]
//! and marks base layouts for vectors. Only requires the
//! length of the vector for instantiation.
//! - [MatrixBaseLayoutType]: Derives from [BaseLayoutType]
//! and marks base layouts for matrices.
//! - [StridedLayoutType]: Derives from [LayoutType] and
//! marks layouts with non-trivial strides.
use crate::types::IndexType;

Expand All @@ -15,6 +87,7 @@ pub trait MatrixBaseLayoutType: BaseLayoutType {}
pub trait StridedLayoutType: LayoutType {}

pub trait LayoutType {

type IndexLayout: BaseLayoutType;

fn stride(&self) -> (IndexType, IndexType);
Expand Down
35 changes: 21 additions & 14 deletions src/traits/random_access.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
//!
//! The traits in this module define safe and unsafe random access
//! methods for a matrix. The user needs to implement `UnsafeRandomAccess`
//! and `UnsafeRandomAccessMut` (for mutable access). The corresponding safe
//! traits `SafeRandomAccess` and `SafeRandomAccessMut` are then auto-implemented.
//! The safe traits check at runtime whether an index is out of bounds.
//! and `UnsafeRandomAccessMut` (for mutable access).
//!
//! If additionally the [Layout](crate::traits::Layout) is implemented (aut-implemented
//! if the [LayoutType](crate::traits::LayoutType) trait is implemented), then
//! he corresponding safe traits `SafeRandomAccess` and
//! `SafeRandomAccessMut` are auto-implemented.
//!
//! Each trait provides a two-dimensional and a one-dimensional access method,
//! namely `get` and `get1d` (together with their mutable and unsafe variants).
Expand All @@ -13,8 +16,7 @@
//!
//! The one-dimensional access
//! takes a single `index` parameter that iterates through the matrix elements.
//! If also the [LayoutType](crate::traits::LayoutType) is implemented, it is
//! recommended to use the [convert_1d_raw](crate::traits::LayoutType::convert_1d_raw)
//! It is recommended to use the [convert_1d_raw](crate::traits::LayoutType::convert_1d_raw)
//! functions from that trait to implement `get1d` to ensure compatibility with
//! the memory layout defined in that trait.
Expand Down Expand Up @@ -47,25 +49,29 @@ pub trait UnsafeRandomAccessMut {
}

/// This trait provides bounds checked access to the underlying data. See
/// [Random Access](crate::traits::random_access) for a description. It depends
/// on the [Layout](crate::traits::Layout) trait to obtain dimension information.
pub trait RandomAccess: UnsafeRandomAccess + Layout {
/// Get the element at position (row, col) of the matrix.
/// [Random Access](crate::traits::random_access) for a description.
pub trait RandomAccess: UnsafeRandomAccess {

/// Return the element at position (`row`, `col`).
fn get(&self, row: usize, col: usize) -> Self::Item;

/// Get element from matrix linearized as 1d array (result depends on memory layout).
/// Return the element at position `index` in one-dimensional numbering.
fn get1d(&self, elem: usize) -> Self::Item;
}

/// Bounds checked mutable random access for matrices.
pub trait RandomAccessMut: UnsafeRandomAccessMut + Layout {
/// Get mutable reference to element at position (row, col) of the matrix.
/// This trait provides bounds checked mutable access to the underlying data. See
/// [Random Access](crate::traits::random_access) for a description.
pub trait RandomAccessMut: UnsafeRandomAccessMut {

/// Return a mutable reference to the element at position (`row`, `col`).
fn get_mut(&mut self, row: usize, col: usize) -> &mut Self::Item;
/// Get mutable reference from matrix linearized as 1d array (result depends on memory layout).

/// Return a mutable reference at position `index` in one-dimensional numbering.
fn get1d_mut(&mut self, elem: usize) -> &mut Self::Item;
}


/// Check that a given pair of `row` and `col` is not out of bounds for given dimension `dim`.
#[inline]
fn assert_dimension(row: IndexType, col: IndexType, dim: (IndexType, IndexType)) {
assert!(
Expand All @@ -84,6 +90,7 @@ fn assert_dimension(row: IndexType, col: IndexType, dim: (IndexType, IndexType))
);
}

/// Check that a given `index` parameter is not out of bounds for `nelems` elements.
#[inline]
fn assert_dimension1d(elem: IndexType, nelems: IndexType) {
assert!(
Expand Down

0 comments on commit 521eeb4

Please sign in to comment.