diff --git a/doc/technical/howto/crackNuts.txt b/doc/technical/howto/crackNuts.txt index 875e92075..a8dfc92cf 100644 --- a/doc/technical/howto/crackNuts.txt +++ b/doc/technical/howto/crackNuts.txt @@ -191,7 +191,6 @@ apply functor to each tuple element:: - provided as `lib::meta::forEach` in 'lib/meta/tuple-helper.hpp - The design of the `DataTable` with CSV-Formatting is based on this technique, see 'lib/stat/data.hpp' - 'lib/iter-zip.hpp' uses this to construct a tuple-of-iterators -- 'test-rand-ontology.cpp' uses this in `manipulateFrame()` to accept an arbitrary number of input chains + unpack iterator into tuple:: Under controlled conditions this is possible (even while it seems like time travel from the runtime into diff --git a/tests/46node.tests b/tests/46node.tests index 7c58e7192..0a3f0c391 100644 --- a/tests/46node.tests +++ b/tests/46node.tests @@ -6,7 +6,7 @@ PLANNED "Proc Node basics" NodeBasic_test < using lib::zip; +using lib::izip; +using std::vector; namespace steam { @@ -69,6 +72,8 @@ namespace test { processing_generateFrame(); processing_generateMultichan(); + processing_duplicateMultichan(); + processing_manipulateMultichan(); processing_manipulateFrame(); processing_combineFrames(); } @@ -87,6 +92,7 @@ namespace test { generateFrame (buff, frameNr, flavour); CHECK ( buff->isSane()); + CHECK ( buff->isPristine()); CHECK (*buff == TestFrame(frameNr,flavour)); } @@ -102,19 +108,91 @@ namespace test { uint channels = 1 + rani(50); CHECK (1 <= channels and channels <= 50); - Buffer buffs[50]; + Buffer buff[50]; for (uint i=0; iisSane()); + CHECK (not buff[i]->isSane()); - generateMultichan (buffs[0], channels, frameNr, flavour); + generateMultichan (buff[0], channels, frameNr, flavour); for (uint i=0; iisSane()); - CHECK (*(buffs[i]) == TestFrame(frameNr,flavour+i)); + CHECK (buff[i]->isPristine()); + CHECK (*(buff[i]) == TestFrame(frameNr,flavour+i)); } } - /** @test function to apply a numeric computation to test data frames + + /** @test clone copy of multichannel test data */ + void + processing_duplicateMultichan() + { + size_t frameNr = defaultGen.u64(); + uint flavour = defaultGen.u64(); + uint channels = 1 + rani(50); + Buffer srcBuff[50]; + generateMultichan (srcBuff[0], channels, frameNr, flavour); + + Buffer clone[50]; + for (uint i=0; iisSane()); + + duplicateMultichan (clone[0],srcBuff[0], channels); + for (uint i=0; iisPristine()); + CHECK (*(clone[i]) == *(srcBuff[i])); + } + } + + + /** @test multichannel data hash-chain manipulation + * - use multichannel pseudo random input data + * - store away a clone copy before manipulation + * - the #manipulateMultichan() operates in-place in the buffers + * - each buffer has been marked with a new checksum afterwards + * - and each buffer now differs from original state + * - verify that corresponding data points over all channels + * have been linked by a hashcode-chain, seeded with the `param` + * and then consecutively hashing in data from each channel. + */ + void + processing_manipulateMultichan() + { + size_t frameNr = defaultGen.u64(); + uint flavour = defaultGen.u64(); + uint channels = 1 + rani(50); + Buffer buff[50], refData[50]; + generateMultichan (buff[0], channels, frameNr, flavour); + // stash away a copy of the test data for verification + duplicateMultichan(refData[0],buff[0], channels); + + for (uint c=0; cisPristine()); + + uint64_t param = defaultGen.u64(); + manipulateMultichan(buff[0], channels, param); + + const uint SIZ = buff[0]->data64().size(); + vector xlink(SIZ, param); // temporary storage for verifying the hash-chain + for (uint c=0; cisSane()); // checksum matches + CHECK (not buff[c]->isPristine()); // data was indeed changed + + CHECK (*(buff[c]) != *(refData[c])); + + for (auto& [i, link] : izip(xlink)) + { + auto const& refPoint = refData[c]->data64()[i]; + lib::hash::combine (link, refPoint); + CHECK (link != refPoint); + CHECK (link == buff[c]->data64()[i]); + } + } + } + + /** @test function to apply a numeric computation to test data frames; + * @remark here basically the same hash-chaining is used as for #manipulateMultichan, + * but only one hash-chain per data point is used and output is written to a different buffer. */ void processing_manipulateFrame() diff --git a/tests/core/steam/engine/test-rand-ontology.cpp b/tests/core/steam/engine/test-rand-ontology.cpp index 29c74d63a..ae3835d3e 100644 --- a/tests/core/steam/engine/test-rand-ontology.cpp +++ b/tests/core/steam/engine/test-rand-ontology.cpp @@ -77,6 +77,47 @@ namespace test { new(buffArry+i) TestFrame{uint(frameNr), flavour+i}; } + /** + * @param chanCnt size of the array of frames to clone + * @param inArry pointer to storage holding a TestFrame[chanCnt] + * @param outArry pointer to allocated storage sufficient to hold a clone copy of these + */ + void + duplicateMultichan (TestFrame* outArry, TestFrame* inArry, uint chanCnt) + { + REQUIRE (inArry); + REQUIRE (outArry); + for (uint i=0; idata64().size(); + for (uint i=0; i - - - +

