"arm_compute::DataLayoutDimension::BATCHES"};
assert(op.getAxis() < sizeof(axis_names) / sizeof(const char*));
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
auto prefix = out->name() + "_concatenate_layer";
auto inputs_var = _constrBlock->var("std::vector<arm_compute::ICLTensor*>", prefix + "_inputs");
auto inputs = inputs_var->use();
assert(prev_nodes.size() == 1);
auto in_node = prev_nodes[0].node;
auto in = AF::id(tensorName(in_node));
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
auto sm_layer_var = _artifactClass->var(false, "arm_compute::CLSoftmaxLayer",
out->name() + "_softmax_layer");
auto sm_layer = sm_layer_var->use();
auto in_node = prev_nodes[0].node;
auto in = AF::id(tensorName(in_node));
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
auto prefix = out->name() + "_pooling_layer";
auto pad_stride_info_var = _constrBlock->var("arm_compute::PadStrideInfo",
auto in = AF::id(tensorName(in_node));
// Create the output tensor in the DOM.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
string operation_name = out->name() + "_fully_connected_layer";
// Create the weights tensor in the DOM and use its id.
auto weights = genTensor(operation_name + "_weights", ir_weights_shape);
// Serialize the weights tensor and generate the function to deserialize it in the artifact.
- serializeTensor<3, 2, 1, 0>(ir_weights);
+ serializeTensor(ir_weights);
_constrBlock->call("deserializeTensor", {_parIn, weights});
// Instantiate the CLFullyConnectedLayer object.
auto in = AF::id(tensorName(in_node));
// Create the output tensor in the DOM and obtain its identifier.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
// Prefix used for the name of variables related to the operation implementation.
string operation_name = out->name() + "_bias_add_layer";
}
void AclCppOpGenerator::visit(INode* node, ops::VariableOp& op) {
- genTensor(node, op);
+ // Axes order is HWC in the Model IR and WHC in the ACL library, so we are switching the first
+ // two dimensions.
+ genTensor(node, transposeShape<1, 0, 2>(op.getOutputShape(0)));
}
void AclCppOpGenerator::visit(INode* node, ops::ReluOp& op) {
auto in = AF::id(tensorName(in_node));
// Create the output tensor in the DOM and return its id.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
// Create an instance of the CLReshapeLayer class as a member of the artifact class.
auto reshape_layer_var = _artifactClass->var(false, "arm_compute::CLReshapeLayer",
auto in = AF::id(tensorName(in_node));
// Generate output tensor description in the DOM.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
auto prefix = out->name() + "_scale_layer";
// Create a CLPixelWiseMultiplication instance.
auto in = AF::id(tensorName(in_node));
// Generate output tensor description in the DOM.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
// Create a CLCopy instance.
auto copy_layer_var = _artifactClass->var(false, "arm_compute::CLCopy",
void AclCppOpGenerator::visit(INode* node, ops::ElementwiseOp& op) {
// Create the output tensor in the DOM and obtain its identifier.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
auto& prev_nodes = node->getPrevNodes();
assert(prev_nodes.size() >= 2);
template <typename Op>
void AclCppOpGenerator::genConvolution(INode* node, Op& op, const string& acl_func_name,
const string& suffix) {
- const TensorVariant& ir_weights = op.getKernel();
- const Shape& ir_weights_shape = ir_weights.getShape();
+ auto ir_weights = transposeTensor<1, 0, 2, 3>(make_shared<TensorVariant>(op.getKernel()));
+ const Shape& ir_weights_shape = ir_weights->getShape();
assert(ir_weights_shape.rank() == 4);
Shape ir_biases_shape({ir_weights_shape.dim(-1)});
const Shape& strides = op.getStrides();
auto in = AF::id(tensorName(in_node));
// Create the output tensor in the DOM.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, transposeShape<1, 0, 2>(op.getOutputShape(0)));
string operation_name = out->name() + suffix;
// Generate a tensor for weights (kernel) in the DOM.
auto weights = genTensor(operation_name + "_weights", ir_weights_shape);
// Save the IR weights tensor to later read this in the artifact.
- serializeTensor<3, 2, 1, 0>(ir_weights);
+ serializeTensor(*ir_weights);
_constrBlock->call("deserializeTensor", {_parIn, weights});
// Create a local variable of type PadStrideInfo in the artifact constructor:
auto in = AF::id(tensorName(in_node));
// Create the output tensor in the DOM and return its id.
- auto out = genTensor(node, op);
+ auto out = genTensor(node, op.getOutputShape(0));
auto prefix = out->name() + "_activation_layer";
// Create an instance of the ActivationLayerInfo class as a local variable in the artifact
return id;
}
-shared_ptr<ArtifactId> AclCppOpGenerator::genTensor(INode* node, OpDescription& op) {
+shared_ptr<ArtifactId> AclCppOpGenerator::genTensor(INode* node, const Shape& ir_shape) {
if (node->getPrevNodes().empty())
_inputs.insert(node);
if (node->getNextNodes().empty())
_outputs.insert(node);
- return genTensor(tensorName(node), op.getOutputShape(0), !node->getName().empty());
+ return genTensor(tensorName(node), ir_shape, !node->getName().empty());
}
void AclCppOpGenerator::genNamed() {
}
}
-template<unsigned int... Ints>
void AclCppOpGenerator::serializeTensor(const TensorVariant& tensor) {
- shared_ptr<TensorVariant> to_tranpose = make_shared<TensorVariant>(tensor);
- shared_ptr<TensorVariant> transposed = transposeTensor<Ints...>(to_tranpose);
- const Shape& shape = transposed->getShape();
+ const Shape& shape = tensor.getShape();
+ Index coords;
+ coords.resize(shape.rank());
+ Index dimensions;
+ dimensions.resize(shape.rank());
+
+ for (int i = 0; i < shape.rank(); ++i) {
+ coords.at(i) = 0;
+ dimensions.at(i) = shape.dim(i);
+ }
+
+ for (;;) {
+ _parOut.write(tensor.at(coords), tensor.getElementSize());
+ bool stop = true;
+ int i;
- for (auto& idx: ShapeRange(shape))
- _parOut.write(tensor.at(idx), sizeof(float));
+ for (i = 0; i < shape.rank(); ++i) {
+ if(coords.at(i) < dimensions.at(i) - 1) {
+ ++coords.at(i);
+ stop = false;
+ break;
+ }
+ }
+
+ if (stop) {
+ break;
+ } else {
+ for (int j = 0; j < i; ++j)
+ coords.at(j) = 0;
+ }
+ }
}
void AclCppOpGenerator::visit(INode* node, ops::SqueezeOp& op) {