From ae89831275111973526ec6b00aba4bbdeb33adfb Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Tue, 29 Aug 2023 04:19:19 +0200 Subject: [PATCH] Activity-Lang: wire Job invocation in the activity::Term builder --- .../mobject/session/sess-manager-impl.cpp | 8 +- src/vault/gear/activity-term.hpp | 28 ++- src/vault/gear/activity.hpp | 10 +- src/vault/gear/job.h | 4 + src/vault/gear/scheduler-diagnostics.hpp | 1 + src/vault/gear/scheduler-frontend.hpp | 3 +- tests/vault/gear/scheduler-activity-test.cpp | 2 +- wiki/thinkPad.ichthyo.mm | 234 ++++++------------ 8 files changed, 115 insertions(+), 175 deletions(-) diff --git a/src/steam/mobject/session/sess-manager-impl.cpp b/src/steam/mobject/session/sess-manager-impl.cpp index 2713db52f..a4a183ec0 100644 --- a/src/steam/mobject/session/sess-manager-impl.cpp +++ b/src/steam/mobject/session/sess-manager-impl.cpp @@ -49,6 +49,7 @@ #include "common/query.hpp" #include +#include @@ -77,9 +78,8 @@ namespace session { } catch (...) { - ERROR (progress, "Unrecoverable Failure while creating the empty default session."); - throw lumiera::error::Fatal ( "Failure while creating the basic session object. System halted." - , LERR_(CREATE_SESSION)); + ERROR (progress, "Unrecoverable Failure while creating the empty default session. System halted."); + std::terminate(); } @@ -295,7 +295,7 @@ namespace session { * to several files (master file and edl files) */ void - SessManagerImpl::save (string stnapshotID) + SessManagerImpl::save (string snapshotID) { UNIMPLEMENTED ("save session (serialised)"); /////////////////////////////////////////////////TODO: need lock? diff --git a/src/vault/gear/activity-term.hpp b/src/vault/gear/activity-term.hpp index f6959686d..fbfa72518 100644 --- a/src/vault/gear/activity-term.hpp +++ b/src/vault/gear/activity-term.hpp @@ -60,7 +60,8 @@ namespace vault{ namespace gear { - using lib::time::Time;////////////WIP + using lib::time::Time; + using lib::time::TimeValue; // using util::isnil; // using std::string; using std::move; @@ -93,6 +94,8 @@ namespace gear { explicit Term (AllocHandle&& allocHandle, Template kind, Time start, Time after, Job job) : alloc_{move (allocHandle)} + , invoke_{setupInvocation (job)} + , post_{setupPost (start,after, invoke_)} { } // virtual std::string @@ -112,6 +115,29 @@ namespace gear { REQUIRE (post_, "Activity Term not yet fully configured"); return *post_; } + + private: + Activity* + setupInvocation (Job& job) + { + Activity& feed1 = alloc_.create (job.parameter.invoKey.code.w1 + ,job.parameter.invoKey.code.w2); + Activity& feed2 = alloc_.create (Activity::FEED); ///////////////////////////////////////TICKET #1295 : rework Job parameters to accommodate input / output info required for rendering + feed1.next = &feed2; + + JobClosure* functor = static_cast (job.jobClosure); ////////////////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs) + REQUIRE (functor); + Activity& invo = alloc_.create (*functor + , Time{TimeValue{job.parameter.nominalTime}} + , feed1); ///////////////////////////////////////////TICKET #1287 : get rid of C-isms in Job descriptor + return & invo; + } + + Activity* + setupPost (Time start, Time after, Activity* followUp) + { + return & alloc_.create (start,after,followUp); + } }; diff --git a/src/vault/gear/activity.hpp b/src/vault/gear/activity.hpp index ddf999063..885d68c5e 100644 --- a/src/vault/gear/activity.hpp +++ b/src/vault/gear/activity.hpp @@ -242,8 +242,8 @@ namespace gear { /** Payload data to provide */ struct Feed { - size_t one; - size_t two; + uint64_t one; + uint64_t two; }; /** Timing observation to propagate */ @@ -320,7 +320,7 @@ namespace gear { /* ==== special case initialisation ==== */ - Activity (size_t o1, size_t o2) noexcept + Activity (uint64_t o1, uint64_t o2) noexcept : Activity{FEED} { data_.feed.one = o1; @@ -437,8 +437,8 @@ namespace gear { JobClosure& functor = static_cast (*data_.invocation.task); /////////////////////TICKET #1287 : fix actual interface down to JobFunctor (after removing C structs) lumiera_jobParameter param; param.nominalTime = _raw(Time{data_.invocation.time}); - param.invoKey.part.a = next->data_.feed.one; - param.invoKey.part.b = next->data_.feed.two; + param.invoKey.code.w1 = next->data_.feed.one; + param.invoKey.code.w2 = next->data_.feed.two; //////////////////////////////////////////////////////////////////////////////////TICKET #1295 : rework Job parameters to accommodate input / output info required for rendering try { functor.invokeJobOperation (param); diff --git a/src/vault/gear/job.h b/src/vault/gear/job.h index 308e31dd6..2c7df501d 100644 --- a/src/vault/gear/job.h +++ b/src/vault/gear/job.h @@ -117,6 +117,10 @@ union InvocationInstanceID struct { int32_t a,b; int64_t t; } part; + struct { + uint64_t w1; + uint64_t w2; + } code; }; diff --git a/src/vault/gear/scheduler-diagnostics.hpp b/src/vault/gear/scheduler-diagnostics.hpp index 00b519b52..add74d70f 100644 --- a/src/vault/gear/scheduler-diagnostics.hpp +++ b/src/vault/gear/scheduler-diagnostics.hpp @@ -27,6 +27,7 @@ ** This allows to verify the operation of the scheduler from within unit-tests; ** typically doing so incurs a performance overhead. ** + ** @deprecated 8/23 obsoleted by rework for »Playback Vertical Slice« //////////////////////////////////TICKET #1228 ** @see SchedulerFrontend ** @see scheduler-interface-test.cpp ** @see EngineServiceMock diff --git a/src/vault/gear/scheduler-frontend.hpp b/src/vault/gear/scheduler-frontend.hpp index 7f5528c53..21063296e 100644 --- a/src/vault/gear/scheduler-frontend.hpp +++ b/src/vault/gear/scheduler-frontend.hpp @@ -25,7 +25,8 @@ ** Scheduler service access point for higher layers. ** @todo WIP unfinished since 9/2013 ** @warning as of 4/2023 Render-Engine integration work is underway ////////////////////////////////////////TICKET #1280 - ** @deprecated as of 7/2023 the scheduler API will likely draw upon the ActivityLang + ** @deprecated 8/23 obsoleted by rework for »Playback Vertical Slice« //////////////////////////////////TICKET #1228 + ** @see activity-lang.hpp the emerging new interface ** */ diff --git a/tests/vault/gear/scheduler-activity-test.cpp b/tests/vault/gear/scheduler-activity-test.cpp index f8c020d71..e3de5e3ae 100644 --- a/tests/vault/gear/scheduler-activity-test.cpp +++ b/tests/vault/gear/scheduler-activity-test.cpp @@ -146,7 +146,7 @@ namespace test { { ActivityDetector detector; - size_t x1=rand(), x2=rand(); + uint64_t x1=rand(), x2=rand(); Time nomTime = lib::test::randTime(); Activity feed{x1,x2}; Activity feed2{x1+1,x1+2}; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index a0dfd723e..c76c7f5e6 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -74737,9 +74737,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

