diff --git a/CMakeLists.txt b/CMakeLists.txt index 0b9d2a6e6a1bc4108e13a9361abf496f70d51801..4ccf73763c08a748b53027d7f4a0f254774a1843 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,6 @@ option(LOG_PROFILE "log profile" ON) option(CPU "armv7 with neon" ON) option(MALI_GPU "mali gpu" OFF) option(FPGA "fpga" OFF) -option(QUANTI "quantification" OFF) file(GLOB_RECURSE PADDLE_MOBILE_CC src/*.cc src/*.cpp src/*.c src/*.mm) file(GLOB_RECURSE PADDLE_MOBILE_H src/*.h) @@ -163,7 +162,4 @@ if(DEBUGING) endif() endif() -if (QUANTI) - add_subdirectory(tools/quantification) -endif () diff --git a/doc/quantification.md b/doc/quantification.md new file mode 100644 index 0000000000000000000000000000000000000000..04a93116a08c094ef71861cec1bb3262304c4cb7 --- /dev/null +++ b/doc/quantification.md @@ -0,0 +1,39 @@ +# Quantification 模型量化、反量化 + +## 背景故事 +部分网络如AlexNet训练出的模型体积较大,不适宜在移动设备上使用。 + + +## 解决模型过大办法 +1. 选用适合移动端的模型结构如:mobilenet、googlenet、 yolo、squeezenet 等; +2. 使用我们提供的量化工具,可以在几乎不影响精度的情况下将float32模型减小至原模型的 1/4; + +- - - - - +## 量化工具介绍 + +### 模型转化工具目录: + +- [量化工具目录](https://github.com/PaddlePaddle/paddle-mobile/tree/develop/tools/quantification) + +- [模型转化工具](https://github.com/PaddlePaddle/paddle-mobile/blob/develop/tools/quantification/convert.cpp) + +#### 使用说明 +- [工具使用](https://github.com/PaddlePaddle/paddle-mobile/blob/develop/tools/quantification/README.md) + +## 如何读取量化后的模型 +load方法中添加了 quantification 参数,默认为false。 如果需要load量化后的模型,按需传参即可。 + +[我是源代码](https://github.com/PaddlePaddle/paddle-mobile/blob/55302b33ea3bd68c9797d8f65e527544792b8095/src/io/paddle_mobile.h) + +```c++ +bool Load(const std::string &dirname, bool optimize = false, + bool quantification = false, int batch_size = 1); +``` + +- - - - - + + + + + + diff --git a/tools/quantification/CMakeLists.txt b/tools/quantification/CMakeLists.txt index 1dfb9ee056a4126f65c2ab6fac4c1417039f66ec..5f1ca7fdc2b65638c7158b0933b924c71eadc4a0 100644 --- a/tools/quantification/CMakeLists.txt +++ b/tools/quantification/CMakeLists.txt @@ -1,5 +1,12 @@ -set(dir ${CMAKE_CURRENT_SOURCE_DIR}) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${dir}/build") +cmake_minimum_required(VERSION 3.6) +project(quali) +add_definitions(-DENABLE_EXCEPTION) -ADD_EXECUTABLE(convert convert.cpp) -target_link_libraries(convert paddle-mobile) \ No newline at end of file +set(CMAKE_CXX_STANDARD 11) +file(GLOB_RECURSE QULIFICATON_CC src/*.cc src/*.cpp src/*.c src/*.mm) +file(GLOB_RECURSE QULIFICATON_H src/*.h) +include_directories(. src/) + +#add_library(paddle-mobile SHARED ${QULIFICATON_CC} ${QULIFICATON_H} convert.cpp) + +add_executable(quantify convert.cpp ${QULIFICATON_CC} ${QULIFICATON_H}) \ No newline at end of file diff --git a/tools/quantification/README.md b/tools/quantification/README.md new file mode 100644 index 0000000000000000000000000000000000000000..ac729af01e7e73328b884097009dad1d468e7997 --- /dev/null +++ b/tools/quantification/README.md @@ -0,0 +1,39 @@ +# 模型量化脚本 + +#### 量化脚本使用指南 +1. 在PaddleMobile项目目录下(如 ~/PaddleProject/paddle-mobile) + +2. cd到 tools/quantification/ 目录 + +3. cmake编译 + + ``` sh + cmake . + make + ``` + +4. 运行量化脚本 + ```sh + ./quantify (0:seperated. 1:combined ) (输入路径) (输出路径) + # quantify googlenet seperated from /Users/xiebaiyuan/PaddleProject/quali/models/googlenet to ./googlenet_min + ./quantify 0 /Users/xiebaiyuan/PaddleProject/quali/models/googlenet ./googlenet_min + + ``` + +*注:* +*量化工具中* +*1.seperated模型model文件默认命名为 "__model__";* +*2.combined模型的model文件默认命名为 "model",参数文件默认命名为"params";* + + +##### 整体如下: +以googlenet非combined为例: + +```sh +cd tools/quantification/ +cmake . +make +./quantify 0 /Users/xiebaiyuan/PaddleProject/quali/models/googlenet ./googlenet_min +``` + + diff --git a/tools/quantification/convert.cpp b/tools/quantification/convert.cpp index 7a9511a654f3de9ac9ace5d3b9621c360bd86ad9..88eef48b39ab8d2aeb1d4e3858ba97ef6360c9a9 100644 --- a/tools/quantification/convert.cpp +++ b/tools/quantification/convert.cpp @@ -1,200 +1,273 @@ -#include "io/paddle_mobile.h" +#include "src/enforce.h" +#include "src/var_desc.h" +#include "src/program_desc.h" #include -using std::string; - -static const std::string g_googlenet_combine = "../models/googlenet_combine"; -static const std::string g_googlenet = "../models/googlenet"; -using paddle_mobile::Executor; -using paddle_mobile::framework::Program; - - char *Get_binary_data(std::string filename) { - FILE *file = fopen(filename.c_str(), "rb"); - PADDLE_MOBILE_ENFORCE(file != nullptr, "can't open file: %s ", - filename.c_str()); - fseek(file, 0, SEEK_END); - int64_t size = ftell(file); - PADDLE_MOBILE_ENFORCE(size > 0, "size is too small"); - rewind(file); - char *data = new char[size]; - size_t bytes_read = fread(data, 1, size, file); - PADDLE_MOBILE_ENFORCE(bytes_read == size, - "read binary file bytes do not match with fseek"); - DLOG << "Get_binary_data end"; - fclose(file); - return data; +#include +#include +#include +#include +#include +#include "src/framework.pb-c.h" +#include "src/protobuf-c.h" +#include +#include + + +const size_t kSize64 = sizeof(uint64_t); +const size_t kSize32 = sizeof(uint32_t); + +char *Get_binary_data(const std::string &filename) { + + FILE *file = fopen(filename.c_str(), "rb"); + + PADDLE_MOBILE_ENFORCE(file != nullptr, "can't open file: %s ", + filename.c_str()); + fseek(file, 0, SEEK_END); + int64_t size = ftell(file); + + PADDLE_MOBILE_ENFORCE(size > 0, "size is too small"); + rewind(file); + auto *data = new char[size]; + size_t bytes_read = fread(data, 1, static_cast(size), file); + PADDLE_MOBILE_ENFORCE(bytes_read == size, + "read binary file bytes do not match with fseek"); + fclose(file); + return data; +} + + +static size_t ReadBuffer(const char *file_name, uint8_t **out) { + FILE *fp; + fp = fopen(file_name, "rb"); + PADDLE_MOBILE_ENFORCE(fp != nullptr, " %s open failed !", file_name); + fseek(fp, 0, SEEK_END); + auto size = static_cast(ftell(fp)); + rewind(fp); + *out = reinterpret_cast(malloc(size)); + size_t cur_len = 0; + size_t nread; + while ((nread = fread(*out + cur_len, 1, size - cur_len, fp)) != 0) { + cur_len += nread; } + fclose(fp); + return cur_len; +} - void LoadWithDump(const paddle_mobile::framework::VarDesc var_desc, - paddle_mobile::framework::LoDTensor *tensor, char **data, FILE *out_file) { - // 1. version - uint32_t version = *reinterpret_cast(*data); - // write version - fwrite(&version, sizeof(uint32_t), 1, out_file ); - (*data) += sizeof(uint32_t); - // 2 Lod information - uint64_t *lod_level_ptr = new uint64_t(); - memcpy(lod_level_ptr, (*data), sizeof(uint64_t)); - uint64_t lod_level = 0; - // write lod Information - fwrite(&lod_level, sizeof(uint64_t), 1, out_file); - delete lod_level_ptr; - (*data) += sizeof(uint64_t); - auto &lod = *tensor->mutable_lod(); - lod.resize(lod_level); - for (uint64_t i = 0; i < lod_level; ++i) { - uint64_t size = *reinterpret_cast(*data); - // write lod size - fwrite(&size, sizeof(uint64_t), 1, out_file); - (*data) += sizeof(uint64_t); - std::vector tmp(size / sizeof(size_t)); - for (int k = 0; k < tmp.size(); ++k) { - tmp[k] = *reinterpret_cast(*data); - (*data) += sizeof(size_t); - } - // write lod size vector - fwrite(&tmp, sizeof(size_t), tmp.size(), out_file ); +std::shared_ptr loadParams(const std::string &model_path) { + PaddleMobile__Framework__Proto__ProgramDesc *c_program; + uint8_t *buf = nullptr; + size_t read_size = ReadBuffer(model_path.c_str(), &buf); + PADDLE_MOBILE_ENFORCE(buf != nullptr, "read from __model__ is null"); + c_program = paddle_mobile__framework__proto__program_desc__unpack( + nullptr, read_size, buf); + PADDLE_MOBILE_ENFORCE(c_program != nullptr, "program is null"); + auto originProgramDesc = std::make_shared(c_program); + return originProgramDesc; - lod[i] = tmp; - } +} - // 3. tensor version - uint32_t tensor_version = *reinterpret_cast(*data); - // write tensor version - fwrite(&tensor_version, sizeof(uint32_t), 1, out_file); - (*data) += sizeof(uint32_t); - - // 4. tensor desc - int32_t size = *reinterpret_cast(*data); - // write tensor desc - fwrite(&size, sizeof(int32_t), 1, out_file); - (*data) += sizeof(int32_t); - - std::unique_ptr buf(new char[size]); - for (int m = 0; m < size; ++m) { - buf.get()[m] = (*data)[m]; - } - fwrite(buf.get(), sizeof(char), size, out_file); - (*data) += (sizeof(char) * size); +void LoadWithDump(const paddle_mobile::framework::VarDesc &var_desc, char *dataP, FILE *out_file) { + // 1. version + uint32_t version = *reinterpret_cast(dataP); - const paddle_mobile::framework::TensorDesc &desc = var_desc.Tensor_desc(); - int memory_size = 1; - for (auto l : desc.Dims()) { - memory_size *= l; - } - tensor->Resize(paddle_mobile::framework::make_ddim(desc.Dims())); - - void *memory = tensor; - int type_size = 0; - switch (desc.DataType()) { - case paddle_mobile::framework::VARTYPE_TYPE_FP16: - type_size = 2; - break; - case paddle_mobile::framework::VARTYPE_TYPE_FP32: - type_size = 4; - memory = tensor->mutable_data(); - break; - case paddle_mobile::framework::VARTYPE_TYPE_FP64: - type_size = 8; - break; - case paddle_mobile::framework::VARTYPE_TYPE_INT32: - type_size = 4; - break; - case paddle_mobile::framework::VARTYPE_TYPE_INT64: - type_size = 8; - break; - case paddle_mobile::framework::VARTYPE_TYPE_BOOL: - type_size = 1; - break; - default: - break; - } - for (int n = 0; n < memory_size * type_size; ++n) { - static_cast(memory)[n] = (*data)[n]; - } - (*data) += (sizeof(char) * memory_size * type_size); - // for float 32 - float min_value = std::numeric_limits::max(); - float max_value = std::numeric_limits::min(); - for (int k = 0; k < memory_size; ++k) { - min_value = std::min(min_value, static_cast (memory)[k]); - max_value = std::max(max_value, static_cast (memory)[k]); - } - fwrite(&min_value, sizeof(float), 1, out_file); - fwrite(&max_value, sizeof(float), 1, out_file); - for (int g = 0; g < memory_size; ++g) { - float value = static_cast (memory)[g]; - uint8_t factor = (uint8_t) round((value - min_value) / (max_value - min_value) * 255); - fwrite(&factor, sizeof(uint8_t), 1, out_file); + // write version + fwrite(&version, kSize32, 1, out_file); + + dataP += kSize32; + + // 2 Lod information + auto *lod_level_ptr = new uint64_t(); + memcpy(lod_level_ptr, dataP, kSize64); + + uint64_t lod_level = 0; + // write lod Information + fwrite(&lod_level, kSize64, 1, out_file); + delete lod_level_ptr; + + dataP += kSize64; + + for (uint64_t i = 0; i < lod_level; ++i) { + uint64_t size = *reinterpret_cast(dataP); + // write lod size + fwrite(&size, kSize64, 1, out_file); + (dataP) += kSize64; + + std::vector tmp(size / sizeof(size_t)); + for (unsigned long &k : tmp) { + k = *reinterpret_cast(dataP); + (dataP) += sizeof(size_t); } + // write lod size vector + fwrite(&tmp, sizeof(size_t), tmp.size(), out_file); + } + + // 3. tensor version + uint32_t tensor_version = *reinterpret_cast(dataP); + // write tensor version + fwrite(&tensor_version, kSize32, 1, out_file); + (dataP) += kSize32; + + // 4. tensor desc + int32_t size = *reinterpret_cast(dataP); + // write tensor desc + fwrite(&size, sizeof(int32_t), 1, out_file); + (dataP) += sizeof(int32_t); + + std::unique_ptr buf(new char[size]); + for (int m = 0; m < size; ++m) { + buf.get()[m] = (dataP)[m]; + } + + fwrite(buf.get(), sizeof(char), static_cast(size), out_file); + (dataP) += (sizeof(char) * size); + + const paddle_mobile::framework::TensorDesc &desc = var_desc.Tensor_desc(); + int memory_size = 1; + for (auto l : desc.Dims()) { + memory_size *= l; + } + + void *memory = nullptr; + int type_size = 0; + switch (desc.DataType()) { + case paddle_mobile::framework::VARTYPE_TYPE_FP16: + type_size = 2; + break; + case paddle_mobile::framework::VARTYPE_TYPE_FP32: + type_size = 4; + break; + case paddle_mobile::framework::VARTYPE_TYPE_FP64: + type_size = 8; + break; + case paddle_mobile::framework::VARTYPE_TYPE_INT32: + type_size = 4; + break; + case paddle_mobile::framework::VARTYPE_TYPE_INT64: + type_size = 8; + break; + case paddle_mobile::framework::VARTYPE_TYPE_BOOL: + type_size = 1; + break; + default: + break; + } + size_t tensorSize = sizeof(char) * memory_size * type_size; + + memory = new char[tensorSize]; + + for (int n = 0; n < tensorSize; ++n) { + static_cast(memory)[n] = (dataP)[n]; + } + dataP += tensorSize; + + // for float 32 + float min_value = std::numeric_limits::max(); + float max_value = std::numeric_limits::min(); + for (int k = 0; k < memory_size; ++k) { + min_value = std::min(min_value, static_cast (memory)[k]); + max_value = std::max(max_value, static_cast (memory)[k]); + } + + fwrite(&min_value, sizeof(float), 1, out_file); + fwrite(&max_value, sizeof(float), 1, out_file); + for (int g = 0; g < memory_size; ++g) { + float value = static_cast (memory)[g]; + auto factor = (uint8_t) round((value - min_value) / (max_value - min_value) * 255); + fwrite(&factor, sizeof(uint8_t), 1, out_file); } +} - void quantificate_combined(std::string model_path, std::string param_path, std::string param_min_path){ - paddle_mobile::Loader loader; - bool optimize = true; - auto program = loader.Load(model_path, param_path, optimize); - char *origin_data = Get_binary_data(program.para_path); - char *data = origin_data; - FILE *out_file = fopen(param_min_path.c_str(), "wb"); - for (const auto &block : program.originProgram->Blocks()) { - for (const auto &var_desc : block->Vars()) { - auto var = program.scope->Var(var_desc->Name()); - if(var_desc ->Persistable()) { - auto tensor = var->template GetMutable(); - if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { - continue; - } - LoadWithDump(*var_desc, tensor, &data,out_file); +void +quantificate_combined(const std::string &model_path, const std::string ¶m_path, const std::string ¶m_min_path) { + + auto program = loadParams(model_path); + char *origin_data = Get_binary_data(param_path); + char *data = origin_data; + FILE *out_file = fopen(param_min_path.c_str(), "wb"); + for (const auto &block : program->Blocks()) { + for (const auto &var_desc : block->Vars()) { + if (var_desc->Persistable()) { + if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { + continue; } + LoadWithDump(*var_desc, data, out_file); } } - fclose(out_file); - delete origin_data; - } - void quantificate_seperated(std::string model_dir, std::string param_min_path) { - paddle_mobile::Loader loader; - bool optimize = true; - auto program = loader.Load(model_dir, optimize); - std::string shell_command = "mkdir "+param_min_path; - system(shell_command.c_str()); - for (const auto &block : program.originProgram->Blocks()) { - for (const auto &var_desc : block->Vars()) { - auto var = program.scope->Var(var_desc->Name()); - if(var_desc ->Persistable()) { - auto tensor = var->template GetMutable(); - if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { - continue; - } - std::string file_name = param_min_path +"/"+ var_desc->Name(); - - FILE *out_file = fopen(file_name.c_str(), "wb"); - char *origin_data = - Get_binary_data(program.model_path + "/" + var_desc->Name()); - char *data = origin_data; - LoadWithDump(*var_desc, tensor, &data,out_file); - delete origin_data; - fclose(out_file); + fclose(out_file); + delete origin_data; + +} + +void quantificate_seperated(const std::string model_dir, const std::string param_min_path) { + + auto program = loadParams(model_dir + "/__model__"); + + std::string shell_command = "mkdir " + param_min_path; + system(shell_command.c_str()); + + for (const auto &block : program->Blocks()) { + for (const auto &var_desc : block->Vars()) { + if (var_desc->Persistable()) { + if (var_desc->Name() == "feed" || var_desc->Name() == "fetch") { + continue; } + std::string file_name = param_min_path + "/" + var_desc->Name(); + FILE *out_file = fopen(file_name.c_str(), "wb"); + char *origin_data = Get_binary_data(model_dir + "/" + var_desc->Name()); + char *data = origin_data; + LoadWithDump(*var_desc, data, out_file); + delete origin_data; + fclose(out_file); } } + } + +} + + +int main(int argc, char **argv) { + + const std::string kNoteEg = "( eg: ./quantify 1 your_combined_model_path output_path or ./quantify 0 your_seperated_model_path output_path)"; + PADDLE_MOBILE_ENFORCE(argc > 1, "wee need params.%s ", kNoteEg.c_str()); + + std::string action_type = argv[1]; + PADDLE_MOBILE_ENFORCE(argc > 1 && (action_type) == "1" || action_type == "0", + "only 1 or 2 supported, current is %s %s ", + action_type.c_str(), + kNoteEg.c_str()); + + PADDLE_MOBILE_ENFORCE(argc > 2, "we need your model path. %s ", kNoteEg.c_str()); + std::string base_path = argv[2]; + + PADDLE_MOBILE_ENFORCE(argc > 3, "we need your output path. %s ", kNoteEg.c_str()); + std::string output_path = argv[3]; + + if (action_type == "0") { + // for seperated + const std::string &seperated_min_dir = output_path; + quantificate_seperated(base_path, seperated_min_dir); + return 0; } - int main() { - std::string filename = "params_min"; - std::string model_path = g_googlenet_combine + "/model"; - std::string param_path = g_googlenet_combine + "/params"; - std::string dirname = "param_min_dir"; - std::string model_dir = g_googlenet; -// quantificate_combined(model_path, param_path,filename); - quantificate_seperated(model_dir, dirname); + + if (action_type == "1") { + // for combined + const std::string &combined_min_dir = output_path; + std::string model_path = base_path + "/model"; + std::string param_path = base_path + "/params"; + quantificate_combined(model_path, param_path, combined_min_dir); return 0; } + return -1; +} + diff --git a/tools/quantification/src/block_desc_local.cpp b/tools/quantification/src/block_desc_local.cpp new file mode 100644 index 0000000000000000000000000000000000000000..8ad1982c05ed0b1b7c7bec5ef26aa8151f941cf3 --- /dev/null +++ b/tools/quantification/src/block_desc_local.cpp @@ -0,0 +1,48 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. */ + +// +// Created by 谢柏渊 on 2018/7/25. +// +#include "src/block_desc_local.h" +#include +#include +#include + +#include "src/framework.pb-c.h" + +std::vector> +BlockDesc::Vars() const { + return vars_; +} + +BlockDesc::BlockDesc(PaddleMobile__Framework__Proto__BlockDesc *desc) + : index_(desc->idx), parent_index_(desc->idx) { + for (int i = 0; i < desc->n_vars; ++i) { + PaddleMobile__Framework__Proto__VarDesc *var_desc = desc->vars[i]; + vars_.emplace_back(std::shared_ptr( + new paddle_mobile::framework::VarDesc(var_desc))); + } + + std::sort(vars_.begin(), vars_.end(), + [](std::shared_ptr left, + std::shared_ptr right) { + return left->Name() < right->Name(); + }); + + // for (int j = 0; j < desc->n_ops; ++j) { + // PaddleMobile__Framework__Proto__OpDesc *op_desc = desc->ops[j]; + // ops_.emplace_back(new OpDesc(op_desc)); + // } +} diff --git a/tools/quantification/src/block_desc_local.h b/tools/quantification/src/block_desc_local.h new file mode 100644 index 0000000000000000000000000000000000000000..41c2dc0abbdf8bb006f4152674e92dd1f7d01500 --- /dev/null +++ b/tools/quantification/src/block_desc_local.h @@ -0,0 +1,55 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. */ + +// +// Created by 谢柏渊 on 2018/7/25. +// + +#ifndef TOOLS_QUANTIFICATION_SRC_BLOCK_DESC_LOCAL_H_ +#define TOOLS_QUANTIFICATION_SRC_BLOCK_DESC_LOCAL_H_ + +#include +#include "src/var_desc.h" + +class BlockDesc { + public: + friend class Node; + friend class ProgramOptimize; + BlockDesc() {} + explicit BlockDesc(PaddleMobile__Framework__Proto__BlockDesc *desc); + + const int &ID() const { return index_; } + + const bool &MultiThread() const { return multi_thread_; } + + const int &Parent() const { return parent_index_; } + + bool operator==(const BlockDesc &in_block) const { + return this->ID() == in_block.ID() && this->Parent() == in_block.Parent(); + } + + bool operator<(const BlockDesc &in_block) const { + return this->ID() < in_block.ID() && this->Parent() < in_block.Parent(); + } + + std::vector> Vars() const; + + private: + int index_; + bool multi_thread_; + int parent_index_; + std::vector> vars_; +}; + +#endif // TOOLS_QUANTIFICATION_SRC_BLOCK_DESC_LOCAL_H_ diff --git a/tools/quantification/src/enforce.h b/tools/quantification/src/enforce.h new file mode 100644 index 0000000000000000000000000000000000000000..51d2110e32433686d1b3353bc63b92a564a13e9d --- /dev/null +++ b/tools/quantification/src/enforce.h @@ -0,0 +1,67 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. */ + +#pragma once + +#ifdef ENABLE_EXCEPTION +#include +#include +#include + +#endif + +namespace paddle_mobile { + +#ifdef ENABLE_EXCEPTION +struct PaddleMobileException : public std::exception { + const std::string exception_prefix = "paddle mobile C++ Exception: \n"; + std::string message; + + PaddleMobileException(const char *header, const char *detail, + const char *file, const int line) { + char buffer[1500]; + snprintf(buffer, sizeof(buffer), + "%s| %s \n| [in file] : %s\n| [on line] : %d\n| [detail] : %s\n", + exception_prefix.c_str(), header, file, line, detail); + message = std::string(buffer); + } + const char *what() const noexcept { return message.c_str(); } +}; + +#define PADDLE_MOBILE_THROW_EXCEPTION(...) \ + { \ + char buffer[1000]; \ + snprintf(buffer, sizeof(buffer), __VA_ARGS__); \ + std::string detail(buffer); \ + throw paddle_mobile::PaddleMobileException("Custom Exception", buffer, \ + __FILE__, __LINE__); \ + } + +#define PADDLE_MOBILE_ENFORCE(stat, ...) \ + { \ + if (stat) { \ + } else { \ + char buffer[1000]; \ + snprintf(buffer, sizeof(buffer), __VA_ARGS__); \ + std::string detail(buffer); \ + throw paddle_mobile::PaddleMobileException("paddle-mobile enforce", \ + buffer, __FILE__, __LINE__); \ + } \ + } +#else +#define PADDLE_MOBILE_THROW_EXCEPTION(...) +#define PADDLE_MOBILE_ENFORCE(stat, ...) +#endif + +} // namespace paddle_mobile diff --git a/tools/quantification/src/framework.pb-c.c b/tools/quantification/src/framework.pb-c.c new file mode 100644 index 0000000000000000000000000000000000000000..aed0a6c9c0614da74a82cea8c7aa705978dddafc --- /dev/null +++ b/tools/quantification/src/framework.pb-c.c @@ -0,0 +1,1403 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: framework.proto */ + +/* Do not generate deprecated warnings for self */ +#ifndef PROTOBUF_C__NO_DEPRECATED +#define PROTOBUF_C__NO_DEPRECATED +#endif + +#include "framework.pb-c.h" +void paddle_mobile__framework__proto__op_desc__attr__init( + PaddleMobile__Framework__Proto__OpDesc__Attr *message) { + static const PaddleMobile__Framework__Proto__OpDesc__Attr init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__ATTR__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__op_desc__var__init( + PaddleMobile__Framework__Proto__OpDesc__Var *message) { + static const PaddleMobile__Framework__Proto__OpDesc__Var init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__VAR__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__op_desc__init( + PaddleMobile__Framework__Proto__OpDesc *message) { + static const PaddleMobile__Framework__Proto__OpDesc init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__INIT; + *message = init_value; +} +size_t paddle_mobile__framework__proto__op_desc__get_packed_size( + const PaddleMobile__Framework__Proto__OpDesc *message) { + assert(message->base.descriptor == + &paddle_mobile__framework__proto__op_desc__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *)(message)); +} + +PaddleMobile__Framework__Proto__OpDesc * +paddle_mobile__framework__proto__op_desc__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) { + return (PaddleMobile__Framework__Proto__OpDesc *)protobuf_c_message_unpack( + &paddle_mobile__framework__proto__op_desc__descriptor, allocator, len, + data); +} +void paddle_mobile__framework__proto__op_desc__free_unpacked( + PaddleMobile__Framework__Proto__OpDesc *message, + ProtobufCAllocator *allocator) { + if (!message) return; + assert(message->base.descriptor == + &paddle_mobile__framework__proto__op_desc__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator); +} +void paddle_mobile__framework__proto__op_proto__var__init( + PaddleMobile__Framework__Proto__OpProto__Var *message) { + static const PaddleMobile__Framework__Proto__OpProto__Var init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__VAR__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__op_proto__attr__init( + PaddleMobile__Framework__Proto__OpProto__Attr *message) { + static const PaddleMobile__Framework__Proto__OpProto__Attr init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__ATTR__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__op_proto__init( + PaddleMobile__Framework__Proto__OpProto *message) { + static const PaddleMobile__Framework__Proto__OpProto init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__INIT; + *message = init_value; +} +size_t paddle_mobile__framework__proto__op_proto__get_packed_size( + const PaddleMobile__Framework__Proto__OpProto *message) { + assert(message->base.descriptor == + &paddle_mobile__framework__proto__op_proto__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *)(message)); +} + +PaddleMobile__Framework__Proto__OpProto * +paddle_mobile__framework__proto__op_proto__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) { + return (PaddleMobile__Framework__Proto__OpProto *)protobuf_c_message_unpack( + &paddle_mobile__framework__proto__op_proto__descriptor, allocator, len, + data); +} +void paddle_mobile__framework__proto__op_proto__free_unpacked( + PaddleMobile__Framework__Proto__OpProto *message, + ProtobufCAllocator *allocator) { + if (!message) return; + assert(message->base.descriptor == + &paddle_mobile__framework__proto__op_proto__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator); +} +void paddle_mobile__framework__proto__var_type__tensor_desc__init( + PaddleMobile__Framework__Proto__VarType__TensorDesc *message) { + static const PaddleMobile__Framework__Proto__VarType__TensorDesc init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TENSOR_DESC__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__var_type__lo_dtensor_desc__init( + PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *message) { + static const PaddleMobile__Framework__Proto__VarType__LoDTensorDesc + init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_DESC__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__init( + PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *message) { + static const PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc + init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_ARRAY_DESC__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__var_type__reader_desc__init( + PaddleMobile__Framework__Proto__VarType__ReaderDesc *message) { + static const PaddleMobile__Framework__Proto__VarType__ReaderDesc init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__READER_DESC__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__var_type__channel_desc__init( + PaddleMobile__Framework__Proto__VarType__ChannelDesc *message) { + static const PaddleMobile__Framework__Proto__VarType__ChannelDesc init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__CHANNEL_DESC__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__var_type__tuple__init( + PaddleMobile__Framework__Proto__VarType__Tuple *message) { + static const PaddleMobile__Framework__Proto__VarType__Tuple init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TUPLE__INIT; + *message = init_value; +} +void paddle_mobile__framework__proto__var_type__init( + PaddleMobile__Framework__Proto__VarType *message) { + static const PaddleMobile__Framework__Proto__VarType init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__INIT; + *message = init_value; +} +size_t paddle_mobile__framework__proto__var_type__get_packed_size( + const PaddleMobile__Framework__Proto__VarType *message) { + assert(message->base.descriptor == + &paddle_mobile__framework__proto__var_type__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *)(message)); +} +PaddleMobile__Framework__Proto__VarType * +paddle_mobile__framework__proto__var_type__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) { + return (PaddleMobile__Framework__Proto__VarType *)protobuf_c_message_unpack( + &paddle_mobile__framework__proto__var_type__descriptor, allocator, len, + data); +} +void paddle_mobile__framework__proto__var_type__free_unpacked( + PaddleMobile__Framework__Proto__VarType *message, + ProtobufCAllocator *allocator) { + if (!message) return; + assert(message->base.descriptor == + &paddle_mobile__framework__proto__var_type__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator); +} +void paddle_mobile__framework__proto__var_desc__init( + PaddleMobile__Framework__Proto__VarDesc *message) { + static const PaddleMobile__Framework__Proto__VarDesc init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_DESC__INIT; + *message = init_value; +} +size_t paddle_mobile__framework__proto__var_desc__get_packed_size( + const PaddleMobile__Framework__Proto__VarDesc *message) { + assert(message->base.descriptor == + &paddle_mobile__framework__proto__var_desc__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *)(message)); +} + +PaddleMobile__Framework__Proto__VarDesc * +paddle_mobile__framework__proto__var_desc__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data) { + return (PaddleMobile__Framework__Proto__VarDesc *)protobuf_c_message_unpack( + &paddle_mobile__framework__proto__var_desc__descriptor, allocator, len, + data); +} +void paddle_mobile__framework__proto__var_desc__free_unpacked( + PaddleMobile__Framework__Proto__VarDesc *message, + ProtobufCAllocator *allocator) { + if (!message) return; + assert(message->base.descriptor == + &paddle_mobile__framework__proto__var_desc__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator); +} +void paddle_mobile__framework__proto__block_desc__init( + PaddleMobile__Framework__Proto__BlockDesc *message) { + static const PaddleMobile__Framework__Proto__BlockDesc init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__BLOCK_DESC__INIT; + *message = init_value; +} +size_t paddle_mobile__framework__proto__block_desc__get_packed_size( + const PaddleMobile__Framework__Proto__BlockDesc *message) { + assert(message->base.descriptor == + &paddle_mobile__framework__proto__block_desc__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *)(message)); +} + +PaddleMobile__Framework__Proto__BlockDesc * +paddle_mobile__framework__proto__block_desc__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { + return (PaddleMobile__Framework__Proto__BlockDesc *)protobuf_c_message_unpack( + &paddle_mobile__framework__proto__block_desc__descriptor, allocator, len, + data); +} +void paddle_mobile__framework__proto__block_desc__free_unpacked( + PaddleMobile__Framework__Proto__BlockDesc *message, + ProtobufCAllocator *allocator) { + if (!message) return; + assert(message->base.descriptor == + &paddle_mobile__framework__proto__block_desc__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator); +} +void paddle_mobile__framework__proto__program_desc__init( + PaddleMobile__Framework__Proto__ProgramDesc *message) { + static const PaddleMobile__Framework__Proto__ProgramDesc init_value = + PADDLE_MOBILE__FRAMEWORK__PROTO__PROGRAM_DESC__INIT; + *message = init_value; +} +size_t paddle_mobile__framework__proto__program_desc__get_packed_size( + const PaddleMobile__Framework__Proto__ProgramDesc *message) { + assert(message->base.descriptor == + &paddle_mobile__framework__proto__program_desc__descriptor); + return protobuf_c_message_get_packed_size( + (const ProtobufCMessage *)(message)); +} + +PaddleMobile__Framework__Proto__ProgramDesc * +paddle_mobile__framework__proto__program_desc__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data) { + return (PaddleMobile__Framework__Proto__ProgramDesc *) + protobuf_c_message_unpack( + &paddle_mobile__framework__proto__program_desc__descriptor, allocator, + len, data); +} +void paddle_mobile__framework__proto__program_desc__free_unpacked( + PaddleMobile__Framework__Proto__ProgramDesc *message, + ProtobufCAllocator *allocator) { + if (!message) return; + assert(message->base.descriptor == + &paddle_mobile__framework__proto__program_desc__descriptor); + protobuf_c_message_free_unpacked((ProtobufCMessage *)message, allocator); +} +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__op_desc__attr__field_descriptors[12] = { + { + "name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, name), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "type", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, type), + &paddle_mobile__framework__proto__attr_type__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "i", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT32, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_i), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, i), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "f", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_FLOAT, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_f), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, f), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "s", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, s), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "ints", 6, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_INT32, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_ints), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, ints), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "floats", 7, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_FLOAT, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_floats), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, floats), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "strings", 8, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_STRING, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_strings), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, strings), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "b", 10, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_b), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, b), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "bools", 11, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, n_bools), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, bools), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "block_idx", 12, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT32, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, + has_block_idx), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, block_idx), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "l", 13, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_INT64, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, has_l), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Attr, l), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__op_desc__attr__field_indices_by_name[] = { + 8, /* field[8] = b */ + 10, /* field[10] = block_idx */ + 9, /* field[9] = bools */ + 3, /* field[3] = f */ + 6, /* field[6] = floats */ + 2, /* field[2] = i */ + 5, /* field[5] = ints */ + 11, /* field[11] = l */ + 0, /* field[0] = name */ + 4, /* field[4] = s */ + 7, /* field[7] = strings */ + 1, /* field[1] = type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__op_desc__attr__number_ranges[2 + 1] = { + {1, 0}, {10, 8}, {0, 12}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_desc__attr__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.OpDesc.Attr", + "Attr", + "PaddleMobile__Framework__Proto__OpDesc__Attr", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__OpDesc__Attr), + 12, + paddle_mobile__framework__proto__op_desc__attr__field_descriptors, + paddle_mobile__framework__proto__op_desc__attr__field_indices_by_name, + 2, + paddle_mobile__framework__proto__op_desc__attr__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__op_desc__attr__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__op_desc__var__field_descriptors[2] = { + { + "parameter", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpDesc__Var, parameter), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "arguments", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_STRING, + offsetof(PaddleMobile__Framework__Proto__OpDesc__Var, n_arguments), + offsetof(PaddleMobile__Framework__Proto__OpDesc__Var, arguments), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__op_desc__var__field_indices_by_name[] = { + 1, /* field[1] = arguments */ + 0, /* field[0] = parameter */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__op_desc__var__number_ranges[1 + 1] = { + {1, 0}, {0, 2}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_desc__var__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.OpDesc.Var", + "Var", + "PaddleMobile__Framework__Proto__OpDesc__Var", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__OpDesc__Var), + 2, + paddle_mobile__framework__proto__op_desc__var__field_descriptors, + paddle_mobile__framework__proto__op_desc__var__field_indices_by_name, + 1, + paddle_mobile__framework__proto__op_desc__var__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__op_desc__var__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const protobuf_c_boolean + paddle_mobile__framework__proto__op_desc__is_target__default_value = 0; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__op_desc__field_descriptors[5] = { + { + "inputs", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__OpDesc, n_inputs), + offsetof(PaddleMobile__Framework__Proto__OpDesc, inputs), + &paddle_mobile__framework__proto__op_desc__var__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "outputs", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__OpDesc, n_outputs), + offsetof(PaddleMobile__Framework__Proto__OpDesc, outputs), + &paddle_mobile__framework__proto__op_desc__var__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "type", 3, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpDesc, type), NULL, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "attrs", 4, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__OpDesc, n_attrs), + offsetof(PaddleMobile__Framework__Proto__OpDesc, attrs), + &paddle_mobile__framework__proto__op_desc__attr__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "is_target", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__OpDesc, has_is_target), + offsetof(PaddleMobile__Framework__Proto__OpDesc, is_target), NULL, + &paddle_mobile__framework__proto__op_desc__is_target__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__op_desc__field_indices_by_name[] = { + 3, /* field[3] = attrs */ + 0, /* field[0] = inputs */ + 4, /* field[4] = is_target */ + 1, /* field[1] = outputs */ + 2, /* field[2] = type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__op_desc__number_ranges[1 + 1] = {{1, 0}, + {0, 5}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.OpDesc", + "OpDesc", + "PaddleMobile__Framework__Proto__OpDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__OpDesc), + 5, + paddle_mobile__framework__proto__op_desc__field_descriptors, + paddle_mobile__framework__proto__op_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__op_desc__number_ranges, + (ProtobufCMessageInit)paddle_mobile__framework__proto__op_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const protobuf_c_boolean + paddle_mobile__framework__proto__op_proto__var__duplicable__default_value = + 0; +static const protobuf_c_boolean + paddle_mobile__framework__proto__op_proto__var__intermediate__default_value = + 0; +static const protobuf_c_boolean + paddle_mobile__framework__proto__op_proto__var__dispensable__default_value = + 0; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__op_proto__var__field_descriptors[5] = { + { + "name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, name), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "comment", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, comment), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "duplicable", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, + has_duplicable), + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, duplicable), + NULL, + &paddle_mobile__framework__proto__op_proto__var__duplicable__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "intermediate", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, + has_intermediate), + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, + intermediate), + NULL, + &paddle_mobile__framework__proto__op_proto__var__intermediate__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dispensable", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, + has_dispensable), + offsetof(PaddleMobile__Framework__Proto__OpProto__Var, dispensable), + NULL, + &paddle_mobile__framework__proto__op_proto__var__dispensable__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__op_proto__var__field_indices_by_name[] = { + 1, /* field[1] = comment */ + 4, /* field[4] = dispensable */ + 2, /* field[2] = duplicable */ + 3, /* field[3] = intermediate */ + 0, /* field[0] = name */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__op_proto__var__number_ranges[1 + 1] = { + {1, 0}, {0, 5}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_proto__var__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.OpProto.Var", + "Var", + "PaddleMobile__Framework__Proto__OpProto__Var", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__OpProto__Var), + 5, + paddle_mobile__framework__proto__op_proto__var__field_descriptors, + paddle_mobile__framework__proto__op_proto__var__field_indices_by_name, + 1, + paddle_mobile__framework__proto__op_proto__var__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__op_proto__var__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const protobuf_c_boolean + paddle_mobile__framework__proto__op_proto__attr__generated__default_value = + 0; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__op_proto__attr__field_descriptors[4] = { + { + "name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, name), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "type", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, type), + &paddle_mobile__framework__proto__attr_type__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "comment", 3, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, comment), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "generated", 4, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, + has_generated), + offsetof(PaddleMobile__Framework__Proto__OpProto__Attr, generated), + NULL, + &paddle_mobile__framework__proto__op_proto__attr__generated__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__op_proto__attr__field_indices_by_name[] = { + 2, /* field[2] = comment */ + 3, /* field[3] = generated */ + 0, /* field[0] = name */ + 1, /* field[1] = type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__op_proto__attr__number_ranges[1 + 1] = { + {1, 0}, {0, 4}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_proto__attr__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.OpProto.Attr", + "Attr", + "PaddleMobile__Framework__Proto__OpProto__Attr", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__OpProto__Attr), + 4, + paddle_mobile__framework__proto__op_proto__attr__field_descriptors, + paddle_mobile__framework__proto__op_proto__attr__field_indices_by_name, + 1, + paddle_mobile__framework__proto__op_proto__attr__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__op_proto__attr__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__op_proto__field_descriptors[5] = { + { + "type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpProto, type), NULL, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "inputs", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__OpProto, n_inputs), + offsetof(PaddleMobile__Framework__Proto__OpProto, inputs), + &paddle_mobile__framework__proto__op_proto__var__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "outputs", 3, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__OpProto, n_outputs), + offsetof(PaddleMobile__Framework__Proto__OpProto, outputs), + &paddle_mobile__framework__proto__op_proto__var__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "attrs", 4, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__OpProto, n_attrs), + offsetof(PaddleMobile__Framework__Proto__OpProto, attrs), + &paddle_mobile__framework__proto__op_proto__attr__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "comment", 5, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__OpProto, comment), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__op_proto__field_indices_by_name[] = { + 3, /* field[3] = attrs */ + 4, /* field[4] = comment */ + 1, /* field[1] = inputs */ + 2, /* field[2] = outputs */ + 0, /* field[0] = type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__op_proto__number_ranges[1 + 1] = {{1, 0}, + {0, 5}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_proto__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.OpProto", + "OpProto", + "PaddleMobile__Framework__Proto__OpProto", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__OpProto), + 5, + paddle_mobile__framework__proto__op_proto__field_descriptors, + paddle_mobile__framework__proto__op_proto__field_indices_by_name, + 1, + paddle_mobile__framework__proto__op_proto__number_ranges, + (ProtobufCMessageInit)paddle_mobile__framework__proto__op_proto__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_type__tensor_desc__field_descriptors + [2] = { + { + "data_type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType__TensorDesc, + data_type), + &paddle_mobile__framework__proto__var_type__type__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "dims", 2, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_INT64, + offsetof(PaddleMobile__Framework__Proto__VarType__TensorDesc, + n_dims), + offsetof(PaddleMobile__Framework__Proto__VarType__TensorDesc, + dims), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_type__tensor_desc__field_indices_by_name + [] = { + 0, /* field[0] = data_type */ + 1, /* field[1] = dims */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__tensor_desc__number_ranges[1 + + 1] = { + {1, 0}, {0, 2}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__tensor_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType.TensorDesc", + "TensorDesc", + "PaddleMobile__Framework__Proto__VarType__TensorDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarType__TensorDesc), + 2, + paddle_mobile__framework__proto__var_type__tensor_desc__field_descriptors, + paddle_mobile__framework__proto__var_type__tensor_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_type__tensor_desc__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__var_type__tensor_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const int32_t + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__lod_level__default_value = + 0; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_descriptors + [2] = { + { + "tensor", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc, + tensor), + &paddle_mobile__framework__proto__var_type__tensor_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "lod_level", 2, PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT32, + offsetof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc, + has_lod_level), + offsetof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc, + lod_level), + NULL, + &paddle_mobile__framework__proto__var_type__lo_dtensor_desc__lod_level__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_indices_by_name + [] = { + 1, /* field[1] = lod_level */ + 0, /* field[0] = tensor */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__number_ranges + [1 + 1] = {{1, 0}, {0, 2}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType.LoDTensorDesc", + "LoDTensorDesc", + "PaddleMobile__Framework__Proto__VarType__LoDTensorDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarType__LoDTensorDesc), + 2, + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_descriptors, + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const int32_t + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__lod_level__default_value = + 0; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_descriptors + [2] = { + { + "tensor", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof( + PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc, + tensor), + &paddle_mobile__framework__proto__var_type__tensor_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "lod_level", 2, PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT32, + offsetof( + PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc, + has_lod_level), + offsetof( + PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc, + lod_level), + NULL, + &paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__lod_level__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_indices_by_name + [] = { + 1, /* field[1] = lod_level */ + 0, /* field[0] = tensor */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__number_ranges + [1 + 1] = {{1, 0}, {0, 2}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType.LoDTensorArrayDesc", + "LoDTensorArrayDesc", + "PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc), + 2, + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_descriptors, + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_type__reader_desc__field_descriptors[1] = { + { + "lod_tensor", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__VarType__ReaderDesc, + n_lod_tensor), + offsetof(PaddleMobile__Framework__Proto__VarType__ReaderDesc, + lod_tensor), + &paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_type__reader_desc__field_indices_by_name + [] = { + 0, /* field[0] = lod_tensor */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__reader_desc__number_ranges[1 + + 1] = { + {1, 0}, {0, 1}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__reader_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType.ReaderDesc", + "ReaderDesc", + "PaddleMobile__Framework__Proto__VarType__ReaderDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarType__ReaderDesc), + 1, + paddle_mobile__framework__proto__var_type__reader_desc__field_descriptors, + paddle_mobile__framework__proto__var_type__reader_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_type__reader_desc__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__var_type__reader_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_type__channel_desc__field_descriptors + [2] = { + { + "data_type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType__ChannelDesc, + data_type), + &paddle_mobile__framework__proto__var_type__type__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "capacity", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_INT64, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType__ChannelDesc, + capacity), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_type__channel_desc__field_indices_by_name + [] = { + 1, /* field[1] = capacity */ + 0, /* field[0] = data_type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__channel_desc__number_ranges[1 + + 1] = + {{1, 0}, {0, 2}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__channel_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType.ChannelDesc", + "ChannelDesc", + "PaddleMobile__Framework__Proto__VarType__ChannelDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarType__ChannelDesc), + 2, + paddle_mobile__framework__proto__var_type__channel_desc__field_descriptors, + paddle_mobile__framework__proto__var_type__channel_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_type__channel_desc__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__var_type__channel_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_type__tuple__field_descriptors[1] = { + { + "element_type", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_ENUM, + offsetof(PaddleMobile__Framework__Proto__VarType__Tuple, + n_element_type), + offsetof(PaddleMobile__Framework__Proto__VarType__Tuple, + element_type), + &paddle_mobile__framework__proto__var_type__type__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_type__tuple__field_indices_by_name[] = + { + 0, /* field[0] = element_type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__tuple__number_ranges[1 + 1] = { + {1, 0}, {0, 1}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__tuple__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType.Tuple", + "Tuple", + "PaddleMobile__Framework__Proto__VarType__Tuple", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarType__Tuple), + 1, + paddle_mobile__framework__proto__var_type__tuple__field_descriptors, + paddle_mobile__framework__proto__var_type__tuple__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_type__tuple__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__var_type__tuple__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue + paddle_mobile__framework__proto__var_type__type__enum_values_by_number[19] = + { + {"BOOL", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL", + 0}, + {"INT16", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT16", + 1}, + {"INT32", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT32", + 2}, + {"INT64", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT64", + 3}, + {"FP16", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP16", + 4}, + {"FP32", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP32", + 5}, + {"FP64", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP64", + 6}, + {"LOD_TENSOR", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR", 7}, + {"SELECTED_ROWS", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__SELECTED_ROWS", + 8}, + {"FEED_MINIBATCH", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FEED_MINIBATCH", + 9}, + {"FETCH_LIST", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FETCH_LIST", 10}, + {"STEP_SCOPES", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__STEP_SCOPES", + 11}, + {"LOD_RANK_TABLE", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_RANK_TABLE", + 12}, + {"LOD_TENSOR_ARRAY", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR_" + "ARRAY", + 13}, + {"PLACE_LIST", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__PLACE_LIST", 14}, + {"READER", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__READER", 15}, + {"CHANNEL", + "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__CHANNEL", 16}, + {"RAW", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__RAW", 17}, + {"TUPLE", "PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__TUPLE", + 18}, +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__type__value_ranges[] = {{0, 0}, + {0, 19}}; +static const ProtobufCEnumValueIndex + paddle_mobile__framework__proto__var_type__type__enum_values_by_name[19] = { + {"BOOL", 0}, + {"CHANNEL", 16}, + {"FEED_MINIBATCH", 9}, + {"FETCH_LIST", 10}, + {"FP16", 4}, + {"FP32", 5}, + {"FP64", 6}, + {"INT16", 1}, + {"INT32", 2}, + {"INT64", 3}, + {"LOD_RANK_TABLE", 12}, + {"LOD_TENSOR", 7}, + {"LOD_TENSOR_ARRAY", 13}, + {"PLACE_LIST", 14}, + {"RAW", 17}, + {"READER", 15}, + {"SELECTED_ROWS", 8}, + {"STEP_SCOPES", 11}, + {"TUPLE", 18}, +}; +const ProtobufCEnumDescriptor + paddle_mobile__framework__proto__var_type__type__descriptor = { + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType.Type", + "Type", + "PaddleMobile__Framework__Proto__VarType__Type", + "paddle_mobile.framework.proto", + 19, + paddle_mobile__framework__proto__var_type__type__enum_values_by_number, + 19, + paddle_mobile__framework__proto__var_type__type__enum_values_by_name, + 1, + paddle_mobile__framework__proto__var_type__type__value_ranges, + NULL, + NULL, + NULL, + NULL /* reserved[1234] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_type__field_descriptors[7] = { + { + "type", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_ENUM, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType, type), + &paddle_mobile__framework__proto__var_type__type__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "selected_rows", 2, PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType, selected_rows), + &paddle_mobile__framework__proto__var_type__tensor_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "lod_tensor", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType, lod_tensor), + &paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "tensor_array", 4, PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_MESSAGE, 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType, tensor_array), + &paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "reader", 5, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType, reader), + &paddle_mobile__framework__proto__var_type__reader_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "channel", 6, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType, channel), + &paddle_mobile__framework__proto__var_type__channel_desc__descriptor, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "tuple", 7, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarType, tuple), + &paddle_mobile__framework__proto__var_type__tuple__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_type__field_indices_by_name[] = { + 5, /* field[5] = channel */ + 2, /* field[2] = lod_tensor */ + 4, /* field[4] = reader */ + 1, /* field[1] = selected_rows */ + 3, /* field[3] = tensor_array */ + 6, /* field[6] = tuple */ + 0, /* field[0] = type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_type__number_ranges[1 + 1] = {{1, 0}, + {0, 7}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarType", + "VarType", + "PaddleMobile__Framework__Proto__VarType", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarType), + 7, + paddle_mobile__framework__proto__var_type__field_descriptors, + paddle_mobile__framework__proto__var_type__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_type__number_ranges, + (ProtobufCMessageInit)paddle_mobile__framework__proto__var_type__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const protobuf_c_boolean + paddle_mobile__framework__proto__var_desc__persistable__default_value = 0; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__var_desc__field_descriptors[3] = { + { + "name", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_STRING, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarDesc, name), NULL, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "type", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_MESSAGE, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__VarDesc, type), + &paddle_mobile__framework__proto__var_type__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "persistable", 3, PROTOBUF_C_LABEL_OPTIONAL, PROTOBUF_C_TYPE_BOOL, + offsetof(PaddleMobile__Framework__Proto__VarDesc, has_persistable), + offsetof(PaddleMobile__Framework__Proto__VarDesc, persistable), + NULL, + &paddle_mobile__framework__proto__var_desc__persistable__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__var_desc__field_indices_by_name[] = { + 0, /* field[0] = name */ + 2, /* field[2] = persistable */ + 1, /* field[1] = type */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__var_desc__number_ranges[1 + 1] = {{1, 0}, + {0, 3}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.VarDesc", + "VarDesc", + "PaddleMobile__Framework__Proto__VarDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__VarDesc), + 3, + paddle_mobile__framework__proto__var_desc__field_descriptors, + paddle_mobile__framework__proto__var_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__var_desc__number_ranges, + (ProtobufCMessageInit)paddle_mobile__framework__proto__var_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const int32_t + paddle_mobile__framework__proto__block_desc__forward_block_idx__default_value = + -1; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__block_desc__field_descriptors[5] = { + { + "idx", 1, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__BlockDesc, idx), NULL, + NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "parent_idx", 2, PROTOBUF_C_LABEL_REQUIRED, PROTOBUF_C_TYPE_INT32, + 0, /* quantifier_offset */ + offsetof(PaddleMobile__Framework__Proto__BlockDesc, parent_idx), + NULL, NULL, 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "vars", 3, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__BlockDesc, n_vars), + offsetof(PaddleMobile__Framework__Proto__BlockDesc, vars), + &paddle_mobile__framework__proto__var_desc__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "ops", 4, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__BlockDesc, n_ops), + offsetof(PaddleMobile__Framework__Proto__BlockDesc, ops), + &paddle_mobile__framework__proto__op_desc__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, + { + "forward_block_idx", 5, PROTOBUF_C_LABEL_OPTIONAL, + PROTOBUF_C_TYPE_INT32, + offsetof(PaddleMobile__Framework__Proto__BlockDesc, + has_forward_block_idx), + offsetof(PaddleMobile__Framework__Proto__BlockDesc, + forward_block_idx), + NULL, + &paddle_mobile__framework__proto__block_desc__forward_block_idx__default_value, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__block_desc__field_indices_by_name[] = { + 4, /* field[4] = forward_block_idx */ + 0, /* field[0] = idx */ + 3, /* field[3] = ops */ + 1, /* field[1] = parent_idx */ + 2, /* field[2] = vars */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__block_desc__number_ranges[1 + 1] = { + {1, 0}, {0, 5}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__block_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.BlockDesc", + "BlockDesc", + "PaddleMobile__Framework__Proto__BlockDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__BlockDesc), + 5, + paddle_mobile__framework__proto__block_desc__field_descriptors, + paddle_mobile__framework__proto__block_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__block_desc__number_ranges, + (ProtobufCMessageInit)paddle_mobile__framework__proto__block_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCFieldDescriptor + paddle_mobile__framework__proto__program_desc__field_descriptors[1] = { + { + "blocks", 1, PROTOBUF_C_LABEL_REPEATED, PROTOBUF_C_TYPE_MESSAGE, + offsetof(PaddleMobile__Framework__Proto__ProgramDesc, n_blocks), + offsetof(PaddleMobile__Framework__Proto__ProgramDesc, blocks), + &paddle_mobile__framework__proto__block_desc__descriptor, NULL, + 0, /* flags */ + 0, NULL, NULL /* reserved1,reserved2, etc */ + }, +}; +static const unsigned + paddle_mobile__framework__proto__program_desc__field_indices_by_name[] = { + 0, /* field[0] = blocks */ +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__program_desc__number_ranges[1 + 1] = { + {1, 0}, {0, 1}}; +const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__program_desc__descriptor = { + PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.ProgramDesc", + "ProgramDesc", + "PaddleMobile__Framework__Proto__ProgramDesc", + "paddle_mobile.framework.proto", + sizeof(PaddleMobile__Framework__Proto__ProgramDesc), + 1, + paddle_mobile__framework__proto__program_desc__field_descriptors, + paddle_mobile__framework__proto__program_desc__field_indices_by_name, + 1, + paddle_mobile__framework__proto__program_desc__number_ranges, + (ProtobufCMessageInit) + paddle_mobile__framework__proto__program_desc__init, + NULL, + NULL, + NULL /* reserved[123] */ +}; +static const ProtobufCEnumValue + paddle_mobile__framework__proto__attr_type__enum_values_by_number[10] = { + {"INT", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT", 0}, + {"FLOAT", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOAT", 1}, + {"STRING", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRING", 2}, + {"INTS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INTS", 3}, + {"FLOATS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOATS", 4}, + {"STRINGS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRINGS", 5}, + {"BOOLEAN", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEAN", 6}, + {"BOOLEANS", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEANS", 7}, + {"BLOCK", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK", 8}, + {"LONG", "PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__LONG", 9}, +}; +static const ProtobufCIntRange + paddle_mobile__framework__proto__attr_type__value_ranges[] = {{0, 0}, + {0, 10}}; +static const ProtobufCEnumValueIndex + paddle_mobile__framework__proto__attr_type__enum_values_by_name[10] = { + {"BLOCK", 8}, {"BOOLEAN", 6}, {"BOOLEANS", 7}, {"FLOAT", 1}, + {"FLOATS", 4}, {"INT", 0}, {"INTS", 3}, {"LONG", 9}, + {"STRING", 2}, {"STRINGS", 5}, +}; +const ProtobufCEnumDescriptor + paddle_mobile__framework__proto__attr_type__descriptor = { + PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC, + "paddle_mobile.framework.proto.AttrType", + "AttrType", + "PaddleMobile__Framework__Proto__AttrType", + "paddle_mobile.framework.proto", + 10, + paddle_mobile__framework__proto__attr_type__enum_values_by_number, + 10, + paddle_mobile__framework__proto__attr_type__enum_values_by_name, + 1, + paddle_mobile__framework__proto__attr_type__value_ranges, + NULL, + NULL, + NULL, + NULL /* reserved[1234] */ +}; diff --git a/tools/quantification/src/framework.pb-c.h b/tools/quantification/src/framework.pb-c.h new file mode 100644 index 0000000000000000000000000000000000000000..3d63bad76ad188d02986971bd911d8f30cf0af81 --- /dev/null +++ b/tools/quantification/src/framework.pb-c.h @@ -0,0 +1,579 @@ +/* Generated by the protocol buffer compiler. DO NOT EDIT! */ +/* Generated from: framework.proto */ + +#ifndef PROTOBUF_C_framework_2eproto__INCLUDED +#define PROTOBUF_C_framework_2eproto__INCLUDED + +#include "protobuf-c.h" + +PROTOBUF_C__BEGIN_DECLS + +#if PROTOBUF_C_VERSION_NUMBER < 1000000 +# error This file was generated by a newer version of protoc-c which is incompatible with your libprotobuf-c headers. Please update your headers. +#elif 1003000 < PROTOBUF_C_MIN_COMPILER_VERSION +# error This file was generated by an older version of protoc-c which is incompatible with your libprotobuf-c headers. Please regenerate this file with a newer version of protoc-c. +#endif + +typedef struct _PaddleMobile__Framework__Proto__OpDesc + PaddleMobile__Framework__Proto__OpDesc; +typedef struct _PaddleMobile__Framework__Proto__OpDesc__Attr + PaddleMobile__Framework__Proto__OpDesc__Attr; +typedef struct _PaddleMobile__Framework__Proto__OpDesc__Var + PaddleMobile__Framework__Proto__OpDesc__Var; +typedef struct _PaddleMobile__Framework__Proto__OpProto + PaddleMobile__Framework__Proto__OpProto; +typedef struct _PaddleMobile__Framework__Proto__OpProto__Var + PaddleMobile__Framework__Proto__OpProto__Var; +typedef struct _PaddleMobile__Framework__Proto__OpProto__Attr + PaddleMobile__Framework__Proto__OpProto__Attr; +typedef struct _PaddleMobile__Framework__Proto__VarType + PaddleMobile__Framework__Proto__VarType; +typedef struct _PaddleMobile__Framework__Proto__VarType__TensorDesc + PaddleMobile__Framework__Proto__VarType__TensorDesc; +typedef struct _PaddleMobile__Framework__Proto__VarType__LoDTensorDesc + PaddleMobile__Framework__Proto__VarType__LoDTensorDesc; +typedef struct _PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc + PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc; +typedef struct _PaddleMobile__Framework__Proto__VarType__ReaderDesc + PaddleMobile__Framework__Proto__VarType__ReaderDesc; +typedef struct _PaddleMobile__Framework__Proto__VarType__ChannelDesc + PaddleMobile__Framework__Proto__VarType__ChannelDesc; +typedef struct _PaddleMobile__Framework__Proto__VarType__Tuple + PaddleMobile__Framework__Proto__VarType__Tuple; +typedef struct _PaddleMobile__Framework__Proto__VarDesc + PaddleMobile__Framework__Proto__VarDesc; +typedef struct _PaddleMobile__Framework__Proto__BlockDesc + PaddleMobile__Framework__Proto__BlockDesc; +typedef struct _PaddleMobile__Framework__Proto__ProgramDesc + PaddleMobile__Framework__Proto__ProgramDesc; + +/* --- enums --- */ + +typedef enum _PaddleMobile__Framework__Proto__VarType__Type { + /* + * Pod Types + */ + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL = 0, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT16 = 1, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT32 = 2, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__INT64 = 3, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP16 = 4, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP32 = 5, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FP64 = 6, + /* + * Other types that may need additional descriptions + */ + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR = 7, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__SELECTED_ROWS = 8, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FEED_MINIBATCH = 9, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__FETCH_LIST = 10, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__STEP_SCOPES = 11, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_RANK_TABLE = 12, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__LOD_TENSOR_ARRAY = 13, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__PLACE_LIST = 14, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__READER = 15, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__CHANNEL = 16, + /* + * Any runtime decided variable type is raw + * raw variables should manage their own allocations + * in operators like nccl_op + */ + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__RAW = 17, + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__TUPLE = + 18 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE( + PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE) +} PaddleMobile__Framework__Proto__VarType__Type; +typedef enum _PaddleMobile__Framework__Proto__AttrType { + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT = 0, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOAT = 1, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRING = 2, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INTS = 3, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__FLOATS = 4, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__STRINGS = 5, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEAN = 6, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BOOLEANS = 7, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__BLOCK = 8, + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__LONG = + 9 PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE( + PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE) +} PaddleMobile__Framework__Proto__AttrType; + +/* --- messages --- */ + +struct _PaddleMobile__Framework__Proto__OpDesc__Attr { + ProtobufCMessage base; + char *name; + PaddleMobile__Framework__Proto__AttrType type; + protobuf_c_boolean has_i; + int32_t i; + protobuf_c_boolean has_f; + float f; + char *s; + size_t n_ints; + int32_t *ints; + size_t n_floats; + float *floats; + size_t n_strings; + char **strings; + protobuf_c_boolean has_b; + protobuf_c_boolean b; + size_t n_bools; + protobuf_c_boolean *bools; + protobuf_c_boolean has_block_idx; + int32_t block_idx; + protobuf_c_boolean has_l; + int64_t l; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__ATTR__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__op_desc__attr__descriptor) \ + , NULL, PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT, 0, 0, 0, 0, NULL, \ + 0, NULL, 0, NULL, 0, NULL, 0, 0, 0, NULL, 0, 0, 0, 0 \ + } + +struct _PaddleMobile__Framework__Proto__OpDesc__Var { + ProtobufCMessage base; + char *parameter; + size_t n_arguments; + char **arguments; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__VAR__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__op_desc__var__descriptor) \ + , NULL, 0, NULL \ + } + +/* + * OpDesc describes an instance of a C++ framework::OperatorBase + * derived class type. + */ +struct _PaddleMobile__Framework__Proto__OpDesc { + ProtobufCMessage base; + char *type; + size_t n_inputs; + PaddleMobile__Framework__Proto__OpDesc__Var **inputs; + size_t n_outputs; + PaddleMobile__Framework__Proto__OpDesc__Var **outputs; + size_t n_attrs; + PaddleMobile__Framework__Proto__OpDesc__Attr **attrs; + protobuf_c_boolean has_is_target; + protobuf_c_boolean is_target; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__op_desc__descriptor) \ + , NULL, 0, NULL, 0, NULL, 0, NULL, 0, 0 \ + } + +/* + * VarProto describes the C++ type framework::Variable. + */ +struct _PaddleMobile__Framework__Proto__OpProto__Var { + ProtobufCMessage base; + char *name; + char *comment; + protobuf_c_boolean has_duplicable; + protobuf_c_boolean duplicable; + protobuf_c_boolean has_intermediate; + protobuf_c_boolean intermediate; + protobuf_c_boolean has_dispensable; + protobuf_c_boolean dispensable; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__VAR__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__op_proto__var__descriptor) \ + , NULL, NULL, 0, 0, 0, 0, 0, 0 \ + } + +/* + * AttrProto describes the C++ type Attribute. + */ +struct _PaddleMobile__Framework__Proto__OpProto__Attr { + ProtobufCMessage base; + char *name; + PaddleMobile__Framework__Proto__AttrType type; + char *comment; + /* + * If that attribute is generated, it means the Paddle third + * language binding has responsibility to fill that + * attribute. End-User should not set that attribute. + */ + protobuf_c_boolean has_generated; + protobuf_c_boolean generated; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__ATTR__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__op_proto__attr__descriptor) \ + , NULL, PADDLE_MOBILE__FRAMEWORK__PROTO__ATTR_TYPE__INT, NULL, 0, 0 \ + } + +/* + * OpProto describes a C++ framework::OperatorBase derived class. + */ +struct _PaddleMobile__Framework__Proto__OpProto { + ProtobufCMessage base; + char *type; + size_t n_inputs; + PaddleMobile__Framework__Proto__OpProto__Var **inputs; + size_t n_outputs; + PaddleMobile__Framework__Proto__OpProto__Var **outputs; + size_t n_attrs; + PaddleMobile__Framework__Proto__OpProto__Attr **attrs; + char *comment; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__OP_PROTO__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__op_proto__descriptor) \ + , NULL, 0, NULL, 0, NULL, 0, NULL, NULL \ + } + +struct _PaddleMobile__Framework__Proto__VarType__TensorDesc { + ProtobufCMessage base; + /* + * Should only be PODType. Is enforced in C++ + */ + PaddleMobile__Framework__Proto__VarType__Type data_type; + /* + * [UNK, 640, 480] is saved as [-1, 640, 480] + */ + size_t n_dims; + int64_t *dims; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TENSOR_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_type__tensor_desc__descriptor) \ + , PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL, 0, NULL \ + } + +struct _PaddleMobile__Framework__Proto__VarType__LoDTensorDesc { + ProtobufCMessage base; + PaddleMobile__Framework__Proto__VarType__TensorDesc *tensor; + protobuf_c_boolean has_lod_level; + int32_t lod_level; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor) \ + , NULL, 0, 0 \ + } + +struct _PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc { + ProtobufCMessage base; + PaddleMobile__Framework__Proto__VarType__TensorDesc *tensor; + protobuf_c_boolean has_lod_level; + int32_t lod_level; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__LO_DTENSOR_ARRAY_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor) \ + , NULL, 0, 0 \ + } + +struct _PaddleMobile__Framework__Proto__VarType__ReaderDesc { + ProtobufCMessage base; + size_t n_lod_tensor; + PaddleMobile__Framework__Proto__VarType__LoDTensorDesc **lod_tensor; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__READER_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_type__reader_desc__descriptor) \ + , 0, NULL \ + } + +struct _PaddleMobile__Framework__Proto__VarType__ChannelDesc { + ProtobufCMessage base; + PaddleMobile__Framework__Proto__VarType__Type data_type; + int64_t capacity; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__CHANNEL_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_type__channel_desc__descriptor) \ + , PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL, 0 \ + } + +struct _PaddleMobile__Framework__Proto__VarType__Tuple { + ProtobufCMessage base; + size_t n_element_type; + PaddleMobile__Framework__Proto__VarType__Type *element_type; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TUPLE__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_type__tuple__descriptor) \ + , 0, NULL \ + } + +struct _PaddleMobile__Framework__Proto__VarType { + ProtobufCMessage base; + PaddleMobile__Framework__Proto__VarType__Type type; + PaddleMobile__Framework__Proto__VarType__TensorDesc *selected_rows; + PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *lod_tensor; + PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *tensor_array; + PaddleMobile__Framework__Proto__VarType__ReaderDesc *reader; + PaddleMobile__Framework__Proto__VarType__ChannelDesc *channel; + PaddleMobile__Framework__Proto__VarType__Tuple *tuple; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_type__descriptor) \ + , PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_TYPE__TYPE__BOOL, NULL, NULL, NULL, \ + NULL, NULL, NULL \ + } + +struct _PaddleMobile__Framework__Proto__VarDesc { + ProtobufCMessage base; + char *name; + PaddleMobile__Framework__Proto__VarType *type; + protobuf_c_boolean has_persistable; + protobuf_c_boolean persistable; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__VAR_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__var_desc__descriptor) \ + , NULL, NULL, 0, 0 \ + } + +struct _PaddleMobile__Framework__Proto__BlockDesc { + ProtobufCMessage base; + int32_t idx; + int32_t parent_idx; + size_t n_vars; + PaddleMobile__Framework__Proto__VarDesc **vars; + size_t n_ops; + PaddleMobile__Framework__Proto__OpDesc **ops; + protobuf_c_boolean has_forward_block_idx; + int32_t forward_block_idx; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__BLOCK_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__block_desc__descriptor) \ + , 0, 0, 0, NULL, 0, NULL, 0, -1 \ + } + +/* + * Please refer to + * https://github.com/PaddlePaddle/Paddle/blob/develop/doc/design/program.md + * for more details. + * TODO(panyx0718): A model can have multiple programs. Need a + * way to distinguish them. Maybe ID or name? + */ +struct _PaddleMobile__Framework__Proto__ProgramDesc { + ProtobufCMessage base; + size_t n_blocks; + PaddleMobile__Framework__Proto__BlockDesc **blocks; +}; +#define PADDLE_MOBILE__FRAMEWORK__PROTO__PROGRAM_DESC__INIT \ + { \ + PROTOBUF_C_MESSAGE_INIT( \ + &paddle_mobile__framework__proto__program_desc__descriptor) \ + , 0, NULL \ + } + +/* PaddleMobile__Framework__Proto__OpDesc__Attr methods */ +void paddle_mobile__framework__proto__op_desc__attr__init( + PaddleMobile__Framework__Proto__OpDesc__Attr *message); +/* PaddleMobile__Framework__Proto__OpDesc__Var methods */ +void paddle_mobile__framework__proto__op_desc__var__init( + PaddleMobile__Framework__Proto__OpDesc__Var *message); +/* PaddleMobile__Framework__Proto__OpDesc methods */ +void paddle_mobile__framework__proto__op_desc__init( + PaddleMobile__Framework__Proto__OpDesc *message); + +size_t paddle_mobile__framework__proto__op_desc__get_packed_size( + const PaddleMobile__Framework__Proto__OpDesc *message); + +PaddleMobile__Framework__Proto__OpDesc * +paddle_mobile__framework__proto__op_desc__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void paddle_mobile__framework__proto__op_desc__free_unpacked( + PaddleMobile__Framework__Proto__OpDesc *message, + ProtobufCAllocator *allocator); +/* PaddleMobile__Framework__Proto__OpProto__Var methods */ +void paddle_mobile__framework__proto__op_proto__var__init( + PaddleMobile__Framework__Proto__OpProto__Var *message); +/* PaddleMobile__Framework__Proto__OpProto__Attr methods */ +void paddle_mobile__framework__proto__op_proto__attr__init( + PaddleMobile__Framework__Proto__OpProto__Attr *message); +/* PaddleMobile__Framework__Proto__OpProto methods */ +void paddle_mobile__framework__proto__op_proto__init( + PaddleMobile__Framework__Proto__OpProto *message); +size_t paddle_mobile__framework__proto__op_proto__get_packed_size( + const PaddleMobile__Framework__Proto__OpProto *message); +PaddleMobile__Framework__Proto__OpProto * +paddle_mobile__framework__proto__op_proto__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void paddle_mobile__framework__proto__op_proto__free_unpacked( + PaddleMobile__Framework__Proto__OpProto *message, + ProtobufCAllocator *allocator); +/* PaddleMobile__Framework__Proto__VarType__TensorDesc methods */ +void paddle_mobile__framework__proto__var_type__tensor_desc__init( + PaddleMobile__Framework__Proto__VarType__TensorDesc *message); +/* PaddleMobile__Framework__Proto__VarType__LoDTensorDesc methods */ +void paddle_mobile__framework__proto__var_type__lo_dtensor_desc__init( + PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *message); +/* PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc methods */ +void paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__init( + PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *message); +/* PaddleMobile__Framework__Proto__VarType__ReaderDesc methods */ +void paddle_mobile__framework__proto__var_type__reader_desc__init( + PaddleMobile__Framework__Proto__VarType__ReaderDesc *message); +/* PaddleMobile__Framework__Proto__VarType__ChannelDesc methods */ +void paddle_mobile__framework__proto__var_type__channel_desc__init( + PaddleMobile__Framework__Proto__VarType__ChannelDesc *message); +/* PaddleMobile__Framework__Proto__VarType__Tuple methods */ +void paddle_mobile__framework__proto__var_type__tuple__init( + PaddleMobile__Framework__Proto__VarType__Tuple *message); +/* PaddleMobile__Framework__Proto__VarType methods */ +void paddle_mobile__framework__proto__var_type__init( + PaddleMobile__Framework__Proto__VarType *message); +size_t paddle_mobile__framework__proto__var_type__get_packed_size( + const PaddleMobile__Framework__Proto__VarType *message); +PaddleMobile__Framework__Proto__VarType * +paddle_mobile__framework__proto__var_type__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void paddle_mobile__framework__proto__var_type__free_unpacked( + PaddleMobile__Framework__Proto__VarType *message, + ProtobufCAllocator *allocator); +/* PaddleMobile__Framework__Proto__VarDesc methods */ +void paddle_mobile__framework__proto__var_desc__init( + PaddleMobile__Framework__Proto__VarDesc *message); +size_t paddle_mobile__framework__proto__var_desc__get_packed_size( + const PaddleMobile__Framework__Proto__VarDesc *message); +PaddleMobile__Framework__Proto__VarDesc * +paddle_mobile__framework__proto__var_desc__unpack(ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +void paddle_mobile__framework__proto__var_desc__free_unpacked( + PaddleMobile__Framework__Proto__VarDesc *message, + ProtobufCAllocator *allocator); +/* PaddleMobile__Framework__Proto__BlockDesc methods */ +void paddle_mobile__framework__proto__block_desc__init( + PaddleMobile__Framework__Proto__BlockDesc *message); +size_t paddle_mobile__framework__proto__block_desc__get_packed_size( + const PaddleMobile__Framework__Proto__BlockDesc *message); +PaddleMobile__Framework__Proto__BlockDesc * +paddle_mobile__framework__proto__block_desc__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data); +void paddle_mobile__framework__proto__block_desc__free_unpacked( + PaddleMobile__Framework__Proto__BlockDesc *message, + ProtobufCAllocator *allocator); +/* PaddleMobile__Framework__Proto__ProgramDesc methods */ +void paddle_mobile__framework__proto__program_desc__init( + PaddleMobile__Framework__Proto__ProgramDesc *message); +size_t paddle_mobile__framework__proto__program_desc__get_packed_size( + const PaddleMobile__Framework__Proto__ProgramDesc *message); +PaddleMobile__Framework__Proto__ProgramDesc * +paddle_mobile__framework__proto__program_desc__unpack( + ProtobufCAllocator *allocator, size_t len, const uint8_t *data); +void paddle_mobile__framework__proto__program_desc__free_unpacked( + PaddleMobile__Framework__Proto__ProgramDesc *message, + ProtobufCAllocator *allocator); +/* --- per-message closures --- */ + +typedef void (*PaddleMobile__Framework__Proto__OpDesc__Attr_Closure)( + const PaddleMobile__Framework__Proto__OpDesc__Attr *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__OpDesc__Var_Closure)( + const PaddleMobile__Framework__Proto__OpDesc__Var *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__OpDesc_Closure)( + const PaddleMobile__Framework__Proto__OpDesc *message, void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__OpProto__Var_Closure)( + const PaddleMobile__Framework__Proto__OpProto__Var *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__OpProto__Attr_Closure)( + const PaddleMobile__Framework__Proto__OpProto__Attr *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__OpProto_Closure)( + const PaddleMobile__Framework__Proto__OpProto *message, void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__VarType__TensorDesc_Closure)( + const PaddleMobile__Framework__Proto__VarType__TensorDesc *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__VarType__LoDTensorDesc_Closure)( + const PaddleMobile__Framework__Proto__VarType__LoDTensorDesc *message, + void *closure_data); +typedef void ( + *PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc_Closure)( + const PaddleMobile__Framework__Proto__VarType__LoDTensorArrayDesc *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__VarType__ReaderDesc_Closure)( + const PaddleMobile__Framework__Proto__VarType__ReaderDesc *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__VarType__ChannelDesc_Closure)( + const PaddleMobile__Framework__Proto__VarType__ChannelDesc *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__VarType__Tuple_Closure)( + const PaddleMobile__Framework__Proto__VarType__Tuple *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__VarType_Closure)( + const PaddleMobile__Framework__Proto__VarType *message, void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__VarDesc_Closure)( + const PaddleMobile__Framework__Proto__VarDesc *message, void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__BlockDesc_Closure)( + const PaddleMobile__Framework__Proto__BlockDesc *message, + void *closure_data); +typedef void (*PaddleMobile__Framework__Proto__ProgramDesc_Closure)( + const PaddleMobile__Framework__Proto__ProgramDesc *message, + void *closure_data); + +/* --- services --- */ + +/* --- descriptors --- */ + +extern const ProtobufCEnumDescriptor + paddle_mobile__framework__proto__attr_type__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_desc__attr__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_desc__var__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_proto__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_proto__var__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__op_proto__attr__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__tensor_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__lo_dtensor_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__lo_dtensor_array_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__reader_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__channel_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_type__tuple__descriptor; +extern const ProtobufCEnumDescriptor + paddle_mobile__framework__proto__var_type__type__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__var_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__block_desc__descriptor; +extern const ProtobufCMessageDescriptor + paddle_mobile__framework__proto__program_desc__descriptor; + +PROTOBUF_C__END_DECLS + +#endif /* PROTOBUF_C_framework_2eproto__INCLUDED */ diff --git a/tools/quantification/src/program_desc.cpp b/tools/quantification/src/program_desc.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f9984832ada5061c7691aeb7fadba86cb5b8c0c --- /dev/null +++ b/tools/quantification/src/program_desc.cpp @@ -0,0 +1,30 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. */ + +// +// Created by 谢柏渊 on 2018/7/25. +// + +#include "src/program_desc.h" +#include + +ProgramDesc::ProgramDesc(PaddleMobile__Framework__Proto__ProgramDesc *desc) { + for (int i = 0; i < desc->n_blocks; ++i) { + blocks_.emplace_back(std::make_shared(desc->blocks[i])); + } +} + +const std::vector> ProgramDesc::Blocks() { + return blocks_; +} diff --git a/tools/quantification/src/program_desc.h b/tools/quantification/src/program_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..60a0f757b0c907165d7639a41e35a407ef083b59 --- /dev/null +++ b/tools/quantification/src/program_desc.h @@ -0,0 +1,41 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. */ + +// +// Created by 谢柏渊 on 2018/7/25. +// + +#ifndef TOOLS_QUANTIFICATION_SRC_PROGRAM_DESC_H_ +#define TOOLS_QUANTIFICATION_SRC_PROGRAM_DESC_H_ + +#include +#include +#include "src/block_desc_local.h" +#include "src/framework.pb-c.h" + +class ProgramDesc { + public: + // friend class Node; + // + // friend class ProgramOptimize; + + explicit ProgramDesc(PaddleMobile__Framework__Proto__ProgramDesc *desc); + + const std::vector> Blocks(); + + private: + std::vector> blocks_; +}; + +#endif // TOOLS_QUANTIFICATION_SRC_PROGRAM_DESC_H_ diff --git a/tools/quantification/src/protobuf-c.c b/tools/quantification/src/protobuf-c.c new file mode 100644 index 0000000000000000000000000000000000000000..1092e3f78b02a343d8c8965ea7b2d777a6fac9ae --- /dev/null +++ b/tools/quantification/src/protobuf-c.c @@ -0,0 +1,2098 @@ +/* + * Copyright (c) 2008-2015, Dave Benson and the protobuf-c authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*! \file + * Support library for `protoc-c` generated code. + * + * This file implements the public API used by the code generated + * by `protoc-c`. + * + * \authors Dave Benson and the protobuf-c authors + * + * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license. + */ + +/** + * \todo 64-BIT OPTIMIZATION: certain implementations use 32-bit math + * even on 64-bit platforms (uint64_size, uint64_pack, parse_uint64). + * + * \todo Use size_t consistently. + */ + +#include /* for malloc, free */ +#include /* for strcmp, strlen, memcpy, memmove, memset */ + +#include "protobuf-c.h" + +#define TRUE 1 +#define FALSE 0 + +#define PROTOBUF_C__ASSERT_NOT_REACHED() assert(0) + +/* Workaround for Microsoft compilers. */ +#ifdef _MSC_VER +#define inline __inline +#endif + +/** + * \defgroup internal Internal functions and macros + * + * These are not exported by the library but are useful to developers working + * on `libprotobuf-c` itself. + */ + +/** + * \defgroup macros Utility macros for manipulating structures + * + * Macros and constants used to manipulate the base "classes" generated by + * `protobuf-c`. They also define limits and check correctness. + * + * \ingroup internal + * @{ + */ + +/** The maximum length of a 64-bit integer in varint encoding. */ +#define MAX_UINT64_ENCODED_SIZE 10 + +#ifndef PROTOBUF_C_UNPACK_ERROR +#define PROTOBUF_C_UNPACK_ERROR(...) +#endif + +const char protobuf_c_empty_string[] = ""; + +/** + * Internal `ProtobufCMessage` manipulation macro. + * + * Base macro for manipulating a `ProtobufCMessage`. Used by STRUCT_MEMBER() and + * STRUCT_MEMBER_PTR(). + */ +#define STRUCT_MEMBER_P(struct_p, struct_offset) \ + ((void *)((uint8_t *)(struct_p) + (struct_offset))) + +/** + * Return field in a `ProtobufCMessage` based on offset. + * + * Take a pointer to a `ProtobufCMessage` and find the field at the offset. + * Cast it to the passed type. + */ +#define STRUCT_MEMBER(member_type, struct_p, struct_offset) \ + (*(member_type *)STRUCT_MEMBER_P((struct_p), (struct_offset))) + +/** + * Return field in a `ProtobufCMessage` based on offset. + * + * Take a pointer to a `ProtobufCMessage` and find the field at the offset. Cast + * it to a pointer to the passed type. + */ +#define STRUCT_MEMBER_PTR(member_type, struct_p, struct_offset) \ + ((member_type *)STRUCT_MEMBER_P((struct_p), (struct_offset))) + +/* Assertions for magic numbers. */ + +#define ASSERT_IS_ENUM_DESCRIPTOR(desc) \ + assert((desc)->magic == PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC) + +#define ASSERT_IS_MESSAGE_DESCRIPTOR(desc) \ + assert((desc)->magic == PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) + +#define ASSERT_IS_MESSAGE(message) \ + ASSERT_IS_MESSAGE_DESCRIPTOR((message)->descriptor) + +#define ASSERT_IS_SERVICE_DESCRIPTOR(desc) \ + assert((desc)->magic == PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC) + +/**@}*/ + +/* --- version --- */ + +const char *protobuf_c_version(void) { return PROTOBUF_C_VERSION; } + +uint32_t protobuf_c_version_number(void) { return PROTOBUF_C_VERSION_NUMBER; } + +/* --- allocator --- */ + +static void *system_alloc(void *allocator_data, size_t size) { + return malloc(size); +} + +static void system_free(void *allocator_data, void *data) { free(data); } + +static inline void *do_alloc(ProtobufCAllocator *allocator, size_t size) { + return allocator->alloc(allocator->allocator_data, size); +} + +static inline void do_free(ProtobufCAllocator *allocator, void *data) { + if (data != NULL) allocator->free(allocator->allocator_data, data); +} + +/* + * This allocator uses the system's malloc() and free(). It is the default + * allocator used if NULL is passed as the ProtobufCAllocator to an exported + * function. + */ +static ProtobufCAllocator protobuf_c__allocator = { + .alloc = &system_alloc, + .free = &system_free, + .allocator_data = NULL, +}; + +/* === buffer-simple === */ + +void protobuf_c_buffer_simple_append(ProtobufCBuffer *buffer, size_t len, + const uint8_t *data) { + ProtobufCBufferSimple *simp = (ProtobufCBufferSimple *)buffer; + size_t new_len = simp->len + len; + + if (new_len > simp->alloced) { + ProtobufCAllocator *allocator = simp->allocator; + size_t new_alloced = simp->alloced * 2; + uint8_t *new_data; + + if (allocator == NULL) allocator = &protobuf_c__allocator; + while (new_alloced < new_len) new_alloced += new_alloced; + new_data = do_alloc(allocator, new_alloced); + if (!new_data) return; + memcpy(new_data, simp->data, simp->len); + if (simp->must_free_data) + do_free(allocator, simp->data); + else + simp->must_free_data = TRUE; + simp->data = new_data; + simp->alloced = new_alloced; + } + memcpy(simp->data + simp->len, data, len); + simp->len = new_len; +} + +/** + * \defgroup packedsz protobuf_c_message_get_packed_size() implementation + * + * Routines mainly used by protobuf_c_message_get_packed_size(). + * + * \ingroup internal + * @{ + */ + +/** + * Return the number of bytes required to store the tag for the field. Includes + * 3 bits for the wire-type, and a single bit that denotes the end-of-tag. + * + * \param number + * Field tag to encode. + * \return + * Number of bytes required. + */ +static inline size_t get_tag_size(uint32_t number) { + if (number < (1UL << 4)) { + return 1; + } else if (number < (1UL << 11)) { + return 2; + } else if (number < (1UL << 18)) { + return 3; + } else if (number < (1UL << 25)) { + return 4; + } else { + return 5; + } +} + +/** + * Return the number of bytes required to store a variable-length unsigned + * 32-bit integer in base-128 varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t uint32_size(uint32_t v) { + if (v < (1UL << 7)) { + return 1; + } else if (v < (1UL << 14)) { + return 2; + } else if (v < (1UL << 21)) { + return 3; + } else if (v < (1UL << 28)) { + return 4; + } else { + return 5; + } +} + +/** + * Return the number of bytes required to store a variable-length signed 32-bit + * integer in base-128 varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t int32_size(int32_t v) { + if (v < 0) { + return 10; + } else if (v < (1L << 7)) { + return 1; + } else if (v < (1L << 14)) { + return 2; + } else if (v < (1L << 21)) { + return 3; + } else if (v < (1L << 28)) { + return 4; + } else { + return 5; + } +} + +/** + * Return the ZigZag-encoded 32-bit unsigned integer form of a 32-bit signed + * integer. + * + * \param v + * Value to encode. + * \return + * ZigZag encoded integer. + */ +static inline uint32_t zigzag32(int32_t v) { + if (v < 0) + return (-(uint32_t)v) * 2 - 1; + else + return (uint32_t)(v)*2; +} + +/** + * Return the number of bytes required to store a signed 32-bit integer, + * converted to an unsigned 32-bit integer with ZigZag encoding, using base-128 + * varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t sint32_size(int32_t v) { return uint32_size(zigzag32(v)); } + +/** + * Return the number of bytes required to store a 64-bit unsigned integer in + * base-128 varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t uint64_size(uint64_t v) { + uint32_t upper_v = (uint32_t)(v >> 32); + + if (upper_v == 0) { + return uint32_size((uint32_t)v); + } else if (upper_v < (1UL << 3)) { + return 5; + } else if (upper_v < (1UL << 10)) { + return 6; + } else if (upper_v < (1UL << 17)) { + return 7; + } else if (upper_v < (1UL << 24)) { + return 8; + } else if (upper_v < (1UL << 31)) { + return 9; + } else { + return 10; + } +} + +/** + * Return the ZigZag-encoded 64-bit unsigned integer form of a 64-bit signed + * integer. + * + * \param v + * Value to encode. + * \return + * ZigZag encoded integer. + */ +static inline uint64_t zigzag64(int64_t v) { + if (v < 0) + return (-(uint64_t)v) * 2 - 1; + else + return (uint64_t)(v)*2; +} + +/** + * Return the number of bytes required to store a signed 64-bit integer, + * converted to an unsigned 64-bit integer with ZigZag encoding, using base-128 + * varint encoding. + * + * \param v + * Value to encode. + * \return + * Number of bytes required. + */ +static inline size_t sint64_size(int64_t v) { return uint64_size(zigzag64(v)); } + +/** + * Calculate the serialized size of a single required message field, including + * the space needed by the preceding tag. + * + * \param field + * Field descriptor for member. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t required_field_get_packed_size( + const ProtobufCFieldDescriptor *field, const void *member) { + size_t rv = get_tag_size(field->id); + + switch (field->type) { + case PROTOBUF_C_TYPE_SINT32: + return rv + sint32_size(*(const int32_t *)member); + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + return rv + int32_size(*(const int32_t *)member); + case PROTOBUF_C_TYPE_UINT32: + return rv + uint32_size(*(const uint32_t *)member); + case PROTOBUF_C_TYPE_SINT64: + return rv + sint64_size(*(const int64_t *)member); + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + return rv + uint64_size(*(const uint64_t *)member); + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + return rv + 4; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + return rv + 8; + case PROTOBUF_C_TYPE_BOOL: + return rv + 1; + case PROTOBUF_C_TYPE_FLOAT: + return rv + 4; + case PROTOBUF_C_TYPE_DOUBLE: + return rv + 8; + case PROTOBUF_C_TYPE_STRING: { + const char *str = *(char *const *)member; + size_t len = str ? strlen(str) : 0; + return rv + uint32_size(len) + len; + } + case PROTOBUF_C_TYPE_BYTES: { + size_t len = ((const ProtobufCBinaryData *)member)->len; + return rv + uint32_size(len) + len; + } + case PROTOBUF_C_TYPE_MESSAGE: { + const ProtobufCMessage *msg = *(ProtobufCMessage *const *)member; + size_t subrv = msg ? protobuf_c_message_get_packed_size(msg) : 0; + return rv + uint32_size(subrv) + subrv; + } + } + PROTOBUF_C__ASSERT_NOT_REACHED(); + return 0; +} + +/** + * Calculate the serialized size of a single oneof message field, including + * the space needed by the preceding tag. Returns 0 if the oneof field isn't + * selected or is not set. + * + * \param field + * Field descriptor for member. + * \param oneof_case + * Enum value that selects the field in the oneof. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t oneof_field_get_packed_size(const ProtobufCFieldDescriptor *field, + uint32_t oneof_case, + const void *member) { + if (oneof_case != field->id) { + return 0; + } + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) { + const void *ptr = *(const void *const *)member; + if (ptr == NULL || ptr == field->default_value) return 0; + } + return required_field_get_packed_size(field, member); +} + +/** + * Calculate the serialized size of a single optional message field, including + * the space needed by the preceding tag. Returns 0 if the optional field isn't + * set. + * + * \param field + * Field descriptor for member. + * \param has + * True if the field exists, false if not. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t optional_field_get_packed_size( + const ProtobufCFieldDescriptor *field, const protobuf_c_boolean has, + const void *member) { + if (field->type == PROTOBUF_C_TYPE_MESSAGE || + field->type == PROTOBUF_C_TYPE_STRING) { + const void *ptr = *(const void *const *)member; + if (ptr == NULL || ptr == field->default_value) return 0; + } else { + if (!has) return 0; + } + return required_field_get_packed_size(field, member); +} + +static protobuf_c_boolean field_is_zeroish( + const ProtobufCFieldDescriptor *field, const void *member) { + protobuf_c_boolean ret = FALSE; + + switch (field->type) { + case PROTOBUF_C_TYPE_BOOL: + ret = (0 == *(const protobuf_c_boolean *)member); + break; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + ret = (0 == *(const uint32_t *)member); + break; + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + ret = (0 == *(const uint64_t *)member); + break; + case PROTOBUF_C_TYPE_FLOAT: + ret = (0 == *(const float *)member); + break; + case PROTOBUF_C_TYPE_DOUBLE: + ret = (0 == *(const double *)member); + break; + case PROTOBUF_C_TYPE_STRING: + ret = (NULL == *(const char *const *)member) || + ('\0' == **(const char *const *)member); + break; + case PROTOBUF_C_TYPE_BYTES: + case PROTOBUF_C_TYPE_MESSAGE: + ret = (NULL == *(const void *const *)member); + break; + default: + ret = TRUE; + break; + } + + return ret; +} + +/** + * Calculate the serialized size of a single unlabeled message field, including + * the space needed by the preceding tag. Returns 0 if the field isn't set or + * if it is set to a "zeroish" value (null pointer or 0 for numerical values). + * Unlabeled fields are supported only in proto3. + * + * \param field + * Field descriptor for member. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t unlabeled_field_get_packed_size( + const ProtobufCFieldDescriptor *field, const void *member) { + if (field_is_zeroish(field, member)) return 0; + return required_field_get_packed_size(field, member); +} + +/** + * Calculate the serialized size of repeated message fields, which may consist + * of any number of values (including 0). Includes the space needed by the + * preceding tags (as needed). + * + * \param field + * Field descriptor for member. + * \param count + * Number of repeated field members. + * \param member + * Field to encode. + * \return + * Number of bytes required. + */ +static size_t repeated_field_get_packed_size( + const ProtobufCFieldDescriptor *field, size_t count, const void *member) { + size_t header_size; + size_t rv = 0; + unsigned i; + void *array = *(void *const *)member; + + if (count == 0) return 0; + header_size = get_tag_size(field->id); + if (0 == (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) header_size *= count; + + switch (field->type) { + case PROTOBUF_C_TYPE_SINT32: + for (i = 0; i < count; i++) rv += sint32_size(((int32_t *)array)[i]); + break; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + for (i = 0; i < count; i++) rv += int32_size(((int32_t *)array)[i]); + break; + case PROTOBUF_C_TYPE_UINT32: + for (i = 0; i < count; i++) rv += uint32_size(((uint32_t *)array)[i]); + break; + case PROTOBUF_C_TYPE_SINT64: + for (i = 0; i < count; i++) rv += sint64_size(((int64_t *)array)[i]); + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + for (i = 0; i < count; i++) rv += uint64_size(((uint64_t *)array)[i]); + break; + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + rv += 4 * count; + break; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + rv += 8 * count; + break; + case PROTOBUF_C_TYPE_BOOL: + rv += count; + break; + case PROTOBUF_C_TYPE_STRING: + for (i = 0; i < count; i++) { + size_t len = strlen(((char **)array)[i]); + rv += uint32_size(len) + len; + } + break; + case PROTOBUF_C_TYPE_BYTES: + for (i = 0; i < count; i++) { + size_t len = ((ProtobufCBinaryData *)array)[i].len; + rv += uint32_size(len) + len; + } + break; + case PROTOBUF_C_TYPE_MESSAGE: + for (i = 0; i < count; i++) { + size_t len = + protobuf_c_message_get_packed_size(((ProtobufCMessage **)array)[i]); + rv += uint32_size(len) + len; + } + break; + } + + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED)) + header_size += uint32_size(rv); + return header_size + rv; +} + +/** + * Calculate the serialized size of an unknown field, i.e. one that is passed + * through mostly uninterpreted. This is required for forward compatibility if + * new fields are added to the message descriptor. + * + * \param field + * Unknown field type. + * \return + * Number of bytes required. + */ +static inline size_t unknown_field_get_packed_size( + const ProtobufCMessageUnknownField *field) { + return get_tag_size(field->tag) + field->len; +} + +/**@}*/ + +/* + * Calculate the serialized size of the message. + */ +size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message) { + unsigned i; + size_t rv = 0; + + ASSERT_IS_MESSAGE(message); + for (i = 0; i < message->descriptor->n_fields; i++) { + const ProtobufCFieldDescriptor *field = message->descriptor->fields + i; + const void *member = ((const char *)message) + field->offset; + const void *qmember = ((const char *)message) + field->quantifier_offset; + + if (field->label == PROTOBUF_C_LABEL_REQUIRED) { + rv += required_field_get_packed_size(field, member); + } else if ((field->label == PROTOBUF_C_LABEL_OPTIONAL || + field->label == PROTOBUF_C_LABEL_NONE) && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF))) { + rv += oneof_field_get_packed_size(field, *(const uint32_t *)qmember, + member); + } else if (field->label == PROTOBUF_C_LABEL_OPTIONAL) { + rv += optional_field_get_packed_size( + field, *(protobuf_c_boolean *)qmember, member); + } else if (field->label == PROTOBUF_C_LABEL_NONE) { + rv += unlabeled_field_get_packed_size(field, member); + } else { + rv += repeated_field_get_packed_size(field, *(const size_t *)qmember, + member); + } + } + for (i = 0; i < message->n_unknown_fields; i++) + rv += unknown_field_get_packed_size(&message->unknown_fields[i]); + return rv; +} + +/** + * \defgroup pack protobuf_c_message_pack() implementation + * + * Routines mainly used by protobuf_c_message_pack(). + * + * \ingroup internal + * @{ + */ + +/** + * Pack an unsigned 32-bit integer in base-128 varint encoding and return the + * number of bytes written, which must be 5 or less. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t uint32_pack(uint32_t value, uint8_t *out) { + unsigned rv = 0; + + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + if (value >= 0x80) { + out[rv++] = value | 0x80; + value >>= 7; + } + } + } + } + /* assert: value<128 */ + out[rv++] = value; + return rv; +} + +/** + * Pack a 64-bit unsigned integer using base-128 varint encoding and return the + * number of bytes written. + * + * \param value + * Value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t uint64_pack(uint64_t value, uint8_t *out) { + uint32_t hi = (uint32_t)(value >> 32); + uint32_t lo = (uint32_t)value; + unsigned rv; + + if (hi == 0) return uint32_pack((uint32_t)lo, out); + out[0] = (lo) | 0x80; + out[1] = (lo >> 7) | 0x80; + out[2] = (lo >> 14) | 0x80; + out[3] = (lo >> 21) | 0x80; + if (hi < 8) { + out[4] = (hi << 4) | (lo >> 28); + return 5; + } else { + out[4] = ((hi & 7) << 4) | (lo >> 28) | 0x80; + hi >>= 3; + } + rv = 5; + while (hi >= 128) { + out[rv++] = hi | 0x80; + hi >>= 7; + } + out[rv++] = hi; + return rv; +} + +/** + * Pack a ProtobufCBinaryData and return the number of bytes written. The output + * includes a length delimiter. + * + * \param bd + * ProtobufCBinaryData to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static inline size_t binary_data_pack(const ProtobufCBinaryData *bd, + uint8_t *out) { + size_t len = bd->len; + size_t rv = uint32_pack(len, out); + memcpy(out + rv, bd->data, len); + return rv + len; +} + +/** + * Pack a field tag. + * + * Wire-type will be added in required_field_pack(). + * + * \todo Just call uint64_pack on 64-bit platforms. + * + * \param id + * Tag value to encode. + * \param[out] out + * Packed value. + * \return + * Number of bytes written to `out`. + */ +static size_t tag_pack(uint32_t id, uint8_t *out) { + if (id < (1UL << (32 - 3))) + return uint32_pack(id << 3, out); + else + return uint64_pack(((uint64_t)id) << 3, out); +} + +/** + * Given a field type, return the in-memory size. + * + * \todo Implement as a table lookup. + * + * \param type + * Field type. + * \return + * Size of the field. + */ +static inline size_t sizeof_elt_in_repeated_array(ProtobufCType type) { + switch (type) { + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + case PROTOBUF_C_TYPE_ENUM: + return 4; + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + return 8; + case PROTOBUF_C_TYPE_BOOL: + return sizeof(protobuf_c_boolean); + case PROTOBUF_C_TYPE_STRING: + case PROTOBUF_C_TYPE_MESSAGE: + return sizeof(void *); + case PROTOBUF_C_TYPE_BYTES: + return sizeof(ProtobufCBinaryData); + } + PROTOBUF_C__ASSERT_NOT_REACHED(); + return 0; +} + +static inline int int_range_lookup(unsigned n_ranges, + const ProtobufCIntRange *ranges, int value) { + unsigned n; + unsigned start; + + if (n_ranges == 0) return -1; + start = 0; + n = n_ranges; + while (n > 1) { + unsigned mid = start + n / 2; + + if (value < ranges[mid].start_value) { + n = mid - start; + } else if (value >= + ranges[mid].start_value + + (int)(ranges[mid + 1].orig_index - ranges[mid].orig_index)) { + unsigned new_start = mid + 1; + n = start + n - new_start; + start = new_start; + } else + return (value - ranges[mid].start_value) + ranges[mid].orig_index; + } + if (n > 0) { + unsigned start_orig_index = ranges[start].orig_index; + unsigned range_size = ranges[start + 1].orig_index - start_orig_index; + + if (ranges[start].start_value <= value && + value < (int)(ranges[start].start_value + range_size)) { + return (value - ranges[start].start_value) + start_orig_index; + } + } + return -1; +} + +static size_t parse_tag_and_wiretype(size_t len, const uint8_t *data, + uint32_t *tag_out, + ProtobufCWireType *wiretype_out) { + unsigned max_rv = len > 5 ? 5 : len; + uint32_t tag = (data[0] & 0x7f) >> 3; + unsigned shift = 4; + unsigned rv; + + *wiretype_out = data[0] & 7; + if ((data[0] & 0x80) == 0) { + *tag_out = tag; + return 1; + } + for (rv = 1; rv < max_rv; rv++) { + if (data[rv] & 0x80) { + tag |= (data[rv] & 0x7f) << shift; + shift += 7; + } else { + tag |= data[rv] << shift; + *tag_out = tag; + return rv + 1; + } + } + return 0; /* error: bad header */ +} + +/* sizeof(ScannedMember) must be <= (1UL< len) { + PROTOBUF_C_UNPACK_ERROR("data too short after length-prefix of %u", val); + return 0; + } + return hdr_len + val; +} + +static size_t max_b128_numbers(size_t len, const uint8_t *data) { + size_t rv = 0; + while (len--) + if ((*data++ & 0x80) == 0) ++rv; + return rv; +} + +/**@}*/ + +/** + * Merge earlier message into a latter message. + * + * For numeric types and strings, if the same value appears multiple + * times, the parser accepts the last value it sees. For embedded + * message fields, the parser merges multiple instances of the same + * field. That is, all singular scalar fields in the latter instance + * replace those in the former, singular embedded messages are merged, + * and repeated fields are concatenated. + * + * The earlier message should be freed after calling this function, as + * some of its fields may have been reused and changed to their default + * values during the merge. + */ +static protobuf_c_boolean merge_messages(ProtobufCMessage *earlier_msg, + ProtobufCMessage *latter_msg, + ProtobufCAllocator *allocator) { + unsigned i; + const ProtobufCFieldDescriptor *fields = latter_msg->descriptor->fields; + for (i = 0; i < latter_msg->descriptor->n_fields; i++) { + if (fields[i].label == PROTOBUF_C_LABEL_REPEATED) { + size_t *n_earlier = + STRUCT_MEMBER_PTR(size_t, earlier_msg, fields[i].quantifier_offset); + uint8_t **p_earlier = + STRUCT_MEMBER_PTR(uint8_t *, earlier_msg, fields[i].offset); + size_t *n_latter = + STRUCT_MEMBER_PTR(size_t, latter_msg, fields[i].quantifier_offset); + uint8_t **p_latter = + STRUCT_MEMBER_PTR(uint8_t *, latter_msg, fields[i].offset); + + if (*n_earlier > 0) { + if (*n_latter > 0) { + /* Concatenate the repeated field */ + size_t el_size = sizeof_elt_in_repeated_array(fields[i].type); + uint8_t *new_field; + + new_field = do_alloc(allocator, (*n_earlier + *n_latter) * el_size); + if (!new_field) return FALSE; + + memcpy(new_field, *p_earlier, *n_earlier * el_size); + memcpy(new_field + *n_earlier * el_size, *p_latter, + *n_latter * el_size); + + do_free(allocator, *p_latter); + do_free(allocator, *p_earlier); + *p_latter = new_field; + *n_latter = *n_earlier + *n_latter; + } else { + /* Zero copy the repeated field from the earlier message */ + *n_latter = *n_earlier; + *p_latter = *p_earlier; + } + /* Make sure the field does not get double freed */ + *n_earlier = 0; + *p_earlier = 0; + } + } else if (fields[i].label == PROTOBUF_C_LABEL_OPTIONAL || + fields[i].label == PROTOBUF_C_LABEL_NONE) { + const ProtobufCFieldDescriptor *field; + uint32_t *earlier_case_p = + STRUCT_MEMBER_PTR(uint32_t, earlier_msg, fields[i].quantifier_offset); + uint32_t *latter_case_p = + STRUCT_MEMBER_PTR(uint32_t, latter_msg, fields[i].quantifier_offset); + protobuf_c_boolean need_to_merge = FALSE; + void *earlier_elem; + void *latter_elem; + const void *def_val; + + if (fields[i].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) { + if (*latter_case_p == 0) { + /* lookup correct oneof field */ + int field_index = int_range_lookup( + latter_msg->descriptor->n_field_ranges, + latter_msg->descriptor->field_ranges, *earlier_case_p); + field = latter_msg->descriptor->fields + field_index; + } else { + /* Oneof is present in the latter message, move on */ + continue; + } + } else { + field = &fields[i]; + } + + earlier_elem = STRUCT_MEMBER_P(earlier_msg, field->offset); + latter_elem = STRUCT_MEMBER_P(latter_msg, field->offset); + def_val = field->default_value; + + switch (field->type) { + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage *em = *(ProtobufCMessage **)earlier_elem; + ProtobufCMessage *lm = *(ProtobufCMessage **)latter_elem; + if (em != NULL) { + if (lm != NULL) { + if (!merge_messages(em, lm, allocator)) return FALSE; + /* Already merged */ + need_to_merge = FALSE; + } else { + /* Zero copy the message */ + need_to_merge = TRUE; + } + } + break; + } + case PROTOBUF_C_TYPE_BYTES: { + uint8_t *e_data = ((ProtobufCBinaryData *)earlier_elem)->data; + uint8_t *l_data = ((ProtobufCBinaryData *)latter_elem)->data; + const ProtobufCBinaryData *d_bd = (ProtobufCBinaryData *)def_val; + + need_to_merge = + (e_data != NULL && (d_bd == NULL || e_data != d_bd->data)) && + (l_data == NULL || (d_bd != NULL && l_data == d_bd->data)); + break; + } + case PROTOBUF_C_TYPE_STRING: { + char *e_str = *(char **)earlier_elem; + char *l_str = *(char **)latter_elem; + const char *d_str = def_val; + + need_to_merge = e_str != d_str && l_str == d_str; + break; + } + default: { + /* Could be has field or case enum, the logic is + * equivalent, since 0 (FALSE) means not set for + * oneof */ + need_to_merge = (*earlier_case_p != 0) && (*latter_case_p == 0); + break; + } + } + + if (need_to_merge) { + size_t el_size = sizeof_elt_in_repeated_array(field->type); + memcpy(latter_elem, earlier_elem, el_size); + /* + * Reset the element from the old message to 0 + * to make sure earlier message deallocation + * doesn't corrupt zero-copied data in the new + * message, earlier message will be freed after + * this function is called anyway + */ + memset(earlier_elem, 0, el_size); + + if (field->quantifier_offset != 0) { + /* Set the has field or the case enum, + * if applicable */ + *latter_case_p = *earlier_case_p; + *earlier_case_p = 0; + } + } + } + } + return TRUE; +} + +/** + * Count packed elements. + * + * Given a raw slab of packed-repeated values, determine the number of + * elements. This function detects certain kinds of errors but not + * others; the remaining error checking is done by + * parse_packed_repeated_member(). + */ +static protobuf_c_boolean count_packed_elements(ProtobufCType type, size_t len, + const uint8_t *data, + size_t *count_out) { + switch (type) { + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + if (len % 4 != 0) { + PROTOBUF_C_UNPACK_ERROR( + "length must be a multiple of 4 for fixed-length 32-bit types"); + return FALSE; + } + *count_out = len / 4; + return TRUE; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + if (len % 8 != 0) { + PROTOBUF_C_UNPACK_ERROR( + "length must be a multiple of 8 for fixed-length 64-bit types"); + return FALSE; + } + *count_out = len / 8; + return TRUE; + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_UINT64: + *count_out = max_b128_numbers(len, data); + return TRUE; + case PROTOBUF_C_TYPE_BOOL: + *count_out = len; + return TRUE; + case PROTOBUF_C_TYPE_STRING: + case PROTOBUF_C_TYPE_BYTES: + case PROTOBUF_C_TYPE_MESSAGE: + default: + PROTOBUF_C_UNPACK_ERROR("bad protobuf-c type %u for packed-repeated", + type); + return FALSE; + } +} + +static inline uint32_t parse_uint32(unsigned len, const uint8_t *data) { + uint32_t rv = data[0] & 0x7f; + if (len > 1) { + rv |= ((uint32_t)(data[1] & 0x7f) << 7); + if (len > 2) { + rv |= ((uint32_t)(data[2] & 0x7f) << 14); + if (len > 3) { + rv |= ((uint32_t)(data[3] & 0x7f) << 21); + if (len > 4) rv |= ((uint32_t)(data[4]) << 28); + } + } + } + return rv; +} + +static inline uint32_t parse_int32(unsigned len, const uint8_t *data) { + return parse_uint32(len, data); +} + +static inline int32_t unzigzag32(uint32_t v) { + if (v & 1) + return -(v >> 1) - 1; + else + return v >> 1; +} + +static inline uint32_t parse_fixed_uint32(const uint8_t *data) { +#if !defined(WORDS_BIGENDIAN) + uint32_t t; + memcpy(&t, data, 4); + return t; +#else + return data[0] | ((uint32_t)(data[1]) << 8) | ((uint32_t)(data[2]) << 16) | + ((uint32_t)(data[3]) << 24); +#endif +} + +static uint64_t parse_uint64(unsigned len, const uint8_t *data) { + unsigned shift, i; + uint64_t rv; + + if (len < 5) return parse_uint32(len, data); + rv = ((uint64_t)(data[0] & 0x7f)) | ((uint64_t)(data[1] & 0x7f) << 7) | + ((uint64_t)(data[2] & 0x7f) << 14) | ((uint64_t)(data[3] & 0x7f) << 21); + shift = 28; + for (i = 4; i < len; i++) { + rv |= (((uint64_t)(data[i] & 0x7f)) << shift); + shift += 7; + } + return rv; +} + +static inline int64_t unzigzag64(uint64_t v) { + if (v & 1) + return -(v >> 1) - 1; + else + return v >> 1; +} + +static inline uint64_t parse_fixed_uint64(const uint8_t *data) { +#if !defined(WORDS_BIGENDIAN) + uint64_t t; + memcpy(&t, data, 8); + return t; +#else + return (uint64_t)parse_fixed_uint32(data) | + (((uint64_t)parse_fixed_uint32(data + 4)) << 32); +#endif +} + +static protobuf_c_boolean parse_boolean(unsigned len, const uint8_t *data) { + unsigned i; + for (i = 0; i < len; i++) + if (data[i] & 0x7f) return TRUE; + return FALSE; +} + +static protobuf_c_boolean parse_required_member( + ScannedMember *scanned_member, void *member, ProtobufCAllocator *allocator, + protobuf_c_boolean maybe_clear) { + unsigned len = scanned_member->len; + const uint8_t *data = scanned_member->data; + ProtobufCWireType wire_type = scanned_member->wire_type; + + switch (scanned_member->field->type) { + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE; + *(int32_t *)member = parse_int32(len, data); + return TRUE; + case PROTOBUF_C_TYPE_UINT32: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE; + *(uint32_t *)member = parse_uint32(len, data); + return TRUE; + case PROTOBUF_C_TYPE_SINT32: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE; + *(int32_t *)member = unzigzag32(parse_uint32(len, data)); + return TRUE; + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + if (wire_type != PROTOBUF_C_WIRE_TYPE_32BIT) return FALSE; + *(uint32_t *)member = parse_fixed_uint32(data); + return TRUE; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE; + *(uint64_t *)member = parse_uint64(len, data); + return TRUE; + case PROTOBUF_C_TYPE_SINT64: + if (wire_type != PROTOBUF_C_WIRE_TYPE_VARINT) return FALSE; + *(int64_t *)member = unzigzag64(parse_uint64(len, data)); + return TRUE; + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + if (wire_type != PROTOBUF_C_WIRE_TYPE_64BIT) return FALSE; + *(uint64_t *)member = parse_fixed_uint64(data); + return TRUE; + case PROTOBUF_C_TYPE_BOOL: + *(protobuf_c_boolean *)member = parse_boolean(len, data); + return TRUE; + case PROTOBUF_C_TYPE_STRING: { + char **pstr = member; + unsigned pref_len = scanned_member->length_prefix_len; + + if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) return FALSE; + + if (maybe_clear && *pstr != NULL) { + const char *def = scanned_member->field->default_value; + if (*pstr != NULL && *pstr != def) do_free(allocator, *pstr); + } + *pstr = do_alloc(allocator, len - pref_len + 1); + if (*pstr == NULL) return FALSE; + memcpy(*pstr, data + pref_len, len - pref_len); + (*pstr)[len - pref_len] = 0; + return TRUE; + } + case PROTOBUF_C_TYPE_BYTES: { + ProtobufCBinaryData *bd = member; + const ProtobufCBinaryData *def_bd; + unsigned pref_len = scanned_member->length_prefix_len; + + if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) return FALSE; + + def_bd = scanned_member->field->default_value; + if (maybe_clear && bd->data != NULL && + (def_bd == NULL || bd->data != def_bd->data)) { + do_free(allocator, bd->data); + } + if (len - pref_len > 0) { + bd->data = do_alloc(allocator, len - pref_len); + if (bd->data == NULL) return FALSE; + memcpy(bd->data, data + pref_len, len - pref_len); + } else { + bd->data = NULL; + } + bd->len = len - pref_len; + return TRUE; + } + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage **pmessage = member; + ProtobufCMessage *subm; + const ProtobufCMessage *def_mess; + protobuf_c_boolean merge_successful = TRUE; + unsigned pref_len = scanned_member->length_prefix_len; + + if (wire_type != PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED) return FALSE; + + def_mess = scanned_member->field->default_value; + subm = + protobuf_c_message_unpack(scanned_member->field->descriptor, + allocator, len - pref_len, data + pref_len); + + if (maybe_clear && *pmessage != NULL && *pmessage != def_mess) { + if (subm != NULL) + merge_successful = merge_messages(*pmessage, subm, allocator); + /* Delete the previous message */ + protobuf_c_message_free_unpacked(*pmessage, allocator); + } + *pmessage = subm; + if (subm == NULL || !merge_successful) return FALSE; + return TRUE; + } + } + return FALSE; +} + +static protobuf_c_boolean parse_oneof_member(ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) { + uint32_t *oneof_case = STRUCT_MEMBER_PTR( + uint32_t, message, scanned_member->field->quantifier_offset); + + /* If we have already parsed a member of this oneof, free it. */ + if (*oneof_case != 0) { + /* lookup field */ + int field_index = + int_range_lookup(message->descriptor->n_field_ranges, + message->descriptor->field_ranges, *oneof_case); + const ProtobufCFieldDescriptor *old_field = + message->descriptor->fields + field_index; + size_t el_size = sizeof_elt_in_repeated_array(old_field->type); + + switch (old_field->type) { + case PROTOBUF_C_TYPE_STRING: { + char **pstr = member; + const char *def = old_field->default_value; + if (*pstr != NULL && *pstr != def) do_free(allocator, *pstr); + break; + } + case PROTOBUF_C_TYPE_BYTES: { + ProtobufCBinaryData *bd = member; + const ProtobufCBinaryData *def_bd = old_field->default_value; + if (bd->data != NULL && (def_bd == NULL || bd->data != def_bd->data)) { + do_free(allocator, bd->data); + } + break; + } + case PROTOBUF_C_TYPE_MESSAGE: { + ProtobufCMessage **pmessage = member; + const ProtobufCMessage *def_mess = old_field->default_value; + if (*pmessage != NULL && *pmessage != def_mess) + protobuf_c_message_free_unpacked(*pmessage, allocator); + break; + } + default: + break; + } + + memset(member, 0, el_size); + } + if (!parse_required_member(scanned_member, member, allocator, TRUE)) + return FALSE; + + *oneof_case = scanned_member->tag; + return TRUE; +} + +static protobuf_c_boolean parse_optional_member(ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) { + if (!parse_required_member(scanned_member, member, allocator, TRUE)) + return FALSE; + if (scanned_member->field->quantifier_offset != 0) + STRUCT_MEMBER(protobuf_c_boolean, message, + scanned_member->field->quantifier_offset) = TRUE; + return TRUE; +} + +static protobuf_c_boolean parse_repeated_member(ScannedMember *scanned_member, + void *member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) { + const ProtobufCFieldDescriptor *field = scanned_member->field; + size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset); + size_t siz = sizeof_elt_in_repeated_array(field->type); + char *array = *(char **)member; + + if (!parse_required_member(scanned_member, array + siz * (*p_n), allocator, + FALSE)) { + return FALSE; + } + *p_n += 1; + return TRUE; +} + +static unsigned scan_varint(unsigned len, const uint8_t *data) { + unsigned i; + if (len > 10) len = 10; + for (i = 0; i < len; i++) + if ((data[i] & 0x80) == 0) break; + if (i == len) return 0; + return i + 1; +} + +static protobuf_c_boolean parse_packed_repeated_member( + ScannedMember *scanned_member, void *member, ProtobufCMessage *message) { + const ProtobufCFieldDescriptor *field = scanned_member->field; + size_t *p_n = STRUCT_MEMBER_PTR(size_t, message, field->quantifier_offset); + size_t siz = sizeof_elt_in_repeated_array(field->type); + void *array = *(char **)member + siz * (*p_n); + const uint8_t *at = scanned_member->data + scanned_member->length_prefix_len; + size_t rem = scanned_member->len - scanned_member->length_prefix_len; + size_t count = 0; + unsigned i; + + switch (field->type) { + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + count = (scanned_member->len - scanned_member->length_prefix_len) / 4; +#if !defined(WORDS_BIGENDIAN) + goto no_unpacking_needed; +#else + for (i = 0; i < count; i++) { + ((uint32_t *)array)[i] = parse_fixed_uint32(at); + at += 4; + } + break; +#endif + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + count = (scanned_member->len - scanned_member->length_prefix_len) / 8; +#if !defined(WORDS_BIGENDIAN) + goto no_unpacking_needed; +#else + for (i = 0; i < count; i++) { + ((uint64_t *)array)[i] = parse_fixed_uint64(at); + at += 8; + } + break; +#endif + case PROTOBUF_C_TYPE_ENUM: + case PROTOBUF_C_TYPE_INT32: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int32 value"); + return FALSE; + } + ((int32_t *)array)[count++] = parse_int32(s, at); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_SINT32: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint32 value"); + return FALSE; + } + ((int32_t *)array)[count++] = unzigzag32(parse_uint32(s, at)); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_UINT32: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated enum or uint32 value"); + return FALSE; + } + ((uint32_t *)array)[count++] = parse_uint32(s, at); + at += s; + rem -= s; + } + break; + + case PROTOBUF_C_TYPE_SINT64: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated sint64 value"); + return FALSE; + } + ((int64_t *)array)[count++] = unzigzag64(parse_uint64(s, at)); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_UINT64: + while (rem > 0) { + unsigned s = scan_varint(rem, at); + if (s == 0) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated int64/uint64 value"); + return FALSE; + } + ((int64_t *)array)[count++] = parse_uint64(s, at); + at += s; + rem -= s; + } + break; + case PROTOBUF_C_TYPE_BOOL: + count = rem; + for (i = 0; i < count; i++) { + if (at[i] > 1) { + PROTOBUF_C_UNPACK_ERROR("bad packed-repeated boolean value"); + return FALSE; + } + ((protobuf_c_boolean *)array)[i] = at[i]; + } + break; + default: + PROTOBUF_C__ASSERT_NOT_REACHED(); + } + *p_n += count; + return TRUE; + +#if !defined(WORDS_BIGENDIAN) +no_unpacking_needed: + memcpy(array, at, count * siz); + *p_n += count; + return TRUE; +#endif +} + +static protobuf_c_boolean is_packable_type(ProtobufCType type) { + return type != PROTOBUF_C_TYPE_STRING && type != PROTOBUF_C_TYPE_BYTES && + type != PROTOBUF_C_TYPE_MESSAGE; +} + +static protobuf_c_boolean parse_member(ScannedMember *scanned_member, + ProtobufCMessage *message, + ProtobufCAllocator *allocator) { + const ProtobufCFieldDescriptor *field = scanned_member->field; + void *member; + + if (field == NULL) { + ProtobufCMessageUnknownField *ufield = + message->unknown_fields + (message->n_unknown_fields++); + ufield->tag = scanned_member->tag; + ufield->wire_type = scanned_member->wire_type; + ufield->len = scanned_member->len; + ufield->data = do_alloc(allocator, scanned_member->len); + if (ufield->data == NULL) return FALSE; + memcpy(ufield->data, scanned_member->data, ufield->len); + return TRUE; + } + member = (char *)message + field->offset; + switch (field->label) { + case PROTOBUF_C_LABEL_REQUIRED: + return parse_required_member(scanned_member, member, allocator, TRUE); + case PROTOBUF_C_LABEL_OPTIONAL: + case PROTOBUF_C_LABEL_NONE: + if (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_ONEOF)) { + return parse_oneof_member(scanned_member, member, message, allocator); + } else { + return parse_optional_member(scanned_member, member, message, + allocator); + } + case PROTOBUF_C_LABEL_REPEATED: + if (scanned_member->wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) || + is_packable_type(field->type))) { + return parse_packed_repeated_member(scanned_member, member, message); + } else { + return parse_repeated_member(scanned_member, member, message, + allocator); + } + } + PROTOBUF_C__ASSERT_NOT_REACHED(); + return 0; +} + +/** + * Initialise messages generated by old code. + * + * This function is used if desc->message_init == NULL (which occurs + * for old code, and which would be useful to support allocating + * descriptors dynamically). + */ +static void message_init_generic(const ProtobufCMessageDescriptor *desc, + ProtobufCMessage *message) { + unsigned i; + + memset(message, 0, desc->sizeof_message); + message->descriptor = desc; + for (i = 0; i < desc->n_fields; i++) { + if (desc->fields[i].default_value != NULL && + desc->fields[i].label != PROTOBUF_C_LABEL_REPEATED) { + void *field = STRUCT_MEMBER_P(message, desc->fields[i].offset); + const void *dv = desc->fields[i].default_value; + + switch (desc->fields[i].type) { + case PROTOBUF_C_TYPE_INT32: + case PROTOBUF_C_TYPE_SINT32: + case PROTOBUF_C_TYPE_SFIXED32: + case PROTOBUF_C_TYPE_UINT32: + case PROTOBUF_C_TYPE_FIXED32: + case PROTOBUF_C_TYPE_FLOAT: + case PROTOBUF_C_TYPE_ENUM: + memcpy(field, dv, 4); + break; + case PROTOBUF_C_TYPE_INT64: + case PROTOBUF_C_TYPE_SINT64: + case PROTOBUF_C_TYPE_SFIXED64: + case PROTOBUF_C_TYPE_UINT64: + case PROTOBUF_C_TYPE_FIXED64: + case PROTOBUF_C_TYPE_DOUBLE: + memcpy(field, dv, 8); + break; + case PROTOBUF_C_TYPE_BOOL: + memcpy(field, dv, sizeof(protobuf_c_boolean)); + break; + case PROTOBUF_C_TYPE_BYTES: + memcpy(field, dv, sizeof(ProtobufCBinaryData)); + break; + + case PROTOBUF_C_TYPE_STRING: + case PROTOBUF_C_TYPE_MESSAGE: + /* + * The next line essentially implements a cast + * from const, which is totally unavoidable. + */ + *(const void **)field = dv; + break; + } + } + } +} + +/**@}*/ + +/* + * ScannedMember slabs (an unpacking implementation detail). Before doing real + * unpacking, we first scan through the elements to see how many there are (for + * repeated fields), and which field to use (for non-repeated fields given + * twice). + * + * In order to avoid allocations for small messages, we keep a stack-allocated + * slab of ScannedMembers of size FIRST_SCANNED_MEMBER_SLAB_SIZE (16). After we + * fill that up, we allocate each slab twice as large as the previous one. + */ +#define FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2 4 + +/* + * The number of slabs, including the stack-allocated ones; choose the number so + * that we would overflow if we needed a slab larger than provided. + */ +#define MAX_SCANNED_MEMBER_SLAB \ + (sizeof(unsigned int) * 8 - 1 - BOUND_SIZEOF_SCANNED_MEMBER_LOG2 - \ + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2) + +#define REQUIRED_FIELD_BITMAP_SET(index) \ + (required_fields_bitmap[(index) / 8] |= (1UL << ((index) % 8))) + +#define REQUIRED_FIELD_BITMAP_IS_SET(index) \ + (required_fields_bitmap[(index) / 8] & (1UL << ((index) % 8))) + +ProtobufCMessage *protobuf_c_message_unpack( + const ProtobufCMessageDescriptor *desc, ProtobufCAllocator *allocator, + size_t len, const uint8_t *data) { + ProtobufCMessage *rv; + size_t rem = len; + const uint8_t *at = data; + const ProtobufCFieldDescriptor *last_field = desc->fields + 0; + ScannedMember first_member_slab[1UL << FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2]; + + /* + * scanned_member_slabs[i] is an array of arrays of ScannedMember. + * The first slab (scanned_member_slabs[0] is just a pointer to + * first_member_slab), above. All subsequent slabs will be allocated + * using the allocator. + */ + ScannedMember *scanned_member_slabs[MAX_SCANNED_MEMBER_SLAB + 1]; + unsigned which_slab = 0; /* the slab we are currently populating */ + unsigned in_slab_index = 0; /* number of members in the slab */ + size_t n_unknown = 0; + unsigned f; + unsigned j; + unsigned i_slab; + unsigned last_field_index = 0; + unsigned required_fields_bitmap_len; + unsigned char required_fields_bitmap_stack[16]; + unsigned char *required_fields_bitmap = required_fields_bitmap_stack; + protobuf_c_boolean required_fields_bitmap_alloced = FALSE; + + ASSERT_IS_MESSAGE_DESCRIPTOR(desc); + + if (allocator == NULL) allocator = &protobuf_c__allocator; + + rv = do_alloc(allocator, desc->sizeof_message); + if (!rv) return (NULL); + scanned_member_slabs[0] = first_member_slab; + + required_fields_bitmap_len = (desc->n_fields + 7) / 8; + if (required_fields_bitmap_len > sizeof(required_fields_bitmap_stack)) { + required_fields_bitmap = do_alloc(allocator, required_fields_bitmap_len); + if (!required_fields_bitmap) { + do_free(allocator, rv); + return (NULL); + } + required_fields_bitmap_alloced = TRUE; + } + memset(required_fields_bitmap, 0, required_fields_bitmap_len); + + /* + * Generated code always defines "message_init". However, we provide a + * fallback for (1) users of old protobuf-c generated-code that do not + * provide the function, and (2) descriptors constructed from some other + * source (most likely, direct construction from the .proto file). + */ + if (desc->message_init != NULL) + protobuf_c_message_init(desc, rv); + else + message_init_generic(desc, rv); + + while (rem > 0) { + uint32_t tag; + ProtobufCWireType wire_type; + size_t used = parse_tag_and_wiretype(rem, at, &tag, &wire_type); + const ProtobufCFieldDescriptor *field; + ScannedMember tmp; + + if (used == 0) { + PROTOBUF_C_UNPACK_ERROR("error parsing tag/wiretype at offset %u", + (unsigned)(at - data)); + goto error_cleanup_during_scan; + } + /* + * \todo Consider optimizing for field[1].id == tag, if field[1] + * exists! + */ + if (last_field == NULL || last_field->id != tag) { + /* lookup field */ + int field_index = + int_range_lookup(desc->n_field_ranges, desc->field_ranges, tag); + if (field_index < 0) { + field = NULL; + n_unknown++; + } else { + field = desc->fields + field_index; + last_field = field; + last_field_index = field_index; + } + } else { + field = last_field; + } + + if (field != NULL && field->label == PROTOBUF_C_LABEL_REQUIRED) + REQUIRED_FIELD_BITMAP_SET(last_field_index); + + at += used; + rem -= used; + tmp.tag = tag; + tmp.wire_type = wire_type; + tmp.field = field; + tmp.data = at; + tmp.length_prefix_len = 0; + + switch (wire_type) { + case PROTOBUF_C_WIRE_TYPE_VARINT: { + unsigned max_len = rem < 10 ? rem : 10; + unsigned i; + + for (i = 0; i < max_len; i++) + if ((at[i] & 0x80) == 0) break; + if (i == max_len) { + PROTOBUF_C_UNPACK_ERROR("unterminated varint at offset %u", + (unsigned)(at - data)); + goto error_cleanup_during_scan; + } + tmp.len = i + 1; + break; + } + case PROTOBUF_C_WIRE_TYPE_64BIT: + if (rem < 8) { + PROTOBUF_C_UNPACK_ERROR("too short after 64bit wiretype at offset %u", + (unsigned)(at - data)); + goto error_cleanup_during_scan; + } + tmp.len = 8; + break; + case PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED: { + size_t pref_len; + + tmp.len = scan_length_prefixed_data(rem, at, &pref_len); + if (tmp.len == 0) { + /* NOTE: scan_length_prefixed_data calls UNPACK_ERROR */ + goto error_cleanup_during_scan; + } + tmp.length_prefix_len = pref_len; + break; + } + case PROTOBUF_C_WIRE_TYPE_32BIT: + if (rem < 4) { + PROTOBUF_C_UNPACK_ERROR("too short after 32bit wiretype at offset %u", + (unsigned)(at - data)); + goto error_cleanup_during_scan; + } + tmp.len = 4; + break; + default: + PROTOBUF_C_UNPACK_ERROR("unsupported tag %u at offset %u", wire_type, + (unsigned)(at - data)); + goto error_cleanup_during_scan; + } + + if (in_slab_index == + (1UL << (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2))) { + size_t size; + + in_slab_index = 0; + if (which_slab == MAX_SCANNED_MEMBER_SLAB) { + PROTOBUF_C_UNPACK_ERROR("too many fields"); + goto error_cleanup_during_scan; + } + which_slab++; + size = sizeof(ScannedMember) + << (which_slab + FIRST_SCANNED_MEMBER_SLAB_SIZE_LOG2); + scanned_member_slabs[which_slab] = do_alloc(allocator, size); + if (scanned_member_slabs[which_slab] == NULL) + goto error_cleanup_during_scan; + } + scanned_member_slabs[which_slab][in_slab_index++] = tmp; + + if (field != NULL && field->label == PROTOBUF_C_LABEL_REPEATED) { + size_t *n = STRUCT_MEMBER_PTR(size_t, rv, field->quantifier_offset); + if (wire_type == PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED && + (0 != (field->flags & PROTOBUF_C_FIELD_FLAG_PACKED) || + is_packable_type(field->type))) { + size_t count; + if (!count_packed_elements(field->type, tmp.len - tmp.length_prefix_len, + tmp.data + tmp.length_prefix_len, &count)) { + PROTOBUF_C_UNPACK_ERROR("counting packed elements"); + goto error_cleanup_during_scan; + } + *n += count; + } else { + *n += 1; + } + } + + at += tmp.len; + rem -= tmp.len; + } + + /* allocate space for repeated fields, also check that all required fields + * have been set */ + for (f = 0; f < desc->n_fields; f++) { + const ProtobufCFieldDescriptor *field = desc->fields + f; + if (field->label == PROTOBUF_C_LABEL_REPEATED) { + size_t siz = sizeof_elt_in_repeated_array(field->type); + size_t *n_ptr = STRUCT_MEMBER_PTR(size_t, rv, field->quantifier_offset); + if (*n_ptr != 0) { + unsigned n = *n_ptr; + void *a; + *n_ptr = 0; + assert(rv->descriptor != NULL); +#define CLEAR_REMAINING_N_PTRS() \ + for (f++; f < desc->n_fields; f++) { \ + field = desc->fields + f; \ + if (field->label == PROTOBUF_C_LABEL_REPEATED) \ + STRUCT_MEMBER(size_t, rv, field->quantifier_offset) = 0; \ + } + a = do_alloc(allocator, siz * n); + if (!a) { + CLEAR_REMAINING_N_PTRS(); + goto error_cleanup; + } + STRUCT_MEMBER(void *, rv, field->offset) = a; + } + } else if (field->label == PROTOBUF_C_LABEL_REQUIRED) { + if (field->default_value == NULL && !REQUIRED_FIELD_BITMAP_IS_SET(f)) { + CLEAR_REMAINING_N_PTRS(); + PROTOBUF_C_UNPACK_ERROR("message '%s': missing required field '%s'", + desc->name, field->name); + goto error_cleanup; + } + } + } +#undef CLEAR_REMAINING_N_PTRS + + /* allocate space for unknown fields */ + if (n_unknown) { + rv->unknown_fields = + do_alloc(allocator, n_unknown * sizeof(ProtobufCMessageUnknownField)); + if (rv->unknown_fields == NULL) goto error_cleanup; + } + + /* do real parsing */ + for (i_slab = 0; i_slab <= which_slab; i_slab++) { + unsigned max = + (i_slab == which_slab) ? in_slab_index : (1UL << (i_slab + 4)); + ScannedMember *slab = scanned_member_slabs[i_slab]; + + for (j = 0; j < max; j++) { + if (!parse_member(slab + j, rv, allocator)) { + PROTOBUF_C_UNPACK_ERROR( + "error parsing member %s of %s", + slab->field ? slab->field->name : "*unknown-field*", desc->name); + goto error_cleanup; + } + } + } + + /* cleanup */ + for (j = 1; j <= which_slab; j++) do_free(allocator, scanned_member_slabs[j]); + if (required_fields_bitmap_alloced) + do_free(allocator, required_fields_bitmap); + return rv; + +error_cleanup: + protobuf_c_message_free_unpacked(rv, allocator); + for (j = 1; j <= which_slab; j++) do_free(allocator, scanned_member_slabs[j]); + if (required_fields_bitmap_alloced) + do_free(allocator, required_fields_bitmap); + return NULL; + +error_cleanup_during_scan: + do_free(allocator, rv); + for (j = 1; j <= which_slab; j++) do_free(allocator, scanned_member_slabs[j]); + if (required_fields_bitmap_alloced) + do_free(allocator, required_fields_bitmap); + return NULL; +} + +void protobuf_c_message_free_unpacked(ProtobufCMessage *message, + ProtobufCAllocator *allocator) { + const ProtobufCMessageDescriptor *desc; + unsigned f; + + if (message == NULL) return; + + desc = message->descriptor; + + ASSERT_IS_MESSAGE(message); + + if (allocator == NULL) allocator = &protobuf_c__allocator; + message->descriptor = NULL; + for (f = 0; f < desc->n_fields; f++) { + if (0 != (desc->fields[f].flags & PROTOBUF_C_FIELD_FLAG_ONEOF) && + desc->fields[f].id != + STRUCT_MEMBER(uint32_t, message, + desc->fields[f].quantifier_offset)) { + /* This is not the selected oneof, skip it */ + continue; + } + + if (desc->fields[f].label == PROTOBUF_C_LABEL_REPEATED) { + size_t n = + STRUCT_MEMBER(size_t, message, desc->fields[f].quantifier_offset); + void *arr = STRUCT_MEMBER(void *, message, desc->fields[f].offset); + + if (arr != NULL) { + if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { + unsigned i; + for (i = 0; i < n; i++) do_free(allocator, ((char **)arr)[i]); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { + unsigned i; + for (i = 0; i < n; i++) + do_free(allocator, ((ProtobufCBinaryData *)arr)[i].data); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { + unsigned i; + for (i = 0; i < n; i++) + protobuf_c_message_free_unpacked(((ProtobufCMessage **)arr)[i], + allocator); + } + do_free(allocator, arr); + } + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_STRING) { + char *str = STRUCT_MEMBER(char *, message, desc->fields[f].offset); + + if (str && str != desc->fields[f].default_value) do_free(allocator, str); + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_BYTES) { + void *data = + STRUCT_MEMBER(ProtobufCBinaryData, message, desc->fields[f].offset) + .data; + const ProtobufCBinaryData *default_bd; + + default_bd = desc->fields[f].default_value; + if (data != NULL && (default_bd == NULL || default_bd->data != data)) { + do_free(allocator, data); + } + } else if (desc->fields[f].type == PROTOBUF_C_TYPE_MESSAGE) { + ProtobufCMessage *sm; + + sm = STRUCT_MEMBER(ProtobufCMessage *, message, desc->fields[f].offset); + if (sm && sm != desc->fields[f].default_value) + protobuf_c_message_free_unpacked(sm, allocator); + } + } + + for (f = 0; f < message->n_unknown_fields; f++) + do_free(allocator, message->unknown_fields[f].data); + if (message->unknown_fields != NULL) + do_free(allocator, message->unknown_fields); + + do_free(allocator, message); +} + +void protobuf_c_message_init(const ProtobufCMessageDescriptor *descriptor, + void *message) { + descriptor->message_init((ProtobufCMessage *)(message)); +} + +protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *message) { + unsigned i; + + if (!message || !message->descriptor || + message->descriptor->magic != PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC) { + return FALSE; + } + + for (i = 0; i < message->descriptor->n_fields; i++) { + const ProtobufCFieldDescriptor *f = message->descriptor->fields + i; + ProtobufCType type = f->type; + ProtobufCLabel label = f->label; + void *field = STRUCT_MEMBER_P(message, f->offset); + + if (label == PROTOBUF_C_LABEL_REPEATED) { + size_t *quantity = STRUCT_MEMBER_P(message, f->quantifier_offset); + + if (*quantity > 0 && *(void **)field == NULL) { + return FALSE; + } + + if (type == PROTOBUF_C_TYPE_MESSAGE) { + ProtobufCMessage **submessage = *(ProtobufCMessage ***)field; + unsigned j; + for (j = 0; j < *quantity; j++) { + if (!protobuf_c_message_check(submessage[j])) return FALSE; + } + } else if (type == PROTOBUF_C_TYPE_STRING) { + char **string = *(char ***)field; + unsigned j; + for (j = 0; j < *quantity; j++) { + if (!string[j]) return FALSE; + } + } else if (type == PROTOBUF_C_TYPE_BYTES) { + ProtobufCBinaryData *bd = *(ProtobufCBinaryData **)field; + unsigned j; + for (j = 0; j < *quantity; j++) { + if (bd[j].len > 0 && bd[j].data == NULL) return FALSE; + } + } + + } else { /* PROTOBUF_C_LABEL_REQUIRED or PROTOBUF_C_LABEL_OPTIONAL */ + + if (type == PROTOBUF_C_TYPE_MESSAGE) { + ProtobufCMessage *submessage = *(ProtobufCMessage **)field; + if (label == PROTOBUF_C_LABEL_REQUIRED || submessage != NULL) { + if (!protobuf_c_message_check(submessage)) return FALSE; + } + } else if (type == PROTOBUF_C_TYPE_STRING) { + char *string = *(char **)field; + if (label == PROTOBUF_C_LABEL_REQUIRED && string == NULL) return FALSE; + } else if (type == PROTOBUF_C_TYPE_BYTES) { + protobuf_c_boolean *has = + STRUCT_MEMBER_P(message, f->quantifier_offset); + ProtobufCBinaryData *bd = field; + if (label == PROTOBUF_C_LABEL_REQUIRED || *has == TRUE) { + if (bd->len > 0 && bd->data == NULL) return FALSE; + } + } + } + } + + return TRUE; +} + +/* === services === */ + +typedef void (*GenericHandler)(void *service, const ProtobufCMessage *input, + ProtobufCClosure closure, void *closure_data); diff --git a/tools/quantification/src/protobuf-c.h b/tools/quantification/src/protobuf-c.h new file mode 100644 index 0000000000000000000000000000000000000000..bd85695b868af6c7b91590196339bc4f7826a256 --- /dev/null +++ b/tools/quantification/src/protobuf-c.h @@ -0,0 +1,921 @@ +/* + * Copyright (c) 2008-2017, Dave Benson and the protobuf-c authors. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/*! \file + * \mainpage Introduction + * + * This is [protobuf-c], a C implementation of [Protocol Buffers]. + * + * This file defines the public API for the `libprotobuf-c` support library. + * This API includes interfaces that can be used directly by client code as well + * as the interfaces used by the code generated by the `protoc-c` compiler. + * + * The `libprotobuf-c` support library performs the actual serialization and + * deserialization of Protocol Buffers messages. It interacts with structures, + * definitions, and metadata generated by the `protoc-c` compiler from .proto + * files. + * + * \authors Dave Benson and the `protobuf-c` authors. + * + * \copyright 2008-2014. Licensed under the terms of the [BSD-2-Clause] license. + * + * [protobuf-c]: https://github.com/protobuf-c/protobuf-c + * [Protocol Buffers]: https://developers.google.com/protocol-buffers/ + * [BSD-2-Clause]: http://opensource.org/licenses/BSD-2-Clause + * + * \page gencode Generated Code + * + * For each enum, we generate a C enum. For each message, we generate a C + * structure which can be cast to a `ProtobufCMessage`. + * + * For each enum and message, we generate a descriptor object that allows us to + * implement a kind of reflection on the structures. + * + * First, some naming conventions: + * + * - The name of the type for enums and messages and services is camel case + * (meaning WordsAreCrammedTogether) except that double underscores are used + * to delimit scopes. For example, the following `.proto` file: + * +~~~{.proto} + package foo.bar; + message BazBah { + optional int32 val = 1; + } +~~~ + * + * would generate a C type `Foo__Bar__BazBah`. + * + * - Identifiers for functions and globals are all lowercase, with camel case + * words separated by single underscores. For example, one of the function + * prototypes generated by `protoc-c` for the above example: + * +~~~{.c} +Foo__Bar__BazBah * + foo__bar__baz_bah__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +~~~ + * + * - Identifiers for enum values contain an uppercase prefix which embeds the + * package name and the enum type name. + * + * - A double underscore is used to separate further components of identifier + * names. + * + * For example, in the name of the unpack function above, the package name + * `foo.bar` has become `foo__bar`, the message name BazBah has become + * `baz_bah`, and the method name is `unpack`. These are all joined with double + * underscores to form the C identifier `foo__bar__baz_bah__unpack`. + * + * We also generate descriptor objects for messages and enums. These are + * declared in the `.pb-c.h` files: + * +~~~{.c} +extern const ProtobufCMessageDescriptor foo__bar__baz_bah__descriptor; +~~~ + * + * The message structures all begin with `ProtobufCMessageDescriptor *` which is + * sufficient to allow them to be cast to `ProtobufCMessage`. + * + * For each message defined in a `.proto` file, we generate a number of + * functions and macros. Each function name contains a prefix based on the + * package name and message name in order to make it a unique C identifier. + * + * - `INIT`. Statically initializes a message object, initializing its + * descriptor and setting its fields to default values. Uninitialized + * messages cannot be processed by the protobuf-c library. + * +~~~{.c} +#define FOO__BAR__BAZ_BAH__INIT \ + { PROTOBUF_C_MESSAGE_INIT (&foo__bar__baz_bah__descriptor), 0 } +~~~ + * - `init()`. Initializes a message object, initializing its descriptor and + * setting its fields to default values. Uninitialized messages cannot be + * processed by the protobuf-c library. + * +~~~{.c} +void foo__bar__baz_bah__init + (Foo__Bar__BazBah *message); +~~~ + * - `unpack()`. Unpacks data for a particular message format. Note that the + * `allocator` parameter is usually `NULL` to indicate that the system's + * `malloc()` and `free()` functions should be used for dynamically allocating + * memory. + * +~~~{.c} +Foo__Bar__BazBah * + foo__bar__baz_bah__unpack + (ProtobufCAllocator *allocator, + size_t len, + const uint8_t *data); +~~~ + * + * - `free_unpacked()`. Frees a message object obtained with the `unpack()` + * method. Freeing `NULL` is allowed (the same as with `free()`). + * +~~~{.c} +void foo__bar__baz_bah__free_unpacked + (Foo__Bar__BazBah *message, + ProtobufCAllocator *allocator); +~~~ + * + * - `get_packed_size()`. Calculates the length in bytes of the serialized + * representation of the message object. + * +~~~{.c} +size_t foo__bar__baz_bah__get_packed_size + (const Foo__Bar__BazBah *message); +~~~ + * + * - `pack()`. Pack a message object into a preallocated buffer. Assumes that + * the buffer is large enough. (Use `get_packed_size()` first.) + * +~~~{.c} +size_t foo__bar__baz_bah__pack + (const Foo__Bar__BazBah *message, + uint8_t *out); +~~~ + * + * - `pack_to_buffer()`. Packs a message into a "virtual buffer". This is an + * object which defines an "append bytes" callback to consume data as it is + * serialized. + * +~~~{.c} +size_t foo__bar__baz_bah__pack_to_buffer + (const Foo__Bar__BazBah *message, + ProtobufCBuffer *buffer); +~~~ + * + * \page pack Packing and unpacking messages + * + * To pack a message, first compute the packed size of the message with + * protobuf_c_message_get_packed_size(), then allocate a buffer of at least + * that size, then call protobuf_c_message_pack(). + * + * Alternatively, a message can be serialized without calculating the final size + * first. Use the protobuf_c_message_pack_to_buffer() function and provide a + * ProtobufCBuffer object which implements an "append" method that consumes + * data. + * + * To unpack a message, call the protobuf_c_message_unpack() function. The + * result can be cast to an object of the type that matches the descriptor for + * the message. + * + * The result of unpacking a message should be freed with + * protobuf_c_message_free_unpacked(). + */ + +#ifndef PROTOBUF_C_H +#define PROTOBUF_C_H + +#include +#include +#include +#include + +#ifdef __cplusplus +#define PROTOBUF_C__BEGIN_DECLS extern "C" { +#define PROTOBUF_C__END_DECLS } +#else +#define PROTOBUF_C__BEGIN_DECLS +#define PROTOBUF_C__END_DECLS +#endif + +PROTOBUF_C__BEGIN_DECLS + +#if defined(_WIN32) && defined(PROTOBUF_C_USE_SHARED_LIB) +#ifdef PROTOBUF_C_EXPORT +#define PROTOBUF_C__API __declspec(dllexport) +#else +#define PROTOBUF_C__API __declspec(dllimport) +#endif +#else +#define PROTOBUF_C__API +#endif + +#if !defined(PROTOBUF_C__NO_DEPRECATED) && \ + ((__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)) +#define PROTOBUF_C__DEPRECATED __attribute__((__deprecated__)) +#else +#define PROTOBUF_C__DEPRECATED +#endif + +#ifndef PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE +#define PROTOBUF_C__FORCE_ENUM_TO_BE_INT_SIZE(enum_name) \ + , _##enum_name##_IS_INT_SIZE = INT_MAX +#endif + +#define PROTOBUF_C__SERVICE_DESCRIPTOR_MAGIC 0x14159bc3 +#define PROTOBUF_C__MESSAGE_DESCRIPTOR_MAGIC 0x28aaeef9 +#define PROTOBUF_C__ENUM_DESCRIPTOR_MAGIC 0x114315af + +/* Empty string used for initializers */ +extern const char protobuf_c_empty_string[]; + +/** + * \defgroup api Public API + * + * This is the public API for `libprotobuf-c`. These interfaces are stable and + * subject to Semantic Versioning guarantees. + * + * @{ + */ + +/** + * Values for the `flags` word in `ProtobufCFieldDescriptor`. + */ +typedef enum { + /** Set if the field is repeated and marked with the `packed` option. */ + PROTOBUF_C_FIELD_FLAG_PACKED = (1 << 0), + + /** Set if the field is marked with the `deprecated` option. */ + PROTOBUF_C_FIELD_FLAG_DEPRECATED = (1 << 1), + + /** Set if the field is a member of a oneof (union). */ + PROTOBUF_C_FIELD_FLAG_ONEOF = (1 << 2), +} ProtobufCFieldFlag; + +/** + * Message field rules. + * + * \see [Defining A Message Type] in the Protocol Buffers documentation. + * + * [Defining A Message Type]: + * https://developers.google.com/protocol-buffers/docs/proto#simple + */ +typedef enum { + /** A well-formed message must have exactly one of this field. */ + PROTOBUF_C_LABEL_REQUIRED, + + /** + * A well-formed message can have zero or one of this field (but not + * more than one). + */ + PROTOBUF_C_LABEL_OPTIONAL, + + /** + * This field can be repeated any number of times (including zero) in a + * well-formed message. The order of the repeated values will be + * preserved. + */ + PROTOBUF_C_LABEL_REPEATED, + + /** + * This field has no label. This is valid only in proto3 and is + * equivalent to OPTIONAL but no "has" quantifier will be consulted. + */ + PROTOBUF_C_LABEL_NONE, +} ProtobufCLabel; + +/** + * Field value types. + * + * \see [Scalar Value Types] in the Protocol Buffers documentation. + * + * [Scalar Value Types]: + * https://developers.google.com/protocol-buffers/docs/proto#scalar + */ +typedef enum { + PROTOBUF_C_TYPE_INT32, /**< int32 */ + PROTOBUF_C_TYPE_SINT32, /**< signed int32 */ + PROTOBUF_C_TYPE_SFIXED32, /**< signed int32 (4 bytes) */ + PROTOBUF_C_TYPE_INT64, /**< int64 */ + PROTOBUF_C_TYPE_SINT64, /**< signed int64 */ + PROTOBUF_C_TYPE_SFIXED64, /**< signed int64 (8 bytes) */ + PROTOBUF_C_TYPE_UINT32, /**< unsigned int32 */ + PROTOBUF_C_TYPE_FIXED32, /**< unsigned int32 (4 bytes) */ + PROTOBUF_C_TYPE_UINT64, /**< unsigned int64 */ + PROTOBUF_C_TYPE_FIXED64, /**< unsigned int64 (8 bytes) */ + PROTOBUF_C_TYPE_FLOAT, /**< float */ + PROTOBUF_C_TYPE_DOUBLE, /**< double */ + PROTOBUF_C_TYPE_BOOL, /**< boolean */ + PROTOBUF_C_TYPE_ENUM, /**< enumerated type */ + PROTOBUF_C_TYPE_STRING, /**< UTF-8 or ASCII string */ + PROTOBUF_C_TYPE_BYTES, /**< arbitrary byte sequence */ + PROTOBUF_C_TYPE_MESSAGE, /**< nested message */ +} ProtobufCType; + +/** + * Field wire types. + * + * \see [Message Structure] in the Protocol Buffers documentation. + * + * [Message Structure]: + * https://developers.google.com/protocol-buffers/docs/encoding#structure + */ +typedef enum { + PROTOBUF_C_WIRE_TYPE_VARINT = 0, + PROTOBUF_C_WIRE_TYPE_64BIT = 1, + PROTOBUF_C_WIRE_TYPE_LENGTH_PREFIXED = 2, + /* "Start group" and "end group" wire types are unsupported. */ + PROTOBUF_C_WIRE_TYPE_32BIT = 5, +} ProtobufCWireType; + +struct ProtobufCAllocator; +struct ProtobufCBinaryData; +struct ProtobufCBuffer; +struct ProtobufCBufferSimple; +struct ProtobufCEnumDescriptor; +struct ProtobufCEnumValue; +struct ProtobufCEnumValueIndex; +struct ProtobufCFieldDescriptor; +struct ProtobufCIntRange; +struct ProtobufCMessage; +struct ProtobufCMessageDescriptor; +struct ProtobufCMessageUnknownField; +struct ProtobufCMethodDescriptor; +struct ProtobufCService; +struct ProtobufCServiceDescriptor; + +typedef struct ProtobufCAllocator ProtobufCAllocator; +typedef struct ProtobufCBinaryData ProtobufCBinaryData; +typedef struct ProtobufCBuffer ProtobufCBuffer; +typedef struct ProtobufCBufferSimple ProtobufCBufferSimple; +typedef struct ProtobufCEnumDescriptor ProtobufCEnumDescriptor; +typedef struct ProtobufCEnumValue ProtobufCEnumValue; +typedef struct ProtobufCEnumValueIndex ProtobufCEnumValueIndex; +typedef struct ProtobufCFieldDescriptor ProtobufCFieldDescriptor; +typedef struct ProtobufCIntRange ProtobufCIntRange; +typedef struct ProtobufCMessage ProtobufCMessage; +typedef struct ProtobufCMessageDescriptor ProtobufCMessageDescriptor; +typedef struct ProtobufCMessageUnknownField ProtobufCMessageUnknownField; +typedef struct ProtobufCMethodDescriptor ProtobufCMethodDescriptor; +typedef struct ProtobufCService ProtobufCService; +typedef struct ProtobufCServiceDescriptor ProtobufCServiceDescriptor; + +/** Boolean type. */ +typedef int protobuf_c_boolean; + +typedef void (*ProtobufCClosure)(const ProtobufCMessage *, void *closure_data); +typedef void (*ProtobufCMessageInit)(ProtobufCMessage *); +typedef void (*ProtobufCServiceDestroy)(ProtobufCService *); + +/** + * Structure for defining a custom memory allocator. + */ +struct ProtobufCAllocator { + /** Function to allocate memory. */ + void *(*alloc)(void *allocator_data, size_t size); + + /** Function to free memory. */ + void (*free)(void *allocator_data, void *pointer); + + /** Opaque pointer passed to `alloc` and `free` functions. */ + void *allocator_data; +}; + +/** + * Structure for the protobuf `bytes` scalar type. + * + * The data contained in a `ProtobufCBinaryData` is an arbitrary sequence of + * bytes. It may contain embedded `NUL` characters and is not required to be + * `NUL`-terminated. + */ +struct ProtobufCBinaryData { + size_t len; /**< Number of bytes in the `data` field. */ + uint8_t *data; /**< Data bytes. */ +}; + +/** + * Structure for defining a virtual append-only buffer. Used by + * protobuf_c_message_pack_to_buffer() to abstract the consumption of serialized + * bytes. + * + * `ProtobufCBuffer` "subclasses" may be defined on the stack. For example, to + * write to a `FILE` object: + * +~~~{.c} +typedef struct { + ProtobufCBuffer base; + FILE *fp; +} BufferAppendToFile; + +static void +my_buffer_file_append(ProtobufCBuffer *buffer, + size_t len, + const uint8_t *data) +{ + BufferAppendToFile *file_buf = (BufferAppendToFile *) buffer; + fwrite(data, len, 1, file_buf->fp); // XXX: No error handling! +} +~~~ + * + * To use this new type of ProtobufCBuffer, it could be called as follows: + * +~~~{.c} +... +BufferAppendToFile tmp = {0}; +tmp.base.append = my_buffer_file_append; +tmp.fp = fp; +protobuf_c_message_pack_to_buffer(&message, &tmp); +... +~~~ + */ +struct ProtobufCBuffer { + /** Append function. Consumes the `len` bytes stored at `data`. */ + void (*append)(ProtobufCBuffer *buffer, size_t len, const uint8_t *data); +}; + +/** + * Simple buffer "subclass" of `ProtobufCBuffer`. + * + * A `ProtobufCBufferSimple` object is declared on the stack and uses a + * scratch buffer provided by the user for the initial allocation. It performs + * exponential resizing, using dynamically allocated memory. A + * `ProtobufCBufferSimple` object can be created and used as follows: + * +~~~{.c} +uint8_t pad[128]; +ProtobufCBufferSimple simple = PROTOBUF_C_BUFFER_SIMPLE_INIT(pad); +ProtobufCBuffer *buffer = (ProtobufCBuffer *) &simple; +~~~ + * + * `buffer` can now be used with `protobuf_c_message_pack_to_buffer()`. Once a + * message has been serialized to a `ProtobufCBufferSimple` object, the + * serialized data bytes can be accessed from the `.data` field. + * + * To free the memory allocated by a `ProtobufCBufferSimple` object, if any, + * call PROTOBUF_C_BUFFER_SIMPLE_CLEAR() on the object, for example: + * +~~~{.c} +PROTOBUF_C_BUFFER_SIMPLE_CLEAR(&simple); +~~~ + * + * \see PROTOBUF_C_BUFFER_SIMPLE_INIT + * \see PROTOBUF_C_BUFFER_SIMPLE_CLEAR + */ +struct ProtobufCBufferSimple { + /** "Base class". */ + ProtobufCBuffer base; + /** Number of bytes allocated in `data`. */ + size_t alloced; + /** Number of bytes currently stored in `data`. */ + size_t len; + /** Data bytes. */ + uint8_t *data; + /** Whether `data` must be freed. */ + protobuf_c_boolean must_free_data; + /** Allocator to use. May be NULL to indicate the system allocator. */ + ProtobufCAllocator *allocator; +}; + +/** + * Describes an enumeration as a whole, with all of its values. + */ +struct ProtobufCEnumDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** The qualified name (e.g., "namespace.Type"). */ + const char *name; + /** The unqualified name as given in the .proto file (e.g., "Type"). */ + const char *short_name; + /** Identifier used in generated C code. */ + const char *c_name; + /** The dot-separated namespace. */ + const char *package_name; + + /** Number elements in `values`. */ + unsigned n_values; + /** Array of distinct values, sorted by numeric value. */ + const ProtobufCEnumValue *values; + + /** Number of elements in `values_by_name`. */ + unsigned n_value_names; + /** Array of named values, including aliases, sorted by name. */ + const ProtobufCEnumValueIndex *values_by_name; + + /** Number of elements in `value_ranges`. */ + unsigned n_value_ranges; + /** Value ranges, for faster lookups by numeric value. */ + const ProtobufCIntRange *value_ranges; + + /** Reserved for future use. */ + void *reserved1; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; + /** Reserved for future use. */ + void *reserved4; +}; + +/** + * Represents a single value of an enumeration. + */ +struct ProtobufCEnumValue { + /** The string identifying this value in the .proto file. */ + const char *name; + + /** The string identifying this value in generated C code. */ + const char *c_name; + + /** The numeric value assigned in the .proto file. */ + int value; +}; + +/** + * Used by `ProtobufCEnumDescriptor` to look up enum values. + */ +struct ProtobufCEnumValueIndex { + /** Name of the enum value. */ + const char *name; + /** Index into values[] array. */ + unsigned index; +}; + +/** + * Describes a single field in a message. + */ +struct ProtobufCFieldDescriptor { + /** Name of the field as given in the .proto file. */ + const char *name; + + /** Tag value of the field as given in the .proto file. */ + uint32_t id; + + /** Whether the field is `REQUIRED`, `OPTIONAL`, or `REPEATED`. */ + ProtobufCLabel label; + + /** The type of the field. */ + ProtobufCType type; + + /** + * The offset in bytes of the message's C structure's quantifier field + * (the `has_MEMBER` field for optional members or the `n_MEMBER` field + * for repeated members or the case enum for oneofs). + */ + unsigned quantifier_offset; + + /** + * The offset in bytes into the message's C structure for the member + * itself. + */ + unsigned offset; + + /** + * A type-specific descriptor. + * + * If `type` is `PROTOBUF_C_TYPE_ENUM`, then `descriptor` points to the + * corresponding `ProtobufCEnumDescriptor`. + * + * If `type` is `PROTOBUF_C_TYPE_MESSAGE`, then `descriptor` points to + * the corresponding `ProtobufCMessageDescriptor`. + * + * Otherwise this field is NULL. + */ + const void *descriptor; /* for MESSAGE and ENUM types */ + + /** The default value for this field, if defined. May be NULL. */ + const void *default_value; + + /** + * A flag word. Zero or more of the bits defined in the + * `ProtobufCFieldFlag` enum may be set. + */ + uint32_t flags; + + /** Reserved for future use. */ + unsigned reserved_flags; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; +}; + +/** + * Helper structure for optimizing int => index lookups in the case + * where the keys are mostly consecutive values, as they presumably are for + * enums and fields. + * + * The data structures requires that the values in the original array are + * sorted. + */ +struct ProtobufCIntRange { + int start_value; + unsigned orig_index; + /* + * NOTE: the number of values in the range can be inferred by looking + * at the next element's orig_index. A dummy element is added to make + * this simple. + */ +}; + +/** + * An instance of a message. + * + * `ProtobufCMessage` is a light-weight "base class" for all messages. + * + * In particular, `ProtobufCMessage` doesn't have any allocation policy + * associated with it. That's because it's common to create `ProtobufCMessage` + * objects on the stack. In fact, that's what we recommend for sending messages. + * If the object is allocated from the stack, you can't really have a memory + * leak. + * + * This means that calls to functions like protobuf_c_message_unpack() which + * return a `ProtobufCMessage` must be paired with a call to a free function, + * like protobuf_c_message_free_unpacked(). + */ +struct ProtobufCMessage { + /** The descriptor for this message type. */ + const ProtobufCMessageDescriptor *descriptor; + /** The number of elements in `unknown_fields`. */ + unsigned n_unknown_fields; + /** The fields that weren't recognized by the parser. */ + ProtobufCMessageUnknownField *unknown_fields; +}; + +/** + * Describes a message. + */ +struct ProtobufCMessageDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** The qualified name (e.g., "namespace.Type"). */ + const char *name; + /** The unqualified name as given in the .proto file (e.g., "Type"). */ + const char *short_name; + /** Identifier used in generated C code. */ + const char *c_name; + /** The dot-separated namespace. */ + const char *package_name; + + /** + * Size in bytes of the C structure representing an instance of this + * type of message. + */ + size_t sizeof_message; + + /** Number of elements in `fields`. */ + unsigned n_fields; + /** Field descriptors, sorted by tag number. */ + const ProtobufCFieldDescriptor *fields; + /** Used for looking up fields by name. */ + const unsigned *fields_sorted_by_name; + + /** Number of elements in `field_ranges`. */ + unsigned n_field_ranges; + /** Used for looking up fields by id. */ + const ProtobufCIntRange *field_ranges; + + /** Message initialisation function. */ + ProtobufCMessageInit message_init; + + /** Reserved for future use. */ + void *reserved1; + /** Reserved for future use. */ + void *reserved2; + /** Reserved for future use. */ + void *reserved3; +}; + +/** + * An unknown message field. + */ +struct ProtobufCMessageUnknownField { + /** The tag number. */ + uint32_t tag; + /** The wire type of the field. */ + ProtobufCWireType wire_type; + /** Number of bytes in `data`. */ + size_t len; + /** Field data. */ + uint8_t *data; +}; + +/** + * Method descriptor. + */ +struct ProtobufCMethodDescriptor { + /** Method name. */ + const char *name; + /** Input message descriptor. */ + const ProtobufCMessageDescriptor *input; + /** Output message descriptor. */ + const ProtobufCMessageDescriptor *output; +}; + +/** + * Service. + */ +struct ProtobufCService { + /** Service descriptor. */ + const ProtobufCServiceDescriptor *descriptor; + /** Function to invoke the service. */ + void (*invoke)(ProtobufCService *service, unsigned method_index, + const ProtobufCMessage *input, ProtobufCClosure closure, + void *closure_data); + /** Function to destroy the service. */ + void (*destroy)(ProtobufCService *service); +}; + +/** + * Service descriptor. + */ +struct ProtobufCServiceDescriptor { + /** Magic value checked to ensure that the API is used correctly. */ + uint32_t magic; + + /** Service name. */ + const char *name; + /** Short version of service name. */ + const char *short_name; + /** C identifier for the service name. */ + const char *c_name; + /** Package name. */ + const char *package; + /** Number of elements in `methods`. */ + unsigned n_methods; + /** Method descriptors, in the order defined in the .proto file. */ + const ProtobufCMethodDescriptor *methods; + /** Sort index of methods. */ + const unsigned *method_indices_by_name; +}; + +/** + * Get the version of the protobuf-c library. Note that this is the version of + * the library linked against, not the version of the headers compiled against. + * + * \return A string containing the version number of protobuf-c. + */ +PROTOBUF_C__API +const char *protobuf_c_version(void); + +/** + * Get the version of the protobuf-c library. Note that this is the version of + * the library linked against, not the version of the headers compiled against. + * + * \return A 32 bit unsigned integer containing the version number of + * protobuf-c, represented in base-10 as (MAJOR*1E6) + (MINOR*1E3) + PATCH. + */ +PROTOBUF_C__API +uint32_t protobuf_c_version_number(void); + +/** + * The version of the protobuf-c headers, represented as a string using the same + * format as protobuf_c_version(). + */ +#define PROTOBUF_C_VERSION "1.3.0" + +/** + * The version of the protobuf-c headers, represented as an integer using the + * same format as protobuf_c_version_number(). + */ +#define PROTOBUF_C_VERSION_NUMBER 1003000 + +/** + * The minimum protoc-c version which works with the current version of the + * protobuf-c headers. + */ +#define PROTOBUF_C_MIN_COMPILER_VERSION 1000000 + +/** + * Determine the number of bytes required to store the serialised message. + * + * \param message + * The message object to serialise. + * \return + * Number of bytes. + */ +PROTOBUF_C__API +size_t protobuf_c_message_get_packed_size(const ProtobufCMessage *message); + +/** + * Unpack a serialised message into an in-memory representation. + * + * \param descriptor + * The message descriptor. + * \param allocator + * `ProtobufCAllocator` to use for memory allocation. May be NULL to + * specify the default allocator. + * \param len + * Length in bytes of the serialised message. + * \param data + * Pointer to the serialised message. + * \return + * An unpacked message object. + * \retval NULL + * If an error occurred during unpacking. + */ +PROTOBUF_C__API +ProtobufCMessage *protobuf_c_message_unpack( + const ProtobufCMessageDescriptor *descriptor, ProtobufCAllocator *allocator, + size_t len, const uint8_t *data); + +/** + * Free an unpacked message object. + * + * This function should be used to deallocate the memory used by a call to + * protobuf_c_message_unpack(). + * + * \param message + * The message object to free. May be NULL. + * \param allocator + * `ProtobufCAllocator` to use for memory deallocation. May be NULL to + * specify the default allocator. + */ +PROTOBUF_C__API +void protobuf_c_message_free_unpacked(ProtobufCMessage *message, + ProtobufCAllocator *allocator); + +/** + * Check the validity of a message object. + * + * Makes sure all required fields (`PROTOBUF_C_LABEL_REQUIRED`) are present. + * Recursively checks nested messages. + * + * \retval TRUE + * Message is valid. + * \retval FALSE + * Message is invalid. + */ +PROTOBUF_C__API +protobuf_c_boolean protobuf_c_message_check(const ProtobufCMessage *); + +/** Message initialiser. */ +#define PROTOBUF_C_MESSAGE_INIT(descriptor) \ + { descriptor, 0, NULL } + +/** + * Initialise a message object from a message descriptor. + * + * \param descriptor + * Message descriptor. + * \param message + * Allocated block of memory of size `descriptor->sizeof_message`. + */ +PROTOBUF_C__API +void protobuf_c_message_init(const ProtobufCMessageDescriptor *descriptor, + void *message); + +/** + * Initialise a `ProtobufCBufferSimple` object. + */ +#define PROTOBUF_C_BUFFER_SIMPLE_INIT(array_of_bytes) \ + { \ + {protobuf_c_buffer_simple_append}, sizeof(array_of_bytes), 0, \ + (array_of_bytes), 0, NULL \ + } + +/** + * Clear a `ProtobufCBufferSimple` object, freeing any allocated memory. + */ +#define PROTOBUF_C_BUFFER_SIMPLE_CLEAR(simp_buf) \ + do { \ + if ((simp_buf)->must_free_data) { \ + if ((simp_buf)->allocator != NULL) \ + (simp_buf)->allocator->free((simp_buf)->allocator, (simp_buf)->data); \ + else \ + free((simp_buf)->data); \ + } \ + } while (0) + +/** + * The `append` method for `ProtobufCBufferSimple`. + * + * \param buffer + * The buffer object to append to. Must actually be a + * `ProtobufCBufferSimple` object. + * \param len + * Number of bytes in `data`. + * \param data + * Data to append. + */ +PROTOBUF_C__API +void protobuf_c_buffer_simple_append(ProtobufCBuffer *buffer, size_t len, + const unsigned char *data); + +/**@}*/ + +PROTOBUF_C__END_DECLS + +#endif /* PROTOBUF_C_H */ diff --git a/tools/quantification/src/tensor_desc.h b/tools/quantification/src/tensor_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..4eadf341db998ae12939d252d585051ba54c3bf0 --- /dev/null +++ b/tools/quantification/src/tensor_desc.h @@ -0,0 +1,72 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. */ + +#pragma once + +#include + +#include "src/framework.pb-c.h" + +namespace paddle_mobile { +namespace framework { + +enum VarType_Type { + VARTYPE_TYPE_BOOL = 0, + VARTYPE_TYPE_INT16 = 1, + VARTYPE_TYPE_INT32 = 2, + VARTYPE_TYPE_INT64 = 3, + VARTYPE_TYPE_FP16 = 4, + VARTYPE_TYPE_FP32 = 5, + VARTYPE_TYPE_FP64 = 6, + VARTYPE_TYPE_LOD_TENSOR = 7, + VARTYPE_TYPE_SELECTED_ROWS = 8, + VARTYPE_TYPE_FEED_MINIBATCH = 9, + VARTYPE_TYPE_FETCH_LIST = 10, + VARTYPE_TYPE_STEP_SCOPES = 11, + VARTYPE_TYPE_STEP_LOD_RANK_TABLE = 12, + VARTYPE_TYPE_STEP_LOD_TENSOR_ARRAY = 13, + VARTYPE_TYPE_STEP_PLACE_LIST = 14, + VARTYPE_TYPE_READER = 15, + VARTYPE_TYPE_CHANNEL = 16, + VARTYPE_TYPE_RAW = 17, + VARTYPE_TYPE_TUPLE = 18 +}; + +class TensorDesc { + public: + TensorDesc() = default; + TensorDesc(const TensorDesc &desc) { + this->dims_ = desc.dims_; + this->data_type_ = desc.data_type_; + } + + explicit TensorDesc( + PaddleMobile__Framework__Proto__VarType__TensorDesc *desc) { + for (int i = 0; i < desc->n_dims; ++i) { + int64_t d = desc->dims[i]; + dims_.emplace_back(d); + } + data_type_ = (VarType_Type)desc->data_type; + } + + std::vector Dims() const { return dims_; } + VarType_Type DataType() const { return data_type_; } + + private: + std::vector dims_; + VarType_Type data_type_; +}; + +} // namespace framework +} // namespace paddle_mobile diff --git a/tools/quantification/src/var_desc.h b/tools/quantification/src/var_desc.h new file mode 100644 index 0000000000000000000000000000000000000000..0b9c5ac4d672be2dd8a8a2a2695c2816f9cae05a --- /dev/null +++ b/tools/quantification/src/var_desc.h @@ -0,0 +1,80 @@ +/* Copyright (c) 2018 PaddlePaddle Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +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. */ + +#pragma once + +#include + +#include "src/framework.pb-c.h" +#include "src/tensor_desc.h" + +namespace paddle_mobile { +namespace framework { + +class VarDesc { + public: + VarDesc(const VarDesc &var_desc) { + this->data_type_ = var_desc.data_type_; + this->name_ = var_desc.name_; + this->persistable_ = var_desc.persistable_; + this->tensor_desc_ = var_desc.tensor_desc_; + this->type_ = var_desc.type_; + } + explicit VarDesc(PaddleMobile__Framework__Proto__VarDesc *desc) { + type_ = (VarType_Type)desc->type->type; + name_ = std::string(desc->name); + persistable_ = static_cast(desc->persistable); + + switch (type_) { + case VARTYPE_TYPE_SELECTED_ROWS: + tensor_desc_ = TensorDesc(desc->type->selected_rows); + break; + case VARTYPE_TYPE_LOD_TENSOR: + tensor_desc_ = TensorDesc(desc->type->lod_tensor->tensor); + break; + case VARTYPE_TYPE_STEP_LOD_TENSOR_ARRAY: + // desc->type->tensor_array->tensor->data_type; + tensor_desc_ = TensorDesc(desc->type->tensor_array->tensor); + + break; + default: + break; + } + switch (type_) { + case VARTYPE_TYPE_CHANNEL: + data_type_ = (VarType_Type)desc->type->channel->data_type; + break; + default: + data_type_ = tensor_desc_.DataType(); + break; + } + } + std::string Name() const { return name_; } + + VarType_Type Type() const { return type_; } + + bool Persistable() const { return persistable_; } + + const TensorDesc &Tensor_desc() const { return tensor_desc_; } + + private: + std::string name_; + bool persistable_; + TensorDesc tensor_desc_; + VarType_Type type_; + VarType_Type data_type_; +}; + +} // namespace framework +} // namespace paddle_mobile