minor improvements to optimizers

This commit is contained in:
Jonathan Shook 2023-12-19 15:38:28 -06:00
parent 3346cd2624
commit 9a81b816b0
17 changed files with 110 additions and 52 deletions

View File

@ -69,7 +69,7 @@ public class CMD_optimize extends NBBaseCommand {
SimFrameCapture capture = new SimFrameValueData(flywheel); SimFrameCapture capture = new SimFrameValueData(flywheel);
String plannerType = params.getOrDefault("planner", "ratchet"); String plannerType = params.getOrDefault("planner", "ratchet");
OptimizerPlannerTypes plannerImpl = OptimizerPlannerTypes.valueOf(plannerType); OptimizerPlannerTypes plannerImpl = OptimizerPlannerTypes.valueOf(plannerType);
SimFramePlanner<?,?> planner = plannerImpl.createPlanner(params); SimFramePlanner<?,?> planner = plannerImpl.createPlanner(this,params);
Record result = planner.analyze(flywheel, capture, stdout, stderr, controller); Record result = planner.analyze(flywheel, capture, stdout, stderr, controller);
stdout.println("result:\n" + result); stdout.println("result:\n" + result);
return result; return result;

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.nosqlbench.scenarios.simframe.optimo; package io.nosqlbench.scenarios.simframe.optimizers.optimo;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBBufferedContainer; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBBufferedContainer;
import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBBaseCommand; import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBBaseCommand;
@ -63,10 +63,10 @@ import java.util.List;
* to contain a reasonably representative character of the overall manifold</LI> * to contain a reasonably representative character of the overall manifold</LI>
* </OL> * </OL>
*/ */
public class NB_optimo extends NBBaseCommand { public class CMD_optimo extends NBBaseCommand {
private final static Logger logger = LogManager.getLogger(CMD_optimize.class); private final static Logger logger = LogManager.getLogger(CMD_optimize.class);
public NB_optimo(NBBufferedContainer parentComponent, String phaseName, String targetScenario) { public CMD_optimo(NBBufferedContainer parentComponent, String phaseName, String targetScenario) {
super(parentComponent, phaseName, targetScenario); super(parentComponent, phaseName, targetScenario);
} }

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.nosqlbench.scenarios.simframe.optimo; package io.nosqlbench.scenarios.simframe.optimizers.optimo;
import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBBaseCommand; import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBBaseCommand;
import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBCommandInfo; import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBCommandInfo;
@ -24,6 +24,6 @@ import io.nosqlbench.nb.annotations.Service;
public class NBOptimoInfo extends NBCommandInfo { public class NBOptimoInfo extends NBCommandInfo {
@Override @Override
public Class<? extends NBBaseCommand> getType() { public Class<? extends NBBaseCommand> getType() {
return NB_optimo.class; return CMD_optimo.class;
} }
} }

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.nosqlbench.scenarios.simframe.optimo; package io.nosqlbench.scenarios.simframe.optimizers.optimo;
import io.nosqlbench.engine.api.activityapi.core.Activity; import io.nosqlbench.engine.api.activityapi.core.Activity;
import io.nosqlbench.engine.api.activityapi.core.RunState; import io.nosqlbench.engine.api.activityapi.core.RunState;

View File

@ -14,14 +14,18 @@
* limitations under the License. * limitations under the License.
*/ */
package io.nosqlbench.scenarios.simframe.optimo; package io.nosqlbench.scenarios.simframe.optimizers.optimo;
import io.nosqlbench.engine.core.lifecycle.scenario.container.InvokableResult;
import io.nosqlbench.engine.core.lifecycle.scenario.execution.NBCommandResult;
import io.nosqlbench.nb.api.config.standard.Param;
import io.nosqlbench.scenarios.simframe.planning.GenericParamModel;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
public class OptimoFrameParams{ public class OptimoFrameParams implements InvokableResult {
OptimoParamModel model; OptimoParamModel model;
double[] paramValues; double[] paramValues;
@ -40,4 +44,12 @@ public class OptimoFrameParams{
return paramValues; return paramValues;
} }
@Override
public Map<String, String> asResult() {
Map<String,String> result = new LinkedHashMap<>();
for (int i = 0; i < this.paramValues.length; i++) {
result.put(model.getParams().get(i).name(),String.valueOf(paramValues[i]));
}
return result;
}
} }

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.nosqlbench.scenarios.simframe.optimo; package io.nosqlbench.scenarios.simframe.optimizers.optimo;
import io.nosqlbench.scenarios.simframe.planning.GenericParamModel; import io.nosqlbench.scenarios.simframe.planning.GenericParamModel;

View File

@ -14,7 +14,7 @@
* limitations under the License. * limitations under the License.
*/ */
package io.nosqlbench.scenarios.simframe.optimo; package io.nosqlbench.scenarios.simframe.optimizers.optimo;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.engine.util.Unit; import io.nosqlbench.nb.api.engine.util.Unit;

View File

@ -17,6 +17,7 @@
package io.nosqlbench.scenarios.simframe.optimizers.planners; package io.nosqlbench.scenarios.simframe.optimizers.planners;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.scenarios.simframe.optimizers.planners.findmax.FindmaxPlanner; import io.nosqlbench.scenarios.simframe.optimizers.planners.findmax.FindmaxPlanner;
import io.nosqlbench.scenarios.simframe.optimizers.planners.ratchet.RatchetPlanner; import io.nosqlbench.scenarios.simframe.optimizers.planners.ratchet.RatchetPlanner;
import io.nosqlbench.scenarios.simframe.optimizers.planners.rcurve.RCurvePlanner; import io.nosqlbench.scenarios.simframe.optimizers.planners.rcurve.RCurvePlanner;
@ -28,11 +29,11 @@ public enum OptimizerPlannerTypes {
findmax, findmax,
rcurve, rcurve,
; ;
public SimFramePlanner<?,?> createPlanner(NBCommandParams params) { public SimFramePlanner<?,?> createPlanner(NBBaseComponent parent, NBCommandParams params) {
return switch (this) { return switch (this) {
case findmax -> new FindmaxPlanner(params); case findmax -> new FindmaxPlanner(parent, params);
case rcurve -> new RCurvePlanner(params); case rcurve -> new RCurvePlanner(parent, params);
case ratchet -> new RatchetPlanner(params); case ratchet -> new RatchetPlanner(parent, params);
}; };
} }
} }

View File

@ -20,6 +20,7 @@ import io.nosqlbench.engine.api.activityapi.core.Activity;
import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.CycleRateSpec; import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.CycleRateSpec;
import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.SimRateSpec; import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.SimRateSpec;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.events.ParamChange; import io.nosqlbench.nb.api.components.events.ParamChange;
import io.nosqlbench.scenarios.simframe.capture.JournalView; import io.nosqlbench.scenarios.simframe.capture.JournalView;
import io.nosqlbench.scenarios.simframe.planning.SimFrame; import io.nosqlbench.scenarios.simframe.planning.SimFrame;
@ -30,10 +31,8 @@ import org.apache.logging.log4j.Logger;
import java.util.Comparator; import java.util.Comparator;
public class FindmaxPlanner extends SimFramePlanner<FindmaxConfig, FindmaxFrameParams> { public class FindmaxPlanner extends SimFramePlanner<FindmaxConfig, FindmaxFrameParams> {
private final Logger logger = LogManager.getLogger(FindmaxPlanner.class); public FindmaxPlanner(NBBaseComponent parent, NBCommandParams analyzerParams) {
super(parent, analyzerParams);
public FindmaxPlanner(NBCommandParams analyzerParams) {
super(analyzerParams);
} }
@Override @Override

View File

@ -20,6 +20,7 @@ import io.nosqlbench.engine.api.activityapi.core.Activity;
import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.CycleRateSpec; import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.CycleRateSpec;
import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.SimRateSpec; import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.SimRateSpec;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.events.ParamChange; import io.nosqlbench.nb.api.components.events.ParamChange;
import io.nosqlbench.scenarios.simframe.capture.JournalView; import io.nosqlbench.scenarios.simframe.capture.JournalView;
import io.nosqlbench.scenarios.simframe.planning.SimFrame; import io.nosqlbench.scenarios.simframe.planning.SimFrame;
@ -28,10 +29,8 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
public class RatchetPlanner extends SimFramePlanner<RatchetConfig, RatchetFrameParams> { public class RatchetPlanner extends SimFramePlanner<RatchetConfig, RatchetFrameParams> {
private final Logger logger = LogManager.getLogger(RatchetPlanner.class); public RatchetPlanner(NBBaseComponent parent, NBCommandParams params) {
super(parent, params);
public RatchetPlanner(NBCommandParams params) {
super(params);
} }

View File

@ -23,20 +23,20 @@ import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
* should be reduced down to the minimum set needed. * should be reduced down to the minimum set needed.
*/ */
public record RCurveConfig( public record RCurveConfig(
double min_rate, double maxrate,
double max_rate, int maxstep,
int steps double min_sample_seconds
) { ) {
public RCurveConfig(NBCommandParams params) { public RCurveConfig(NBCommandParams params) {
this( this(
params.maybeGet("min_rate").map(Double::parseDouble).orElse(0.0),
params.maybeGet("max_rate").map(Double::parseDouble).orElse(10.0), params.maybeGet("max_rate").map(Double::parseDouble).orElse(10.0),
params.maybeGet("steps").map(Integer::parseInt).orElse(10) params.maybeGet("max_step").map(Integer::parseInt).orElse(10),
params.maybeGet("min_sample_seconds").map(Double::parseDouble).orElse(10.0)
); );
} }
double rateForStep(int step) { double rateForStep(int step) {
return min_rate + ((max_rate-min_rate)*((double)step/(double)steps)); return ((double)step/(double) maxstep)*maxrate;
} }
} }

View File

@ -19,6 +19,10 @@ package io.nosqlbench.scenarios.simframe.optimizers.planners.rcurve;
public record RCurveFrameParams( public record RCurveFrameParams(
double rate, double rate,
int step, int step,
int maxsteps,
String description String description
) { ) {
public double ratio() {
return ((double)step/(double)maxsteps);
}
} }

View File

@ -20,28 +20,34 @@ import io.nosqlbench.engine.api.activityapi.core.Activity;
import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.CycleRateSpec; import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.CycleRateSpec;
import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.SimRateSpec; import io.nosqlbench.engine.api.activityapi.ratelimits.simrate.SimRateSpec;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.components.events.ParamChange; import io.nosqlbench.nb.api.components.events.ParamChange;
import io.nosqlbench.scenarios.simframe.capture.JournalView; import io.nosqlbench.scenarios.simframe.capture.JournalView;
import io.nosqlbench.scenarios.simframe.capture.SimFrameCapture;
import io.nosqlbench.scenarios.simframe.planning.HoldAndSample;
import io.nosqlbench.scenarios.simframe.planning.SimFrame; import io.nosqlbench.scenarios.simframe.planning.SimFrame;
import io.nosqlbench.scenarios.simframe.planning.SimFramePlanner; import io.nosqlbench.scenarios.simframe.planning.SimFramePlanner;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFrameParams> { import java.util.concurrent.locks.LockSupport;
private final Logger logger = LogManager.getLogger(RCurvePlanner.class);
public RCurvePlanner(NBCommandParams params) { public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFrameParams> implements HoldAndSample {
super(params); private RCurveFrameParams lastFrame;
public RCurvePlanner(NBBaseComponent parent, NBCommandParams params) {
super(parent,params);
create().gauge("rcuve_step",() -> lastFrame==null ? 0 : (double)lastFrame.step());
create().gauge("rcurve_maxstep",() -> lastFrame==null ? 0 : (double)lastFrame.maxsteps());
create().gauge("rcurve_ratio",() -> lastFrame==null ? 0.0 : lastFrame.ratio());
create().gauge("rcurve_rate",() -> lastFrame==null ? 0.0 : lastFrame.rate());
} }
@Override @Override
public RCurveConfig getConfig(NBCommandParams params) { public RCurveConfig getConfig(NBCommandParams params) {
return new RCurveConfig(params); return new RCurveConfig(params);
} }
public RCurveFrameParams initialStep() { public RCurveFrameParams initialStep() {
return new RCurveFrameParams(config.rateForStep(1), 1, "INITIAL"); return new RCurveFrameParams(config.rateForStep(1), 1,config.maxstep(),"INITIAL");
} }
/** /**
@ -58,8 +64,8 @@ public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFramePara
public RCurveFrameParams nextStep(JournalView<RCurveFrameParams> journal) { public RCurveFrameParams nextStep(JournalView<RCurveFrameParams> journal) {
SimFrame<RCurveFrameParams> last = journal.last(); SimFrame<RCurveFrameParams> last = journal.last();
int nextStep = last.params().step() +1; int nextStep = last.params().step() +1;
if (nextStep<=config.steps()) { if (nextStep<=config.maxstep()) {
return new RCurveFrameParams(config.rateForStep(nextStep),nextStep,"Advancing to step " + nextStep); return new RCurveFrameParams(config.rateForStep(nextStep),nextStep,config.maxstep(),"Advancing to step " + nextStep);
} else { } else {
return null; return null;
} }
@ -69,4 +75,11 @@ public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFramePara
public void applyParams(RCurveFrameParams params, Activity flywheel) { public void applyParams(RCurveFrameParams params, Activity flywheel) {
flywheel.onEvent(ParamChange.of(new CycleRateSpec(params.rate(), 1.1d, SimRateSpec.Verb.restart))); flywheel.onEvent(ParamChange.of(new CycleRateSpec(params.rate(), 1.1d, SimRateSpec.Verb.restart)));
} }
@Override
public void holdAndSample(SimFrameCapture capture) {
logger.info("holding and sampling for " + config.min_sample_seconds() + " seconds");
LockSupport.parkNanos((long)(config.min_sample_seconds()*1_000_000_000));
capture.awaitSteadyState();
}
} }

View File

@ -0,0 +1,27 @@
/*
* Copyright (c) 2023 nosqlbench
*
* 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 io.nosqlbench.scenarios.simframe.planning;
import io.nosqlbench.scenarios.simframe.capture.SimFrameCapture;
public interface HoldAndSample {
/**
* This should block until it is ready to stop sampling.
* @param capture The capture data for the current frame.
*/
void holdAndSample(SimFrameCapture capture);
}

View File

@ -19,6 +19,8 @@ package io.nosqlbench.scenarios.simframe.planning;
import io.nosqlbench.engine.api.activityapi.core.Activity; import io.nosqlbench.engine.api.activityapi.core.Activity;
import io.nosqlbench.engine.core.lifecycle.scenario.container.ContainerActivitiesController; import io.nosqlbench.engine.core.lifecycle.scenario.container.ContainerActivitiesController;
import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams; import io.nosqlbench.engine.core.lifecycle.scenario.container.NBCommandParams;
import io.nosqlbench.nb.api.components.core.NBBaseComponent;
import io.nosqlbench.nb.api.labels.NBLabels;
import io.nosqlbench.scenarios.simframe.capture.*; import io.nosqlbench.scenarios.simframe.capture.*;
import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger; import org.apache.logging.log4j.Logger;
@ -32,12 +34,13 @@ import java.io.PrintWriter;
* @param <C> * @param <C>
* The configuration type for the planner * The configuration type for the planner
*/ */
public abstract class SimFramePlanner<C,P extends Record> { public abstract class SimFramePlanner<C,P extends Record> extends NBBaseComponent {
private final Logger logger = LogManager.getLogger(SimFramePlanner.class); protected final Logger logger = LogManager.getLogger(SimFramePlanner.class);
protected final C config; protected final C config;
protected final SimFrameJournal<P> journal; protected final SimFrameJournal<P> journal;
public SimFramePlanner(NBCommandParams analyzerParams) { public SimFramePlanner(NBBaseComponent parent, NBCommandParams analyzerParams) {
super(parent, NBLabels.forKV());
this.config = getConfig(analyzerParams); this.config = getConfig(analyzerParams);
this.journal = initJournal(); this.journal = initJournal();
} }
@ -69,11 +72,11 @@ public abstract class SimFramePlanner<C,P extends Record> {
stdout.println(frameParams); stdout.println(frameParams);
applyParams(frameParams,flywheel); applyParams(frameParams,flywheel);
capture.startWindow(); capture.startWindow();
capture.awaitSteadyState(); if (this instanceof HoldAndSample has) {
// applyParams(frameParams,flywheel); has.holdAndSample(capture);
// capture.restartWindow(); } else {
//// controller.waitMillis(500); capture.awaitSteadyState();
// capture.awaitSteadyState(); }
capture.stopWindow(); capture.stopWindow();
journal.record(frameParams, capture.last()); journal.record(frameParams, capture.last());
stdout.println(capture.last()); stdout.println(capture.last());

View File

@ -178,9 +178,9 @@ public class StabilityDetector implements Runnable {
double value = source.getAsDouble(); double value = source.getAsDouble();
apply(value); apply(value);
double stabilityFactor = computeStability(); double stabilityFactor = computeStability();
// if (Double.isNaN(stabilityFactor)) { if (Double.isNaN(stabilityFactor)) {
// System.out.println("NaN stability factor"); throw new RuntimeException("NaN stability factor:" + this);
// } }
if (stabilityFactor > threshold) { if (stabilityFactor > threshold) {
detectionTime = ((double) (nextCheckAt - startedAt)) / 1000d; detectionTime = ((double) (nextCheckAt - startedAt)) / 1000d;

View File

@ -21,7 +21,7 @@ bindings:
# create a simple 2-d vector from a step function over the unit interval # create a simple 2-d vector from a step function over the unit interval
# of 10 steps (the maximum number of characters per digit) # of 10 maxstep (the maximum number of characters per digit)
v2d: DoubleVectors('0-2*2') v2d: DoubleVectors('0-2*2')
# use Stringify() to visualize the value of numeric array types # use Stringify() to visualize the value of numeric array types