示例#1
0
        public async Task <IHastlayer> InitializeHastlayer(bool verifyOutput, bool randomSeedEnable)
        {
            _verifyOutput     = verifyOutput;
            _randomSeedEnable = randomSeedEnable;

            LogItFunction("Creating Hastlayer Factory...");

            var hastlayer = await Hastlayer.Create();

            hastlayer.ExecutedOnHardware += (sender, e) =>
            {
                LogItFunction("Hastlayer timer: " +
                              e.HardwareExecutionInformation.HardwareExecutionTimeMilliseconds + "ms (net) / " +
                              e.HardwareExecutionInformation.FullExecutionTimeMilliseconds + " ms (total)"
                              );
            };

            var configuration = new HardwareGenerationConfiguration((await hastlayer.GetSupportedDevices()).First().Name);

            configuration.VhdlTransformerConfiguration().VhdlGenerationConfiguration = VhdlGenerationConfiguration.Debug;
            configuration.EnableCaching = false;

            LogItFunction("Generating hardware...");

            if (_kpzTarget.HastlayerParallelizedAlgorithm())
            {
                configuration.AddHardwareEntryPointType <KpzKernelsParallelizedInterface>();
                configuration.TransformerConfiguration().AddAdditionalInlinableMethod <RandomMwc64X>(r => r.NextUInt32());
            }
            else if (_kpzTarget.HastlayerPlainAlgorithm())
            {
                configuration.AddHardwareEntryPointType <KpzKernelsInterface>();
            }
            else // if (kpzTarget == KpzTarget.PrngTest)
            {
                configuration.AddHardwareEntryPointType <PrngTestInterface>();
            }


            var hardwareRepresentation = await hastlayer.GenerateHardware(new[] {
                typeof(KpzKernelsParallelizedInterface).Assembly,
                typeof(RandomMwc64X).Assembly
            }, configuration);

            await hardwareRepresentation.HardwareDescription.WriteSource(VhdlOutputFilePath);

            LogItFunction("Generating proxy...");

            if (_kpzTarget.HastlayerOnFpga())
            {
                var proxyConf = new ProxyGenerationConfiguration
                {
                    VerifyHardwareResults = _verifyOutput
                };

                if (_kpzTarget == KpzTarget.Fpga)
                {
                    Kernels = await hastlayer.GenerateProxy(
                        hardwareRepresentation,
                        new KpzKernelsInterface(),
                        proxyConf);
                }
                else if (_kpzTarget == KpzTarget.FpgaParallelized)
                {
                    KernelsParallelized = await hastlayer.GenerateProxy(
                        hardwareRepresentation,
                        new KpzKernelsParallelizedInterface(),
                        proxyConf);
                }
                else //if(kpzTarget == KpzTarget.PrngTest)
                {
                    KernelsP = await hastlayer.GenerateProxy(
                        hardwareRepresentation,
                        new PrngTestInterface(),
                        proxyConf);
                }

                LogItFunction("FPGA target detected");
            }
            else //if (kpzTarget == KpzTarget.HastlayerSimulation())
            {
                Kernels             = new KpzKernelsInterface();
                KernelsParallelized = new KpzKernelsParallelizedInterface();
                LogItFunction("Simulation target detected");
            }

            if (_kpzTarget.HastlayerPlainAlgorithm())
            {
                LogItFunction("Running TestAdd...");
                uint resultFpga = Kernels.TestAddWrapper(4313, 123);
                uint resultCpu  = 4313 + 123;
                if (resultCpu == resultFpga)
                {
                    LogItFunction(string.Format("Success: {0} == {1}", resultFpga, resultCpu));
                }
                else
                {
                    LogItFunction(string.Format("Fail: {0} != {1}", resultFpga, resultCpu));
                }
            }

            if (_kpzTarget == KpzTarget.PrngTest)
            {
                LogItFunction("Running TestPrng...");

                var   kernelsCpu = new PrngTestInterface();
                ulong randomSeed = 0x37a92d76a96ef210UL;
                var   smCpu      = kernelsCpu.PushRandomSeed(randomSeed);
                var   smFpga     = KernelsP.PushRandomSeed(randomSeed);
                LogItFunction("PRNG results:");
                bool success = true;

                for (int PrngTestIndex = 0; PrngTestIndex < 10; PrngTestIndex++)
                {
                    uint prngCpuResult  = kernelsCpu.GetNextRandom(smCpu);
                    uint prngFpgaResult = KernelsP.GetNextRandom(smFpga);
                    if (prngCpuResult != prngFpgaResult)
                    {
                        success = false;
                    }
                    LogItFunction(String.Format("{0}, {1}", prngCpuResult, prngFpgaResult));
                }

                if (success)
                {
                    LogItFunction("TestPrng succeeded!");
                }
                else
                {
                    LogItFunction("TestPrng failed!");
                }
            }
            return(hastlayer);
        }
        /// <summary>
        /// Wrapper for calling <see cref="KpzKernelsParallelizedInterface.ScheduleIterations"/>.
        /// </summary>
        /// <param name="hostGrid">The grid that we work on.</param>
        /// <param name="pushToFpga">Force pushing the grid into the FPGA (or work on the grid already there).</param>
        /// <param name="randomSeedEnable">
        /// If it is disabled, preprogrammed random numbers will be written into
        /// SimpleMemory instead of real random generated numbers. This helps debugging, keeping the output more
        /// consistent across runs.
        /// </param>
        /// <param name="numberOfIterations">The number of iterations to perform.</param>
        public static void DoIterationsWrapper(this KpzKernelsParallelizedInterface kernels, KpzNode[,] hostGrid, bool pushToFpga,
                                               bool randomSeedEnable, uint numberOfIterations)
        {
            // The following numbers will be used when random seed is disabled in GUI.
            // This makes the result more predictable while debugging.
            // Add more random numbers manually if you get an out of bounds exception on notRandomSeed.
            // This might happen if you increase KpzKernelsGInterface.ParallelTasks.
            // You can generate these with the following python expression:
            //    print [random.randint(-2147483648, 2147483647) for x in range(32)]
            var notRandomSeed = new int[] {
                -2122284207, -805426534, -296351199, 1082586369, -864339821,
                331357875, 1192493543, -851078246, -1091834350, -671234217,
                -1623097030, -100086504, -1516943165, 1569609717, 1695030944,
                -888770401, 341459416, -1970567826, 794279071, 1480098339,
                -2057457019, -257344031, -850635314, -210624876, -678618985,
                -232192458, 2099559718, 1809993314, -43947016, -1478372364,
                -1049983320, -827693764,
                541247270, -762735333, 1201597916, 63792507, 572540375,
                372071952, -1908453570, -79328169, -792331270, -499848108,
                -824609528, -1798425884, 1921971887, 334688140, -1210315495,
                303879804, -854493128, 168364778, 1153057767, 1892111935,
                -1121887497, -411064952, -1153708605, -1236973870, 1909433338,
                840379860, 648328296, 815910809, 1054583403, 641704477,
                -751562304, 1514065758, -1503136866, -290638406, -1465068879,
                -480074650, -1189373896, 1628987870, -1801471129, 1149055452,
                -1213044536, 1501859543, 1766766693, -11506391, 1354826834,
                -1605994989, 1371816845, -1806325888, 899112301, -1972685877,
                -1351549709, 1989386170, -1745931254, -1294330993, -280576358,
                -1135040353, 2064141162, -1550762441, 206482802, -208760219,
                -1763282295, -1559411916, 212239689, -1713858924, 1957674632,
                399597100, -1822066773, -521605668, 442732461, 2139235466,
                1949728360, -1333355612, -1523271090, 1873782401, 109175483,
                1455879393, -1508517739, 22132201, 1503847013, 1121324155,
                -1149836541, -174007501, 1742754517, 514371316, -1438578033,
                605535816, 1415254613, 1944255343, -1057195252, 1981414947,
                -356281736, -589212081, 1146701526, 224674108, 2035824054,
                292251866, 1396937563, 1323024996, -1196314790, 1566610809,
                928352174, 1714994319, -799030393, -462839450, -418035901,
                -1286542568, -1534707733, 985188849, -1960744352, -1463825054,
                -1344050653, 1279472494, -1840938918, 1248877495, 861602743,
                844790112, -1844342060, 1945398439, 309808498, -239141205,
                -54120626, 499261195, -1761618908, 966279259, 217571661,
                93473713, -937734760, -279968717
            };

            int numRandomUints = 2 + KpzKernelsParallelizedInterface.ParallelTasks * 4;
            var sm             = new SimpleMemory(
                KpzKernelsParallelizedInterface.GridSize * KpzKernelsParallelizedInterface.GridSize + numRandomUints + 1);

            if (pushToFpga)
            {
                CopyFromGridToSimpleMemory(hostGrid, sm);
            }

            sm.WriteUInt32(KpzKernelsParallelizedInterface.MemIndexNumberOfIterations, numberOfIterations);

            var rnd = new Random();

            for (int randomWriteIndex = 0; randomWriteIndex < numRandomUints; randomWriteIndex++)
            {
                sm.WriteUInt32(KpzKernelsParallelizedInterface.MemIndexRandomSeed + randomWriteIndex,
                               (randomSeedEnable) ? (uint)rnd.Next() : (uint)notRandomSeed[randomWriteIndex]);
                //See comment on notRandomSeed if you get an index out of bounds error here.
            }

            kernels.ScheduleIterations(sm);

            CopyFromSimpleMemoryToGrid(hostGrid, sm);
        }