// Tencent is pleased to support the open source community by making ncnn available. // // Copyright (C) 2017 THL A29 Limited, a Tencent company. All rights reserved. // // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except // in compliance with the License. You may obtain a copy of the License at // // https://opensource.org/licenses/BSD-3-Clause // // Unless required by applicable law or agreed to in writing, software distributed // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR // CONDITIONS OF ANY KIND, either express or implied. See the License for the // specific language governing permissions and limitations under the License. #include #include #include #include #include #include #include #include #include #include #include #include "graph.pb.h" static bool read_proto_from_binary(const char* filepath, google::protobuf::Message* message) { std::ifstream fs(filepath, std::ifstream::in | std::ifstream::binary); if (!fs.is_open()) { fprintf(stderr, "open failed %s\n", filepath); return false; } google::protobuf::io::IstreamInputStream input(&fs); google::protobuf::io::CodedInputStream codedstr(&input); codedstr.SetTotalBytesLimit(INT_MAX, INT_MAX / 2); bool success = message->ParseFromCodedStream(&codedstr); fs.close(); return success; } static bool find_tensor_proto(const std::map& weights, const tensorflow::NodeDef& node, tensorflow::TensorProto& tensor) { for (int j=0; j::const_iterator it = weights.find(input_name); if (it != weights.end()) { tensor = it->second; return true; } } return false; } static bool find_attr_value(const tensorflow::NodeDef& node, const char* key, tensorflow::AttrValue& value) { const google::protobuf::Map& attr = node.attr(); const google::protobuf::Map::const_iterator it = attr.find(key); if (it != attr.end()) { value = it->second; return true; } return false; } int main(int argc, char** argv) { const char* tensorflowpb = argv[1]; const char* ncnn_prototxt = argc >= 4 ? argv[2] : "ncnn.proto"; const char* ncnn_modelbin = argc >= 4 ? argv[3] : "ncnn.bin"; tensorflow::GraphDef graph; // load bool s1 = read_proto_from_binary(tensorflowpb, &graph); if (!s1) { fprintf(stderr, "read_proto_from_binary failed\n"); return -1; } FILE* pp = fopen(ncnn_prototxt, "wb"); FILE* bp = fopen(ncnn_modelbin, "wb"); int node_count = graph.node_size(); // fprintf(stderr, "node_count = %d\n\n", node_count); // node reference std::map node_reference; // mapping for Const and Const-Identity std::map weights; // Dropout like Identity std::set dropouts; // global definition line // [layer count] [blob count] std::set blob_names; for (int i=0; i::iterator it = node_reference.begin(); while (it != node_reference.end()) { if (it->second == 1) { node_reference.erase(it++); } else { splitncnn_blob_count += it->second; // fprintf(stderr, "%s %d\n", it->first.c_str(), it->second); ++it; } } fprintf(pp, "%lu %lu\n", node_count + node_reference.size() - weights.size(), blob_names.size() + splitncnn_blob_count); int internal_split = 0; for (int i=0; i(tensor.tensor_content().c_str()); weight_data_size = tensor.tensor_content().size() / sizeof(float); fwrite(data, sizeof(float), weight_data_size, bp); } else if (tensor.dtype() == 3)// int32 { const int* data = reinterpret_cast(tensor.tensor_content().c_str()); weight_data_size = tensor.tensor_content().size() / sizeof(int); float tmp; for (int i=0; i(tensor.tensor_content().c_str()); weight_data_size = tensor.tensor_content().size() / sizeof(float); float tmp; for (int p=0; p(tensor.tensor_content().c_str()); weight_data_size = tensor.tensor_content().size() / sizeof(int); float tmp; for (int p=0; p(tensor.tensor_content().c_str()); weight_data_size = tensor.tensor_content().size() / sizeof(float); float tmp; for (int p=0; p(tensor.tensor_content().c_str()); weight_data_size = tensor.tensor_content().size() / sizeof(int); float tmp; for (int p=0; p(tensor.tensor_content().c_str()); int size = tensor.tensor_content().size() / sizeof(int); // n h w c // n h w // n w if (size == 4) { fprintf(pp, " %d %d %d 0", data[2], data[1], data[3]); } if (size == 3) { fprintf(pp, " %d %d -233 1", data[2], data[1]); } if (size == 2) { fprintf(pp, " %d -233 -233 1", data[1]); } } } else { // pass through fprintf(pp, " 0 0 0"); } } else if (node.op() == "Softmax") { } else { const google::protobuf::Map& attr = node.attr(); google::protobuf::Map::const_iterator it = attr.begin(); for (; it != attr.end(); it++) { std::cerr << it->first << std::endl; std::cerr << it->second.type() << std::endl; } } fprintf(pp, "\n"); std::string output_name = node.name(); if (node_reference.find(output_name) != node_reference.end()) { int refcount = node_reference[output_name]; if (refcount > 1) { char splitname[256]; sprintf(splitname, "splitncnn_%d", internal_split); fprintf(pp, "%-16s %-16s %d %d", "Split", splitname, 1, refcount); fprintf(pp, " %s", output_name.c_str()); for (int j=0; j