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);
String plannerType = params.getOrDefault("planner", "ratchet");
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);
stdout.println("result:\n" + result);
return result;

View File

@ -14,7 +14,7 @@
* 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.execution.NBBaseCommand;
@ -63,10 +63,10 @@ import java.util.List;
* to contain a reasonably representative character of the overall manifold</LI>
* </OL>
*/
public class NB_optimo extends NBBaseCommand {
public class CMD_optimo extends NBBaseCommand {
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);
}

View File

@ -14,7 +14,7 @@
* 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.NBCommandInfo;
@ -24,6 +24,6 @@ import io.nosqlbench.nb.annotations.Service;
public class NBOptimoInfo extends NBCommandInfo {
@Override
public Class<? extends NBBaseCommand> getType() {
return NB_optimo.class;
return CMD_optimo.class;
}
}

View File

@ -14,7 +14,7 @@
* 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.RunState;

View File

@ -14,14 +14,18 @@
* 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.List;
import java.util.Map;
public class OptimoFrameParams{
public class OptimoFrameParams implements InvokableResult {
OptimoParamModel model;
double[] paramValues;
@ -40,4 +44,12 @@ public class OptimoFrameParams{
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.
*/
package io.nosqlbench.scenarios.simframe.optimo;
package io.nosqlbench.scenarios.simframe.optimizers.optimo;
import io.nosqlbench.scenarios.simframe.planning.GenericParamModel;

View File

@ -14,7 +14,7 @@
* 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.nb.api.engine.util.Unit;

View File

@ -17,6 +17,7 @@
package io.nosqlbench.scenarios.simframe.optimizers.planners;
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.ratchet.RatchetPlanner;
import io.nosqlbench.scenarios.simframe.optimizers.planners.rcurve.RCurvePlanner;
@ -28,11 +29,11 @@ public enum OptimizerPlannerTypes {
findmax,
rcurve,
;
public SimFramePlanner<?,?> createPlanner(NBCommandParams params) {
public SimFramePlanner<?,?> createPlanner(NBBaseComponent parent, NBCommandParams params) {
return switch (this) {
case findmax -> new FindmaxPlanner(params);
case rcurve -> new RCurvePlanner(params);
case ratchet -> new RatchetPlanner(params);
case findmax -> new FindmaxPlanner(parent, params);
case rcurve -> new RCurvePlanner(parent, 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.SimRateSpec;
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.scenarios.simframe.capture.JournalView;
import io.nosqlbench.scenarios.simframe.planning.SimFrame;
@ -30,10 +31,8 @@ import org.apache.logging.log4j.Logger;
import java.util.Comparator;
public class FindmaxPlanner extends SimFramePlanner<FindmaxConfig, FindmaxFrameParams> {
private final Logger logger = LogManager.getLogger(FindmaxPlanner.class);
public FindmaxPlanner(NBCommandParams analyzerParams) {
super(analyzerParams);
public FindmaxPlanner(NBBaseComponent parent, NBCommandParams analyzerParams) {
super(parent, analyzerParams);
}
@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.SimRateSpec;
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.scenarios.simframe.capture.JournalView;
import io.nosqlbench.scenarios.simframe.planning.SimFrame;
@ -28,10 +29,8 @@ import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class RatchetPlanner extends SimFramePlanner<RatchetConfig, RatchetFrameParams> {
private final Logger logger = LogManager.getLogger(RatchetPlanner.class);
public RatchetPlanner(NBCommandParams params) {
super(params);
public RatchetPlanner(NBBaseComponent parent, NBCommandParams params) {
super(parent, 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.
*/
public record RCurveConfig(
double min_rate,
double max_rate,
int steps
double maxrate,
int maxstep,
double min_sample_seconds
) {
public RCurveConfig(NBCommandParams params) {
this(
params.maybeGet("min_rate").map(Double::parseDouble).orElse(0.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) {
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(
double rate,
int step,
int maxsteps,
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.SimRateSpec;
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.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.SimFramePlanner;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFrameParams> {
private final Logger logger = LogManager.getLogger(RCurvePlanner.class);
import java.util.concurrent.locks.LockSupport;
public RCurvePlanner(NBCommandParams params) {
super(params);
public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFrameParams> implements HoldAndSample {
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
public RCurveConfig getConfig(NBCommandParams params) {
return new RCurveConfig(params);
}
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) {
SimFrame<RCurveFrameParams> last = journal.last();
int nextStep = last.params().step() +1;
if (nextStep<=config.steps()) {
return new RCurveFrameParams(config.rateForStep(nextStep),nextStep,"Advancing to step " + nextStep);
if (nextStep<=config.maxstep()) {
return new RCurveFrameParams(config.rateForStep(nextStep),nextStep,config.maxstep(),"Advancing to step " + nextStep);
} else {
return null;
}
@ -69,4 +75,11 @@ public class RCurvePlanner extends SimFramePlanner<RCurveConfig, RCurveFramePara
public void applyParams(RCurveFrameParams params, Activity flywheel) {
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.core.lifecycle.scenario.container.ContainerActivitiesController;
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 org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
@ -32,12 +34,13 @@ import java.io.PrintWriter;
* @param <C>
* The configuration type for the planner
*/
public abstract class SimFramePlanner<C,P extends Record> {
private final Logger logger = LogManager.getLogger(SimFramePlanner.class);
public abstract class SimFramePlanner<C,P extends Record> extends NBBaseComponent {
protected final Logger logger = LogManager.getLogger(SimFramePlanner.class);
protected final C config;
protected final SimFrameJournal<P> journal;
public SimFramePlanner(NBCommandParams analyzerParams) {
public SimFramePlanner(NBBaseComponent parent, NBCommandParams analyzerParams) {
super(parent, NBLabels.forKV());
this.config = getConfig(analyzerParams);
this.journal = initJournal();
}
@ -69,11 +72,11 @@ public abstract class SimFramePlanner<C,P extends Record> {
stdout.println(frameParams);
applyParams(frameParams,flywheel);
capture.startWindow();
capture.awaitSteadyState();
// applyParams(frameParams,flywheel);
// capture.restartWindow();
//// controller.waitMillis(500);
// capture.awaitSteadyState();
if (this instanceof HoldAndSample has) {
has.holdAndSample(capture);
} else {
capture.awaitSteadyState();
}
capture.stopWindow();
journal.record(frameParams, capture.last());
stdout.println(capture.last());

View File

@ -178,9 +178,9 @@ public class StabilityDetector implements Runnable {
double value = source.getAsDouble();
apply(value);
double stabilityFactor = computeStability();
// if (Double.isNaN(stabilityFactor)) {
// System.out.println("NaN stability factor");
// }
if (Double.isNaN(stabilityFactor)) {
throw new RuntimeException("NaN stability factor:" + this);
}
if (stabilityFactor > threshold) {
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
# 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')
# use Stringify() to visualize the value of numeric array types