| 140 | } |
| 141 | |
| 142 | ErrorCode GeometryComputerUtils::shapeComputeAndGeometryTransform( |
| 143 | const Runtime* cpuRuntime, |
| 144 | FileLoader* external, |
| 145 | std::vector<Schedule::OpCacheInfo>& infos, |
| 146 | GeometryComputer::Context& geoContext, |
| 147 | std::shared_ptr<Backend> backupBackend, |
| 148 | Runtime::CompilerType compileType, |
| 149 | bool skipShapeCompute, |
| 150 | bool permitCodegen) { |
| 151 | bool openCache = geoContext.support(Interpreter::GeometryComputeMask::GEOMETRCOMPUTEMASK_OPENCACHE); |
| 152 | /** Size Compute and compute Const Begin */ |
| 153 | GeometryComputer::Context ctx(Interpreter::GeometryComputeMask::GEOMETRCOMPUTEMASK_ALL, backupBackend); |
| 154 | bool needRelease = geoContext.mNeedRelease; |
| 155 | // Size Compute and compute Const |
| 156 | for (int i=0; i<infos.size(); ++i) { |
| 157 | auto& info = infos[i]; |
| 158 | auto& cmdBufferVir = info.executeBuffer; |
| 159 | auto& tempBuffer = info.cacheBuffer; |
| 160 | // TODO: Optimize |
| 161 | for (auto t : info.outputs) { |
| 162 | if (!TensorUtils::getDescribe(t)->isMutable) { |
| 163 | continue; |
| 164 | } |
| 165 | auto des = TensorUtils::getDescribe(t); |
| 166 | auto usage = des->usage; |
| 167 | auto type = des->memoryType; |
| 168 | MNN_ASSERT(type != Tensor::InsideDescribe::MEMORY_OUTSIDE); |
| 169 | MNN_ASSERT(type != Tensor::InsideDescribe::MEMORY_HOST); |
| 170 | if (TensorUtils::getDescribeOrigin(t)->mContent.use_count() > 1) { |
| 171 | TensorUtils::getDescribeOrigin(t)->mContent.reset(new Tensor::InsideDescribe::NativeInsideDescribe); |
| 172 | t->buffer().dim = TensorUtils::getDescribe(t)->dims; |
| 173 | TensorUtils::getDescribeOrigin(t)->setBackend(nullptr); |
| 174 | TensorUtils::getDescribeOrigin(t)->mem = nullptr; |
| 175 | TensorUtils::getDescribe(t)->usage = usage; |
| 176 | info.computeCache.close(); |
| 177 | } else if (des->group == 0) { |
| 178 | if (info.type != Schedule::CONSTANT && usage != Tensor::InsideDescribe::TRAINABLE) { |
| 179 | TensorUtils::getDescribeOrigin(t)->setBackend(nullptr); |
| 180 | // TODO: If output is static and length larger than new size, don't clear mem |
| 181 | TensorUtils::getDescribeOrigin(t)->mem = nullptr; |
| 182 | } |
| 183 | } |
| 184 | } |
| 185 | for (auto t : info.outputs) { |
| 186 | TensorUtils::getDescribe(t)->stageMask &= (~Tensor::InsideDescribe::StageInfo::COMPUTE_SHAPE_STAGE); |
| 187 | } |
| 188 | bool compared = false; |
| 189 | bool needCompute = !info.computeCache.match(info.inputs, compared); |
| 190 | if (needCompute && compared) { |
| 191 | // If not match, means the op's shape is mutable, close cache and don't compare |
| 192 | info.computeCache.close(false); |
| 193 | } |
| 194 | if ((!skipShapeCompute) && needCompute) { |
| 195 | auto res = SizeComputer::computeOutputSize(info.op, info.inputs, info.outputs); |
| 196 | if (!res) { |
| 197 | if (info.op->name() != nullptr) { |
| 198 | MNN_ERROR("Compute Shape Error for %s\n", info.op->name()->c_str()); |
| 199 | } else { |
nothing calls this directly
no test coverage detected