| 1708 | } |
| 1709 | |
| 1710 | void CheckIsReadyForQuantization(const Model& model) { |
| 1711 | for (const auto& op : model.operators) { |
| 1712 | for (const auto& input : op->inputs) { |
| 1713 | const auto& input_array = model.GetArray(input); |
| 1714 | if (input_array.data_type != ArrayDataType::kFloat) { |
| 1715 | // The array is not floats, no quantization needed. |
| 1716 | continue; |
| 1717 | } |
| 1718 | if (input_array.minmax) { |
| 1719 | // The array has minmax, we're good. |
| 1720 | continue; |
| 1721 | } |
| 1722 | if (input_array.buffer) { |
| 1723 | // The array has a constant buffer, so we can |
| 1724 | // fall back to computing the minmax from actual array entries |
| 1725 | // (with a WARNING about possible accuracy implications). |
| 1726 | continue; |
| 1727 | } |
| 1728 | LOG(FATAL) |
| 1729 | << "Array " << input << ", which is an input to the " |
| 1730 | << HelpfulOperatorTypeName(*op) << " operator producing the output " |
| 1731 | << "array " << op->outputs[0] << ", is lacking min/max data, " |
| 1732 | << "which is necessary for quantization. If accuracy matters, either " |
| 1733 | << "target a non-quantized output format, or run quantized training " |
| 1734 | << "with your model from a floating point checkpoint to change the " |
| 1735 | << "input graph to contain min/max information. If you don't care " |
| 1736 | << "about accuracy, you can pass --default_ranges_min= and " |
| 1737 | << "--default_ranges_max= for easy experimentation."; |
| 1738 | } |
| 1739 | } |
| 1740 | } |
| 1741 | |
| 1742 | int ElementSize(ArrayDataType data_type) { |
| 1743 | switch (data_type) { |
no test coverage detected