Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor storage types for views and mutable views #148

Merged
merged 9 commits into from
May 5, 2024
Merged

Conversation

robertknight
Copy link
Owner

@robertknight robertknight commented May 4, 2024

Previously tensor views used slices as their storage type (the TensorBase::data field).

When tensor operations create logically separate mutable views whose underlying storage ranges overlap (for example, a mutable iterator over the column axis of a matrix), this lead to violations of Rust's ownership rules. Miri's stacked borrows check complained about this.

This PR refactors tensor storage to address this:

  • TensorView and TensorViewMut now use custom types (ViewData, ViewMutData) instead of slices for their storage. These types have the same representation, but don't promise there is no overlap between a mutable storage and other storage instances. Instead the caller has to ensure that.
  • The signature of TensorBase has changed from TensorBase<T, S: AsRef<[T]>, L: MutLayout> to TensorBase<S: Storage, L: MutLayout> where Storage is a trait that is implemented by Vec<T>, Cow<[T]>, ViewData and ViewMutData. The Storage trait provides access to the underlying raw data. It has methods for getting a reference to the element at a given offset, but unlike AsRef these are unsafe, since the caller has to ensure that no mutable references can exist. The type of element in a TensorBase is now accessed via S::Elem
  • TensorBase::{non_contiguous_data, data_mut_ptr} have been replaced with TensorBase::{storage, storage_mut} for low-level code that needs to get at the underlying data pointer. non_contiguous_data was unsound due to the same issues as storage for mutable views.
  • make miri has been updated to re-enable the stacked borrows check.

Previously `&[T]` and `&mut [T]` were used as the storage types for
tensor views and mutable tensor views respectively. When logically
non-overlapping views are created of non-contigous tensors, their
underlying storages (ie. the memory ranges) may however overlap. Though
it has not caused a practical problem yet, it violates Rust's ownership
rules.

This refactor replaces the storage types for views with custom types
which have the same representation as slices, but do not have the same
ownership rules.

The goal is to prevent future mistakes caused by these ownership rule
violations, and also enable rten to be checked by Miri without disabling
the stacked borrows check.
Since mutable views no longer use mutable slices as their backing storage, Miri
doesn't complain if the storage ranges overlap. Note that the library still
needs to ensure that the logically accessible elements within each view do not
overlap.
Update following the changes to tensor storage.
@robertknight robertknight force-pushed the storage-trait branch 2 times, most recently from 62d2b4f to 65bf5c4 Compare May 5, 2024 07:34
The element type is part of the storage type, accessible via `Storage::Elem`, so
`TensorBase` doesn't need its own generic parameter for this.
Since `Storage` bypasses the Rust restriction on mutable slices not overlapping
other slices, the caller has to ensure this instead.

Also make these methods default methods in `Storage`, since the logic is
the same for each impl.
Replace the existing `TensorBase::{non_contiguous_data, data_mut_ptr}` methods
with `storage` and `storage_mut`, for low-level code that needs to get at the
underlying data pointer. `non_contiguous_data` was unsound in the case where the
view was not contiguous and overlapping mutable views existed.
@robertknight robertknight marked this pull request as ready for review May 5, 2024 08:23
@robertknight robertknight merged commit 0dda7a5 into main May 5, 2024
2 checks passed
@robertknight robertknight deleted the storage-trait branch May 5, 2024 08:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant