示例#1
0
        public unsafe void GeneratedPermutationsAreCorrect()
        {
            var perms = GenerateStableIntPermTableValues().ToArray();

            for (var i = 0U; i < 256U; i++)
            {
                var pivot = 666;

                var r = new Random((int)DateTime.UtcNow.Ticks);

                var data = new int[8] {
                    -1, -1, -1, -1, -1, -1, -1, -1
                };
                for (var j = 0; j < 8; j++)
                {
                    data[j] = (((i >> j) & 0x1) == 0) ? r.Next(0, 666) : r.Next(777, 1000);
                }

                // Check if I messed up and there's a -1 somewhere
                Assert.That(data, Is.All.Not.Negative);

                var permutedData = new int[8];

                fixed(int *perm = &perms[i][0])
                fixed(int *pSrc  = &data[0])
                fixed(int *pDest = &permutedData[0])
                {
                    var dataVector = LoadDquVector256(pSrc);

                    dataVector = PermuteVar8x32(dataVector, LoadDquVector256(perm));
                    Store(pDest, dataVector);
                }

                var numLeft = 8 - (int)Popcnt.PopCount(i);
                Assert.That(permutedData[0..numLeft], Is.All.LessThan(pivot));
示例#2
0
        static IEnumerable <int[]> GenerateStableIntPermTableValues()
        {
            for (var mask = 0U; mask < 256U; mask++)
            {
                var data  = new int[] { -1, -1, -1, -1, -1, -1, -1, -1 };
                var left  = 0;
                var right = 0;

                var numRight     = (int)Popcnt.PopCount(mask);
                var numLeft      = 8 - numRight;
                var leftSegment  = new  Span <int>(data, 0, numLeft);
                var rightSegment = new  Span <int>(data, numLeft, numRight);


                for (var b = 0; b < 8; b++)
                {
                    if (((mask >> b) & 1) == 0)
                    {
                        leftSegment[left++] = b;
                    }
                    else
                    {
                        rightSegment[right++] = b;
                    }
                }

                for (var b = 0; b < 8; b++)
                {
                    Assert.That(data[b], Is.Not.Negative);
                }

                yield return(data);
            }
        }
示例#3
0
        public static uint CountBits(this Span <byte> thisSpan)
        {
            uint result = 0;

            if (Popcnt.IsSupported)
            {
                Span <uint> uintSpam = MemoryMarshal.Cast <byte, uint>(thisSpan);
                for (int i = 0; i < uintSpam.Length; i++)
                {
                    result += Popcnt.PopCount(uintSpam[i]);
                }
            }
            else
            {
                for (int i = 0; i < thisSpan.Length; i++)
                {
                    int n = thisSpan[i];
                    while (n > 0)
                    {
                        n &= n - 1;
                        result++;
                    }
                }
            }

            return(result);
        }
示例#4
0
        static int Main(string[] args)
        {
            int testResult = Pass;

            if (Popcnt.IsSupported)
            {
                uint si;
                uint resi;
                for (int i = 0; i < intPopcntTable.Length; i++)
                {
                    si = intPopcntTable[i].s;

                    resi = Popcnt.PopCount(si);
                    if (resi != intPopcntTable[i].res)
                    {
                        Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x}",
                                          i, si, intPopcntTable[i].res, resi);
                        testResult = Fail;
                    }

                    resi = Convert.ToUInt32(typeof(Popcnt).GetMethod(nameof(Popcnt.PopCount), new Type[] { si.GetType() }).Invoke(null, new object[] { si }));
                    if (resi != intPopcntTable[i].res)
                    {
                        Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x} - Reflection",
                                          i, si, intPopcntTable[i].res, resi);
                        testResult = Fail;
                    }
                }
            }

            return(testResult);
        }
        internal override ImmutableDictionary <TKey, TValue> Add(TKey key, TValue value, uint hash, int shift)
        {
            var bit = 1U << (int)((hash >> shift) & Mask);

            if ((_bitmapNodes & bit) != 0)
            {
                var newNodes = new ImmutableDictionary <TKey, TValue> [_nodes.Length];
                Array.Copy(_nodes, newNodes, _nodes.Length);
                var index = Popcnt.PopCount(_bitmapNodes & (bit - 1));
                newNodes[index] = _nodes[index].Add(key, value, hash, shift + Shift);
                return(new BitMapNode <TKey, TValue, TValues>(_bitmapNodes, newNodes, _bitmapValues, _values));
            }
            else if ((_bitmapValues & bit) != 0)
            {
                // TODO collisions and same value
                var newNodes = new ImmutableDictionary <TKey, TValue> [_nodes.Length + 1];
                var index    = Popcnt.PopCount(_bitmapNodes & (bit - 1));
                Array.Copy(_nodes, newNodes, index);
                Array.Copy(_nodes, index, newNodes, index + 1, _nodes.Length - index);

                var indexValues = Popcnt.PopCount(_bitmapValues & (bit - 1));
                var key2        = _values.GetKey(indexValues);
                var value2      = _values.GetValue(indexValues);
                newNodes[index] = BitMapNode <TKey, TValue, TValues> .From(key, value, hash, shift + Shift, key2, value2);

                return(_values.Shrink(_bitmapNodes | bit, newNodes, _bitmapValues ^ bit, (uint)indexValues));
            }
            else
            {
                var index = (uint)Popcnt.PopCount(_bitmapValues & (bit - 1));
                return(_values.Add(key, value, _bitmapNodes, _nodes, _bitmapValues | bit, index));
            }
        }
示例#6
0
        public static int PopCount(uint value)
        {
            if (Popcnt.IsSupported)
            {
                return((int)Popcnt.PopCount(value));
            }

            return(SoftwareFallback(value));
示例#7
0
        private static int SkipAvx(byte[] content, int index, int endIndex, ref uint depth)
        {
            // Load a vector to convert unsigned to signed value order (only signed compare supported)
            Vector256 <sbyte> toSignedV = SetAllTo(128);

            // Look for StartObject, StartArray, EndObject, EndArray
            Vector256 <sbyte> startOrEndCutoffV = SetAllTo(0xFB);

            startOrEndCutoffV = Avx2.Subtract(startOrEndCutoffV, toSignedV);

            Vector256 <sbyte> startCutoffV = SetAllTo(0xFD);

            startCutoffV = Avx2.Subtract(startCutoffV, toSignedV);

            fixed(byte *contentPtr = &content[0])
            {
                int fullBlockLength = endIndex - 32;

                int i;

                for (i = index; i < fullBlockLength; i += 32)
                {
                    // Load a vector of content and convert to signed
                    Vector256 <sbyte> contentV  = Unsafe.ReadUnaligned <Vector256 <sbyte> >(&contentPtr[i]);
                    Vector256 <sbyte> contentSV = Avx2.Subtract(contentV, toSignedV);

                    // Find start containers only, convert to bit vector
                    Vector256 <sbyte> startV = Avx2.CompareGreaterThan(contentSV, startCutoffV);
                    uint startBits           = unchecked ((uint)Avx2.MoveMask(startV));

                    // Find all start or end containers, convert to bit vector
                    Vector256 <sbyte> startOrEndV = Avx2.CompareGreaterThan(contentSV, startOrEndCutoffV);
                    uint startOrEndBits           = unchecked ((uint)Avx2.MoveMask(startOrEndV));
                    uint endBits = (startOrEndBits & ~startBits);

                    // Count start and ends found
                    uint startCount = Popcnt.PopCount(startBits);
                    uint endCount   = Popcnt.PopCount(endBits);

                    if (depth - endCount <= 0)
                    {
                        // If there are enough end containers here to reach the root, we have to check the order
                        int inner = SkipCs(content, i, i + 32, ref depth);
                        if (inner < i + 32)
                        {
                            return(inner);
                        }
                    }
                    else
                    {
                        // Otherwise, it's safe to continue looking for the end
                        depth = depth - endCount + startCount;
                    }
                }

                return(SkipCs(content, i, endIndex, ref depth));
            }
        }
        private static unsafe int PopCount(uint x)
        {
            if (Popcnt.IsSupported)
            {
                return((int)Popcnt.PopCount(x));
            }

            return(PrecomputedPopcnt.Bits.wordBits[x & 0xFFFF] + PrecomputedPopcnt.Bits.wordBits[x >> 16]);
        }
示例#9
0
        static int Main(string[] args)
        {
            ulong sl = 0;
            long  resl;
            int   testResult = Pass;

            if (!Popcnt.IsSupported || !Environment.Is64BitProcess)
            {
                try
                {
                    resl = Popcnt.PopCount(sl);
                    Console.WriteLine("Intrinsic Popcnt.PopCount is called on non-supported hardware");
                    Console.WriteLine("Popcnt.IsSupported " + Popcnt.IsSupported);
                    Console.WriteLine("Environment.Is64BitProcess " + Environment.Is64BitProcess);
                    return(Fail);
                }
                catch (PlatformNotSupportedException)
                {
                    testResult = Pass;
                }
            }


            if (Popcnt.IsSupported)
            {
                if (Environment.Is64BitProcess)
                {
                    for (int i = 0; i < longPopcntTable.Length; i++)
                    {
                        sl   = longPopcntTable[i].s;
                        resl = Popcnt.PopCount(sl);
                        if (resl != longPopcntTable[i].res)
                        {
                            Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x}",
                                              i, sl, longPopcntTable[i].res, resl);
                            testResult = Fail;
                        }
                    }
                }

                uint si;
                int  resi;
                for (int i = 0; i < intPopcntTable.Length; i++)
                {
                    si   = intPopcntTable[i].s;
                    resi = Popcnt.PopCount(si);
                    if (resi != intPopcntTable[i].res)
                    {
                        Console.WriteLine("{0}: Inputs: 0x{1,16:x} Expected: 0x{3,16:x} actual: 0x{4,16:x}",
                                          i, si, intPopcntTable[i].res, resi);
                        testResult = Fail;
                    }
                }
            }

            return(testResult);
        }