nach dem Setzen eines neuen Label-Texts müssen wir die Länge des IDLabel erneut ausmessen, und dazu müssen alle seine Komponenten vorrübergehend visible() gesetzt werden; hatte bisher darauf gesetzt, daß der size-constraint-Algo dann von selber wieder auf den richtigen Status kommt... @@ -20496,9 +20494,7 @@ - - - +

also bitte nicht mit statischen Globals arbeiten! @@ -20944,9 +20940,7 @@ - - - +

denn, ohne daß dies nach Außen sichtbar wäre, ist TrackBody selbst die ViewHookable-Implementierung @@ -21388,9 +21382,7 @@ - - - +

denn wenn alle Methoden auf dem TrackBody liegen, kann man diese auch von außen direkt aufrufen @@ -22490,9 +22482,7 @@ - - - +

  • @@ -24060,9 +24050,7 @@ - - - +

    wenn man die mark "test"-Nachricht an eine Timeline schickt, die vorher per Population "reingeschossen" wurde, ohne sie jemals im UI anzuzeigen. Das heißt, im Moment haben wir da definitiv eine offene Flanke -- allerdings ist das ganze Thema auch bisher ehr ein draft @@ -27442,9 +27430,7 @@ - - - +

    die konkrete Aufgabe ist mit FreeCAD elegant
    — aber Resultate sind schwer zugänglich — @@ -36016,9 +36002,7 @@ - - - +

    A Gtk::UIManager constructs a user interface (menus and toolbars) from one or more UI definitions, @@ -39420,9 +39404,7 @@ - - - +

    sobald man globale Screen-Koordinaten für die Delta-Berechnung verwendet; der Button klebt jetzt exakt an der Stelle, an der zuerst geklickt wurde @@ -40771,9 +40753,7 @@ - - - +

    mein Anspruch ist, hier eine absolut fehlerfrei arbeitende Komponente zu schreiben @@ -41541,9 +41521,7 @@ - - - +

    warum auch nicht? @@ -42059,9 +42037,7 @@ - - - +

    Vorsicht: Ergebnis-Faktor kann trotzdem giftig sein @@ -42363,9 +42339,7 @@ - - - +

    Der Rechenweg ist hier eine »Einbahnstraße« : durch einen Kniff ist es gelungen die Quatisierung zu berechnen Metrik ⟼ pxWidth. Aber die Umkehrfunktion können wir nicht berechnen, weil es in der Berechnung zu einem Überlauf kommt. Daher können wir die Fehler-Korrektur nicht einfach ausrechnen, weil wir nicht einfach von einen Pixel-Δ auf ein Metrik-Δ zurückrechnen können @@ -42767,9 +42741,7 @@ - - - +

    bleibt noch der Belang: die Duration soll hier auf µ-Tick aufgerundet  werden @@ -87673,18 +87645,47 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + + + +

    + Ich hab das mit der »Domain-Onology« bisher nur auf einem abstrakt-logischen Level konzipiert — nach dem „müßte so hinhauen“-Schema. Auf dem Weg bin ich jetzt so weit, daß ich sehe, was für elementare Berechnugs-Primitive nützlich sein könnten. Also implementiert man die mal und sieht dann weiter.... +

    +

    + »Dann weiter« läuft darauf hinaus, daß eine »Dummy-Media-Processing-Library« entsteht. Das heißt, die wird dann auch ihre eigene Beschreibung von Datentypen haben, wie.z.B. Anzahl Kanäle. Aktuell sind das erst mal Parameter für TestFrame, aber das würde dann längerfristig auf sowas hinauslaufen wie einen StreamType-ImplType. +

    +

    + +

    +

    + Gut möglich, daß man das überhaupt erst im nächsten Vertical-Slice wird zusammenschalten können +

    + +
    + +
    + - - + + - - + + + + + + + + + + + @@ -93390,7 +93391,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + @@ -93399,14 +93400,14 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

    + - + + - - - + @@ -93418,6 +93419,26 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    + + + + + + + + + + + + +

    + ⟹ als nächstes muß aus aus den Manipulationen eine richtige Funktion gemacht werden +

    + + +
    +
    +
    @@ -93644,16 +93665,44 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - + + - + + + + +

    + Es geht hier zunächst darum, die eigentliche Rechen-Funktionalität bereitzustellen. Erst in weiteren Schritten werde ich dann daraus eine Test-Manipulations-Umgebung aufmachen, die diese Funktionalität in sinnvolle Operationen und Verknüfpungen verpackt. Was im Moment die Parameter für TestFrame sind, könnte mal die Emulation eines StreamType-ImplType werden +

    + +
    - + + + + + + + + + +

    + Stelle eine Hash-Kette her, die jeweils „quer“ über die Datenpunkte in benachbarten Frames läuft. Ein »param«-Wert dient als Seed und könnte später vom Node-Hash genommen werden. Dann wird der jeweilige original-Datenwert eingehasht und durch das Ergebnis der Kette ersetzt. +

    + + +
    +
    + + + +
    @@ -93668,9 +93717,9 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - - - + + + @@ -93683,6 +93732,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    +