Skip to content

Commit fc13f65

Browse files
committed
Initial C# 7.3 upgrade for T : struct constraints
1 parent 91d02f5 commit fc13f65

File tree

5 files changed

+34
-32
lines changed

5 files changed

+34
-32
lines changed

NeuralNetwork.NET/Extensions/ArrayExtensions.cs

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using System.Runtime.CompilerServices;
54
using System.Threading.Tasks;
65
using JetBrains.Annotations;
76

@@ -19,10 +18,9 @@ internal static class ArrayExtensions
1918
/// <param name="m">The input 2D array to flatten</param>
2019
[Pure]
2120
[CollectionAccess(CollectionAccessType.Read)]
22-
public static unsafe T[] Flatten<T>([NotNull] this T[,] m) where T : struct
21+
public static unsafe T[] Flatten<T>([NotNull] this T[,] m) where T : unmanaged
2322
{
24-
fixed (void* p = &Unsafe.As<T, byte>(ref m[0, 0]))
25-
return new Span<T>(p, m.Length * Unsafe.SizeOf<T>()).ToArray();
23+
fixed (T* p = m) return new Span<T>(p, m.Length).ToArray();
2624
}
2725

2826
/// <summary>
@@ -32,17 +30,24 @@ public static unsafe T[] Flatten<T>([NotNull] this T[,] m) where T : struct
3230
/// <param name="lines">The lines to merge</param>
3331
[Pure]
3432
[CollectionAccess(CollectionAccessType.Read)]
35-
public static (T[,], T[,]) MergeLines<T>(this IEnumerable<(T[], T[])> lines) where T : struct
33+
public static unsafe (T[,], T[,]) MergeLines<T>(this IEnumerable<(T[], T[])> lines) where T : unmanaged
3634
{
3735
(T[] X, T[] Y)[] set = lines.ToArray();
3836
T[,]
3937
x = new T[set.Length, set[0].X.Length],
4038
y = new T[set.Length, set[0].Y.Length];
41-
Parallel.For(0, set.Length, i =>
39+
int
40+
wx = x.GetLength(1),
41+
wy = y.GetLength(1);
42+
fixed (T* px0 = x, py0 = y)
4243
{
43-
set[i].X.AsSpan().CopyTo(x.Slice(i));
44-
set[i].Y.AsSpan().CopyTo(y.Slice(i));
45-
}).AssertCompleted();
44+
T* px = px0, py = py0;
45+
Parallel.For(0, set.Length, i =>
46+
{
47+
set[i].X.AsSpan().CopyTo(new Span<T>(px + i * wx, wx));
48+
set[i].Y.AsSpan().CopyTo(new Span<T>(py + i * wy, wy));
49+
}).AssertCompleted();
50+
}
4651
return (x, y);
4752
}
4853
}

NeuralNetwork.NET/Extensions/SpanExtensions.cs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,29 +17,27 @@ public static class SpanExtensions
1717
/// </summary>
1818
/// <param name="span">The <see cref="Span{T}"/> to fill up</param>
1919
/// <param name="provider">The values provider to use</param>
20-
public static unsafe void Fill<T>(this Span<T> span, [NotNull] Func<T> provider) where T : struct
20+
public static unsafe void Fill<T>(this Span<T> span, [NotNull] Func<T> provider) where T : unmanaged
2121
{
2222
// Fill in parallel
2323
int
2424
cores = Environment.ProcessorCount,
2525
batch = span.Length / cores,
26-
mod = span.Length % cores,
27-
size = Unsafe.SizeOf<T>();
28-
ref T r0 = ref span.DangerousGetPinnableReference();
29-
fixed (byte* p0 = &Unsafe.As<T, byte>(ref r0))
26+
mod = span.Length % cores;
27+
fixed (T* p0 = &span.DangerousGetPinnableReference())
3028
{
31-
byte* pc = p0;
29+
T* pc = p0;
3230
Parallel.For(0, cores, i =>
3331
{
34-
byte* p = pc + i * batch * size;
35-
for (int j = 0; j < batch; j++, p += size)
32+
T* p = pc + i * batch;
33+
for (int j = 0; j < batch; j++, p++)
3634
Unsafe.Write(p, provider());
3735
}).AssertCompleted();
3836

3937
// Remaining values
4038
if (mod < 1) return;
4139
for (int i = span.Length - mod; i < span.Length; i++)
42-
Unsafe.Write(pc + i * size, provider());
40+
Unsafe.Write(pc + i, provider());
4341
}
4442
}
4543

@@ -51,12 +49,12 @@ public static unsafe void Fill<T>(this Span<T> span, [NotNull] Func<T> provider)
5149
/// <param name="w">The number of matrix columns</param>
5250
[Pure, NotNull]
5351
[CollectionAccess(CollectionAccessType.Read)]
54-
public static unsafe T[,] AsMatrix<T>(this Span<T> span, int h, int w) where T : struct
52+
public static unsafe T[,] AsMatrix<T>(this Span<T> span, int h, int w) where T : unmanaged
5553
{
5654
if (h * w != span.Length) throw new ArgumentException("The input dimensions don't match the source vector size");
5755
T[,] m = new T[h, w];
58-
fixed (void* p = &Unsafe.As<T, byte>(ref m[0, 0]))
59-
span.CopyTo(new Span<T>(p, m.Length * Unsafe.SizeOf<T>()));
56+
fixed (void* p = m)
57+
span.CopyTo(new Span<T>(p, m.Length));
6058
return m;
6159
}
6260

