Defines a basic OpenCL kernal, as used by Encog. Contains the kernal source c and a compiled program/kernal.
        /// <summary>
        /// Calculate the kernel values.
        /// </summary>
        ///
        /// <param name="kernel">The kernel to calculate for.</param>
        /// <param name="training">The training params to use.</param>
        public void CalculateKernelParams(EncogKernel kernel,
                IEngineIndexableSet training)
        {
            bool globalValuesAssigned = false;
            int workPerIteration;

            // there are two special cases

            // first, if the ratio is 1.0
            if (Math.Abs(this.segmentationRatio - 1.0d) < EncogEngine.DEFAULT_ZERO_TOLERANCE)
            {
                // if the segmentation ratio is 1, then we want NO SEGMENTATION
                // we will have to find a workgroup size that is even
                int trialLocalSize = (int)Math.Min(kernel.MaxWorkGroupSize, training.Count);

                trialLocalSize++;// falsely add one so the loop can decrease it with
                // no effect.

                // loop and try to find a local size small enough to be even.
                do
                {
                    trialLocalSize--;
                    this.kernelLocalWorkgroup = (int)(trialLocalSize * this.localRatio);
                    this.kernelGlobalWorkgroup = (int)(this.kernelLocalWorkgroup * this.globalRatio);
                    this.kernelWorkPerCall = (int)((training.Count / this.kernelGlobalWorkgroup) * this.segmentationRatio);
                    workPerIteration = this.kernelGlobalWorkgroup
                            * this.kernelWorkPerCall;
                } while ((workPerIteration != training.Count)
                        && trialLocalSize > 1);

                if (trialLocalSize > 0)
                    globalValuesAssigned = true;
            }

            // if we either wanted to segment, or the attempt to find an even group
            // size above failed
            if (!globalValuesAssigned)
            {
                // otherwise divide into segments
                int maxLocalSize = (int)Math.Min(kernel.MaxWorkGroupSize, training.Count);
                this.kernelLocalWorkgroup = (int)(maxLocalSize * this.localRatio);
                this.kernelGlobalWorkgroup = (int)(this.kernelLocalWorkgroup * this.globalRatio);

                // second special case, if the segmentation ratio is zero, then just
                // do one item per OpenCL call
                if (this.segmentationRatio < EncogEngine.DEFAULT_ZERO_TOLERANCE)
                {
                    this.kernelWorkPerCall = 1;
                }
                else
                {
                    this.kernelWorkPerCall = (int)((training.Count / this.kernelGlobalWorkgroup) * this.segmentationRatio);
                    if (this.kernelWorkPerCall == 0)
                    {
                        this.kernelWorkPerCall = 1;
                    }
                }
            }

            workPerIteration = this.kernelGlobalWorkgroup * this.kernelWorkPerCall;

            this.kernelNumberOfCalls = (int)(training.Count / workPerIteration);
            this.kernelRemainder = (int)(training.Count % workPerIteration);

            this.kernelRemainderGlobal = this.kernelGlobalWorkgroup;

            // if there is no "final training set", because it lined up evenly,
            // still create one.
            // the final training set is where learning happens.
            if (this.kernelRemainder == 0)
            {
                this.kernelRemainder = this.kernelGlobalWorkgroup;
                this.kernelRemainderPer = this.kernelWorkPerCall;
                this.kernelNumberOfCalls--;
            }
            else
                this.kernelRemainderPer = this.kernelRemainder
                        / this.kernelGlobalWorkgroup;

            // does the remainder not have enough to fill the global tasks global?
            if (this.kernelRemainderPer == 0)
            {
                this.kernelRemainderPer = 1;
                this.kernelRemainderGlobal = this.kernelRemainder;
            }
        }
예제 #2
0
        /// <summary>
        /// Execute the specified kernel.  
        /// </summary>
        ///
        /// <param name="kernel">The kernel to execute.</param>
        public void Execute(EncogKernel kernel)
        {
            long[] globalWorkSize = new long[] { kernel.GlobalWork };
            long[] localWorkSize = new long[] { kernel.LocalWork };

            // Execute the kernel
            this.commands.Execute(kernel.Kernel, null, globalWorkSize, localWorkSize, null);
        }