Improve UI for Operator/Node/GraphView/Tensor
Context
Analysing Operators and their parameters is currently complicated.
Printing any aidge object except Tensor doesn't provide any information for its user. Moreover, Operators' attributes are complicated to get and use the PascalCase convention of C++
>>> import aidge_core as ai
>>> op = ai.ConvOp2D([5,5])
>>> op
<aidge_core.aidge_core.ConvOp2D object at 0x7fb249aec630>
>>> op.get_attrs_name()
{'KernelDims', 'NoBias', 'StrideDims', 'DilationDims'}
>>> op.KernelDims
[5, 5]
The aim of this MR is to provide a more userfriendly interface with Aidge objects, especially Operators, and make access and use of attributes highly intuitive for Python users. I think accessing parameters shoud not be an obstacle.
Here is a glimpse at the proposed interface:
>>> import aidge_core as ai
>>> ai.ConvOp2D([5,5])
Operator(type = 'Conv', nb_in = 3, nb_out = 1, attr = AttrDict({'stride_dims': [1, 1], 'dilation_dims': [1, 1], 'kernel_dims': [5, 5], 'no_bias': False}), backend = None)
>>> import aidge_backend_cpu
>>> op.set_backend("cpu")
Operator(type = 'Conv', nb_in = 3, nb_out = 1, attr = AttrDict({'stride_dims': [1, 1], 'dilation_dims': [1, 1], 'kernel_dims': [5, 5], 'no_bias': False}), backend = 'cpu')
>>> gop = ai.GenericOperatorOp('Custom', 1, 0, 1)
>>> gop
Operator(type = 'Custom', nb_in = 1, nb_out = 1, attr = AttrDict({}), backend = '')
>>> gop.attr
AttrDict({})
>>> gop.attr.dummy_parameter
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: map::at
>>> gop.attr.DummyParamter
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: map::at
>>> gop.attr.something = 3
>>> gop.attr.something
3
>>> gop.attr
AttrDict({'something': 3})
>>> d = op.attr.dict() # convert attributes to a dictionnary
>>> d.keys()
dict_keys(['stride_dims', 'dilation_dims', 'kernel_dims', 'no_bias'])
>>> ai.GraphView()
GraphView(name='', Nodes: 0 (inputs: 0, outputs: 0))
>>> n_relu = ai.ReLU()
>>> n_prod = ai.Producer([1,1])
>>> n_relu
Node(name='', optype='ReLU', parents: [0], children: [[]]) # One parent, not connected, one child, not connected
>>> n_prod
Node(name='', optype='Producer', children: [[]]) # no parent, one child, not connected
>>> n_relu(n_prod())
>>> n_relu
Node(name='', optype='ReLU', parents: [1], children: [[]]) # change from 0 to 1 => connected
>>> n_prod
Node(name='', optype='Producer', children: [[1]]) # child connected to one node
Modified files
Attribute.hpp
, StaticAttribute.hpp
, DynamicAttribute.hpp
Every Operator hpp, cpp, python binding
Major modification
Operators do not inherit from Attributes base class anymore. There is now a member attribute of type Attribute in the Operator.
Also:
- fix
Softmax
import in case of negative axis - add
TargetType
parameter toCast
Operator - change aidge_core.DataType.Float32 to aidge_core.dtype.float32 (and each other type to lower case as well)
TODO in following MR
- Create a way to easily access MetaOperator attributes
- Inputs / Outputs access using names or idx
>>> op = ai.Conv2DOp([5,5])
>>> op.i.data # return data input Tensor
>>> op.i.weight # return weight input Tensor
>>> op.inputs # return list of inputs iterable so that (op.inputs[0] == op.i.data)
- fix
GraphView::forward_dims()
#125, currently tmp fix in this MR - enhance
GraphView::getNode()
, also part of enhancing MetaOperator - Better handle optional inputs #126 (closed)
- UI for
Connector
object - Have a uniform interface for DynamicAttributes and StaticAttributes when an attribute is not found