| 931 | } |
| 932 | |
| 933 | TfLiteStatus Subgraph::SetTensorParametersReadOnly( |
| 934 | int tensor_index, TfLiteType type, const char* name, const size_t rank, |
| 935 | const int* dims, TfLiteQuantization quantization, const char* buffer, |
| 936 | size_t bytes, const Allocation* allocation) { |
| 937 | // Ensure quantization cleanup on failure. |
| 938 | ScopedTfLiteQuantization scoped_quantization(&quantization); |
| 939 | if (state_ == kStateInvokableAndImmutable) { |
| 940 | ReportError( |
| 941 | "SetTensorParametersReadOnly is disallowed when graph is immutable."); |
| 942 | return kTfLiteError; |
| 943 | } |
| 944 | |
| 945 | TF_LITE_ENSURE(&context_, |
| 946 | tensor_index < context_.tensors_size && tensor_index >= 0); |
| 947 | // For most tensors we know exactly how much memory is necessary so we can |
| 948 | // ensure the buffer is large enough. However, we need to skip string tensors |
| 949 | // because their sizes change with the contents of the individual strings. |
| 950 | if (type != kTfLiteString) { |
| 951 | size_t required_bytes; |
| 952 | TF_LITE_ENSURE_OK(&context_, |
| 953 | BytesRequired(type, dims, rank, &required_bytes)); |
| 954 | TF_LITE_ENSURE_EQ(&context_, required_bytes, bytes); |
| 955 | } |
| 956 | |
| 957 | TfLiteTensor& tensor = context_.tensors[tensor_index]; |
| 958 | if (type == tensor.type && |
| 959 | EqualArrayAndTfLiteIntArray(tensor.dims, rank, dims)) { |
| 960 | // Fast path which does not invalidate the invokable property. |
| 961 | TfLiteTensorDataFree(&tensor); |
| 962 | TfLiteQuantizationFree(&tensor.quantization); |
| 963 | tensor.data.raw = const_cast<char*>(buffer); |
| 964 | if (!tensor.dims) tensor.dims = ConvertArrayToTfLiteIntArray(rank, dims); |
| 965 | tensor.params = GetLegacyQuantization(quantization); |
| 966 | tensor.quantization = *scoped_quantization.release(); |
| 967 | tensor.allocation_type = kTfLiteMmapRo; |
| 968 | tensor.allocation = allocation; |
| 969 | } else { |
| 970 | state_ = kStateUninvokable; |
| 971 | TfLiteTensorReset(type, name, ConvertArrayToTfLiteIntArray(rank, dims), |
| 972 | GetLegacyQuantization(quantization), |
| 973 | const_cast<char*>(buffer), bytes, kTfLiteMmapRo, |
| 974 | allocation, false, &tensor); |
| 975 | // TODO(suharshs): Update TfLiteTensorReset to include the new quantization |
| 976 | // if there are other required callers. |
| 977 | tensor.quantization = *scoped_quantization.release(); |
| 978 | } |
| 979 | return kTfLiteOk; |
| 980 | } |
| 981 | |
| 982 | // Set description of inputs/outputs/data/fptrs for node `node_index`. |
| 983 | // This variant assumes an external buffer has been allocated of size |