public IONodeConvolutionParallel(Point2D inputDim, IONode filter, Point2D stepSize)
     : base(inputDim, new Point2D(filter.output.Width * inputDim.X / stepSize.X, filter.output.Height * inputDim.Y / stepSize.Y))
 {
     this.filter   = filter;
     this.stepSize = stepSize;
     //if (this.filter.input.Width % 2 == 0||this.filter.input.Height % 2 == 0)
     //{
     //    throw new ArgumentException("Filter input cannot be even.");
     //}
 }
Example #2
0
        public void pushLayer(IONode n)
        {
            if (layers.Count != 0 && layers.Last().output.Size != n.input.Size)
            {
                throw new Exception("The input size of the layer you are trying to push is not consistent with the output of the previous layer.");
            }

            layers.Add(n);

            if (layers.Count == 1)
            {
                Resize(n.input.Size, n.output.Size); //resize both input and output
            }
            else
            {
                Resize(input.Size, n.output.Size); //resize only the output
            }
        }
        /// <summary>
        /// Move a sliding window and apply the filter by using its BottomUp() method.
        /// </summary>
        protected override void bottomUp()
        {
            System.Collections.Concurrent.ConcurrentStack <IONode> filterClones = new ConcurrentStack <IONode>();
            int stepsWidth  = (int)(input.Width / stepSize.X);
            int stepsHeight = (int)(input.Height / stepSize.Y);

            int totalIterations = stepsWidth * stepsHeight;

            for (int i = 0; i < totalIterations; i++)
            {
                IONode clone = ObjectCopier.Clone(filter);
                filterClones.Push(clone);
            }

            System.Collections.Concurrent.ConcurrentStack <IONode> filterClonesUsed = new ConcurrentStack <IONode>();

            //We pass all components of the input signal
            Parallel.For(0, stepsWidth, stepX =>
            {
                int xI = stepX * (int)stepSize.X;
                Parallel.For(0, stepsHeight, stepY =>
                {
                    int yI = stepY * (int)stepSize.Y;

                    //Clone the filter
                    IONode clone;
                    while (!filterClones.TryPop(out clone))
                    {
                        ;
                    }

                    //We construct the filter input based on its dimensions
                    for (int xF = 0; xF < clone.input.Width; xF++)
                    {
                        for (int yF = 0; yF < clone.input.Height; yF++)
                        {
                            int x = xI - clone.input.Width / 2 + xF;
                            int y = yI - clone.input.Height / 2 + yF;
                            x     = Math.Min(input.Width - 1, Math.Max(x, 0));
                            y     = Math.Min(input.Height - 1, Math.Max(y, 0));
                            clone.input.reality[xF, yF] = input.reality[x, y];
                        }
                    }

                    //We apply the clone
                    clone.BottomUp();

                    //We copy the result of the clone to the output
                    for (int xF = 0; xF < clone.output.Width; xF++)
                    {
                        for (int yF = 0; yF < clone.output.Height; yF++)
                        {
                            output.prediction[(int)(xI / stepSize.X) * clone.output.Width + xF, (int)(yI / stepSize.Y) * clone.output.Height + yF] = clone.output.prediction[xF, yF];
                        }
                    }
                    filterClonesUsed.Push(clone);
                });
            });

            if (filter is IONodeAdaptive)
            {
                IEnumerable <IONodeAdaptive> casted = filterClonesUsed.Cast <IONodeAdaptive>();
                (filter as IONodeAdaptive).fuse(casted);
            }
        }