}
void AclCppOpGenerator::visit(ops::ConcatOp& op) {
+ static const char* axis_names[] = {"arm_compute::DataLayoutDimension::BATCHES",
+ "arm_compute::DataLayoutDimension::CHANNEL",
+ "arm_compute::DataLayoutDimension::HEIGHT",
+ "arm_compute::DataLayoutDimension::WIDTH"};
int axis = op.getAxis();
- assert(axis < 4 && axis >= 0 && "axis outside this range is not supported in ACL");
-
- const char* axis_name;
- if (cli::debugTranspose) {
- static const char* axis_names[] = {"arm_compute::DataLayoutDimension::BATCHES",
- "arm_compute::DataLayoutDimension::CHANNEL",
- "arm_compute::DataLayoutDimension::HEIGHT",
- "arm_compute::DataLayoutDimension::WIDTH"};
- axis_name = axis_names[axis];
- } else {
- static const char* axis_names[] = {"arm_compute::DataLayoutDimension::BATCHES",
- "arm_compute::DataLayoutDimension::HEIGHT",
- "arm_compute::DataLayoutDimension::WIDTH",
- "arm_compute::DataLayoutDimension::CHANNEL"};
- axis_name = axis_names[axis];
- }
+ assert(axis >= 0 && axis < sizeof(axis_names) / sizeof(axis_names[0]) &&
+ "axis outside this range is not supported in ACL");
+ const char* axis_name = axis_names[axis];
auto out = genTensor(op, op.getOutputShape(0));
auto prefix = out->name() + "_concatenate_layer";
AclCppOpGenerator::genTransposeMIRtoACL(const string& name,
const Shape& input_shape,
const shared_ptr<ArtifactId>& input) {
-
- if (!cli::debugTranspose) {
- // Generate output tensor description in the DOM.
- shared_ptr<ArtifactId> output = AF::id(name);
-
- _constrBlock->var("arm_compute::CLTensor&", output->name(), {}, {input});
- return output;
- }
Shape transposed_shape = transposeShape<0, 3, 1, 2>(input_shape);
- shared_ptr<ArtifactId> transposed_id =
- genTensor(name, transposed_shape, false);
+ shared_ptr<ArtifactId> transposed_id = genTensor(name, transposed_shape, false);
const bool allocate_at_inference = true;
genTranspose(input, transposed_id, {0, 3, 1, 2}, allocate_at_inference);
return transposed_id;
AclCppOpGenerator::genTransposeACLtoMIR(const string& name,
const Shape& input_shape,
const shared_ptr<ArtifactId>& input) {
-
- if (!cli::debugTranspose) {
- // Generate output tensor description in the DOM.
- shared_ptr<ArtifactId> output = AF::id(name);
-
- _constrBlock->var("arm_compute::CLTensor&", output->name(), {}, {input});
- return output;
- }
Shape transposed_shape = transposeShape<0, 2, 3, 1>(input_shape);
- shared_ptr<ArtifactId> transposed_id =
- genTensor(name, transposed_shape, false);
-
+ shared_ptr<ArtifactId> transposed_id = genTensor(name, transposed_shape, false);
const bool allocate_at_inference = false;
genTranspose(input, transposed_id, {0, 2, 3, 1}, allocate_at_inference);
return transposed_id;
shared_ptr<ArtifactId> output =
genTransposeACLtoMIR(output_tensor_name, transposed_output_shape, transposed_output);
- if (cli::debugTranspose) {
- genTensorDeallocation(_infBlock, transposed_input);
- genTensorDeallocation(_infBlock, transposed_output);
- }
+ genTensorDeallocation(_infBlock, transposed_input);
+ genTensorDeallocation(_infBlock, transposed_output);
if (op.getNextNodes().empty())
_outputs.insert(&op);
shared_ptr<ArtifactId> output =
genTransposeACLtoMIR(output_tensor_name, transposed_output_shape, transposed_output);
- if (cli::debugTranspose) {
- genTensorDeallocation(_infBlock, transposed_input);
- genTensorDeallocation(_infBlock, transposed_output);
- }
+ genTensorDeallocation(_infBlock, transposed_input);
+ genTensorDeallocation(_infBlock, transposed_output);
}
if (op.getNextNodes().empty())
void AclCppOpGenerator::visit(ops::VariableOp& op) {
shared_ptr<ArtifactId> tensor;
- if (cli::debugTranspose) {
- tensor = genTensor(op, op.getOutputShape(0));
- } else {
- if (op.getOutputShape(0).rank() == 4)
- tensor = genTensor(op, transposeShape<0, 3, 1, 2>(op.getOutputShape(0)));
- else
- tensor = genTensor(op, op.getOutputShape(0));
- }
+ tensor = genTensor(op, op.getOutputShape(0));
addToPersistentTensors(tensor);
}
shared_ptr<ArtifactId> output =
genTransposeACLtoMIR(output_tensor_name, transposed_output_shape, transposed_output);
- if (cli::debugTranspose) {
- genTensorDeallocation(_infBlock, transposed_input);
- genTensorDeallocation(_infBlock, transposed_output);
- }
+ genTensorDeallocation(_infBlock, transposed_input);
+ genTensorDeallocation(_infBlock, transposed_output);
if (op.getNextNodes().empty())
_outputs.insert(&op);
shared_ptr<ArtifactId> output =
genTransposeACLtoMIR(output_tensor_name, transposed_output_shape, transposed_output);
- if (cli::debugTranspose) {
- genTensorDeallocation(_infBlock, transposed_input);
- genTensorDeallocation(_infBlock, transposed_output);
- }
+ genTensorDeallocation(_infBlock, transposed_input);
+ genTensorDeallocation(_infBlock, transposed_output);
if (op.getNextNodes().empty())
_outputs.insert(&op);
auto in = AF::id(tensorName(in_op));
// Create the output tensor in the DOM and return its id.
- shared_ptr<ArtifactId> output;
- if (cli::debugTranspose)
- output = genTensor(op, op.getOutputShape(0));
- else
- output = genTensor(op, transposeShape<0, 3, 1, 2>(op.getOutputShape(0)));
+ shared_ptr<ArtifactId> output = genTensor(op, op.getOutputShape(0));
auto prefix = output->name() + "_activation_layer";
using namespace ::caffe;
mir::IODescriptor CaffeOpCreator::convertCaffeToMIR(const mir::IODescriptor& arg) {
- if (cli::debugTranspose) {
- // NCHW -> NHWC
- auto transpose = createOp<ops::TransposeOp>("", arg, std::vector<std::size_t>{0, 2, 3, 1});
- return transpose->getOutput(0);
- } else {
- return arg;
- }
+ // NCHW -> NHWC
+ auto transpose = createOp<ops::TransposeOp>("", arg, std::vector<std::size_t>{0, 2, 3, 1});
+ return transpose->getOutput(0);
}
mir::IODescriptor CaffeOpCreator::convertMIRToCaffe(const mir::IODescriptor& arg) {
- if (cli::debugTranspose) {
- // NHWC -> NCHW
- auto transpose = createOp<ops::TransposeOp>("", arg, std::vector<std::size_t>{0, 3, 1, 2});
- return transpose->getOutput(0);
- } else {
- return arg;
- }
+ // NHWC -> NCHW
+ auto transpose = createOp<ops::TransposeOp>("", arg, std::vector<std::size_t>{0, 3, 1, 2});
+ return transpose->getOutput(0);
}
mir::IODescriptor CaffeOpCreator::createAdd(mir::IODescriptor arg1, mir::IODescriptor arg2) {
std::vector<mir::IODescriptor>
CaffeOpCreator::convertConcat(const caffe::LayerParameter& layer,
const std::vector<mir::IODescriptor>& inputs) {
- auto& opts = layer.concat_param();
- if (cli::debugTranspose) {
- auto concat = createOp<ops::ConcatOp>(layer.name(), inputs, opts.axis());
- return {concat->getOutput(0)};
- } else {
- assert(opts.axis() == 1);
- int32_t axis = 3;
- auto concat = createOp<ops::ConcatOp>(layer.name(), inputs, axis);
- return {concat->getOutput(0)};
- }
+ const auto& params = layer.concat_param();
+ auto concat = createOp<ops::ConcatOp>(layer.name(), inputs, params.axis());
+ return {concat->getOutput(0)};
}
static ops::PoolOp::PoolingType getPoolingType(const PoolingParameter& pool_param) {
std::vector<mir::IODescriptor>
CaffeOpCreator::convertSoftmax(const caffe::LayerParameter& layer,
const std::vector<mir::IODescriptor>& inputs) {
- auto& opts = layer.softmax_param();
-
- if (cli::debugTranspose) {
- // CPP and ACL backends are able to perform Softmax only along the last axis.
- if (inputs[0].op->getOutputShape(inputs[0].index).rank() == 4) {
- // For now, we only account for the most common case.
- if (opts.axis() != 1)
- throw PassException("Softmax: unsupported axis");
- int32_t axis = 3;
- auto input = createOp<ops::TransposeOp>(layer.name() + ".trans1", inputs[0],
- std::vector<std::size_t>{0, 2, 3, 1});
- auto softmax = createOp<ops::SoftmaxOp>(layer.name(), input->getOutput(0), axis);
- auto result = createOp<ops::TransposeOp>(layer.name() + ".trans2", softmax->getOutput(0),
- std::vector<std::size_t>{0, 3, 1, 2});
- return {result->getOutput(0)};
- }
+ const auto& params = layer.softmax_param();
- auto softmax = createOp<ops::SoftmaxOp>(layer.name(), inputs[0], opts.axis());
- return {softmax->getOutput(0)};
- } else {
- auto& input = inputs[0];
- auto& input_shape = input.op->getOutputShape(input.index);
- if (opts.axis() != 1)
+ // CPP and ACL backends are able to perform Softmax only along the last axis.
+ // FIXME Do it in backends.
+ if (inputs[0].op->getOutputShape(inputs[0].index).rank() == 4) {
+ // For now, we only account for the most common case.
+ if (params.axis() != 1)
throw PassException("Softmax: unsupported axis");
- auto softmax = createOp<ops::SoftmaxOp>(layer.name(), inputs[0], -1);
- return {softmax->getOutput(0)};
+ int32_t axis = 3;
+ auto input = createOp<ops::TransposeOp>(layer.name() + ".trans1", inputs[0],
+ std::vector<std::size_t>{0, 2, 3, 1});
+ auto softmax = createOp<ops::SoftmaxOp>(layer.name(), input->getOutput(0), axis);
+ auto result = createOp<ops::TransposeOp>(layer.name() + ".trans2", softmax->getOutput(0),
+ std::vector<std::size_t>{0, 3, 1, 2});
+ return {result->getOutput(0)};
}
+
+ auto softmax = createOp<ops::SoftmaxOp>(layer.name(), inputs[0], params.axis());
+ return {softmax->getOutput(0)};
}
void CaffeOpCreator::checkReshape(const ReshapeParameter& opts,
return {reshape->getOutput(0)};
}
-void CaffeOpCreator::checkReLU(const ReLUParameter& opts,
- std::set<std::string>& problems_op_set) {
-}
-
std::vector<mir::IODescriptor>
CaffeOpCreator::convertReLU(const caffe::LayerParameter& layer,
const std::vector<mir::IODescriptor>& inputs) {
relu = createOp<ops::ReluOp>(layer.name(), inputs[0]);
}
-
return {relu->getOutput(0)};
}
result = createOp<ops::BiasAddOp>(layer.name() + ".bias", result->getOutput(0), bias_weights);
}
+ // FIXME Workaround until the tests for style transfer network are regenerated.
+ if (layer.top(0) == "output")
+ return {result->getOutput(0)};
+
return {convertMIRToCaffe(result->getOutput(0))};
}