diff --git a/Hast.Core b/Hast.Core index 3eb677a3a..6454ae2e5 160000 --- a/Hast.Core +++ b/Hast.Core @@ -1 +1 @@ -Subproject commit 3eb677a3a065ee1d255beafaf05436de5f0505af +Subproject commit 6454ae2e5d1db298b93a4909c5d8ce077e4dcb1c diff --git a/Hast.Samples.Posit/App.config b/Hast.Samples.Posit/App.config new file mode 100644 index 000000000..00bfd114a --- /dev/null +++ b/Hast.Samples.Posit/App.config @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Hast.Samples.Posit/Hast.Samples.Posit.csproj b/Hast.Samples.Posit/Hast.Samples.Posit.csproj new file mode 100644 index 000000000..d7a7933c6 --- /dev/null +++ b/Hast.Samples.Posit/Hast.Samples.Posit.csproj @@ -0,0 +1,63 @@ + + + netcoreapp3.1 + Exe + false + true + + + + + + + + + + + + + TextTemplatingFileGenerator + PositCalculator.cs + + + TextTemplatingFileGenerator + PositCalculatorSampleRunner.cs + + + TextTemplatingFileGenerator + Program.cs + + + TextTemplatingFileGenerator + Sample.cs + + + + + + + + + + + True + True + PositCalculator.tt + + + True + True + PositCalculatorSampleRunner.tt + + + True + True + Program.tt + + + True + True + Sample.tt + + + diff --git a/Hast.Samples.Posit/Posit16E0Calculator.cs b/Hast.Samples.Posit/Posit16E0Calculator.cs new file mode 100644 index 000000000..72fa7d8fa --- /dev/null +++ b/Hast.Samples.Posit/Posit16E0Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit16E0Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit16E0((ushort)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (ushort)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit16E0(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit16E0(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit16E0((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit16E0((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit16E0CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit16E0Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit16E0Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit16E0Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit16E0Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit16E0Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit16E0Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit16E0(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit16E0((ushort)memory.ReadUInt32( Posit16E0Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit16E0Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit16E0Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit16E0Calculator is (" + + Posit16E0Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit16E0Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit16E0Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit16E0Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit16E0Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit16E0Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit16E0Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit16E0Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit16E0Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit16E0Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit16E0CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit16E0CalculatorSampleRunner.cs new file mode 100644 index 000000000..4615dd962 --- /dev/null +++ b/Hast.Samples.Posit/Posit16E0CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit16E0CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit16E0Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 10000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit16E0Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E0Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit16E0Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E0Array[i] = new Posit16E0((float)0.25 * 2 * i).PositBits; + else Posit16E0Array[i] = new Posit16E0((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit16E0Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit16E0Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 10000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit16E0Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E0Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit16E0Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E0Array[i] = new Posit16E0((float)0.25 * 2 * i).PositBits; + else Posit16E0Array[i] = new Posit16E0((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit16E0Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit16E0Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit16E1Calculator.cs b/Hast.Samples.Posit/Posit16E1Calculator.cs new file mode 100644 index 000000000..bb8077398 --- /dev/null +++ b/Hast.Samples.Posit/Posit16E1Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit16E1Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit16E1((ushort)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (ushort)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit16E1(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit16E1(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit16E1((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit16E1((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit16E1CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit16E1Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit16E1Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit16E1Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit16E1Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit16E1Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit16E1Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit16E1(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit16E1((ushort)memory.ReadUInt32( Posit16E1Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit16E1Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit16E1Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit16E1Calculator is (" + + Posit16E1Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit16E1Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit16E1Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit16E1Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit16E1Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit16E1Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit16E1Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit16E1Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit16E1Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit16E1Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit16E1CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit16E1CalculatorSampleRunner.cs new file mode 100644 index 000000000..b044c4938 --- /dev/null +++ b/Hast.Samples.Posit/Posit16E1CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit16E1CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit16E1Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 10000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit16E1Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E1Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit16E1Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E1Array[i] = new Posit16E1((float)0.25 * 2 * i).PositBits; + else Posit16E1Array[i] = new Posit16E1((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit16E1Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit16E1Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 10000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit16E1Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E1Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit16E1Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E1Array[i] = new Posit16E1((float)0.25 * 2 * i).PositBits; + else Posit16E1Array[i] = new Posit16E1((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit16E1Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit16E1Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit16E2Calculator.cs b/Hast.Samples.Posit/Posit16E2Calculator.cs new file mode 100644 index 000000000..416da047e --- /dev/null +++ b/Hast.Samples.Posit/Posit16E2Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit16E2Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit16E2((ushort)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (ushort)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit16E2(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit16E2(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit16E2((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit16E2((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit16E2CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit16E2Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit16E2Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit16E2Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit16E2Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit16E2Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit16E2Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit16E2(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit16E2((ushort)memory.ReadUInt32( Posit16E2Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit16E2Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit16E2Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit16E2Calculator is (" + + Posit16E2Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit16E2Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit16E2Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit16E2Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit16E2Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit16E2Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit16E2Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit16E2Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit16E2Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit16E2Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit16E2CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit16E2CalculatorSampleRunner.cs new file mode 100644 index 000000000..ec06540a4 --- /dev/null +++ b/Hast.Samples.Posit/Posit16E2CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit16E2CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit16E2Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 10000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit16E2Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E2Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit16E2Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E2Array[i] = new Posit16E2((float)0.25 * 2 * i).PositBits; + else Posit16E2Array[i] = new Posit16E2((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit16E2Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit16E2Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 10000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit16E2Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E2Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit16E2Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E2Array[i] = new Posit16E2((float)0.25 * 2 * i).PositBits; + else Posit16E2Array[i] = new Posit16E2((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit16E2Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit16E2Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit16E3Calculator.cs b/Hast.Samples.Posit/Posit16E3Calculator.cs new file mode 100644 index 000000000..c9d1559b9 --- /dev/null +++ b/Hast.Samples.Posit/Posit16E3Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit16E3Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit16E3((ushort)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (ushort)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit16E3(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit16E3(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit16E3((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit16E3((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit16E3CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit16E3Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit16E3Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit16E3Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit16E3Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit16E3Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit16E3Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit16E3(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit16E3((ushort)memory.ReadUInt32( Posit16E3Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit16E3Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit16E3Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit16E3Calculator is (" + + Posit16E3Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit16E3Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit16E3Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit16E3Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit16E3Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit16E3Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit16E3Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit16E3Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit16E3Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit16E3Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit16E3CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit16E3CalculatorSampleRunner.cs new file mode 100644 index 000000000..e34544e10 --- /dev/null +++ b/Hast.Samples.Posit/Posit16E3CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit16E3CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit16E3Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 10000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit16E3Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E3Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit16E3Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E3Array[i] = new Posit16E3((float)0.25 * 2 * i).PositBits; + else Posit16E3Array[i] = new Posit16E3((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit16E3Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit16E3Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 10000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit16E3Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E3Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit16E3Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E3Array[i] = new Posit16E3((float)0.25 * 2 * i).PositBits; + else Posit16E3Array[i] = new Posit16E3((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit16E3Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit16E3Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit16E4Calculator.cs b/Hast.Samples.Posit/Posit16E4Calculator.cs new file mode 100644 index 000000000..8b09ac783 --- /dev/null +++ b/Hast.Samples.Posit/Posit16E4Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit16E4Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit16E4((ushort)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (ushort)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit16E4(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit16E4(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit16E4((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit16E4((ushort)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit16E4CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit16E4Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit16E4Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit16E4Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit16E4Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit16E4Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit16E4Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit16E4(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit16E4((ushort)memory.ReadUInt32( Posit16E4Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit16E4Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit16E4Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit16E4Calculator is (" + + Posit16E4Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit16E4Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit16E4Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit16E4Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit16E4Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit16E4Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit16E4Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit16E4Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit16E4Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit16E4Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit16E4CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit16E4CalculatorSampleRunner.cs new file mode 100644 index 000000000..c31fb8e7a --- /dev/null +++ b/Hast.Samples.Posit/Posit16E4CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit16E4CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit16E4Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 10000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit16E4Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E4Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit16E4Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E4Array[i] = new Posit16E4((float)0.25 * 2 * i).PositBits; + else Posit16E4Array[i] = new Posit16E4((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit16E4Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit16E4Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 10000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit16E4Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit16E4Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit16E4Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit16E4Array[i] = new Posit16E4((float)0.25 * 2 * i).PositBits; + else Posit16E4Array[i] = new Posit16E4((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit16E4Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit16E4Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit32E0Calculator.cs b/Hast.Samples.Posit/Posit32E0Calculator.cs new file mode 100644 index 000000000..ea6835d7c --- /dev/null +++ b/Hast.Samples.Posit/Posit32E0Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit32E0Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit32E0((uint)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (uint)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit32E0(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit32E0(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit32E0((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit32E0((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit32E0CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit32E0Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit32E0Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit32E0Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit32E0Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit32E0Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit32E0Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit32E0(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit32E0((uint)memory.ReadUInt32( Posit32E0Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit32E0Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit32E0Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit32E0Calculator is (" + + Posit32E0Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit32E0Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit32E0Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit32E0Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit32E0Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit32E0Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit32E0Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit32E0Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit32E0Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit32E0Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit32E0CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit32E0CalculatorSampleRunner.cs new file mode 100644 index 000000000..0846fb012 --- /dev/null +++ b/Hast.Samples.Posit/Posit32E0CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit32E0CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit32E0Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 100000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit32E0Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E0Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit32E0Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E0Array[i] = new Posit32E0((float)0.25 * 2 * i).PositBits; + else Posit32E0Array[i] = new Posit32E0((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit32E0Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit32E0Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 100000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit32E0Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E0Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit32E0Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E0Array[i] = new Posit32E0((float)0.25 * 2 * i).PositBits; + else Posit32E0Array[i] = new Posit32E0((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit32E0Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit32E0Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit32E1Calculator.cs b/Hast.Samples.Posit/Posit32E1Calculator.cs new file mode 100644 index 000000000..29845812e --- /dev/null +++ b/Hast.Samples.Posit/Posit32E1Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit32E1Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit32E1((uint)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (uint)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit32E1(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit32E1(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit32E1((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit32E1((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit32E1CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit32E1Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit32E1Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit32E1Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit32E1Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit32E1Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit32E1Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit32E1(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit32E1((uint)memory.ReadUInt32( Posit32E1Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit32E1Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit32E1Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit32E1Calculator is (" + + Posit32E1Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit32E1Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit32E1Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit32E1Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit32E1Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit32E1Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit32E1Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit32E1Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit32E1Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit32E1Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit32E1CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit32E1CalculatorSampleRunner.cs new file mode 100644 index 000000000..7442fe11e --- /dev/null +++ b/Hast.Samples.Posit/Posit32E1CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit32E1CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit32E1Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 100000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit32E1Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E1Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit32E1Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E1Array[i] = new Posit32E1((float)0.25 * 2 * i).PositBits; + else Posit32E1Array[i] = new Posit32E1((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit32E1Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit32E1Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 100000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit32E1Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E1Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit32E1Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E1Array[i] = new Posit32E1((float)0.25 * 2 * i).PositBits; + else Posit32E1Array[i] = new Posit32E1((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit32E1Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit32E1Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit32E2Calculator.cs b/Hast.Samples.Posit/Posit32E2Calculator.cs new file mode 100644 index 000000000..a6c334d66 --- /dev/null +++ b/Hast.Samples.Posit/Posit32E2Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit32E2Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit32E2((uint)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (uint)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit32E2(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit32E2(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit32E2((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit32E2((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit32E2CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit32E2Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit32E2Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit32E2Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit32E2Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit32E2Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit32E2Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit32E2(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit32E2((uint)memory.ReadUInt32( Posit32E2Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit32E2Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit32E2Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit32E2Calculator is (" + + Posit32E2Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit32E2Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit32E2Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit32E2Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit32E2Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit32E2Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit32E2Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit32E2Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit32E2Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit32E2Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit32E2CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit32E2CalculatorSampleRunner.cs new file mode 100644 index 000000000..27131ecea --- /dev/null +++ b/Hast.Samples.Posit/Posit32E2CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit32E2CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit32E2Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 100000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit32E2Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E2Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit32E2Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E2Array[i] = new Posit32E2((float)0.25 * 2 * i).PositBits; + else Posit32E2Array[i] = new Posit32E2((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit32E2Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit32E2Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 100000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit32E2Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E2Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit32E2Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E2Array[i] = new Posit32E2((float)0.25 * 2 * i).PositBits; + else Posit32E2Array[i] = new Posit32E2((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit32E2Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit32E2Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit32E3Calculator.cs b/Hast.Samples.Posit/Posit32E3Calculator.cs new file mode 100644 index 000000000..33d2b0e83 --- /dev/null +++ b/Hast.Samples.Posit/Posit32E3Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit32E3Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit32E3((uint)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (uint)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit32E3(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit32E3(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit32E3((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit32E3((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit32E3CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit32E3Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit32E3Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit32E3Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit32E3Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit32E3Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit32E3Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit32E3(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit32E3((uint)memory.ReadUInt32( Posit32E3Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit32E3Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit32E3Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit32E3Calculator is (" + + Posit32E3Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit32E3Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit32E3Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit32E3Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit32E3Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit32E3Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit32E3Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit32E3Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit32E3Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit32E3Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit32E3CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit32E3CalculatorSampleRunner.cs new file mode 100644 index 000000000..23429354c --- /dev/null +++ b/Hast.Samples.Posit/Posit32E3CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit32E3CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit32E3Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 100000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit32E3Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E3Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit32E3Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E3Array[i] = new Posit32E3((float)0.25 * 2 * i).PositBits; + else Posit32E3Array[i] = new Posit32E3((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit32E3Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit32E3Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 100000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit32E3Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E3Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit32E3Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E3Array[i] = new Posit32E3((float)0.25 * 2 * i).PositBits; + else Posit32E3Array[i] = new Posit32E3((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit32E3Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit32E3Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit32E4Calculator.cs b/Hast.Samples.Posit/Posit32E4Calculator.cs new file mode 100644 index 000000000..4c732daab --- /dev/null +++ b/Hast.Samples.Posit/Posit32E4Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit32E4Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit32E4((uint)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (uint)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit32E4(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit32E4(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit32E4((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit32E4((uint)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit32E4CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit32E4Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit32E4Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit32E4Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit32E4Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit32E4Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit32E4Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit32E4(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit32E4((uint)memory.ReadUInt32( Posit32E4Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit32E4Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit32E4Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit32E4Calculator is (" + + Posit32E4Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit32E4Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit32E4Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit32E4Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit32E4Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit32E4Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit32E4Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit32E4Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit32E4Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit32E4Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit32E4CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit32E4CalculatorSampleRunner.cs new file mode 100644 index 000000000..14fb28e7b --- /dev/null +++ b/Hast.Samples.Posit/Posit32E4CalculatorSampleRunner.cs @@ -0,0 +1,123 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit32E4CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit32E4Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 100000, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + var numbers = new int[Posit32E4Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E4Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit32E4Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E4Array[i] = new Posit32E4((float)0.25 * 2 * i).PositBits; + else Posit32E4Array[i] = new Posit32E4((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit32E4Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit32E4Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + var powerOfReal = positCalculator.CalculatePowerOfReal( + 100000, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit32E4Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit32E4Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit32E4Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit32E4Array[i] = new Posit32E4((float)0.25 * 2 * i).PositBits; + else Posit32E4Array[i] = new Posit32E4((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit32E4Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit32E4Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit8E0Calculator.cs b/Hast.Samples.Posit/Posit8E0Calculator.cs new file mode 100644 index 000000000..077a3d0e6 --- /dev/null +++ b/Hast.Samples.Posit/Posit8E0Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit8E0Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit8E0((byte)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (byte)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit8E0(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit8E0(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit8E0((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit8E0((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit8E0CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit8E0Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit8E0Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit8E0Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit8E0Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit8E0Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit8E0Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit8E0(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit8E0((byte)memory.ReadUInt32( Posit8E0Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit8E0Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit8E0Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit8E0Calculator is (" + + Posit8E0Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit8E0Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit8E0Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit8E0Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit8E0Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit8E0Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit8E0Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit8E0Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit8E0Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit8E0Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit8E0CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit8E0CalculatorSampleRunner.cs new file mode 100644 index 000000000..f075a2fdf --- /dev/null +++ b/Hast.Samples.Posit/Posit8E0CalculatorSampleRunner.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit8E0CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit8E0Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 5, (float)0.5); + + + var numbers = new int[Posit8E0Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E0Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit8E0Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E0Array[i] = new Posit8E0((float)0.25 * 2 * i).PositBits; + else Posit8E0Array[i] = new Posit8E0((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit8E0Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit8E0Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + + var powerOfReal = positCalculator.CalculatePowerOfReal( 5, (float)0.5, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration ); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit8E0Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E0Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit8E0Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E0Array[i] = new Posit8E0((float)0.25 * 2 * i).PositBits; + else Posit8E0Array[i] = new Posit8E0((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit8E0Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit8E0Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit8E1Calculator.cs b/Hast.Samples.Posit/Posit8E1Calculator.cs new file mode 100644 index 000000000..481acb27a --- /dev/null +++ b/Hast.Samples.Posit/Posit8E1Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit8E1Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit8E1((byte)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (byte)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit8E1(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit8E1(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit8E1((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit8E1((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit8E1CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit8E1Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit8E1Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit8E1Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit8E1Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit8E1Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit8E1Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit8E1(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit8E1((byte)memory.ReadUInt32( Posit8E1Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit8E1Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit8E1Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit8E1Calculator is (" + + Posit8E1Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit8E1Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit8E1Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit8E1Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit8E1Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit8E1Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit8E1Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit8E1Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit8E1Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit8E1Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit8E1CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit8E1CalculatorSampleRunner.cs new file mode 100644 index 000000000..12da1942e --- /dev/null +++ b/Hast.Samples.Posit/Posit8E1CalculatorSampleRunner.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit8E1CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit8E1Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 5, (float)0.5); + + + var numbers = new int[Posit8E1Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E1Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit8E1Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E1Array[i] = new Posit8E1((float)0.25 * 2 * i).PositBits; + else Posit8E1Array[i] = new Posit8E1((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit8E1Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit8E1Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + + var powerOfReal = positCalculator.CalculatePowerOfReal( 5, (float)0.5, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration ); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit8E1Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E1Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit8E1Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E1Array[i] = new Posit8E1((float)0.25 * 2 * i).PositBits; + else Posit8E1Array[i] = new Posit8E1((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit8E1Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit8E1Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit8E2Calculator.cs b/Hast.Samples.Posit/Posit8E2Calculator.cs new file mode 100644 index 000000000..dbbd438d4 --- /dev/null +++ b/Hast.Samples.Posit/Posit8E2Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit8E2Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit8E2((byte)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (byte)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit8E2(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit8E2(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit8E2((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit8E2((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit8E2CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit8E2Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit8E2Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit8E2Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit8E2Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit8E2Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit8E2Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit8E2(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit8E2((byte)memory.ReadUInt32( Posit8E2Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit8E2Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit8E2Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit8E2Calculator is (" + + Posit8E2Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit8E2Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit8E2Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit8E2Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit8E2Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit8E2Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit8E2Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit8E2Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit8E2Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit8E2Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit8E2CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit8E2CalculatorSampleRunner.cs new file mode 100644 index 000000000..fb00ff80a --- /dev/null +++ b/Hast.Samples.Posit/Posit8E2CalculatorSampleRunner.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit8E2CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit8E2Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 5, (float)0.5); + + + var numbers = new int[Posit8E2Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E2Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit8E2Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E2Array[i] = new Posit8E2((float)0.25 * 2 * i).PositBits; + else Posit8E2Array[i] = new Posit8E2((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit8E2Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit8E2Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + + var powerOfReal = positCalculator.CalculatePowerOfReal( 5, (float)0.5, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration ); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit8E2Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E2Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit8E2Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E2Array[i] = new Posit8E2((float)0.25 * 2 * i).PositBits; + else Posit8E2Array[i] = new Posit8E2((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit8E2Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit8E2Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit8E3Calculator.cs b/Hast.Samples.Posit/Posit8E3Calculator.cs new file mode 100644 index 000000000..c76aceede --- /dev/null +++ b/Hast.Samples.Posit/Posit8E3Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit8E3Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit8E3((byte)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (byte)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit8E3(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit8E3(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit8E3((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit8E3((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit8E3CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit8E3Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit8E3Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit8E3Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit8E3Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit8E3Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit8E3Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit8E3(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit8E3((byte)memory.ReadUInt32( Posit8E3Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit8E3Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit8E3Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit8E3Calculator is (" + + Posit8E3Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit8E3Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit8E3Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit8E3Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit8E3Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit8E3Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit8E3Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit8E3Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit8E3Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit8E3Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit8E3CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit8E3CalculatorSampleRunner.cs new file mode 100644 index 000000000..3237db1f7 --- /dev/null +++ b/Hast.Samples.Posit/Posit8E3CalculatorSampleRunner.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit8E3CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit8E3Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 5, (float)0.5); + + + var numbers = new int[Posit8E3Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E3Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit8E3Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E3Array[i] = new Posit8E3((float)0.25 * 2 * i).PositBits; + else Posit8E3Array[i] = new Posit8E3((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit8E3Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit8E3Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + + var powerOfReal = positCalculator.CalculatePowerOfReal( 5, (float)0.5, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration ); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit8E3Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E3Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit8E3Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E3Array[i] = new Posit8E3((float)0.25 * 2 * i).PositBits; + else Posit8E3Array[i] = new Posit8E3((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit8E3Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit8E3Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/Posit8E4Calculator.cs b/Hast.Samples.Posit/Posit8E4Calculator.cs new file mode 100644 index 000000000..83357a167 --- /dev/null +++ b/Hast.Samples.Posit/Posit8E4Calculator.cs @@ -0,0 +1,203 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class Posit8E4Calculator + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new Posit8E4((byte)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (byte)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new Posit8E4(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new Posit8E4(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new Posit8E4((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new Posit8E4((byte)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class Posit8E4CalculatorCalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this Posit8E4Calculator positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( Posit8E4Calculator.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( Posit8E4Calculator.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this Posit8E4Calculator positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( Posit8E4Calculator.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( Posit8E4Calculator.CalculatePowerOfReal_InputPosit32Index, new Posit8E4(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new Posit8E4((byte)memory.ReadUInt32( Posit8E4Calculator.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this Posit8E4Calculator positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != Posit8E4Calculator.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of Posit8E4Calculator is (" + + Posit8E4Calculator.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(Posit8E4Calculator.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, Posit8E4Calculator.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( Posit8E4Calculator.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ Posit8E4Calculator.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( Posit8E4Calculator.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this Posit8E4Calculator positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( Posit8E4Calculator.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( Posit8E4Calculator.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( Posit8E4Calculator.AddPositsInArray_OutputPosit32Index), true); + } + } +} + diff --git a/Hast.Samples.Posit/Posit8E4CalculatorSampleRunner.cs b/Hast.Samples.Posit/Posit8E4CalculatorSampleRunner.cs new file mode 100644 index 000000000..a75548616 --- /dev/null +++ b/Hast.Samples.Posit/Posit8E4CalculatorSampleRunner.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class Posit8E4CalculatorSampleRunner + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new Posit8E4Calculator()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + positCalculator.CalculatePowerOfReal( 5, (float)0.5); + + + var numbers = new int[Posit8E4Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E4Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var Posit8E4Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E4Array[i] = new Posit8E4((float)0.25 * 2 * i).PositBits; + else Posit8E4Array[i] = new Posit8E4((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(Posit8E4Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new Posit8E4Calculator(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + + var powerOfReal = positCalculator.CalculatePowerOfReal( 5, (float)0.5, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration ); + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[Posit8E4Calculator.MaxDegreeOfParallelism]; + for (int i = 0; i < Posit8E4Calculator.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var Posit8E4Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) Posit8E4Array[i] = new Posit8E4((float)0.25 * 2 * i).PositBits; + else Posit8E4Array[i] = new Posit8E4((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( Posit8E4Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( Posit8E4Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + diff --git a/Hast.Samples.Posit/PositCalculator.cs b/Hast.Samples.Posit/PositCalculator.cs new file mode 100644 index 000000000..a9674679a --- /dev/null +++ b/Hast.Samples.Posit/PositCalculator.cs @@ -0,0 +1,21 @@ + + + + +// Generated helper templates +// Generated items +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E4Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E3Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E2Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E1Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E0Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E4Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E3Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E2Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E1Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E0Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E4Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E3Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E2Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E1Calculator.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E0Calculator.cs diff --git a/Hast.Samples.Posit/PositCalculator.tt b/Hast.Samples.Posit/PositCalculator.tt new file mode 100644 index 000000000..a6b0ae695 --- /dev/null +++ b/Hast.Samples.Posit/PositCalculator.tt @@ -0,0 +1,237 @@ +<#@ template debug="true" hostSpecific="true" #> +<#@ output extension=".cs" #> +<#@ include file="PositCalculatorTemplateFileManager.ttinclude" #> + + +<# + +var manager = TemplateFileManager.Create(this); + +#> + +<# + var positSizes = new byte[] {8,16,32,64}; + var underLyingStructureName= new string[] {"byte", "ushort","uint","ulong","BitMask"}; + +for (var i = 0; i<3; i++){ + for(var MaximumExponentSize = 0; MaximumExponentSize <= 4; MaximumExponentSize++){ + var positName = $"Posit{positSizes[i]}E{MaximumExponentSize}"; + var className = $"{positName}Calculator"; + var quireSize = 1; + while (quireSize < (4*positSizes[i]-8)*(1< +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Transformer.Abstractions.SimpleMemory; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + + public class <#= className#> + { + public const int CalculateLargeIntegerSum_InputInt32Index = 0; + public const int CalculateLargeIntegerSum_OutputInt32Index = 0; + public const int ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex = 0; + public const int ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex = 0; + public const int AddPositsInArray_InputPosit32CountIndex = 0; + public const int AddPositsInArray_InputPosit32sStartIndex = 1; + public const int AddPositsInArray_OutputPosit32Index = 2; + public const int CalculatePowerOfReal_InputInt32Index = 0; + public const int CalculatePowerOfReal_InputPosit32Index = 1; + public const int CalculatePowerOfReal_OutputPosit32Index = 0; + + public const int MaxDegreeOfParallelism = 5; + + + public virtual void CalculateIntegerSumUpToNumber(SimpleMemory memory) + { + var number = memory.ReadUInt32(CalculateLargeIntegerSum_InputInt32Index); + + var a = new <#=positName#>((<#= underLyingStructureName[i]#>)1); + var b = a; + + for (uint i = 1; i < number; i++) + { + a += b; + } + + var result = (int)a; + memory.WriteInt32(CalculateLargeIntegerSum_OutputInt32Index, result); + } + + public virtual void CalculatePowerOfReal(SimpleMemory memory) + { + var number = memory.ReadInt32(CalculatePowerOfReal_InputInt32Index); + var positToMultiply = (<#= underLyingStructureName[i]#>)memory.ReadUInt32(CalculatePowerOfReal_InputPosit32Index); + + var a = new <#=positName#>(positToMultiply, true); + var b = a; + + for (uint i = 0; i < number; i++) + { + a *= b; + } + + var result = a.PositBits; + memory.WriteUInt32(CalculatePowerOfReal_OutputPosit32Index, result); + } + + public virtual void ParallelizedCalculateIntegerSumUpToNumbers(SimpleMemory memory) + { + var numbers = new int[MaxDegreeOfParallelism]; + + var tasks = new Task[MaxDegreeOfParallelism]; + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + var upToNumber = memory.ReadInt32(ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i); + + tasks[i] = Task.Factory.StartNew( + upToNumberObject => + { + var a = new <#=positName#>(1); + var b = a; + + for (int j = 1; j < (int)upToNumberObject; j++) + { + a += b; + } + + return (int)a; + }, upToNumber); + } + + Task.WhenAll(tasks).Wait(); + + for (int i = 0; i < MaxDegreeOfParallelism; i++) + { + memory.WriteInt32(ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i, tasks[i].Result); + } + } + + public virtual void AddPositsInArray(SimpleMemory memory) + { + uint numberCount = memory.ReadUInt32(AddPositsInArray_InputPosit32CountIndex); + + var result = new <#=positName#>((<#= underLyingStructureName[i]#>)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex), true); + + for (int i = 1; i < numberCount; i++) + { + result += new <#=positName#>((<#= underLyingStructureName[i]#>)memory.ReadUInt32(AddPositsInArray_InputPosit32sStartIndex + i), true); + } + + memory.WriteUInt32(AddPositsInArray_OutputPosit32Index, result.PositBits); + } + } + + + public static class <#=className#>CalculatorExtensions + { + public static int CalculateIntegerSumUpToNumber( + this <#= className#> positCalculator, + int number, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(1) + : hastlayer.CreateMemory(configuration, 1); + + memory.WriteInt32( <#= className#>.CalculateLargeIntegerSum_InputInt32Index, number); + positCalculator.CalculateIntegerSumUpToNumber(memory); + + return memory.ReadInt32( <#= className#>.CalculateLargeIntegerSum_OutputInt32Index); + } + + public static float CalculatePowerOfReal( + this <#= className#> positCalculator, + int number, + float real, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(2) + : hastlayer.CreateMemory(configuration, 2); + + memory.WriteInt32( <#= className#>.CalculatePowerOfReal_InputInt32Index, number); + memory.WriteUInt32( <#= className#>.CalculatePowerOfReal_InputPosit32Index, new <#=positName#>(real).PositBits); + + positCalculator.CalculatePowerOfReal(memory); + + return (float)new <#=positName#>((<#= underLyingStructureName[i]#>)memory.ReadUInt32( <#= className#>.CalculatePowerOfReal_OutputPosit32Index), true); + } + + public static IEnumerable ParallelizedCalculateIntegerSumUpToNumbers( + this <#= className#> positCalculator, + int[] numbers, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + if (numbers.Length != <#= className#>.MaxDegreeOfParallelism) + { + throw new ArgumentException( + "Provide as many numbers as the degree of parallelism of <#= className#> is (" + + <#= className#>.MaxDegreeOfParallelism + ")"); + } + + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(<#= className#>.MaxDegreeOfParallelism) + : hastlayer.CreateMemory(configuration, <#= className#>.MaxDegreeOfParallelism); + + for (int i = 0; i < numbers.Length; i++) + { + memory.WriteInt32( <#= className#>.ParallelizedCalculateLargeIntegerSum_Int32NumbersStartIndex + i, numbers[i]); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(memory); + + var results = new int[ <#= className#>.MaxDegreeOfParallelism]; + + for (int i = 0; i < numbers.Length; i++) + { + results[i] = memory.ReadInt32( <#= className#>.ParallelizedCalculateLargeIntegerSum_OutputInt32sStartIndex + i); + } + + return results; + } + + public static float AddPositsInArray( + this <#= className#> positCalculator, + uint[] positArray, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) + { + var memory = hastlayer is null + ? SimpleMemory.CreateSoftwareMemory(positArray.Length + 1) + : hastlayer.CreateMemory(configuration, positArray.Length + 1); + + memory.WriteUInt32( <#= className#>.AddPositsInArray_InputPosit32CountIndex, (uint) positArray.Length); + + for (var i = 0; i < positArray.Length; i++) + { + memory.WriteUInt32( <#= className#>.AddPositsInArray_InputPosit32sStartIndex + i, positArray[i]); + } + + positCalculator.AddPositsInArray(memory); + + return (float)new Posit32(memory.ReadUInt32( <#= className#>.AddPositsInArray_OutputPosit32Index), true); + } + } +} + +<# + } +}#> +<# + +manager.Process(); + +#> diff --git a/Hast.Samples.Posit/PositCalculatorSampleRunner.cs b/Hast.Samples.Posit/PositCalculatorSampleRunner.cs new file mode 100644 index 000000000..e32099d2f --- /dev/null +++ b/Hast.Samples.Posit/PositCalculatorSampleRunner.cs @@ -0,0 +1,21 @@ + + + + +// Generated helper templates +// Generated items +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E4CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E3CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E2CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E1CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit32E0CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E4CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E3CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E2CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E1CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit16E0CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E4CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E3CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E2CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E1CalculatorSampleRunner.cs +// D:\DEV\Hastlayer\Hastlayer-SDK\Hast.Samples.Posit\Posit8E0CalculatorSampleRunner.cs diff --git a/Hast.Samples.Posit/PositCalculatorSampleRunner.tt b/Hast.Samples.Posit/PositCalculatorSampleRunner.tt new file mode 100644 index 000000000..cd41b32f1 --- /dev/null +++ b/Hast.Samples.Posit/PositCalculatorSampleRunner.tt @@ -0,0 +1,183 @@ +<#@ template debug="true" hostSpecific="true" #> +<#@ output extension=".cs" #> +<#@ include file="PositCalculatorTemplateFileManager.ttinclude" #> + + +<# + +var manager = TemplateFileManager.Create(this); + +#> + +<# + var positSizes = new byte[] {8,16,32,64}; + var underLyingStructureName= new string[] {"byte", "ushort","uint","ulong","BitMask"}; + +for (var i = 0; i<3; i++){ + for(var MaximumExponentSize = 0; MaximumExponentSize <=4; MaximumExponentSize++){ + var positName = $"Posit{positSizes[i]}E{MaximumExponentSize}"; + var calculatorName = $"{positName}Calculator"; + var className = $"{calculatorName}SampleRunner"; + var quireSize = 1; + while (quireSize < (4*positSizes[i]-8)*(1<=0 ;n--) + { + maxScaleFactor = Math.Pow((1 << (1 << MaximumExponentSize)), positSizes[i]-2-MaximumExponentSize-n) + (1<= pIntMax) break; + } + manager.StartNewFile(className + ".cs"); +#> +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Hast.Layer; +using Hast.Samples.SampleAssembly; +using Lombiq.Arithmetics; + +namespace Hast.Samples.Posit +{ + internal class <#=className#> + { + public static void Configure(HardwareGenerationConfiguration configuration) + { + configuration.AddHardwareEntryPointType<<#=calculatorName#>>(); + } + + public static async Task Run(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + RunSoftwareBenchmarks(hastlayer, hardwareRepresentation); + + var positCalculator = await hastlayer.GenerateProxyAsync(hardwareRepresentation, new <#=calculatorName#>()); + + + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber(100000, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + <# if (i == 0) + { + #> + positCalculator.CalculatePowerOfReal( 5, (float)0.5); + + <# } else { #> + positCalculator.CalculatePowerOfReal( <#=(int) Math.Pow(10,Math.Log(positSizes[i], 2)) #>, (float)1.015625, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + <# } #> + + var numbers = new int[<#=calculatorName#>.MaxDegreeOfParallelism]; + for (int i = 0; i < <#=calculatorName#>.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + + + var <#=positName#>Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) <#=positName#>Array[i] = new <#=positName#>((float)0.25 * 2 * i).PositBits; + else <#=positName#>Array[i] = new <#=positName#>((float)0.25 * -2 * i).PositBits; + } + + var positsInArraySum = positCalculator.AddPositsInArray(<#=positName#>Array); + } + + public static void RunSoftwareBenchmarks(IHastlayer hastlayer, IHardwareRepresentation hardwareRepresentation) + { + var positCalculator = new <#=calculatorName#>(); + + + // Not to run the benchmark below the first time, because JIT compiling can affect it. + positCalculator.CalculateIntegerSumUpToNumber(100000); + var sw = Stopwatch.StartNew(); + var integerSumUpToNumber = positCalculator.CalculateIntegerSumUpToNumber( + 100000, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to 100000: " + integerSumUpToNumber); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + positCalculator.CalculatePowerOfReal(100000, (float)1.0001, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + + <# if (i == 0) + { + #> + + var powerOfReal = positCalculator.CalculatePowerOfReal( 5, (float)0.5, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration ); + <# } else { #> + var powerOfReal = positCalculator.CalculatePowerOfReal( + <#=(int) Math.Pow(10,Math.Log(positSizes[i], 2)) #>, + (float)1.015625, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + <# } #> + + sw.Stop(); + + Console.WriteLine("Result of power of real number: " + powerOfReal); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var numbers = new int[<#=calculatorName#>.MaxDegreeOfParallelism]; + for (int i = 0; i < <#=calculatorName#>.MaxDegreeOfParallelism; i++) + { + numbers[i] = 100000 + (i % 2 == 0 ? -1 : 1); + } + + positCalculator.ParallelizedCalculateIntegerSumUpToNumbers(numbers,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var integerSumsUpToNumbers = positCalculator.ParallelizedCalculateIntegerSumUpToNumbers( + numbers, + hastlayer, + hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of counting up to ~100000 parallelized: " + string.Join(", ", integerSumsUpToNumbers)); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + + Console.WriteLine(); + + var <#=positName#>Array = new uint[100000]; + + for (var i = 0; i < 100000; i++) + { + if (i % 2 == 0) <#=positName#>Array[i] = new <#=positName#>((float)0.25 * 2 * i).PositBits; + else <#=positName#>Array[i] = new <#=positName#>((float)0.25 * -2 * i).PositBits; + } + + positCalculator.AddPositsInArray( <#=positName#>Array,hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw = Stopwatch.StartNew(); + var positsInArraySum = positCalculator.AddPositsInArray( <#=positName#>Array, hastlayer, hardwareRepresentation.HardwareGenerationConfiguration); + sw.Stop(); + + Console.WriteLine("Result of addition of posits in array: " + positsInArraySum); + Console.WriteLine("Elapsed: " + sw.ElapsedMilliseconds + "ms"); + Console.WriteLine(); + }} +} + +<# + } +}#> +<# + +manager.Process(); + +#> diff --git a/Hast.Samples.Posit/PositCalculatorTemplateFileManager.ttinclude b/Hast.Samples.Posit/PositCalculatorTemplateFileManager.ttinclude new file mode 100644 index 000000000..6292508e8 --- /dev/null +++ b/Hast.Samples.Posit/PositCalculatorTemplateFileManager.ttinclude @@ -0,0 +1,1092 @@ +<#@ assembly name="System.Core" #> +<#@ assembly name="System.Data" #> +<#@ assembly name="System.Data.Entity" #> +<#@ assembly name="System.Xml" #> +<#@ assembly name="System.Xml.Linq" #> +<#@ assembly name="System.Windows.Forms" #> +<#@ assembly name="EnvDTE" #> +<#@ assembly name="EnvDTE80" #> +<#@ assembly name="Microsoft.VisualStudio.Shell.15.0" #> +<#@ assembly name="Microsoft.VisualStudio.Shell.Framework" #> +<#@ assembly name="Microsoft.VisualStudio.Shell.Interop" #> +<#@ assembly name="Microsoft.VisualStudio.Validation.dll" #> +<#@ import namespace="Microsoft.VisualStudio.Shell.Interop" #> +<#@ import namespace="System" #> +<#@ import namespace="System.Data" #> +<#@ import namespace="System.Data.Objects" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.IO" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ import namespace="System.Data.Objects.DataClasses" #> +<#@ import namespace="System.Text.RegularExpressions" #> +<#@ import namespace="System.Xml" #> +<#@ import namespace="System.Xml.Linq" #> +<#@ import namespace="System.Globalization" #> +<#@ import namespace="System.Reflection" #> +<#@ import namespace="System.CodeDom" #> +<#@ import namespace="System.CodeDom.Compiler" #> +<#@ import namespace="Microsoft.CSharp" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="EnvDTE" #> +<#@ import namespace="Microsoft.VisualStudio.TextTemplating" #> +<#+ +/* + This software is supplied "AS IS". The authors disclaim all warranties, + expressed or implied, including, without limitation, the warranties of + merchantability and of fitness for any purpose. The authors assume no + liability for direct, indirect, incidental, special, exemplary, or + consequential damages, which may result from the use of this software, + even if advised of the possibility of such damage. + +The TemplateFileManager is based on EntityFrameworkTemplateFileManager (EFTFM) from MS. + +Differences to EFTFM +Version 2.1: +- Replace Enum BuildAction with class for more flexibility +Version 2: +- StartHeader works with Parameter $filename$ +- StartNewFile has a new named parameter FileProperties + - Support for: + - BuildAction + - CustomTool + - user defined parameter for using in StartHeader-Block +- Property IsAutoIndentEnabled for support Format Document (C#, VB) when set to true + +Version: 1.1 +Add method WriteLineToBuildPane, WriteToBuildPane + +Version 1: +- StartNewFile with named parameters projectName and folderName for generating files to different locations. +- Property CanOverrideExistingFile, to define whether existing files are can overwritten +- Property Encoding Encode type for output files. +*/ + +/// +/// Writes a line to the build pane in visual studio and activates it +/// +/// Text to output - a \n is appended +void WriteLineToBuildPane (string message){ + WriteLineToBuildPane(String.Format("{0}\n", message)); +} + +/// +/// Writes a string to the build pane in visual studio and activates it +/// +/// Text to output +void WriteToBuildPane (string message){ + IVsOutputWindow outWindow = (this.Host as IServiceProvider).GetService( +typeof( SVsOutputWindow ) ) as IVsOutputWindow; + Guid generalPaneGuid = +Microsoft.VisualStudio.VSConstants.OutputWindowPaneGuid.BuildOutputPane_guid; + // P.S. There's also the GUID_OutWindowDebugPane available. + IVsOutputWindowPane generalPane; + outWindow.GetPane( ref generalPaneGuid , out generalPane ); + generalPane.OutputString( message ); + generalPane.Activate(); // Brings this pane into view +} + +/// +/// Responsible for marking the various sections of the generation, +/// so they can be split up into separate files and projects +/// +/// R. Leupold +public class TemplateFileManager +{ + private EnvDTE.ProjectItem templateProjectItem; + private Action checkOutAction; + private Action> projectSyncAction; + private EnvDTE.DTE dte; + private List templatePlaceholderList = new List(); + + /// + /// Creates files with VS sync + /// + public static TemplateFileManager Create(object textTransformation) + { + DynamicTextTransformation2 transformation = DynamicTextTransformation2.Create(textTransformation); + IDynamicHost2 host = transformation.Host; + return new TemplateFileManager(transformation); + } + + private readonly List files = new List(); + private readonly Block footer = new Block(); + private readonly Block header = new Block(); + private readonly DynamicTextTransformation2 _textTransformation; + + // reference to the GenerationEnvironment StringBuilder on the + // TextTransformation object + private readonly StringBuilder _generationEnvironment; + + private Block currentBlock; + + /// + /// Initializes an TemplateFileManager Instance with the + /// TextTransformation (T4 generated class) that is currently running + /// + private TemplateFileManager(object textTransformation) + { + if (textTransformation == null) + { + throw new ArgumentNullException("textTransformation"); + } + + _textTransformation = DynamicTextTransformation2.Create(textTransformation); + _generationEnvironment = _textTransformation.GenerationEnvironment; + + var hostServiceProvider = _textTransformation.Host.AsIServiceProvider(); + if (hostServiceProvider == null) + { + throw new ArgumentNullException("Could not obtain hostServiceProvider"); + } + + dte = (EnvDTE.DTE) hostServiceProvider.GetService(typeof(EnvDTE.DTE)); + if (dte == null) + { + throw new ArgumentNullException("Could not obtain DTE from host"); + } + + this.templateProjectItem = dte.Solution.FindProjectItem(_textTransformation.Host.TemplateFile); + this.CanOverrideExistingFile = true; + this.IsAutoIndentEnabled = false; + this.Encoding = System.Text.Encoding.UTF8; + checkOutAction = fileName => dte.SourceControl.CheckOutItem(fileName); + projectSyncAction = keepFileNames => ProjectSync(templateProjectItem, keepFileNames); + } + + /// + /// If set to false, existing files are not overwritten + /// + /// + public bool CanOverrideExistingFile { get; set; } + + /// + /// If set to true, output files (c#, vb) are formatted based on the vs settings. + /// + /// + public bool IsAutoIndentEnabled { get; set; } + + /// + /// Defines Encoding format for generated output file. (Default UTF8) + /// + /// + public System.Text.Encoding Encoding { get; set; } + + /// + /// Marks the end of the last file if there was one, and starts a new + /// and marks this point in generation as a new file. + /// + /// Filename + /// Name of the target project for the new file. + /// Name of the target folder for the new file. + /// File property settings in vs for the new File + public void StartNewFile(string name + , string projectName = "", string folderName = "", FileProperties fileProperties = null) + { + if (String.IsNullOrWhiteSpace(name) == true) + { + throw new ArgumentException("name"); + } + + CurrentBlock = new Block + { + Name = name, + ProjectName = projectName, + FolderName = folderName, + FileProperties = fileProperties ?? new FileProperties() + }; + } + + public void StartFooter() + { + CurrentBlock = footer; + } + + public void StartHeader() + { + CurrentBlock = header; + } + + public void EndBlock() + { + if (CurrentBlock == null) + { + return; + } + + CurrentBlock.Length = _generationEnvironment.Length - CurrentBlock.Start; + + if (CurrentBlock != header && CurrentBlock != footer) + { + files.Add(CurrentBlock); + } + + currentBlock = null; + } + + /// + /// Produce the template output files. + /// + public virtual IEnumerable Process(bool split = true) + { + var list = new List(); + + if (split) + { + EndBlock(); + + var headerText = _generationEnvironment.ToString(header.Start, header.Length); + var footerText = _generationEnvironment.ToString(footer.Start, footer.Length); + files.Reverse(); + + foreach (var block in files) + { + var outputPath = VSHelper.GetOutputPath(dte, block, Path.GetDirectoryName(_textTransformation.Host.TemplateFile)); + var fileName = Path.Combine(outputPath, block.Name); + var content = this.ReplaceParameter(headerText, block) + + _generationEnvironment.ToString(block.Start, block.Length) + + footerText; + + var file = new OutputFile + { + FileName = fileName, + ProjectName = block.ProjectName, + FolderName = block.FolderName, + FileProperties = block.FileProperties, + Content = content + }; + + CreateFile(file); + _generationEnvironment.Remove(block.Start, block.Length); + + list.Add(file); + } + } + + projectSyncAction(list); + this.CleanUpTemplatePlaceholders(); + var items = VSHelper.GetOutputFilesAsProjectItems(this.dte, list); + this.WriteVsProperties(items, list); + + if (this.IsAutoIndentEnabled == true && split == true) + { + this.FormatProjectItems(items); + } + + this.WriteLog(list); + + return list; + } + + private void FormatProjectItems(IEnumerable items) + { + foreach (var item in items) + { + this._textTransformation.WriteLine( + VSHelper.ExecuteVsCommand(this.dte, item, "Edit.FormatDocument")); //, "Edit.RemoveAndSort")); + this._textTransformation.WriteLine("//-> " + item.Name); + } + } + + private void WriteVsProperties(IEnumerable items, IEnumerable outputFiles) + { + foreach (var file in outputFiles) + { + var item = items.Where(p => p.Name == Path.GetFileName(file.FileName)).FirstOrDefault(); + if (item == null) continue; + + if (String.IsNullOrEmpty(file.FileProperties.CustomTool) == false) + { + VSHelper.SetPropertyValue(item, "CustomTool", file.FileProperties.CustomTool); + } + + if (String.IsNullOrEmpty(file.FileProperties.BuildActionString) == false) + { + VSHelper.SetPropertyValue(item, "ItemType", file.FileProperties.BuildActionString); + } + } + } + + private string ReplaceParameter(string text, Block block) + { + if (String.IsNullOrEmpty(text) == false) + { + text = text.Replace("$filename$", block.Name); + } + + + foreach (var item in block.FileProperties.TemplateParameter.AsEnumerable()) + { + text = text.Replace(item.Key, item.Value); + } + + return text; + } + + /// + /// Write log to the default output file. + /// + /// + private void WriteLog(IEnumerable list) + { + this._textTransformation.WriteLine("// Generated helper templates"); + foreach (var item in templatePlaceholderList) + { + this._textTransformation.WriteLine("// " + this.GetDirectorySolutionRelative(item)); + } + + this._textTransformation.WriteLine("// Generated items"); + foreach (var item in list) + { + this._textTransformation.WriteLine("// " + this.GetDirectorySolutionRelative(item.FileName)); + } + } + + /// + /// Removes old template placeholders from the solution. + /// + private void CleanUpTemplatePlaceholders() + { + string[] activeTemplateFullNames = this.templatePlaceholderList.ToArray(); + string[] allHelperTemplateFullNames = VSHelper.GetAllSolutionItems(this.dte) + .Where(p => p.Name == VSHelper.GetTemplatePlaceholderName(this.templateProjectItem)) + .Select(p => VSHelper.GetProjectItemFullPath(p)) + .ToArray(); + + var delta = allHelperTemplateFullNames.Except(activeTemplateFullNames).ToArray(); + + var dirtyHelperTemplates = VSHelper.GetAllSolutionItems(this.dte) + .Where(p => delta.Contains(VSHelper.GetProjectItemFullPath(p))); + + foreach (ProjectItem item in dirtyHelperTemplates) + { + if (item.ProjectItems != null) + { + foreach (ProjectItem subItem in item.ProjectItems) + { + subItem.Remove(); + } + } + + item.Remove(); + } + } + + /// + /// Gets a list of helper templates from the log. + /// + /// List of generated helper templates. + private string[] GetPreviousTemplatePlaceholdersFromLog() + { + string path = Path.GetDirectoryName(this._textTransformation.Host.ResolvePath(this._textTransformation.Host.TemplateFile)); + string file1 = Path.GetFileNameWithoutExtension(this._textTransformation.Host.TemplateFile) + ".txt"; + string contentPrevious = File.ReadAllText(Path.Combine(path, file1)); + + var result = contentPrevious + .Split(new[] { Environment.NewLine }, StringSplitOptions.RemoveEmptyEntries) + .Select(x => x.Split(new[] { "=>" }, StringSplitOptions.RemoveEmptyEntries).First()) + .Select(x => Regex.Replace(x, "//", String.Empty).Trim()) + .Where(x => x.EndsWith(VSHelper.GetTemplatePlaceholderName(this.templateProjectItem))) + .ToArray(); + + return result; + } + + private string GetDirectorySolutionRelative(string fullName) + { + int slnPos = fullName.IndexOf(Path.GetFileNameWithoutExtension(this.dte.Solution.FileName)); + if (slnPos < 0) + { + slnPos = 0; + } + + return fullName.Substring(slnPos); + } + + protected virtual void CreateFile(OutputFile file) + { + if (this.CanOverrideExistingFile == false && File.Exists(file.FileName) == true) + { + return; + } + + if (IsFileContentDifferent(file)) + { + CheckoutFileIfRequired(file.FileName); + File.WriteAllText(file.FileName, file.Content, this.Encoding); + } + } + + protected bool IsFileContentDifferent(OutputFile file) + { + return !(File.Exists(file.FileName) && File.ReadAllText(file.FileName) == file.Content); + } + + private Block CurrentBlock + { + get { return currentBlock; } + set + { + if (CurrentBlock != null) + { + EndBlock(); + } + + if (value != null) + { + value.Start = _generationEnvironment.Length; + } + + currentBlock = value; + } + } + + private void ProjectSync(EnvDTE.ProjectItem templateProjectItem, IEnumerable keepFileNames) + { + var groupedFileNames = from f in keepFileNames + group f by new { f.ProjectName, f.FolderName } + into l + select new { + ProjectName = l.Key.ProjectName, + FolderName = l.Key.FolderName, + FirstItem = l.First(), + OutputFiles = l + }; + + this.templatePlaceholderList.Clear(); + + foreach (var item in groupedFileNames) + { + EnvDTE.ProjectItem pi = VSHelper.GetTemplateProjectItem(templateProjectItem.DTE, item.FirstItem, templateProjectItem); + ProjectSyncPart(pi, item.OutputFiles); + + if (pi.Name.EndsWith("txt4")) + this.templatePlaceholderList.Add(VSHelper.GetProjectItemFullPath(pi)); + } + + // clean up + bool hasDefaultItems = groupedFileNames.Where(f => String.IsNullOrEmpty(f.ProjectName) && String.IsNullOrEmpty(f.FolderName)).Count() > 0; + if (hasDefaultItems == false) + { + ProjectSyncPart(templateProjectItem, new List()); + } + } + + private static void ProjectSyncPart(EnvDTE.ProjectItem templateProjectItem, IEnumerable keepFileNames) + { + var keepFileNameSet = new HashSet(keepFileNames); + var projectFiles = new Dictionary(); + var originalOutput = Path.GetFileNameWithoutExtension(templateProjectItem.FileNames[0]); + + foreach (EnvDTE.ProjectItem projectItem in templateProjectItem.ProjectItems) + { + projectFiles.Add(projectItem.FileNames[0], projectItem); + } + + // Remove unused items from the project + foreach (var pair in projectFiles) + { + bool isNotFound = keepFileNames.Where(f=>f.FileName == pair.Key).Count() == 0; + if (isNotFound == true + && !(Path.GetFileNameWithoutExtension(pair.Key) + ".").StartsWith(originalOutput + ".")) + { + pair.Value.Delete(); + } + } + + // Add missing files to the project + foreach (var fileName in keepFileNameSet) + { + if (!projectFiles.ContainsKey(fileName.FileName)) + { + templateProjectItem.ProjectItems.AddFromFile(fileName.FileName); + } + } + } + + private void CheckoutFileIfRequired(string fileName) + { + if (dte.SourceControl == null + || !dte.SourceControl.IsItemUnderSCC(fileName) + || dte.SourceControl.IsItemCheckedOut(fileName)) + { + return; + } + + // run on worker thread to prevent T4 calling back into VS + checkOutAction.EndInvoke(checkOutAction.BeginInvoke(fileName, null, null)); + } +} + +/// +/// Responsible creating an instance that can be passed +/// to helper classes that need to access the TextTransformation +/// members. It accesses member by name and signature rather than +/// by type. This is necessary when the +/// template is being used in Preprocessed mode +/// and there is no common known type that can be +/// passed instead +/// +public class DynamicTextTransformation2 +{ + private object _instance; + IDynamicHost2 _dynamicHost; + + private readonly MethodInfo _write; + private readonly MethodInfo _writeLine; + private readonly PropertyInfo _generationEnvironment; + private readonly PropertyInfo _errors; + private readonly PropertyInfo _host; + + /// + /// Creates an instance of the DynamicTextTransformation class around the passed in + /// TextTransformation shapped instance passed in, or if the passed in instance + /// already is a DynamicTextTransformation, it casts it and sends it back. + /// + public static DynamicTextTransformation2 Create(object instance) + { + if (instance == null) + { + throw new ArgumentNullException("instance"); + } + + DynamicTextTransformation2 textTransformation = instance as DynamicTextTransformation2; + if (textTransformation != null) + { + return textTransformation; + } + + return new DynamicTextTransformation2(instance); + } + + private DynamicTextTransformation2(object instance) + { + _instance = instance; + Type type = _instance.GetType(); + _write = type.GetMethod("Write", new Type[] { typeof(string) }); + _writeLine = type.GetMethod("WriteLine", new Type[] { typeof(string) }); + _generationEnvironment = type.GetProperty("GenerationEnvironment", BindingFlags.Instance | BindingFlags.NonPublic); + _host = type.GetProperty("Host"); + _errors = type.GetProperty("Errors"); + } + + /// + /// Gets the value of the wrapped TextTranformation instance's GenerationEnvironment property + /// + public StringBuilder GenerationEnvironment { get { return (StringBuilder)_generationEnvironment.GetValue(_instance, null); } } + + /// + /// Gets the value of the wrapped TextTranformation instance's Errors property + /// + public System.CodeDom.Compiler.CompilerErrorCollection Errors { get { return (System.CodeDom.Compiler.CompilerErrorCollection)_errors.GetValue(_instance, null); } } + + /// + /// Calls the wrapped TextTranformation instance's Write method. + /// + public void Write(string text) + { + _write.Invoke(_instance, new object[] { text }); + } + + /// + /// Calls the wrapped TextTranformation instance's WriteLine method. + /// + public void WriteLine(string text) + { + _writeLine.Invoke(_instance, new object[] { text }); + } + + /// + /// Gets the value of the wrapped TextTranformation instance's Host property + /// if available (shows up when hostspecific is set to true in the template directive) and returns + /// the appropriate implementation of IDynamicHost + /// + public IDynamicHost2 Host + { + get + { + if (_dynamicHost == null) + { + if(_host == null) + { + _dynamicHost = new NullHost2(); + } + else + { + _dynamicHost = new DynamicHost2(_host.GetValue(_instance, null)); + } + } + return _dynamicHost; + } + } +} + +/// +/// Reponsible for abstracting the use of Host between times +/// when it is available and not +/// +public interface IDynamicHost2 +{ + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// + string ResolveParameterValue(string id, string name, string otherName); + + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// + string ResolvePath(string path); + + /// + /// An abstracted call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// + string TemplateFile { get; } + + /// + /// Returns the Host instance cast as an IServiceProvider + /// + IServiceProvider AsIServiceProvider(); +} + +/// +/// Reponsible for implementing the IDynamicHost as a dynamic +/// shape wrapper over the Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost interface +/// rather than type dependent wrapper. We don't use the +/// interface type so that the code can be run in preprocessed mode +/// on a .net framework only installed machine. +/// +public class DynamicHost2 : IDynamicHost2 +{ + private readonly object _instance; + private readonly MethodInfo _resolveParameterValue; + private readonly MethodInfo _resolvePath; + private readonly PropertyInfo _templateFile; + + /// + /// Creates an instance of the DynamicHost class around the passed in + /// Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost shapped instance passed in. + /// + public DynamicHost2(object instance) + { + _instance = instance; + Type type = _instance.GetType(); + _resolveParameterValue = type.GetMethod("ResolveParameterValue", new Type[] { typeof(string), typeof(string), typeof(string) }); + _resolvePath = type.GetMethod("ResolvePath", new Type[] { typeof(string) }); + _templateFile = type.GetProperty("TemplateFile"); + + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// + public string ResolveParameterValue(string id, string name, string otherName) + { + return (string)_resolveParameterValue.Invoke(_instance, new object[] { id, name, otherName }); + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// + public string ResolvePath(string path) + { + return (string)_resolvePath.Invoke(_instance, new object[] { path }); + } + + /// + /// A call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// + public string TemplateFile + { + get + { + return (string)_templateFile.GetValue(_instance, null); + } + } + + /// + /// Returns the Host instance cast as an IServiceProvider + /// + public IServiceProvider AsIServiceProvider() + { + return _instance as IServiceProvider; + } +} + +/// +/// Reponsible for implementing the IDynamicHost when the +/// Host property is not available on the TextTemplating type. The Host +/// property only exists when the hostspecific attribute of the template +/// directive is set to true. +/// +public class NullHost2 : IDynamicHost2 +{ + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolveParameterValue + /// that simply retuns null. + /// + public string ResolveParameterValue(string id, string name, string otherName) + { + return null; + } + + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost ResolvePath + /// that simply retuns the path passed in. + /// + public string ResolvePath(string path) + { + return path; + } + + /// + /// An abstraction of the call to Microsoft.VisualStudio.TextTemplating.ITextTemplatingEngineHost TemplateFile + /// that returns null. + /// + public string TemplateFile + { + get + { + return null; + } + } + + /// + /// Returns null. + /// + public IServiceProvider AsIServiceProvider() + { + return null; + } +} + +public sealed class Block +{ + public String Name; + public int Start, Length; + public string ProjectName { get; set; } + public string FolderName { get; set; } + public FileProperties FileProperties { get; set; } +} + +public class ParamTextTemplate +{ + private ITextTemplatingEngineHost Host { get; set; } + + private ParamTextTemplate(ITextTemplatingEngineHost host) + { + this.Host = host; + } + + public static ParamTextTemplate Create(ITextTemplatingEngineHost host) + { + return new ParamTextTemplate(host); + } + + public static TextTemplatingSession GetSessionObject() + { + return new TextTemplatingSession(); + } + + public string TransformText(string templateName, TextTemplatingSession session) + { + return this.GetTemplateContent(templateName, session); + } + + public string GetTemplateContent(string templateName, TextTemplatingSession session) + { + string fullName = this.Host.ResolvePath(templateName); + string templateContent = File.ReadAllText(fullName); + + var sessionHost = this.Host as ITextTemplatingSessionHost; + sessionHost.Session = session; + + Engine engine = new Engine(); + return engine.ProcessTemplate(templateContent, this.Host); + } +} + +public class VSHelper +{ + /// + /// Execute Visual Studio commands against the project item. + /// + /// The current project item. + /// The vs command as string. + /// An error message if the command fails. + public static string ExecuteVsCommand(EnvDTE.DTE dte, EnvDTE.ProjectItem item, params string[] command) + { + if (item == null) + { + throw new ArgumentNullException("item"); + } + + string error = String.Empty; + + try + { + EnvDTE.Window window = item.Open(); + window.Activate(); + + foreach (var cmd in command) + { + if (String.IsNullOrWhiteSpace(cmd) == true) + { + continue; + } + + EnvDTE80.DTE2 dte2 = dte as EnvDTE80.DTE2; + dte2.ExecuteCommand(cmd, String.Empty); + } + + item.Save(); + window.Visible = false; + // window.Close(); // Ends VS, but not the tab :( + } + catch (Exception ex) + { + error = String.Format("Error processing file {0} {1}", item.Name, ex.Message); + } + + return error; + } + + /// + /// Sets a property value for the vs project item. + /// + public static void SetPropertyValue(EnvDTE.ProjectItem item, string propertyName, object value) + { + EnvDTE.Property property = item.Properties.Item(propertyName); + if (property == null) + { + throw new ArgumentException(String.Format("The property {0} was not found.", propertyName)); + } + else + { + property.Value = value; + } + } + + public static IEnumerable GetOutputFilesAsProjectItems(EnvDTE.DTE dte, IEnumerable outputFiles) + { + var fileNames = (from o in outputFiles + select Path.GetFileName(o.FileName)).ToArray(); + + return VSHelper.GetAllSolutionItems(dte).Where(f => fileNames.Contains(f.Name)); + } + + public static string GetOutputPath(EnvDTE.DTE dte, Block block, string defaultPath) + { + if (String.IsNullOrEmpty(block.ProjectName) == true && String.IsNullOrEmpty(block.FolderName) == true) + { + return defaultPath; + } + + EnvDTE.Project prj = null; + EnvDTE.ProjectItem item = null; + + if (String.IsNullOrEmpty(block.ProjectName) == false) + { + prj = GetProject(dte, block.ProjectName); + } + + if (String.IsNullOrEmpty(block.FolderName) == true && prj != null) + { + return Path.GetDirectoryName(prj.FullName); + } + else if (prj != null && String.IsNullOrEmpty(block.FolderName) == false) + { + item = GetAllProjectItemsRecursive(prj.ProjectItems).Where(i=>i.Name == block.FolderName).First(); + } + else if (String.IsNullOrEmpty(block.FolderName) == false) + { + item = GetAllProjectItemsRecursive( + dte.ActiveDocument.ProjectItem.ContainingProject.ProjectItems). + Where(i=>i.Name == block.FolderName).First(); + } + + if (item != null) + { + return GetProjectItemFullPath(item); + } + + return defaultPath; + } + public static string GetTemplatePlaceholderName(EnvDTE.ProjectItem item) + { + return String.Format("{0}.txt4", Path.GetFileNameWithoutExtension(item.Name)); + } + + public static EnvDTE.ProjectItem GetTemplateProjectItem(EnvDTE.DTE dte, OutputFile file, EnvDTE.ProjectItem defaultItem) + { + if (String.IsNullOrEmpty(file.ProjectName) == true && String.IsNullOrEmpty(file.FolderName) == true) + { + return defaultItem; + } + + string templatePlaceholder = GetTemplatePlaceholderName(defaultItem); + string itemPath = Path.GetDirectoryName(file.FileName); + string fullName = Path.Combine(itemPath, templatePlaceholder); + EnvDTE.Project prj = null; + EnvDTE.ProjectItem item = null; + + if (String.IsNullOrEmpty(file.ProjectName) == false) + { + prj = GetProject(dte, file.ProjectName); + } + + if (String.IsNullOrEmpty(file.FolderName) == true && prj != null) + { + return FindProjectItem(prj.ProjectItems, fullName, true); + } + else if (prj != null && String.IsNullOrEmpty(file.FolderName) == false) + { + item = GetAllProjectItemsRecursive(prj.ProjectItems).Where(i=>i.Name == file.FolderName).First(); + } + else if (String.IsNullOrEmpty(file.FolderName) == false) + { + item = GetAllProjectItemsRecursive( + dte.ActiveDocument.ProjectItem.ContainingProject.ProjectItems). + Where(i=>i.Name == file.FolderName).First(); + } + + if (item != null) + { + return FindProjectItem(item.ProjectItems, fullName, true); + } + + return defaultItem; + } + + private static EnvDTE.ProjectItem FindProjectItem(EnvDTE.ProjectItems items, string fullName, bool canCreateIfNotExists) + { + EnvDTE.ProjectItem item = (from i in items.Cast() + where i.Name == Path.GetFileName(fullName) + select i).FirstOrDefault(); + if (item == null) + { + File.CreateText(fullName); + item = items.AddFromFile(fullName); + } + + return item; + } + + public static EnvDTE.Project GetProject(EnvDTE.DTE dte, string projectName) + { + return GetAllProjects(dte).Where(p=>p.Name == projectName).First(); + } + + public static IEnumerable GetAllProjects(EnvDTE.DTE dte) + { + List projectList = new List(); + + var folders = dte.Solution.Projects.Cast().Where(p=>p.Kind == EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder); + + foreach (EnvDTE.Project folder in folders) + { + if (folder.ProjectItems == null) continue; + + foreach (EnvDTE.ProjectItem item in folder.ProjectItems) + { + if (item.Object is EnvDTE.Project) + projectList.Add(item.Object as EnvDTE.Project); + } + } + + var projects = dte.Solution.Projects.Cast().Where(p=>p.Kind != EnvDTE80.ProjectKinds.vsProjectKindSolutionFolder); + + if (projects.Count() > 0) + projectList.AddRange(projects); + + return projectList; + } + + public static EnvDTE.ProjectItem GetProjectItemWithName(EnvDTE.ProjectItems items, string itemName) + { + return GetAllProjectItemsRecursive(items).Cast().Where(i=>i.Name == itemName).First(); + } + + public static string GetProjectItemFullPath(EnvDTE.ProjectItem item) + { + return item.Properties.Item("FullPath").Value.ToString(); + } + + public static IEnumerable GetAllSolutionItems(EnvDTE.DTE dte) + { + List itemList = new List(); + + foreach (Project item in GetAllProjects(dte)) + { + if (item == null || item.ProjectItems == null) continue; + + itemList.AddRange(GetAllProjectItemsRecursive(item.ProjectItems)); + } + + return itemList; + } + + public static IEnumerable GetAllProjectItemsRecursive(EnvDTE.ProjectItems projectItems) + { + foreach (EnvDTE.ProjectItem projectItem in projectItems) + { + if (projectItem.ProjectItems == null) continue; + + foreach (EnvDTE.ProjectItem subItem in GetAllProjectItemsRecursive(projectItem.ProjectItems)) + { + yield return subItem; + } + + + yield return projectItem; + } + } +} + +public sealed class OutputFile +{ + public OutputFile() + { + this.FileProperties = new FileProperties + { + CustomTool = String.Empty, + BuildAction = BuildAction.None + }; + } + + public string FileName { get; set; } + public string ProjectName { get; set; } + public string FolderName { get; set; } + public string Content { get; set; } + public FileProperties FileProperties { get; set; } +} + +public class BuildAction +{ + public const string None = "None"; + public const string Compile = "Compile"; + public const string Content = "Content"; + public const string EmbeddedResource = "EmbeddedResource"; + public const string EntityDeploy = "EntityDeploy"; +} + +public sealed class FileProperties +{ + public FileProperties () + { + this.TemplateParameter = new Dictionary(); + } + + public string CustomTool { get; set; } + public string BuildAction { get; set; } + public Dictionary TemplateParameter { get; set; } + + internal string BuildActionString + { + get + { + return this.BuildAction; + } + } +} + + +#> diff --git a/Hast.Samples.Posit/Program.cs b/Hast.Samples.Posit/Program.cs new file mode 100644 index 000000000..ea02ae85b --- /dev/null +++ b/Hast.Samples.Posit/Program.cs @@ -0,0 +1,194 @@ +using Hast.Layer; +using Hast.Transformer.Vhdl.Abstractions.Configuration; +using Lombiq.Arithmetics; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Hast.Samples.Posit +{ + internal static class Configuration + { + public static string DeviceName = "Nexys A7"; + public static Sample SampleToRun = Sample.Posit32E0Calculator; + public static string HardwareFrameworkPath = "HardwareFramework"; + } + + internal class Program + { + private static void Main() + { + Task.Run(async () => + { + /* + * On a high level these are the steps to use Hastlayer: + * 1. Create the Hastlayer shell. + * 2. Configure hardware generation and generate FPGA hardware representation of the given .NET code. + * 3. Generate proxies for hardware-transformed types and use these proxies to utilize hardware + * implementations. (You can see this inside the SampleRunners.) + */ + + // Configuring the Hastlayer shell. Which flavor should we use? If you're unsure then you'll need + // the Client flavor: This will let you connect to a remote Hastlayer service to run the software + // to hardware transformation. + var hastlayerConfiguration = new HastlayerConfiguration { Flavor = HastlayerFlavor.Developer }; + + // Initializing a Hastlayer shell. Since this is non-trivial to do you can cache this shell object + // while the program runs and re-use it continuously. No need to always wrap it into a using() like + // here, just make sure to Dispose() it before the program terminates. + using var hastlayer = Hastlayer.Create(hastlayerConfiguration); + + // Hooking into an event of Hastlayer so some execution information can be made visible on the + // console. + hastlayer.ExecutedOnHardware += (sender, e) => + Console.WriteLine(@$"Executing {e.Arguments.MemberFullName} on hardware took +{e.Arguments.HardwareExecutionInformation.HardwareExecutionTimeMilliseconds} milliseconds (net) +{e.Arguments.HardwareExecutionInformation.FullExecutionTimeMilliseconds} milliseconds (all together)."); + + + // We need to set what kind of device (FPGA/FPGA board) to generate the hardware for. + var devices = hastlayer.GetSupportedDevices(); + // Let's just use the first one that is available. However you might want to use a specific + // device, not just any first one. + var configuration = new HardwareGenerationConfiguration( + Configuration.DeviceName, + Configuration.HardwareFrameworkPath); + + // If you're running Hastlayer in the Client flavor, you also need to configure some credentials + // here: + var remoteClientConfiguration = configuration.RemoteClientConfiguration(); + remoteClientConfiguration.AppName = "TestApp"; + remoteClientConfiguration.AppSecret = "appsecret"; + if (hastlayerConfiguration.Flavor == HastlayerFlavor.Client && + remoteClientConfiguration.AppSecret == "appsecret") + { + throw new InvalidOperationException("You haven't changed the default remote credentials!" + + " Write to crew@hastlayer.com to receive access if you don't have yet."); + } + + + // Letting the configuration of samples run. Check out those methods too! + switch (Configuration.SampleToRun) + { + case Sample.Posit8E0Calculator: + Posit8E0CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit8E1Calculator: + Posit8E1CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit8E2Calculator: + Posit8E2CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit8E3Calculator: + Posit8E3CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit16E0Calculator: + Posit16E0CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit16E1Calculator: + Posit16E1CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit16E2Calculator: + Posit16E2CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit16E3Calculator: + Posit16E3CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit32E0Calculator: + Posit32E0CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit32E1Calculator: + Posit32E1CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit32E2Calculator: + Posit32E2CalculatorSampleRunner.Configure(configuration); + break; + case Sample.Posit32E3Calculator: + Posit32E3CalculatorSampleRunner.Configure(configuration); + break; + default: + break; + } + + // The generated VHDL code will contain debug-level information, though it will be slower to + // create. + configuration.VhdlTransformerConfiguration().VhdlGenerationConfiguration = + VhdlGenerationConfiguration.Debug; + + Console.WriteLine("Hardware generation starts."); + + // Generating hardware from the sample assembly with the given configuration. + var hardwareRepresentation = await hastlayer.GenerateHardwareAsync( + new[] + { + typeof(Posit8E0).Assembly, + typeof(Posit8E0Calculator).Assembly, + }, + configuration); + + Console.WriteLine($"Hardware generation finished.{Environment.NewLine}"); + + // Be sure to check out transformation warnings. Most of the time the issues noticed shouldn't + // cause any problems, but sometimes they can. + if (hardwareRepresentation.HardwareDescription.Warnings.Any()) + { + Console.WriteLine( + "There were the following transformation warnings, which may hint on issues " + + $"that can cause the hardware implementation to produce incorrect results:{Environment.NewLine}" + + string.Join( + Environment.NewLine, + hardwareRepresentation.HardwareDescription.Warnings.Select(warning => $"* {warning}")) + + Environment.NewLine); + } + + Console.WriteLine("Starting hardware execution."); + + // Running samples. + switch (Configuration.SampleToRun) + { + case Sample.Posit8E0Calculator: + await Posit8E0CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit8E1Calculator: + await Posit8E1CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit8E2Calculator: + await Posit8E2CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit8E3Calculator: + await Posit8E3CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit16E0Calculator: + await Posit16E0CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit16E1Calculator: + await Posit16E1CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit16E2Calculator: + await Posit16E2CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit16E3Calculator: + await Posit16E3CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit32E0Calculator: + await Posit32E0CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit32E1Calculator: + await Posit32E1CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit32E2Calculator: + await Posit32E2CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + case Sample.Posit32E3Calculator: + await Posit32E3CalculatorSampleRunner.Run(hastlayer, hardwareRepresentation); + break; + default: + break; + } + }).Wait(); + + Console.WriteLine("Press any key to exit."); + Console.ReadKey(); + } + } +} diff --git a/Hast.Samples.Posit/Program.tt b/Hast.Samples.Posit/Program.tt new file mode 100644 index 000000000..15ff346b2 --- /dev/null +++ b/Hast.Samples.Posit/Program.tt @@ -0,0 +1,162 @@ +<#@ template debug="true" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + var positSizes = new byte[] { 8, 16, 32 }; + var calculatorTypes = new string[] { "Calculator" }; + var exponentSizes = Enumerable.Range(0, 4); +#> +using Hast.Layer; +using Hast.Transformer.Vhdl.Abstractions.Configuration; +using Lombiq.Arithmetics; +using System; +using System.Linq; +using System.Threading.Tasks; + +namespace Hast.Samples.Posit +{ + internal static class Configuration + { + public static string DeviceName = "Nexys A7"; + public static Sample SampleToRun = Sample.Posit32E0Calculator; + public static string HardwareFrameworkPath = "HardwareFramework"; + } + + internal class Program + { + private static void Main() + { + Task.Run(async () => + { + /* + * On a high level these are the steps to use Hastlayer: + * 1. Create the Hastlayer shell. + * 2. Configure hardware generation and generate FPGA hardware representation of the given .NET code. + * 3. Generate proxies for hardware-transformed types and use these proxies to utilize hardware + * implementations. (You can see this inside the SampleRunners.) + */ + + // Configuring the Hastlayer shell. Which flavor should we use? If you're unsure then you'll need + // the Client flavor: This will let you connect to a remote Hastlayer service to run the software + // to hardware transformation. + var hastlayerConfiguration = new HastlayerConfiguration { Flavor = HastlayerFlavor.Developer }; + + // Initializing a Hastlayer shell. Since this is non-trivial to do you can cache this shell object + // while the program runs and re-use it continuously. No need to always wrap it into a using() like + // here, just make sure to Dispose() it before the program terminates. + using var hastlayer = Hastlayer.Create(hastlayerConfiguration); + + // Hooking into an event of Hastlayer so some execution information can be made visible on the + // console. + hastlayer.ExecutedOnHardware += (sender, e) => + Console.WriteLine(@$"Executing {e.Arguments.MemberFullName} on hardware took +{e.Arguments.HardwareExecutionInformation.HardwareExecutionTimeMilliseconds} milliseconds (net) +{e.Arguments.HardwareExecutionInformation.FullExecutionTimeMilliseconds} milliseconds (all together)."); + + + // We need to set what kind of device (FPGA/FPGA board) to generate the hardware for. + var devices = hastlayer.GetSupportedDevices(); + // Let's just use the first one that is available. However you might want to use a specific + // device, not just any first one. + var configuration = new HardwareGenerationConfiguration( + Configuration.DeviceName, + Configuration.HardwareFrameworkPath); + + // If you're running Hastlayer in the Client flavor, you also need to configure some credentials + // here: + var remoteClientConfiguration = configuration.RemoteClientConfiguration(); + remoteClientConfiguration.AppName = "TestApp"; + remoteClientConfiguration.AppSecret = "appsecret"; + if (hastlayerConfiguration.Flavor == HastlayerFlavor.Client && + remoteClientConfiguration.AppSecret == "appsecret") + { + throw new InvalidOperationException("You haven't changed the default remote credentials!" + + " Write to crew@hastlayer.com to receive access if you don't have yet."); + } + + + // Letting the configuration of samples run. Check out those methods too! + switch (Configuration.SampleToRun) + { +<#foreach (var positSize in positSizes) +{ + foreach (var exponentSize in exponentSizes) + { + foreach (var calculatorType in calculatorTypes) + { + var positCalculatorName = $"Posit{positSize}E{exponentSize}{calculatorType}";#> + case Sample.<#=positCalculatorName#>: + <#=positCalculatorName#>SampleRunner.Configure(configuration); + break; +<# } + } +}#> + default: + break; + } + + // The generated VHDL code will contain debug-level information, though it will be slower to + // create. + configuration.VhdlTransformerConfiguration().VhdlGenerationConfiguration = + VhdlGenerationConfiguration.Debug; + + Console.WriteLine("Hardware generation starts."); + + // Generating hardware from the sample assembly with the given configuration. + var hardwareRepresentation = await hastlayer.GenerateHardwareAsync( + new[] + { + typeof(Posit8E0).Assembly, + typeof(Posit8E0Calculator).Assembly, + }, + configuration); + + Console.WriteLine($"Hardware generation finished.{Environment.NewLine}"); + + // Be sure to check out transformation warnings. Most of the time the issues noticed shouldn't + // cause any problems, but sometimes they can. + if (hardwareRepresentation.HardwareDescription.Warnings.Any()) + { + Console.WriteLine( + "There were the following transformation warnings, which may hint on issues " + + $"that can cause the hardware implementation to produce incorrect results:{Environment.NewLine}" + + string.Join( + Environment.NewLine, + hardwareRepresentation.HardwareDescription.Warnings.Select(warning => $"* {warning}")) + + Environment.NewLine); + } + + Console.WriteLine("Starting hardware execution."); + + // Running samples. + switch (Configuration.SampleToRun) + { +<#foreach (var positSize in positSizes) +{ + foreach (var exponentSize in exponentSizes) + { + foreach (var calculatorType in calculatorTypes) + { + var positCalculatorName = $"Posit{positSize}E{exponentSize}{calculatorType}";#> + case Sample.<#=positCalculatorName#>: + await <#=positCalculatorName#>SampleRunner.Run(hastlayer, hardwareRepresentation); + break; +<# } + } +}#> + default: + break; + } + }).Wait(); + + Console.WriteLine("Press any key to exit."); + Console.ReadKey(); + } + } +} +<# + +#> diff --git a/Hast.Samples.Posit/Properties/AssemblyInfo.cs b/Hast.Samples.Posit/Properties/AssemblyInfo.cs new file mode 100644 index 000000000..b31e8f7b9 --- /dev/null +++ b/Hast.Samples.Posit/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("Hast.Samples.Posit")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("Hast.Samples.Posit")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("d60c14f3-05fd-44bf-b109-7a3f4113cc46")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/Hast.Samples.Posit/Sample.cs b/Hast.Samples.Posit/Sample.cs new file mode 100644 index 000000000..be5a28874 --- /dev/null +++ b/Hast.Samples.Posit/Sample.cs @@ -0,0 +1,54 @@ +namespace Hast.Samples.Posit +{ + internal enum Sample + { + Posit8E0Calculator, + Posit8E0AdvancedCalculator, + Posit8E0FusedCalculator, + Posit8E1Calculator, + Posit8E1AdvancedCalculator, + Posit8E1FusedCalculator, + Posit8E2Calculator, + Posit8E2AdvancedCalculator, + Posit8E2FusedCalculator, + Posit8E3Calculator, + Posit8E3AdvancedCalculator, + Posit8E3FusedCalculator, + Posit16E0Calculator, + Posit16E0AdvancedCalculator, + Posit16E0FusedCalculator, + Posit16E1Calculator, + Posit16E1AdvancedCalculator, + Posit16E1FusedCalculator, + Posit16E2Calculator, + Posit16E2AdvancedCalculator, + Posit16E2FusedCalculator, + Posit16E3Calculator, + Posit16E3AdvancedCalculator, + Posit16E3FusedCalculator, + Posit32E0Calculator, + Posit32E0AdvancedCalculator, + Posit32E0FusedCalculator, + Posit32E1Calculator, + Posit32E1AdvancedCalculator, + Posit32E1FusedCalculator, + Posit32E2Calculator, + Posit32E2AdvancedCalculator, + Posit32E2FusedCalculator, + Posit32E3Calculator, + Posit32E3AdvancedCalculator, + Posit32E3FusedCalculator, + Posit64E0Calculator, + Posit64E0AdvancedCalculator, + Posit64E0FusedCalculator, + Posit64E1Calculator, + Posit64E1AdvancedCalculator, + Posit64E1FusedCalculator, + Posit64E2Calculator, + Posit64E2AdvancedCalculator, + Posit64E2FusedCalculator, + Posit64E3Calculator, + Posit64E3AdvancedCalculator, + Posit64E3FusedCalculator, + } +} diff --git a/Hast.Samples.Posit/Sample.tt b/Hast.Samples.Posit/Sample.tt new file mode 100644 index 000000000..4c259e2e2 --- /dev/null +++ b/Hast.Samples.Posit/Sample.tt @@ -0,0 +1,34 @@ +<#@ template debug="false" hostspecific="false" language="C#" #> +<#@ assembly name="System.Core" #> +<#@ import namespace="System.Linq" #> +<#@ import namespace="System.Text" #> +<#@ import namespace="System.Collections.Generic" #> +<#@ output extension=".cs" #> +<# + var positSizes = new byte[] { 8, 16, 32, 64 }; + var calculatorTypes = new string[] { "Calculator", "AdvancedCalculator", "FusedCalculator" }; + var exponentSizes = Enumerable.Range(0, 4); + + List calculatorNames = new List(); + + foreach (var positSize in positSizes) + { + foreach (var exponentSize in exponentSizes) + { + foreach (var calculatorType in calculatorTypes) + { + calculatorNames.Add($"Posit{positSize}E{exponentSize}{calculatorType}"); + } + } + } +#> +namespace Hast.Samples.Posit +{ + internal enum Sample + { + <# + foreach (var name in calculatorNames) + {#> + <#= name #>, + <#}#>} +} diff --git a/Hastlayer.SDK.sln b/Hastlayer.SDK.sln index 133758189..3084e7d94 100644 --- a/Hastlayer.SDK.sln +++ b/Hastlayer.SDK.sln @@ -130,6 +130,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hast.Vitis.Abstractions.Har EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lombiq.HelpfulLibraries.RestEase", "Libraries\Lombiq.HelpfulLibraries\Lombiq.HelpfulLibraries.RestEase\Lombiq.HelpfulLibraries.RestEase.csproj", "{4C53D384-FDED-4608-8C9A-616531CA4832}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Hast.Samples.Posit", "Hast.Samples.Posit\Hast.Samples.Posit.csproj", "{D60C14F3-05FD-44BF-B109-7A3F4113CC46}" +EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Libraries", "Libraries", "{75BB7270-46E1-47D9-91CA-2A7666251ED6}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Terminal.Gui", "Libraries\Terminal.Gui\Terminal.Gui\Terminal.Gui.csproj", "{48BFCAEE-D73D-4A21-A67E-52EA341D4276}" @@ -268,6 +270,10 @@ Global {EB781B61-C535-4A9B-A039-E28B56ACCB64}.Debug|Any CPU.Build.0 = Debug|Any CPU {EB781B61-C535-4A9B-A039-E28B56ACCB64}.Release|Any CPU.ActiveCfg = Release|Any CPU {EB781B61-C535-4A9B-A039-E28B56ACCB64}.Release|Any CPU.Build.0 = Release|Any CPU + {D60C14F3-05FD-44BF-B109-7A3F4113CC46}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {D60C14F3-05FD-44BF-B109-7A3F4113CC46}.Debug|Any CPU.Build.0 = Debug|Any CPU + {D60C14F3-05FD-44BF-B109-7A3F4113CC46}.Release|Any CPU.ActiveCfg = Release|Any CPU + {D60C14F3-05FD-44BF-B109-7A3F4113CC46}.Release|Any CPU.Build.0 = Release|Any CPU {2C30740A-0E66-476C-89B2-C89D86BFA70C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {2C30740A-0E66-476C-89B2-C89D86BFA70C}.Debug|Any CPU.Build.0 = Debug|Any CPU {2C30740A-0E66-476C-89B2-C89D86BFA70C}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -364,6 +370,7 @@ Global {0DD555F3-B472-422B-8CFB-63CB494CBB5A} = {765A6EB0-438E-422C-ACDD-13544EFE6467} {CBAC105A-E50F-4202-A647-CFD674E6C0F8} = {765A6EB0-438E-422C-ACDD-13544EFE6467} {E77C13E5-DA6A-4A9D-9601-B17BDBFE50BD} = {701D5B71-9A6F-47A4-A3C2-3714AF8B4115} + {D60C14F3-05FD-44BF-B109-7A3F4113CC46} = {765A6EB0-438E-422C-ACDD-13544EFE6467} {2C30740A-0E66-476C-89B2-C89D86BFA70C} = {51A02816-8D25-480F-9D28-EC7D05DC3F63} {1059805B-3221-4788-BDF3-11120FA4BF1A} = {B88EC5D8-5D8A-4C87-81B3-F4F8C7FB2BF8} {EE140765-5088-40AA-9621-D4B0A971EE2C} = {765A6EB0-438E-422C-ACDD-13544EFE6467} diff --git a/Lombiq.Arithmetics b/Lombiq.Arithmetics index d34d4af98..e4aeb999f 160000 --- a/Lombiq.Arithmetics +++ b/Lombiq.Arithmetics @@ -1 +1 @@ -Subproject commit d34d4af981cc0f8b0108891c797648de2079ad59 +Subproject commit e4aeb999f895cbb4e9646e64e2dc0cc85cfa6e91 diff --git a/Samples/Hast.Samples.SampleAssembly/Loopback.cs b/Samples/Hast.Samples.SampleAssembly/Loopback.cs index 971d1c5ac..9593f94ae 100644 --- a/Samples/Hast.Samples.SampleAssembly/Loopback.cs +++ b/Samples/Hast.Samples.SampleAssembly/Loopback.cs @@ -17,7 +17,10 @@ public virtual void Run(SimpleMemory memory) => // sent back. memory.WriteInt32(RunInputOutputInt32Index, memory.ReadInt32(RunInputOutputInt32Index) + 1); - public int Run(int input, IHastlayer hastlayer = null, IHardwareGenerationConfiguration configuration = null) + public int Run( + int input, + IHastlayer hastlayer = null, + IHardwareGenerationConfiguration configuration = null) { var memory = hastlayer is null ? SimpleMemory.CreateSoftwareMemory(1)