public static double sum(ReadOnlySpan <double> src) { var veclen = Vec128 <double> .Length; var seglen = 2 * veclen; var srclen = src.Length; require(0 == srclen % seglen); var dst = Vec128.Fill((double)0); var offset = 0; for (var i = 0; i < srclen; i += seglen) { var v1 = Vec128.Load(src, offset); offset += veclen; var v2 = Vec128.Load(src, offset); offset += veclen; var vSum = dfp.hadd(v1, v2); dst = dfp.add(dst, vSum); } Span <double> final = stackalloc double[veclen]; vstore(dst, ref final[0]); var total = (double)0; for (var i = 0; i < veclen; i++) { total += final[i]; } return(total); }
static BitVector128 clmul(BitVector64 lhs, BitVector64 rhs) { var a = Vec128.LoadScalar(lhs.Scalar); var b = Vec128.LoadScalar(rhs.Scalar); return(dinx.clmul(a, b, ClMulMask.X00)); }
public static UInt128 clmul(ulong lhs, ulong rhs) { var a = Vec128.LoadScalar(lhs); var b = Vec128.LoadScalar(rhs); return(CarrylessMultiply(a, b, 0x00)); }
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 Vec512 <T> FromParts <T>(Vec128 <T> v00, Vec128 <T> v01, Vec128 <T> v10, Vec128 <T> v11) where T : struct { Vec256 <T> lo = ginx.set(v00, v01); Vec256 <T> hi = ginx.set(v10, v11); return(new Vec512 <T>(in lo, in hi)); }
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 T[] ToArray <T>(this Vec128 <T> src) where T : struct { var dst = new T[Vec128 <T> .Length]; vstore(src, ref head(dst)); return(dst); }
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); }
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 void transpose(ref Vec128 <float> row0, ref Vec128 <float> row1, ref Vec128 <float> row2, ref Vec128 <float> row3) { var tmp0 = Shuffle(row0, row1, 0x44); var tmp2 = Shuffle(row0, row1, 0xEE); var tmp1 = Shuffle(row2, row3, 0x44); var tmp3 = Shuffle(row2, row3, 0xEE); row0 = Shuffle(tmp0, tmp1, 0x88); row1 = Shuffle(tmp0, tmp1, 0xDD); row2 = Shuffle(tmp2, tmp3, 0x88); row3 = Shuffle(tmp2, tmp3, 0xDD); }
/// <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 Vec128 <T> Fill <T>(T value) where T : struct { if (typeof(T) == typeof(sbyte)) { return(generic <T>(Vec128.fill(int8(value)))); } else if (typeof(T) == typeof(byte)) { return(generic <T>(Vec128.fill(uint8(value)))); } else if (typeof(T) == typeof(short)) { return(generic <T>(Vec128.fill(int16(value)))); } else if (typeof(T) == typeof(ushort)) { return(generic <T>(Vec128.fill(uint16(value)))); } else if (typeof(T) == typeof(int)) { return(generic <T>(Vec128.fill(int32(value)))); } else if (typeof(T) == typeof(uint)) { return(generic <T>(Vec128.fill(uint32(value)))); } else if (typeof(T) == typeof(long)) { return(generic <T>(Vec128.fill(int64(value)))); } else if (typeof(T) == typeof(ulong)) { return(generic <T>(Vec128.fill(uint64(value)))); } else if (typeof(T) == typeof(float)) { return(generic <T>(Vec128.fill(float32(value)))); } else if (typeof(T) == typeof(double)) { return(generic <T>(Vec128.fill(float64(value)))); } else { throw unsupported <T>(); } }
public static unsafe void store <T>(Vec128 <T> src, ref T dst) where T : struct { if (typeof(T) == typeof(sbyte)) { vstore(int8(src), ref int8(ref dst)); } else if (typeof(T) == typeof(byte)) { vstore(uint8(src), ref uint8(ref dst)); } else if (typeof(T) == typeof(short)) { vstore(int16(src), ref int16(ref dst)); } else if (typeof(T) == typeof(ushort)) { vstore(uint16(src), ref uint16(ref dst)); } else if (typeof(T) == typeof(int)) { vstore(int32(src), ref int32(ref dst)); } else if (typeof(T) == typeof(uint)) { vstore(uint32(src), ref uint32(ref dst)); } else if (typeof(T) == typeof(long)) { vstore(int64(src), ref int64(ref dst)); } else if (typeof(T) == typeof(ulong)) { vstore(uint64(src), ref uint64(ref dst)); } else if (typeof(T) == typeof(float)) { vstore(float32(src), ref float32(ref dst)); } else if (typeof(T) == typeof(double)) { vstore(float64(src), ref float64(ref dst)); } else { throw unsupported <T>(); } }
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 Vec128 <double> ToVec128() => Vec128.FromParts(x0d, x1d);
static Vec128 <float> CalcFpSignMask32() => Vec128.Fill(-0.0f);
static Vec128 <double> CalcFpSignMask64() => Vec128.Fill(-0.0);
public static Vec128 <T> LoadVec128 <T>(this Span <T> src, int offset = 0) where T : unmanaged => Vec128.Load(ref src[offset]);
public static Vec128 <T> LoadVec128 <T>(this ReadOnlySpan128 <T> src, int block = 0) where T : unmanaged => Vec128.Load(src, block);
public static Vec128 <T> Or <T>(this Vec128 <T> lhs, in Vec128 <T> rhs)
public static Vec128 <ulong> alignr(Vec128 <ulong> left, Vec128 <ulong> right, byte offset) => AlignRight(left, right, offset);
public static Vector128 <ulong> negate(Vector128 <ulong> src) => add(BitUtil.flip(src), Vec128.Ones <ulong>());
public static Vector128 <byte> negate(Vector128 <byte> src) => add(BitUtil.flip(src), Vec128.Ones <byte>());
public static Vec128 <T> Flip <T>(this Vec128 <T> src) where T : struct => gbits.flip(in src);
public static unsafe void maskstore(Vec128 <int> src, Vec128 <int> mask, ref int dst) => MaskStore(refptr(ref dst), src, mask);
public static unsafe Vec128 <int> maskload(ref int src, Vec128 <int> mask) => MaskLoad(refptr(ref src), mask);
public static Vec128 <int> alignr(Vec128 <int> left, Vec128 <int> right, byte offset) => AlignRight(left, right, offset);
public static Vec128 <float> Div(this Vec128 <float> lhs, in Vec128 <float> rhs)
public static Vec128 <float> rcp(Vec128 <float> src) => Reciprocal(src);
public static Vec128 <float> rsqrt(Vec128 <float> src) => ReciprocalSqrt(src);