org.optaplanner.benchmark.impl.SubSingleBenchmarkRunner Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.optaplanner.benchmark.impl;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.Callable;
import org.optaplanner.benchmark.impl.result.ProblemBenchmarkResult;
import org.optaplanner.benchmark.impl.result.SingleBenchmarkResult;
import org.optaplanner.benchmark.impl.result.SubSingleBenchmarkResult;
import org.optaplanner.benchmark.impl.statistic.StatisticRegistry;
import org.optaplanner.benchmark.impl.statistic.SubSingleStatistic;
import org.optaplanner.core.api.score.ScoreExplanation;
import org.optaplanner.core.api.solver.SolutionManager;
import org.optaplanner.core.api.solver.SolutionUpdatePolicy;
import org.optaplanner.core.config.solver.SolverConfig;
import org.optaplanner.core.impl.domain.solution.descriptor.SolutionDescriptor;
import org.optaplanner.core.impl.solver.DefaultSolver;
import org.optaplanner.core.impl.solver.DefaultSolverFactory;
import org.optaplanner.core.impl.solver.scope.SolverScope;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tags;
public class SubSingleBenchmarkRunner implements Callable> {
public static final String NAME_MDC = "subSingleBenchmark.name";
private static final Logger LOGGER = LoggerFactory.getLogger(SubSingleBenchmarkRunner.class);
private final SubSingleBenchmarkResult subSingleBenchmarkResult;
private final boolean warmUp;
private Long randomSeed = null;
private Throwable failureThrowable = null;
/**
* @param subSingleBenchmarkResult never null
*/
public SubSingleBenchmarkRunner(SubSingleBenchmarkResult subSingleBenchmarkResult, boolean warmUp) {
this.subSingleBenchmarkResult = subSingleBenchmarkResult;
this.warmUp = warmUp;
}
public SubSingleBenchmarkResult getSubSingleBenchmarkResult() {
return subSingleBenchmarkResult;
}
public Long getRandomSeed() {
return randomSeed;
}
public Throwable getFailureThrowable() {
return failureThrowable;
}
public void setFailureThrowable(Throwable failureThrowable) {
this.failureThrowable = failureThrowable;
}
// ************************************************************************
// Benchmark methods
// ************************************************************************
@Override
public SubSingleBenchmarkRunner call() {
MDC.put(NAME_MDC, subSingleBenchmarkResult.getName());
Runtime runtime = Runtime.getRuntime();
SingleBenchmarkResult singleBenchmarkResult = subSingleBenchmarkResult.getSingleBenchmarkResult();
ProblemBenchmarkResult problemBenchmarkResult = singleBenchmarkResult
.getProblemBenchmarkResult();
Solution_ problem = problemBenchmarkResult.readProblem();
if (!problemBenchmarkResult.getPlannerBenchmarkResult().hasMultipleParallelBenchmarks()) {
runtime.gc();
subSingleBenchmarkResult.setUsedMemoryAfterInputSolution(runtime.totalMemory() - runtime.freeMemory());
}
LOGGER.trace("Benchmark problem has been read for subSingleBenchmarkResult ({}).",
subSingleBenchmarkResult);
SolverConfig solverConfig = singleBenchmarkResult.getSolverBenchmarkResult()
.getSolverConfig();
if (singleBenchmarkResult.getSubSingleCount() > 1) {
solverConfig = new SolverConfig(solverConfig);
solverConfig.offerRandomSeedFromSubSingleIndex(subSingleBenchmarkResult.getSubSingleBenchmarkIndex());
}
Map subSingleBenchmarkTagMap = new HashMap<>();
String runId = UUID.randomUUID().toString();
subSingleBenchmarkTagMap.put("optaplanner.benchmark.run", runId);
solverConfig = new SolverConfig(solverConfig);
randomSeed = solverConfig.getRandomSeed();
// Defensive copy of solverConfig for every SingleBenchmarkResult to reset Random, tabu lists, ...
DefaultSolverFactory solverFactory = new DefaultSolverFactory<>(new SolverConfig(solverConfig));
DefaultSolver solver = (DefaultSolver) solverFactory.buildSolver();
solver.setMonitorTagMap(subSingleBenchmarkTagMap);
StatisticRegistry statisticRegistry = new StatisticRegistry<>(solver);
Metrics.addRegistry(statisticRegistry);
solver.addPhaseLifecycleListener(statisticRegistry);
Tags runTag = Tags.of("optaplanner.benchmark.run", runId);
for (SubSingleStatistic subSingleStatistic : subSingleBenchmarkResult.getEffectiveSubSingleStatisticMap()
.values()) {
subSingleStatistic.open(statisticRegistry, runTag, solver);
subSingleStatistic.initPointList();
}
Solution_ solution = solver.solve(problem);
solver.removePhaseLifecycleListener(statisticRegistry);
Metrics.removeRegistry(statisticRegistry);
long timeMillisSpent = solver.getTimeMillisSpent();
for (SubSingleStatistic subSingleStatistic : subSingleBenchmarkResult.getEffectiveSubSingleStatisticMap()
.values()) {
subSingleStatistic.close(statisticRegistry, runTag, solver);
subSingleStatistic.hibernatePointList();
}
if (!warmUp) {
SolverScope solverScope = solver.getSolverScope();
SolutionDescriptor solutionDescriptor = solverScope.getSolutionDescriptor();
problemBenchmarkResult.registerScale(solutionDescriptor.getEntityCount(solution),
solutionDescriptor.getGenuineVariableCount(solution),
solutionDescriptor.getMaximumValueCount(solution),
solutionDescriptor.getProblemScale(solution));
subSingleBenchmarkResult.setScore(solutionDescriptor.getScore(solution));
subSingleBenchmarkResult.setTimeMillisSpent(timeMillisSpent);
subSingleBenchmarkResult.setScoreCalculationCount(solverScope.getScoreCalculationCount());
SolutionManager solutionManager = SolutionManager.create(solverFactory);
boolean isConstraintMatchEnabled = solver.getSolverScope().getScoreDirector().isConstraintMatchEnabled();
if (isConstraintMatchEnabled) { // Easy calculator fails otherwise.
ScoreExplanation scoreExplanation =
solutionManager.explain(solution, SolutionUpdatePolicy.NO_UPDATE);
subSingleBenchmarkResult.setScoreExplanationSummary(scoreExplanation.getSummary());
}
problemBenchmarkResult.writeSolution(subSingleBenchmarkResult, solution);
}
MDC.remove(NAME_MDC);
return this;
}
public String getName() {
return subSingleBenchmarkResult.getName();
}
@Override
public String toString() {
return subSingleBenchmarkResult.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy