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

Add support for copying from Vector<T> to Span<T> #29929

Closed
surban opened this issue Jun 18, 2019 · 3 comments
Closed

Add support for copying from Vector<T> to Span<T> #29929

surban opened this issue Jun 18, 2019 · 3 comments
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Numerics
Milestone

Comments

@surban
Copy link

surban commented Jun 18, 2019

Currently Vector<T> can be constructed from a Span<T>, but writing the result of a vectorized operation into a Span<T> is impossible, since the Vector<T>.CopyTo method lacks the necessary overload.

Rationale and usage

The following code computes the sum of two arrays using SIMD operations and stores it in the trgt parameter.

        static void VectorizedArrayAdd(double[] trgt, double[] x, double[] y)
        {
            Debug.Assert(x.Length == y.Length && x.Length == trgt.Length);
            Debug.Assert(x.Length % Vector<double>.Count == 0);

            for (int i=0; i < x.Length; i += Vector<double>.Count)
            {
                var xv = new Vector<double>(x, i);
                var yv = new Vector<double>(y, i);
                var tv = xv + yv;
                tv.CopyTo(trgt, i);
            }
        }

Converting this code to accept Span<double> instead of double[] makes sense, for example to support operation on slices of arrays or on external memory. A first conversion attempt leads to the following code.

        static void VectorizedSpanAdd(Span<double> trgt, Span<double> x, Span<double> y)
        {
            Debug.Assert(x.Length == y.Length && x.Length == trgt.Length);
            Debug.Assert(x.Length % Vector<double>.Count == 0);

            for (int i = 0; i < x.Length; i += Vector<double>.Count)
            {
                var xs = x.Slice(i, Vector<double>.Count);
                var xv = new Vector<double>(xs);

                var ys = y.Slice(i, Vector<double>.Count);
                var yv = new Vector<double>(ys);

                var tv = xv + yv;
                var ts = trgt.Slice(i, Vector<double>.Count);
                tv.CopyTo(ts); // ERROR: Argument 1: cannot convert from 'System.Span<double>' to 'double[]' 
            }
        }

However, this fails to compile since Vector<double>.CopyTo(Span<double> x) does not exist.

Propsed API

Extend Vector<T> as follows.

public struct Vector<T> : IEquatable<System.Numerics.Vector<T>>, IFormattable where T : struct
{
    public void CopyTo(Span<T> destination);
}

Details

@scalablecory
Copy link
Contributor

scalablecory commented Jun 18, 2019

There's a standard feature for this already:

Span<byte> span;
Span<Vector<byte>> vector = MemoryMarshal.Cast<Vector<byte>, byte>(span);
vector[0] = ...;

We may need better documentation of this.

@tannergooding
Copy link
Member

We already added this in: dotnet/coreclr#23333

@tannergooding
Copy link
Member

It will be available in .NET Core 3.0 and should already be available in the latest public preview.

@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 3.0 milestone Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 12, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
api-suggestion Early API idea and discussion, it is NOT ready for implementation area-System.Numerics
Projects
None yet
Development

No branches or pull requests

4 participants