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
        }
示例#3
0
        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
        }
示例#5
0
 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);
        }
示例#7
0
        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)));
        }
示例#8
0
        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);
            }
        }
示例#13
0
        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.");
        }
示例#14
0
        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);
        }
示例#15
0
        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.");
        }
示例#19
0
 /// <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);
示例#20
0
        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();
                }
            });
        }