/// <summary> /// This function adds two numbers on the FPGA using <see cref="KpzKernelsInterface.TestAdd(SimpleMemory)"/>. /// </summary> public static uint TestAddWrapper(this KpzKernelsInterface kernels, uint a, uint b) { var sm = new SimpleMemory(3); sm.WriteUInt32(0, a); sm.WriteUInt32(1, b); kernels.TestAdd(sm); return(sm.ReadUInt32(2)); }
/// <summary> /// This is a wrapper for running the KPZ algorithm on the FPGA. /// </summary> /// <param name="kernels"></param> /// <param name="hostGrid"> /// This is the grid of initial <see cref="KpzNode"/> items for the algorithm to work on. /// </param> /// <param name="pushToFpga"> /// If this parameter is false, the FPGA will work on the grid currently available in it, /// instead of the grid in the <see cref="hostGrid"/> parameter. /// </param> /// <param name="testMode"> /// does several things: /// <list type="bullet"> /// <item> /// if it is true, <see cref="KpzKernels.RandomlySwitchFourCells(bool)"/> always switches the cells /// if it finds an adequate place, /// </item> /// <item> /// it also does only a single poke, then sends the grid back to the host so that the algorithm /// can be analyzed in the step-by-step window. /// </item> /// </list> /// </param> /// <param name="randomSeed1">is a random seed for the algorithm.</param> /// <param name="randomSeed2">is a random seed for the algorithm.</param> /// <param name="numberOfIterations">is the number of iterations to perform.</param> public static void DoIterationsWrapper(this KpzKernelsInterface kernels, KpzNode[,] hostGrid, bool pushToFpga, bool testMode, ulong randomSeed1, ulong randomSeed2, uint numberOfIterations) { SimpleMemory sm = new SimpleMemory(KpzKernels.SizeOfSimpleMemory); if (pushToFpga) { CopyParametersToMemory(sm, testMode, randomSeed1, randomSeed2, numberOfIterations); CopyFromGridToSimpleMemory(hostGrid, sm); } kernels.DoIterations(sm); CopyFromSimpleMemoryToGrid(hostGrid, sm); }
/// <summary> /// This function generates random numbers on the FPGA using /// <see cref="KpzKernelsInterface.TestPrng(SimpleMemory)"/>. /// </summary> public static uint[] TestPrngWrapper(this KpzKernelsInterface kernels) { var numbers = new uint[KpzKernels.GridWidth * KpzKernels.GridHeight]; var sm = new SimpleMemory(KpzKernels.SizeOfSimpleMemory); CopyParametersToMemory(sm, false, 0x5289a3b89ac5f211, 0x5289a3b89ac5f211, 0); kernels.TestPrng(sm); for (int i = 0; i < KpzKernels.GridWidth * KpzKernels.GridHeight; i++) { numbers[i] = sm.ReadUInt32(i); } return(numbers); }
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); }