ich gehe davon aus, daß praktisch alle Tests, die dieses Mock-Framework verwenden, lediglich prüfen daß eine gewisse Connection durchgereicht wurde @@ -74808,9 +74806,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

ich will für den ganzen Mock-Support eine Lösung, die „einfach funktioniert“ — sofern man mit einer Instanz von MockSegmentation bzw. MockDispatcher arbeitet (und sonst nichts beeinflußt) @@ -74827,9 +74823,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...denn das entspricht noch am Meisten dem später mal erwarteten Ablauf @@ -74859,9 +74853,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

FAIL___expectation___________ @@ -74938,9 +74930,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...ursprünglich hatte ich nämlich per emplace_back() alloziert.... @@ -74954,9 +74944,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

an der Stelle, wo die Referenz auf Objekt-33 zurückgeliefert werden sollte, kommt tatsächlich eine Referenz auf das zuletzt rekursiv erzeugte Objekt-44  zurück, und wird daher in die Liste der Prerequisites eingefügt. @@ -74978,9 +74966,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

um den Lifecycle komplett kontrollieren zu können @@ -75033,9 +75019,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...auf irgend ein Objekt... @@ -75049,9 +75033,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...da aktuell noch keine Verbindung zum Render-Nodes-Network besteht... @@ -75124,9 +75106,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

und das heißt im Klartext: std::deque — später kombiniert mit einem custom-Allocator, der auf den AllocationCluster delegiert @@ -75183,9 +75163,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

