/*
* 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.engine.concurrency.calc;
import java.util.ArrayList;
import java.util.List;
import org.encog.engine.EncogEngine;
import org.encog.engine.data.EngineIndexableSet;
import org.encog.engine.network.flat.FlatNetwork;
import org.encog.engine.opencl.EncogCLDevice;
/**
* Class used to provide concurrent calculation between the CPU and OpenCL
* devices.
*
*/
public final class ConcurrentCalculate {
/**
* The instance.
*/
private static ConcurrentCalculate instance;
/**
* @return The instance.
*/
public static ConcurrentCalculate getInstance() {
if (ConcurrentCalculate.instance == null) {
ConcurrentCalculate.instance = new ConcurrentCalculate();
}
return ConcurrentCalculate.instance;
}
/**
* The current network.
*/
private FlatNetwork network;
/**
* The current training data.
*/
private EngineIndexableSet trainingData;
/**
* The OpenCL devices to use.
*/
private final List<CalcOpenCLDevice> devices
= new ArrayList<CalcOpenCLDevice>();
/**
* True, if we should use OpenCL.
*/
private boolean useOpenCL;
/**
* Private constructor.
*/
private ConcurrentCalculate() {
}
/**
* @return THe calculated error.
*/
public double calculateError() {
// if we are using OpenCL, then try to execute on OpenCL first
if (this.useOpenCL) {
for (final CalcOpenCLDevice dev : this.devices) {
final CalculationResult result = dev.calculateError();
if (result.isExecuted()) {
return result.getError();
}
}
}
// use regular CPU code to calculate
return this.network.calculateError(this.trainingData);
}
/**
* @return The current network.
*/
public FlatNetwork getNetwork() {
return this.network;
}
/**
* @return The current training data.
*/
public EngineIndexableSet getTrainingData() {
return this.trainingData;
}
/**
* Init for OpenCL.
*/
public void initCL() {
this.devices.clear();
for (final EncogCLDevice device : EncogEngine.getInstance().getCL()
.getEnabledDevices()) {
CalcOpenCLDevice d = new CalcOpenCLDevice(device, this);
this.devices.add(d);
if( this.network!=null )
d.setNetwork(this.network);
if( this.trainingData!=null )
d.setTraining(this.trainingData);
}
this.useOpenCL = true;
}
/**
* @return the useOpenCL
*/
public boolean isUseOpenCL() {
return this.useOpenCL;
}
/**
* Set the current network.
* @param network The current network.
*/
public void setNetwork(final FlatNetwork network) {
this.network = network;
for (final CalcOpenCLDevice dev : this.devices) {
dev.setTraining(this.trainingData);
}
}
/**
* Set the current training data.
* @param trainingData The current training data.
*/
public void setTrainingData(final EngineIndexableSet trainingData) {
this.trainingData = trainingData;
for (final CalcOpenCLDevice dev : this.devices) {
dev.setTraining(trainingData);
}
}
/**
* @param useOpenCL
* the useOpenCL to set
*/
public void setUseOpenCL(final boolean useOpenCL) {
this.useOpenCL = useOpenCL;
}
}