explicate the JobPlanningSequence definition
..causing the compiler to instantiate the involved templates, i.e. get the complete pipeline definition through the compiler
This commit is contained in:
parent
b52a1a8366
commit
062e1bbdc1
4 changed files with 45 additions and 15 deletions
|
|
@ -175,9 +175,11 @@ namespace lib {
|
||||||
typedef typename SRC::reference reference;
|
typedef typename SRC::reference reference;
|
||||||
typedef typename SRC::pointer pointer;
|
typedef typename SRC::pointer pointer;
|
||||||
|
|
||||||
/** Metafunction: the resulting type when binding a functor of type FUN */
|
/** Metafunction: the resulting type when binding ("flat mapping")
|
||||||
|
* a functor of type FUN. Basically the result of binding a function
|
||||||
|
* is again an IterExplorer (with an "expanded" state core type) */
|
||||||
template<class FUN>
|
template<class FUN>
|
||||||
struct Binding
|
struct FlatMapped
|
||||||
{
|
{
|
||||||
typedef IterExplorer<_COM_<IterExplorer,FUN>, _COM_> Type;
|
typedef IterExplorer<_COM_<IterExplorer,FUN>, _COM_> Type;
|
||||||
};
|
};
|
||||||
|
|
@ -210,11 +212,11 @@ namespace lib {
|
||||||
* of the result iterator.
|
* of the result iterator.
|
||||||
*/
|
*/
|
||||||
template<class FUN>
|
template<class FUN>
|
||||||
IterExplorer<_COM_<IterExplorer,FUN>, _COM_>
|
typename FlatMapped<FUN>::Type
|
||||||
operator >>= (FUN explorer)
|
operator >>= (FUN explorer)
|
||||||
{
|
{
|
||||||
typedef _COM_<IterExplorer,FUN> Combinator; // instantiation of the combinator strategy
|
typedef _COM_<IterExplorer,FUN> Combinator; // instantiation of the combinator strategy
|
||||||
typedef IterExplorer<Combinator, _COM_> ResultsIter; // result IterExplorer using that instance as state core
|
typedef typename FlatMapped<FUN>::Type ResultsIter; // result IterExplorer using that instance as state core
|
||||||
|
|
||||||
return ResultsIter (
|
return ResultsIter (
|
||||||
Combinator (explorer // build a new iteration state core
|
Combinator (explorer // build a new iteration state core
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,13 @@ namespace meta{
|
||||||
typedef typename FunctionSignature<function<SIG> >::Ret Ret;
|
typedef typename FunctionSignature<function<SIG> >::Ret Ret;
|
||||||
typedef typename FunctionSignature<function<SIG> >::Args Args;
|
typedef typename FunctionSignature<function<SIG> >::Args Args;
|
||||||
};
|
};
|
||||||
|
/** Specialisation when using a function reference */
|
||||||
|
template<typename SIG>
|
||||||
|
struct _Fun<SIG&>
|
||||||
|
{
|
||||||
|
typedef typename FunctionSignature<function<SIG> >::Ret Ret;
|
||||||
|
typedef typename FunctionSignature<function<SIG> >::Args Args;
|
||||||
|
};
|
||||||
/** Specialisation for passing a functor */
|
/** Specialisation for passing a functor */
|
||||||
template<typename SIG>
|
template<typename SIG>
|
||||||
struct _Fun<function<SIG> >
|
struct _Fun<function<SIG> >
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
//#include "proc/state.hpp"
|
//#include "proc/state.hpp"
|
||||||
#include "proc/engine/job.hpp"
|
#include "proc/engine/job.hpp"
|
||||||
#include "proc/engine/job-ticket.hpp"
|
#include "proc/engine/job-ticket.hpp"
|
||||||
|
#include "proc/engine/time-anchor.hpp"
|
||||||
//#include "proc/engine/frame-coord.hpp"
|
//#include "proc/engine/frame-coord.hpp"
|
||||||
//#include "lib/time/timevalue.hpp"
|
//#include "lib/time/timevalue.hpp"
|
||||||
//#include "lib/time/timequant.hpp"
|
//#include "lib/time/timequant.hpp"
|
||||||
|
|
@ -190,7 +191,7 @@ namespace engine {
|
||||||
return this->wrapping(*prerequisites);
|
return this->wrapping(*prerequisites);
|
||||||
// explanation: PlanningState represents a sequence of successive planning points.
|
// explanation: PlanningState represents a sequence of successive planning points.
|
||||||
// actually this is implemented by switching an embedded JobPlanning element
|
// actually this is implemented by switching an embedded JobPlanning element
|
||||||
// through a sequence of states. Thus the initial state of the investigation
|
// through a sequence of states. Thus the initial state of an investigation
|
||||||
// (which is a JobPlanning) can stand-in for the sequence of prerequisites
|
// (which is a JobPlanning) can stand-in for the sequence of prerequisites
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -210,10 +211,10 @@ namespace engine {
|
||||||
|
|
||||||
|
|
||||||
inline PlanningState
|
inline PlanningState
|
||||||
expandPrerequisites (PlanningState const& calculationStep)
|
expandPrerequisites (JobPlanning const& calculationStep)
|
||||||
{
|
{
|
||||||
PlanningState newSubEvaluation(
|
PlanningState newSubEvaluation(
|
||||||
calculationStep->discoverPrerequisites());
|
calculationStep.discoverPrerequisites());
|
||||||
return newSubEvaluation;
|
return newSubEvaluation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -233,11 +234,18 @@ namespace engine {
|
||||||
*/
|
*/
|
||||||
class PlanningStepGenerator
|
class PlanningStepGenerator
|
||||||
{
|
{
|
||||||
|
engine::TimeAnchor anchor_;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef JobPlanning value_type;
|
typedef JobPlanning value_type;
|
||||||
typedef JobPlanning& reference;
|
typedef JobPlanning& reference;
|
||||||
typedef JobPlanning * pointer;
|
typedef JobPlanning * pointer;
|
||||||
|
|
||||||
|
// PlanningStepGenerator() { }
|
||||||
|
|
||||||
|
PlanningStepGenerator(engine::TimeAnchor startPoint)
|
||||||
|
: anchor_(startPoint)
|
||||||
|
{ }
|
||||||
|
|
||||||
/* === Iteration control API for IterStateWrapper== */
|
/* === Iteration control API for IterStateWrapper== */
|
||||||
|
|
||||||
|
|
@ -261,8 +269,14 @@ namespace engine {
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#if false /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #827
|
|
||||||
#endif /////////////////////////////////////////////////////////////////////////////////////////////////////////////UNIMPLEMENTED :: TICKET #827
|
|
||||||
|
typedef PlanningState (*SIG_expandPrerequisites) (JobPlanning const&);
|
||||||
|
|
||||||
|
typedef lib::IterExplorer<PlanningStepGenerator
|
||||||
|
,lib::iter_explorer::RecursiveSelfIntegration> JobPlanningChunkStartPoint;
|
||||||
|
|
||||||
|
typedef JobPlanningChunkStartPoint::FlatMapped<SIG_expandPrerequisites>::Type ExpandedPlanningSequence;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -270,11 +284,18 @@ namespace engine {
|
||||||
* @todo 6/12 WIP-WIP-WIP how to prepare jobs for scheduling
|
* @todo 6/12 WIP-WIP-WIP how to prepare jobs for scheduling
|
||||||
*/
|
*/
|
||||||
class JobPlanningSequence
|
class JobPlanningSequence
|
||||||
: public lib::IterExplorer<PlanningStepGenerator
|
: public ExpandedPlanningSequence
|
||||||
,lib::iter_explorer::RecursiveSelfIntegration>
|
|
||||||
{
|
{
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
// JobPlanningSequence() { }
|
||||||
|
|
||||||
|
JobPlanningSequence(engine::TimeAnchor startPoint)
|
||||||
|
: ExpandedPlanningSequence(
|
||||||
|
JobPlanningChunkStartPoint(
|
||||||
|
PlanningStepGenerator(startPoint))
|
||||||
|
>>= expandPrerequisites)
|
||||||
|
{ }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2797,15 +2797,15 @@ From experiences with other middle scale projects, I prefer having the test code
|
||||||
[img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
|
[img[Example: Interfaces/Namespaces of the ~Session-Subsystems|uml/fig130053.png]]
|
||||||
</pre>
|
</pre>
|
||||||
</div>
|
</div>
|
||||||
<div title="JobTicket" modifier="Ichthyostega" modified="201204290241" created="201202120018" tags="spec Rendering draft" changecount="12">
|
<div title="JobTicket" modifier="Ichthyostega" modified="201208311625" created="201202120018" tags="spec Rendering draft" changecount="14">
|
||||||
<pre>The actual media data is rendered by [[individually scheduled render jobs|RenderJob]]. When preparing such jobs, in order to [[dispatch|FrameDispatcher]] the individual frames calculations required to make a given [[stream of calculations|CalcStream]] happen, a ''node planning phase'' is performed. The goal is to find out
|
<pre>The actual media data is rendered by [[individually scheduled render jobs|RenderJob]]. All these calculations together implement a [[stream of calculations|CalcStream]], as demanded and directed by the PlayProcess. During the preparation of playback, a ''node planning phase'' is performed, to arrange for [[dispatching|FrameDispatcher]] the individual calculations per frame. The goal of these //preparations//&nbsp; is to find out
|
||||||
* what channel(s) to pull
|
* what channel(s) to pull
|
||||||
* what prerequisites to prepare
|
* what prerequisites to prepare
|
||||||
* what parameters to provide
|
* what parameters to provide
|
||||||
The result of this planning phase is the {{{JobTicket}}}, a complete ''execution plan''.
|
The result of this planning phase is the {{{JobTicket}}}, a complete ''execution plan''.
|
||||||
This planning is uniform for each segment and treated for all channels together, resulting in a nested tree structure of sub job tickets, allocated and stored alongside with the processing nodes and wiring descriptors to form the segment's data and descriptor network. Job tickets are //higher order functions:// entering a concrete frame number and channel into a given job ticket will produce an actual job descriptor, which in itself is again a function, to be invoked through the scheduler when it's time to trigger the actual calculations.
|
This planning is uniform for each [[segment|Segmentation]] and treated for all channels together, resulting in a nested tree structure of sub job tickets, allocated and stored alongside with the processing nodes and wiring descriptors to form the segment's data and descriptor network. Job tickets are //higher order functions:// entering a concrete frame number and channel into a given job ticket will produce an actual job descriptor, which in itself is again a function, to be invoked through the scheduler when it's time to trigger the actual calculations.
|
||||||
|
|
||||||
!Structure of the render Jobs created
|
!Structure of the Render Jobs created
|
||||||
To be more precise: in the general case, invoking the ~JobTicket with a given frame number will produce //multiple jobs// -- typically each frame rendering will require at least one further source media frame; and because Lumiera render jobs will //never block waiting on IO,// this source media access will be packaged as a separate [[resource retrieving job|ResourceJob]], to be treated specifically by the scheduler.
|
To be more precise: in the general case, invoking the ~JobTicket with a given frame number will produce //multiple jobs// -- typically each frame rendering will require at least one further source media frame; and because Lumiera render jobs will //never block waiting on IO,// this source media access will be packaged as a separate [[resource retrieving job|ResourceJob]], to be treated specifically by the scheduler.
|
||||||
|
|
||||||
To support the generation of multiple dependent jobs, a ~JobTicket might refer to further ~JobTickets corresponding to the prerequisites. These prerequisite ~JobTickets are the result of a classical recursive descent call into the top level ProcNode, to perform the planning step. There is always an 1:1 relation between actual jobs generated and the corresponding tickets. More precisely, for each possible job to generate there is a suitable ''job closure'', representing exactly the context information necessary to get that job started. To stress that point: a ProcNode might be configured such as to perform a series of recursive invocations of other prerequisite nodes right away (especially when those recursive invocations correspond just to further CPU bound calculations) -- yet still there is only //one//&nbsp; ~JobTicket, because there will be only one Job to invoke the whole sequence. On the other hand, when there is a prerequisite requiring an operation to be scheduled separately, a corresponding separate {{{JobClosure}}} will be referred.
|
To support the generation of multiple dependent jobs, a ~JobTicket might refer to further ~JobTickets corresponding to the prerequisites. These prerequisite ~JobTickets are the result of a classical recursive descent call into the top level ProcNode, to perform the planning step. There is always an 1:1 relation between actual jobs generated and the corresponding tickets. More precisely, for each possible job to generate there is a suitable ''job closure'', representing exactly the context information necessary to get that job started. To stress that point: a ProcNode might be configured such as to perform a series of recursive invocations of other prerequisite nodes right away (especially when those recursive invocations correspond just to further CPU bound calculations) -- yet still there is only //one//&nbsp; ~JobTicket, because there will be only one Job to invoke the whole sequence. On the other hand, when there is a prerequisite requiring an operation to be scheduled separately, a corresponding separate {{{JobClosure}}} will be referred.
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue