diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/CMD_findmax.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/CMD_findmax.java index 7afa39cc5..f1e29c9ea 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/CMD_findmax.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/CMD_findmax.java @@ -78,16 +78,10 @@ public class CMD_findmax extends NBBaseCommand { throw new RuntimeException("Unsupported optimization type: " + findmaxConfig.optimization_type()); } - SimFrameCapture capture = new SimFrameValueData(flywheel); FindmaxFrameFunction frameFunction = new FindmaxFrameFunction(controller, findmaxConfig, flywheel, capture, journal, model); - double[] initialPoint = {findmaxConfig.base_value()}; - double result = frameFunction.value(initialPoint); - while (result != 0.0d) { - result = frameFunction.nextStep(); - } - - SimFrame best = frameFunction.journal().bestRun(); + FindmaxAnalyzer analyzer = new FindmaxAnalyzer(frameFunction, findmaxConfig); + SimFrame best = analyzer.analyze(); stdout.println("Best Run:\n" + best); return best.params(); } diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/FindmaxAnalyzer.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/FindmaxAnalyzer.java new file mode 100644 index 000000000..fbb66e2a2 --- /dev/null +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/FindmaxAnalyzer.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2024 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.optimizers.findmax; + +import io.nosqlbench.scenarios.simframe.planning.SimFrame; +import io.nosqlbench.scenarios.simframe.planning.SimFrameFunctionAnalyzer; + +import java.util.Comparator; + +import static io.nosqlbench.virtdata.core.bindings.VirtDataLibrary.logger; + +public class FindmaxAnalyzer implements SimFrameFunctionAnalyzer { + private final FindmaxFrameFunction function; + private final FindmaxConfig config; + + public FindmaxAnalyzer(FindmaxFrameFunction function, FindmaxConfig config) { + this.function = function; + this.config = config; + } + public SimFrame analyze() { + double[] initialPoint = {config.base_value()}; + double result = function.value(initialPoint); + while (result != 0.0d) { + result = nextStep(); + } + return function.journal().bestRun(); + } + + public double nextStep() { + double newValue; + SimFrame last = function.journal().last(); + SimFrame best = function.journal().bestRun(); + if (best.index() == last.index()) { // got better consecutively + newValue = last.params().paramValues()[0] + config.step_value(); + config.setStep_value(config.step_value() * config.value_incr()); + } else if (best.index() == last.index() - 1) { + // got worse consecutively, this may be collapsed out since the general case below covers it (test first) + if (((last.params().paramValues()[0] + config.step_value()) - + (best.params().paramValues()[0] + config.step_value())) <= config.step_value()) { + logger.info("could not divide search space further, stop condition met"); + return 0; + } else { + newValue = best.params().paramValues()[0] + config.step_value(); + config.setSample_time_ms(config.sample_time_ms() * config.sample_incr()); + config.setMin_settling_ms(config.min_settling_ms() * 4); + } + } else { // any other case + // find next frame with higher rate but lower value, the closest one by rate + SimFrame nextWorseFrameWithHigherRate = function.journal().frames().stream() + .filter(f -> f.value() < best.value()) + .filter(f -> f.params().paramValues()[0] + config.step_value() > (best.params().paramValues()[0] + config.step_value())) + .min(Comparator.comparingDouble(f -> f.params().paramValues()[0] + config.step_value())) + .orElseThrow(() -> new RuntimeException("inconsistent samples")); + if ((nextWorseFrameWithHigherRate.params().paramValues()[0] + config.step_value() - + best.params().paramValues()[0] + config.step_value()) > config.step_value()) { + newValue = best.params().paramValues()[0] + config.step_value(); + config.setSample_time_ms(config.sample_time_ms() * config.sample_incr()); + config.setMin_settling_ms(config.min_settling_ms() * 2); + } else { + logger.info("could not divide search space further, stop condition met"); + return 0.0d; + } + } + double[] point = {newValue}; + return function.value(point); + } +} diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/FindmaxFrameFunction.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/FindmaxFrameFunction.java index 35ce2fb55..b1f7ec33b 100644 --- a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/FindmaxFrameFunction.java +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/optimizers/findmax/FindmaxFrameFunction.java @@ -21,13 +21,8 @@ import io.nosqlbench.engine.api.activityapi.core.RunState; import io.nosqlbench.engine.core.lifecycle.scenario.container.ContainerActivitiesController; import io.nosqlbench.scenarios.simframe.capture.SimFrameCapture; import io.nosqlbench.scenarios.simframe.capture.SimFrameJournal; -import io.nosqlbench.scenarios.simframe.planning.SimFrame; import io.nosqlbench.scenarios.simframe.planning.SimFrameFunction; -import java.util.Comparator; - -import static io.nosqlbench.virtdata.core.bindings.VirtDataLibrary.logger; - public class FindmaxFrameFunction implements SimFrameFunction { private final Activity flywheel; @@ -74,45 +69,6 @@ public class FindmaxFrameFunction implements SimFrameFunction { return journal.last().value(); } - public double nextStep() { - double newValue; - SimFrame last = journal.last(); - SimFrame best = journal.bestRun(); - if (best.index() == last.index()) { // got better consecutively - newValue = last.params().paramValues()[0] + settings.step_value(); - settings.setStep_value(settings.step_value() * settings.value_incr()); - } else if (best.index() == last.index() - 1) { - // got worse consecutively, this may be collapsed out since the general case below covers it (test first) - if (((last.params().paramValues()[0] + settings.step_value()) - - (best.params().paramValues()[0] + settings.step_value())) <= settings.step_value()) { - logger.info("could not divide search space further, stop condition met"); - return 0; - } else { - newValue = best.params().paramValues()[0] + settings.step_value(); - settings.setSample_time_ms(settings.sample_time_ms() * settings.sample_incr()); - settings.setMin_settling_ms(settings.min_settling_ms() * 4); - } - } else { // any other case - // find next frame with higher rate but lower value, the closest one by rate - SimFrame nextWorseFrameWithHigherRate = journal.frames().stream() - .filter(f -> f.value() < best.value()) - .filter(f -> f.params().paramValues()[0] + settings.step_value() > (best.params().paramValues()[0] + settings.step_value())) - .min(Comparator.comparingDouble(f -> f.params().paramValues()[0] + settings.step_value())) - .orElseThrow(() -> new RuntimeException("inconsistent samples")); - if ((nextWorseFrameWithHigherRate.params().paramValues()[0] + settings.step_value() - - best.params().paramValues()[0] + settings.step_value()) > settings.step_value()) { - newValue = best.params().paramValues()[0] + settings.step_value(); - settings.setSample_time_ms(settings.sample_time_ms() * settings.sample_incr()); - settings.setMin_settling_ms(settings.min_settling_ms() * 2); - } else { - logger.info("could not divide search space further, stop condition met"); - return 0.0d; - } - } - double[] point = {newValue}; - return value(point); - } - public SimFrameJournal journal() { return journal; } diff --git a/nbr/src/main/java/io/nosqlbench/scenarios/simframe/planning/SimFrameFunctionAnalyzer.java b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/planning/SimFrameFunctionAnalyzer.java new file mode 100644 index 000000000..f4cb0d13a --- /dev/null +++ b/nbr/src/main/java/io/nosqlbench/scenarios/simframe/planning/SimFrameFunctionAnalyzer.java @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024 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; + +public interface SimFrameFunctionAnalyzer { +}