示例#10
0
        /// <summary>
        /// Counts the total population of enabled bits in the source
        /// </summary>
        /// <param name="src">The bit source</param>
        public static ulong pop(Span <ushort> src)
        {
            var count = 0u;

            for (var i = 0; i < src.Length; i++)
            {
                count += Popcnt.PopCount(src[i]);
            }
            return(count);
        }
示例#11
0
        public static int PopCount(uint value)
        {
#if NETCOREAPP2_1
            if (IsPopcountSupported)
            {
                return(Popcnt.PopCount(value));
            }
#endif
            return(PopcountManaged(value));
        }
示例#12
0
        public static uint PopCount(uint value)
        {
#if HAS_INTRINSICS
            if (IsPopcountSupported)
            {
                return(Popcnt.PopCount(value));
            }
#endif
            return(PopcountManaged(value));
        }
示例#13
0
 public static bool IsPow2(uint value)
 {
     if (Popcnt.IsSupported)
     {
         return(Popcnt.PopCount(value) == 1);
     }
     else
     {
         return(unchecked ((value & (value - 1)) == 0) && (value != 0));
     }
 }
示例#14
0
    public static uint GetSetBitCount(uint i)
    {
#if NETCOREAPP
        // use the popcnt intrinsic to find the number of set bits for the input value
        return(Popcnt.PopCount(i));
#else
        i = i - ((i >> 1) & 0x55555555U);
        i = (i & 0x33333333U) + ((i >> 2) & 0x33333333U);
        return((uint)(unchecked (((i + (i >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24));
#endif
    }
示例#15
0
 public static size_t hamming(UInt64 input_num)
 {
     if (IntPtr.Size == 8)
     {
         return(Popcnt.X64.PopCount(input_num));
     }
     else
     {
         return((size_t)(Popcnt.PopCount((UInt32)input_num) +
                         Popcnt.PopCount((UInt32)(input_num >> 32))));
     }
 }
        internal override bool ContainsKey(TKey key, uint hash, int shift)
        {
            var bit = 1U << (int)((hash >> shift) & Mask);

            if ((_bitmap & bit) == 0)
            {
                return(false);
            }
            var index = Popcnt.PopCount((_bitmap >> (int)bit) & Mask);

            return(_nodes[index].ContainsKey(key, hash, shift + Shift));
        }
示例#17
0
        public int PopCountIntrinsic()
        {
            long longResult = 0;
            var  data       = numbers;

            for (int i = 0; i < N; i++)
            {
                longResult += Popcnt.PopCount(data[i]);
            }

            return((int)longResult);
        }
示例#18
0
        public override void Solve(IOManager io)
        {
            var girls           = io.ReadInt();
            var boys            = io.ReadInt();
            var girlsGroup      = io.ReadInt();
            var boysGroup       = io.ReadInt();
            var chocolatesCount = io.ReadInt();

            var chocolates = Enumerable.Repeat(0, boys).Select(_ => new List <Chocolate>()).ToArray();

            for (int i = 0; i < chocolatesCount; i++)
            {
                var g = io.ReadInt() - 1;
                var b = io.ReadInt() - 1;
                var h = io.ReadInt();

                chocolates[b].Add(new Chocolate(g, h));
            }

            int max = 0;

            for (var flag = BitSet.Zero; flag < 1 << girls; flag++)
            {
                if (Popcnt.PopCount(flag) != girlsGroup)
                {
                    continue;
                }

                var currentMax = new int[boys + 1];

                for (int boy = 0; boy < chocolates.Length; boy++)
                {
                    int sum = 0;
                    foreach (var choco in chocolates[boy])
                    {
                        if (flag[choco.Girl])
                        {
                            sum += choco.Happiness;
                        }
                    }

                    for (int i = currentMax.Length - 2; i >= 0; i--)
                    {
                        currentMax[i + 1] = Math.Max(currentMax[i + 1], currentMax[i] + sum);
                    }
                }

                max = Math.Max(max, currentMax[boysGroup]);
            }

            io.WriteLine(max);
        }
示例#19
0
    public static ulong GetSetBitCount(ulong i)
    {
#if NETCOREAPP
        // use the popcnt intrinsic to find the number of set bits for the input value
#if WIN64
        return(Popcnt.X64.PopCount(i));
#else
        return(Popcnt.PopCount(unchecked ((uint)(i & 0xFFFFFFFFUL))) +
               Popcnt.PopCount(unchecked ((uint)((i >> 32) & 0xFFFFFFFFUL))));
#endif
#else
        i = i - ((i >> 1) & 0x5555555555555555UL);
        i = (i & 0x3333333333333333UL) + ((i >> 2) & 0x3333333333333333UL);
        return((ulong)(unchecked (((i + (i >> 4)) & 0xF0F0F0F0F0F0F0FUL) * 0x101010101010101UL) >> 56));
#endif
    }
示例#20
0
        public int GetPrimeCount()
        {
            if (flags_ is null)
            {
                return(-1);
            }

            int ret = 3;

            foreach (var f in flags_)
            {
                ret += (int)Popcnt.PopCount(f);
            }

            return(ret);
        }
示例#21
0
        public static int PopCount(uint value)
        {
            if (Popcnt.IsSupported)
            {
                return((int)Popcnt.PopCount(value));
            }

            if (AdvSimd.Arm64.IsSupported)
            {
                // PopCount works on vector so convert input value to vector first.

                Vector64 <uint> input      = Vector64.CreateScalar(value);
                Vector64 <byte> aggregated = AdvSimd.Arm64.AddAcross(AdvSimd.PopCount(input.AsByte()));
                return(aggregated.ToScalar());
            }

            return(SoftwareFallback(value));
示例#22
0
        public static byte GetChannelDepth(ushort maxValue)
        {
            // If the hardware instruction is available, use this one, because it's WAY faster...
            if (Popcnt.IsSupported)
            {
                return((byte)Popcnt.PopCount(maxValue));
            }

            // Fallback: https://en.wikichip.org/wiki/population_count#Implementations
            // TODO: Probably there is something faster for this special use case, but mostly popcnt will be available anyway.
            byte depth = 0;

            for (; maxValue != 0; maxValue &= (ushort)(maxValue - 1))
            {
                depth++;
            }
            return(depth);
        }
        internal override bool ContainsKey(TKey key, uint hash, int shift)
        {
            var bit = 1U << (int)((hash >> shift) & Mask);

            if ((_bitmapNodes & bit) != 0)
            {
                var index = Popcnt.PopCount(_bitmapNodes & (bit - 1));
                return(_nodes.ContainsKey(key, hash, (int)index, shift + Shift));
            }
            else if ((_bitmapValues & bit) != 0)
            {
                var index = Popcnt.PopCount(_bitmapValues & (bit - 1));
                return(_values.ContainsKey(key, hash, index));
            }
            else
            {
                return(false);
            }
        }
示例#24
0
        public int Run()
        {
            var value = _value;

            // begin
            if (Popcnt.IsSupported) // assume is true
            {
                return((int)Popcnt.PopCount(value));
            }

            int count;

            for (count = 0; value != 0; count++)
            {
                value &= value - 1;
            }

            return(count);
            // end
        }
示例#25
0
        public static int PopCount(uint value)
        {
            if (Popcnt.IsSupported)
            {
                return((int)Popcnt.PopCount(value));
            }

            if (AdvSimd.Arm64.IsSupported)
            {
                // PopCount works on vector so convert input value to vector first.

                // Vector64.CreateScalar(uint) generates suboptimal code by storing and
                // loading the result to memory.
                // See https://github.com/dotnet/runtime/issues/35976 for details.
                // Hence use Vector64.Create(ulong) to create Vector64<ulong> and operate on that.
                Vector64 <ulong> input      = Vector64.Create((ulong)value);
                Vector64 <byte>  aggregated = AdvSimd.Arm64.AddAcross(AdvSimd.PopCount(input.AsByte()));
                return(aggregated.ToScalar());
            }

            return(SoftwareFallback(value));
示例#26
0
        public override ulong Run(CancellationToken cancellationToken)
        {
            if (!Popcnt.IsSupported)
            {
                return(0uL);
            }

            var iterations = 0uL;

            while (!cancellationToken.IsCancellationRequested)
            {
                for (var i = 0; i < LENGTH; i++)
                {
                    data = Popcnt.PopCount(data);
                }

                iterations++;
            }

            return(iterations);
        }
示例#27
0
        public (List <int> codes, int score) Solve(int gridCode)
        {
            var minScore      = int.MaxValue;
            var solutionCodes = new List <int>();

            for (int i = 0; i < 1 << (Size * Size); i++)
            {
                var numBlack = (int)Popcnt.PopCount((uint)(gridCode ^ flipActions[i]));
                var score    = (int)Popcnt.PopCount((uint)i) + Math.Min(numBlack, Size * Size - numBlack);
                if (minScore >= score)
                {
                    if (minScore > score)
                    {
                        solutionCodes.Clear();
                    }
                    solutionCodes.Add(i);
                    minScore = score;
                }
            }
            return(solutionCodes, minScore);
        }
示例#28
0
        internal static int GetHammingDistanceCore(ulong v)
        {
#if !NO_X86_INSTRINSICS
            unchecked
            {
                if (Popcnt.X64.IsSupported)
                {
                    return((int)Popcnt.X64.PopCount(v));
                }
                if (Popcnt.IsSupported)
                {
                    return((int)(Popcnt.PopCount((uint)v) + Popcnt.PopCount((uint)(v >> 32))));
                }
            }
#endif
            unchecked
            {
                v = v - ((v >> 1) & 0x5555555555555555UL);
                v = (v & 0x3333333333333333UL) + ((v >> 2) & 0x3333333333333333UL);
                return((int)((((v + (v >> 4)) & 0xF0F0F0F0F0F0F0FUL) * 0x101010101010101UL) >> 56));
            }
        }
        internal override ImmutableDictionary <TKey, TValue> Add(TKey key, TValue value, uint hash, int shift)
        {
            var bit = 1U << (int)((hash >> shift) & Mask);

            if ((_bitmapNodes & bit) != 0)
            {
                var index = Popcnt.PopCount(_bitmapNodes & (bit - 1));
                return(_nodes.DuplicateWith(key, value, hash, index, shift, _bitmapNodes, _bitmapValues, _values));
            }
            else if ((_bitmapValues & bit) != 0)
            {
                // TODO collisions and same value
                var index       = Popcnt.PopCount(_bitmapNodes & (bit - 1));
                var indexValues = Popcnt.PopCount(_bitmapValues & (bit - 1));
                return(_nodes.Add(key, value, hash, (uint)index, (uint)indexValues, shift, _bitmapNodes | bit, _bitmapValues ^ bit, _values));
            }
            else
            {
                var index = (uint)Popcnt.PopCount(_bitmapValues & (bit - 1));
                return(_values.Add(key, value, _bitmapNodes, _nodes, _bitmapValues | bit, index));
            }
        }
        internal override ImmutableDictionary <TKey, TValue> Add(TKey key, TValue value, uint hash, int shift)
        {
            var bit = 1U << (int)((hash >> shift) & Mask);

            if ((_bitmap & bit) != 0)
            {
                var newNodes = new ImmutableDictionary <TKey, TValue> [_nodes.Length];
                Array.Copy(_nodes, newNodes, _nodes.Length);
                var index = Popcnt.PopCount((_bitmap >> (int)bit) & Mask);
                newNodes[index] = _nodes[index].Add(key, value, hash, shift + Shift);
                return(new BitMapNode <TKey, TValue>(_bitmap, newNodes));
            }
            else
            {
                var index    = Popcnt.PopCount((_bitmap >> (int)bit) & Mask);
                var newNodes = new ImmutableDictionary <TKey, TValue> [_nodes.Length + 1];
                Array.Copy(_nodes, newNodes, index);
                Array.Copy(_nodes, index, newNodes, index + 1, _nodes.Length - index);
                newNodes[index] = new KeyValueNode <TKey, TValue>(key, value, hash);
                return(new BitMapNode <TKey, TValue>(_bitmap | bit, newNodes));
            }
        }