/* * Encog(tm) Core v2.5 - Java Version * http://www.heatonresearch.com/encog/ * http://code.google.com/p/encog-java/ * Copyright 2008-2010 Heaton Research, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * For more information on Heaton Research copyrights, licenses * and trademarks visit: * http://www.heatonresearch.com/copyright */ package org.encog.util.benchmark; import java.io.File; import java.io.PrintStream; import org.encog.Encog; import org.encog.engine.StatusReportable; import org.encog.engine.opencl.EncogCLDevice; import org.encog.engine.util.Format; import org.encog.neural.data.NeuralDataPair; import org.encog.neural.data.basic.BasicNeuralDataPair; import org.encog.neural.data.basic.BasicNeuralDataSet; import org.encog.neural.data.buffer.BufferedNeuralDataSet; import org.encog.util.logging.Logging; /** * Benchmark Encog with several network types. * * @author jheaton * */ public class EncogBenchmark { /** * Number of steps in all. */ private static final int STEPS = 4; /** * The first step. */ private static final int STEP1 = 1; /** * The second step. */ private static final int STEP2 = 2; /** * The third step. */ private static final int STEP3 = 3; /** * The fourth step. */ private static final int STEP4 = 4; /** * Report progress. */ private final StatusReportable report; private int cpuScore; private int clScore; private int memoryScore; private int binaryScore; private EncogCLDevice device; /** * Construct a benchmark object. * * @param report * The object to report progress to. */ public EncogBenchmark(final StatusReportable report) { this.report = report; } /** * Perform the benchmark. Returns the total amount of time for all of the * benchmarks. Returns the final score. The lower the better for a score. * * @return The total time, which is the final Encog benchmark score. */ public String process() { Logging.stopConsoleLogging(); this.report.report(EncogBenchmark.STEPS, 0, "Beginning benchmark"); evalCPU(); evalOpenCL(); evalMemory(); evalBinary(); StringBuilder result = new StringBuilder(); result.append("Encog Benchmark: CPU:"); result.append(Format.formatInteger(this.cpuScore)); result.append(", OpenCL"); if (this.device == null) result.append("(none)"); else if (this.device.isCPU()) result.append("(cpu)"); else result.append("(gpu)"); result.append(":"); result.append(Format.formatInteger(this.clScore)); result.append(", Memory:"); result.append(Format.formatInteger(this.memoryScore)); result.append(", Disk:"); result.append(Format.formatInteger(this.binaryScore)); this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEPS, result .toString()); return result.toString(); } /** * Train the neural network with 0 hidden layers. * * @return The amount of time this benchmark took. */ private void evalCPU() { int small = Evaluate.evaluateTrain(2, 4, 0, 1); this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEP1, "Evaluate CPU, tiny= " + Format.formatInteger(small / 100)); int medium = Evaluate.evaluateTrain(10, 20, 0, 1); this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEP1, "Evaluate CPU, small= " + Format.formatInteger(medium / 30)); int large = Evaluate.evaluateTrain(100, 200, 40, 5); this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEP1, "Evaluate CPU, large= " + Format.formatInteger(large)); int huge = Evaluate.evaluateTrain(200, 300, 200, 50); this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEP1, "Evaluate CPU, huge= " + Format.formatInteger(huge)); int result = (small / 100) + (medium / 30) + large + huge; this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEP1, "CPU result: " + result); this.cpuScore = result; } /** * Train the neural network with 0 hidden layers. * * @return The amount of time this benchmark took. */ 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) { PrintStream saved = System.err; System.setErr(null);// don't display OpenCL errors try { if (Encog.getInstance().getCL() == null) Encog.getInstance().initCL(); this.device = Encog.getInstance().getCL().chooseDevice(); } finally { System.setErr(saved); } } } catch (Throwable t) { 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 (Throwable t) { 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 (Throwable t) { 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 (Throwable t) { 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 (Throwable t) { 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; } private void evalMemory() { final BasicNeuralDataSet training = RandomTrainingFactory.generate( 1000, 10000, 10, 10, -1, 1); final long start = System.currentTimeMillis(); final long stop = start + (10 * Evaluate.MILIS); int record = 0; NeuralDataPair pair = BasicNeuralDataPair.createPair(10, 10); int iterations = 0; while (System.currentTimeMillis() < stop) { iterations++; training.getRecord(record++, pair); if (record >= training.getRecordCount()) record = 0; } iterations /= 100000; this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEP3, "Memory dataset, result: " + Format.formatInteger(iterations)); this.memoryScore = iterations; } private void evalBinary() { File file = new File("temp.egb"); final BasicNeuralDataSet training = RandomTrainingFactory.generate( 1000, 10000, 10, 10, -1, 1); // create the binary file file.delete(); BufferedNeuralDataSet training2 = new BufferedNeuralDataSet(file); training2.load(training); final long start = System.currentTimeMillis(); final long stop = start + (10 * Evaluate.MILIS); int record = 0; NeuralDataPair pair = BasicNeuralDataPair.createPair(10, 10); int iterations = 0; while (System.currentTimeMillis() < stop) { iterations++; training2.getRecord(record++, pair); if (record >= training2.getRecordCount()) record = 0; } training.close(); iterations /= 100000; this.report.report(EncogBenchmark.STEPS, EncogBenchmark.STEP4, "Disk(binary) dataset, result: " + Format.formatInteger(iterations)); file.delete(); this.binaryScore = iterations; } /** * @return the cpuScore */ public int getCpuScore() { return cpuScore; } /** * @return the clScore */ public int getClScore() { return clScore; } /** * @return the memoryScore */ public int getMemoryScore() { return memoryScore; } /** * @return the binaryScore */ public int getBinaryScore() { return binaryScore; } /** * @return the device */ public EncogCLDevice getDevice() { return device; } /** * @param device * the device to set */ public void setDevice(EncogCLDevice device) { this.device = device; } }