public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var monteCarloAlgorithm = await hastlayer .GenerateProxy(hardwareRepresentation, new MonteCarloAlgorithm()); var monteCarloResult = monteCarloAlgorithm.CalculateTorusSectionValues(5000000); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var recursiveAlgorithms = await hastlayer.GenerateProxy(hardwareRepresentation, new RecursiveAlgorithms()); var fibonacci = recursiveAlgorithms.CalculateFibonacchiSeries(13); // 233 var factorial = recursiveAlgorithms.CalculateFactorial(6); // 720 }
public async Task <T> GenerateProxy <T>( IHardwareRepresentation hardwareRepresentation, T hardwareObject, IProxyGenerationConfiguration configuration) where T : class { if (!hardwareRepresentation.SoftAssemblyPaths.Contains(hardwareObject.GetType().Assembly.Location)) { throw new InvalidOperationException( "The supplied type is not part of any assembly that this hardware representation was generated from."); } try { return(await _host .RunGet(scope => Task.Run(() => scope.Resolve <IProxyGenerator>().CreateCommunicationProxy(hardwareRepresentation, hardwareObject, configuration)))); } catch (Exception ex) when(!ex.IsFatal()) { var message = "An error happened during generating the Hastlayer proxy for an object of the following type: " + hardwareObject.GetType().FullName; await _host.Run <ILoggerService>(logger => Task.Run(() => logger.Error(ex, message))); throw new HastlayerException(message, ex); } }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var ooShowcase = await hastlayer .GenerateProxy(hardwareRepresentation, new ObjectOrientedShowcase()); var sum = ooShowcase.Run(93); // 293 }
public ExecutedOnHardwareEventArgs( IHardwareRepresentation hardwareRepresentation, string memberFullName, IHardwareExecutionInformation hardwareExecutionInformation) { _hardwareRepresentation = hardwareRepresentation; _memberFullName = memberFullName; _hardwareExecutionInformation = hardwareExecutionInformation; }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var loopback = await hastlayer.GenerateProxy(hardwareRepresentation, new Loopback()); var output1 = loopback.Run(123); var output2 = loopback.Run(1234); var output3 = loopback.Run(-9); var output4 = loopback.Run(0); var output5 = loopback.Run(-19); var output6 = loopback.Run(1); }
public T CreateCommunicationProxy <T>(IHardwareRepresentation hardwareRepresentation, T target, IProxyGenerationConfiguration configuration) where T : class { var memberInvocationHandler = _memberInvocationHandlerFactory.CreateMemberInvocationHandler(hardwareRepresentation, target, configuration); if (typeof(T).IsInterface) { return(_proxyGenerator.CreateInterfaceProxyWithTarget(target, new MemberInvocationInterceptor(memberInvocationHandler))); } return(_proxyGenerator.CreateClassProxyWithTarget(target, new MemberInvocationInterceptor(memberInvocationHandler))); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var memoryTest = await hastlayer.GenerateProxy(hardwareRepresentation, new MemoryTest()); var output1 = memoryTest.Run(0, 1); var output2 = memoryTest.Run(0, 3); var output3 = memoryTest.Run(0, 7); var output4 = memoryTest.Run(0, 50); var output5 = memoryTest.Run(1, 1); var output6 = memoryTest.Run(3, 7); var output7 = memoryTest.Run(47, 100); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { // Starting with 1 not to have a divide by zero. var vector = Enumerable.Range(1, SimdCalculator.MaxDegreeOfParallelism * 4).ToArray(); var simdCalculator = await hastlayer.GenerateProxy(hardwareRepresentation, new SimdCalculator()); var sumVector = ThrowIfNotCorrect(simdCalculator, calculator => calculator.AddVectors(vector, vector)); var differenceVector = ThrowIfNotCorrect(simdCalculator, calculator => calculator.SubtractVectors(vector, vector)); var productVector = ThrowIfNotCorrect(simdCalculator, calculator => calculator.MultiplyVectors(vector, vector)); var quotientVector = ThrowIfNotCorrect(simdCalculator, calculator => calculator.DivideVectors(vector, vector)); }
public BasicExecutionContext(IHastlayer hastlayer, string deviceName, string communicationChannelName, Dictionary <string, object> customConfiguration = null) { HardwareRepresentation = hastlayer.GenerateHardware(new Assembly[] { Assembly.GetExecutingAssembly() }, new HardwareGenerationConfiguration(deviceName)).Result; ProxyGenerationConfiguration = new ProxyGenerationConfiguration() { CommunicationChannelName = communicationChannelName, CustomConfiguration = customConfiguration ?? new Dictionary <string, object>(), VerifyHardwareResults = false }; }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var cpuOjutput = new FSharpParallelAlgorithmContainer.FSharpParallelAlgorithm().Run(234234); var parallelAlgorithm = await hastlayer.GenerateProxy(hardwareRepresentation, new FSharpParallelAlgorithmContainer.FSharpParallelAlgorithm()); var output1 = parallelAlgorithm.Run(234234); var output2 = parallelAlgorithm.Run(123); var output3 = parallelAlgorithm.Run(9999); var sw = System.Diagnostics.Stopwatch.StartNew(); var cpuOutput = new FSharpParallelAlgorithmContainer.FSharpParallelAlgorithm().Run(234234); sw.Stop(); System.Console.WriteLine("On CPU it took " + sw.ElapsedMilliseconds + "ms."); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { using (var bitmap = new Bitmap("fpga.jpg")) { var imageContrastModifier = await hastlayer .GenerateProxy(hardwareRepresentation, new ImageContrastModifier()); // This takes about 160ms on an i7 CPU and net 150ms on an FPGA. var modifiedImage = imageContrastModifier.ChangeImageContrast(bitmap, -50); modifiedImage.Save("contrast.bmp"); // ImageFilter disabled until it's improved. //var imageFilter = await hastlayer.GenerateProxy(hardwareRepresentation, new ImageFilter()); //var filteredImage = imageFilter.DetectHorizontalEdges(bitmap); } }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var hastlayerOptimizedAlgorithm = await hastlayer.GenerateProxy(hardwareRepresentation, new ParallelAlgorithm()); // This takes about 1900ms on an i7 processor with 4 physical (8 logical) cores and 300ms on an FPGA (with // a MaxDegreeOfParallelism of 280 while the device is about 80% utilized). With a higher degree of // parallelism it won't fit on the Nexys 4 DDR board's FPGA. var output1 = hastlayerOptimizedAlgorithm.Run(234234); var output2 = hastlayerOptimizedAlgorithm.Run(123); var output3 = hastlayerOptimizedAlgorithm.Run(9999); var sw = System.Diagnostics.Stopwatch.StartNew(); var cpuOutput = new ParallelAlgorithm().Run(234234); sw.Stop(); System.Console.WriteLine("On CPU it took " + sw.ElapsedMilliseconds + "ms."); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var primeCalculator = await hastlayer.GenerateProxy(hardwareRepresentation, new PrimeCalculator()); var isPrime = primeCalculator.IsPrimeNumber(15); var isPrime2 = primeCalculator.IsPrimeNumber(13); var isPrime3 = await primeCalculator.IsPrimeNumberAsync(21); // Only 2341 is prime. var arePrimes = primeCalculator.ArePrimeNumbers(new uint[] { 15, 493, 2341, 99237 }); var arePrimes2 = primeCalculator.ArePrimeNumbers(new uint[] { 13, 493 }); // You can also launch hardware-executed method calls in parallel. If there are multiple boards // connected then all of them will be utilized. If the whole device pool is utilized calls will // wait for their turn. // Uncomment if you have multiple boards connected. //var parallelLaunchedIsPrimeTasks = new List<Task<bool>>(); //for (uint i = 100; i < 110; i++) //{ // parallelLaunchedIsPrimeTasks // .Add(Task.Factory.StartNew(indexObject => primeCalculator.IsPrimeNumber((uint)indexObject), i)); //} //var parallelLaunchedArePrimes = await Task.WhenAll(parallelLaunchedIsPrimeTasks); // In-algorithm parallelization: // Note that if the amount of numbers used here can't be divided by PrimeCalculator.MaxDegreeOfParallelism // then for ParallelizedArePrimeNumbers the input and output will be padded to a divisible amount (see // comments in the method). Thus the communication round-trip will be slower for ParallelizedArePrimeNumbers. // Because of this since PrimeCalculator.MaxDegreeOfParallelism is 30 we use 30 numbers here. // All of these numbers except for 9999 are primes. var numbers = new uint[] { 9749, 9999, 902119, 907469, 915851, 9749, 9973, 902119, 907469, 915851, 9749, 9999, 902119, 907469, 915851, 9749, 9973, 902119, 907469, 915851, 9749, 9999, 902119, 907469, 915851, 9749, 9973, 902119, 907469, 915851 }; var arePrimes3 = primeCalculator.ArePrimeNumbers(numbers); var arePrimes4 = primeCalculator.ParallelizedArePrimeNumbers(numbers); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var genomeMatcher = await hastlayer.GenerateProxy(hardwareRepresentation, new GenomeMatcher()); // Sample from IBM. var inputOne = "GCCCTAGCG"; var inputTwo = "GCGCAATG"; var result = genomeMatcher.CalculateLongestCommonSubsequence(inputOne, inputTwo); // Sample from Wikipedia. inputOne = "ACACACTA"; inputTwo = "AGCACACA"; result = genomeMatcher.CalculateLongestCommonSubsequence(inputOne, inputTwo); inputOne = "lombiqtech"; inputTwo = "coulombtech"; result = genomeMatcher.CalculateLongestCommonSubsequence(inputOne, inputTwo); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var parallelAlgorithm = await hastlayer.GenerateProxy(hardwareRepresentation, new ParallelAlgorithm()); // This takes about 1900ms on an i7 processor with 4 physical (8 logical) cores and 300ms on an FPGA (with // a MaxDegreeOfParallelism of 280 while the device is about 80% utilized). With a higher degree of // parallelism it won't fit on the Nexys A7 board's FPGA. // On Catapult a MaxDegreeOfParallelism of 700 will fit as well (70% resource utilization) and run in about // 200ms (including communication latency) vs about 5s on the previous reference PC. Compiling that // hardware design will take about 14.5 hours though (with MaxDegreeOfParallelism of 600 it'll take about // 4). var output1 = parallelAlgorithm.Run(234234); var output2 = parallelAlgorithm.Run(123); var output3 = parallelAlgorithm.Run(9999); var sw = System.Diagnostics.Stopwatch.StartNew(); var cpuOutput = new ParallelAlgorithm().Run(234234); sw.Stop(); System.Console.WriteLine("On CPU it took " + sw.ElapsedMilliseconds + "ms."); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { var fixed64Calculator = await hastlayer.GenerateProxy(hardwareRepresentation, new Fix64Calculator()); var sum = fixed64Calculator.CalculateIntegerSumUpToNumber(10000000); // This takes about 274ms on an i7 processor with 4 physical (8 logical) cores and 1300ms on an FPGA (with // a MaxDegreeOfParallelism of 13 while the device is about 76% utilized). // Since this basically does what the single-threaded sample but in multiple copies on multiple threads // the single-threaded sample takes the same amount of time on the FPGA. // Creating an array of numbers alternating between 9999999 and 10000001 so we can also see that threads // don't step on each other's feet. var numbers = new int[Fix64Calculator.MaxDegreeOfParallelism]; for (int i = 0; i < Fix64Calculator.MaxDegreeOfParallelism; i++) { numbers[i] = 10000000 + (i % 2 == 0 ? -1 : 1); } var sums = fixed64Calculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers); }
public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) { uint iterationsCount = MonteCarloPiEstimator.MaxDegreeOfParallelism * 500000; // On a Nexys A7 this takes about 34ms with a 76 degree of parallelism and method inlining. It takes // about 120ms on an i7 processor with 4 physical (8 logical) cores. // On Catapult with a 350 degree of parallelism it takes 26ms on hardware and 160ms on the (2*32 logical // core) CPU. var monteCarloPiEstimator = await hastlayer.GenerateProxy(hardwareRepresentation, new MonteCarloPiEstimator()); var piEstimateHardware = monteCarloPiEstimator.EstimatePi(iterationsCount); Console.WriteLine("Estimate for Pi on hardware: " + piEstimateHardware); var sw = System.Diagnostics.Stopwatch.StartNew(); var piEstimateSoftware = new MonteCarloPiEstimator().EstimatePi(iterationsCount); sw.Stop(); Console.WriteLine("Estimate for Pi on software: " + piEstimateSoftware); Console.WriteLine("On CPU it took " + sw.ElapsedMilliseconds + "ms."); }
/// <summary> /// Generates a proxy for the given object that will transfer suitable calls to the hardware implementation using the default proxy generation configuration. /// </summary> /// <typeparam name="T">Type of the object to generate a proxy for.</typeparam> /// <param name="hardwareRepresentation">The representation of the assemblies implemented as hardware.</param> /// <param name="hardwareObject">The object to generate the proxy for.</param> /// <returns>The generated proxy object.</returns> /// <exception cref="HastlayerException"> /// Thrown if any lower-level exception or other error happens during proxy generation. /// </exception> public static Task <T> GenerateProxy <T>( this IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation, T hardwareObject) where T : class => hastlayer.GenerateProxy(hardwareRepresentation, hardwareObject, ProxyGenerationConfiguration.Default);
public MemberInvocationHandler CreateMemberInvocationHandler( IHardwareRepresentation hardwareRepresentation, object target, IProxyGenerationConfiguration configuration) { return(invocation => { var methodAsynchronicity = GetMethodAsynchronicity(invocation); if (methodAsynchronicity == MethodAsynchronicity.AsyncFunction) { throw new NotSupportedException("Only async methods that return a Task, not Task<T>, are supported."); } async Task invocationHandler() { using (var workContext = _wca.CreateWorkContextScope()) { // Although it says Method it can also be a property. var memberFullName = invocation.Method.GetFullName(); var invocationContext = new MemberInvocationContext { Invocation = invocation, MemberFullName = memberFullName, HardwareRepresentation = hardwareRepresentation }; var eventHandler = workContext.Resolve <IMemberInvocationEventHandler>(); eventHandler.MemberInvoking(invocationContext); workContext.Resolve <IEnumerable <IMemberInvocationPipelineStep> >().InvokePipelineSteps(step => { invocationContext.HardwareExecutionIsCancelled = step.CanContinueHardwareExecution(invocationContext); }); if (!invocationContext.HardwareExecutionIsCancelled) { var hardwareMembers = hardwareRepresentation.HardwareDescription.HardwareEntryPointNamesToMemberIdMappings; var memberNameAlternates = new HashSet <string>(hardwareMembers.Keys.SelectMany(member => member.GetMemberNameAlternates())); if (!hardwareMembers.ContainsKey(memberFullName) && !memberNameAlternates.Contains(memberFullName)) { invocationContext.HardwareExecutionIsCancelled = true; } } if (invocationContext.HardwareExecutionIsCancelled) { invocation.Proceed(); if (methodAsynchronicity == MethodAsynchronicity.AsyncAction) { await(Task) invocation.ReturnValue; } return; } var communicationChannelName = configuration.CommunicationChannelName; var deviceManifest = hardwareRepresentation.DeviceManifest; if (string.IsNullOrEmpty(communicationChannelName)) { communicationChannelName = deviceManifest.DefaultCommunicationChannelName; } if (!deviceManifest.SupportedCommunicationChannelNames.Contains(communicationChannelName)) { throw new NotSupportedException( "The configured communication channel \"" + communicationChannelName + "\" is not supported by the current device."); } var memory = (SimpleMemory)invocation.Arguments.SingleOrDefault(argument => argument is SimpleMemory); if (memory != null) { var memoryByteCount = (ulong)memory.CellCount * SimpleMemory.MemoryCellSizeBytes; if (memoryByteCount > deviceManifest.AvailableMemoryBytes) { throw new InvalidOperationException( "The input is too large to fit into the device's memory: the input is " + memoryByteCount + " bytes, the available memory is " + deviceManifest.AvailableMemoryBytes + " bytes."); } SimpleMemory softMemory = null; if (configuration.VerifyHardwareResults) { softMemory = new SimpleMemory(memory.CellCount); var memoryBytes = new SimpleMemoryAccessor(memory).Get(); memoryBytes.CopyTo(new SimpleMemoryAccessor(softMemory).Get()); var memoryArgumentIndex = invocation.Arguments .Select((argument, index) => new { Argument = argument, Index = index }) .Single(argument => argument.Argument is SimpleMemory) .Index; invocation.SetArgumentValue(memoryArgumentIndex, softMemory); // This needs to happen before the awaited Execute() call below, otherwise the Task // in ReturnValue wouldn't be the original one any more. invocation.Proceed(); if (methodAsynchronicity == MethodAsynchronicity.AsyncAction) { await(Task) invocation.ReturnValue; } } // At this point we checked that the hardware entry point does have a mapping. var memberId = hardwareRepresentation .HardwareDescription .HardwareEntryPointNamesToMemberIdMappings[memberFullName]; invocationContext.ExecutionInformation = await workContext .Resolve <ICommunicationServiceSelector>() .GetCommunicationService(communicationChannelName) .Execute( memory, memberId, new HardwareExecutionContext { ProxyGenerationConfiguration = configuration, HardwareRepresentation = hardwareRepresentation }); if (configuration.VerifyHardwareResults) { var mismatches = new List <HardwareExecutionResultMismatchException.Mismatch>(); if (memory.CellCount != softMemory.CellCount) { int overflowIndex = Math.Min(memory.CellCount, softMemory.CellCount); mismatches.Add(new HardwareExecutionResultMismatchException.LengthMismatch( memory.CellCount, softMemory.CellCount, overflowIndex, memory.CellCount > softMemory.CellCount ? memory.Read4Bytes(overflowIndex) : new byte[0], softMemory.CellCount > memory.CellCount ? softMemory.Read4Bytes(overflowIndex) : new byte[0])); } else { for (int i = 0; i < memory.CellCount; i++) { if (!memory.Read4Bytes(i).SequenceEqual(softMemory.Read4Bytes(i))) { mismatches.Add(new HardwareExecutionResultMismatchException.Mismatch( i, memory.Read4Bytes(i), softMemory.Read4Bytes(i))); } } } if (mismatches.Any()) { throw new HardwareExecutionResultMismatchException(mismatches); } } } else { throw new NotSupportedException( "Only SimpleMemory-using implementations are supported for hardware execution. The invocation didn't include a SimpleMemory argument."); } eventHandler.MemberExecutedOnHardware(invocationContext); } } if (methodAsynchronicity == MethodAsynchronicity.AsyncAction) { invocation.ReturnValue = invocationHandler(); } else { invocationHandler().Wait(); } }); }