/// <summary> /// Perform the addition. /// </summary> /// /// <param name="device">The OpenCL device to use.</param> /// <param name="inputA">The first vector to add.</param> /// <param name="inputB">The second vector to add.</param> /// <returns>The result of the addition.</returns> public double[] Add(EncogCLDevice device, double[] inputA, double[] inputB) { for (int i = 0; i < inputA.Length; i++) { this.arrayA[i] = (float)inputA[i]; this.arrayB[i] = (float)inputB[i]; } this.Kernel.SetMemoryArgument(0, bufferArrayA); this.Kernel.SetMemoryArgument(1, bufferArrayB); this.Kernel.SetMemoryArgument(2, bufferTargetArray); EncogCLQueue queue = Device.Queue; queue.Array2Buffer(this.arrayA, this.bufferArrayA); queue.Array2Buffer(this.arrayB, this.bufferArrayB); queue.Execute(this); queue.Buffer2Array(this.bufferTargetArray, this.targetArray); queue.WaitFinish(); double[] result = new double[this.targetArray.Length]; for (int i = 0; i < this.targetArray.Length; i++) { result[i] = this.targetArray[i]; } return(result); }
/// <summary> /// Construct a training profile. /// </summary> /// /// <param name="device">The device to use.</param> /// <param name="localRatio">The local ratio.</param> /// <param name="globalRatio">The global ratio.</param> /// <param name="segmentationRatio">The segmentation ratio.</param> public OpenCLTrainingProfile(EncogCLDevice device, double localRatio, int globalRatio, double segmentationRatio) : base() { this.device = device; if (localRatio < 0 || globalRatio < 0 || segmentationRatio < 0) { throw new OpenCLError("None of the ratios can be below zero."); } if (localRatio > 1.0d) { throw new OpenCLError( "The local ratio cannot be greater than 1.0. That would cause the OpenCL device to have more local items than it can handle."); } if (globalRatio < 1.0d) { throw new OpenCLError( "The global ratio cannot be less than 1.0. That would cause the global work area to be less than a local work area."); } if (segmentationRatio > 1.0d) { throw new OpenCLError( "The segmentation ratio cannot be greater than 1.0. That would cause the trainer to require more training elements per iteration than exist."); } this.localRatio = localRatio; this.globalRatio = globalRatio; this.segmentationRatio = segmentationRatio; }
/// <summary> /// Create an Encog OpenCL kernel. The Kernel will be loaded from an embedded /// resource. /// </summary> /// /// <param name="device">The OpenCL device to use.</param> /// <param name="sourceName">The name of the kernel, from an embedded resource.</param> /// <param name="kernelName">The name of the function, in the kernel, called to start thekernel.</param> public EncogKernel(EncogCLDevice device, String sourceName, String kernelName) { this.sourceName = sourceName; this.context = device.Platform.Context; this.device = device; this.kernelName = kernelName; this.cl = ResourceLoader.LoadString(sourceName); }
/// <summary> /// Construct a simple kernel to add two vectors. /// </summary> /// /// <param name="device">The device to use.</param> /// <param name="length">The length of the vector.</param> public KernelVectorAdd(EncogCLDevice device, int length) : base(device, "Encog.Engine.Resources.KernelVectorAdd.txt", "VectorAdd") { // Create input- and output data this.arrayA = new float[length]; this.arrayB = new float[length]; this.targetArray = new float[length]; this.bufferArrayA = this.CreateArrayReadOnly(this.arrayA); this.bufferArrayB = this.CreateArrayReadOnly(this.arrayB); this.bufferTargetArray = CreateFloatArrayWriteOnly(this.targetArray.Length); GlobalWork = length; LocalWork = 1; }
/// <summary> /// Construct a kernel to train the network. /// </summary> /// /// <param name="device">The OpenCL device to use.</param> /// <param name="flat">The network to train.</param> /// <param name="training">The training data.</param> /// <param name="tempDataSize">How much temp data.</param> public KernelNetworkTrain(EncogCLDevice device, FlatNetwork flat, IEngineIndexableSet training, int tempDataSize) : base(device, "Encog.Engine.Resources.KernelNetTrain.txt", "NetworkTrain") { this.training = training; this.trainingLength = (int)this.training.Count; this.device = device; this.flat = flat; this.weightInArray = new float[flat.Weights.Length]; this.weightOutArray = new float[flat.Weights.Length]; this.tempDataArray = new float[tempDataSize]; this.gradients = new float[flat.Weights.Length]; this.layerDeltaSize = 0; for (int i = 0; i < flat.LayerCounts.Length; i++) { this.layerDeltaSize += flat.LayerCounts[i]; } int inputSize = flat.InputCount; int idealSize = flat.OutputCount; this.inputArray = new float[inputSize * this.trainingLength]; this.idealArray = new float[idealSize * this.trainingLength]; this.paramArray = new int[10]; IEngineData pair = BasicEngineData.CreatePair( flat.InputCount, flat.OutputCount); int inputIndex = 0; int idealIndex = 0; for (int i = 0; i < this.trainingLength; i++) { training.GetRecord(i, pair); for (int col = 0; col < flat.InputCount; col++) { this.inputArray[inputIndex++] = (float)pair.InputArray[col]; } for (int col = 0; col < flat.OutputCount; col++) { this.idealArray[idealIndex++] = (float)pair.IdealArray[col]; } } }
/// <summary> /// Construct an OpenCL device performer. /// </summary> /// <param name="number">The device number.</param> /// <param name="device">The device.</param> public ConcurrentTrainingPerformerOpenCL(int number, EncogCLDevice device) : base(number) { if (EncogFramework.Instance.CL == null) { throw new NeuralNetworkError( "Can't use an OpenCL performer, because OpenCL " + "is not enabled."); } if (EncogFramework.Instance.CL == null) { throw new NeuralNetworkError("Can't use a null OpenCL device."); } this.device = device; }
/// <summary> /// Evaluate training, use OpenCL. /// </summary> /// <param name="device">The OpenCL device, null for CPU.</param> /// <param name="input">Input neurons.</param> /// <param name="hidden1">Hidden 1 neurons.</param> /// <param name="hidden2">Hidden 2 neurons.</param> /// <param name="output">Output neurons.</param> /// <returns>The result of the evaluation.</returns> public static int EvaluateTrain(EncogCLDevice device, int input, int hidden1, int hidden2, int output) { BasicNetwork network = EncogUtility.SimpleFeedForward(input, hidden1, hidden2, output, true); INeuralDataSet training = RandomTrainingFactory.Generate(1000, 10000, input, output, -1, 1); OpenCLTrainingProfile profile = null; #if !SILVERLIGHT if (device != null) { profile = new OpenCLTrainingProfile(device); } #endif return(EvaluateTrain(profile, network, training)); }
/// <inheritdoc/> public void Run() { Stopwatch watch = new Stopwatch(); try { watch.Start(); OpenCLTrainingProfile profile = null; #if !SILVERLIGHT if (this is ConcurrentTrainingPerformerOpenCL) { EncogCLDevice device = ((ConcurrentTrainingPerformerOpenCL)this).Device; profile = new OpenCLTrainingProfile(device, this.currentJob.LocalRatio, this.currentJob.GlobalRatio, this.currentJob.SegmentationRatio); } #endif this.currentJob.CreateTrainer(profile, Manager.SingleThreaded); ITrain train = this.currentJob.Train; int interation = 1; while (this.currentJob.ShouldContinue()) { train.Iteration(this.currentJob.IterationsPer); interation++; } watch.Stop(); } catch (Exception t) { this.currentJob.Error = t; } finally { lock (this) { this.ready = true; } this.Manager.JobDone(watch.ElapsedMilliseconds, this); } }
/// <summary> /// Perform the addition. /// </summary> /// /// <param name="device">The OpenCL device to use.</param> /// <param name="inputA">The first vector to add.</param> /// <param name="inputB">The second vector to add.</param> /// <returns>The result of the addition.</returns> public double[] Add(EncogCLDevice device, double[] inputA, double[] inputB) { for (int i = 0; i < inputA.Length; i++) { this.arrayA[i] = (float)inputA[i]; this.arrayB[i] = (float)inputB[i]; } this.Kernel.SetMemoryArgument(0, bufferArrayA); this.Kernel.SetMemoryArgument(1, bufferArrayB); this.Kernel.SetMemoryArgument(2, bufferTargetArray); EncogCLQueue queue = Device.Queue; queue.Array2Buffer(this.arrayA, this.bufferArrayA); queue.Array2Buffer(this.arrayB, this.bufferArrayB); queue.Execute(this); queue.Buffer2Array(this.bufferTargetArray, this.targetArray); queue.WaitFinish(); double[] result = new double[this.targetArray.Length]; for (int i = 0; i < this.targetArray.Length; i++) { result[i] = this.targetArray[i]; } return result; }
/// <summary> /// Evaluate the OpenCL device. /// </summary> private void EvalOpenCL() { try { // did the caller assign a device? If not, use the first GPU, // failing that, // use the first CPU. Failing that, as well, don't test OpenCL. if (this.device == null) { if (EncogFramework.Instance.CL == null) { EncogFramework.Instance.InitCL(); } this.device = EncogFramework.Instance.CL.ChooseDevice(); } } catch (Exception) { this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "No OpenCL devices, result: 0"); this.clScore = 0; } int small = 0, medium = 0, large = 0, huge = 0; try { small = Evaluate.EvaluateTrain(device, 2, 4, 0, 1); this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, tiny= " + Format.FormatInteger(small / 100)); } catch (Exception) { this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, tiny FAILED"); } try { medium = Evaluate.EvaluateTrain(device, 10, 20, 0, 1); this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, small= " + Format.FormatInteger(medium / 30)); } catch (Exception) { this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, small FAILED"); } try { large = Evaluate.EvaluateTrain(device, 100, 200, 40, 5); this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, large= " + Format.FormatInteger(large)); } catch (Exception) { this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, large FAILED"); } try { huge = Evaluate.EvaluateTrain(device, 200, 300, 200, 50); this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, huge= " + Format.FormatInteger(huge)); } catch (Exception) { this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "Evaluate OpenCL, huge FAILED"); } int result = (small / 100) + (medium / 30) + large + huge; this.report.Report(EncogBenchmark.STEPS, EncogBenchmark.STEP2, "OpenCL result: " + result); this.clScore = result; }
/// <summary> /// Construct a training profile with the specified device and the value of one for all ratios. /// </summary> /// /// <param name="device">The device to use.</param> public OpenCLTrainingProfile(EncogCLDevice device) : this(device, 1.0d, 1, 1.0d) { }