| 90 | class GeometryReduce : public GeometryComputer { |
| 91 | public: |
| 92 | virtual bool onCompute(const Op* op, const std::vector<Tensor*>& inputs, const std::vector<Tensor*>& outputs, |
| 93 | Context& context, CommandBuffer& res) const override { |
| 94 | MNN_ASSERT(1 == outputs.size()); |
| 95 | MNN_ASSERT(inputs.size() >= 1); |
| 96 | auto reduct = op->main_as_ReductionParam(); |
| 97 | auto reductOp = reduct->operation(); |
| 98 | std::vector<int> axises; |
| 99 | if (inputs.size() >= 2) { |
| 100 | auto size = inputs[1]->elementSize(); |
| 101 | auto dims = inputs[1]->host<int32_t>(); |
| 102 | for (int i = 0; i < size; ++i) { |
| 103 | axises.emplace_back(dims[i]); |
| 104 | } |
| 105 | } else { |
| 106 | auto reduct = op->main_as_ReductionParam(); |
| 107 | if (nullptr != reduct->dim()) { |
| 108 | for (int i = 0; i < reduct->dim()->size(); ++i) { |
| 109 | axises.emplace_back(reduct->dim()->data()[i]); |
| 110 | } |
| 111 | } |
| 112 | } |
| 113 | for (int i = 0; i < axises.size(); ++i) { |
| 114 | if (axises[i] < 0) { |
| 115 | axises[i] = inputs[0]->dimensions() + axises[i]; |
| 116 | } |
| 117 | } |
| 118 | if (1 == axises.size() && TensorUtils::getDescribe(inputs[0])->dimensionFormat != MNN_DATA_FORMAT_NC4HW4 && TensorUtils::getDescribe(outputs[0])->dimensionFormat != MNN_DATA_FORMAT_NC4HW4) { |
| 119 | auto cmd = GeometryComputerUtils::makeReduce(reductOp, inputs[0], outputs[0], axises[0]); |
| 120 | res.command.emplace_back(std::move(cmd)); |
| 121 | return true; |
| 122 | } |
| 123 | // prod([]) = 1 |
| 124 | if (inputs[0]->elementSize() == 0) { |
| 125 | if(!context.allocTensor(outputs[0])) { |
| 126 | return false; |
| 127 | } |
| 128 | float res; |
| 129 | switch (reductOp) { |
| 130 | case ReductionType_PROD: |
| 131 | res = 1.0f; |
| 132 | break; |
| 133 | default: |
| 134 | res = 0.0f; |
| 135 | break; |
| 136 | } |
| 137 | if (outputs[0]->getType() == halide_type_of<float>()) { |
| 138 | outputs[0]->host<float>()[0] = (float)res; |
| 139 | } else { |
| 140 | outputs[0]->host<int>()[0] = (int)res; |
| 141 | } |
| 142 | return true; |
| 143 | } |
| 144 | auto reduceDims = _computeReduceDims(inputs, axises); |
| 145 | Tensor* currentInput = inputs[0]; |
| 146 | MNN_ASSERT(reduceDims.size() > 0); |
| 147 | auto dimType = currentInput->getDimensionType(); |
| 148 | for (int i = 0; i < reduceDims.size(); ++i) { |
| 149 | auto& iter = reduceDims[i]; |
nothing calls this directly
no test coverage detected