package edu.stanford.rsl.jpop;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import edu.stanford.rsl.jpop.FunctionOptimizer.OptimizationMode;
/**
* Class to process the gradient evaluations in parallel to speed up computationally expensive function / gradient / Hessian evaluations.
* @author akmaier
*
*/
public class ParallelFunctionController extends FunctionController {
protected boolean debug = true;
@Override
public double evaluate(OptimizableFunction function, double[] x) {
BlockThread [] blocks = initializeBlocks(x, function, OptimizationMode.Function);
try {
runParallel(blocks);
} catch (InterruptedException e) {
e.printStackTrace();
}
double [] results = new double [blocks.length];
for (int i = 0; i < blocks.length; i++){
results[i] = (Double) blocks[i].getResult();
}
return assembler.assembleEvaluationBlocks(results);
}
@Override
public double[] gradient(GradientOptimizableFunction function, double[] x) {
BlockThread [] blocks = initializeBlocks(x, function, OptimizationMode.Gradient);
try {
runParallel(blocks);
} catch (InterruptedException e) {
e.printStackTrace();
}
double [][] results = new double [blocks.length][];
for (int i = 0; i < blocks.length; i++){
results[i] = (double []) blocks[i].getResult();
}
return assembler.assembleGradientBlocks(results);
}
@Override
public double[][] hessian(HessianOptimizableFunction function, double[] x) {
BlockThread [] blocks = initializeBlocks(x, function, OptimizationMode.Hessian);
try {
runParallel(blocks);
} catch (InterruptedException e) {
e.printStackTrace();
}
double [][][] results = new double [blocks.length][][];
for (int i = 0; i < blocks.length; i++){
results[i] = (double [][]) blocks[i].getResult();
}
return assembler.assembleHessianBlocks(results);
}
/**
* Creates and Prepares the blocks for execution
* @param x the point to evaluate
* @param function the function
* @param mode the evaluation Mode
* @return the prepared blocks
*/
protected BlockThread [] initializeBlocks(double [] x, OptimizableFunction function, OptimizationMode mode){
int threads = function.getNumberOfProcessingBlocks();
BlockThread [] blocks = new BlockThread[function.getNumberOfProcessingBlocks()];
for (int i = 0; i < threads; i++){
blocks[i] = new BlockThread();
blocks[i].setX(x);
blocks[i].setBlock(i);
blocks[i].setFunction(function);
blocks[i].setMode(mode);
}
return blocks;
}
/**
* executes the parallel processing.
* @param threads
* @throws InterruptedException
*/
protected void runParallel(BlockThread [] threads) throws InterruptedException{
ExecutorService e = Executors.newFixedThreadPool(threads.length);
CountDownLatch latch = new CountDownLatch(threads.length);
for (int i = 0; i < threads.length; i++){
if (debug) System.out.println("Running " + i + " of " + threads.length);
threads[i].setLatch(latch);
e.submit(threads[i]);
}
latch.await();
e.shutdownNow();
}
}
Ads help maintain this website.