| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | #include "paramdict.h" |
| |
|
| | #include "datareader.h" |
| | #include "mat.h" |
| | #include "platform.h" |
| |
|
| | #include <ctype.h> |
| |
|
| | #if NCNN_STDIO |
| | #include <stdio.h> |
| | #endif |
| |
|
| | namespace ncnn { |
| |
|
| | class ParamDictPrivate |
| | { |
| | public: |
| | struct |
| | { |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | int type; |
| | union |
| | { |
| | int i; |
| | float f; |
| | }; |
| | Mat v; |
| | } params[NCNN_MAX_PARAM_COUNT]; |
| | }; |
| |
|
| | ParamDict::ParamDict() |
| | : d(new ParamDictPrivate) |
| | { |
| | clear(); |
| | } |
| |
|
| | ParamDict::~ParamDict() |
| | { |
| | delete d; |
| | } |
| |
|
| | ParamDict::ParamDict(const ParamDict& rhs) |
| | : d(new ParamDictPrivate) |
| | { |
| | for (int i = 0; i < NCNN_MAX_PARAM_COUNT; i++) |
| | { |
| | int type = rhs.d->params[i].type; |
| | d->params[i].type = type; |
| | if (type == 1 || type == 2 || type == 3) |
| | { |
| | d->params[i].i = rhs.d->params[i].i; |
| | } |
| | else |
| | { |
| | d->params[i].v = rhs.d->params[i].v; |
| | } |
| | } |
| | } |
| |
|
| | ParamDict& ParamDict::operator=(const ParamDict& rhs) |
| | { |
| | if (this == &rhs) |
| | return *this; |
| |
|
| | for (int i = 0; i < NCNN_MAX_PARAM_COUNT; i++) |
| | { |
| | int type = rhs.d->params[i].type; |
| | d->params[i].type = type; |
| | if (type == 1 || type == 2 || type == 3) |
| | { |
| | d->params[i].i = rhs.d->params[i].i; |
| | } |
| | else |
| | { |
| | d->params[i].v = rhs.d->params[i].v; |
| | } |
| | } |
| |
|
| | return *this; |
| | } |
| |
|
| | int ParamDict::type(int id) const |
| | { |
| | return d->params[id].type; |
| | } |
| |
|
| | |
| | int ParamDict::get(int id, int def) const |
| | { |
| | return d->params[id].type ? d->params[id].i : def; |
| | } |
| |
|
| | float ParamDict::get(int id, float def) const |
| | { |
| | return d->params[id].type ? d->params[id].f : def; |
| | } |
| |
|
| | Mat ParamDict::get(int id, const Mat& def) const |
| | { |
| | return d->params[id].type ? d->params[id].v : def; |
| | } |
| |
|
| | void ParamDict::set(int id, int i) |
| | { |
| | d->params[id].type = 2; |
| | d->params[id].i = i; |
| | } |
| |
|
| | void ParamDict::set(int id, float f) |
| | { |
| | d->params[id].type = 3; |
| | d->params[id].f = f; |
| | } |
| |
|
| | void ParamDict::set(int id, const Mat& v) |
| | { |
| | d->params[id].type = 4; |
| | d->params[id].v = v; |
| | } |
| |
|
| | void ParamDict::clear() |
| | { |
| | for (int i = 0; i < NCNN_MAX_PARAM_COUNT; i++) |
| | { |
| | d->params[i].type = 0; |
| | d->params[i].v = Mat(); |
| | } |
| | } |
| |
|
| | #if NCNN_STRING |
| | static bool vstr_is_float(const char vstr[16]) |
| | { |
| | |
| | for (int j = 0; j < 16; j++) |
| | { |
| | if (vstr[j] == '\0') |
| | break; |
| |
|
| | if (vstr[j] == '.' || tolower(vstr[j]) == 'e') |
| | return true; |
| | } |
| |
|
| | return false; |
| | } |
| |
|
| | static float vstr_to_float(const char vstr[16]) |
| | { |
| | double v = 0.0; |
| |
|
| | const char* p = vstr; |
| |
|
| | |
| | bool sign = *p != '-'; |
| | if (*p == '+' || *p == '-') |
| | { |
| | p++; |
| | } |
| |
|
| | |
| | unsigned int v1 = 0; |
| | while (isdigit(*p)) |
| | { |
| | v1 = v1 * 10 + (*p - '0'); |
| | p++; |
| | } |
| |
|
| | v = (double)v1; |
| |
|
| | |
| | if (*p == '.') |
| | { |
| | p++; |
| |
|
| | unsigned int pow10 = 1; |
| | unsigned int v2 = 0; |
| |
|
| | while (isdigit(*p)) |
| | { |
| | v2 = v2 * 10 + (*p - '0'); |
| | pow10 *= 10; |
| | p++; |
| | } |
| |
|
| | v += v2 / (double)pow10; |
| | } |
| |
|
| | |
| | if (*p == 'e' || *p == 'E') |
| | { |
| | p++; |
| |
|
| | |
| | bool fact = *p != '-'; |
| | if (*p == '+' || *p == '-') |
| | { |
| | p++; |
| | } |
| |
|
| | |
| | unsigned int expon = 0; |
| | while (isdigit(*p)) |
| | { |
| | expon = expon * 10 + (*p - '0'); |
| | p++; |
| | } |
| |
|
| | double scale = 1.0; |
| | while (expon >= 8) |
| | { |
| | scale *= 1e8; |
| | expon -= 8; |
| | } |
| | while (expon > 0) |
| | { |
| | scale *= 10.0; |
| | expon -= 1; |
| | } |
| |
|
| | v = fact ? v * scale : v / scale; |
| | } |
| |
|
| | |
| | return sign ? (float)v : (float)-v; |
| | } |
| |
|
| | int ParamDict::load_param(const DataReader& dr) |
| | { |
| | clear(); |
| |
|
| | |
| |
|
| | |
| | int id = 0; |
| | while (dr.scan("%d=", &id) == 1) |
| | { |
| | bool is_array = id <= -23300; |
| | if (is_array) |
| | { |
| | id = -id - 23300; |
| | } |
| |
|
| | if (id >= NCNN_MAX_PARAM_COUNT) |
| | { |
| | NCNN_LOGE("id < NCNN_MAX_PARAM_COUNT failed (id=%d, NCNN_MAX_PARAM_COUNT=%d)", id, NCNN_MAX_PARAM_COUNT); |
| | return -1; |
| | } |
| |
|
| | if (is_array) |
| | { |
| | int len = 0; |
| | int nscan = dr.scan("%d", &len); |
| | if (nscan != 1) |
| | { |
| | NCNN_LOGE("ParamDict read array length failed"); |
| | return -1; |
| | } |
| |
|
| | d->params[id].v.create(len); |
| |
|
| | for (int j = 0; j < len; j++) |
| | { |
| | char vstr[16]; |
| | nscan = dr.scan(",%15[^,\n ]", vstr); |
| | if (nscan != 1) |
| | { |
| | NCNN_LOGE("ParamDict read array element failed"); |
| | return -1; |
| | } |
| |
|
| | bool is_float = vstr_is_float(vstr); |
| |
|
| | if (is_float) |
| | { |
| | float* ptr = d->params[id].v; |
| | ptr[j] = vstr_to_float(vstr); |
| | } |
| | else |
| | { |
| | int* ptr = d->params[id].v; |
| | nscan = sscanf(vstr, "%d", &ptr[j]); |
| | if (nscan != 1) |
| | { |
| | NCNN_LOGE("ParamDict parse array element failed"); |
| | return -1; |
| | } |
| | } |
| |
|
| | d->params[id].type = is_float ? 6 : 5; |
| | } |
| | } |
| | else |
| | { |
| | char vstr[16]; |
| | int nscan = dr.scan("%15s", vstr); |
| | if (nscan != 1) |
| | { |
| | NCNN_LOGE("ParamDict read value failed"); |
| | return -1; |
| | } |
| |
|
| | bool is_float = vstr_is_float(vstr); |
| |
|
| | if (is_float) |
| | { |
| | d->params[id].f = vstr_to_float(vstr); |
| | } |
| | else |
| | { |
| | nscan = sscanf(vstr, "%d", &d->params[id].i); |
| | if (nscan != 1) |
| | { |
| | NCNN_LOGE("ParamDict parse value failed"); |
| | return -1; |
| | } |
| | } |
| |
|
| | d->params[id].type = is_float ? 3 : 2; |
| | } |
| | } |
| |
|
| | return 0; |
| | } |
| | #endif |
| |
|
| | int ParamDict::load_param_bin(const DataReader& dr) |
| | { |
| | clear(); |
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | int id = 0; |
| | size_t nread; |
| | nread = dr.read(&id, sizeof(int)); |
| | if (nread != sizeof(int)) |
| | { |
| | NCNN_LOGE("ParamDict read id failed %zd", nread); |
| | return -1; |
| | } |
| |
|
| | while (id != -233) |
| | { |
| | bool is_array = id <= -23300; |
| | if (is_array) |
| | { |
| | id = -id - 23300; |
| | } |
| |
|
| | if (id >= NCNN_MAX_PARAM_COUNT) |
| | { |
| | NCNN_LOGE("id < NCNN_MAX_PARAM_COUNT failed (id=%d, NCNN_MAX_PARAM_COUNT=%d)", id, NCNN_MAX_PARAM_COUNT); |
| | return -1; |
| | } |
| |
|
| | if (is_array) |
| | { |
| | int len = 0; |
| | nread = dr.read(&len, sizeof(int)); |
| | if (nread != sizeof(int)) |
| | { |
| | NCNN_LOGE("ParamDict read array length failed %zd", nread); |
| | return -1; |
| | } |
| |
|
| | d->params[id].v.create(len); |
| |
|
| | float* ptr = d->params[id].v; |
| | nread = dr.read(ptr, sizeof(float) * len); |
| | if (nread != sizeof(float) * len) |
| | { |
| | NCNN_LOGE("ParamDict read array element failed %zd", nread); |
| | return -1; |
| | } |
| |
|
| | d->params[id].type = 4; |
| | } |
| | else |
| | { |
| | nread = dr.read(&d->params[id].f, sizeof(float)); |
| | if (nread != sizeof(float)) |
| | { |
| | NCNN_LOGE("ParamDict read value failed %zd", nread); |
| | return -1; |
| | } |
| |
|
| | d->params[id].type = 1; |
| | } |
| |
|
| | nread = dr.read(&id, sizeof(int)); |
| | if (nread != sizeof(int)) |
| | { |
| | NCNN_LOGE("ParamDict read EOP failed %zd", nread); |
| | return -1; |
| | } |
| | } |
| |
|
| | return 0; |
| | } |
| |
|
| | } |
| |
|