public unsafe static void Zeroset(UInt32[] value, uint index, uint length) { if (length <= 0) { return; } #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (index + length) <= value.Length); #endif uint length_sets = Mask256.UInt32Sets(length), length_rems = Mask256.UInt32Rems(length); fixed(UInt32 *v = value) { for (uint i = 0; i < length_sets; i += Mask256.MM256UInt32s) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (i + index + Mask256.MM256UInt32s) <= value.Length); #endif Avx.Store(v + i + index, Vector256 <UInt32> .Zero); } if (length_rems > 0) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (length_sets + index + length_rems) <= value.Length); #endif Avx2.MaskStore(v + length_sets + index, Mask256.LSV(length_rems), Vector256 <UInt32> .Zero); } } }
/// <summary>Shift uint32 array v <<= sft</summary> public static unsafe void LeftShift(UInt32[] value, int sft) { #if DEBUG Debug <ArgumentOutOfRangeException> .Assert(sft >= 0); #endif if (sft > LeadingZeroCount(value)) { throw new OverflowException(); } int sftdev = sft / UInt32Bits; int sftrem = sft % UInt32Bits; if (sftrem == 0) { LeftBlockShift(value, sftdev); return; } uint count = (uint)(value.Length - sftdev - 1); uint count_sets = Mask256.UInt32Sets(count), count_rems = Mask256.UInt32Rems(count); fixed(UInt32 *v = value) { if (count_rems > 0) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (count_sets + sftdev + 1 + count_rems) <= value.Length); #endif Vector256 <UInt32> mask = Mask256.LSV(count_rems); Vector256 <UInt32> ls = Avx2.ShiftRightLogical(Avx2.MaskLoad(v + count_sets, mask), (byte)(UInt32Bits - sftrem)); Vector256 <UInt32> ms = Avx2.ShiftLeftLogical(Avx2.MaskLoad(v + count_sets + 1, mask), (byte)sftrem); Avx2.MaskStore(v + count_sets + sftdev + 1, mask, Avx2.Or(ls, ms)); } for (uint i = count_sets; i >= Mask256.MM256UInt32s; i -= Mask256.MM256UInt32s) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (i + sftdev + 1) <= value.Length); #endif Vector256 <UInt32> ls = Avx2.ShiftRightLogical(Avx.LoadVector256(v + i - Mask256.MM256UInt32s), (byte)(UInt32Bits - sftrem)); Vector256 <UInt32> ms = Avx2.ShiftLeftLogical(Avx.LoadVector256(v + i + 1 - Mask256.MM256UInt32s), (byte)sftrem); Avx.Store(v + i + sftdev + 1 - Mask256.MM256UInt32s, Avx2.Or(ls, ms)); } #if DEBUG Debug <IndexOutOfRangeException> .Assert(sftdev < value.Length); #endif v[sftdev] = v[0] << sftrem; } Zeroset(value, 0, (uint)sftdev); }
/// <summary>Shift uint32 array v >>= sft</summary> public static unsafe void RightShift(UInt32[] value, int sft) { #if DEBUG Debug <ArgumentOutOfRangeException> .Assert(sft >= 0); #endif int sftdev = sft / UInt32Bits; int sftrem = sft % UInt32Bits; if (sftrem == 0 || sftdev >= value.Length) { RightBlockShift(value, sftdev); return; } uint count = (uint)(value.Length - sftdev - 1); uint count_sets = Mask256.UInt32Sets(count), count_rems = Mask256.UInt32Rems(count); fixed(UInt32 *v = value) { for (uint i = 0; i < count_sets; i += Mask256.MM256UInt32s) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (i + sftdev + 1 + Mask256.MM256UInt32s) <= value.Length); #endif Vector256 <UInt32> ls = Avx2.ShiftRightLogical(Avx.LoadVector256(v + i + sftdev), (byte)sftrem); Vector256 <UInt32> ms = Avx2.ShiftLeftLogical(Avx.LoadVector256(v + i + sftdev + 1), (byte)(UInt32Bits - sftrem)); Avx.Store(v + i, Avx2.Or(ls, ms)); } if (count_rems > 0) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (count_sets + sftdev + 1 + count_rems) <= value.Length); #endif Vector256 <UInt32> mask = Mask256.LSV(count_rems); Vector256 <UInt32> ls = Avx2.ShiftRightLogical(Avx2.MaskLoad(v + count_sets + sftdev, mask), (byte)sftrem); Vector256 <UInt32> ms = Avx2.ShiftLeftLogical(Avx2.MaskLoad(v + count_sets + sftdev + 1, mask), (byte)(UInt32Bits - sftrem)); Avx2.MaskStore(v + count_sets, mask, Avx2.Or(ls, ms)); } #if DEBUG Debug <IndexOutOfRangeException> .Assert(count < value.Length); #endif v[count] = v[value.Length - 1] >> sftrem; } Zeroset(value, count + 1, (uint)sftdev); }
/// <summary>Shift uint32 array v >>= sft * UInt32Bits</summary> public static unsafe void RightBlockShift(UInt32[] value, int sft) { #if DEBUG Debug <ArgumentOutOfRangeException> .Assert(sft >= 0); #endif if (sft >= value.Length) { Zeroset(value); return; } uint count = (uint)(value.Length - sft); uint count_sets = Mask256.UInt32Sets(count), count_rems = Mask256.UInt32Rems(count); fixed(UInt32 *v = value) { for (uint i = 0; i < count_sets; i += Mask256.MM256UInt32s) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (i + sft + Mask256.MM256UInt32s) <= value.Length); #endif Avx.Store(v + i, Avx.LoadVector256(v + i + sft)); } if (count_rems > 0) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (count_sets + sft + count_rems) <= value.Length); #endif Vector256 <UInt32> mask = Mask256.LSV(count_rems); Avx2.MaskStore(v + count_sets, mask, Avx2.MaskLoad(v + count_sets + sft, mask)); } } Zeroset(value, count, (uint)sft); }
public static unsafe void LeftBlockShift(UInt32[] value, int sft) { #if DEBUG Debug <ArgumentOutOfRangeException> .Assert(sft >= 0); #endif if (checked (sft + Digits(value)) > value.Length) { throw new OverflowException(); } uint count = (uint)(value.Length - sft); uint count_sets = Mask256.UInt32Sets(count), count_rems = Mask256.UInt32Rems(count); fixed(UInt32 *v = value) { if (count_rems > 0) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (count_sets + sft + count_rems) <= value.Length); #endif Vector256 <UInt32> mask = Mask256.LSV(count_rems); Avx2.MaskStore(v + count_sets + sft, mask, Avx2.MaskLoad(v + count_sets, mask)); } for (uint i = count_sets; i >= Mask256.MM256UInt32s; i -= Mask256.MM256UInt32s) { #if DEBUG Debug <IndexOutOfRangeException> .Assert(checked (i + sft) <= value.Length); #endif Avx.Store(v + i + sft - Mask256.MM256UInt32s, Avx.LoadVector256(v + i - Mask256.MM256UInt32s)); } } Zeroset(value, 0, (uint)sft); }
private static unsafe void Add(Vector256 <UInt64>[] s, Vector256 <UInt32>[] v, int shift) { int shift_sets = shift / Vector256 <UInt64> .Count; int shift_rems = shift % Vector256 <UInt64> .Count; if (shift_rems == 0) { #if DEBUG Debug <OverflowException> .Assert(checked (shift_sets + v.Length) <= s.Length); #endif fixed(Vector256 <UInt64> *ps = s) { fixed(Vector256 <UInt32> *pv = v) { for (int i = 0, store_idx = shift_sets; i < v.Length; i++, store_idx++) { ps[store_idx] = Avx2.Add(ps[store_idx], pv[i].AsUInt64()); } } } } else { #if DEBUG Debug <OverflowException> .Assert(checked (shift_sets + v.Length) < s.Length); #endif Vector256 <UInt64> ml = Mask256.MSV(checked ((uint)(shift_rems * 2))).AsUInt64(); Vector256 <UInt64> mh = Mask256.LSV(checked ((uint)(shift_rems * 2))).AsUInt64(); byte mm_perm = shift_rems switch { 1 => MM_PERM_CBAD, 2 => MM_PERM_BADC, 3 => MM_PERM_ADCB, _ => throw new ArgumentException(nameof(shift_rems)) }; int store_idx = shift_sets; Vector256 <UInt64> uh, ul, u; fixed(Vector256 <UInt64> *ps = s) { fixed(Vector256 <UInt32> *pv = v) { u = Avx2.Permute4x64(pv[0].AsUInt64(), mm_perm); ul = Avx2.And(u, ml); ps[store_idx] = Avx2.Add(ps[store_idx], ul); store_idx++; for (int i = 1; i < v.Length; i++) { uh = Avx2.And(u, mh); u = Avx2.Permute4x64(pv[i].AsUInt64(), mm_perm); ul = Avx2.And(u, ml); ps[store_idx] = Avx2.Add(ps[store_idx], Avx2.Or(uh, ul)); store_idx++; } uh = Avx2.And(u, mh); ps[store_idx] = Avx2.Add(ps[store_idx], uh); } } } }
public Mask256s(Mask256 value) : base(value.Get(0), value.Get(1), value.Get(2), value.Get(3)) { }
///----------------------------------------------------------------- public Mask256s(string name, Mask256 default_value) : base(name) { Resize(Mask256.MAX_SIZE); }
///--------------------------------------------------------------------- public static Mask256s Get(string name, Mask256 default_value) { return(new Mask256s(name, default_value)); }