diff --git a/Common/src/main/collections/ListUtils.java b/Common/src/main/collections/ListUtils.java index 66bd77a0a2..eaafdcef27 100644 --- a/Common/src/main/collections/ListUtils.java +++ b/Common/src/main/collections/ListUtils.java @@ -138,6 +138,52 @@ public static TIntArrayList range(final int maxExclusive) return list; } + /** + * @param minInclusive + * @param maxExclusive + * @return Exactly like python's range() function, generates a list from minInclusive to maxExclusive + */ + public static TIntArrayList range(final int minInclusive, final int maxExclusive) + { + final TIntArrayList list = new TIntArrayList(maxExclusive); + for (int i = minInclusive; i < maxExclusive - minInclusive; ++i) + { + list.add(i); + } + return list; + } + + /** + * Splits the given list into numLists different sublists. The sublists will be + * equally-sized (except for, possibly, the last one, which may be smaller than the others). + * + * @param list + * @param numLists + * @return + */ + public static TIntArrayList[] split(final TIntArrayList list, final int numLists) + { + final TIntArrayList[] sublists = new TIntArrayList[numLists]; + final int sublistSize = (int) Math.ceil((double) list.size() / numLists); + + for (int i = 0; i < numLists; ++i) + { + final TIntArrayList sublist = new TIntArrayList(); + + for (int j = 0; j < sublistSize; ++j) + { + sublist.add(list.getQuick(i * sublistSize + j)); + + if (i * sublistSize + j + 1 >= list.size()) + break; + } + + sublists[i] = sublist; + } + + return sublists; + } + //------------------------------------------------------------------------- /** diff --git a/Player/src/supplementary/experiments/concepts/ParallelComputeConceptsMultipleGames.java b/Player/src/supplementary/experiments/concepts/ParallelComputeConceptsMultipleGames.java index 810f4f6736..7bd62cc5f6 100644 --- a/Player/src/supplementary/experiments/concepts/ParallelComputeConceptsMultipleGames.java +++ b/Player/src/supplementary/experiments/concepts/ParallelComputeConceptsMultipleGames.java @@ -12,21 +12,28 @@ import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; +import java.util.concurrent.ThreadLocalRandom; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; +import java.util.regex.Pattern; +import org.apache.commons.rng.core.RandomProviderDefaultState; import org.json.JSONObject; import org.json.JSONTokener; import features.feature_sets.network.JITSPatterNetFeatureSet; import game.Game; +import gnu.trove.list.array.TIntArrayList; import main.CommandLineArgParse; import main.CommandLineArgParse.ArgOption; import main.CommandLineArgParse.OptionTypes; import main.DaemonThreadFactory; +import main.collections.ListUtils; import other.GameLoader; import other.concept.Concept; import other.concept.ConceptDataType; +import other.context.Context; +import other.trial.Trial; /** * Implementation of an experiment that computes concepts for multiple games in parallel. @@ -265,9 +272,47 @@ public void startExperiment() @SuppressWarnings("resource") final ExecutorService threadPool = Executors.newFixedThreadPool(numThreads, DaemonThreadFactory.INSTANCE); + final TIntArrayList trialIndicesToGenerate = ListUtils.range(firstTrialIndex, firstTrialIndex + numTrialsToRun); + final TIntArrayList[] trialIndicesPerJob = ListUtils.split(trialIndicesToGenerate, numThreads); + try { - // TODO + for (final TIntArrayList trialIndices : trialIndicesPerJob) + { + // Submit a job for this sublist of trial indices + threadPool.submit + ( + () -> + { + for (int i = 0; i < trialIndices.size(); ++i) + { + final int trialIdx = trialIndices.getQuick(i); + + try + { + final Trial trial = new Trial(game); + final Context context = new Context(game, trial); + final RandomProviderDefaultState gameStartRngState = (RandomProviderDefaultState) context.rng().saveState(); + game.start(context); + game.playout(context, null, 1.0, null, 0, -1, ThreadLocalRandom.current()); + + String trialFilepath = trialsDir.getAbsolutePath(); + trialFilepath = trialFilepath.replaceAll(Pattern.quote("\\"), "/"); + if (!trialFilepath.endsWith("/")) + trialFilepath += "/"; + trialFilepath += "Trial_" + trialIdx + ".txt"; + + // TODO game path and options + //trial.saveTrialToTextFile(trialFilepath, game.name(), new ArrayList(), gameStartRngState); + } + catch (final Exception e) + { + e.printStackTrace(); + } + } + } + ); + } } catch (final Exception e) {