/*******************************************************************************
* Copyright 2013 Analog Devices, 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.
********************************************************************************/
package com.analog.lyric.dimple.solvers.core.multithreading;
import java.util.EnumMap;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import org.eclipse.jdt.annotation.Nullable;
import com.analog.lyric.dimple.exceptions.DimpleException;
import com.analog.lyric.dimple.model.core.FactorGraph;
import com.analog.lyric.dimple.schedulers.dependencyGraph.StaticDependencyGraph;
import com.analog.lyric.dimple.solvers.core.multithreading.phasealgorithm.PhaseMultithreadingAlgorithm;
import com.analog.lyric.dimple.solvers.core.multithreading.singlequeuealgorithm.SingleQueueMutlithreadingAlgorithm;
import com.analog.lyric.dimple.solvers.interfaces.ISolverFactorGraph;
import com.analog.lyric.util.misc.Matlab;
/*
* The MultiThreading Manager handles the collection of multithreading algorithms
* Dimple currently supports.
*/
public class MultiThreadingManager
{
private final ISolverFactorGraph _sgraph;
private Map<MultithreadingMode,MultithreadingAlgorithm> _mode2alg =
new EnumMap<MultithreadingMode, MultithreadingAlgorithm>(MultithreadingMode.class);
private final @Nullable ExecutorService _service;
private int _numWorkers;
private long _cachedVersion = -1;
private @Nullable StaticDependencyGraph _cachedDependencyGraph;
private MultithreadingMode _whichAlg = MultithreadingMode.Phase;
public MultiThreadingManager(ISolverFactorGraph sfg, @Nullable ExecutorService service)
{
_sgraph = sfg;
_service = service;
setNumWorkersToDefault();
_mode2alg.put(MultithreadingMode.Phase,new PhaseMultithreadingAlgorithm(this));
_mode2alg.put(MultithreadingMode.SingleQueue,new SingleQueueMutlithreadingAlgorithm(this));
}
public MultiThreadingManager(ISolverFactorGraph sfg)
{
this(sfg,null);
}
public ExecutorService getService()
{
final ExecutorService service = _service;
if (service == null)
return ThreadPool.getThreadPool();
else
return service;
}
@Matlab
public MultithreadingMode [] getModes()
{
return MultithreadingMode.values();
}
@Matlab
public void setMode(String mode)
{
setMode(MultithreadingMode.valueOf(mode));
}
@Matlab
public void setMode(MultithreadingMode mode)
{
_whichAlg = mode;
}
public FactorGraph getFactorGraph()
{
return _sgraph.getModelObject();
}
public ISolverFactorGraph getSolverGraph()
{
return _sgraph;
}
/*
* Create the threads in the thread pool.
*/
@Matlab
public void setNumWorkers(int numWorkers)
{
if (numWorkers < 1)
throw new DimpleException("can't set this less than 1");
_numWorkers = numWorkers;
}
@Matlab
public void setNumWorkersToDefault()
{
_numWorkers = Math.max(1, Runtime.getRuntime().availableProcessors() - 1);
}
@Matlab
public int getNumWorkers()
{
return _numWorkers;
}
public void iterate(int numIters)
{
_mode2alg.get(_whichAlg).iterate(numIters);
}
/*
* Provide dependency graph caching.
*/
public StaticDependencyGraph getDependencyGraph()
{
final FactorGraph fg = _sgraph.getModelObject();
long version = fg.structureVersion();
if (version != _cachedVersion)
{
_cachedVersion = version;
_cachedDependencyGraph = new StaticDependencyGraph(_sgraph);
}
return Objects.requireNonNull(_cachedDependencyGraph);
}
}