aktuell wäre spezifisch besser — @@ -75214,9 +75192,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Beschluß: Allo ≡ Funktor mit variadischen Argumenten @@ -75249,9 +75225,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

exakt dieses Problem hatte ich schon vor einigen Wochen, bei der ersten (damals Mock)-Implementierung: da die Prerequisites private sind, gibt es keine andere Lösung als sie aus dem übergeordneten ctor heraus zu konstruieren, und damit re-entrant aus dem JobTicket-ctor ein weiteres JobTicket zu allozieren. Vector und Deque können das nicht hanhaben, und es kommt zu einem gefährlichen Aliasing, bei dem das geschachtelte Ticket an der gleichen Stelle im Speicher steht wie das Haupt-Ticket, und damit dessen ctor-Aufruf korrumpiert @@ -75301,9 +75275,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

damit sitz ich in der Falle... @@ -75361,9 +75333,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

bisherige Mock-Lösung
nun darauf aufsetzen @@ -75371,9 +75341,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

nach dem ersten Schreck (weil ich es doch grade erst neu programmiert hatte...) zeigt sich, daß die bisherige Mock-Implementierung bereits sehr gut ist, und strukturell direkt in die endgültige Implementierung übersetzt werden kann; wir machen dann lediglich zweimal eine strukturgleiche rekursive Verarbeitung (GenNode ⟼ ExitNode-Struktur sowie dann ExitNode-Struktur ⟼ JobTicket) @@ -75385,9 +75353,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

ursprünglich dachte ich, im Ticket würde intern noch nach einer Channel-ID (für Mehrkanal-Medien) differenziert; die Analyse im Detail ergab jedoch, daß dies stets unter dem Konstrukt »ModelPort« subsummiert werden kann — viele interne Komplexitäten fallen damit weg @@ -75424,9 +75390,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Testfall: retrieve_JobTicket @@ -75442,9 +75406,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

head_ steam::engine::JobTicket::Provision * 0x2525252525252525 @@ -75465,9 +75427,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

provision.requirements.emplace(preNode) @@ -75478,9 +75438,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

und die nimmt im ctor ein JobTicket const& @@ -75519,9 +75477,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...denn das ist nicht wirklich ein Belang der Segmentation (diese arbeitet stets mit den Model-Port-Indices), sondern hat ehr mit dem globalen Mapping auf eine Timeline zu tun — also etwas, was  irgendwo in der RenderEnvironmentClosure verborgen liegt, denn wir wollen definitiv nicht ein globales »Timelines«-Array durch die Hintertür einführen.  Das High-Level-Model ist auf oberster Ebene ein Wald, und nicht eine einzige kohärente Struktur @@ -75538,9 +75494,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

neue Dispatcher-Operation: size_t resolveModelPort(ModelPort) @@ -75581,9 +75535,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

...denn dieser hat natürlicherweise beide Elemente in der Hand... @@ -75610,9 +75562,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

