| 401 | } |
| 402 | |
| 403 | StatusOr<mlir::ElementsAttr> ConvertIntBuffer( |
| 404 | mlir::RankedTensorType shaped_type, mlir::Type elem_type, |
| 405 | const std::vector<uint8_t>& buffer) { |
| 406 | unsigned bit_width; |
| 407 | if (auto itype = elem_type.dyn_cast<mlir::IntegerType>()) { |
| 408 | bit_width = itype.getWidth(); |
| 409 | } else if (auto qtype = elem_type.dyn_cast<QuantizedType>()) { |
| 410 | bit_width = qtype.getStorageTypeIntegralWidth(); |
| 411 | shaped_type = mlir::RankedTensorType::get(shaped_type.getShape(), |
| 412 | qtype.getStorageType()); |
| 413 | } else { |
| 414 | return errors::InvalidArgument("unsupported integer constant type"); |
| 415 | } |
| 416 | |
| 417 | switch (bit_width) { |
| 418 | case 1: { |
| 419 | // vector<bool> doesn't convert to an ArrayRef |
| 420 | llvm::SmallVector<bool, 8> values; |
| 421 | values.reserve(buffer.size()); |
| 422 | for (auto b : buffer) { |
| 423 | values.emplace_back(b != 0); |
| 424 | } |
| 425 | return DenseElementsAttr::get(shaped_type, ArrayRef<bool>(values)); |
| 426 | } |
| 427 | case 8: { |
| 428 | return DenseElementsAttr::get(shaped_type, ArrayRef<uint8_t>(buffer)); |
| 429 | } |
| 430 | case 16: { |
| 431 | auto values = ReadAsLittleEndian<uint16_t>(buffer); |
| 432 | return DenseElementsAttr::get(shaped_type, ArrayRef<uint16_t>(values)); |
| 433 | } |
| 434 | case 32: { |
| 435 | auto values = ReadAsLittleEndian<uint32_t>(buffer); |
| 436 | return DenseElementsAttr::get(shaped_type, ArrayRef<uint32_t>(values)); |
| 437 | } |
| 438 | case 64: { |
| 439 | auto values = ReadAsLittleEndian<uint64_t>(buffer); |
| 440 | return DenseElementsAttr::get(shaped_type, ArrayRef<uint64_t>(values)); |
| 441 | } |
| 442 | default: |
| 443 | return errors::Unimplemented("Cannot handle bit width ", bit_width); |
| 444 | } |
| 445 | } |
| 446 | |
| 447 | StatusOr<Operation*> BuildExternalConstOp(const tflite::TensorT& tensor, |
| 448 | int32_t buffer_index, |
no test coverage detected