|
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337 |
- // Tencent is pleased to support the open source community by making ncnn available.
- //
- // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved.
- //
- // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
- // in compliance with the License. You may obtain a copy of the License at
- //
- // https://opensource.org/licenses/BSD-3-Clause
- //
- // Unless required by applicable law or agreed to in writing, software distributed
- // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
- // CONDITIONS OF ANY KIND, either express or implied. See the License for the
- // specific language governing permissions and limitations under the License.
-
- #include "modelbin.h"
-
- #include "datareader.h"
-
- #include <string.h>
-
- namespace ncnn {
-
- ModelBin::ModelBin()
- {
- }
-
- ModelBin::~ModelBin()
- {
- }
-
- Mat ModelBin::load(int w, int h, int type) const
- {
- Mat m = load(w * h, type);
- if (m.empty())
- return m;
-
- return m.reshape(w, h);
- }
-
- Mat ModelBin::load(int w, int h, int c, int type) const
- {
- Mat m = load(w * h * c, type);
- if (m.empty())
- return m;
-
- return m.reshape(w, h, c);
- }
-
- Mat ModelBin::load(int w, int h, int d, int c, int type) const
- {
- Mat m = load(w * h * d * c, type);
- if (m.empty())
- return m;
-
- return m.reshape(w, h, d, c);
- }
-
- class ModelBinFromDataReaderPrivate
- {
- public:
- ModelBinFromDataReaderPrivate(const DataReader& _dr)
- : dr(_dr)
- {
- }
- const DataReader& dr;
- };
-
- ModelBinFromDataReader::ModelBinFromDataReader(const DataReader& _dr)
- : ModelBin(), d(new ModelBinFromDataReaderPrivate(_dr))
- {
- }
-
- ModelBinFromDataReader::~ModelBinFromDataReader()
- {
- delete d;
- }
-
- ModelBinFromDataReader::ModelBinFromDataReader(const ModelBinFromDataReader&)
- : d(0)
- {
- }
-
- ModelBinFromDataReader& ModelBinFromDataReader::operator=(const ModelBinFromDataReader&)
- {
- return *this;
- }
-
- Mat ModelBinFromDataReader::load(int w, int type) const
- {
- Mat m;
-
- if (type == 0)
- {
- size_t nread;
-
- union
- {
- struct
- {
- unsigned char f0;
- unsigned char f1;
- unsigned char f2;
- unsigned char f3;
- };
- unsigned int tag;
- } flag_struct;
-
- nread = d->dr.read(&flag_struct, sizeof(flag_struct));
- if (nread != sizeof(flag_struct))
- {
- NCNN_LOGE("ModelBin read flag_struct failed %zd", nread);
- return Mat();
- }
-
- unsigned int flag = flag_struct.f0 + flag_struct.f1 + flag_struct.f2 + flag_struct.f3;
-
- if (flag_struct.tag == 0x01306B47)
- {
- // half-precision data
- size_t align_data_size = alignSize(w * sizeof(unsigned short), 4);
-
- // try reference data
- const void* refbuf = 0;
- nread = d->dr.reference(align_data_size, &refbuf);
- if (nread == align_data_size)
- {
- m = Mat::from_float16((const unsigned short*)refbuf, w);
- }
- else
- {
- std::vector<unsigned short> float16_weights;
- float16_weights.resize(align_data_size);
- nread = d->dr.read(&float16_weights[0], align_data_size);
- if (nread != align_data_size)
- {
- NCNN_LOGE("ModelBin read float16_weights failed %zd", nread);
- return Mat();
- }
-
- m = Mat::from_float16(&float16_weights[0], w);
- }
-
- return m;
- }
- else if (flag_struct.tag == 0x000D4B38)
- {
- // int8 data
- size_t align_data_size = alignSize(w, 4);
-
- // try reference data
- const void* refbuf = 0;
- nread = d->dr.reference(align_data_size, &refbuf);
- if (nread == align_data_size)
- {
- m = Mat(w, (void*)refbuf, (size_t)1u);
- }
- else
- {
- std::vector<signed char> int8_weights;
- int8_weights.resize(align_data_size);
- nread = d->dr.read(&int8_weights[0], align_data_size);
- if (nread != align_data_size)
- {
- NCNN_LOGE("ModelBin read int8_weights failed %zd", nread);
- return Mat();
- }
-
- m.create(w, (size_t)1u);
- if (m.empty())
- return m;
-
- memcpy(m.data, &int8_weights[0], w);
- }
-
- return m;
- }
- else if (flag_struct.tag == 0x0002C056)
- {
- // try reference data
- const void* refbuf = 0;
- nread = d->dr.reference(w * sizeof(float), &refbuf);
- if (nread == w * sizeof(float))
- {
- m = Mat(w, (void*)refbuf);
- }
- else
- {
- m.create(w);
- if (m.empty())
- return m;
-
- // raw data with extra scaling
- nread = d->dr.read(m, w * sizeof(float));
- if (nread != w * sizeof(float))
- {
- NCNN_LOGE("ModelBin read weight_data failed %zd", nread);
- return Mat();
- }
- }
-
- return m;
- }
-
- if (flag != 0)
- {
- m.create(w);
- if (m.empty())
- return m;
-
- // quantized data
- float quantization_value[256];
- nread = d->dr.read(quantization_value, 256 * sizeof(float));
- if (nread != 256 * sizeof(float))
- {
- NCNN_LOGE("ModelBin read quantization_value failed %zd", nread);
- return Mat();
- }
-
- size_t align_weight_data_size = alignSize(w * sizeof(unsigned char), 4);
- std::vector<unsigned char> index_array;
- index_array.resize(align_weight_data_size);
- nread = d->dr.read(&index_array[0], align_weight_data_size);
- if (nread != align_weight_data_size)
- {
- NCNN_LOGE("ModelBin read index_array failed %zd", nread);
- return Mat();
- }
-
- float* ptr = m;
- for (int i = 0; i < w; i++)
- {
- ptr[i] = quantization_value[index_array[i]];
- }
- }
- else if (flag_struct.f0 == 0)
- {
- // try reference data
- const void* refbuf = 0;
- nread = d->dr.reference(w * sizeof(float), &refbuf);
- if (nread == w * sizeof(float))
- {
- m = Mat(w, (void*)refbuf);
- }
- else
- {
- m.create(w);
- if (m.empty())
- return m;
-
- // raw data
- nread = d->dr.read(m, w * sizeof(float));
- if (nread != w * sizeof(float))
- {
- NCNN_LOGE("ModelBin read weight_data failed %zd", nread);
- return Mat();
- }
- }
- }
-
- return m;
- }
- else if (type == 1)
- {
- // try reference data
- const void* refbuf = 0;
- size_t nread = d->dr.reference(w * sizeof(float), &refbuf);
- if (nread == w * sizeof(float))
- {
- m = Mat(w, (void*)refbuf);
- }
- else
- {
- m.create(w);
- if (m.empty())
- return m;
-
- // raw data
- size_t nread = d->dr.read(m, w * sizeof(float));
- if (nread != w * sizeof(float))
- {
- NCNN_LOGE("ModelBin read weight_data failed %zd", nread);
- return Mat();
- }
- }
-
- return m;
- }
- else
- {
- NCNN_LOGE("ModelBin load type %d not implemented", type);
- return Mat();
- }
-
- return Mat();
- }
-
- class ModelBinFromMatArrayPrivate
- {
- public:
- ModelBinFromMatArrayPrivate(const Mat* _weights)
- : weights(_weights)
- {
- }
- mutable const Mat* weights;
- };
-
- ModelBinFromMatArray::ModelBinFromMatArray(const Mat* _weights)
- : ModelBin(), d(new ModelBinFromMatArrayPrivate(_weights))
- {
- }
-
- ModelBinFromMatArray::~ModelBinFromMatArray()
- {
- delete d;
- }
-
- ModelBinFromMatArray::ModelBinFromMatArray(const ModelBinFromMatArray&)
- : d(0)
- {
- }
-
- ModelBinFromMatArray& ModelBinFromMatArray::operator=(const ModelBinFromMatArray&)
- {
- return *this;
- }
-
- Mat ModelBinFromMatArray::load(int /*w*/, int /*type*/) const
- {
- if (!d->weights)
- return Mat();
-
- Mat m = d->weights[0];
- d->weights++;
- return m;
- }
-
- } // namespace ncnn
|