Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found

Target

Select target project
  • eclipse/aidge/aidge_core
  • hrouis/aidge_core
  • mszczep/aidge_core
  • oantoni/aidge_core
  • cguillon/aidge_core
  • jeromeh/aidge_core
  • axelfarr/aidge_core
  • cmoineau/aidge_core
  • noamzerah/aidge_core
  • lrakotoarivony/aidge_core
  • silvanosky/aidge_core
  • maab05/aidge_core
  • mick94/aidge_core
  • lucaslopez/aidge_core_ll
  • wboussella/aidge_core
  • farnez/aidge_core
  • mnewson/aidge_core
17 results
Show changes
Commits on Source (100)
Showing
with 1096 additions and 281 deletions
import matplotlib
import matplotlib.pyplot as plt
from functools import partial
import numpy as np
import aidge_core
class DynamicAnalysis(aidge_core.DynamicAnalysis):
def log_nb_arithm_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_arithm_ops, filename, title, log_scale)
def log_nb_logic_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_logic_ops, filename, title, log_scale)
def log_nb_comp_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_comp_ops, filename, title, log_scale)
def log_nb_nl_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_nl_ops, filename, title, log_scale)
def log_nb_mac_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_mac_ops, filename, title, log_scale)
def log_nb_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_ops, filename, title, log_scale)
def log_nb_arithm_int_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_arithm_int_ops, filename, title, log_scale)
def log_nb_arithm_fp_ops(self, filename, title=None, log_scale=False):
return self._log_callback(aidge_core.OperatorStats.get_nb_arithm_fp_ops, filename, title, log_scale)
def log_nb_ops_by_type(self, filename, title=None, log_scale=False):
return self._log_callback([aidge_core.OperatorStats.get_nb_arithm_int_ops,
aidge_core.OperatorStats.get_nb_arithm_fp_ops,
aidge_core.OperatorStats.get_nb_logic_ops,
aidge_core.OperatorStats.get_nb_comp_ops,
aidge_core.OperatorStats.get_nb_nl_ops], filename, title, log_scale)
def _log_callback(self, callback, filename, title=None, log_scale=False):
"""
Log a statistic given by an OperatorStats callback member function.
Usage:
stats = DynamicAnalysis(model)
stats.log_callback(aidge_core.OperatorStats.get_nb_params, "stats.png", "Nb params per operator")
:param func: OperatorStats member function to call.
:param filename: Output graph file name.
:type filename: str
:param title: Title of the graph.
:type title: str
"""
namePtrTable = self.get_graph().get_ranked_nodes_name("{0} ({1}#{3})");
nodes = self.get_graph().get_ordered_nodes()
series = []
legend = None
for node in nodes:
if node.type() == "Producer":
continue
stats = aidge_core.OperatorStats.get_op_stats(node)
name = namePtrTable[node]
attr = {}
if type(node.get_operator()) is aidge_core.GenericOperatorOp:
# Display Generic Op in orange
attr = {'color': 'orange'}
elif not node.get_operator().is_atomic():
# Display Meta Op in bold
attr = {'fontweight': 'bold'}
elif node.type() not in aidge_core.get_keys_OperatorStats():
# Display unsupported operator in red labels
attr = {'color': 'red'}
if attr:
name = (name, attr)
if isinstance(callback, list):
series.append([name, [partial(cb, stats)() for cb in callback]])
legend = [cb.__name__ for cb in callback]
if title is None: title = str(legend)
else:
series.append([name, partial(callback, stats)()])
if title is None: title = callback.__name__
if title is None: title = str(callback)
if filename is not None:
self._log_bar(series, filename, title, legend, log_scale)
return series
def _log_bar(self, series, filename, title=None, legend=None, log_scale=False):
names, values = zip(*series)
names_only = [item[0] if isinstance(item, tuple) else item for item in names]
fig, ax = plt.subplots(figsize=(max(5, len(names)/4), 5))
plt.xlim(-0.5, len(names) - 0.5)
if isinstance(values[0], list):
series = [list(i) for i in zip(*values)]
bot = np.zeros(len(series[0]))
for i, serie in enumerate(series):
plt.bar(names_only, serie, bottom=bot)
bot += serie
else:
plt.bar(names_only, values)
if callable(getattr(ax.yaxis, 'minorticks_on', None)):
ax.yaxis.minorticks_on() # introduced in matplotlib 3.9.x
plt.grid(axis='y', which='major', linestyle='--', color='gray')
plt.grid(axis='y', which='minor', linestyle=':', color='lightgray')
formatter0 = matplotlib.ticker.EngFormatter(unit='')
ax.yaxis.set_major_formatter(formatter0)
plt.gca().set_axisbelow(True)
labels = plt.gca().get_xticks()
tick_labels = plt.gca().get_xticklabels()
for i, label in enumerate(labels):
if isinstance(names[i], tuple):
if 'color' in names[i][1]:
tick_labels[i].set_color(names[i][1]['color'])
elif 'fontweight' in names[i][1]:
tick_labels[i].set_fontweight(names[i][1]['fontweight'])
plt.xticks(rotation='vertical')
if log_scale: plt.yscale('log')
if title is not None: plt.title(title)
if legend is not None: plt.legend(legend)
plt.savefig(filename, bbox_inches='tight')
def _log_barh(self, series, filename, title=None, legend=None, log_scale=False):
names, values = zip(*series)
names_only = [item[0] if isinstance(item, tuple) else item for item in names]
fig, ax = plt.subplots(figsize=(10, max(5, len(names)/4)))
plt.ylim(-0.5, len(names) - 0.5)
if isinstance(values[0], list):
series = [list(i) for i in zip(*values)]
left = np.zeros(len(series[0]))
for i, serie in enumerate(series):
plt.barh(names_only, serie, left=left)
left += serie
else:
plt.barh(names_only, values)
if callable(getattr(ax.xaxis, 'minorticks_on', None)):
ax.xaxis.minorticks_on() # introduced in matplotlib 3.9.x
plt.grid(axis='x', which='major', linestyle='--', color='gray')
plt.grid(axis='x', which='minor', linestyle=':', color='lightgray')
formatter0 = matplotlib.ticker.EngFormatter(unit='')
ax.xaxis.set_major_formatter(formatter0)
plt.gca().set_axisbelow(True)
plt.gca().xaxis.set_label_position('top')
plt.gca().xaxis.tick_top()
labels = plt.gca().get_yticks()
tick_labels = plt.gca().get_yticklabels()
for i, label in enumerate(labels):
if isinstance(names[i], tuple):
if 'color' in names[i][1]:
tick_labels[i].set_color(names[i][1]['color'])
elif 'fontweight' in names[i][1]:
tick_labels[i].set_fontweight(names[i][1]['fontweight'])
if log_scale: plt.xscale('log')
if title is not None: plt.title(title)
if legend is not None: plt.legend(legend)
plt.savefig(filename, bbox_inches='tight')
......@@ -42,7 +42,7 @@ def scheduler_export(scheduler, export_folder_path: str, export_lib: ExportLib =
:param scheduler: Scheduler instance managing the computation graph.
Uses `graph_view` and `get_static_scheduling` methods
Uses `graph_view` and `get_sequential_static_scheduling` methods
to retrieve the computation graph layout and ordered nodes.
:type scheduler: aidge_core.Scheduler
:param export_folder_path: Path to the folder where the generated export files will be saved.
......@@ -88,7 +88,7 @@ def scheduler_export(scheduler, export_folder_path: str, export_lib: ExportLib =
outputs_size: List[int] = []
# List of aidge_core.Node ordered by scheduler
list_forward_nodes: List[aidge_core.Node] = scheduler.get_static_scheduling()
list_forward_nodes: List[aidge_core.Node] = scheduler.get_sequential_static_scheduling()
# If exportLib define use it
# else parse component in platform
......
......@@ -22,7 +22,7 @@ def compute_default_mem_info(scheduler: aidge_core.Scheduler) -> Tuple[int, List
mem_size = 0
# Exclude Producers and the last layers (because the results are stored outside the export)
for i, node in enumerate(scheduler.get_static_scheduling()):
for i, node in enumerate(scheduler.get_sequential_static_scheduling()):
if node.type() != "Producer":
node_mem_info = []
for out_id in range(node.get_nb_outputs()):
......@@ -109,7 +109,7 @@ def log_meminfo(mem_manager:aidge_core.MemoryManager, path: Path, diplay_names:b
aidge_core.Log.notice(f"Generated memory management info at: {path}")
def generate_optimized_memory_info(scheduler: aidge_core.Scheduler, stats_folder: Path = None, wrapping: bool = False, auto_concat: bool = False, display_names: bool=True) -> Tuple[int, List[dict]]:
def generate_optimized_memory_info(scheduler: aidge_core.SequentialScheduler, stats_folder: Path = None, wrapping: bool = False, auto_concat: bool = False, display_names: bool=True) -> Tuple[int, List[dict]]:
"""Generates optimized memory information for a computation graph managed by a scheduler.
This function analyzes the memory usage of a computation graph, determining the memory peak
......@@ -161,7 +161,7 @@ def generate_optimized_memory_info(scheduler: aidge_core.Scheduler, stats_folder
mem_planes = mem_manager.get_planes()
for node in scheduler.get_static_scheduling():
for node in scheduler.get_sequential_static_scheduling():
node_mem_info = []
if node.type() == "Producer":
pass
......
......@@ -4,7 +4,7 @@ from functools import partial
import numpy as np
import aidge_core
class StaticAnalysisExt(aidge_core.StaticAnalysis):
class StaticAnalysis(aidge_core.StaticAnalysis):
def log_nb_params(self, filename, title=None, log_scale=False):
namePtrTable = self.get_graph().get_ranked_nodes_name("{0} ({1}#{3})");
nodes = self.get_graph().get_ordered_nodes()
......@@ -77,7 +77,7 @@ class StaticAnalysisExt(aidge_core.StaticAnalysis):
Log a statistic given by an OperatorStats callback member function.
Usage:
stats = StaticAnalysisExt(model)
stats = StaticAnalysis(model)
stats.log_callback(aidge_core.OperatorStats.get_nb_params, "stats.png", "Nb params per operator")
:param func: OperatorStats member function to call.
......@@ -96,7 +96,7 @@ class StaticAnalysisExt(aidge_core.StaticAnalysis):
if node.type() == "Producer":
continue
stats = self.get_op_stats(node)
stats = aidge_core.OperatorStats.get_op_stats(node)
name = namePtrTable[node]
attr = {}
if type(node.get_operator()) is aidge_core.GenericOperatorOp:
......
"""
Copyright (c) 2023 CEA-List
This program and the accompanying materials are made available under the
terms of the Eclipse Public License 2.0 which is available at
http://www.eclipse.org/legal/epl-2.0.
SPDX-License-Identifier: EPL-2.0
"""
import unittest
import aidge_core
import numpy as np
class DivImpl(aidge_core.OperatorImpl):
"""Div operator implementation to avoid dependency to backend_cpu"""
def __init__(self, op: aidge_core.Operator):
aidge_core.OperatorImpl.__init__(self, op, "div")
self.op = op
print("Creating divImpl")
def forward(self):
data_input_0 = np.array(self.op.get_input(0))
data_input_1 = np.array(self.op.get_input(1))
output = (data_input_0 / data_input_1)
self.op.set_output(0, aidge_core.Tensor(output)) # setting operator output
# Note: In this test, except Div, every operator are backend independent
aidge_core.register_DivOp("cpu", DivImpl)
class test_forward_dims_constant_shape(unittest.TestCase):
"""Test forwardDims with shapeAsConstant=True
"""
def setUp(self):
# Declaring constant values
prod_two_a = aidge_core.Producer(aidge_core.Tensor(np.array(2, dtype=np.int64)), "two_a", constant=True)
prod_two_b = aidge_core.Producer(aidge_core.Tensor(np.array(2, dtype=np.int64)), "two_b", constant=True)
# Declaring operators
shape_op_1 = aidge_core.Shape(name="shape_op_1")
shape_op_2 = aidge_core.Shape(name="shape_op_2")
shape_op_3 = aidge_core.Shape(name="shape_op_3")
shape_op_4 = aidge_core.Shape(name="shape_op_4")
gather_op_1 = aidge_core.Gather(axis = 0, indices = [0], name="gather_op_1")
gather_op_2 = aidge_core.Gather(axis = 0, indices = [1], name="gather_op_2")
gather_op_3 = aidge_core.Gather(axis = 0, indices = [2], name="gather_op_3")
gather_op_4 = aidge_core.Gather(axis = 0, indices = [3], name="gather_op_4")
div_op = aidge_core.Div(name="div_op")
u_op_1 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_1")
u_op_2 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_2")
u_op_3 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_3")
u_op_4 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_4")
u_op_5 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_5")
u_op_6 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_6")
u_op_7 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_7")
u_op_8 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_8")
u_op_9 = aidge_core.Unsqueeze(axes = [0], name="unsqueeze_op_9")
concat_op_1 = aidge_core.Concat(5, name="concat_op_1")
concat_op_2 = aidge_core.Concat(4, name="concat_op_2")
reshape_op_1 = aidge_core.Reshape(name="reshape_op_1")
reshape_op_2 = aidge_core.Reshape(name="reshape_op_2")
transpose_op_1 = aidge_core.Transpose([0, 2, 1, 3, 4], name="transpose_op_1")
# Declaring Connectors
x = aidge_core.Connector(aidge_core.Identity(f"Input"))
a = aidge_core.Connector(prod_two_a)
b = aidge_core.Connector(prod_two_b)
# Graph creation using functional declaration
x1 = shape_op_1(x)
x2 = shape_op_2(x)
x3 = shape_op_3(x)
x4 = shape_op_4(x)
n = gather_op_1(x1)
c = gather_op_2(x2)
h = gather_op_3(x3)
w = gather_op_4(x4)
shape_1 = concat_op_1(u_op_1(n), u_op_2(a), u_op_3(div_op(c, b)), u_op_4(h), u_op_5(w))
shape_2 = concat_op_2(u_op_6(n), u_op_7(c), u_op_8(h), u_op_9(w))
y = reshape_op_2(transpose_op_1(reshape_op_1(x, shape_1)), shape_2)
self.graph = aidge_core.generate_graph([y])
def tearDown(self):
pass
def test_constant_shape_folding(self):
# Note: Except Div every operator are backend independent
self.graph.set_backend("cpu")
self.graph.set_datatype(aidge_core.dtype.float32)
aidge_core.constant_shape_folding(self.graph, [[5, 12, 24, 24]])
self.assertEqual(len(self.graph.get_nodes()), 6, "After forward dims with constant folding we don't have the expected number of nodes.")
if __name__ == '__main__':
unittest.main()
......@@ -184,9 +184,7 @@ class TestSqueeze(unittest.TestCase):
input_data.set_backend("cpu")
test_squeeze_op.set_input(0, input_data)
with self.assertRaises((RuntimeError, AssertionError)):
test_squeeze_op.forward_dims()
test_squeeze_op.forward()
self.assertFalse(test_squeeze_op.forward_dims())
return
......
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_ANALYSIS_DYNAMICANALYSIS_H_
#define AIDGE_CORE_ANALYSIS_DYNAMICANALYSIS_H_
#include <cstddef> // std::size_t
#include <memory>
#include "aidge/analysis/OperatorStats.hpp"
#include "aidge/scheduler/Scheduler.hpp"
namespace Aidge {
/**
* @brief Base class to compute statistics from a scheduled graph
*
*/
class DynamicAnalysis : public std::enable_shared_from_this<DynamicAnalysis> {
public:
DynamicAnalysis() = delete;
DynamicAnalysis(const Scheduler& scheduler);
virtual ~DynamicAnalysis();
std::size_t getNbArithmOps() const;
std::size_t getNbLogicOps() const;
std::size_t getNbCompOps() const;
std::size_t getNbNLOps() const;
std::size_t getNbOps() const;
std::size_t getNbArithmIntOps() const;
std::size_t getNbArithmFpOps() const;
std::size_t getNbMACOps() const;
protected:
const Scheduler& mScheduler;
std::size_t accumulate(std::size_t (OperatorStats::*func)() const) const;
};
}
#endif /* AIDGE_CORE_ANALYSIS_DYNAMICANALYSIS_H_ */
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_ANALYSIS_STATICANALYSIS_H_
#define AIDGE_CORE_ANALYSIS_STATICANALYSIS_H_
#include <cstddef> // std::size_t
#include <memory>
#include <string>
#include "aidge/analysis/OperatorStats.hpp"
#include "aidge/data/Tensor.hpp"
#include "aidge/graph/GraphView.hpp"
#include "aidge/operator/Operator.hpp"
#include "aidge/utils/Registrar.hpp"
namespace Aidge {
/**
* @brief Base class to compute statistics from a GraphView
*
*/
class StaticAnalysis : public std::enable_shared_from_this<StaticAnalysis> {
public:
StaticAnalysis() = delete;
StaticAnalysis(std::shared_ptr<GraphView> graph);
virtual ~StaticAnalysis();
inline const std::shared_ptr<GraphView> getGraph() const noexcept { return mGraph; }
/**
* @brief Get the number of parameters associated to a node. This includes
* all Producers directly connected to the node's inputs as well as all
* internal Producers (in case of a meta operator).
*
* Note: this function does not check if parameters are shared between
* several nodes or not. This means that simply adding parameters count from
* several nodes may lead to a higher number of parameters than in reality
* if some of them are shared.
*
* @param node Node
* @return std::size_t Number of parameters
*/
virtual std::size_t getNbParams(std::shared_ptr<Node> node) const;
/**
* @brief Get the total parameters memory size, in bits, associated to a node.
* This includes all Producers directly connected to the node's inputs as
* well as all internal Producers (in case of a meta operator).
*
* Note: this function does not check if parameters are shared between
* several nodes or not. This means that simply adding parameters size from
* several nodes may lead to a higher parameter size than in reality
* if some of them are shared.
*
* @param node Node
* @return std::size_t Total parameters memory, in bits
*/
virtual std::size_t getParamsSize(std::shared_ptr<Node> node) const;
std::size_t getNbArithmOps() const;
std::size_t getNbLogicOps() const;
std::size_t getNbCompOps() const;
std::size_t getNbNLOps() const;
std::size_t getNbOps() const;
std::size_t getNbArithmIntOps() const;
std::size_t getNbArithmFpOps() const;
std::size_t getNbMACOps() const;
virtual void summary(bool incProducers = false) const;
protected:
const std::shared_ptr<GraphView> mGraph;
std::size_t accumulate(std::size_t (OperatorStats::*func)() const) const;
};
}
#endif /* AIDGE_CORE_ANALYSIS_STATICANALYSIS_H_ */
......@@ -17,7 +17,6 @@
#include "aidge/data/Tensor.hpp"
#include "aidge/utils/Registrar.hpp"
#include "aidge/utils/Types.h"
#include "aidge/utils/ErrorHandling.hpp"
#include "aidge/utils/future_std/span.hpp"
namespace Aidge {
......@@ -50,42 +49,24 @@ public:
void zeros() override final;
void copy(const void *src, NbElts_t length, NbElts_t offset = 0) override final {
AIDGE_ASSERT(offset + length <= mNbElts, "TensorImpl_cpu<{}>::copy(): copy offset ({}) + length ({}) is above capacity ({})", typeid(T).name(), offset, length, mNbElts);
const T* srcT = static_cast<const T *>(src);
T* dstT = static_cast<T *>(rawPtr(offset));
AIDGE_ASSERT(dstT < srcT || dstT >= srcT + length, "TensorImpl_cpu<{}>::copy(): overlapping copy is not supported", typeid(T).name());
std::copy_n(srcT, length, dstT);
}
void copy(const void *src, NbElts_t length, NbElts_t offset = 0) override final;
void copyCast(const void *src, const DataType srcDt, NbElts_t length, NbElts_t offset = 0) override final;
void copyFromDevice(const void *src, const std::pair<std::string, DeviceIdx_t>& device, NbElts_t length, NbElts_t offset = 0) override final {
AIDGE_ASSERT(device.first == Backend, "TensorImpl_cpu<{}>::copyFromDevice(): backend must match", typeid(T).name());
AIDGE_ASSERT(device.second == 0, "TensorImpl_cpu<{}>::copyFromDevice(): device ({}) cannot be != 0 for CPU backend", typeid(T).name(), device.second);
copy(src, length, offset);
}
void copyFromDevice(const void *src, const std::pair<std::string, DeviceIdx_t>& device, NbElts_t length, NbElts_t offset = 0) override final;
inline void copyFromHost(const void *src, NbElts_t length, NbElts_t offset = 0) override final {
copy(src, length, offset);
}
void copyToHost(void *dst, NbElts_t length, NbElts_t offset = 0) const override final {
const T* src = static_cast<const T*>(rawPtr(offset));
AIDGE_ASSERT(offset + length <= mData.size(), "TensorImpl_cpu<{}>::copy(): copy offset ({}) + length ({}) is above capacity ({})", typeid(T).name(), offset, length, mData.size());
std::copy(src, src + length, static_cast<T *>(dst));
}
void copyToHost(void *dst, NbElts_t length, NbElts_t offset = 0) const override final;
void *rawPtr(NbElts_t offset = 0) override final {
lazyInit();
return (mData.data() + offset);
};
const void *rawPtr(NbElts_t offset = 0) const override final {
AIDGE_ASSERT(mData.size() >= mNbElts, "TensorImpl_cpu<{}>::rawPtr(): accessing uninitialized const rawPtr", typeid(T).name());
return (mData.data() + offset);
};
const void *rawPtr(NbElts_t offset = 0) const override final;
void *hostPtr(NbElts_t offset = 0) override final {
lazyInit();
......@@ -97,23 +78,12 @@ public:
return (mData.data() + offset);
};
void setRawPtr(void *ptr, NbElts_t length) override final {
AIDGE_ASSERT(length >= mNbElts, "TensorImpl_cpu<{}>::setRawPtr(): trying to set raw pointer (length: {}) of insufficient capacity (required: {})", typeid(T).name(), length, mNbElts);
mData = future_std::span<T>(static_cast<T *>(ptr), length);
mDataOwner.reset();
};
void setRawPtr(void *ptr, NbElts_t length) override final;
virtual ~TensorImpl_cpu() = default;
private:
void lazyInit() {
if (mData.size() < mNbElts) {
// Need more data, a re-allocation will occur
AIDGE_ASSERT(mData.empty() || mDataOwner != nullptr, "TensorImpl_cpu<{}>: trying to enlarge non-owned data", typeid(T).name());
mDataOwner.reset(new T[mNbElts]);
mData = future_std::span<T>(mDataOwner.get(), mNbElts);
}
}
void lazyInit();
};
......
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_CASTIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_CASTIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
namespace Aidge {
class Cast_OpImpl : public OperatorImpl {
public:
Cast_OpImpl(const Operator& op, const std::string& backend = "")
: OperatorImpl(op, backend)
{}
void forward() override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_CASTIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_CONCATIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_CONCATIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
namespace Aidge {
/**
* @class Concat_OpImpl
* @brief Implementation of the Concat operator.
*
* Since Concat operation is backend-agnostic, its implementation is located in aidge_core.
*/
class Concat_OpImpl : public OperatorImpl {
public:
/**
* @brief Constructor for Concat_OpImpl.
* @param[in] op Operator instance.
* @param[in] backend Name of the backend.
*/
Concat_OpImpl(const Operator& op, const std::string& backend = "")
: OperatorImpl(op, backend)
{}
/**
* @brief Perform the forward pass of the Concat operator.
*/
void forward() override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_CONCATIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_DEPTHTOSPACEIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_DEPTHTOSPACEIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
namespace Aidge {
/**
* @class DepthToSpace_OpImpl
* @brief Implementation of the DepthToSpace operation for rearranging data from depth into spatial dimensions.
*/
class DepthToSpace_OpImpl : public OperatorImpl {
public:
/**
* @brief Constructor for the DepthToSpace_OpImpl.
* @param op Operator containing attributes for DepthToSpace.
* @param backend The backend used for computation.
*/
DepthToSpace_OpImpl(const Operator& op, const std::string& backend = "") : OperatorImpl(op, backend) {}
/**
* @brief Perform the forward computation for DepthToSpace.
*/
void forward() override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_DEPTHTOSPACEIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_FLATTENIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_FLATTENIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
#include "aidge/scheduler/ProdConso.hpp"
namespace Aidge {
/**
* @brief Implementation of the Flatten operation.
*
* Since Flatten operation is just backend-agnostic, its implementation is located in aidge_core.
*/
class Flatten_OpImpl : public OperatorImpl {
public:
/**
* @brief Constructor for Flatten operator implementation.
* @param op Operator instance.
* @param backend Optional. Name of the backend.
*/
Flatten_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {}
/**
* @brief Compute the forward pass of the Flatten operation.
*/
void forward() override;
std::shared_ptr<ProdConso> getProdConso() const override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_FLATTENIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_GATHERIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_GATHERIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
namespace Aidge {
/**
* @class Gather_OpImpl
* @brief Backend implementation for the Gather operation.
*
* The Gather operation selects elements from the input tensor based on specified indices
* and an axis, producing a tensor with a gathered shape.
*/
class Gather_OpImpl : public OperatorImpl {
public:
Gather_OpImpl(const Operator& op, const std::string& backend = "")
: OperatorImpl(op, backend) {}
/**
* @brief Execute the Gather operation.
*/
void forward() override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_GATHERIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_IDENTITYIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_IDENTITYIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
#include "aidge/scheduler/ProdConso.hpp"
namespace Aidge {
class Identity_OpImpl : public OperatorImpl {
public:
Identity_OpImpl(const Operator& op, const std::string& backend = "")
: OperatorImpl(op, backend) {}
void forward() override;
std::shared_ptr<ProdConso> getProdConso() const override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_IDENTITYIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_MEMORIZEIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_MEMORIZEIMPL_H_
#include <memory>
#include <string>
#include <vector>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/data/Elts.hpp"
#include "aidge/operator/Operator.hpp"
#include "aidge/scheduler/ProdConso.hpp"
#include "aidge/utils/Types.h"
namespace Aidge {
/**
* @class Memorize_ProdConso
* @brief Implements the producer-consumer principle for the `Memorize` operator.
*
* The `Memorize_ProdConso` class defines the logic for managing data dependencies during
* the forward process of the `Memorize` operator.
*
* This class ensures that:
* - All data produced by the `Memorize` operator is properly consumed.
* - All required outputs are correctly filled during the forward pass.
*
* It also calculates data and memory requirements specific to the `Memorize` operator.
*/
class Memorize_ProdConso : public ProdConso {
public:
/**
* @brief Constructor for the `Memorize_ProdConso` class.
* @param[in] op The operator instance for which producer-consumer relationships are managed.
*
* @details:
* - The provided `Operator` instance is used to initialize the base `ProdConso` class.
* - This operator will determine the specific requirements for data production
* and consumption during the forward process.
*/
Memorize_ProdConso(const Operator& op): ProdConso(op) {}
/**
* @brief Get the number of data elements required from an input tensor for forward computation.
* @param[in] inputIdx The index of the input tensor.
* @return The number of required elements (`Elts_t`).
*
* @details:
* - For each input tensor identified by `inputIdx`, this method calculates the
* minimum amount of data needed by the `Memorize` operator to perform its forward step.
*/
Elts_t getNbRequiredData(const IOIndex_t inputIdx) const override final;
/**
* @brief Compute the memory requirements for an output tensor.
* @param[in] outputIdx The index of the output tensor.
* @param[in] inputsSize A vector containing the dimensions of the input tensors.
* @return The memory required (`Elts_t`) for the specified output tensor.
*
* @details:
* - This method evaluates how much memory is needed for the `outputIdx` tensor
* based on the input tensor dimensions and the attributes of the `Memorize` operator.
* - Memory requirements are influenced by factors such as sequence length and
* the forward step configuration.
*/
Elts_t getRequiredMemory(const IOIndex_t outputIdx, const std::vector<DimSize_t>& inputsSize) const override final;
/**
* @brief Update the producer-consumer relationships for the `Memorize` operator.
* @details:
* - This method ensures that all data produced by the `Memorize` operator is
* appropriately consumed by downstream operators in the computational graph.
* - It also verifies that all required outputs are filled during the forward pass,
* maintaining consistency in the data flow.
* - This step is crucial for ensuring correctness in recurrent computations and
* maintaining dependencies in the graph.
*/
void updateConsummerProducer() override;
};
/**
* @brief Implementation of the Memorize operation.
*
* Since Memorize operation is just backend-agnostic, its implementation is located in aidge_core.
*/
class Memorize_OpImpl : public OperatorImpl {
public:
/**
* @brief Constructs a Memorize_OpImpl object.
* @param[in] op The operator to be implemented.
* @param[in] backend The backend used for execution.
*/
Memorize_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {}
/**
* @brief Get the Producer Consumer object of the operator.
* @return A shared pointer to the ProdConso object.
*/
std::shared_ptr<ProdConso> getProdConso() const override { return std::make_shared<Memorize_ProdConso>(mOp); };
/**
* @brief Executes the forward pass for the Memorize operation.
*/
void forward() override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_MEMORIZEIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_MOVEIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_MOVEIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
namespace Aidge {
class Move_OpImpl : public OperatorImpl {
public:
Move_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {}
void forward() override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_MOVEIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_POPIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_POPIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
namespace Aidge {
/**
* @class Pop_ProdConso
* @brief Implements the producer-consumer principle for the `Pop` operator.
*
* The `Pop_ProdConso` class defines the logic for managing data dependencies during
* the forward process of the `Pop` operator.
*
* This class ensures that:
* - All data consumed by the `Pop` operator is correctly handled.
* - The operator respects memory and data requirements during the forward computation.
*/
class Pop_ProdConso : public ProdConso {
public:
/**
* @brief Constructor for the `Pop_ProdConso` class.
* @param[in] op The operator instance for which producer-consumer relationships are managed.
*
* @details:
* - The provided `Operator` instance is used to initialize the base `ProdConso` class.
* - This operator determines specific requirements for data consumption during the forward process.
*/
Pop_ProdConso(const Operator& op): ProdConso(op) {}
/**
* @brief Get the number of data elements required from an input tensor for forward computation.
* @param[in] inputIdx The index of the input tensor.
* @return The number of required elements (`Elts_t`).
*
* @details:
* - For each input tensor identified by `inputIdx`, this method calculates the
* minimum amount of data needed by the `Pop` operator to perform its forward step.
*/
Elts_t getNbRequiredData(const IOIndex_t inputIdx) const override;
};
/**
* @class Pop_OpImpl
* @brief Implementation of the `Pop` operation.
*
* The `Pop_OpImpl` class defines the backend-agnostic logic for executing
* the forward pass of the `Pop` operator.
*/
class Pop_OpImpl : public OperatorImpl {
public:
/**
* @brief Constructs a `Pop_OpImpl` object.
* @param[in] op The operator to be implemented.
* @param[in] backend The backend used for execution (optional).
*/
Pop_OpImpl(const Operator& op, const std::string& backend = ""): OperatorImpl(op, backend) {}
/**
* @brief Get the Producer Consumer object of the operator.
* @return A shared pointer to the `Pop_ProdConso` object.
*/
std::shared_ptr<ProdConso> getProdConso() const override { return std::make_shared<Pop_ProdConso>(mOp); }
/**
* @brief Executes the forward pass for the `Pop` operation.
*/
void forward() override;
/**
* @brief Executes the backward pass for the `Pop` operation.
*/
void backward() override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_POPIMPL_H_
/********************************************************************************
* Copyright (c) 2023 CEA-List
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* SPDX-License-Identifier: EPL-2.0
*
********************************************************************************/
#ifndef AIDGE_CORE_BACKEND_GENERIC_OPERATOR_RESHAPEIMPL_H_
#define AIDGE_CORE_BACKEND_GENERIC_OPERATOR_RESHAPEIMPL_H_
#include <string>
#include "aidge/backend/OperatorImpl.hpp"
#include "aidge/operator/Operator.hpp"
#include "aidge/scheduler/ProdConso.hpp"
namespace Aidge {
/**
* @brief Implementation of the Reshape operator.
* @note This operator implementation is agnostic to the backend and is located here instead of in aidge_backend.
*/
class Reshape_OpImpl : public OperatorImpl {
public:
/**
* @brief Constructor for Reshape_OpImpl.
* @param[in] op The Operator instance.
* @param[in] backend The backend name (optional).
*/
Reshape_OpImpl(const Operator& op, const std::string& backend = "")
: OperatorImpl(op, backend) {}
/**
* @brief Perform the forward operation for the reshape.
*/
void forward() override;
void backward() override;
std::shared_ptr<ProdConso> getProdConso() const override;
};
} // namespace Aidge
#endif // AIDGE_CORE_BACKEND_GENERIC_OPERATOR_RESHAPEIMPL_H_