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 (2)
......@@ -180,6 +180,19 @@ size_t convToMatMul(std::shared_ptr<GraphView> graph);
*/
void adaptToBackend(std::shared_ptr<GraphView> graph);
// /**
// * @brief The node passed contains an operator which input of index 1 is supposed be be weights of type Int4, Int3, Int2, binary.
// * This recipie only operates memory transformations on the weight tensor.
// * First, permutes the dimensions to match the dataformat NHWC
// * Second, compact the last dimension (Channel dimension) into int8_t
// *
// * @param node Node
// */
// void applyWeightInterleaving(std::shared_ptr<Node> node);
void toGenericOp(std::shared_ptr<Node> node);
} // namespace Aidge
#endif /* AIDGE_CORE_UTILS_RECIPES_H_ */
......@@ -34,6 +34,12 @@ namespace py = pybind11;
namespace Aidge {
// Detection idiom to check if a type T has a less-than operator
template <typename T, typename = void>
struct has_less_than_operator : std::false_type {};
template <typename T>
struct has_less_than_operator<T, std::void_t<decltype(std::declval<T>() < std::declval<T>())>> : std::true_type {};
///\todo store also a fix-sized code that indicates the type
///\todo managing complex types or excluding non-trivial, non-aggregate types
......@@ -344,6 +350,14 @@ public:
}
};
template<typename T>
static inline typename std::enable_if<!has_less_than_operator<T>::value, void>::type makeTypeConditionallyAvailable() {}
template<typename T>
static inline typename std::enable_if<has_less_than_operator<T>::value, void>::type makeTypeConditionallyAvailable() {
mAnyUtils.emplace(typeid(T), std::unique_ptr<AnyUtils<T>>(new AnyUtils<T>()));
}
// Stores typed utils functions for each attribute type ever used
static std::map<std::type_index, std::unique_ptr<AnyUtils_>> mAnyUtils;
};
......@@ -407,6 +421,19 @@ namespace std {
return seed;
}
};
// Special case for std::array
template <typename T, std::size_t N>
struct hash<std::array<T, N>> {
std::size_t operator()(const std::array<T, N>& iterable) const {
std::size_t seed = 0;
for (const auto& v : iterable) {
// Recursively hash the value pointed by the iterator
Aidge::hash_combine(seed, std::hash<T>()(v));
}
return seed;
}
};
}
namespace future_std {
......
......@@ -24,6 +24,7 @@
#endif
#include "aidge/utils/Attributes.hpp"
#include "aidge/utils/DynamicAttributes.hpp"
#include "aidge/utils/ErrorHandling.hpp"
namespace Aidge {
......@@ -322,7 +323,11 @@ private:
inline typename std::enable_if<I == sizeof...(Tp), void>::type appendAttr(const std::tuple<Tp...>& /*t*/, std::map<std::string, future_std::any>& /*attrs*/) const {}
template<std::size_t I = 0, typename... Tp>
inline typename std::enable_if<I < sizeof...(Tp), void>::type appendAttr(const std::tuple<Tp...>& t, std::map<std::string, future_std::any>& attrs) const {
inline typename std::enable_if<I < sizeof...(Tp), void>::type appendAttr(const std::tuple<Tp...>& t, std::map<std::string, future_std::any>& attrs) const {
// Ensure that the type will be known to DynamicAttributes
using ElementType = typename std::tuple_element<I,std::tuple<Tp...>>::type;
DynamicAttributes::makeTypeConditionallyAvailable<ElementType>();
attrs.insert(std::make_pair(EnumStrings<ATTRS_ENUM>::data[I], future_std::any(std::get<I>(t))));
appendAttr<I + 1, Tp...>(t, attrs);
}
......
......@@ -144,6 +144,13 @@ void init_Recipes(py::module &m)
:param graph_view: Graph view on which we want to apply the recipe
:type graph_view: :py:class:`aidge_core.GraphView`
)mydelimiter");
m.def("to_generic_op", toGenericOp, py::arg("node"), R"mydelimiter(
Transform to a Generic Operator.
:param node: Node which Operator will turn into a Generic Operator
:type graph_view: :py:class:`aidge_core.Node`
)mydelimiter");
}
} // namespace Aidge
......@@ -22,7 +22,8 @@
Aidge::GenericOperator_Op::GenericOperator_Op(const std::string& type,
const std::vector<Aidge::InputCategory>& inputsCategory,
Aidge::IOIndex_t nbOut)
: OperatorTensor(type, inputsCategory, nbOut)
: OperatorTensor(type, inputsCategory, nbOut),
mAttributes(std::make_shared<DynamicAttributes>())
{
mImpl = std::make_shared<OperatorImpl>(*this);
}
......
/********************************************************************************
* 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
*
********************************************************************************/
#include <memory>
#include "aidge/graph/Node.hpp"
#include "aidge/graph/GraphView.hpp"
#include "aidge/operator/GenericOperator.hpp"
#include "aidge/recipes/Recipes.hpp"
void Aidge::toGenericOp(std::shared_ptr<Node> node) {
auto newGenOp = {GenericOperator(node->type(), std::dynamic_pointer_cast<Aidge::OperatorTensor>(node->getOperator()), node->name())};
auto OldOp = {node};
GraphView::replace(OldOp, newGenOp);
}
/********************************************************************************
* 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
*
********************************************************************************/
#include <catch2/catch_test_macros.hpp>
#include <memory>
#include <set>
#include "aidge/graph/GraphView.hpp"
#include "aidge/graph/OpArgs.hpp"
#include "aidge/operator/Conv.hpp"
#include "aidge/operator/FC.hpp"
#include "aidge/operator/ReLU.hpp"
#include "aidge/operator/GenericOperator.hpp"
#include "aidge/recipes/Recipes.hpp"
namespace Aidge {
TEST_CASE("[graph/convert] toGenericOp", "[toGenericOp][recipies]") {
// Create a convolution operator
std::shared_ptr<GraphView> g =
Sequential({
Conv(1, 3, {3, 3}, "conv1"),
ReLU(),
Conv(3, 4, {1, 1}, "conv2"),
ReLU(),
Conv(4, 3, {1, 1}, "conv3"),
ReLU(),
FC(2028, 256, false, "fc1"),
ReLU(),
FC(256, 10, false, "fc2")});
// NCHW - MNIST DATA like
g->forwardDims({{5, 1, 28, 28}});
SECTION("Test Operator to Generic Operator") {
auto convOp = g->getNode("conv2");
// Convert to GenericOperator
toGenericOp(convOp);
auto newGenOp = g->getNode("conv2");
// Ensure the conversion
REQUIRE(newGenOp->type() == "Conv2D");
const auto convOpAttr = convOp->getOperator()->attributes()->getAttrs();
const auto newGenOpAttr = (newGenOp->getOperator()->attributes()->getAttrs());
REQUIRE((!(newGenOpAttr < convOpAttr) && !(convOpAttr < newGenOpAttr)));
}
SECTION("Test MetaOperator to Generic Operator") {
const auto nbFused = fuseToMetaOps(g, "Conv2D->ReLU->FC", "ConvReLUFC");
REQUIRE(nbFused == 1);
std::shared_ptr<Node> metaOpNode;
for (const auto& nodePtr : g->getNodes())
{
if (nodePtr->type() == "ConvReLUFC")
{
nodePtr->setName("ConvReLUFC_0");
metaOpNode = nodePtr;
// Convert to GenericOperator
toGenericOp(nodePtr);
}
}
auto newGenOp = g->getNode("ConvReLUFC_0");
// Ensure the conversion
REQUIRE(newGenOp->type() == "ConvReLUFC");
const auto metaOpAttr = *std::static_pointer_cast<DynamicAttributes>(metaOpNode->getOperator()->attributes());
const auto newGenOpAttr = *std::static_pointer_cast<DynamicAttributes>(newGenOp->getOperator()->attributes());
REQUIRE((!(newGenOpAttr < metaOpAttr) && !(metaOpAttr < newGenOpAttr)));
}
}
} // namespace Aidge