Example #1
0
        protected override void OnParametersSet()
        {
            base.OnParametersSet();
            _horizontalLines.Clear();
            _verticalLines.Clear();
            _horizontalValues.Clear();
            _verticalValues.Clear();
            _legends.Clear();
            _chartLines.Clear();

            if (MudChartParent != null)
            {
                _series = MudChartParent.ChartSeries;
            }

            var maxY       = 0.0;
            var numValues  = 0;
            var numXLabels = XAxisLabels.Length;

            foreach (var item in _series)
            {
                if (numValues < item.Data.Length)
                {
                    numValues = item.Data.Length;
                }
                foreach (int i in item.Data)
                {
                    if (maxY < i)
                    {
                        maxY = i;
                    }
                }
            }

            var boundHeight = 350.0;
            var boundWidth  = 650.0;

            double gridYUnits = MudChartParent?.ChartOptions.YAxisTicks ?? 20;
            double gridXUnits = 30;

            var numVerticalLines = numValues - 1;

            var numHorizontalLines = ((int)(maxY / gridYUnits)) + 1;

            var verticalStartSpace   = 25.0;
            var horizontalStartSpace = 30.0;
            var verticalEndSpace     = 25.0;
            var horizontalEndSpace   = 30.0;

            var verticalSpace       = (boundHeight - verticalStartSpace - verticalEndSpace) / (numHorizontalLines);
            var horizontalSpace     = (boundWidth - horizontalStartSpace - horizontalEndSpace) / (numVerticalLines);
            var interpolationOption = MudChartParent?.ChartOptions.InterpolationOption ?? InterpolationOption.Straight;

            //Horizontal Grid Lines
            var    y          = verticalStartSpace;
            double startGridY = 0;

            for (var counter = 0; counter <= numHorizontalLines; counter++)
            {
                var line = new SvgPath()
                {
                    Index = counter,
                    Data  = $"M {ToS(horizontalStartSpace)} {ToS((boundHeight - y))} L {ToS((boundWidth - horizontalEndSpace))} {ToS((boundHeight - y))}"
                };
                _horizontalLines.Add(line);

                var lineValue = new SvgText()
                {
                    X = (horizontalStartSpace - 10), Y = (boundHeight - y + 5), Value = ToS(startGridY, MudChartParent?.ChartOptions.YAxisFormat)
                };
                _horizontalValues.Add(lineValue);

                startGridY += gridYUnits;
                y          += verticalSpace;
            }

            //Vertical Grid Lines
            var    x          = horizontalStartSpace;
            double startGridX = 0;

            for (var counter = 0; counter <= numVerticalLines; counter++)
            {
                var line = new SvgPath()
                {
                    Index = counter,
                    Data  = $"M {ToS(x)} {ToS((boundHeight - verticalStartSpace))} L {ToS(x)} {ToS(verticalEndSpace)}"
                };
                _verticalLines.Add(line);

                var xLabels = "";
                if (counter < numXLabels)
                {
                    xLabels = XAxisLabels[counter];
                }

                var lineValue = new SvgText()
                {
                    X = x, Y = boundHeight - 2, Value = xLabels
                };
                _verticalValues.Add(lineValue);

                startGridX += gridXUnits;
                x          += horizontalSpace;
            }


            //Chart Lines
            var colorcounter = 0;

            foreach (var item in _series)
            {
                var               chartLine  = "";
                double            gridValueX = 0;
                double            gridValueY = 0;
                var               firstTime  = true;
                double[]          XValues    = new double[item.Data.Length];
                double[]          YValues    = new double[item.Data.Length];
                ILineInterpolator interpolator;
                for (var i = 0; i <= item.Data.Length - 1; i++)
                {
                    if (i == 0)
                    {
                        XValues[i] = 30;
                    }
                    else
                    {
                        XValues[i] = XValues[i - 1] + horizontalSpace;
                    }

                    var gridValue = (item.Data[i]) * verticalSpace / gridYUnits;
                    YValues[i] = boundHeight - (verticalStartSpace + gridValue);
                }
                switch (interpolationOption)
                {
                case InterpolationOption.NaturalSpline:
                    interpolator = new NaturalSpline(XValues, YValues);
                    break;

                case InterpolationOption.EndSlope:
                    interpolator = new EndSlopeSpline(XValues, YValues);
                    break;

                case InterpolationOption.Periodic:
                    interpolator = new PeriodicSpline(XValues, YValues);
                    break;

                case InterpolationOption.Straight:
                default:
                    interpolator = new NoInterpolation();
                    break;
                }

                if (interpolator?.InterpolationRequired == true)
                {
                    horizontalSpace = (boundWidth - horizontalStartSpace - horizontalEndSpace) / interpolator.InterpolatedXs.Length;
                    foreach (var yValue in interpolator.InterpolatedYs)
                    {
                        if (firstTime)
                        {
                            chartLine += "M ";
                            firstTime  = false;
                            gridValueX = horizontalStartSpace;
                            gridValueY = verticalStartSpace;
                        }
                        else
                        {
                            chartLine  += " L ";
                            gridValueX += horizontalSpace;
                            gridValueY  = verticalStartSpace;
                        }
                        gridValueY = yValue;
                        chartLine  = chartLine + ToS(gridValueX) + " " + ToS(gridValueY);
                    }
                }
                else
                {
                    foreach (var dataLine in item.Data)
                    {
                        if (firstTime)
                        {
                            chartLine += "M ";
                            firstTime  = false;
                            gridValueX = horizontalStartSpace;
                            gridValueY = verticalStartSpace;
                        }
                        else
                        {
                            chartLine  += " L ";
                            gridValueX += horizontalSpace;
                            gridValueY  = verticalStartSpace;
                        }

                        var gridValue = ((double)dataLine) * verticalSpace / gridYUnits;
                        gridValueY = boundHeight - (gridValueY + gridValue);
                        chartLine  = chartLine + ToS(gridValueX) + " " + ToS(gridValueY);
                    }
                }

                var line = new SvgPath()
                {
                    Index = colorcounter,
                    Data  = chartLine
                };

                var legend = new SvgLegend()
                {
                    Index  = colorcounter,
                    Labels = item.Name
                };
                colorcounter++;
                _chartLines.Add(line);
                _legends.Add(legend);
            }
        }
        public static void Main(int tasks = 20, int imgWidth = 600, int imgHeight = 400, string imgPath = "./")
        {
            //Model test configurations
            var minProcessors = 1;
            var maxProcessors = 1025;
            var testSet       = new List <Fraction> {
                Fraction.FromDoubleRounded(0.5),
                Fraction.FromDoubleRounded(0.75),
                Fraction.FromDoubleRounded(0.9),
                Fraction.FromDoubleRounded(0.95)
            };

            //Running models
            var plotData = testSet.ToDictionary(fraction => fraction, fraction => new List <PlotFrame>());

            testSet.ForEach(
                parallelPart =>
            {
                for (Fraction i = minProcessors; i < maxProcessors; i *= 2)
                {
                    var processors = i.ToInt32();
                    var simulation = new SimulationControllerBase <AmdahlLaw>(
                        generator: () => new AmdahlLaw(tasks, processors, parallelPart),
                        strategy: SimulationStrategy.None
                        );
                    var stop = false;
                    simulation.OnPlaceUpdate(
                        simulation.state.TopGroup.Done,
                        list => { stop = true; }
                        );

                    while (!stop)
                    {
                        simulation.SimulationStep();
                    }

                    //Logging results

                    Console.WriteLine(
                        $"processors: {processors} steps: {((simulation.state.CurrentTime - simulation.TopGroup.DoneChecker.TimeScale) / simulation.state.TimeStep).ToDouble()} time: {simulation.state.CurrentTime.ToDouble()} timeStep {simulation.state.TimeStep}"
                        );
                    plotData[parallelPart].Add(
                        new PlotFrame(
                            processors,
                            (simulation.state.CurrentTime - simulation.TopGroup.DoneChecker.TimeScale).ToDouble()
                            )
                        );
                }
            }
                );

            //Plotting
            var i          = 0;
            var xPositions = plotData.Values.First().Select(frame => Convert.ToDouble(++i)).ToArray();
            var xLabels    = plotData.Values.First().Select(frame => frame.Key.ToString()).ToArray();

            var plt = new Plot(imgWidth, imgHeight);

            foreach (var kvp in plotData)
            {
                var ys  = kvp.Value.Select(frame => frame.Value).ToArray();
                var esi = new EndSlopeSpline(xPositions, ys, 15);
                plt.PlotScatter(esi.interpolatedXs, esi.interpolatedYs, markerSize: 0, label: null);
                plt.PlotScatter(xPositions, ys, label: kvp.Key.ToString(), markerSize: 5, lineWidth: 0);
            }

            plt.XTicks(xPositions, xLabels);
            plt.PlotHLine(tasks, lineStyle: LineStyle.Dash);
            plt.PlotHLine(1, lineStyle: LineStyle.Dash);
            plt.Legend();
            plt.Title("Amdahl's law");
            plt.YLabel("Time");
            plt.XLabel("Number of processors");
            plt.SaveFig(imgPath + "AmdahlTime.png");

            var plt2 = new Plot(imgWidth, imgHeight);

            foreach (var kvp in plotData)
            {
                var ys  = kvp.Value.Select(frame => kvp.Value[0].Value / frame.Value).ToArray();
                var esi = new EndSlopeSpline(xPositions, ys, 15);
                plt2.PlotScatter(esi.interpolatedXs, esi.interpolatedYs, markerSize: 0, label: null);
                plt2.PlotScatter(xPositions, ys, label: kvp.Key.ToString(), markerSize: 5, lineWidth: 0);
            }

            plt2.PlotHLine(1, lineStyle: LineStyle.Dash);
            plt2.PlotHLine(tasks, lineStyle: LineStyle.Dash);
            plt2.Legend();
            plt2.XTicks(xPositions, xLabels);
            plt2.Title("Amdahl's law");
            plt2.YLabel("SpeedUp");
            plt2.XLabel("Number of processors");
            plt2.SaveFig(imgPath + "AmdahlSpeedUp.png");
        }