You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

general_bitpacking.cc 2.8 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. /**
  2. * Copyright 2020 Huawei Technologies Co., Ltd
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include "tools/converter/quantizer/general_bitpacking.h"
  17. namespace mindspore {
  18. namespace lite {
  19. BitPack::BitPack(const uint8_t &bitnum) { this->bitnum = bitnum; }
  20. void BitPack::UnPackFromUint8ToOrigin(uint8_t &n, std::queue<bool> &unpackBitData) {
  21. int bitCount = 0;
  22. while (bitCount < 8) {
  23. bool a = n % 2;
  24. n = n >> 1;
  25. bitCount++;
  26. unpackBitData.push(a);
  27. }
  28. }
  29. void BitPack::UnPack(uint8_t bitnum, uint8_t &packedData, std::vector<uint8_t> &originData,
  30. std::queue<bool> &unpackBitData) {
  31. UnPackFromUint8ToOrigin(packedData, unpackBitData);
  32. // std::queue<bool> unpackBitTmpData;
  33. while (unpackBitData.size() > bitnum) {
  34. uint32_t result = 0;
  35. for (int k = 0; k < bitnum; k++) {
  36. bool bitTmp = unpackBitData.front();
  37. result = (result << 1) + static_cast<int>(bitTmp);
  38. unpackBitData.pop();
  39. }
  40. originData.push_back(result);
  41. }
  42. }
  43. void BitPack::PackFromOriginToUint8(std::stack<bool> &ans, std::vector<uint8_t> &packedDataVec) {
  44. uint32_t result = 0;
  45. for (size_t i = 0; i < 8; i++) {
  46. bool bit_tmp = ans.top();
  47. result = (result << 1) + static_cast<int>(bit_tmp);
  48. ans.pop();
  49. }
  50. packedDataVec.push_back(result);
  51. }
  52. void BitPack::DoBinary(uint8_t &n, std::stack<bool> &ans, std::vector<uint8_t> &packedDataVec) {
  53. int bitCount = 0;
  54. while (bitCount < bitnum) {
  55. bool a = n / (1 << (unsigned int)(bitnum - bitCount - 1));
  56. n = n - a * (1 << (unsigned int)(bitnum - bitCount - 1));
  57. bitCount++;
  58. ans.push(a);
  59. if (ans.size() == 8) {
  60. PackFromOriginToUint8(ans, packedDataVec);
  61. }
  62. }
  63. }
  64. void BitPack::BitPacking(const std::vector<uint8_t> &originDataVec, std::vector<uint8_t> &packedDataVec) {
  65. std::stack<bool> bitDataVec;
  66. for (size_t i = 0; i < originDataVec.size(); i++) {
  67. uint8_t tmp = originDataVec[i];
  68. DoBinary(tmp, bitDataVec, packedDataVec);
  69. }
  70. size_t remainBitData = bitDataVec.size();
  71. if (8 > remainBitData && remainBitData > 0) {
  72. for (size_t i = 0; i < 8 - remainBitData; i++) {
  73. bitDataVec.push(0);
  74. }
  75. PackFromOriginToUint8(bitDataVec, packedDataVec);
  76. }
  77. }
  78. } // namespace lite
  79. } // namespace mindspore