diff --git a/Src/ILGPU.Algorithms/Vectors/VectorView.cs b/Src/ILGPU.Algorithms/Vectors/VectorView.cs
new file mode 100644
index 000000000..b5ec0259a
--- /dev/null
+++ b/Src/ILGPU.Algorithms/Vectors/VectorView.cs
@@ -0,0 +1,210 @@
+// ---------------------------------------------------------------------------------------
+// ILGPU Algorithms
+// Copyright (c) 2023 ILGPU Project
+// www.ilgpu.net
+//
+// File: VectorView.cs
+//
+// This file is part of ILGPU and is distributed under the University of Illinois Open
+// Source License. See LICENSE.txt for details.
+// ---------------------------------------------------------------------------------------
+
+using ILGPU.Runtime;
+using System.Diagnostics;
+using System.Runtime.CompilerServices;
+
+#pragma warning disable CA1043 // Use integral or string argument for indexers
+#pragma warning disable CA1000 // Do not declare static members on generic types
+#pragma warning disable CA2225 // Provide named methods as alternative for operators
+
+namespace ILGPU.Algorithms.Vectors
+{
+ ///
+ /// Represents a single 64bit-addressed vector view in memory with a specific stride
+ /// that accesses all values in a stride way using the following memory layout:
+ /// (x1, x2, x3, x4, ... xN) | (y1, y2, y3, y4, ... yN),
+ /// where N is the dimension of the vector and the stride is equal to the number of
+ /// vectors.
+ ///
+ /// The underlying element type.
+ public readonly struct SingleVectorView
+ where T : unmanaged
+ {
+ private readonly ArrayView dataView;
+
+ ///
+ /// Constructs a new vector view pointing to a single vector.
+ ///
+ /// The source linear vector view.
+ /// The number of vectors.
+ /// The vector dimension of each vector.
+ /// The current vector index.
+ public SingleVectorView(
+ ArrayView vectorView,
+ LongIndex1D numVectors,
+ Index1D dimension,
+ LongIndex1D vectorIndex)
+ {
+ dataView = vectorView;
+
+ NumVectors = numVectors;
+ Dimension = dimension;
+ VectorIndex = vectorIndex;
+ }
+
+ ///
+ /// Constructs a new vector view pointing to a single vector.
+ ///
+ ///
+ /// The source linear vector view using the stride information as the number of
+ /// vectors this view points to.
+ ///
+ /// The vector dimension of each vector.
+ /// The current vector index.
+ public SingleVectorView(
+ ArrayView1D vectorView,
+ Index1D dimension,
+ LongIndex1D vectorIndex)
+ {
+ dataView = vectorView.BaseView;
+
+ NumVectors = vectorView.Stride.StrideExtent;
+ Dimension = dimension;
+ VectorIndex = vectorIndex;
+ }
+
+ ///
+ /// Returns true if this view points to a valid location.
+ ///
+ public bool IsValid => dataView.IsValid;
+
+ ///
+ /// Returns the generic stride of this single vector view.
+ ///
+ public LongIndex1D NumVectors { get; }
+
+ ///
+ /// Returns the general vector index of this vector view
+ ///
+ public LongIndex1D VectorIndex { get; }
+
+ ///
+ /// Returns the dimension of this vector.
+ ///
+ public Index1D Dimension { get; }
+
+ ///
+ /// Returns a reference to the i-th vector element.
+ ///
+ /// The element index.
+ public ref T this[Index1D elementIndex]
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ Trace.Assert(
+ elementIndex < Dimension,
+ "Element index out of range");
+ return ref dataView[elementIndex * NumVectors + VectorIndex];
+ }
+ }
+
+ ///
+ /// Converts a general data view into a single vector view.
+ ///
+ /// The source data view to convert.
+ /// The converted 64bit addressed vector view.
+ public static implicit operator SingleVectorView(
+ ArrayView1D dataView) =>
+ new(dataView, dataView.IntLength, 0);
+ }
+
+ ///
+ /// Represents a 64bit-addressed vector view in memory with a specific stride
+ /// that accesses all values in a stride way using the following memory layout:
+ /// (x1, x2, x3, x4, ... xN) | (y1, y2, y3, y4, ... yN),
+ /// where N is the dimension of the vector and the stride is equal to the number of
+ /// vectors.
+ ///
+ /// The underlying element type.
+ public readonly struct VectorView
+ where T : unmanaged
+ {
+ ///
+ /// Allocates a new buffer compatible with this vector view.
+ ///
+ /// The accelerator to use.
+ /// The number of vectors to allocate.
+ /// The vector dimension of each vector.
+ /// The allocated memory buffer.
+ public static MemoryBuffer2D Allocate(
+ Accelerator accelerator,
+ LongIndex1D numVectors,
+ Index1D dimension) =>
+ accelerator.Allocate2DDenseY(
+ new LongIndex2D(dimension,
+ numVectors));
+
+ ///
+ /// Constructs a multi-vector view from the given 2D dense array view.
+ ///
+ /// The dense source array view.
+ public VectorView(ArrayView2D arrayView2D)
+ {
+ DataView = arrayView2D;
+ }
+
+ ///
+ /// Returns true if this view points to a valid location.
+ ///
+ public bool IsValid => DataView.IsValid;
+
+ ///
+ /// Returns the dimension of the vector.
+ ///
+ public Index1D Dimension => (Index1D)DataView.Extent.X;
+
+ ///
+ /// Returns the number of the vectors included in this view.
+ ///
+ public LongIndex1D NumVectors => DataView.Extent.Y;
+
+ ///
+ /// Returns the underlying dense array view.
+ ///
+ public ArrayView2D DataView { get; }
+
+ ///
+ /// Returns a reference to the j-th vector element of the i-th vector.
+ ///
+ /// The source vector index.
+ /// The element index.
+ public ref T this[LongIndex1D vectorIndex, Index1D elementIndex]
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get => ref DataView[elementIndex, vectorIndex];
+ }
+
+ ///
+ /// Returns a view to a single vector.
+ ///
+ /// The vector index.
+ /// The sliced view.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ public SingleVectorView SliceVector(LongIndex1D vectorIndex) =>
+ new(DataView.AsContiguous(), NumVectors, Dimension, vectorIndex);
+
+ ///
+ /// Converts a general data view into a vector view.
+ ///
+ /// The source data view to convert.
+ /// The converted 64bit addressed vector view.
+ public static implicit operator VectorView(
+ ArrayView2D dataView) =>
+ new(dataView);
+ }
+}
+
+#pragma warning restore CA2225
+#pragma warning restore CA1000
+#pragma warning restore CA1043