| 784 | } |
| 785 | |
| 786 | void UserKernel::ForwardShape(KernelContext* ctx) const { |
| 787 | const auto BnInOp2Blob = [ctx](const std::string& bn) { return ctx->BnInOp2Blob(bn); }; |
| 788 | infer_ctx_->UpdateArg2Tensor(BnInOp2Blob); |
| 789 | infer_cache_->UpdateCacheKey(infer_ctx_.get()); |
| 790 | if (!infer_cache_->IsCacheHit()) { |
| 791 | auto* op_infer_ctx = dynamic_cast<UserKernelOpInferContext*>(infer_ctx_->MutOpInferContext()); |
| 792 | CHECK_NOTNULL(op_infer_ctx); |
| 793 | op_infer_ctx->UpdateArg2TensorDesc(BnInOp2Blob); |
| 794 | kernel_->InferShape(infer_ctx_.get()); |
| 795 | for (const auto& out_arg_pair : infer_ctx_->outputs()) { |
| 796 | const Shape& static_shape = |
| 797 | infer_ctx_->TensorDesc4ArgNameAndIndex(out_arg_pair.first, out_arg_pair.second)->shape(); |
| 798 | const ShapeView& shape_view = |
| 799 | infer_ctx_->ShapeView4ArgNameAndIndex(out_arg_pair.first, out_arg_pair.second); |
| 800 | CHECK_LE(shape_view.elem_cnt(), static_shape.elem_cnt()) |
| 801 | << "InferShape of OpKernel (op_type_name: " << op_conf().user_conf().op_type_name() |
| 802 | << ", op_name: " << op_conf().name() |
| 803 | << ") raise error, output arg's (name: " << out_arg_pair.first |
| 804 | << ", index: " << out_arg_pair.second << ") runtime shape " << shape_view.ToString() |
| 805 | << " surpass the limit of static shape " << static_shape.ToString(); |
| 806 | } |
| 807 | infer_cache_->UpdateCacheValue(infer_ctx_.get()); |
| 808 | } else { |
| 809 | std::shared_ptr<const OpInferCacheValue> cache_value_ptr = infer_cache_->GetCacheValue(); |
| 810 | FOR_RANGE(int, i, 0, infer_ctx_->outputs().size()) { |
| 811 | const auto& out_arg_pair = infer_ctx_->outputs().at(i); |
| 812 | MutShapeView mut_shape_view = |
| 813 | infer_ctx_->MutShapeView4ArgNameAndIndex(out_arg_pair.first, out_arg_pair.second); |
| 814 | mut_shape_view.set_shape(*cache_value_ptr->obn_idx2shape_sym.at(i)); |
| 815 | } |
| 816 | } |
| 817 | } |
| 818 | |
| 819 | bool UserKernel::IsStateless() const { return !kernel_->AlwaysComputeWhenAllOutputsEmpty(); } |
| 820 | NEW_REGISTER_KERNEL(OperatorConf::kUserConf, UserKernel).SetIsMatchedPred([](const KernelConf&) { |
nothing calls this directly
no test coverage detected