/******************************************************************************* * 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); } }