Eigentlich könnte das JobTicket für ein ganzes Segment konstant sein, ggfs noch aufdifferenziert nach ModelPort — der eigentliche JobFunctor (im Ticket) wäre vom Prinzip her in jedem Fall konstant und damit nur einmal alloziert. Aber jeder separate CalcStream braucht die Daten in einem anderen Ausgabe-Puffer, gegeben durch das DataSink-Handle. @@ -75624,9 +75574,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
- - - +

  • @@ -75701,9 +75649,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - - - +

    also stets das 2.Element im Tupel. Bin nämlich zu faul, hier auch noch das Tupel irgendwie zu rendern. Das mach ich dann im nächsten Testfall... @@ -75718,9 +75664,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - - - +

    FAIL___expectation___________ @@ -75790,9 +75734,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
    - - - +

    • @@ -75882,9 +75824,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      bisher: FrameCnt getNextAnchorPoint() @@ -75928,9 +75868,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      lib::Handle<OutputSlot::Connection> @@ -75940,9 +75878,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      denn die Inovcation muß in diese Sink rendern @@ -75955,9 +75891,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      Verhältnis von JobPlanning @@ -76038,9 +75972,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      und zwar wegen Separation of Concerns   —  der JobFunctor ist kein Informations-Service (genau dafür haben wir ja das JobTicket geschaffen) @@ -76090,9 +76022,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      Problem : habe nur JobTicket des unmittelbaren  Vorgängers @@ -76120,9 +76050,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      weil das die einzige Stelle ist in der zugleich Dependent und Dependency zugänglich sind @@ -76141,9 +76069,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      da im JobPlanning nochmal eine JobTicket& liegt, sind die zwei bisher im darunter liegenden Tupel gespeicherten JobTicket* eigentlich redundant und werden nur für die Explorer-Mechanik gebraucht @@ -76153,9 +76079,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      weil nun auf jeder Ebene im Explorer-Stack eine JobPlanning-Instanz liegt, und zwar dort im ItemWrapper für den jeweiligen TransformIterator (der die Explorer-Funktion implementiert) @@ -76169,9 +76093,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      ....und das gilt aber auch für die einzelnen Felder darin, nachdem nun FrameCoord als Konzept aufgegeben wurden: es sind nun zwei Referenzen statt einer, aber ich erwarte, daß alle diese Referenzen vom Optimiser erkannt und ausgelassen werden... @@ -76181,9 +76103,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      Wenn man die Daten entsprechend reorganisiert und dadurch die Redundanzen in der Pipeline minimiert kann der Optimiser viel machen, da (private) Referenzen überhaupt nicht repräsentiert werden müssen, sofern die referenzierte Quelle (wie hier) stabil im gleichen Objekt liegt. Wenn ich richtig schätze, habe ich mit dem Umbau nur einen »slot« mehr Speicher verbraucht (weil drei redundante »slots« wegfallen können) @@ -76202,9 +76122,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      AUA: dieser parent-Pointer war bisher sogar eine dangling reference — er zeigte nämlich auf einen Pointer im Stack-Frame des λ-Aufrufs, der aber gar nicht mehr existiert, wenn man den Transform-Iterator auswertet. Soschnellkannsgehen @@ -76215,9 +76133,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      ...denn sonst müßte ich sie in eine λ-Closure binden, was aber für zwei der drei Felder redundate Storage wäre; es macht auch sonst Sinn, wenn der Tick-Generator eben auf den FrameCoord arbeitet @@ -76231,9 +76147,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      dann müssen die FrameCoord jetzt sterben @@ -76252,9 +76166,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      verwendet nur absoluteNominalTime @@ -76285,9 +76197,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      das ist die einzige Verwendung von zwei Feldern @@ -76300,9 +76210,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      Das ist genau der Grund warum sie jetzt zum Problem werden: diese Funktion erzeugt FrameCoord, die irgendwo leben müssen, und das bloß, um den einen Aufruf zu machen. Das bestätigt die Enscheidung, sie zurückzubauen @@ -76366,9 +76274,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      leider ist das ziemlich abschüssiges Gelände @@ -76376,9 +76282,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      ....per SFINAE feststellen, daß ein Asignment-Operator unterdrückt wurde; lt. Standard sollte das gehen (das war eine späte Änderung zu C++11, da es in der Stdlib so viel Probleme gemacht hat) — aber in der Praxis weiß ich, daß das fragil ist, manchmal Fehler auslösen kann (statt SFINAE), und daß es Diskrepanzen zwischen den Compilern gibt. Ich hatte auch schon Fälle, wo std::is_assignable rundweg versagt hat.... @@ -76388,9 +76292,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      also käme erst mal nur in Frage, dort stets die alte Payload @@ -76404,9 +76306,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      Der typische use-case, für den dieser ItemWrapper geschaffen wurde, ist, ein beliebiges Lambda auszuwerten, und das Resultat dann im Puffer vorzuhalten; speziell wenn das Lambda ein neues Objekt konstruiert und per Value zurückgibt, sorgt die RVO dafür, daß dieses Objekt dann (per copy elision) sofort im Puffer im ItemWrapper konstruiert wird — in der Praxis ist das der häufigste use-case und tritt im Besonderen in einem Transform-Iterator auf. Wenn andererseits die Payload ein POD oder einfacher Wert ist, dann sind Destruktor und Konstruktor ohnehin trivial... @@ -76459,9 +76359,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      ...denn sonst würde es genau zu rekursiven kaskadierenden (quadratisch aufwendigen) Aufrufen der Deadline-Berechnungs-Logik kommen; um das Caching zu steuern, kann ich einen Marker-Wert Time::NEVER verwenden @@ -76477,9 +76375,7 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - - +

      Ich kann mir nicht vorstellen, daß die große Mehrheit der Jobs mehr als eine Prerequisite bekommt...  der Aufwand ist n/2 * (n+1), das bringt uns erst mal solange nicht um (bis es uns nachweislich umbringt...) @@ -78267,8 +78163,12 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - + + + + + + @@ -80372,8 +80272,8 @@ Date:   Thu Apr 20 18:53:17 2023 +0200
      - - + + @@ -80390,17 +80290,25 @@ Date:   Thu Apr 20 18:53:17 2023 +0200

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