Skip to content

Commit 06f9760

Browse files
committed
Refactor to using shared implementations for operators
1 parent e4ceb72 commit 06f9760

File tree

5 files changed

+1470
-399
lines changed

5 files changed

+1470
-399
lines changed

src/libraries/System.Numerics.Tensors/src/Resources/Strings.resx

+2-2
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,6 @@
121121
<value>Destination is too short.</value>
122122
</data>
123123
<data name="Argument_SpansMustHaveSameLength" xml:space="preserve">
124-
<value>Length of '{0}' must be same as length of '{1}'.</value>
124+
<value>Input span arguments must all have the same length.</value>
125125
</data>
126-
</root>
126+
</root>

src/libraries/System.Numerics.Tensors/src/System/Numerics/Tensors/TensorPrimitives.cs

-324
Original file line numberDiff line numberDiff line change
@@ -6,330 +6,6 @@ namespace System.Numerics.Tensors
66
/// <summary>Performs primitive tensor operations over spans of memory.</summary>
77
public static partial class TensorPrimitives
88
{
9-
/// <summary>Computes the element-wise result of: <c><paramref name="x" /> - <paramref name="y" /></c>.</summary>
10-
/// <param name="x">The first tensor, represented as a span.</param>
11-
/// <param name="y">The second tensor, represented as a scalar.</param>
12-
/// <param name="destination">The destination tensor, represented as a span.</param>
13-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="y" />'.</exception>
14-
/// <exception cref="ArgumentException">Destination is too short.</exception>
15-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = <paramref name="x" />[i] - <paramref name="y" />[i]</c>.</remarks>
16-
public static void Subtract(ReadOnlySpan<float> x, ReadOnlySpan<float> y, Span<float> destination)
17-
{
18-
if (x.Length != y.Length)
19-
{
20-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(y));
21-
}
22-
23-
if (x.Length > destination.Length)
24-
{
25-
ThrowHelper.ThrowArgument_DestinationTooShort();
26-
}
27-
28-
for (int i = 0; i < x.Length; i++)
29-
{
30-
destination[i] = x[i] - y[i];
31-
}
32-
}
33-
34-
/// <summary>Computes the element-wise result of: <c><paramref name="x" /> - <paramref name="y" /></c>.</summary>
35-
/// <param name="x">The first tensor, represented as a span.</param>
36-
/// <param name="y">The second tensor, represented as a scalar.</param>
37-
/// <param name="destination">The destination tensor, represented as a span.</param>
38-
/// <exception cref="ArgumentException">Destination is too short.</exception>
39-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = <paramref name="x" />[i] - <paramref name="y" /></c>.</remarks>
40-
public static void Subtract(ReadOnlySpan<float> x, float y, Span<float> destination)
41-
{
42-
if (x.Length > destination.Length)
43-
{
44-
ThrowHelper.ThrowArgument_DestinationTooShort();
45-
}
46-
47-
for (int i = 0; i < x.Length; i++)
48-
{
49-
destination[i] = x[i] - y;
50-
}
51-
}
52-
53-
/// <summary>Computes the element-wise result of: <c><paramref name="x" /> * <paramref name="y" /></c>.</summary>
54-
/// <param name="x">The first tensor, represented as a span.</param>
55-
/// <param name="y">The second tensor, represented as a span.</param>
56-
/// <param name="destination">The destination tensor, represented as a span.</param>
57-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="y" />'.</exception>
58-
/// <exception cref="ArgumentException">Destination is too short.</exception>
59-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = <paramref name="x" />[i] * <paramref name="y" /></c>.</remarks>
60-
public static void Multiply(ReadOnlySpan<float> x, ReadOnlySpan<float> y, Span<float> destination)
61-
{
62-
if (x.Length != y.Length)
63-
{
64-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(y));
65-
}
66-
67-
if (x.Length > destination.Length)
68-
{
69-
ThrowHelper.ThrowArgument_DestinationTooShort();
70-
}
71-
72-
for (int i = 0; i < x.Length; i++)
73-
{
74-
destination[i] = x[i] * y[i];
75-
}
76-
}
77-
78-
/// <summary>Computes the element-wise result of: <c><paramref name="x" /> * <paramref name="y" /></c>.</summary>
79-
/// <param name="x">The first tensor, represented as a span.</param>
80-
/// <param name="y">The second tensor, represented as a scalar.</param>
81-
/// <param name="destination">The destination tensor, represented as a span.</param>
82-
/// <exception cref="ArgumentException">Destination is too short.</exception>
83-
/// <remarks>
84-
/// <para>This method effectively does <c><paramref name="destination" />[i] = <paramref name="x" />[i] * <paramref name="y" /></c>.</para>
85-
/// <para>This method corresponds to the <c>scal</c> method defined by <c>BLAS1</c>.</para>
86-
/// </remarks>
87-
public static void Multiply(ReadOnlySpan<float> x, float y, Span<float> destination)
88-
{
89-
if (x.Length > destination.Length)
90-
{
91-
ThrowHelper.ThrowArgument_DestinationTooShort();
92-
}
93-
94-
for (int i = 0; i < x.Length; i++)
95-
{
96-
destination[i] = x[i] * y;
97-
}
98-
}
99-
100-
/// <summary>Computes the element-wise result of: <c><paramref name="x" /> / <paramref name="y" /></c>.</summary>
101-
/// <param name="x">The first tensor, represented as a span.</param>
102-
/// <param name="y">The second tensor, represented as a span.</param>
103-
/// <param name="destination">The destination tensor, represented as a span.</param>
104-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="y" />'.</exception>
105-
/// <exception cref="ArgumentException">Destination is too short.</exception>
106-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = <paramref name="x" />[i] / <paramref name="y" /></c>.</remarks>
107-
public static void Divide(ReadOnlySpan<float> x, ReadOnlySpan<float> y, Span<float> destination)
108-
{
109-
if (x.Length != y.Length)
110-
{
111-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(y));
112-
}
113-
114-
if (x.Length > destination.Length)
115-
{
116-
ThrowHelper.ThrowArgument_DestinationTooShort();
117-
}
118-
119-
for (int i = 0; i < x.Length; i++)
120-
{
121-
destination[i] = x[i] / y[i];
122-
}
123-
}
124-
125-
/// <summary>Computes the element-wise result of: <c><paramref name="x" /> / <paramref name="y" /></c>.</summary>
126-
/// <param name="x">The first tensor, represented as a span.</param>
127-
/// <param name="y">The second tensor, represented as a scalar.</param>
128-
/// <param name="destination">The destination tensor, represented as a span.</param>
129-
/// <exception cref="ArgumentException">Destination is too short.</exception>
130-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = <paramref name="x" />[i] / <paramref name="y" /></c>.</remarks>
131-
public static void Divide(ReadOnlySpan<float> x, float y, Span<float> destination)
132-
{
133-
if (x.Length > destination.Length)
134-
{
135-
ThrowHelper.ThrowArgument_DestinationTooShort();
136-
}
137-
138-
for (int i = 0; i < x.Length; i++)
139-
{
140-
destination[i] = x[i] / y;
141-
}
142-
}
143-
144-
/// <summary>Computes the element-wise result of: <c>-<paramref name="x" /></c>.</summary>
145-
/// <param name="x">The tensor, represented as a span.</param>
146-
/// <param name="destination">The destination tensor, represented as a span.</param>
147-
/// <exception cref="ArgumentException">Destination is too short.</exception>
148-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = -<paramref name="x" />[i]</c>.</remarks>
149-
public static void Negate(ReadOnlySpan<float> x, Span<float> destination)
150-
{
151-
if (x.Length > destination.Length)
152-
{
153-
ThrowHelper.ThrowArgument_DestinationTooShort();
154-
}
155-
156-
for (int i = 0; i < x.Length; i++)
157-
{
158-
destination[i] = -x[i];
159-
}
160-
}
161-
162-
/// <summary>Computes the element-wise result of: <c>(<paramref name="x" /> + <paramref name="y" />) * <paramref name="multiplier" /></c>.</summary>
163-
/// <param name="x">The first tensor, represented as a span.</param>
164-
/// <param name="y">The second tensor, represented as a span.</param>
165-
/// <param name="multiplier">The third tensor, represented as a span.</param>
166-
/// <param name="destination">The destination tensor, represented as a span.</param>
167-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="y" />'.</exception>
168-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="multiplier" />'.</exception>
169-
/// <exception cref="ArgumentException">Destination is too short.</exception>
170-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = (<paramref name="x" />[i] + <paramref name="y" />[i]) * <paramref name="multiplier" />[i]</c>.</remarks>
171-
public static void AddMultiply(ReadOnlySpan<float> x, ReadOnlySpan<float> y, ReadOnlySpan<float> multiplier, Span<float> destination)
172-
{
173-
if (x.Length != y.Length)
174-
{
175-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(y));
176-
}
177-
178-
if (x.Length != multiplier.Length)
179-
{
180-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(multiplier));
181-
}
182-
183-
if (x.Length > destination.Length)
184-
{
185-
ThrowHelper.ThrowArgument_DestinationTooShort();
186-
}
187-
188-
for (int i = 0; i < x.Length; i++)
189-
{
190-
destination[i] = (x[i] + y[i]) * multiplier[i];
191-
}
192-
}
193-
194-
/// <summary>Computes the element-wise result of: <c>(<paramref name="x" /> + <paramref name="y" />) * <paramref name="multiplier" /></c>.</summary>
195-
/// <param name="x">The first tensor, represented as a span.</param>
196-
/// <param name="y">The second tensor, represented as a span.</param>
197-
/// <param name="multiplier">The third tensor, represented as a scalar.</param>
198-
/// <param name="destination">The destination tensor, represented as a span.</param>
199-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="y" />'.</exception>
200-
/// <exception cref="ArgumentException">Destination is too short.</exception>
201-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = (<paramref name="x" />[i] + <paramref name="y" />[i]) * <paramref name="multiplier" /></c>.</remarks>
202-
public static void AddMultiply(ReadOnlySpan<float> x, ReadOnlySpan<float> y, float multiplier, Span<float> destination)
203-
{
204-
if (x.Length != y.Length)
205-
{
206-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(y));
207-
}
208-
209-
if (x.Length > destination.Length)
210-
{
211-
ThrowHelper.ThrowArgument_DestinationTooShort();
212-
}
213-
214-
for (int i = 0; i < x.Length; i++)
215-
{
216-
destination[i] = (x[i] + y[i]) * multiplier;
217-
}
218-
}
219-
220-
/// <summary>Computes the element-wise result of: <c>(<paramref name="x" /> + <paramref name="y" />) * <paramref name="multiplier" /></c>.</summary>
221-
/// <param name="x">The first tensor, represented as a span.</param>
222-
/// <param name="y">The second tensor, represented as a scalar.</param>
223-
/// <param name="multiplier">The third tensor, represented as a span.</param>
224-
/// <param name="destination">The destination tensor, represented as a span.</param>
225-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="multiplier" />'.</exception>
226-
/// <exception cref="ArgumentException">Destination is too short.</exception>
227-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = (<paramref name="x" />[i] + <paramref name="y" />) * <paramref name="multiplier" />[i]</c>.</remarks>
228-
public static void AddMultiply(ReadOnlySpan<float> x, float y, ReadOnlySpan<float> multiplier, Span<float> destination)
229-
{
230-
if (x.Length != multiplier.Length)
231-
{
232-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(multiplier));
233-
}
234-
235-
if (x.Length > destination.Length)
236-
{
237-
ThrowHelper.ThrowArgument_DestinationTooShort();
238-
}
239-
240-
for (int i = 0; i < x.Length; i++)
241-
{
242-
destination[i] = (x[i] + y) * multiplier[i];
243-
}
244-
}
245-
246-
/// <summary>Computes the element-wise result of: <c>(<paramref name="x" /> * <paramref name="y" />) + <paramref name="addend" /></c>.</summary>
247-
/// <param name="x">The first tensor, represented as a span.</param>
248-
/// <param name="y">The second tensor, represented as a span.</param>
249-
/// <param name="addend">The third tensor, represented as a span.</param>
250-
/// <param name="destination">The destination tensor, represented as a span.</param>
251-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="y" />'.</exception>
252-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="addend" />'.</exception>
253-
/// <exception cref="ArgumentException">Destination is too short.</exception>
254-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = (<paramref name="x" />[i] * <paramref name="y" />[i]) + <paramref name="addend" />[i]</c>.</remarks>
255-
public static void MultiplyAdd(ReadOnlySpan<float> x, ReadOnlySpan<float> y, ReadOnlySpan<float> addend, Span<float> destination)
256-
{
257-
if (x.Length != y.Length)
258-
{
259-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(y));
260-
}
261-
262-
if (x.Length != addend.Length)
263-
{
264-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(addend));
265-
}
266-
267-
if (x.Length > destination.Length)
268-
{
269-
ThrowHelper.ThrowArgument_DestinationTooShort();
270-
}
271-
272-
for (int i = 0; i < x.Length; i++)
273-
{
274-
destination[i] = (x[i] * y[i]) + addend[i];
275-
}
276-
}
277-
278-
/// <summary>Computes the element-wise result of: <c>(<paramref name="x" /> * <paramref name="y" />) + <paramref name="addend" /></c>.</summary>
279-
/// <param name="x">The first tensor, represented as a span.</param>
280-
/// <param name="y">The second tensor, represented as a span.</param>
281-
/// <param name="addend">The third tensor, represented as a span.</param>
282-
/// <param name="destination">The destination tensor, represented as a span.</param>
283-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="y" />'.</exception>
284-
/// <exception cref="ArgumentException">Destination is too short.</exception>
285-
/// <remarks>
286-
/// <para>This method effectively does <c><paramref name="destination" />[i] = (<paramref name="x" />[i] * <paramref name="y" />[i]) + <paramref name="addend" /></c>.</para>
287-
/// <para>This method corresponds to the <c>axpy</c> method defined by <c>BLAS1</c>.</para>
288-
/// </remarks>
289-
public static void MultiplyAdd(ReadOnlySpan<float> x, ReadOnlySpan<float> y, float addend, Span<float> destination)
290-
{
291-
if (x.Length != y.Length)
292-
{
293-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(y));
294-
}
295-
296-
if (x.Length > destination.Length)
297-
{
298-
ThrowHelper.ThrowArgument_DestinationTooShort();
299-
}
300-
301-
for (int i = 0; i < x.Length; i++)
302-
{
303-
destination[i] = (x[i] * y[i]) + addend;
304-
}
305-
}
306-
307-
/// <summary>Computes the element-wise result of: <c>(<paramref name="x" /> * <paramref name="y" />) + <paramref name="addend" /></c>.</summary>
308-
/// <param name="x">The first tensor, represented as a span.</param>
309-
/// <param name="y">The second tensor, represented as a span.</param>
310-
/// <param name="addend">The third tensor, represented as a span.</param>
311-
/// <param name="destination">The destination tensor, represented as a span.</param>
312-
/// <exception cref="ArgumentException">Length of '<paramref name="x" />' must be same as length of '<paramref name="addend" />'.</exception>
313-
/// <exception cref="ArgumentException">Destination is too short.</exception>
314-
/// <remarks>This method effectively does <c><paramref name="destination" />[i] = (<paramref name="x" />[i] * <paramref name="y" />) + <paramref name="addend" />[i]</c>.</remarks>
315-
public static void MultiplyAdd(ReadOnlySpan<float> x, float y, ReadOnlySpan<float> addend, Span<float> destination)
316-
{
317-
if (x.Length != addend.Length)
318-
{
319-
ThrowHelper.ThrowArgument_SpansMustHaveSameLength(nameof(x), nameof(addend));
320-
}
321-
322-
if (x.Length > destination.Length)
323-
{
324-
ThrowHelper.ThrowArgument_DestinationTooShort();
325-
}
326-
327-
for (int i = 0; i < x.Length; i++)
328-
{
329-
destination[i] = (x[i] * y) + addend[i];
330-
}
331-
}
332-
3339
/// <summary>Computes the element-wise result of: <c>pow(e, <paramref name="x" />)</c>.</summary>
33410
/// <param name="x">The tensor, represented as a span.</param>
33511
/// <param name="destination">The destination tensor, represented as a span.</param>

0 commit comments

Comments
 (0)