Skip to content

SUB-EPIC: full port, block, graph, scheduler API #148

@wirew0rm

Description

@wirew0rm

missing API definitions and ideas (from Schulder API Architecture meeting 2023-06-12)

  • ports:

    • [5pt,8pt] Enable MESSAGE passing/ports #210
      • dedicated process_async function (N.B. sync: process_one, process_bulk)
      • rstein will draft a proposal
    • bool optional(): meta information determining whether block has to be connected, can be used by grc and graph setup
    • auto port_domain()
    • auto port_direction()
      • drop BIDIRECTIONAL: unnecessarily complex and only minor benefit over (IN|OUT) pair
  • block / node

    • naming: rename all things node to block<T> to comply with gnuradio terminology
    • void reset() mechanics → easy extension to existing settings managment (needs to keep state of initial/default settings)
    • dynamic port definitions -> needs to be addressed (example: adder for 1-10+ input of the same type)
      • follow-up: allows for/enables hier-blocks
    • new -- simplifications/convenience methods: (to note: KISS, clean and lean)
      • std::span availableInputSamples() -- available samples at input ports
        • tbd: updated whenever called (N.B. caller pays the costs for calling)
      • std::span minInputSamples() -- minimum required samples
      • std::span maxInputSamples() -- maximum required samples
      • do we need this for outputs as well? -> not for now
    • BlockingIO-concept -- concept by rstein:
      • scheduler injects atomic counter and thread-pool for each blocking-enabled block
      • same atomic for all blocking blocks (and/or per scheduled CPU core)
      • scheduler waits on atomic counter (N.B. C++20 feature) if there is no more work to be down
      • e.g. spin-loop -> wait based on expoential back-off
      • similar/same strategies as circular buffer 'WaitingStrategy'
      • block/or spawned blocking worker notifies via atomic_counter.notify_all()
      • see: demo clock and source handling BlockingIO #140
    • [2pt] work() DONE return type and disjoint use-case #209
      • a) continuous running/looping through graph
      • b) running for a given number of samples and then stop
      • status quo, not ideal:
        enum class work_return_t {
            ERROR                     = -100, /// error occurred in the work function
            INSUFFICIENT_OUTPUT_ITEMS = -3,   /// work requires a larger output buffer to produce output
            INSUFFICIENT_INPUT_ITEMS  = -2,   /// work requires a larger input buffer to produce output
            DONE                      = -1,   /// block has completed processing and the flowgraph should be done -> should become API call ... need ideas
            OK                        = 0,    /// work call was successful and return values in i/o structs are valid
            CALLBACK_INITIATED        = 1,    /// rather than ...
        };
        
    • constraining the amount of 'work' a block is permitted to execute <-> latency optimisation, needs:
      • OK, rstein will make a draft PR + scheduling examples
      • work return indicating how much work has been done (e.g. 1st order number of samples)
      • work input indicating how much work shall be done (same number as above) to limit max execution
      • OK, rstein will make a draft PR + scheduling examples: changed node:work() signature #105
    • refactoring work() [Xpt] graph: refactor Block::work() function #81
    • MergedGraph
      • naming: merged_block vs MergedGraph
      • misses (sub-)settings() API -> volunteers?
      • misses tag forwarding handling
      • cannot handle graphs with loops -> Matthias? other volunteers?
  • hier-graph -> SubGraph or Graph -> see also Managed Nested SubGraph with Scheduler Integration #487 & [8SP;6SP] Sub-graph's YAML-Based definition and plugin-like extension #488

    • needs convenience/helper methods (and Ivan's patch as prerequisite)
    • sub-settings management
  • graph:

    • edge interface should be implemented here
      • dynamic runtime definition of buffer sizes
      • dynamic definition of edge priorities for scheduler -> tbd. later
        • either: auto weight() -> float - more graph-theory - vote:
        • xor (vote Ralph): auto priority() -> size_t or dedicated enum: - more OS/scheduling - vote: Alex, Ivan
    • handling of cyclic graphs -- initially handle only one-sample delay case
      • runtime: probably only cycle detection and init-problem (i.e. generating the first zero-padded sample in the buffer where the cycle has been detected)
      • compile-time merge API: ... needs some work/input from @mattkretz, @ivan-cukic or other volunteers
  • scheduler:

    • to note: scheduler is owner of the graph, access/modifications only via scheduler and/or copy of graph
    • define required state-machine of (IDLE, INITIALISING, RUN, PAUSE, ..., SHUTTING_DOWN) -> use this
    • circular graph detection (& handling)
      • run-time graph: resolved by 'init one sample at input'
      • alt: explicit ZOH padding block
      • compile-time graph: see merged_node above
    • optional: performance metrics (<-> use circular_buffer as aggregator and Google perf format): work in progress, see Profiler class for scheduler/block profiling #131
    • long-term: handling of sub-graph and (domain-specific) (sub-)sub-scheduler
      • shall a sub-scheduler behave like a:
        • sub-graph (scheduler behaves like a node), or
        • coordinated/parallel schedule

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    documentationImprovements or additions to documentation

    Type

    No type

    Projects

    Status

    🔖 Selected (6)

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions