41class MAYAFLUX_API
ComputeMatrix :
public std::enable_shared_from_this<ComputeMatrix> {
46 static std::shared_ptr<ComputeMatrix>
create()
48 return std::make_shared<ComputeMatrix>();
58 template <
typename OpClass>
63 return m_operations.add(
name, operation);
74 template <
typename OpClass,
typename... Args>
77 auto operation = std::make_shared<OpClass>(std::forward<Args>(args)...);
78 if (m_operations.add(
name, operation)) {
90 template <
typename OpClass>
93 return m_operations.get<OpClass>(
name);
103 return m_operations.remove(
name);
112 return m_operations.list_names();
120 m_operations.clear();
135 auto operation = std::make_shared<OpClass>(std::forward<Args>(args)...);
136 return execute_operation<OpClass, InputType, OutputType>(operation,
input);
148 template <
typename OpClass, ComputeData InputType, ComputeData OutputType = InputType>
151 auto operation = m_operations.get<OpClass>(
name);
154 return execute_operation<OpClass, InputType, OutputType>(operation,
input);
166 template <
typename OpClass, ComputeData InputType, ComputeData OutputType = InputType>
169 return execute_operation<OpClass, InputType, OutputType>(operation,
input);
184 return std::async(std::launch::async, [
this,
input, args...]() {
185 return execute<OpClass, InputType, OutputType>(input, args...);
192 template <
typename OpClass, ComputeData InputType, ComputeData OutputType = InputType>
195 return std::async(std::launch::async, [
this,
name,
input]() {
196 return execute_named<OpClass, InputType, OutputType>(
name,
input);
207 template <
ComputeData InputType,
typename... OpClasses>
210 return std::make_tuple(
211 execute_async<OpClasses, InputType>(
input).get()...);
223 template <
typename OpClass, ComputeData InputType, ComputeData OutputType = InputType>
225 const std::vector<std::string>& names,
228 std::vector<std::future<std::optional<Datum<OutputType>>>> futures;
229 futures.reserve(names.size());
231 for (
const auto&
name : names) {
232 futures.push_back(execute_named_async<OpClass, InputType, OutputType>(
name,
input));
235 std::vector<std::optional<Datum<OutputType>>> results;
236 results.reserve(futures.size());
238 for (
auto& future : futures) {
239 results.push_back(future.get());
255 template <
typename FirstOp,
typename SecondOp,
261 auto first_result = execute<FirstOp, InputType, IntermediateType>(
input);
265 return execute<SecondOp, IntermediateType, OutputType>(*first_result);
271 template <
typename FirstOp,
typename SecondOp,
276 const std::string& first_name,
277 const std::string& second_name,
280 auto first_result = execute_named<FirstOp, InputType, IntermediateType>(first_name,
input);
284 return execute_named<SecondOp, IntermediateType, OutputType>(second_name, *first_result);
301 auto operation = std::make_shared<OpClass>(std::forward<Args>(args)...);
303 std::vector<std::optional<Datum<OutputType>>> results;
304 results.reserve(inputs.size());
306 for (
const auto&
input : inputs) {
307 results.push_back(execute_operation<OpClass, InputType, OutputType>(operation,
input));
321 auto operation = std::make_shared<OpClass>(std::forward<Args>(args)...);
323 std::vector<std::optional<Datum<OutputType>>> results(inputs.size());
325 std::transform(std::execution::par_unseq,
326 inputs.begin(), inputs.end(),
329 return execute_operation<OpClass, InputType, OutputType>(operation, input);
341 template <ComputeData StartType>
347 template <ComputeData StartType>
357 template <ComputeData StartType>
363 template <ComputeData StartType>
401 template <ComputeData StartType,
typename ChainFunc,
typename CompleteFn>
404 auto self = shared_from_this();
405 register_async(std::async(std::launch::async,
409 on_complete = std::forward<CompleteFn>(on_complete)]()
mutable {
415 template <ComputeData StartType,
typename ChainFunc,
typename CompleteFn>
419 std::forward<ChainFunc>(
chain),
420 std::forward<CompleteFn>(on_complete));
429 m_execution_policy = policy;
437 return m_execution_policy;
445 m_profiling_enabled = enabled;
453 auto stats = m_operations.get_statistics();
454 stats[
"total_executions"] = m_total_executions.load();
455 stats[
"failed_executions"] = m_failed_executions.load();
456 if (m_profiling_enabled) {
457 stats[
"average_execution_time_ms"] = m_average_execution_time.load();
467 std::function<
void(
ExecutionContext&,
const std::type_index&)> configurator)
469 m_context_configurator = std::move(configurator);
478 m_default_timeout = timeout;
482 : m_async_tasks([this](
std::exception_ptr ep) { handle_async_error(std::move(ep)); })
490 template <
typename OpClass, ComputeData InputType, ComputeData OutputType>
492 std::shared_ptr<OpClass> operation,
498 m_total_executions++;
502 configure_execution_context(ctx, std::type_index(
typeid(OpClass)));
504 auto start = std::chrono::steady_clock::now();
506 auto result = operation->apply_operation_internal(
input, ctx);
508 if (m_profiling_enabled) {
509 auto end = std::chrono::steady_clock::now();
510 auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
511 update_execution_time(duration.count());
516 }
catch (
const std::exception& e) {
517 m_failed_executions++;
518 handle_execution_error(e, std::type_index(
typeid(OpClass)));
528 switch (m_execution_policy) {
529 case ExecutionPolicy::CONSERVATIVE:
530 case ExecutionPolicy::BALANCED:
531 ctx.
mode = ExecutionMode::SYNC;
533 case ExecutionPolicy::AGGRESSIVE:
534 ctx.
mode = ExecutionMode::PARALLEL;
538 ctx.
timeout = m_default_timeout;
540 if (m_context_configurator) {
541 m_context_configurator(ctx, op_type);
552 m_last_error = e.what();
553 m_last_error_type = op_type;
555 if (m_error_callback) {
556 m_error_callback(e, op_type);
565 double current_avg = m_average_execution_time.load();
566 double total_execs = m_total_executions.load();
567 double new_avg = (current_avg * (total_execs - 1) + ms) / total_execs;
568 m_average_execution_time.store(new_avg);
573 m_async_tasks.submit(std::move(f));
588 std::rethrow_exception(std::move(ep));
589 }
catch (
const std::exception& e) {
590 handle_execution_error(e,
typeid(
void));
592 m_last_error =
"async chain failed with unrecognized exception";
593 m_last_error_type =
typeid(void);
600 std::chrono::milliseconds m_default_timeout { 0 };
603 std::atomic<size_t> m_total_executions { 0 };
604 std::atomic<size_t> m_failed_executions { 0 };
605 std::atomic<double> m_average_execution_time { 0.0 };
606 bool m_profiling_enabled =
false;
611 std::type_index m_last_error_type {
typeid(void) };
619 std::function<
void(
const std::exception&,
const std::type_index&)>
callback)
621 m_error_callback = std::move(
callback);
640 m_async_tasks.
drain();
Core::GlobalInputConfig input
BufferProcessingChain * chain
void drain()
Blocks until every currently submitted future completes.
Owns a set of in-flight std::async futures on behalf of a subsystem.
std::unordered_map< std::string, std::any > get_statistics() const
Get execution statistics.
std::vector< std::optional< Datum< OutputType > > > execute_batch(const std::vector< Datum< InputType > > &inputs, Args &&... args)
Execute operation on multiple inputs.
std::vector< std::optional< Datum< OutputType > > > execute_parallel_named(const std::vector< std::string > &names, const Datum< InputType > &input)
Execute multiple named operations in parallel.
ExecutionPolicy get_execution_policy() const
Get current execution policy.
void update_execution_time(double ms)
Update execution time statistics.
std::future< std::optional< Datum< OutputType > > > execute_named_async(const std::string &name, const Datum< InputType > &input)
Execute named operation asynchronously.
FluentExecutor< ComputeMatrix, StartType > with(StartType &&input)
std::optional< Datum< OutputType > > execute_named(const std::string &name, const Datum< InputType > &input)
Execute a named operation from the pool.
std::optional< Datum< OutputType > > execute_chain(const Datum< InputType > &input)
Execute operations in sequence (type-safe chain)
void set_context_configurator(std::function< void(ExecutionContext &, const std::type_index &)> configurator)
Set custom context configurator.
std::shared_ptr< OpClass > get_operation(const std::string &name)
Get a named operation from this matrix.
OperationPool m_operations
void with_async(StartType input, ChainFunc &&chain, CompleteFn &&on_complete)
std::future< std::optional< Datum< OutputType > > > execute_async(const Datum< InputType > &input, Args &&... args)
Execute operation asynchronously.
void set_error_callback(std::function< void(const std::exception &, const std::type_index &)> callback)
Set error callback.
std::string get_last_error() const
Get last error message.
void configure_execution_context(ExecutionContext &ctx, const std::type_index &op_type)
Configure execution context based on operation type and policy.
std::vector< std::optional< Datum< OutputType > > > execute_batch_parallel(const std::vector< Datum< InputType > > &inputs, Args &&... args)
Execute operation on multiple inputs in parallel.
std::function< void(const std::exception &, const std::type_index &)> m_error_callback
FluentExecutor< ComputeMatrix, StartType > with(const Datum< StartType > &input)
Create a fluent executor for chaining operations.
std::vector< std::string > list_operations() const
List all operation names in this matrix.
void set_profiling(bool enabled)
Enable/disable execution profiling.
std::shared_ptr< OpClass > create_operation(const std::string &name, Args &&... args)
Create and add an operation to this matrix.
std::optional< Datum< OutputType > > execute_with(std::shared_ptr< OpClass > operation, const Datum< InputType > &input)
Execute with provided operation instance.
void handle_execution_error(const std::exception &e, const std::type_index &op_type)
Handle execution errors.
void set_default_timeout(std::chrono::milliseconds timeout)
Set default execution timeout.
void set_execution_policy(ExecutionPolicy policy)
Set execution policy for this matrix.
std::optional< Datum< OutputType > > execute(const Datum< InputType > &input, Args &&... args)
Execute an operation by creating a new instance.
void register_async(std::future< void > f)
std::optional< Datum< OutputType > > execute_chain_named(const std::string &first_name, const std::string &second_name, const Datum< InputType > &input)
Execute named operations in sequence.
void handle_async_error(std::exception_ptr ep)
Routes an async chain's exception into the same reporting surface as a synchronous operation failure.
bool add_operation(const std::string &name, std::shared_ptr< OpClass > operation)
Add a pre-configured operation instance to this matrix.
void clear_operations()
Clear all operations from this matrix.
FluentExecutor< ComputeMatrix, StartType > with(Datum< StartType > &&input)
Create a fluent executor with move semantics.
void with_async(Datum< StartType > input, ChainFunc &&chain, CompleteFn &&on_complete)
Execute an operation chain asynchronously.
Parallel::AsyncGroup< void > m_async_tasks
std::function< void(ExecutionContext &, const std::type_index &)> m_context_configurator
auto execute_parallel(const Datum< InputType > &input)
Execute multiple operations in parallel.
FluentExecutor< ComputeMatrix, StartType > with(const StartType &input)
std::optional< Datum< OutputType > > execute_operation(std::shared_ptr< OpClass > operation, const Datum< InputType > &input)
Core execution implementation.
void drain_async()
Block until all in-flight async chains complete.
bool remove_operation(const std::string &name)
Remove a named operation from this matrix.
static std::shared_ptr< ComputeMatrix > create()
Create a new ComputeMatrix instance.
Local execution orchestrator for computational operations.
Fluent interface for chaining operations on any executor.
Thread-safe pool for managing named operation instances.
Universal concept for types that can flow through the computation pipeline.
ExecutionPolicy
Policy for execution strategy selection.
Input/Output container for computation pipeline data flow with structure preservation.
ExecutionMode mode
Execution mode controlling scheduling behavior.
std::chrono::milliseconds timeout
Optional timeout for operation execution.
Context information controlling how a compute operation executes.