Commit graph

2074 commits

Author SHA1 Message Date
10fa0aaa79 Scheduler-test: design problems impeding clean test-setup
Encountering ''just some design problems related to the test setup,''
which however turn out hard to overcome. Seems that, in my eagerness
to create a succinct and clear presentation of the test, I went into
danger territory, overstretching the abilities of the C++ language.

After working with a set of tools created step by step over an extended span of time,
''for me'' the machinations of this setup seem to be reduced to flipping a toggle
here and there, and I want to focus these active parts while laying out this test.
''This would require'' to create a system of nested scopes, while getting more and more
specific gradually, and moving to the individual case at question; notably any
clarification and definition within those inner focused contexts would have to be
picked up and linked in dynamically.

Yet the C++ language only allows to be ''either'' open and flexible towards
the actual types, or ''alternatively'' to select dynamically within a fixed
set of (virtual) methods, which then must be determined from the beginning.
It is not possible to tweak and adjust base definitions after the fact,
and it is not possible to fill in constant definitions dynamically
with late binding to some specific implementation type provided only
at current scope.

Seems that I am running against that brick wall over and over again,
piling up complexities driven by an desire for succinctness and clarity.

Now attempting to resolve this quite frustrating situation...
- fix the actual type of the TestChainLoad by a typedef in test context
- avoid the definitions (and thus the danger of shadowing)
  and use one `testSetup()` method to place all local adjustments.
2024-04-08 03:54:00 +02:00
d47f24d745 Scheduler-test: reorganise test-setup in Stress-test-rig
With the addition of a second tool `bench::ParameterRange`,
the setup of the test-context for measurement became confusing,
since the original scheme was mostly oriented towards the
''breaking point search.''

On close investigation, I discovered several redundancies, and
moreover, it seems questionable to generate an ''adapted-schedule''
for the Parameter-Range measurement method, which aims at overloading
the scheduler and watch the time to resolve such a load peak.

The solution entertained here is to move most of the schedule-ctx setup
into the base implementation, which is typically just inherited by the
actual testcase setup. This allows to leave the decision whether to build
an adapted schedule to the actual tool. So `bench::BreakingPoint` can
always setup the adapted schedule with a specific stress-factor,
while `bench::ParameterRange` by default does nothing in this
respect, and thus the `ScheduleCtx` will provide a default schedule
with the configured level-duration (and the default for this is
lowered to 200µs here).

In a similar vein, calculation of result data points from the raw measurement
is moved over into the actual test setup, thereby gaining flexibility.
2024-04-08 03:54:00 +02:00
0d3dc91584 Scheduler-test: rework ParameterRange tool for data visualisation
Rework the existing tool to capture the measurement series
into the newly integrated CSV-based data storage, allowing
to turn the results into a Gnuplot-visualisation.
2024-04-04 02:52:57 +02:00
55f8f229f1 Library: customisation of the generated Gnuplot diagram 2024-04-03 19:31:00 +02:00
96202f845a Library: example to schow the secondary diagram
...which is added automatically whenever additional data columns are present

Result can only be verified visually

 * the upper diagram should show the first fibonacci points
 * a (correct) linear regression line should be overlayed in red
 * below, a secondary diagram should appear, with aligned axis
 * the row "one" in this diagram should be shown as impulses
 * the further rows "two" and "three" should be drawn as
   green points, using the secondary Y-axis (values 100-250)
 * Gnuplot can handle missing data points
2024-04-03 00:29:27 +02:00
c997fc2341 Library: develop Gnuplot code for flexible scatter-regression
The idea is to build the Layout-branching into the generated Gnuplot script,
based on the number of data columns detected. If there is at least one further
data column, then the "mulitplot" layout will be used to feature this
additional data in a secondary diagram below with aligned axis;
if more than one additional data column is present, all further
visualisation will draw points, using the secondary Y-axis

Moreover, Gnuplot can calculate the linear regresssion line itself,
and the drawing will then be done using an `arrow` command,
defining a function regLine(x) based on the linear model.
2024-04-02 23:59:59 +02:00
f37e651b61 Library: add some mutual integration between DataFile and CSVData
...both are related to CSV, and it is conceivable
to create inline CSVData in a test case to populate a DataFile
2024-04-02 21:18:23 +02:00
03c2191649 Library: rearrange support for CSV notation
- `forElse` belongs to the metaprogramming utils

- have a CSVLine, which is a string with custom appending mechanism

- this in turn allows CSVData to accept arbitrary sized tuples,
  by rendering them into CSVLine
2024-04-01 22:33:55 +02:00
fc084c1ca5 Library: find a better organisation of entrance points to plotting
The intention is to create a library of convenient building blocks;
providing a visualisation should be as simple as invoking a free function
with CSV data, yet with the ability to tweak some lables or display
variations if desired.

This can be achieved by..
 * having a series of ready-made standard visualisations
 * expose a function call for each, accepting a data-context builder
 * provide secondary convenience shortcuts, which add some of the expected bindings
 * notably a shortcut is provided to take the data as CSV-string
 * augmented by a wrapper/builder to allow defining data points inline
2024-03-31 19:12:43 +02:00
a6084bd2d6 Library: implement generation of a simple data visualisation
CSV data -> Gnuplot script
2024-03-31 01:46:12 +01:00
db0838ddcc Library: draft invocation framework for generating a Gnuplot
Deliberately keep it unstructured and add dedicated functions
for each new emerging use case; hopefully some commen usage scheme
will emerge over time.

 * Data is to be handed in as an iterator over CSV-strings.
 * will have to find out about additional parametrisation on a case-by-case base
2024-03-31 01:45:23 +01:00
f627d42b6e Library: develop a suitable gnuplot layout and styling
The default visuals of gnuplot are simple,
yet tend to look cluttered and are not well suited for our purpose

We need the following presentation
 * a scatter diagram with a regression line
 * additionally a secondary diagram stacked below, with aligned axis

Thus 🠲 R-T-F-M
 * The [http://gnuplot.info/ Gnuplot docu] is exhaustive, yet hard to get into
 * Helpful was this collection of [http://gnuplotting.org/ example solutions for scientific plots]
 * and — Stackoverflow...
2024-03-30 04:08:45 +01:00
918f96bb6f Library: complete ETD data-source binding and test (closes #1359)
A minimalist `TextTemplate` engine is available for in-project use.

 * supports only the bare minimum of features (no programming language)
   * substitution of `${placeholder}` by key-name data access
   * conditional section `${if key}...${end if}`
   * iteration over a data sequence
 * other then most solutions available as library,
   this implementation does **not require** a specific data type,
   nor does it invent a dynamic object system or JSON backend;
   rather, a generic ''Data Source Adapter'' is used, which can
   be specialised to access any kind of ''structured data''
 * the following `DataSource` specialisations are provided
   * `std::map<string,string>`
   * Lumiera »External Tree Description« (based on `GenNode`)
   * a string-based spec for testing
2024-03-28 03:18:02 +01:00
4c4ae0691c Library: verify DataSrc binding for Map 2024-03-28 03:14:21 +01:00
597d8191c7 Library: code the DataSource template
...turns out challenging, since our intention here
is borderline to the intended design of the Lumiera ETD.
It ''should work'' though, when combined with a Variant-visitor...
2024-03-27 04:07:55 +01:00
64f60356b7 Library: prepare for a ETD binding
Document existing data binding logic and investigate in detail
what must be done to enable a similar binding backed by Lumiera's ETD structures.
This analysis highlights some tricky aspects, which can be accommodated by
slight adjustments and generalisations in the `TextTemplate` implementation
 * `GenNode` is not structured string data, rather binary data
 * thus exposing a std::string_view is not adequate, requiring to
   pick up the result type from the actual data binding
 * moreover, to allow for arbitrary nested scopes, a back-pointer
   to the parent scope must be maintained, which requires stable memory locations.
   This can best be solved within the InstanceCore itself, which manages
   the actual hierarchy of data source references.
 * the existing code happens already to fulfil this requirement, but
   for sake of clarity, handling of such a nested scope is now extracted
   into a dedicated operation, to highlight the guaranteed memory layout.
2024-03-27 01:24:41 +01:00
c0439b265c Library: verify proper working of logic constructs
uncovers some minor implementation bugs, as can be expected...
2024-03-26 06:30:23 +01:00
4e26d655a8 Library: workaround for tricky problems with Template-Argument-Deduction
We use a DataSrc<DAT> template to access the actual data to be substituted.
However, when applying the Text-Template, we need to pick the right
specialisation, based on the type of the actual data provided.

Here we face several challenges:

 * Class-Template-Argument-Deduction starts from the *primary* template's constructors.
   Without that, the compiler will only try the copy constructor and will
   never see the constructors of partial specialisations.
   This can be fixed by providing a ''dummy constructor''.
 * The specifics of how to provide a custom CTAD deduction guide
   for a **nested template** are not well documented. I have found
   several bug reports, and seemingly one of these bugs failed my
   my various attempts. Moreover it is ''not clear if such a deduction
   guide can even be given outside of the class definition scope.''
   For the intended usage pattern this would be crucial, since users
   are expected to provide further specialisations of the DataSrc-template
 * Thus I resorted to the ''old school solution,'' which is to use
   a ''free builder function'' as an extension point. Thus users could
   provide further overloads for the `buildDataSrc()` function.
 * Unfortunately, SFINAE-Tricks are way more limited for function overload.
   Thus it seems impossible to have a generic and more specialised cases,
   unless all special cases are disjoint.

Thus the solution is far from perfect, ''yet for the current situation it seems
sufficient'' (and C++20 Concepts will greatly help to resolve this kind of problems)
2024-03-26 02:41:42 +01:00
a89e272e35 Library: supply a string-spec-binding for tests
...implemented by simply parsing the string into key=value pairs,
which are then stored into a shared map. The actual data binding
implementation can thus be inherited from the existing Map-binding
2024-03-25 18:26:17 +01:00
9b6fc3ebe5 Library: fix handling of escapes
While they were detected just fine, thy were passed-through
unaltered, which subverts the purpose of such an escape,
which is to allow for the tag syntax to be present in the
processed, substituted document (e.g. when generating a
shell script)

thus `\${escaped}` becomes `${escaped}`
2024-03-25 15:44:48 +01:00
c09f44e20f Library: complete implementation of Map-databinding
...using a ''special protocol'' to represent iterative data sequences
 * use an Index-Key with a CSV list of element prefixes
 * synthesise key-prefixes for each data element
 * perform lookup with the decorated key first

This allows to somehow ''emulate'' nested associations within a single, flat Map.
Obviously this is more like a proof-of-concept; actually the Map-databinding
is meant to handle the simple cases, where just placeholders are to be substituted.

The logic structures are much more relevant when binding to structural data,
most notably to the Lumiera _External Tree Description_ format, which is
used for model data and inter-layer communication.
2024-03-25 04:23:59 +01:00
58ffbac7f3 Library: implement logic-interpretation
- the basic interpretation of Action-tokens is already in place
 - add the interpretation of conditional and looping constructs
 - this includes helpers for
   * reset to another Action-token index
   * recursive interpretation of the next token
   * handling of nested loop evaluation context

In order to make this implementation compile, also the skeleton
of the Map-string-string data binding must be completed, including
a draft how to handle nested keys in a simple map
2024-03-25 03:30:16 +01:00
dd67b9f97b Library: cover some definition errors 2024-03-25 00:38:35 +01:00
20f2b1b90a Library: complete implementation of code generation
...including the handling of cross jumps / links
...verified by one elaborate example in the tests
2024-03-24 21:42:38 +01:00
aab446ce48 Library: further straighten iteration logic
playing the »fence post problem« the other way round
and abandoning the ''pull processing'' in favour of direct manipulation
leads to much clearer formulation of the code-generation logic
2024-03-24 15:51:38 +01:00
bc8e947f3c Library: remould compiler to active iteration
...turns out the ''pipeline design'' is not a good fit for the
Action compilation, since the compiler needs to refer to previous Actions;
better to let the compiler ''build'' the `ActionSeq`
2024-03-24 14:21:44 +01:00
b835d6a012 Library: get the template compiler basically operative
...implementation of bracketed constructs and cross references still omitted

...define a fairly elaborate test example for parsing
2024-03-24 00:48:04 +01:00
a9cbe7eb90 Library: define skeleton of TextTemplate compilation
...implemented as »custom processing layer« within a
demand-driven parsing pipeline, with the ability to
inject additional Action-tokens to represent the intermittent
constant text between tags; special handling to expose one
constant postfix after the last active tag.
2024-03-23 19:38:53 +01:00
5b53b53c4c Library: solution for ''trailing prefix'' in parser-context
* use a string-view embedded into the context-λ
 * on each match clip off some starting prefix from this string-view
2024-03-23 02:55:28 +01:00
c2df391f48 Library: draft how a pipelined-parser could work 2024-03-23 02:55:28 +01:00
2a60f77bdf Library: improve formulation of the parsing regexp
- allow additional leading and trailing whitespace within token
- more precise on the sequence of keywords
- clearer build-up of the regexp syntax
2024-03-23 02:55:28 +01:00
10bda3a400 Library: develop a token-parsing regular expression
oh my!
2024-03-23 02:55:28 +01:00
a2749adbc9 Library: also cover the smart-ptr usage variant
The way I've written this helper template, as a byproduct
it is also possible to maintain the back-refrence to the container
through a smart-ptr. In this case, the iterator-handle also manages
the ownership automatically.
2024-03-21 19:57:34 +01:00
f716fb0bee Library: build a helper to encapsulate container access by index
...mostly we want the usual convenient handling pattern for iterators,
but with the proviso actually to perform an access by subscript,
and the ability to re-set to another current index
2024-03-21 19:57:34 +01:00
76bd9ba6ce Library: establish evaluation and iteration on application 2024-03-21 19:57:34 +01:00
7893cc99c3 Library: further work out the framework for TextTemplate instantiation 2024-03-21 19:57:34 +01:00
d2dcf6c163 Library: draft the interpretation of a compiled TextTemplate
will use an iteration-pipeline, based on the »State Core« concept
2024-03-21 19:57:34 +01:00
5881b014fe Library: work out a treatment for text template substitution (see: #1359)
* establish the feature set to provide
 * choose scheme for runtime representation
 * break down analysis to individual parsing and execution steps
 * conclude which actions to conduct and the necessary data
 * derive the abstract binding API required
2024-03-21 19:57:34 +01:00
af1f549190 Library: Assessment and plan for a text templating engine
Conducted an extended investigation regarding text templating
and the library solutions available and still maintained today.

The conclusion is
 * there are some mature and widely used solutions available for C++
 * all of these are considered a mismatch for the task at hand,
   which is to generate Gnuplot scripts for test data visualisation

Points of contention
 * all solutions offer a massive feature set, oriented towards web content generation
 * all solutions provide their own structured data type or custom property-tree framework

**Decision** 🠲  better to write a minimalistic templating engine from scratch rather
2024-03-21 19:57:34 +01:00
d3fda114f8 Library: Research -- Gnuplot
Read the documentation and find out how to generate the kind of diagram
necessary for visualisation of Scheduler-Stress-Test observations.

I used to have basic Gnuplot knowledge, and thus had to find out about
- reading CSV
- supported diagram types
- layering and styling

Conclusion: will use Gnuplot and generate a script from Test code
2024-03-21 19:57:34 +01:00
aa93bf9285 Library: cover statistic functions and linear regression 2024-03-16 03:05:49 +01:00
599407deea Library: complete coverage of CSV data table including storage
also encompasses some coverage for the simplistic CSV format
implemented as storage backend for this data table
2024-03-15 02:45:45 +01:00
3b3600379a Library: introduce formating variants for decimal10
showDecimal -> decimal10 (maximal precision to survive round-trip through decimal representation=

showComplete -> max_decimal10 (enough decimal places to capture each possible distinct floating-point value)


Use these new functions to rewrite the format4csv() helper
2024-03-14 17:32:22 +01:00
4a8364e422 Library: extend the DataFile to allow using it without storage
...seems obvious and does not compromise the simplistic design...
...we do check the file path anyway, just need to add saveAs()...
2024-03-13 18:57:48 +01:00
1c2cbd4d47 Library: coverage for some filesystem convenience helpers
...created as a byproduct of the TempDir feature,
which in turn is required to do ''any'' meaningful unit-test
of filesystem related functionality.
2024-03-13 03:52:35 +01:00
a6aad5261c Library: complete and verify temp-dir helper
verify also that clean-up happens in case of exceptions thrown;
as an aside, add Macro to check for ''any'' exception and match
on something in the message (as opposed to just a Lumiera Exception)
2024-03-13 02:50:13 +01:00
18b1d37a3d Library: also create unique temporary files
...using the same method for sake of uniformity

Also move the permissions helpers to the file.hpp support functions
and setup a separate unit test for these
2024-03-12 22:54:05 +01:00
a1832b1cb9 Library: base implementation of temp-dir creation
Inspired by https://stackoverflow.com/a/58454949

Verified behaviour of fs::create_directory
 --> it returns true only if it ''indeed could create'' a new directory
 --> it returns false if the directory exists already
 --> it throws when some other obstacle shows up

As an aside: the Header include/limits.h could be cleaned up,
and it is used solely from C++ code, thus could be typed, namespaced etc.
2024-03-12 20:14:29 +01:00
b426ea4921 Library: simple default implementation for random sequences
Since this is a much more complicated topic,
for now I decided to establish two instances through global variables:
 * a sequence seeded with a fixed starting value
 * another sequence seeded from a true entropy source

What we actually need however is some kind of execution framework
to define points of random-seeding and to capture seed values for
reproducible tests.
2024-03-12 02:34:19 +01:00
7a3e4098c8 Library: some first thoughts regarding random number generation
Relying on random numbers for verification and measurements is known to be problematic.
At some point we are bound to control the seed values -- and in the actual
application usage we want to record sequence seeding in the event log.

Some initial thoughts regarding this intricate topic.
 * a low-ceremony drop-in replacement for rand() is required
 * we want the ability to pick-up and control each and every usage eventually
 * however, some usages explicitly require true randomness
 * the ability to use separate streams of random-number generation is desirable
2024-03-12 00:48:11 +01:00