@@ -66,16 +64,15 @@ public static unsafe void Fill<T>(this Span<T> span, [NotNull] Func<T> provider)
6664
/// <typeparam name="T">The type of each value in the input <see cref="Span{T}"/></typeparam>
6765
/// <param name="span">The input <see cref="Span{T}"/> to read</param>
6866
[Pure]
69-
public static unsafe int GetContentHashCode<T>(this Span<T> span) where T : struct
67+
public static unsafe int GetContentHashCode<T>(this Span<T> span) where T : unmanaged
7068
{
71-
fixed (byte* p0 = &Unsafe.As<T, byte>(ref span.DangerousGetPinnableReference()))
69+
fixed (T* p0 = &span.DangerousGetPinnableReference())
7270
{
73-
int size = Unsafe.SizeOf<T>();
7471
int hash = 17;
7572
unchecked
7673
{
7774
for (int i = 0; i < span.Length; i++)
78-
hash = hash * 23 + Unsafe.Read<T>(p0 + size * i).GetHashCode();
75+
hash = hash * 23 + Unsafe.Read<T>(p0 + i).GetHashCode();
7976
return hash;
8077
}
8178
}

NeuralNetwork.NET/Extensions/StreamExtensions.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ internal static class StreamExtensions
1616
/// <typeparam name="T">The <see langword="struct"/> type to serialize</typeparam>
1717
/// <param name="stream">The target <see cref="Stream"/> to use to write the data</param>
1818
/// <param name="value">The <see langword="struct"/> to write to the <see cref="Stream"/> instance</param>
19-
public static unsafe void Write<T>([NotNull] this Stream stream, T value) where T : struct
19+
public static unsafe void Write<T>([NotNull] this Stream stream, T value) where T : unmanaged
2020
{
2121
byte[] bytes = new byte[Unsafe.SizeOf<T>()];
2222
fixed (void* p = bytes) Unsafe.Copy(p, ref value);
@@ -30,7 +30,7 @@ public static unsafe void Write<T>([NotNull] this Stream stream, T value) where
3030
/// <param name="stream">The source <see cref="Stream"/> instance to use to read the data</param>
3131
/// <param name="value">The resulting <typeparamref name="T"/> value that is read from the <see cref="Stream"/></param>
3232
[MustUseReturnValue]
33-
public static unsafe bool TryRead<T>([NotNull] this Stream stream, out T value) where T : struct
33+
public static unsafe bool TryRead<T>([NotNull] this Stream stream, out T value) where T : unmanaged
3434
{
3535
byte[] bytes = new byte[Unsafe.SizeOf<T>()];
3636
value = default;

NeuralNetwork.NET/Helpers/Sha256.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,11 @@ public static class Sha256
2424
/// <param name="array">The input array to process</param>
2525
[PublicAPI]
2626
[Pure, NotNull]
27-
public static unsafe byte[] Hash<T>([NotNull] T[] array) where T : struct
27+
public static unsafe byte[] Hash<T>([NotNull] T[] array) where T : unmanaged
2828
{
2929
int size = Unsafe.SizeOf<T>() * array.Length;
30-
fixed (byte* p = &Unsafe.As<T, byte>(ref array[0]))
31-
using (UnmanagedMemoryStream stream = new UnmanagedMemoryStream(p, size, size, FileAccess.Read))
30+
fixed (T* p = array)
31+
using (UnmanagedMemoryStream stream = new UnmanagedMemoryStream((byte*)p, size, size, FileAccess.Read))
3232
using (SHA256 provider = SHA256.Create())
3333
{
3434
return provider.ComputeHash(stream);
@@ -42,7 +42,7 @@ public static unsafe byte[] Hash<T>([NotNull] T[] array) where T : struct
4242
/// <param name="arrays">The arrays to process</param>
4343
[PublicAPI]
4444
[Pure, NotNull]
45-
public static unsafe byte[] Hash<T>([NotNull, ItemNotNull] params T[][] arrays) where T : struct
45+
public static unsafe byte[] Hash<T>([NotNull, ItemNotNull] params T[][] arrays) where T : unmanaged
4646
{
4747
// Compute the hashes in parallel
4848
if (arrays.Length == 0) return new byte[0];

NeuralNetwork.NET/SupervisedLearning/Data/Pin{T}.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ namespace NeuralNetworkNET.SupervisedLearning.Data
77
/// It can be used to replace <see cref="System.Span{T}"/> to quickly pass pointers around in non stack-only methods.
88
/// </summary>
99
/// <typeparam name="T">The type of the target referenced by the exposed pointer</typeparam>
10-
internal readonly unsafe struct Pin<T> where T : struct
10+
internal readonly unsafe struct Pin<T> where T : unmanaged
1111
{
1212
/// <summary>
1313
/// The pinned pointer

0 commit comments

Comments
 (0)