public static void dec(Span128 <byte> src, Vec128 <byte> key, Span128 <byte> dst) { for (var block = 0; block < src.BlockCount; block++) { vstore(dec(src.LoadVec128(block), key), ref dst.Block(block)); } }
public static Span128 <T> Store <T>(Vec128 <T> src, Span128 <T> dst, int blockIndex) where T : struct { var offset = Span128.BlockLength <T>(blockIndex); Vec128.Store(src, ref dst[offset]); return(dst); }
public static Span128 <T> ToSpan128 <T>(this Vec128 <T> src) where T : struct { var dst = Span128.AllocBlocks <T>(1); vstore(src, ref dst[0]); return(dst); }
public static Span128 <T> AllocBlocks(int count, T?fill = null) { var dst = new Span128 <T>(new T[count * BlockLength]); if (fill != null) { dst.data.Fill(fill.Value); } return(dst); }
public static Span128 <T> Swap <T>(this Span128 <T> src, params Swap[] swaps) where T : struct { if (swaps.Length == 0) { return(src); } src.Unblocked.Swap(swaps); return(src); }
/// <summary> /// Asserts content equality for two blocked spans of primal type /// </summary> /// <param name="lhs">The left span</param> /// <param name="rhs">The right span</param> /// <param name="caller">The invoking function</param> /// <param name="file">The file in which the invoking function is defined </param> /// <param name="line">The file line number of invocation</param> /// <typeparam name="T">The element type</typeparam> public static void ClaimEqual <T>(this ReadOnlySpan128 <T> lhs, ReadOnlySpan128 <T> rhs, [Member] string caller = null, [File] string file = null, [Line] int?line = null) where T : struct { for (var i = 0; i < Span128.Length(lhs, rhs); i++) { if (!gmath.eq(lhs[i], rhs[i])) { throw Errors.ItemsNotEqual(i, lhs[i], rhs[i], caller, file, line); } } }
static Vec128 <T> CalcUnits() { var n = Length; var dst = Span128.Alloc <T>(n); var one = gmath.one <T>(); for (var i = 0; i < n; i++) { dst[i] = one; } return(Vec128.Load(dst)); }
public static bool Identical <T>(this ReadOnlySpan128 <T> lhs, ReadOnlySpan128 <T> rhs) where T : struct { for (var i = 0; i < Span128.Length(lhs, rhs); i++) { if (gmath.neq(lhs[i], rhs[i])) { return(false); } } return(true); }
/// <summary> /// Creates a vector with incrementing components /// v[0] = first and v[i+1] = v[i] + 1 for i=1...N-1 /// </summary> /// <param name="first">The value of the first component</param> /// <typeparam name="T">The primal component type</typeparam> public static Vec128 <T> Increments(T first = default, params Swap[] swaps) { var n = Length; var dst = Span128.Alloc <T>(n); var val = first; for (var i = 0; i < n; i++) { dst[i] = val; gmath.inc(ref val); } return(Vec128.Load(dst.Swap(swaps))); }
public static Span128 <T> Alloc <T>(int minlen, T?fill = null) where T : struct { Span128.Alignment <T>(minlen, out int blocklen, out int fullBlocks, out int remainder); if (remainder == 0) { return(AllocBlocks <T>(fullBlocks, fill)); } else { return(Span128.AllocBlocks <T>(fullBlocks + 1, fill)); } }
public static void VerifyBinOp <T>(IPolyrand random, int blocks, Vector128BinOp <T> inXOp, Func <T, T, T> primalOp) where T : unmanaged { var blocklen = Span128 <T> .BlockLength; var lhs = random.ReadOnlySpan128 <T>(blocks); Claim.eq(blocks * blocklen, lhs.Length); var rhs = random.ReadOnlySpan128 <T>(blocks); Claim.eq(blocks * blocklen, rhs.Length); var expect = Span128.AllocBlocks <T>(blocks); Claim.eq(blocks, expect.BlockCount); var actual = Span128.AllocBlocks <T>(blocks); Claim.eq(blocks, actual.BlockCount); var tmp = new T[blocklen]; for (var block = 0; block < blocks; block++) { var offset = block * blocklen; for (var i = 0; i < blocklen; i++) { tmp[i] = primalOp(lhs[offset + i], rhs[offset + i]); } var vExpect = Vec128.LoadVector <T>(ref tmp[0]); var vX = lhs.LoadVec128(block); var vY = rhs.LoadVec128(block); var vActual = inXOp(vX, vY); Claim.eq(vExpect, vActual); ginx.store(vExpect, ref expect.Block(block)); ginx.store(vActual, ref actual.Block(block)); } Claim.eq(expect, actual); }
public static Span128 <byte> From <T>(Span128 <T> src) where T : struct => Span128.Load(MemoryMarshal.AsBytes(src.Unblock()));
public static Span128 <T> add <T>(ReadOnlySpan128 <T> lhs, ReadOnlySpan128 <T> rhs, Span128 <T> dst) where T : struct { if (typeof(T) == typeof(sbyte)) { dinx.add(int8(lhs), int8(rhs), int8(dst)); } else if (typeof(T) == typeof(byte)) { dinx.add(uint8(lhs), uint8(rhs), uint8(dst)); } else if (typeof(T) == typeof(short)) { dinx.add(int16(lhs), int16(rhs), int16(dst)); } else if (typeof(T) == typeof(ushort)) { dinx.add(uint16(lhs), uint16(rhs), uint16(dst)); } else if (typeof(T) == typeof(int)) { dinx.add(int32(lhs), int32(rhs), int32(dst)); } else if (typeof(T) == typeof(uint)) { dinx.add(uint32(lhs), uint32(rhs), uint32(dst)); } else if (typeof(T) == typeof(long)) { dinx.add(int64(lhs), int64(rhs), int64(dst)); } else if (typeof(T) == typeof(ulong)) { dinx.add(uint64(lhs), uint64(rhs), uint64(dst)); } else if (typeof(T) == typeof(float)) { dfp.add(float32(lhs), float32(rhs), float32(dst)); } else if (typeof(T) == typeof(double)) { dfp.add(float64(lhs), float64(rhs), float64(dst)); } else { throw unsupported <T>(); } return(dst); }
public static Span128 <ulong> add(ReadOnlySpan128 <ulong> lhs, ReadOnlySpan128 <ulong> rhs, Span128 <ulong> dst) { var blocks = dst.BlockCount; for (var block = 0; block < blocks; block++) { vstore(dinx.add(lhs.LoadVec128(block), rhs.LoadVec128(block)), ref dst.Block(block)); } return(dst); }
public static string FormatList <T>(this Span128 <T> src, char delimiter = ',', int offset = 0) where T : struct => src.Unblocked.FormatList(delimiter, offset);
public static Span128 <double> div(ReadOnlySpan128 <double> lhs, ReadOnlySpan128 <double> rhs, Span128 <double> dst) { var blocks = dst.BlockCount; for (var block = 0; block < blocks; block++) { vstore(dfp.div(lhs.LoadVec128(block), rhs.LoadVec128(block)), ref dst[block]); } return(dst); }
public static Span128 <float> fmul(ReadOnlySpan128 <float> lhs, ReadOnlySpan128 <float> rhs, Span128 <float> dst) { var blocks = dst.BlockCount; for (var block = 0; block < blocks; block++) { vstore(dfp.fmul(lhs.LoadVec128(block), rhs.LoadVec128(block)), ref dst.Block(block)); } return(dst); }
public static bool aligned(int length) => Span128 <T> .Aligned(length);
ReadOnlySpan128(Span128 <T> src) { data = src.ReadOnly(); }
public static bool Identical <T>(this Span128 <T> lhs, Span128 <T> rhs) where T : struct => lhs.ReadOnly().Identical(rhs);
public static Span128 <T> FromParts <T>(params T[] src) where T : struct => Span128 <T> .Load(src);
public static Span128 <T> AllocBlock <T>(T?fill = null) where T : struct => Span128 <T> .AllocBlocks(1, fill);
public static Span128 <T> AllocBlocks <T>(int blocks, T?fill = null) where T : struct => Span128 <T> .AllocBlocks(blocks, fill);
public static Vec128 <T> LoadVec128 <T>(this Span128 <T> src, int block = 0) where T : unmanaged => Vec128.Load(src, block);
public static ReadOnlySpan128 <T> Load(Span128 <T> src) => new ReadOnlySpan128 <T>(src);
public static Span128 <T> sub <T>(ReadOnlySpan128 <T> lhs, ReadOnlySpan128 <T> rhs, Span128 <T> dst) where T : struct { var blocks = dst.BlockCount; for (var block = 0; block < blocks; block++) { store(ginx.sub(ginx.lddqu128(in lhs.Block(block)), ginx.lddqu128(in rhs.Block(block))), ref dst.Block(block)); } return(dst); }
public static Span128 <T> Load <T>(ReadOnlySpan <T> src, int offset = 0) where T : struct => Span128 <T> .Load(src, offset);
public static void ClaimEqual <T>(this Span128 <T> lhs, Span128 <T> rhs, [Member] string caller = null, [File] string file = null, [Line] int?line = null) where T : struct => lhs.ReadOnly().ClaimEqual(rhs, caller, file, line);