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