Chain-Load: mapping helper for control-rules

writing a control-value rule for topology generation typically
involves some modulus and then arthmetic operations to map
only part of the value range to the expected output range.

These calculations are generic, noisy and error-prone.
Thus introduce a helper type, which allows the client just
to mark up the target range of the provided value to map and
transform to the actually expected result range, including some
slight margin to absorb rounding errors. Moreover, all calculations
done in double, to avoid the perils of unsigned-wrap-around.
This commit is contained in:
Fischlurch 2023-11-16 21:38:06 +01:00
parent cc56117574
commit 686b98ff1e
2 changed files with 81 additions and 7 deletions

View file

@ -88,6 +88,7 @@
#include "lib/iter-explorer.hpp"
#include "lib/format-cout.hpp"
#include "lib/dot-gen.hpp"
#include "lib/util.hpp"
#include <boost/functional/hash.hpp>
#include <functional>
@ -110,7 +111,9 @@ namespace test {
// using lib::time::FSecs;
// using lib::time::Offset;
// using lib::meta::RebindVariadic;
using util::min;
using util::max;
using util::limited;
using util::unConst;
using util::toString;
using util::showHashLSB;
@ -125,9 +128,38 @@ namespace test {
namespace { // Default definitions for topology generation
const size_t DEFAULT_FAN = 16;
const size_t DEFAULT_SIZ = 256;
const double CAP_EPSILON = 0.001; ///< tiny bias to absorb rounding problems
}
/**
* Helper to cap and map to a value range.
*/
struct Cap
{
double lower{0};
double value{0};
double upper{1};
Cap(int i) : value(i){ }
Cap(size_t s) : value(s){ }
Cap(double d) : value{d}{ }
size_t
mapped (size_t scale)
{
if (value==lower)
return 0;
value -= lower;
value /= upper-lower;
value *= scale;
value += CAP_EPSILON;
value = limited (size_t(0), value, scale);
return size_t(value);
}
};
/**
* A Generator for synthetic Render Jobs for Scheduler load testing.
@ -225,7 +257,7 @@ namespace test {
private:
using NodeTab = typename Node::Tab;
using NodeStorage = std::array<Node, numNodes>;
using CtrlRule = std::function<size_t(size_t, double)>;
using CtrlRule = std::function<Cap(size_t, double)>;
std::unique_ptr<NodeStorage> nodes_;
@ -256,6 +288,28 @@ namespace test {
/* ===== topology control ===== */
TestChainLoad&&
seedingRule (CtrlRule r)
{
seedingRule_ = r;
return move(*this);
}
TestChainLoad&&
expansionRule (CtrlRule r)
{
expansionRule_ = r;
return move(*this);
}
TestChainLoad&&
reductionRule (CtrlRule r)
{
reductionRule_ = r;
return move(*this);
}
/**
* Use current configuration and seed to (re)build Node connectivity.
*/
@ -283,7 +337,8 @@ namespace test {
};
auto apply = [&](CtrlRule& rule, Node* n)
{
return rule (n->hash, height(level));
Cap param = rule (n->hash, height(level));
return param.mapped (maxFan);
};
addNode(); // prime next with root node
@ -352,12 +407,11 @@ namespace test {
Code TOP {"shape=box, style=rounded"};
Code DEFAULT{};
auto nodeID = [&](Node& nn){ return size_t(&nn - &nodes_->front()); };
auto nodeID = [&](Node& n){ return size_t(&n - &nodes_->front()); };
// prepare time-level zero
size_t level(0);
auto timeLevel = scope(level);
layers += timeLevel.rank("min ");
auto timeLevel = scope(level).rank("min ");
for (Node& n : allNodes())
{
@ -372,13 +426,14 @@ namespace test {
if (level != n.level)
{// switch to next time-level
layers += timeLevel;
++level;
ENSURE (level == n.level);
timeLevel = scope(level).rank("same");
layers += timeLevel;
}
timeLevel.add (node(i));
}
layers += timeLevel; // close last layer
// combine and render collected definitions as DOT-code
return digraph (nodes, layers, topology);

View file

@ -95887,6 +95887,16 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699805813117" ID="ID_593874916" MODIFIED="1699805822698" TEXT="buildTopology: Grundstruktur">
<icon BUILTIN="pencil"/>
</node>
<node BACKGROUND_COLOR="#eee5c3" COLOR="#990000" CREATED="1700163498328" ID="ID_14989689" MODIFIED="1700163505288" TEXT="CtrlRules + Infrastruktur">
<icon BUILTIN="flag-yellow"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700163679808" ID="ID_310818837" MODIFIED="1700166673231" TEXT="Hilfsmittel: Cap(lower, value, upper)">
<linktarget COLOR="#fdedce" DESTINATION="ID_310818837" ENDARROW="Default" ENDINCLINATION="174;13;" ID="Arrow_ID_184825307" SOURCE="ID_1054737506" STARTARROW="None" STARTINCLINATION="247;-214;"/>
<icon BUILTIN="pencil"/>
<node CREATED="1700163740200" ID="ID_499899287" MODIFIED="1700163769112" TEXT="greift ein beliebiges Intervall heraus"/>
<node CREATED="1700163771644" ID="ID_1990055220" MODIFIED="1700163816450" TEXT="transformiert per double-Arrithmetik"/>
<node CREATED="1700163817537" ID="ID_1890257970" MODIFIED="1700163833752" TEXT="kappt dann auf [0 ... maxFan]"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699746891934" ID="ID_1003055056" MODIFIED="1699803875494" TEXT="Node">
@ -96008,12 +96018,21 @@ Date:&#160;&#160;&#160;Thu Apr 20 18:53:17 2023 +0200<br/>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699805890752" ID="ID_604823204" MODIFIED="1699827731274" TEXT="Limitierungen einhalten">
<icon BUILTIN="pencil"/>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1700163524509" ID="ID_1054737506" MODIFIED="1700166665465" TEXT="Auswertung der CtrlRules sicher handhaben">
<arrowlink COLOR="#fdedce" DESTINATION="ID_310818837" ENDARROW="Default" ENDINCLINATION="174;13;" ID="Arrow_ID_184825307" STARTARROW="None" STARTINCLINATION="247;-214;"/>
<icon BUILTIN="pencil"/>
<node CREATED="1700163554337" ID="ID_467387724" MODIFIED="1700163567392" TEXT="diverse Fallen hier">
<icon BUILTIN="clanbomber"/>
</node>
<node CREATED="1700163568492" ID="ID_1902020306" MODIFIED="1700163589018" TEXT="unsigned-wrap-around"/>
<node CREATED="1700163611881" ID="ID_1655584485" MODIFIED="1700163625384" TEXT="numerische Probleme"/>
</node>
</node>
</node>
</node>
<node BACKGROUND_COLOR="#eef0c5" COLOR="#990000" CREATED="1699971822836" ID="ID_1118263931" MODIFIED="1700156360589" TEXT="Diagnostik">
<icon BUILTIN="pencil"/>
<node COLOR="#338800" CREATED="1699972014017" FOLDED="true" ID="ID_1464042796" MODIFIED="1700156443450" TEXT="Topologie sichtbar machen">
<node COLOR="#338800" CREATED="1699972014017" FOLDED="true" ID="ID_1464042796" MODIFIED="1700159727325" TEXT="Topologie sichtbar machen">
<linktarget COLOR="#62819c" DESTINATION="ID_1464042796" ENDARROW="Default" ENDINCLINATION="21;-256;" ID="Arrow_ID_596151514" SOURCE="ID_1991398605" STARTARROW="None" STARTINCLINATION="787;55;"/>
<icon BUILTIN="button_ok"/>
<node COLOR="#435e98" CREATED="1699972026007" ID="ID_551004748" MODIFIED="1700105381375" TEXT="Idee: DOT generieren (Graphviz)">