Qualify uses of std::string
PiperOrigin-RevId: 316907769 Change-Id: I01c3ca5f0fb1b1b2284ae5969da968cec7493583
This commit is contained in:
parent
d8e0beacd9
commit
c870b9f920
@ -55,8 +55,8 @@ bool EndsAt(const ArrayLifespan& lifespan, std::size_t op_index) {
|
||||
// Helper function for ComputeArrayLifespans: updates one ArrayLifespan for
|
||||
// one array for one op.
|
||||
void UpdateArrayLifespan(
|
||||
const string& array_name, std::size_t op_index,
|
||||
std::unordered_map<string, ArrayLifespan>* array_lifespans) {
|
||||
const std::string& array_name, std::size_t op_index,
|
||||
std::unordered_map<std::string, ArrayLifespan>* array_lifespans) {
|
||||
if (array_lifespans->count(array_name)) {
|
||||
auto& lifespan = array_lifespans->at(array_name);
|
||||
if (!lifespan.persistent) {
|
||||
@ -74,7 +74,7 @@ void UpdateArrayLifespan(
|
||||
// Computes the ArrayLifespan for each array.
|
||||
void ComputeArrayLifespans(
|
||||
const Model& model,
|
||||
std::unordered_map<string, ArrayLifespan>* array_lifespans) {
|
||||
std::unordered_map<std::string, ArrayLifespan>* array_lifespans) {
|
||||
CHECK(array_lifespans->empty());
|
||||
for (const auto& rnn_state : model.flags.rnn_states()) {
|
||||
ArrayLifespan lifespan;
|
||||
@ -159,7 +159,8 @@ class Allocator {
|
||||
|
||||
// Returns the required transient allocation size (in bytes) for a given array,
|
||||
// or 0 if it's not a transient array.
|
||||
std::size_t TransientArraySize(const Model& model, const string& array_name,
|
||||
std::size_t TransientArraySize(const Model& model,
|
||||
const std::string& array_name,
|
||||
std::size_t transient_data_alignment) {
|
||||
if (!IsAllocatableTransientArray(model, array_name)) {
|
||||
return 0;
|
||||
@ -191,7 +192,7 @@ std::size_t TransientArraySize(const Model& model, const string& array_name,
|
||||
|
||||
// Allocates an array: call this for every array just before the first
|
||||
// op where it is used.
|
||||
void AllocateTransientArray(const Model& model, const string& array_name,
|
||||
void AllocateTransientArray(const Model& model, const std::string& array_name,
|
||||
Allocator* allocator,
|
||||
std::size_t transient_data_alignment) {
|
||||
if (!IsAllocatableTransientArray(model, array_name)) {
|
||||
@ -206,7 +207,7 @@ void AllocateTransientArray(const Model& model, const string& array_name,
|
||||
|
||||
// Deallocates an array: call this for every array just after the last
|
||||
// op where it is used.
|
||||
void DeallocateTransientArray(const Model& model, const string& array_name,
|
||||
void DeallocateTransientArray(const Model& model, const std::string& array_name,
|
||||
Allocator* allocator) {
|
||||
if (!IsAllocatableTransientArray(model, array_name)) {
|
||||
return;
|
||||
@ -216,7 +217,7 @@ void DeallocateTransientArray(const Model& model, const string& array_name,
|
||||
allocator->Deallocate(*array->alloc);
|
||||
}
|
||||
|
||||
void PushBackIfNotFound(const string& s, std::vector<string>* v) {
|
||||
void PushBackIfNotFound(const std::string& s, std::vector<std::string>* v) {
|
||||
if (std::find(v->begin(), v->end(), s) == v->end()) {
|
||||
v->push_back(s);
|
||||
}
|
||||
@ -227,7 +228,7 @@ void PushBackIfNotFound(const string& s, std::vector<string>* v) {
|
||||
void AllocateTransientArrays(Model* model,
|
||||
std::size_t transient_data_alignment) {
|
||||
// Precompute the lifespans for all arrays.
|
||||
std::unordered_map<string, ArrayLifespan> array_lifespans;
|
||||
std::unordered_map<std::string, ArrayLifespan> array_lifespans;
|
||||
ComputeArrayLifespans(*model, &array_lifespans);
|
||||
|
||||
// In case of variable batch, our convention will be to compute the
|
||||
@ -250,7 +251,7 @@ void AllocateTransientArrays(Model* model,
|
||||
|
||||
// Construct a sorted map of array names, so that other layout engines can
|
||||
// match exactly.
|
||||
std::map<string, const Array*> ordered_arrays_map;
|
||||
std::map<std::string, const Array*> ordered_arrays_map;
|
||||
for (const auto& pair : model->GetArrayMap()) {
|
||||
ordered_arrays_map[pair.first] = pair.second.get();
|
||||
}
|
||||
@ -258,7 +259,7 @@ void AllocateTransientArrays(Model* model,
|
||||
// Allocate persistent arrays (like RNN states). For them, 'transient'
|
||||
// is a misnormer, should read 'workspace'.
|
||||
for (const auto& array_pair : ordered_arrays_map) {
|
||||
const string& array_name = array_pair.first;
|
||||
const std::string& array_name = array_pair.first;
|
||||
auto it = array_lifespans.find(array_name);
|
||||
if (it != array_lifespans.end() && it->second.persistent) {
|
||||
AllocateTransientArray(*model, array_name, &allocator,
|
||||
@ -270,7 +271,7 @@ void AllocateTransientArrays(Model* model,
|
||||
op_index++) {
|
||||
const auto& op = model->operators[op_index];
|
||||
// Allocate those arrays whose lifespan starts exactly here.
|
||||
std::vector<string> arrays_to_allocate;
|
||||
std::vector<std::string> arrays_to_allocate;
|
||||
for (const auto& input : op->inputs) {
|
||||
if (StartsAt(array_lifespans[input], op_index)) {
|
||||
PushBackIfNotFound(input, &arrays_to_allocate);
|
||||
@ -281,13 +282,13 @@ void AllocateTransientArrays(Model* model,
|
||||
PushBackIfNotFound(output, &arrays_to_allocate);
|
||||
}
|
||||
}
|
||||
for (const string& array : arrays_to_allocate) {
|
||||
for (const std::string& array : arrays_to_allocate) {
|
||||
AllocateTransientArray(*model, array, &allocator,
|
||||
transient_data_alignment);
|
||||
}
|
||||
|
||||
// Deallocate those arrays whose lifespan ends exactly here.
|
||||
std::vector<string> arrays_to_deallocate;
|
||||
std::vector<std::string> arrays_to_deallocate;
|
||||
for (const auto& input : op->inputs) {
|
||||
if (EndsAt(array_lifespans[input], op_index)) {
|
||||
PushBackIfNotFound(input, &arrays_to_deallocate);
|
||||
@ -298,7 +299,7 @@ void AllocateTransientArrays(Model* model,
|
||||
PushBackIfNotFound(output, &arrays_to_deallocate);
|
||||
}
|
||||
}
|
||||
for (const string& array : arrays_to_deallocate) {
|
||||
for (const std::string& array : arrays_to_deallocate) {
|
||||
DeallocateTransientArray(*model, array, &allocator);
|
||||
}
|
||||
}
|
||||
@ -309,7 +310,7 @@ void AllocateTransientArrays(Model* model,
|
||||
std::size_t optimal_transient_alloc_size = 0;
|
||||
std::size_t persistent_alloc_size = 0;
|
||||
for (const auto& array_pair : ordered_arrays_map) {
|
||||
const string& array_name = array_pair.first;
|
||||
const std::string& array_name = array_pair.first;
|
||||
auto it = array_lifespans.find(array_name);
|
||||
if (it != array_lifespans.end() && it->second.persistent) {
|
||||
persistent_alloc_size +=
|
||||
@ -320,7 +321,7 @@ void AllocateTransientArrays(Model* model,
|
||||
// for each operator, compute the sum of the sizes of the array that must
|
||||
// be live during the execution of this operator, plus the size of
|
||||
// persistent arrays that must be live at all times.
|
||||
std::vector<string> non_persistent_edges;
|
||||
std::vector<std::string> non_persistent_edges;
|
||||
for (const auto& input : op->inputs) {
|
||||
if (!array_lifespans[input].persistent) {
|
||||
PushBackIfNotFound(input, &non_persistent_edges);
|
||||
@ -332,7 +333,7 @@ void AllocateTransientArrays(Model* model,
|
||||
}
|
||||
}
|
||||
std::size_t size = persistent_alloc_size;
|
||||
for (const string& edge : non_persistent_edges) {
|
||||
for (const std::string& edge : non_persistent_edges) {
|
||||
size += TransientArraySize(*model, edge, transient_data_alignment);
|
||||
}
|
||||
// The optimal total size is the maximum of all operator-specific sizes.
|
||||
|
@ -94,14 +94,16 @@ bool SplitStructuredLine(absl::string_view line, char delimiter,
|
||||
}
|
||||
|
||||
inline bool TryStripPrefixString(absl::string_view str,
|
||||
absl::string_view prefix, string* result) {
|
||||
absl::string_view prefix,
|
||||
std::string* result) {
|
||||
bool res = absl::ConsumePrefix(&str, prefix);
|
||||
result->assign(str.begin(), str.end());
|
||||
return res;
|
||||
}
|
||||
|
||||
inline bool TryStripSuffixString(absl::string_view str,
|
||||
absl::string_view suffix, string* result) {
|
||||
absl::string_view suffix,
|
||||
std::string* result) {
|
||||
bool res = absl::ConsumeSuffix(&str, suffix);
|
||||
result->assign(str.begin(), str.end());
|
||||
return res;
|
||||
@ -109,7 +111,7 @@ inline bool TryStripSuffixString(absl::string_view str,
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Arg<toco::IntList>::Parse(string text) {
|
||||
bool Arg<toco::IntList>::Parse(std::string text) {
|
||||
parsed_value_.elements.clear();
|
||||
specified_ = true;
|
||||
// strings::Split("") produces {""}, but we need {} on empty input.
|
||||
@ -125,7 +127,7 @@ bool Arg<toco::IntList>::Parse(string text) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Arg<toco::StringMapList>::Parse(string text) {
|
||||
bool Arg<toco::StringMapList>::Parse(std::string text) {
|
||||
parsed_value_.elements.clear();
|
||||
specified_ = true;
|
||||
|
||||
@ -138,24 +140,24 @@ bool Arg<toco::StringMapList>::Parse(string text) {
|
||||
// TODO(aselle): Change argument parsing when absl supports structuredline.
|
||||
SplitStructuredLine(text_disposable_copy, ',', "{}", &outer_vector);
|
||||
for (const absl::string_view& outer_member_stringpiece : outer_vector) {
|
||||
string outer_member(outer_member_stringpiece);
|
||||
std::string outer_member(outer_member_stringpiece);
|
||||
if (outer_member.empty()) {
|
||||
continue;
|
||||
}
|
||||
string outer_member_copy = outer_member;
|
||||
std::string outer_member_copy = outer_member;
|
||||
absl::StripAsciiWhitespace(&outer_member);
|
||||
if (!TryStripPrefixString(outer_member, "{", &outer_member)) return false;
|
||||
if (!TryStripSuffixString(outer_member, "}", &outer_member)) return false;
|
||||
const std::vector<string> inner_fields_vector =
|
||||
const std::vector<std::string> inner_fields_vector =
|
||||
absl::StrSplit(outer_member, ',');
|
||||
|
||||
std::unordered_map<string, string> element;
|
||||
for (const string& member_field : inner_fields_vector) {
|
||||
std::vector<string> outer_member_key_value =
|
||||
std::unordered_map<std::string, std::string> element;
|
||||
for (const std::string& member_field : inner_fields_vector) {
|
||||
std::vector<std::string> outer_member_key_value =
|
||||
absl::StrSplit(member_field, ':');
|
||||
if (outer_member_key_value.size() != 2) return false;
|
||||
string& key = outer_member_key_value[0];
|
||||
string& value = outer_member_key_value[1];
|
||||
std::string& key = outer_member_key_value[0];
|
||||
std::string& value = outer_member_key_value[1];
|
||||
absl::StripAsciiWhitespace(&key);
|
||||
absl::StripAsciiWhitespace(&value);
|
||||
if (element.count(key) != 0) return false;
|
||||
|
@ -35,7 +35,7 @@ struct IntList {
|
||||
std::vector<int32> elements;
|
||||
};
|
||||
struct StringMapList {
|
||||
std::vector<std::unordered_map<string, string>> elements;
|
||||
std::vector<std::unordered_map<std::string, std::string>> elements;
|
||||
};
|
||||
|
||||
// command_line_flags.h don't track whether or not a flag is specified. Arg
|
||||
@ -82,13 +82,13 @@ template <>
|
||||
class Arg<toco::IntList> final {
|
||||
public:
|
||||
// Provide default_value() to arg list
|
||||
string default_value() const { return ""; }
|
||||
std::string default_value() const { return ""; }
|
||||
// Return true if the command line argument was specified on the command line.
|
||||
bool specified() const { return specified_; }
|
||||
// Bind the parse member function so tensorflow::Flags can call it.
|
||||
bool Parse(string text);
|
||||
bool Parse(std::string text);
|
||||
|
||||
std::function<bool(string)> bind() {
|
||||
std::function<bool(std::string)> bind() {
|
||||
return std::bind(&Arg::Parse, this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
@ -103,14 +103,14 @@ template <>
|
||||
class Arg<toco::StringMapList> final {
|
||||
public:
|
||||
// Provide default_value() to StringMapList
|
||||
string default_value() const { return ""; }
|
||||
std::string default_value() const { return ""; }
|
||||
// Return true if the command line argument was specified on the command line.
|
||||
bool specified() const { return specified_; }
|
||||
// Bind the parse member function so tensorflow::Flags can call it.
|
||||
|
||||
bool Parse(string text);
|
||||
bool Parse(std::string text);
|
||||
|
||||
std::function<bool(string)> bind() {
|
||||
std::function<bool(std::string)> bind() {
|
||||
return std::bind(&Arg::Parse, this, std::placeholders::_1);
|
||||
}
|
||||
|
||||
@ -123,18 +123,18 @@ class Arg<toco::StringMapList> final {
|
||||
|
||||
// Flags that describe a model. See model_cmdline_flags.cc for details.
|
||||
struct ParsedModelFlags {
|
||||
Arg<string> input_array;
|
||||
Arg<string> input_arrays;
|
||||
Arg<string> output_array;
|
||||
Arg<string> output_arrays;
|
||||
Arg<string> input_shapes;
|
||||
Arg<std::string> input_array;
|
||||
Arg<std::string> input_arrays;
|
||||
Arg<std::string> output_array;
|
||||
Arg<std::string> output_arrays;
|
||||
Arg<std::string> input_shapes;
|
||||
Arg<int> batch_size = Arg<int>(1);
|
||||
Arg<float> mean_value = Arg<float>(0.f);
|
||||
Arg<string> mean_values;
|
||||
Arg<std::string> mean_values;
|
||||
Arg<float> std_value = Arg<float>(1.f);
|
||||
Arg<string> std_values;
|
||||
Arg<string> input_data_type;
|
||||
Arg<string> input_data_types;
|
||||
Arg<std::string> std_values;
|
||||
Arg<std::string> input_data_type;
|
||||
Arg<std::string> input_data_types;
|
||||
Arg<bool> variable_batch = Arg<bool>(false);
|
||||
Arg<toco::IntList> input_shape;
|
||||
Arg<toco::StringMapList> rnn_states;
|
||||
@ -142,44 +142,44 @@ struct ParsedModelFlags {
|
||||
Arg<bool> change_concat_input_ranges = Arg<bool>(true);
|
||||
// Debugging output options.
|
||||
// TODO(benoitjacob): these shouldn't be ModelFlags.
|
||||
Arg<string> graphviz_first_array;
|
||||
Arg<string> graphviz_last_array;
|
||||
Arg<string> dump_graphviz;
|
||||
Arg<std::string> graphviz_first_array;
|
||||
Arg<std::string> graphviz_last_array;
|
||||
Arg<std::string> dump_graphviz;
|
||||
Arg<bool> dump_graphviz_video = Arg<bool>(false);
|
||||
Arg<string> conversion_summary_dir;
|
||||
Arg<std::string> conversion_summary_dir;
|
||||
Arg<bool> allow_nonexistent_arrays = Arg<bool>(false);
|
||||
Arg<bool> allow_nonascii_arrays = Arg<bool>(false);
|
||||
Arg<string> arrays_extra_info_file;
|
||||
Arg<string> model_flags_file;
|
||||
Arg<std::string> arrays_extra_info_file;
|
||||
Arg<std::string> model_flags_file;
|
||||
};
|
||||
|
||||
// Flags that describe the operation you would like to do (what conversion
|
||||
// you want). See toco_cmdline_flags.cc for details.
|
||||
struct ParsedTocoFlags {
|
||||
Arg<string> input_file;
|
||||
Arg<string> savedmodel_directory;
|
||||
Arg<string> output_file;
|
||||
Arg<string> input_format = Arg<string>("TENSORFLOW_GRAPHDEF");
|
||||
Arg<string> output_format = Arg<string>("TFLITE");
|
||||
Arg<string> savedmodel_tagset;
|
||||
Arg<std::string> input_file;
|
||||
Arg<std::string> savedmodel_directory;
|
||||
Arg<std::string> output_file;
|
||||
Arg<std::string> input_format = Arg<std::string>("TENSORFLOW_GRAPHDEF");
|
||||
Arg<std::string> output_format = Arg<std::string>("TFLITE");
|
||||
Arg<std::string> savedmodel_tagset;
|
||||
// TODO(aselle): command_line_flags doesn't support doubles
|
||||
Arg<float> default_ranges_min = Arg<float>(0.);
|
||||
Arg<float> default_ranges_max = Arg<float>(0.);
|
||||
Arg<float> default_int16_ranges_min = Arg<float>(0.);
|
||||
Arg<float> default_int16_ranges_max = Arg<float>(0.);
|
||||
Arg<string> inference_type;
|
||||
Arg<string> inference_input_type;
|
||||
Arg<std::string> inference_type;
|
||||
Arg<std::string> inference_input_type;
|
||||
Arg<bool> drop_fake_quant = Arg<bool>(false);
|
||||
Arg<bool> reorder_across_fake_quant = Arg<bool>(false);
|
||||
Arg<bool> allow_custom_ops = Arg<bool>(false);
|
||||
Arg<bool> allow_dynamic_tensors = Arg<bool>(true);
|
||||
Arg<string> custom_opdefs;
|
||||
Arg<std::string> custom_opdefs;
|
||||
Arg<bool> post_training_quantize = Arg<bool>(false);
|
||||
Arg<bool> quantize_to_float16 = Arg<bool>(false);
|
||||
// Deprecated flags
|
||||
Arg<bool> quantize_weights = Arg<bool>(false);
|
||||
Arg<string> input_type;
|
||||
Arg<string> input_types;
|
||||
Arg<std::string> input_type;
|
||||
Arg<std::string> input_types;
|
||||
Arg<bool> debug_disable_recurrent_cell_fusion = Arg<bool>(false);
|
||||
Arg<bool> drop_control_dependency = Arg<bool>(false);
|
||||
Arg<bool> propagate_fake_quant_num_bits = Arg<bool>(false);
|
||||
|
@ -77,7 +77,9 @@ class Color {
|
||||
|
||||
// Returns the string serialization of this color in graphviz format,
|
||||
// for use as 'fillcolor' in boxes.
|
||||
string AsHexString() const { return StringF("#%.2X%.2X%.2X", r_, g_, b_); }
|
||||
std::string AsHexString() const {
|
||||
return StringF("#%.2X%.2X%.2X", r_, g_, b_);
|
||||
}
|
||||
// The color to use for this node; will be used as 'fillcolor'
|
||||
// for its box. See Color::AsHexString. A suitable, different
|
||||
// color will be chosen for the 'fontcolor' for the inside text
|
||||
@ -85,7 +87,7 @@ class Color {
|
||||
// Returns the serialization in graphviz format of a suitable color to use
|
||||
// 'fontcolor' in the same boxes. It should black or white, whichever offers
|
||||
// the better contrast from AsHexString().
|
||||
string TextColorString() const {
|
||||
std::string TextColorString() const {
|
||||
// https://en.wikipedia.org/wiki/Relative_luminance
|
||||
const float luminance = 0.2126f * r_ + 0.7152f * g_ + 0.0722f * b_;
|
||||
const uint8 l = luminance > 128.f ? 0 : 255;
|
||||
@ -96,7 +98,7 @@ class Color {
|
||||
uint8 r_ = 0, g_ = 0, b_ = 0;
|
||||
};
|
||||
|
||||
Color HashStringToColor(string s) {
|
||||
Color HashStringToColor(std::string s) {
|
||||
// Return a unique color for a name.
|
||||
//
|
||||
// This function removes Tensorflow anti-collision suffixes (eg "_2"), hashes
|
||||
@ -120,8 +122,8 @@ Color HashStringToColor(string s) {
|
||||
return Color(color_word);
|
||||
}
|
||||
|
||||
void GetArrayColorAndShape(const Model& model, const string& array_name,
|
||||
Color* color, string* shape) {
|
||||
void GetArrayColorAndShape(const Model& model, const std::string& array_name,
|
||||
Color* color, std::string* shape) {
|
||||
// All colors in this file are from:
|
||||
// https://material.io/guidelines/style/color.html
|
||||
// Arrays involved in RNN back-edges have a different color
|
||||
@ -167,7 +169,8 @@ void GetArrayColorAndShape(const Model& model, const string& array_name,
|
||||
*shape = "box";
|
||||
}
|
||||
|
||||
string GetArrayCompassPt(const Model& model, const string& array_name) {
|
||||
std::string GetArrayCompassPt(const Model& model,
|
||||
const std::string& array_name) {
|
||||
// The "compass point" is the point on the node where edge connections are
|
||||
// made. For most arrays we don't care, but input's and outputs look better
|
||||
// connected at the tip of the "house" and "invhouse" shapes used. So we
|
||||
@ -191,7 +194,7 @@ string GetArrayCompassPt(const Model& model, const string& array_name) {
|
||||
return "";
|
||||
}
|
||||
|
||||
void AppendArrayVal(string* string, Array const& array, int index) {
|
||||
void AppendArrayVal(std::string* string, Array const& array, int index) {
|
||||
if (array.buffer->type == ArrayDataType::kFloat) {
|
||||
const auto& data = array.GetBuffer<ArrayDataType::kFloat>().data;
|
||||
if (index >= data.size()) {
|
||||
@ -231,10 +234,10 @@ void AppendArrayVal(string* string, Array const& array, int index) {
|
||||
}
|
||||
}
|
||||
|
||||
typedef std::map<string, string> Attributes;
|
||||
typedef std::map<std::string, std::string> Attributes;
|
||||
|
||||
string AttributesToHtml(Attributes attributes) {
|
||||
string html;
|
||||
std::string AttributesToHtml(Attributes attributes) {
|
||||
std::string html;
|
||||
for (const auto& attr : attributes) {
|
||||
html += R"CODE(<TR><TD CELLPADDING="1" ALIGN="RIGHT">)CODE";
|
||||
html += attr.first;
|
||||
@ -245,8 +248,8 @@ string AttributesToHtml(Attributes attributes) {
|
||||
return html;
|
||||
}
|
||||
|
||||
string GetArrayLabel(const Model& model, const string& array_id) {
|
||||
string html;
|
||||
std::string GetArrayLabel(const Model& model, const std::string& array_id) {
|
||||
std::string html;
|
||||
|
||||
// Use HTML-like labels (http://www.graphviz.org/doc/info/shapes.html#html)
|
||||
html += "<";
|
||||
@ -265,7 +268,7 @@ string GetArrayLabel(const Model& model, const string& array_id) {
|
||||
html += R"CODE(<TR><TD COLSPAN="2" ALIGN="CENTER">)CODE";
|
||||
html += R"CODE(<FONT POINT-SIZE="16" FACE="Helvetica"><I>)CODE";
|
||||
AppendF(&html, R"CODE(%s)CODE",
|
||||
std::vector<string>(absl::StrSplit(array_id, '/')).back());
|
||||
std::vector<std::string>(absl::StrSplit(array_id, '/')).back());
|
||||
html += R"CODE(</I></FONT>)CODE";
|
||||
html += "</TD></TR>";
|
||||
|
||||
@ -371,7 +374,7 @@ Attributes GetOpAttributes(const Model& model, const Operator& op) {
|
||||
switch (op.type) {
|
||||
case OperatorType::kConv: {
|
||||
const auto& conv_op = static_cast<const ConvOperator&>(op);
|
||||
string stride;
|
||||
std::string stride;
|
||||
AppendF(&stride, "%d", conv_op.stride_width);
|
||||
stride += kUnicodeMult;
|
||||
AppendF(&stride, "%d", conv_op.stride_height);
|
||||
@ -382,7 +385,7 @@ Attributes GetOpAttributes(const Model& model, const Operator& op) {
|
||||
}
|
||||
case OperatorType::kDepthwiseConv: {
|
||||
const auto& depthconv_op = static_cast<const ConvOperator&>(op);
|
||||
string stride;
|
||||
std::string stride;
|
||||
AppendF(&stride, "%d", depthconv_op.stride_width);
|
||||
stride += kUnicodeMult;
|
||||
AppendF(&stride, "%d", depthconv_op.stride_height);
|
||||
@ -426,9 +429,9 @@ Color GetOpColor(const Operator& op) {
|
||||
}
|
||||
}
|
||||
|
||||
string GetOpLabel(const Model& model, const Operator& op) {
|
||||
std::string GetOpLabel(const Model& model, const Operator& op) {
|
||||
// Use HTML-like labels (http://www.graphviz.org/doc/info/shapes.html#html)
|
||||
string html;
|
||||
std::string html;
|
||||
html += "<";
|
||||
|
||||
// Begin Table
|
||||
@ -462,7 +465,8 @@ string GetOpLabel(const Model& model, const Operator& op) {
|
||||
if (op.type == OperatorType::kUnsupported) {
|
||||
html += static_cast<const TensorFlowUnsupportedOperator&>(op).tensorflow_op;
|
||||
} else {
|
||||
html += string(absl::StripPrefix(OperatorTypeName(op.type), "TensorFlow"));
|
||||
html +=
|
||||
std::string(absl::StripPrefix(OperatorTypeName(op.type), "TensorFlow"));
|
||||
}
|
||||
html += R"CODE(</B></FONT>)CODE";
|
||||
html += "</TD></TR>";
|
||||
@ -498,7 +502,7 @@ string GetOpLabel(const Model& model, const Operator& op) {
|
||||
return html;
|
||||
}
|
||||
|
||||
float GetLog2BufferSize(const Model& model, const string& array_id) {
|
||||
float GetLog2BufferSize(const Model& model, const std::string& array_id) {
|
||||
auto& array = model.GetArray(array_id);
|
||||
if (array.has_shape()) {
|
||||
int buffer_size = 0;
|
||||
@ -510,22 +514,23 @@ float GetLog2BufferSize(const Model& model, const string& array_id) {
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
string GetOpId(int op_index) { return StringF("op%05d", op_index); }
|
||||
std::string GetOpId(int op_index) { return StringF("op%05d", op_index); }
|
||||
|
||||
void DumpOperator(const Model& model, string* output_file, int op_index) {
|
||||
void DumpOperator(const Model& model, std::string* output_file, int op_index) {
|
||||
// Dump node for operator.
|
||||
const Operator& op = *model.operators[op_index];
|
||||
Color color = GetOpColor(op);
|
||||
string label = GetOpLabel(model, op);
|
||||
string op_id = GetOpId(op_index);
|
||||
std::string label = GetOpLabel(model, op);
|
||||
std::string op_id = GetOpId(op_index);
|
||||
AppendF(output_file, kOpNodeFmt, op_id, label, color.AsHexString(),
|
||||
color.TextColorString());
|
||||
}
|
||||
|
||||
void DumpOperatorEdges(const Model& model, string* output_file, int op_index) {
|
||||
void DumpOperatorEdges(const Model& model, std::string* output_file,
|
||||
int op_index) {
|
||||
// Inputs
|
||||
const Operator& op = *model.operators[op_index];
|
||||
string op_id = GetOpId(op_index);
|
||||
std::string op_id = GetOpId(op_index);
|
||||
for (int i = 0; i < op.inputs.size(); i++) {
|
||||
const auto& input = op.inputs[i];
|
||||
if (!model.HasArray(input)) {
|
||||
@ -546,7 +551,7 @@ void DumpOperatorEdges(const Model& model, string* output_file, int op_index) {
|
||||
// would otherwise skew the layout.
|
||||
weight = 1.0f;
|
||||
}
|
||||
string compass_pt = GetArrayCompassPt(model, input);
|
||||
std::string compass_pt = GetArrayCompassPt(model, input);
|
||||
AppendF(output_file, kInputEdgeFmt, input, compass_pt, op_id, i, line_width,
|
||||
weight);
|
||||
}
|
||||
@ -563,7 +568,7 @@ void DumpOperatorEdges(const Model& model, string* output_file, int op_index) {
|
||||
if (!IsArrayConsumed(model, output)) {
|
||||
weight = 1.0f;
|
||||
}
|
||||
string compass_pt = GetArrayCompassPt(model, output);
|
||||
std::string compass_pt = GetArrayCompassPt(model, output);
|
||||
AppendF(output_file, kOutputEdgeFmt, op_id, i, output, compass_pt,
|
||||
line_width, weight);
|
||||
}
|
||||
@ -572,19 +577,19 @@ void DumpOperatorEdges(const Model& model, string* output_file, int op_index) {
|
||||
struct Node {
|
||||
Node() : math_ops(0) {}
|
||||
// Name used as a key in the model's array map
|
||||
string array_id;
|
||||
std::string array_id;
|
||||
|
||||
// Estimated number of math ops incurred by this node (the sum of the op
|
||||
// with this array as 1st output, plus all children nodes).
|
||||
int64 math_ops;
|
||||
|
||||
// A map of child nodes keyed by name.
|
||||
std::map<const string, std::unique_ptr<Node>> children;
|
||||
std::map<const std::string, std::unique_ptr<Node>> children;
|
||||
};
|
||||
|
||||
string GetSubgraphLabel(Node const& node, const string& subgraph) {
|
||||
std::string GetSubgraphLabel(Node const& node, const std::string& subgraph) {
|
||||
// Use HTML-like labels (http://www.graphviz.org/doc/info/shapes.html#html)
|
||||
string html;
|
||||
std::string html;
|
||||
html += "<";
|
||||
|
||||
// Begin Table
|
||||
@ -613,19 +618,19 @@ string GetSubgraphLabel(Node const& node, const string& subgraph) {
|
||||
return html;
|
||||
}
|
||||
|
||||
void DumpSubgraphHeader(string* output_file, Node const& node,
|
||||
const string& node_name) {
|
||||
void DumpSubgraphHeader(std::string* output_file, Node const& node,
|
||||
const std::string& node_name) {
|
||||
Color color = HashStringToColor(node_name);
|
||||
string label = GetSubgraphLabel(node, node_name);
|
||||
std::string label = GetSubgraphLabel(node, node_name);
|
||||
AppendF(output_file, kSubgraphFmt, node_name, color.AsHexString(), label);
|
||||
}
|
||||
|
||||
void DumpArray(const Model& model, string* output_file,
|
||||
const string& array_id) {
|
||||
void DumpArray(const Model& model, std::string* output_file,
|
||||
const std::string& array_id) {
|
||||
Color color;
|
||||
string shape;
|
||||
std::string shape;
|
||||
GetArrayColorAndShape(model, array_id, &color, &shape);
|
||||
string label = GetArrayLabel(model, array_id);
|
||||
std::string label = GetArrayLabel(model, array_id);
|
||||
AppendF(output_file, kArrayNodeFmt, array_id, label, array_id, shape,
|
||||
color.AsHexString(), color.TextColorString());
|
||||
|
||||
@ -638,8 +643,8 @@ void DumpArray(const Model& model, string* output_file,
|
||||
}
|
||||
}
|
||||
|
||||
void DumpNode(const Model& model, string* output_file, const string& node_name,
|
||||
Node const& node) {
|
||||
void DumpNode(const Model& model, std::string* output_file,
|
||||
const std::string& node_name, Node const& node) {
|
||||
bool not_root = !node_name.empty();
|
||||
if (not_root) {
|
||||
DumpSubgraphHeader(output_file, node, node_name);
|
||||
@ -662,7 +667,7 @@ void DumpNode(const Model& model, string* output_file, const string& node_name,
|
||||
}
|
||||
}
|
||||
|
||||
int64 GetArithmeticOpsCount(const Model& model, const string& array_id) {
|
||||
int64 GetArithmeticOpsCount(const Model& model, const std::string& array_id) {
|
||||
for (const auto& op : model.operators) {
|
||||
if (!op->outputs.empty() && op->outputs[0] == array_id) {
|
||||
int64 count;
|
||||
@ -676,15 +681,15 @@ int64 GetArithmeticOpsCount(const Model& model, const string& array_id) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void InsertNode(const Model& model, const string& array_id, Node* node,
|
||||
std::vector<string> prefixes, int64* math_ops) {
|
||||
void InsertNode(const Model& model, const std::string& array_id, Node* node,
|
||||
std::vector<std::string> prefixes, int64* math_ops) {
|
||||
if (prefixes.empty()) {
|
||||
// Base case: store array in this node.
|
||||
node->array_id = array_id;
|
||||
*math_ops = GetArithmeticOpsCount(model, array_id);
|
||||
} else {
|
||||
// Insert into the sub-tree for that prefix.
|
||||
string prefix = prefixes.back();
|
||||
std::string prefix = prefixes.back();
|
||||
prefixes.pop_back();
|
||||
if (node->children.count(prefix) == 0) {
|
||||
// Create a new node if this prefix is unseen.
|
||||
@ -700,16 +705,16 @@ void InsertNode(const Model& model, const string& array_id, Node* node,
|
||||
void BuildArrayTree(const Model& model, Node* tree) {
|
||||
// Delimit array names by path "/", then place into a tree based on this path.
|
||||
for (const auto& array_id : model.GetArrayMap()) {
|
||||
std::vector<string> prefixes = absl::StrSplit(array_id.first, '/');
|
||||
std::vector<std::string> prefixes = absl::StrSplit(array_id.first, '/');
|
||||
std::reverse(prefixes.begin(), prefixes.end());
|
||||
int64 math_ops; // Temporary storage for math ops used during recursion.
|
||||
InsertNode(model, array_id.first, tree, prefixes, &math_ops);
|
||||
}
|
||||
}
|
||||
|
||||
string GetGraphLabel(const Model& model, const string& graph_name) {
|
||||
std::string GetGraphLabel(const Model& model, const std::string& graph_name) {
|
||||
// Use HTML-like labels (http://www.graphviz.org/doc/info/shapes.html#html)
|
||||
string html;
|
||||
std::string html;
|
||||
html += "<";
|
||||
|
||||
// Begin Table
|
||||
@ -753,8 +758,8 @@ string GetGraphLabel(const Model& model, const string& graph_name) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void DumpGraphviz(const Model& model, string* output_file,
|
||||
const string& graph_name) {
|
||||
void DumpGraphviz(const Model& model, std::string* output_file,
|
||||
const std::string& graph_name) {
|
||||
// Start graphviz format
|
||||
AppendF(output_file, kGraphFmt, GetGraphLabel(model, graph_name));
|
||||
|
||||
|
@ -21,8 +21,8 @@ limitations under the License.
|
||||
|
||||
namespace toco {
|
||||
|
||||
void DumpGraphviz(const Model& model, string* output_file_contents,
|
||||
const string& graph_name);
|
||||
void DumpGraphviz(const Model& model, std::string* output_file_contents,
|
||||
const std::string& graph_name);
|
||||
|
||||
} // namespace toco
|
||||
|
||||
|
@ -49,7 +49,7 @@ namespace toco {
|
||||
namespace {
|
||||
|
||||
tensorflow::DataType GetTensorFlowDataType(ArrayDataType data_type,
|
||||
const string& error_location) {
|
||||
const std::string& error_location) {
|
||||
switch (data_type) {
|
||||
case ArrayDataType::kBool:
|
||||
return tensorflow::DT_BOOL;
|
||||
@ -74,12 +74,12 @@ tensorflow::DataType GetTensorFlowDataType(ArrayDataType data_type,
|
||||
}
|
||||
|
||||
tensorflow::DataType GetTensorFlowDataTypeForOp(ArrayDataType data_type,
|
||||
const string& op_name) {
|
||||
const std::string& op_name) {
|
||||
return GetTensorFlowDataType(data_type, "op '" + op_name + "'");
|
||||
}
|
||||
|
||||
tensorflow::DataType GetTensorFlowDataType(const Model& model,
|
||||
const string& array_name) {
|
||||
const std::string& array_name) {
|
||||
return GetTensorFlowDataType(model.GetArray(array_name).data_type,
|
||||
"array '" + array_name + "'");
|
||||
}
|
||||
@ -113,8 +113,8 @@ void ExportFloatArray(const Shape& input_shape, const float* input_data,
|
||||
}
|
||||
}
|
||||
output_tensor->set_tensor_content(
|
||||
string(reinterpret_cast<const char*>(input_data),
|
||||
sizeof(*input_data) * input_flat_size));
|
||||
std::string(reinterpret_cast<const char*>(input_data),
|
||||
sizeof(*input_data) * input_flat_size));
|
||||
}
|
||||
|
||||
void ExportFloatArray(AxesOrder input_axes_order, const Shape& input_shape,
|
||||
@ -137,7 +137,7 @@ void ExportFloatArray(AxesOrder input_axes_order, const Shape& input_shape,
|
||||
legacy_scalar_policy);
|
||||
}
|
||||
|
||||
bool HasAlreadyExportedConst(const string& name,
|
||||
bool HasAlreadyExportedConst(const std::string& name,
|
||||
const GraphDef& tensorflow_graph) {
|
||||
for (const auto& node : tensorflow_graph.node()) {
|
||||
if (node.op() == "Const" && node.name() == name) {
|
||||
@ -147,7 +147,7 @@ bool HasAlreadyExportedConst(const string& name,
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConvertFloatTensorConst(const string& name, const Shape& input_shape,
|
||||
void ConvertFloatTensorConst(const std::string& name, const Shape& input_shape,
|
||||
const float* input_data,
|
||||
AxesOrder input_axes_order,
|
||||
AxesOrder output_axes_order,
|
||||
@ -165,7 +165,7 @@ void ConvertFloatTensorConst(const string& name, const Shape& input_shape,
|
||||
tensor, legacy_scalar_policy);
|
||||
}
|
||||
|
||||
void ConvertFloatTensorConst(const string& name, const Shape& input_shape,
|
||||
void ConvertFloatTensorConst(const std::string& name, const Shape& input_shape,
|
||||
const float* input_data,
|
||||
AxesOrder input_axes_order,
|
||||
AxesOrder output_axes_order,
|
||||
@ -175,7 +175,7 @@ void ConvertFloatTensorConst(const string& name, const Shape& input_shape,
|
||||
LegacyScalarPolicy::kAvoidLegacyScalars);
|
||||
}
|
||||
|
||||
void ConvertFloatTensorConst(const Model& model, const string& name,
|
||||
void ConvertFloatTensorConst(const Model& model, const std::string& name,
|
||||
AxesOrder input_axes_order,
|
||||
AxesOrder output_axes_order,
|
||||
GraphDef* tensorflow_graph) {
|
||||
@ -193,7 +193,7 @@ void ConvertFloatTensorConst(const Model& model, const string& name,
|
||||
output_axes_order, tensorflow_graph);
|
||||
}
|
||||
|
||||
void ConvertFloatTensorConst(const Model& model, const string& name,
|
||||
void ConvertFloatTensorConst(const Model& model, const std::string& name,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
return;
|
||||
@ -214,7 +214,7 @@ void ConvertFloatTensorConst(const Model& model, const string& name,
|
||||
LegacyScalarPolicy::kAvoidLegacyScalars);
|
||||
}
|
||||
|
||||
void ConvertBoolTensorConst(const Model& model, const string& name,
|
||||
void ConvertBoolTensorConst(const Model& model, const std::string& name,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
return;
|
||||
@ -238,7 +238,7 @@ void ConvertBoolTensorConst(const Model& model, const string& name,
|
||||
}
|
||||
}
|
||||
|
||||
void ConvertIntTensorConst(const Model& model, const string& name,
|
||||
void ConvertIntTensorConst(const Model& model, const std::string& name,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
return;
|
||||
@ -262,7 +262,8 @@ void ConvertIntTensorConst(const Model& model, const string& name,
|
||||
}
|
||||
}
|
||||
|
||||
void CreateIntTensorConst(const string& name, const std::vector<int32>& data,
|
||||
void CreateIntTensorConst(const std::string& name,
|
||||
const std::vector<int32>& data,
|
||||
const std::vector<int32>& shape,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
@ -286,7 +287,7 @@ void CreateIntTensorConst(const string& name, const std::vector<int32>& data,
|
||||
CHECK_EQ(num_elements, data.size());
|
||||
}
|
||||
|
||||
void ConvertComplex64TensorConst(const Model& model, const string& name,
|
||||
void ConvertComplex64TensorConst(const Model& model, const std::string& name,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
return;
|
||||
@ -311,7 +312,7 @@ void ConvertComplex64TensorConst(const Model& model, const string& name,
|
||||
}
|
||||
}
|
||||
|
||||
void CreateMatrixShapeTensorConst(const string& name, int rows, int cols,
|
||||
void CreateMatrixShapeTensorConst(const std::string& name, int rows, int cols,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
return;
|
||||
@ -324,12 +325,12 @@ void CreateMatrixShapeTensorConst(const string& name, int rows, int cols,
|
||||
tensor->set_dtype(DT_INT32);
|
||||
const int32 data[2] = {cols, rows};
|
||||
tensor->set_tensor_content(
|
||||
string(reinterpret_cast<const char*>(data), sizeof(data)));
|
||||
std::string(reinterpret_cast<const char*>(data), sizeof(data)));
|
||||
auto* shape = tensor->mutable_tensor_shape();
|
||||
shape->add_dim()->set_size(2);
|
||||
}
|
||||
|
||||
void CreateDummyConcatDimTensorConst(const string& name, int dim,
|
||||
void CreateDummyConcatDimTensorConst(const std::string& name, int dim,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
return;
|
||||
@ -343,7 +344,7 @@ void CreateDummyConcatDimTensorConst(const string& name, int dim,
|
||||
tensor->add_int_val(dim);
|
||||
}
|
||||
|
||||
void CreateReshapeShapeTensorConst(const string& name,
|
||||
void CreateReshapeShapeTensorConst(const std::string& name,
|
||||
const std::vector<int32>& shape,
|
||||
GraphDef* tensorflow_graph) {
|
||||
if (HasAlreadyExportedConst(name, *tensorflow_graph)) {
|
||||
@ -367,7 +368,7 @@ void CreateReshapeShapeTensorConst(const string& name,
|
||||
}
|
||||
}
|
||||
|
||||
string WalkUpToConstantArray(const Model& model, const string& name) {
|
||||
std::string WalkUpToConstantArray(const Model& model, const std::string& name) {
|
||||
const Array& original_array = model.GetArray(name);
|
||||
if (original_array.buffer) {
|
||||
return name;
|
||||
@ -375,7 +376,7 @@ string WalkUpToConstantArray(const Model& model, const string& name) {
|
||||
const auto* op = GetOpWithOutput(model, name);
|
||||
CHECK(op);
|
||||
CHECK(op->type == OperatorType::kFakeQuant);
|
||||
const string& input_of_fakequant_name = op->inputs[0];
|
||||
const std::string& input_of_fakequant_name = op->inputs[0];
|
||||
const Array& input_of_fakequant = model.GetArray(input_of_fakequant_name);
|
||||
CHECK(input_of_fakequant.buffer);
|
||||
return input_of_fakequant_name;
|
||||
@ -384,7 +385,7 @@ string WalkUpToConstantArray(const Model& model, const string& name) {
|
||||
void ConvertConvOperator(const Model& model, const ConvOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
const bool has_bias = src_op.inputs.size() >= 3;
|
||||
string conv_output = src_op.outputs[0];
|
||||
std::string conv_output = src_op.outputs[0];
|
||||
if (has_bias) {
|
||||
conv_output += "/conv";
|
||||
}
|
||||
@ -395,7 +396,7 @@ void ConvertConvOperator(const Model& model, const ConvOperator& src_op,
|
||||
*conv2d_op->add_input() = src_op.inputs[0];
|
||||
*conv2d_op->add_input() = src_op.inputs[1];
|
||||
(*conv2d_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
const string& weights_array_name =
|
||||
const std::string& weights_array_name =
|
||||
WalkUpToConstantArray(model, src_op.inputs[1]);
|
||||
const auto& weights_array = model.GetArray(weights_array_name);
|
||||
CHECK(weights_array.buffer->type == ArrayDataType::kFloat);
|
||||
@ -414,7 +415,7 @@ void ConvertConvOperator(const Model& model, const ConvOperator& src_op,
|
||||
dilations.mutable_list()->add_i(src_op.dilation_width_factor);
|
||||
dilations.mutable_list()->add_i(1);
|
||||
}
|
||||
string padding;
|
||||
std::string padding;
|
||||
if (src_op.padding.type == PaddingType::kSame) {
|
||||
padding = "SAME";
|
||||
} else if (src_op.padding.type == PaddingType::kValid) {
|
||||
@ -432,7 +433,7 @@ void ConvertConvOperator(const Model& model, const ConvOperator& src_op,
|
||||
biasadd_op->add_input(src_op.inputs[2]);
|
||||
(*biasadd_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
CHECK(model.HasArray(src_op.inputs[2]));
|
||||
const string& bias_array_name =
|
||||
const std::string& bias_array_name =
|
||||
WalkUpToConstantArray(model, src_op.inputs[2]);
|
||||
const auto& bias_array = model.GetArray(bias_array_name);
|
||||
// TODO(b/62904716) Bias arrays should be 1-D, and used directly.
|
||||
@ -452,7 +453,7 @@ void ConvertDepthwiseConvOperator(const Model& model,
|
||||
const DepthwiseConvOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
const bool has_bias = src_op.inputs.size() >= 3;
|
||||
string conv_output = src_op.outputs[0];
|
||||
std::string conv_output = src_op.outputs[0];
|
||||
if (has_bias) {
|
||||
conv_output += "/conv";
|
||||
}
|
||||
@ -469,7 +470,7 @@ void ConvertDepthwiseConvOperator(const Model& model,
|
||||
// That's only a matter of constructing a Dims object; the actual
|
||||
// array layout is the same.
|
||||
CHECK(model.HasArray(src_op.inputs[1]));
|
||||
const string& src_weights_name =
|
||||
const std::string& src_weights_name =
|
||||
WalkUpToConstantArray(model, src_op.inputs[1]);
|
||||
const auto& src_weights_array = model.GetArray(src_weights_name);
|
||||
const auto& src_weights_shape = src_weights_array.shape();
|
||||
@ -505,7 +506,7 @@ void ConvertDepthwiseConvOperator(const Model& model,
|
||||
dilations.mutable_list()->add_i(src_op.dilation_width_factor);
|
||||
dilations.mutable_list()->add_i(1);
|
||||
}
|
||||
string padding;
|
||||
std::string padding;
|
||||
if (src_op.padding.type == PaddingType::kSame) {
|
||||
padding = "SAME";
|
||||
} else if (src_op.padding.type == PaddingType::kValid) {
|
||||
@ -523,7 +524,8 @@ void ConvertDepthwiseConvOperator(const Model& model,
|
||||
biasadd_op->add_input(src_op.inputs[2]);
|
||||
(*biasadd_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
CHECK(model.HasArray(src_op.inputs[2]));
|
||||
const string& bias_name = WalkUpToConstantArray(model, src_op.inputs[2]);
|
||||
const std::string& bias_name =
|
||||
WalkUpToConstantArray(model, src_op.inputs[2]);
|
||||
const auto& bias_array = model.GetArray(bias_name);
|
||||
// TODO(b/62904716) Bias arrays should be 1-D, and used directly.
|
||||
Shape bias_shape_1d = bias_array.shape();
|
||||
@ -548,7 +550,7 @@ void ConvertTransposeConvOperator(const Model& model,
|
||||
*conv2d_op->add_input() = src_op.inputs[1];
|
||||
*conv2d_op->add_input() = src_op.inputs[2];
|
||||
(*conv2d_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
const string& weights_array_name = WalkUpToConstantArray(
|
||||
const std::string& weights_array_name = WalkUpToConstantArray(
|
||||
model, src_op.inputs[TransposeConvOperator::WEIGHTS]);
|
||||
const auto& weights_array = model.GetArray(weights_array_name);
|
||||
CHECK(weights_array.buffer->type == ArrayDataType::kFloat);
|
||||
@ -559,7 +561,7 @@ void ConvertTransposeConvOperator(const Model& model,
|
||||
strides.mutable_list()->add_i(src_op.stride_height);
|
||||
strides.mutable_list()->add_i(src_op.stride_width);
|
||||
strides.mutable_list()->add_i(1);
|
||||
string padding;
|
||||
std::string padding;
|
||||
if (src_op.padding.type == PaddingType::kSame) {
|
||||
padding = "SAME";
|
||||
} else if (src_op.padding.type == PaddingType::kValid) {
|
||||
@ -596,9 +598,9 @@ void ConvertFullyConnectedOperator(const Model& model,
|
||||
const FullyConnectedOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
// Reshape input activations to have the shape expected by the MatMul.
|
||||
const string reshape_output =
|
||||
const std::string reshape_output =
|
||||
AvailableArrayName(model, src_op.outputs[0] + "/reshape");
|
||||
const string reshape_shape =
|
||||
const std::string reshape_shape =
|
||||
AvailableArrayName(model, reshape_output + "/shape");
|
||||
const auto& fc_weights_array = model.GetArray(src_op.inputs[1]);
|
||||
const auto& fc_weights_shape = fc_weights_array.shape();
|
||||
@ -614,7 +616,7 @@ void ConvertFullyConnectedOperator(const Model& model,
|
||||
GetTensorFlowDataType(model, src_op.inputs[0]));
|
||||
|
||||
const bool has_bias = src_op.inputs.size() >= 3;
|
||||
string matmul_output = src_op.outputs[0];
|
||||
std::string matmul_output = src_op.outputs[0];
|
||||
if (has_bias) {
|
||||
matmul_output += "/matmul";
|
||||
}
|
||||
@ -622,9 +624,9 @@ void ConvertFullyConnectedOperator(const Model& model,
|
||||
// Transpose the RHS input from column-major to row-major to match TensorFlow
|
||||
// expectations. This is the inverse of the transpose we do during
|
||||
// ResolveTensorFlowMatMul.
|
||||
const string transpose_output =
|
||||
const std::string transpose_output =
|
||||
AvailableArrayName(model, matmul_output + "/transpose_weights");
|
||||
const string transpose_perm =
|
||||
const std::string transpose_perm =
|
||||
AvailableArrayName(model, transpose_output + "/perm");
|
||||
CreateIntTensorConst(transpose_perm, {1, 0}, {2}, tensorflow_graph);
|
||||
tensorflow::NodeDef* transpose_op = tensorflow_graph->add_node();
|
||||
@ -733,9 +735,9 @@ void ConvertReluOperator(const Model& model, const ReluOperator& src_op,
|
||||
|
||||
void ConvertRelu1Operator(const Relu1Operator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
const string max_bounds = src_op.outputs[0] + "/max_bounds";
|
||||
const string min_bounds = src_op.outputs[0] + "/min_bounds";
|
||||
const string max_output = src_op.outputs[0] + "/max_output";
|
||||
const std::string max_bounds = src_op.outputs[0] + "/max_bounds";
|
||||
const std::string min_bounds = src_op.outputs[0] + "/min_bounds";
|
||||
const std::string max_output = src_op.outputs[0] + "/max_output";
|
||||
|
||||
tensorflow::NodeDef* max_bounds_const_op = tensorflow_graph->add_node();
|
||||
max_bounds_const_op->set_op("Const");
|
||||
@ -808,15 +810,16 @@ void ConvertTanhOperator(const TanhOperator& src_op,
|
||||
|
||||
void ConvertSoftmaxOperator(const Model& model, const SoftmaxOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
string softmax_input;
|
||||
std::string softmax_input;
|
||||
Operator* providing_op = GetOpWithOutput(model, src_op.inputs[0]);
|
||||
if (providing_op != nullptr && providing_op->type == OperatorType::kReshape) {
|
||||
softmax_input = src_op.inputs[0];
|
||||
} else {
|
||||
// Insert a reshape operator that reduces the dimensions down to the 2 that
|
||||
// are required for TensorFlow Logits.
|
||||
const string reshape_output = src_op.outputs[0] + "/softmax_insert_reshape";
|
||||
const string softmax_size = src_op.outputs[0] + "/softmax_insert_size";
|
||||
const std::string reshape_output =
|
||||
src_op.outputs[0] + "/softmax_insert_reshape";
|
||||
const std::string softmax_size = src_op.outputs[0] + "/softmax_insert_size";
|
||||
softmax_input = reshape_output;
|
||||
|
||||
tensorflow::NodeDef* reshape_op = tensorflow_graph->add_node();
|
||||
@ -848,16 +851,17 @@ void ConvertSoftmaxOperator(const Model& model, const SoftmaxOperator& src_op,
|
||||
void ConvertLogSoftmaxOperator(const Model& model,
|
||||
const LogSoftmaxOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
string softmax_input;
|
||||
std::string softmax_input;
|
||||
Operator* providing_op = GetOpWithOutput(model, src_op.inputs[0]);
|
||||
if (providing_op != nullptr && providing_op->type == OperatorType::kReshape) {
|
||||
softmax_input = src_op.inputs[0];
|
||||
} else {
|
||||
// Insert a reshape operator that reduces the dimensions down to the 2 that
|
||||
// are required for TensorFlow Logits.
|
||||
const string reshape_output =
|
||||
const std::string reshape_output =
|
||||
src_op.outputs[0] + "/log_softmax_insert_reshape";
|
||||
const string softmax_size = src_op.outputs[0] + "/log_softmax_insert_size";
|
||||
const std::string softmax_size =
|
||||
src_op.outputs[0] + "/log_softmax_insert_size";
|
||||
softmax_input = reshape_output;
|
||||
|
||||
tensorflow::NodeDef* reshape_op = tensorflow_graph->add_node();
|
||||
@ -886,11 +890,12 @@ void ConvertLogSoftmaxOperator(const Model& model,
|
||||
|
||||
void ConvertL2NormalizationOperator(const L2NormalizationOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
const string square_output = src_op.outputs[0] + "/square";
|
||||
const string sum_reduction_indices = src_op.outputs[0] + "/reduction_indices";
|
||||
const string sum_output = src_op.outputs[0] + "/sum";
|
||||
const string rsqrt_output = src_op.outputs[0] + "/rsqrt";
|
||||
const string rsqrt_tiled_output = src_op.outputs[0] + "/rsqrt_tiled";
|
||||
const std::string square_output = src_op.outputs[0] + "/square";
|
||||
const std::string sum_reduction_indices =
|
||||
src_op.outputs[0] + "/reduction_indices";
|
||||
const std::string sum_output = src_op.outputs[0] + "/sum";
|
||||
const std::string rsqrt_output = src_op.outputs[0] + "/rsqrt";
|
||||
const std::string rsqrt_tiled_output = src_op.outputs[0] + "/rsqrt_tiled";
|
||||
|
||||
tensorflow::NodeDef* sum_reduction_indices_op = tensorflow_graph->add_node();
|
||||
sum_reduction_indices_op->set_op("Const");
|
||||
@ -975,7 +980,7 @@ void ConvertMaxPoolOperator(const MaxPoolOperator& src_op,
|
||||
strides.mutable_list()->add_i(src_op.stride_height);
|
||||
strides.mutable_list()->add_i(src_op.stride_width);
|
||||
strides.mutable_list()->add_i(1);
|
||||
string padding;
|
||||
std::string padding;
|
||||
if (src_op.padding.type == PaddingType::kSame) {
|
||||
padding = "SAME";
|
||||
} else if (src_op.padding.type == PaddingType::kValid) {
|
||||
@ -1003,7 +1008,7 @@ void ConvertAveragePoolOperator(const AveragePoolOperator& src_op,
|
||||
strides.mutable_list()->add_i(src_op.stride_height);
|
||||
strides.mutable_list()->add_i(src_op.stride_width);
|
||||
strides.mutable_list()->add_i(1);
|
||||
string padding;
|
||||
std::string padding;
|
||||
if (src_op.padding.type == PaddingType::kSame) {
|
||||
padding = "SAME";
|
||||
} else if (src_op.padding.type == PaddingType::kValid) {
|
||||
@ -1026,7 +1031,7 @@ void ConvertConcatenationOperator(const Model& model,
|
||||
tensorflow::NodeDef* dc_op = tensorflow_graph->add_node();
|
||||
dc_op->set_op("ConcatV2");
|
||||
dc_op->set_name(src_op.outputs[0]);
|
||||
const string dummy_axis = src_op.outputs[0] + "/axis";
|
||||
const std::string dummy_axis = src_op.outputs[0] + "/axis";
|
||||
CreateDummyConcatDimTensorConst(dummy_axis, src_op.axis, tensorflow_graph);
|
||||
for (const auto& input : src_op.inputs) {
|
||||
*dc_op->add_input() = input;
|
||||
@ -1060,8 +1065,8 @@ void ConvertTensorFlowReshapeOperator(const Model& model,
|
||||
|
||||
void ConvertL2PoolOperator(const L2PoolOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
const string square_output = src_op.outputs[0] + "/square";
|
||||
const string avgpool_output = src_op.outputs[0] + "/avgpool";
|
||||
const std::string square_output = src_op.outputs[0] + "/square";
|
||||
const std::string avgpool_output = src_op.outputs[0] + "/avgpool";
|
||||
|
||||
tensorflow::NodeDef* square_op = tensorflow_graph->add_node();
|
||||
square_op->set_op("Square");
|
||||
@ -1069,7 +1074,7 @@ void ConvertL2PoolOperator(const L2PoolOperator& src_op,
|
||||
*square_op->add_input() = src_op.inputs[0];
|
||||
(*square_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
string padding;
|
||||
std::string padding;
|
||||
if (src_op.padding.type == PaddingType::kSame) {
|
||||
padding = "SAME";
|
||||
} else if (src_op.padding.type == PaddingType::kValid) {
|
||||
@ -1235,7 +1240,7 @@ void ConvertGatherOperator(const Model& model, const GatherOperator& src_op,
|
||||
} else {
|
||||
// Constant axis.
|
||||
CHECK_EQ(src_op.inputs.size(), 2);
|
||||
const string gather_axis =
|
||||
const std::string gather_axis =
|
||||
AvailableArrayName(model, gather_op->name() + "/axis");
|
||||
CreateIntTensorConst(gather_axis, {src_op.axis.value()}, {},
|
||||
tensorflow_graph);
|
||||
@ -1454,8 +1459,8 @@ absl::string_view FindLongestCommonPrefix(absl::string_view a,
|
||||
|
||||
const char* pa = a.data();
|
||||
const char* pb = b.data();
|
||||
string::difference_type count = 0;
|
||||
const string::difference_type limit = std::min(a.size(), b.size());
|
||||
std::string::difference_type count = 0;
|
||||
const std::string::difference_type limit = std::min(a.size(), b.size());
|
||||
while (count < limit && *pa == *pb) {
|
||||
++pa;
|
||||
++pb;
|
||||
@ -1469,12 +1474,12 @@ absl::string_view FindLongestCommonPrefix(absl::string_view a,
|
||||
void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
GraphDef* tensorflow_graph) {
|
||||
// Find the base name
|
||||
const string base(
|
||||
const std::string base(
|
||||
FindLongestCommonPrefix(src_op.outputs[LstmCellOperator::STATE_OUTPUT],
|
||||
src_op.outputs[LstmCellOperator::ACTIV_OUTPUT]));
|
||||
|
||||
// Concatenate inputs
|
||||
const string concat_output = base + "basic_lstm_cell/concat";
|
||||
const std::string concat_output = base + "basic_lstm_cell/concat";
|
||||
// Op names have been chosen to match the tf.slim LSTM naming
|
||||
// as closely as possible.
|
||||
const int axis =
|
||||
@ -1484,7 +1489,7 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
1;
|
||||
// Note that DATA_INPUT may have extra size 1 dimensions, but TF concat
|
||||
// works the same since the tensor has the same underlying data layout.
|
||||
const string axis_output = concat_output + "/axis";
|
||||
const std::string axis_output = concat_output + "/axis";
|
||||
CreateDummyConcatDimTensorConst(axis_output, axis, tensorflow_graph);
|
||||
tensorflow::NodeDef* concat_op = tensorflow_graph->add_node();
|
||||
concat_op->set_op("ConcatV2");
|
||||
@ -1497,9 +1502,9 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
(*concat_op->mutable_attr())["N"].set_i(2); // Number of inputs
|
||||
|
||||
// Write weights
|
||||
const string weights_output = base + "weights";
|
||||
const std::string weights_output = base + "weights";
|
||||
CHECK(model.HasArray(src_op.inputs[LstmCellOperator::WEIGHTS_INPUT]));
|
||||
const string weights_name = WalkUpToConstantArray(
|
||||
const std::string weights_name = WalkUpToConstantArray(
|
||||
model, src_op.inputs[LstmCellOperator::WEIGHTS_INPUT]);
|
||||
const auto& weights_array = model.GetArray(weights_name);
|
||||
// Convert 4D FullyConnected weights into 2D matrix
|
||||
@ -1513,7 +1518,7 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
AxesOrder::kCR, AxesOrder::kRC, tensorflow_graph);
|
||||
|
||||
// Fully connected matrix multiply
|
||||
const string matmul_output = base + "MatMul";
|
||||
const std::string matmul_output = base + "MatMul";
|
||||
tensorflow::NodeDef* matmul_op = tensorflow_graph->add_node();
|
||||
matmul_op->set_op("MatMul");
|
||||
matmul_op->set_name(matmul_output);
|
||||
@ -1524,9 +1529,9 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
(*matmul_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
// Write biases
|
||||
const string biases_output = base + "biases";
|
||||
const std::string biases_output = base + "biases";
|
||||
CHECK(model.HasArray(src_op.inputs[LstmCellOperator::BIASES_INPUT]));
|
||||
const string bias_name = WalkUpToConstantArray(
|
||||
const std::string bias_name = WalkUpToConstantArray(
|
||||
model, src_op.inputs[LstmCellOperator::BIASES_INPUT]);
|
||||
const auto& bias_array = model.GetArray(bias_name);
|
||||
// TODO(b/62904716) Bias arrays should be 1-D, and used directly.
|
||||
@ -1542,7 +1547,7 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
LegacyScalarPolicy::kDoCreateLegacyScalars);
|
||||
|
||||
// Add biases
|
||||
string biasadd_output = base + "BiasAdd";
|
||||
std::string biasadd_output = base + "BiasAdd";
|
||||
tensorflow::NodeDef* biasadd_op = tensorflow_graph->add_node();
|
||||
biasadd_op->set_op("BiasAdd");
|
||||
biasadd_op->set_name(biasadd_output);
|
||||
@ -1552,10 +1557,10 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
(*biasadd_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
// Split
|
||||
string split_dim_output = base + "split/split_dim";
|
||||
std::string split_dim_output = base + "split/split_dim";
|
||||
// The dimension is the same as the concatenation dimension
|
||||
CreateDummyConcatDimTensorConst(split_dim_output, axis, tensorflow_graph);
|
||||
string split_output = base + "split";
|
||||
std::string split_output = base + "split";
|
||||
tensorflow::NodeDef* split_op = tensorflow_graph->add_node();
|
||||
split_op->set_op("Split");
|
||||
split_op->set_name(split_output);
|
||||
@ -1565,21 +1570,21 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
(*split_op->mutable_attr())["num_split"].set_i(4); // Split into four outputs
|
||||
|
||||
// Activation functions and memory computations
|
||||
const string tanh_0_output = base + "Tanh";
|
||||
const std::string tanh_0_output = base + "Tanh";
|
||||
tensorflow::NodeDef* tanh_0_op = tensorflow_graph->add_node();
|
||||
tanh_0_op->set_op("Tanh");
|
||||
tanh_0_op->set_name(tanh_0_output);
|
||||
*tanh_0_op->add_input() = split_output + ":1";
|
||||
(*tanh_0_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string sigmoid_1_output = base + "Sigmoid_1";
|
||||
const std::string sigmoid_1_output = base + "Sigmoid_1";
|
||||
tensorflow::NodeDef* logistic_1_op = tensorflow_graph->add_node();
|
||||
logistic_1_op->set_op("Sigmoid");
|
||||
logistic_1_op->set_name(sigmoid_1_output);
|
||||
*logistic_1_op->add_input() = split_output;
|
||||
(*logistic_1_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string mul_1_output = base + "mul_1";
|
||||
const std::string mul_1_output = base + "mul_1";
|
||||
tensorflow::NodeDef* mul_1_op = tensorflow_graph->add_node();
|
||||
mul_1_op->set_op("Mul");
|
||||
mul_1_op->set_name(mul_1_output);
|
||||
@ -1587,21 +1592,21 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
*mul_1_op->add_input() = tanh_0_output;
|
||||
(*mul_1_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string sigmoid_0_output = base + "Sigmoid";
|
||||
const std::string sigmoid_0_output = base + "Sigmoid";
|
||||
tensorflow::NodeDef* logistic_2_op = tensorflow_graph->add_node();
|
||||
logistic_2_op->set_op("Sigmoid");
|
||||
logistic_2_op->set_name(sigmoid_0_output);
|
||||
*logistic_2_op->add_input() = split_output + ":2";
|
||||
(*logistic_2_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string sigmoid_2_output = base + "Sigmoid_2";
|
||||
const std::string sigmoid_2_output = base + "Sigmoid_2";
|
||||
tensorflow::NodeDef* logistic_3_op = tensorflow_graph->add_node();
|
||||
logistic_3_op->set_op("Sigmoid");
|
||||
logistic_3_op->set_name(sigmoid_2_output);
|
||||
*logistic_3_op->add_input() = split_output + ":3";
|
||||
(*logistic_3_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string mul_0_output = base + "mul";
|
||||
const std::string mul_0_output = base + "mul";
|
||||
tensorflow::NodeDef* mul_0_op = tensorflow_graph->add_node();
|
||||
mul_0_op->set_op("Mul");
|
||||
mul_0_op->set_name(mul_0_output);
|
||||
@ -1609,7 +1614,8 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
*mul_0_op->add_input() = sigmoid_0_output;
|
||||
(*mul_0_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string add_1_output = src_op.outputs[LstmCellOperator::STATE_OUTPUT];
|
||||
const std::string add_1_output =
|
||||
src_op.outputs[LstmCellOperator::STATE_OUTPUT];
|
||||
tensorflow::NodeDef* add_1_op = tensorflow_graph->add_node();
|
||||
add_1_op->set_op("Add");
|
||||
add_1_op->set_name(add_1_output);
|
||||
@ -1617,14 +1623,15 @@ void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
|
||||
*add_1_op->add_input() = mul_1_output;
|
||||
(*add_1_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string tanh_1_output = base + "Tanh_1";
|
||||
const std::string tanh_1_output = base + "Tanh_1";
|
||||
tensorflow::NodeDef* tanh_1_op = tensorflow_graph->add_node();
|
||||
tanh_1_op->set_op("Tanh");
|
||||
tanh_1_op->set_name(tanh_1_output);
|
||||
*tanh_1_op->add_input() = add_1_output;
|
||||
(*tanh_1_op->mutable_attr())["T"].set_type(DT_FLOAT);
|
||||
|
||||
const string mul_2_output = src_op.outputs[LstmCellOperator::ACTIV_OUTPUT];
|
||||
const std::string mul_2_output =
|
||||
src_op.outputs[LstmCellOperator::ACTIV_OUTPUT];
|
||||
tensorflow::NodeDef* mul_2_op = tensorflow_graph->add_node();
|
||||
mul_2_op->set_op("Mul");
|
||||
mul_2_op->set_name(mul_2_output);
|
||||
@ -1730,7 +1737,8 @@ void ConvertPadV2Operator(const Model& model, const PadV2Operator& src_op,
|
||||
shape->add_dim()->set_size(2);
|
||||
}
|
||||
|
||||
void CreateSliceInput(const string& input_name, const std::vector<int>& values,
|
||||
void CreateSliceInput(const std::string& input_name,
|
||||
const std::vector<int>& values,
|
||||
GraphDef* tensorflow_graph) {
|
||||
tensorflow::NodeDef* params_op = tensorflow_graph->add_node();
|
||||
params_op->set_op("Const");
|
||||
@ -1797,7 +1805,8 @@ void ConvertSliceOperator(const Model& model, const SliceOperator& src_op,
|
||||
|
||||
template <typename T>
|
||||
void ConvertReduceOperator(const Model& model, const T& src_op,
|
||||
GraphDef* tensorflow_graph, const string& op_name) {
|
||||
GraphDef* tensorflow_graph,
|
||||
const std::string& op_name) {
|
||||
tensorflow::NodeDef* new_op = tensorflow_graph->add_node();
|
||||
new_op->set_op(op_name);
|
||||
new_op->set_name(src_op.outputs[0]);
|
||||
@ -2412,7 +2421,7 @@ void ConvertOperator(const Model& model, const Operator& src_op,
|
||||
}
|
||||
}
|
||||
|
||||
void AddPlaceholder(const string& name, ArrayDataType type,
|
||||
void AddPlaceholder(const std::string& name, ArrayDataType type,
|
||||
GraphDef* tensorflow_graph) {
|
||||
tensorflow::NodeDef* placeholder = tensorflow_graph->add_node();
|
||||
placeholder->set_op("Placeholder");
|
||||
@ -2444,8 +2453,8 @@ void AddPlaceholder(const string& name, ArrayDataType type,
|
||||
placeholder->set_name(name);
|
||||
}
|
||||
|
||||
void AddPlaceholderForRNNState(const Model& model, const string& name, int size,
|
||||
GraphDef* tensorflow_graph) {
|
||||
void AddPlaceholderForRNNState(const Model& model, const std::string& name,
|
||||
int size, GraphDef* tensorflow_graph) {
|
||||
tensorflow::NodeDef* placeholder = tensorflow_graph->add_node();
|
||||
placeholder->set_op("Placeholder");
|
||||
placeholder->set_name(name);
|
||||
@ -2484,7 +2493,7 @@ void ExportTensorFlowGraphDefImplementation(const Model& model,
|
||||
// after, as some operators need to export arrays that they reference
|
||||
// in a specific way, rather than in the generic way done below.
|
||||
for (const auto& array_pair : model.GetArrayMap()) {
|
||||
const string& array_name = array_pair.first;
|
||||
const std::string& array_name = array_pair.first;
|
||||
const auto& array = *array_pair.second;
|
||||
if (array.buffer) {
|
||||
switch (array.data_type) {
|
||||
@ -2510,12 +2519,12 @@ void ExportTensorFlowGraphDefImplementation(const Model& model,
|
||||
|
||||
void EncodeConstantArraysMinMaxByWrappingThemInFakeQuantNodes(Model* model) {
|
||||
for (const auto& array_kv : model->GetArrayMap()) {
|
||||
const string& array_name = array_kv.first;
|
||||
const std::string& array_name = array_kv.first;
|
||||
Array& array = *array_kv.second;
|
||||
if (!array.buffer || !array.minmax) {
|
||||
continue;
|
||||
}
|
||||
const string& wrapped_array_name =
|
||||
const std::string& wrapped_array_name =
|
||||
AvailableArrayName(*model, array_name + "/data");
|
||||
Array& wrapped_array = model->GetOrCreateArray(wrapped_array_name);
|
||||
wrapped_array.data_type = array.data_type;
|
||||
@ -2533,7 +2542,7 @@ void EncodeConstantArraysMinMaxByWrappingThemInFakeQuantNodes(Model* model) {
|
||||
}
|
||||
|
||||
void ExportTensorFlowGraphDef(const Model& model,
|
||||
string* output_file_contents) {
|
||||
std::string* output_file_contents) {
|
||||
CHECK(output_file_contents->empty());
|
||||
GraphDef tensorflow_graph;
|
||||
ExportTensorFlowGraphDefImplementation(model, &tensorflow_graph);
|
||||
|
@ -20,7 +20,8 @@ limitations under the License.
|
||||
|
||||
namespace toco {
|
||||
|
||||
void ExportTensorFlowGraphDef(const Model& model, string* output_file_contents);
|
||||
void ExportTensorFlowGraphDef(const Model& model,
|
||||
std::string* output_file_contents);
|
||||
|
||||
void EncodeConstantArraysMinMaxByWrappingThemInFakeQuantNodes(Model* model);
|
||||
|
||||
|
@ -38,13 +38,13 @@ inline const char* IdentityOrConvertStringToRaw(const std::string& foo) {
|
||||
|
||||
// Delegate to TensorFlow Appendf function until absl has an equivalent.
|
||||
template <typename... Args>
|
||||
inline void AppendFHelper(string* destination, const char* fmt,
|
||||
inline void AppendFHelper(std::string* destination, const char* fmt,
|
||||
Args&&... args) {
|
||||
tensorflow::strings::Appendf(destination, fmt, args...);
|
||||
}
|
||||
|
||||
// Specialization for no argument format string (avoid security bug).
|
||||
inline void AppendFHelper(string* destination, const char* fmt) {
|
||||
inline void AppendFHelper(std::string* destination, const char* fmt) {
|
||||
tensorflow::strings::Appendf(destination, "%s", fmt);
|
||||
}
|
||||
|
||||
@ -52,15 +52,15 @@ inline void AppendFHelper(string* destination, const char* fmt) {
|
||||
// pointed to by destination. fmt follows C printf semantics.
|
||||
// One departure is that %s can be driven by a std::string or string.
|
||||
template <typename... Args>
|
||||
inline void AppendF(string* destination, const char* fmt, Args&&... args) {
|
||||
inline void AppendF(std::string* destination, const char* fmt, Args&&... args) {
|
||||
AppendFHelper(destination, fmt, IdentityOrConvertStringToRaw(args)...);
|
||||
}
|
||||
|
||||
// Return formatted string (with format fmt and args args). fmt follows C printf
|
||||
// semantics. One departure is that %s can be driven by a std::string or string.
|
||||
template <typename... Args>
|
||||
inline string StringF(const char* fmt, Args&&... args) {
|
||||
string result;
|
||||
inline std::string StringF(const char* fmt, Args&&... args) {
|
||||
std::string result;
|
||||
AppendFHelper(&result, fmt, IdentityOrConvertStringToRaw(args)...);
|
||||
return result;
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ using tensorflow::TensorShapeProto;
|
||||
namespace toco {
|
||||
|
||||
namespace {
|
||||
bool HasAttr(const NodeDef& node, const string& attr_name) {
|
||||
bool HasAttr(const NodeDef& node, const std::string& attr_name) {
|
||||
return node.attr().count(attr_name) > 0;
|
||||
}
|
||||
|
||||
@ -78,14 +78,15 @@ bool HasWildcardDimension(const TensorShapeProto& shape) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const string& GetStringAttr(const NodeDef& node, const string& attr_name) {
|
||||
const std::string& GetStringAttr(const NodeDef& node,
|
||||
const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name));
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
CHECK_EQ(attr.value_case(), AttrValue::kS);
|
||||
return attr.s();
|
||||
}
|
||||
|
||||
int64 GetIntAttr(const NodeDef& node, const string& attr_name) {
|
||||
int64 GetIntAttr(const NodeDef& node, const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name)) << attr_name << " not found in:\n"
|
||||
<< node.DebugString();
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
@ -93,14 +94,14 @@ int64 GetIntAttr(const NodeDef& node, const string& attr_name) {
|
||||
return attr.i();
|
||||
}
|
||||
|
||||
float GetFloatAttr(const NodeDef& node, const string& attr_name) {
|
||||
float GetFloatAttr(const NodeDef& node, const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name));
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
CHECK_EQ(attr.value_case(), AttrValue::kF);
|
||||
return attr.f();
|
||||
}
|
||||
|
||||
bool GetBoolAttr(const NodeDef& node, const string& attr_name) {
|
||||
bool GetBoolAttr(const NodeDef& node, const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name));
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
CHECK_EQ(attr.value_case(), AttrValue::kB);
|
||||
@ -108,7 +109,7 @@ bool GetBoolAttr(const NodeDef& node, const string& attr_name) {
|
||||
}
|
||||
|
||||
tensorflow::DataType GetDataTypeAttr(const NodeDef& node,
|
||||
const string& attr_name) {
|
||||
const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name));
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
CHECK_EQ(attr.value_case(), AttrValue::kType);
|
||||
@ -116,14 +117,15 @@ tensorflow::DataType GetDataTypeAttr(const NodeDef& node,
|
||||
}
|
||||
|
||||
const TensorShapeProto& GetShapeAttr(const NodeDef& node,
|
||||
const string& attr_name) {
|
||||
const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name));
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
CHECK_EQ(attr.value_case(), AttrValue::kShape);
|
||||
return attr.shape();
|
||||
}
|
||||
|
||||
const TensorProto& GetTensorAttr(const NodeDef& node, const string& attr_name) {
|
||||
const TensorProto& GetTensorAttr(const NodeDef& node,
|
||||
const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name)) << "No attr named '" << attr_name << "'";
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
CHECK_EQ(attr.value_case(), AttrValue::kTensor);
|
||||
@ -131,7 +133,7 @@ const TensorProto& GetTensorAttr(const NodeDef& node, const string& attr_name) {
|
||||
}
|
||||
|
||||
const AttrValue::ListValue& GetListAttr(const NodeDef& node,
|
||||
const string& attr_name) {
|
||||
const std::string& attr_name) {
|
||||
CHECK(HasAttr(node, attr_name));
|
||||
const auto& attr = node.attr().at(attr_name);
|
||||
CHECK_EQ(attr.value_case(), AttrValue::kList);
|
||||
@ -139,10 +141,10 @@ const AttrValue::ListValue& GetListAttr(const NodeDef& node,
|
||||
}
|
||||
|
||||
tensorflow::Status CheckOptionalAttr(const NodeDef& node,
|
||||
const string& attr_name,
|
||||
const string& expected_value) {
|
||||
const std::string& attr_name,
|
||||
const std::string& expected_value) {
|
||||
if (HasAttr(node, attr_name)) {
|
||||
const string& value = GetStringAttr(node, attr_name);
|
||||
const std::string& value = GetStringAttr(node, attr_name);
|
||||
if (value != expected_value) {
|
||||
return tensorflow::errors::InvalidArgument(
|
||||
"Unexpected value for attribute '" + attr_name + "'. Expected '" +
|
||||
@ -153,7 +155,7 @@ tensorflow::Status CheckOptionalAttr(const NodeDef& node,
|
||||
}
|
||||
|
||||
tensorflow::Status CheckOptionalAttr(
|
||||
const NodeDef& node, const string& attr_name,
|
||||
const NodeDef& node, const std::string& attr_name,
|
||||
const tensorflow::DataType& expected_value) {
|
||||
if (HasAttr(node, attr_name)) {
|
||||
const tensorflow::DataType& value = GetDataTypeAttr(node, attr_name);
|
||||
@ -168,7 +170,7 @@ tensorflow::Status CheckOptionalAttr(
|
||||
|
||||
template <typename T1, typename T2>
|
||||
tensorflow::Status ExpectValue(const T1& v1, const T2& v2,
|
||||
const string& description) {
|
||||
const std::string& description) {
|
||||
if (v1 == v2) return tensorflow::Status::OK();
|
||||
return tensorflow::errors::InvalidArgument(absl::StrCat(
|
||||
"Unexpected ", description, ": got ", v1, ", expected ", v2));
|
||||
@ -244,8 +246,8 @@ template <>
|
||||
struct TensorTraits<float> {
|
||||
static int size(const TensorProto& p) { return p.float_val_size(); }
|
||||
static float get(const TensorProto& p, int i) { return p.float_val(i); }
|
||||
static string accessor_name() { return "float_val"; }
|
||||
static string type_name() { return "float"; }
|
||||
static std::string accessor_name() { return "float_val"; }
|
||||
static std::string type_name() { return "float"; }
|
||||
static void CopyFromContent(const TensorProto& p, std::vector<float>* data) {
|
||||
toco::port::CopyToBuffer(p.tensor_content(),
|
||||
reinterpret_cast<char*>(data->data()));
|
||||
@ -256,8 +258,8 @@ template <>
|
||||
struct TensorTraits<uint8_t> {
|
||||
static int size(const TensorProto& p) { return p.int_val_size(); }
|
||||
static uint8_t get(const TensorProto& p, int i) { return p.int_val(i); }
|
||||
static string accessor_name() { return "int_val"; }
|
||||
static string type_name() { return "uint8"; }
|
||||
static std::string accessor_name() { return "int_val"; }
|
||||
static std::string type_name() { return "uint8"; }
|
||||
static void CopyFromContent(const TensorProto& p,
|
||||
std::vector<uint8_t>* data) {
|
||||
toco::port::CopyToBuffer(p.tensor_content(),
|
||||
@ -272,8 +274,8 @@ struct TensorTraits<std::complex<float>> {
|
||||
return std::complex<float>(p.scomplex_val(2 * i),
|
||||
p.scomplex_val(2 * i + 1));
|
||||
}
|
||||
static string accessor_name() { return "scomplex_val"; }
|
||||
static string type_name() { return "complex64"; }
|
||||
static std::string accessor_name() { return "scomplex_val"; }
|
||||
static std::string type_name() { return "complex64"; }
|
||||
static void CopyFromContent(const TensorProto& p,
|
||||
std::vector<std::complex<float>>* data) {
|
||||
toco::port::CopyToBuffer(p.tensor_content(),
|
||||
@ -285,8 +287,8 @@ template <>
|
||||
struct TensorTraits<int32> {
|
||||
static int size(const TensorProto& p) { return p.int_val_size(); }
|
||||
static int32 get(const TensorProto& p, int i) { return p.int_val(i); }
|
||||
static string accessor_name() { return "int_val"; }
|
||||
static string type_name() { return "int32"; }
|
||||
static std::string accessor_name() { return "int_val"; }
|
||||
static std::string type_name() { return "int32"; }
|
||||
static void CopyFromContent(const TensorProto& p, std::vector<int32>* data) {
|
||||
toco::port::CopyToBuffer(p.tensor_content(),
|
||||
reinterpret_cast<char*>(data->data()));
|
||||
@ -297,8 +299,8 @@ template <>
|
||||
struct TensorTraits<int64> {
|
||||
static int size(const TensorProto& p) { return p.int64_val_size(); }
|
||||
static int64 get(const TensorProto& p, int i) { return p.int64_val(i); }
|
||||
static string accessor_name() { return "int64_val"; }
|
||||
static string type_name() { return "int64"; }
|
||||
static std::string accessor_name() { return "int64_val"; }
|
||||
static std::string type_name() { return "int64"; }
|
||||
static void CopyFromContent(const TensorProto& p, std::vector<int64>* data) {
|
||||
toco::port::CopyToBuffer(p.tensor_content(),
|
||||
reinterpret_cast<char*>(data->data()));
|
||||
@ -309,8 +311,8 @@ template <>
|
||||
struct TensorTraits<bool> {
|
||||
static int size(const TensorProto& p) { return p.bool_val_size(); }
|
||||
static bool get(const TensorProto& p, int i) { return p.bool_val(i); }
|
||||
static string accessor_name() { return "bool_val"; }
|
||||
static string type_name() { return "bool"; }
|
||||
static std::string accessor_name() { return "bool_val"; }
|
||||
static std::string type_name() { return "bool"; }
|
||||
static void CopyFromContent(const TensorProto& p, std::vector<bool>* data) {
|
||||
std::vector<char> buf(p.tensor_content().size());
|
||||
toco::port::CopyToBuffer(p.tensor_content(), buf.data());
|
||||
@ -348,8 +350,8 @@ tensorflow::Status ImportTensorData(const TensorProto& input_tensor,
|
||||
(*output_data)[i] = last;
|
||||
}
|
||||
} else {
|
||||
string accessor_name = TensorTraits<T>::accessor_name();
|
||||
string type_name = TensorTraits<T>::type_name();
|
||||
std::string accessor_name = TensorTraits<T>::accessor_name();
|
||||
std::string type_name = TensorTraits<T>::type_name();
|
||||
return tensorflow::errors::InvalidArgument(
|
||||
absl::StrCat("Neither input_content (",
|
||||
input_tensor.tensor_content().size() / sizeof(T), ") nor ",
|
||||
@ -527,10 +529,11 @@ tensorflow::Status CheckInputsCount(
|
||||
}
|
||||
|
||||
template <ArrayDataType T>
|
||||
string CreateConstArray(Model* model, string const& name,
|
||||
std::vector<typename toco::DataType<T> > const& data) {
|
||||
std::string CreateConstArray(
|
||||
Model* model, std::string const& name,
|
||||
std::vector<typename toco::DataType<T>> const& data) {
|
||||
// Utility function to create a const 1D array, useful for input parameters.
|
||||
string array_name = toco::AvailableArrayName(*model, name);
|
||||
std::string array_name = toco::AvailableArrayName(*model, name);
|
||||
auto& array = model->GetOrCreateArray(array_name);
|
||||
array.data_type = T;
|
||||
array.mutable_shape()->mutable_dims()->emplace_back(
|
||||
@ -576,7 +579,7 @@ void GetOutputNamesFromNodeDef(const NodeDef& node,
|
||||
++next_output;
|
||||
};
|
||||
for (int i = 0; i < op_def.output_arg_size(); ++i) {
|
||||
string multiples = op_def.output_arg(i).number_attr();
|
||||
std::string multiples = op_def.output_arg(i).number_attr();
|
||||
if (!multiples.empty()) {
|
||||
CHECK(HasAttr(node, multiples)) << "No attr named " << multiples;
|
||||
int num_outputs = GetIntAttr(node, multiples);
|
||||
@ -584,7 +587,7 @@ void GetOutputNamesFromNodeDef(const NodeDef& node,
|
||||
add_output();
|
||||
}
|
||||
} else {
|
||||
string list = op_def.output_arg(i).type_list_attr();
|
||||
std::string list = op_def.output_arg(i).type_list_attr();
|
||||
if (!list.empty()) {
|
||||
CHECK(HasAttr(node, list)) << "No attr named " << list;
|
||||
const AttrValue::ListValue& list_value = GetListAttr(node, list);
|
||||
@ -624,7 +627,7 @@ void GetOutputTypesFromNodeDef(const NodeDef& node,
|
||||
};
|
||||
|
||||
for (int i = 0; i < op_def.output_arg_size(); ++i) {
|
||||
string multiples = op_def.output_arg(i).number_attr();
|
||||
std::string multiples = op_def.output_arg(i).number_attr();
|
||||
if (!multiples.empty()) {
|
||||
CHECK(HasAttr(node, multiples)) << "No attr named " << multiples;
|
||||
int num_outputs = GetIntAttr(node, multiples);
|
||||
@ -633,7 +636,7 @@ void GetOutputTypesFromNodeDef(const NodeDef& node,
|
||||
add_type(type);
|
||||
}
|
||||
} else {
|
||||
string list = op_def.output_arg(i).type_list_attr();
|
||||
std::string list = op_def.output_arg(i).type_list_attr();
|
||||
if (!list.empty()) {
|
||||
CHECK(HasAttr(node, list)) << "No attr named " << list;
|
||||
const AttrValue::ListValue& list_value = GetListAttr(node, list);
|
||||
@ -1057,7 +1060,7 @@ tensorflow::Status ConvertIdentityNOperator(
|
||||
for (int i = 0; i < node.input_size(); ++i) {
|
||||
auto* op = new TensorFlowIdentityOperator;
|
||||
const auto& input_name = node.input(i);
|
||||
string output_name = node.name();
|
||||
std::string output_name = node.name();
|
||||
if (i > 0) {
|
||||
output_name = output_name + ":" + std::to_string(i);
|
||||
}
|
||||
@ -1756,13 +1759,13 @@ tensorflow::Status ConvertBatchNormWithGlobalNormalizationOperator(
|
||||
// to the input, before feeding it into TensorFlowRsqrtOperator.
|
||||
// CHECK_EQ(GetFloatAttr(node, "variance_epsilon"), 0.001f);
|
||||
|
||||
string multiplier = node.name() + "_mul";
|
||||
std::string multiplier = node.name() + "_mul";
|
||||
if (GetBoolAttr(node, "scale_after_normalization")) {
|
||||
// Create graph:
|
||||
// v -> RSQRT ->
|
||||
// MUL -> multiplier
|
||||
// gamma ----->
|
||||
string rsqrt = node.name() + "_rsqrt";
|
||||
std::string rsqrt = node.name() + "_rsqrt";
|
||||
|
||||
auto* rsqrt_op = new TensorFlowRsqrtOperator;
|
||||
rsqrt_op->inputs.push_back(node.input(2));
|
||||
@ -1803,17 +1806,19 @@ tensorflow::Status ConvertFusedBatchNormOperator(
|
||||
TF_QCHECK_OK(CheckInputsCount(node, tf_import_flags, 5));
|
||||
|
||||
// Declare shortcuts for the inputs.
|
||||
const string& gamma_input = node.input(1);
|
||||
const string& beta_input = node.input(2);
|
||||
const string& moving_mean_input = node.input(3);
|
||||
const string& moving_variance_input = node.input(4);
|
||||
const std::string& gamma_input = node.input(1);
|
||||
const std::string& beta_input = node.input(2);
|
||||
const std::string& moving_mean_input = node.input(3);
|
||||
const std::string& moving_variance_input = node.input(4);
|
||||
|
||||
// Create an array holding the epsilon value (typically, 0.001).
|
||||
const string epsilon_array_name = CreateConstArray<ArrayDataType::kFloat>(
|
||||
model, node.name() + "_epsilon_array", {GetFloatAttr(node, "epsilon")});
|
||||
const std::string epsilon_array_name =
|
||||
CreateConstArray<ArrayDataType::kFloat>(model,
|
||||
node.name() + "_epsilon_array",
|
||||
{GetFloatAttr(node, "epsilon")});
|
||||
|
||||
// Add epsilon to the moving variance.
|
||||
const string epsilon_add_op_name = node.name() + "_epsilon";
|
||||
const std::string epsilon_add_op_name = node.name() + "_epsilon";
|
||||
auto* epsilon_add_op = new AddOperator;
|
||||
epsilon_add_op->inputs.push_back(moving_variance_input);
|
||||
epsilon_add_op->inputs.push_back(epsilon_array_name);
|
||||
@ -1821,14 +1826,14 @@ tensorflow::Status ConvertFusedBatchNormOperator(
|
||||
model->operators.emplace_back(epsilon_add_op);
|
||||
|
||||
// Take the inverse square root of the (variance + epsilon).
|
||||
const string rsqrt_op_name = node.name() + "_rsqrt";
|
||||
const std::string rsqrt_op_name = node.name() + "_rsqrt";
|
||||
auto* rsqrt_op = new TensorFlowRsqrtOperator;
|
||||
rsqrt_op->inputs.push_back(epsilon_add_op_name);
|
||||
rsqrt_op->outputs.push_back(rsqrt_op_name);
|
||||
model->operators.emplace_back(rsqrt_op);
|
||||
|
||||
// Multiply the result by gamma.
|
||||
const string multiplier = node.name() + "_mul";
|
||||
const std::string multiplier = node.name() + "_mul";
|
||||
auto* mul_op = new MulOperator;
|
||||
mul_op->inputs.push_back(rsqrt_op_name);
|
||||
mul_op->inputs.push_back(gamma_input);
|
||||
@ -1966,8 +1971,8 @@ tensorflow::Status ConvertTransposeConvOperator(
|
||||
<< "].";
|
||||
}
|
||||
|
||||
const string& weights_name = node.input(TransposeConvOperator::WEIGHTS);
|
||||
const string& transposed_weights_name = weights_name + "_transposed";
|
||||
const std::string& weights_name = node.input(TransposeConvOperator::WEIGHTS);
|
||||
const std::string& transposed_weights_name = weights_name + "_transposed";
|
||||
// Check if a TransposeOperator was already created for these weights
|
||||
// (can happen when multiple layers share the same weights).
|
||||
const Operator* existing_transpose =
|
||||
@ -1980,7 +1985,7 @@ tensorflow::Status ConvertTransposeConvOperator(
|
||||
// because they consider this a backward conv, inverting the sense of
|
||||
// input/output.)
|
||||
TransposeOperator* transpose = new TransposeOperator;
|
||||
string perm_array = CreateConstArray<ArrayDataType::kInt32>(
|
||||
std::string perm_array = CreateConstArray<ArrayDataType::kInt32>(
|
||||
model, node.name() + "_transpose_perm", {2, 0, 1, 3});
|
||||
transpose->inputs = {weights_name, perm_array};
|
||||
transpose->outputs = {transposed_weights_name};
|
||||
@ -2137,10 +2142,10 @@ tensorflow::Status ConvertReverseSequenceOperator(
|
||||
void StripCaretFromArrayNames(Model* model) {
|
||||
for (auto& op : model->operators) {
|
||||
for (auto& input : op->inputs) {
|
||||
input = string(absl::StripPrefix(input, "^"));
|
||||
input = std::string(absl::StripPrefix(input, "^"));
|
||||
}
|
||||
for (auto& output : op->outputs) {
|
||||
output = string(absl::StripPrefix(output, "^"));
|
||||
output = std::string(absl::StripPrefix(output, "^"));
|
||||
}
|
||||
}
|
||||
for (auto& array : model->GetArrayMap()) {
|
||||
@ -2152,7 +2157,7 @@ void StripCaretFromArrayNames(Model* model) {
|
||||
|
||||
void StripZeroOutputIndexFromInputs(NodeDef* node) {
|
||||
for (auto& input : *node->mutable_input()) {
|
||||
input = string(absl::StripSuffix(input, ":0"));
|
||||
input = std::string(absl::StripSuffix(input, ":0"));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2170,15 +2175,15 @@ void StripZeroOutputIndexFromInputs(NodeDef* node) {
|
||||
// all nodes, we can use that information.
|
||||
void AddExtraOutputs(Model* model) {
|
||||
// Construct the list of all arrays consumed by anything in the graph.
|
||||
std::vector<string> consumed_arrays;
|
||||
std::vector<std::string> consumed_arrays;
|
||||
// Add arrays consumed by an op.
|
||||
for (const auto& consumer_op : model->operators) {
|
||||
for (const string& input : consumer_op->inputs) {
|
||||
for (const std::string& input : consumer_op->inputs) {
|
||||
consumed_arrays.push_back(input);
|
||||
}
|
||||
}
|
||||
// Add global outputs of the model.
|
||||
for (const string& output_array : model->flags.output_arrays()) {
|
||||
for (const std::string& output_array : model->flags.output_arrays()) {
|
||||
consumed_arrays.push_back(output_array);
|
||||
}
|
||||
// Add arrays consumed by a RNN back-edge.
|
||||
@ -2187,7 +2192,7 @@ void AddExtraOutputs(Model* model) {
|
||||
}
|
||||
// Now add operator outputs so that all arrays that are consumed,
|
||||
// are produced.
|
||||
for (const string& consumed_array : consumed_arrays) {
|
||||
for (const std::string& consumed_array : consumed_arrays) {
|
||||
// Test if consumed_array is already the output of some op.
|
||||
// This has occurred in a model where separate nodes had names of the form
|
||||
// foo:$i with the same base name foo.
|
||||
@ -2195,7 +2200,7 @@ void AddExtraOutputs(Model* model) {
|
||||
continue;
|
||||
}
|
||||
// Split the consumed array name into the form name:output_index.
|
||||
const std::vector<string>& split = absl::StrSplit(consumed_array, ':');
|
||||
const std::vector<std::string>& split = absl::StrSplit(consumed_array, ':');
|
||||
// If not of the form name:output_index, then this is not an additional
|
||||
// output of a node with multiple outputs, so nothing to do here.
|
||||
if (split.size() != 2) {
|
||||
@ -2288,7 +2293,7 @@ tensorflow::Status ConvertTopKV2Operator(
|
||||
op->inputs.push_back(node.input(0));
|
||||
// K can be encoded as attr (TopK) convert it to a const.
|
||||
if (HasAttr(node, "k")) {
|
||||
string k_array = CreateConstArray<ArrayDataType::kInt32>(
|
||||
std::string k_array = CreateConstArray<ArrayDataType::kInt32>(
|
||||
model, node.name() + "k", {static_cast<int32>(GetIntAttr(node, "k"))});
|
||||
op->inputs.push_back(k_array);
|
||||
} else {
|
||||
@ -2346,7 +2351,7 @@ tensorflow::Status ConvertSparseToDenseOperator(
|
||||
TF_QCHECK_OK(CheckInputsCount(node, tf_import_flags, 4));
|
||||
|
||||
auto* op = new SparseToDenseOperator;
|
||||
for (const string& input : node.input()) {
|
||||
for (const std::string& input : node.input()) {
|
||||
op->inputs.push_back(input);
|
||||
}
|
||||
op->outputs.push_back(node.name());
|
||||
@ -2371,7 +2376,7 @@ tensorflow::Status ConvertOneHotOperator(
|
||||
|
||||
auto op = absl::make_unique<OneHotOperator>();
|
||||
op->axis = HasAttr(node, "axis") ? GetIntAttr(node, "axis") : -1;
|
||||
for (const string& input : node.input()) {
|
||||
for (const std::string& input : node.input()) {
|
||||
op->inputs.push_back(input);
|
||||
}
|
||||
op->outputs.push_back(node.name());
|
||||
@ -2386,7 +2391,7 @@ tensorflow::Status ConvertCTCBeamSearchDecoderOperator(
|
||||
TF_QCHECK_OK(CheckInputsCount(node, tf_import_flags, 2));
|
||||
|
||||
auto* op = new CTCBeamSearchDecoderOperator;
|
||||
for (const string& input : node.input()) {
|
||||
for (const std::string& input : node.input()) {
|
||||
op->inputs.push_back(input);
|
||||
}
|
||||
|
||||
@ -2434,7 +2439,7 @@ tensorflow::Status ConvertUnidirectionalSequenceLstm(
|
||||
count++;
|
||||
} else {
|
||||
// Optional input.
|
||||
string optional_name = node.name() + "_" + std::to_string(idx);
|
||||
std::string optional_name = node.name() + "_" + std::to_string(idx);
|
||||
model->CreateOptionalArray(optional_name);
|
||||
op->inputs[idx] = optional_name;
|
||||
}
|
||||
@ -2442,7 +2447,7 @@ tensorflow::Status ConvertUnidirectionalSequenceLstm(
|
||||
} else { // Legacy version.
|
||||
std::vector<bool> done(kInputsSize);
|
||||
int idx = 0;
|
||||
for (const string& input : node.input()) {
|
||||
for (const std::string& input : node.input()) {
|
||||
int real_index = indices.i(idx);
|
||||
op->inputs[real_index] = (input);
|
||||
done[real_index] = true;
|
||||
@ -2451,7 +2456,7 @@ tensorflow::Status ConvertUnidirectionalSequenceLstm(
|
||||
|
||||
for (int idx = 0; idx < done.size(); idx++) {
|
||||
if (!done[idx]) {
|
||||
string optional_name = node.name() + "_" + std::to_string(idx);
|
||||
std::string optional_name = node.name() + "_" + std::to_string(idx);
|
||||
model->CreateOptionalArray(optional_name);
|
||||
op->inputs[idx] = optional_name;
|
||||
}
|
||||
@ -2491,7 +2496,7 @@ tensorflow::Status ConvertUnidirectionalSequenceRnn(
|
||||
}
|
||||
|
||||
auto* op = new UnidirectionalSequenceRnnOperator();
|
||||
for (const string& input : node.input()) {
|
||||
for (const std::string& input : node.input()) {
|
||||
op->inputs.push_back(input);
|
||||
}
|
||||
// Only use the last one as input.
|
||||
@ -2703,7 +2708,8 @@ std::unique_ptr<Model> ImportTensorFlowGraphDef(
|
||||
<< "Unsupported explicit zero output index: "
|
||||
<< specified_input_array.name();
|
||||
}
|
||||
for (const string& specified_output_array : model_flags.output_arrays()) {
|
||||
for (const std::string& specified_output_array :
|
||||
model_flags.output_arrays()) {
|
||||
CHECK(!absl::EndsWith(specified_output_array, ":0"))
|
||||
<< "Unsupported explicit zero output index: " << specified_output_array;
|
||||
}
|
||||
@ -2746,7 +2752,7 @@ std::unique_ptr<Model> ImportTensorFlowGraphDef(
|
||||
|
||||
std::unique_ptr<Model> ImportTensorFlowGraphDef(
|
||||
const ModelFlags& model_flags, const TensorFlowImportFlags& tf_import_flags,
|
||||
const string& input_file_contents) {
|
||||
const std::string& input_file_contents) {
|
||||
std::unique_ptr<GraphDef> tf_graph(new GraphDef);
|
||||
CHECK(ParseFromStringEitherTextOrBinary(input_file_contents, tf_graph.get()));
|
||||
|
||||
|
@ -43,7 +43,7 @@ std::unique_ptr<Model> ImportTensorFlowGraphDef(
|
||||
// flags.
|
||||
std::unique_ptr<Model> ImportTensorFlowGraphDef(
|
||||
const ModelFlags& model_flags, const TensorFlowImportFlags& tf_import_flags,
|
||||
const string& input_file_contents);
|
||||
const std::string& input_file_contents);
|
||||
|
||||
// Gets a list of supported ops by their names.
|
||||
std::vector<std::string> GetPotentiallySupportedOps();
|
||||
|
@ -163,7 +163,7 @@ void BuildConstNode(std::initializer_list<int64_t> shape,
|
||||
TEST(FlexImportTest, ConditionalConst) {
|
||||
Model model;
|
||||
auto build_and_import_node =
|
||||
[&model](const string& name, std::initializer_list<int64_t> shape,
|
||||
[&model](const std::string& name, std::initializer_list<int64_t> shape,
|
||||
tensorflow::DataType dtype, int64_t num_elements) {
|
||||
NodeDef node;
|
||||
BuildConstNode(shape, dtype, num_elements, &node);
|
||||
@ -486,8 +486,8 @@ class TensorContentTest : public ::testing::Test {
|
||||
break;
|
||||
}
|
||||
t.set_tensor_content(
|
||||
string(reinterpret_cast<const char*>(allocated_content.get()),
|
||||
num_elements * sizeof(T)));
|
||||
std::string(reinterpret_cast<const char*>(allocated_content.get()),
|
||||
num_elements * sizeof(T)));
|
||||
|
||||
AttrValue value_attr;
|
||||
SetAttrValue(t, &value_attr);
|
||||
|
@ -287,7 +287,7 @@ struct DataTypeImpl<ArrayDataType::kUint64> {
|
||||
};
|
||||
template <>
|
||||
struct DataTypeImpl<ArrayDataType::kString> {
|
||||
typedef string Type;
|
||||
typedef std::string Type;
|
||||
};
|
||||
template <>
|
||||
struct DataTypeImpl<ArrayDataType::kComplex64> {
|
||||
@ -398,10 +398,10 @@ struct Operator {
|
||||
// names to addresses is given by the Model, which owns both Operator's and
|
||||
// Array's. Thus, an Operator on its own doesn't contain much information,
|
||||
// it is meant to be used in conjunction with the Model that owns it.
|
||||
std::vector<string> inputs;
|
||||
std::vector<std::string> inputs;
|
||||
|
||||
// Output activation arrays. Same comments as for inputs apply here too.
|
||||
std::vector<string> outputs;
|
||||
std::vector<std::string> outputs;
|
||||
|
||||
// If true, the operator has more outputs than are listed in the 'outputs'
|
||||
// member. These need to be resolved by some graph transformation.
|
||||
@ -415,7 +415,7 @@ struct Operator {
|
||||
// It's guaranteed to be filled for `TensorFlowUnsupportedOperator`.
|
||||
// It's not guaranteed to be filled for other ops. Ops created by graph
|
||||
// transformations won't have TensorFlow NodeDef.
|
||||
string tensorflow_node_def;
|
||||
std::string tensorflow_node_def;
|
||||
|
||||
protected:
|
||||
// Constructor used by subclasses for specific OperatorType's.
|
||||
@ -1693,7 +1693,7 @@ struct TensorFlowUnsupportedOperator : Operator {
|
||||
TensorFlowUnsupportedOperator() : Operator(OperatorType::kUnsupported) {}
|
||||
|
||||
// The original TF operation type. Used for diagnostic purposes.
|
||||
string tensorflow_op;
|
||||
std::string tensorflow_op;
|
||||
// A boolean indicating if the unsupported op should be treated as quantized.
|
||||
bool quantized = false;
|
||||
// A boolean indicating if the unsupported op output should allow float values
|
||||
@ -2393,14 +2393,16 @@ struct Array {
|
||||
// Owns everything.
|
||||
class Model {
|
||||
public:
|
||||
using ArrayMap = std::unordered_map<string, std::unique_ptr<Array>>;
|
||||
using ArrayMap = std::unordered_map<std::string, std::unique_ptr<Array>>;
|
||||
|
||||
bool HasArray(const string& name) const { return arrays.count(name) > 0; }
|
||||
Array& GetArray(const string& name) const {
|
||||
bool HasArray(const std::string& name) const {
|
||||
return arrays.count(name) > 0;
|
||||
}
|
||||
Array& GetArray(const std::string& name) const {
|
||||
DCHECK(HasArray(name)) << "Array not found: " << name;
|
||||
return *arrays.at(name);
|
||||
}
|
||||
Array& GetOrCreateArray(const string& name) {
|
||||
Array& GetOrCreateArray(const std::string& name) {
|
||||
// Make sure name is not used by an optional array
|
||||
DCHECK(!optional_arrays.count(name));
|
||||
if (!HasArray(name)) {
|
||||
@ -2410,17 +2412,17 @@ class Model {
|
||||
Array& result = GetArray(name);
|
||||
return result;
|
||||
}
|
||||
void CreateOptionalArray(const string& name) {
|
||||
void CreateOptionalArray(const std::string& name) {
|
||||
DCHECK(!arrays.count(name) && !optional_arrays.count(name));
|
||||
optional_arrays.insert(name);
|
||||
}
|
||||
bool IsOptionalArray(const string& name) const {
|
||||
bool IsOptionalArray(const std::string& name) const {
|
||||
return optional_arrays.count(name);
|
||||
}
|
||||
|
||||
// Note that this invalidates all array iterators.
|
||||
void EraseArray(const string& name) { arrays.erase(name); }
|
||||
void EraseArrays(std::function<bool(const string&)> discardable) {
|
||||
void EraseArray(const std::string& name) { arrays.erase(name); }
|
||||
void EraseArrays(std::function<bool(const std::string&)> discardable) {
|
||||
for (auto it = arrays.begin(); it != arrays.end();) {
|
||||
if (discardable(it->first)) {
|
||||
it = arrays.erase(it);
|
||||
@ -2434,17 +2436,17 @@ class Model {
|
||||
|
||||
int64 ArithmeticOpsCount() const { return ops_count; }
|
||||
|
||||
void AddInvalidInputArray(string invalid_input_array) {
|
||||
void AddInvalidInputArray(std::string invalid_input_array) {
|
||||
invalid_input_arrays_.insert(invalid_input_array);
|
||||
}
|
||||
|
||||
const std::unordered_set<string>& GetInvalidInputArrays() const {
|
||||
const std::unordered_set<std::string>& GetInvalidInputArrays() const {
|
||||
return invalid_input_arrays_;
|
||||
}
|
||||
|
||||
// Optional arrays are used for optional tensors,
|
||||
// these tensors do not have data, but with reserved names as op inputs.
|
||||
std::set<string> optional_arrays;
|
||||
std::set<std::string> optional_arrays;
|
||||
|
||||
// The list of operators. Notice how it's a list of unique_ptr's, implying
|
||||
// that the Model is what owns Operator's and keeps them alive.
|
||||
@ -2467,10 +2469,10 @@ class Model {
|
||||
// that the Model is what owns Array's and keeps them alive.
|
||||
// The Operator's refer to these Array's by their name strings, not by their
|
||||
// addresses. See Operator::inputs, Operator::outputs.
|
||||
std::unordered_map<string, std::unique_ptr<Array>> arrays;
|
||||
std::unordered_map<std::string, std::unique_ptr<Array>> arrays;
|
||||
|
||||
// Invalid input arrays.
|
||||
std::unordered_set<string> invalid_input_arrays_;
|
||||
std::unordered_set<std::string> invalid_input_arrays_;
|
||||
};
|
||||
|
||||
// OperatorSignature contains the information required to making versioning
|
||||
|
@ -36,7 +36,7 @@ limitations under the License.
|
||||
namespace toco {
|
||||
|
||||
bool ParseModelFlagsFromCommandLineFlags(
|
||||
int* argc, char* argv[], string* msg,
|
||||
int* argc, char* argv[], std::string* msg,
|
||||
ParsedModelFlags* parsed_model_flags_ptr) {
|
||||
ParsedModelFlags& parsed_flags = *parsed_model_flags_ptr;
|
||||
using tensorflow::Flag;
|
||||
@ -188,7 +188,7 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
// Load proto containing the initial model flags.
|
||||
// Additional flags specified on the command line will overwrite the values.
|
||||
if (parsed_model_flags.model_flags_file.specified()) {
|
||||
string model_flags_file_contents;
|
||||
std::string model_flags_file_contents;
|
||||
QCHECK(port::file::GetContents(parsed_model_flags.model_flags_file.value(),
|
||||
&model_flags_file_contents,
|
||||
port::file::Defaults())
|
||||
@ -217,9 +217,9 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
}
|
||||
|
||||
if (parsed_model_flags.output_arrays.specified()) {
|
||||
std::vector<string> output_arrays =
|
||||
std::vector<std::string> output_arrays =
|
||||
absl::StrSplit(parsed_model_flags.output_arrays.value(), ',');
|
||||
for (const string& output_array : output_arrays) {
|
||||
for (const std::string& output_array : output_arrays) {
|
||||
model_flags->add_output_arrays(output_array);
|
||||
}
|
||||
}
|
||||
@ -251,7 +251,7 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
QCHECK(uses_multi_input_flags);
|
||||
for (const auto& input_array :
|
||||
absl::StrSplit(parsed_model_flags.input_arrays.value(), ',')) {
|
||||
model_flags->add_input_arrays()->set_name(string(input_array));
|
||||
model_flags->add_input_arrays()->set_name(std::string(input_array));
|
||||
}
|
||||
}
|
||||
if (parsed_model_flags.mean_value.specified()) {
|
||||
@ -261,7 +261,7 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
}
|
||||
if (parsed_model_flags.mean_values.specified()) {
|
||||
QCHECK(uses_multi_input_flags);
|
||||
std::vector<string> mean_values =
|
||||
std::vector<std::string> mean_values =
|
||||
absl::StrSplit(parsed_model_flags.mean_values.value(), ',');
|
||||
QCHECK(mean_values.size() == model_flags->input_arrays_size());
|
||||
for (size_t i = 0; i < mean_values.size(); ++i) {
|
||||
@ -278,7 +278,7 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
}
|
||||
if (parsed_model_flags.std_values.specified()) {
|
||||
QCHECK(uses_multi_input_flags);
|
||||
std::vector<string> std_values =
|
||||
std::vector<std::string> std_values =
|
||||
absl::StrSplit(parsed_model_flags.std_values.value(), ',');
|
||||
QCHECK(std_values.size() == model_flags->input_arrays_size());
|
||||
for (size_t i = 0; i < std_values.size(); ++i) {
|
||||
@ -296,7 +296,7 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
}
|
||||
if (parsed_model_flags.input_data_types.specified()) {
|
||||
QCHECK(uses_multi_input_flags);
|
||||
std::vector<string> input_data_types =
|
||||
std::vector<std::string> input_data_types =
|
||||
absl::StrSplit(parsed_model_flags.input_data_types.value(), ',');
|
||||
QCHECK(input_data_types.size() == model_flags->input_arrays_size());
|
||||
for (size_t i = 0; i < input_data_types.size(); ++i) {
|
||||
@ -319,7 +319,7 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
}
|
||||
if (parsed_model_flags.input_shapes.specified()) {
|
||||
QCHECK(uses_multi_input_flags);
|
||||
std::vector<string> input_shapes =
|
||||
std::vector<std::string> input_shapes =
|
||||
absl::StrSplit(parsed_model_flags.input_shapes.value(), ':');
|
||||
QCHECK(input_shapes.size() == model_flags->input_arrays_size());
|
||||
for (size_t i = 0; i < input_shapes.size(); ++i) {
|
||||
@ -352,8 +352,8 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
for (const auto& element : parsed_model_flags.rnn_states.value().elements) {
|
||||
auto* rnn_state_proto = model_flags->add_rnn_states();
|
||||
for (const auto& kv_pair : element) {
|
||||
const string& key = kv_pair.first;
|
||||
const string& value = kv_pair.second;
|
||||
const std::string& key = kv_pair.first;
|
||||
const std::string& value = kv_pair.second;
|
||||
if (key == "state_array") {
|
||||
rnn_state_proto->set_state_array(value);
|
||||
} else if (key == "back_edge_source_array") {
|
||||
@ -377,8 +377,8 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
for (const auto& element : parsed_model_flags.model_checks.value().elements) {
|
||||
auto* model_check_proto = model_flags->add_model_checks();
|
||||
for (const auto& kv_pair : element) {
|
||||
const string& key = kv_pair.first;
|
||||
const string& value = kv_pair.second;
|
||||
const std::string& key = kv_pair.first;
|
||||
const std::string& value = kv_pair.second;
|
||||
if (key == "count_type") {
|
||||
model_check_proto->set_count_type(value);
|
||||
} else if (key == "count_min") {
|
||||
@ -411,7 +411,7 @@ void ReadModelFlagsFromCommandLineFlags(
|
||||
}
|
||||
|
||||
if (parsed_model_flags.arrays_extra_info_file.specified()) {
|
||||
string arrays_extra_info_file_contents;
|
||||
std::string arrays_extra_info_file_contents;
|
||||
CHECK(port::file::GetContents(
|
||||
parsed_model_flags.arrays_extra_info_file.value(),
|
||||
&arrays_extra_info_file_contents, port::file::Defaults())
|
||||
@ -443,7 +443,7 @@ void ParseModelFlagsOrDie(int* argc, char* argv[]) {
|
||||
// TODO(aselle): in the future allow Google version to use
|
||||
// flags, and only use this mechanism for open source
|
||||
auto* flags = UncheckedGlobalParsedModelFlags(false);
|
||||
string msg;
|
||||
std::string msg;
|
||||
bool model_success =
|
||||
toco::ParseModelFlagsFromCommandLineFlags(argc, argv, &msg, flags);
|
||||
if (!model_success || !msg.empty()) {
|
||||
|
@ -28,7 +28,7 @@ namespace toco {
|
||||
// is successful. msg has the usage string if there was an error or
|
||||
// "--help" was specified
|
||||
bool ParseModelFlagsFromCommandLineFlags(
|
||||
int* argc, char* argv[], string* msg,
|
||||
int* argc, char* argv[], std::string* msg,
|
||||
ParsedModelFlags* parsed_model_flags_ptr);
|
||||
// Populate the ModelFlags proto with model data.
|
||||
void ReadModelFlagsFromCommandLineFlags(
|
||||
|
@ -35,8 +35,8 @@ TEST(ModelCmdlineFlagsTest, ParseArgsStringMapList) {
|
||||
"back_edge_source_array:rnn/basic_lstm_cell/Mul_2,size:4}",
|
||||
nullptr};
|
||||
|
||||
string expected_input_arrays = "input_1";
|
||||
std::vector<std::unordered_map<string, string>> expected_rnn_states;
|
||||
std::string expected_input_arrays = "input_1";
|
||||
std::vector<std::unordered_map<std::string, std::string>> expected_rnn_states;
|
||||
expected_rnn_states.push_back(
|
||||
{{"state_array", "rnn/BasicLSTMCellZeroState/zeros"},
|
||||
{"back_edge_source_array", "rnn/basic_lstm_cell/Add_1"},
|
||||
@ -46,7 +46,7 @@ TEST(ModelCmdlineFlagsTest, ParseArgsStringMapList) {
|
||||
{"back_edge_source_array", "rnn/basic_lstm_cell/Mul_2"},
|
||||
{"size", "4"}});
|
||||
|
||||
string message;
|
||||
std::string message;
|
||||
ParsedModelFlags result_flags;
|
||||
|
||||
EXPECT_TRUE(ParseModelFlagsFromCommandLineFlags(
|
||||
|
@ -37,16 +37,16 @@ namespace toco {
|
||||
using tensorflow::AttrValue;
|
||||
using tensorflow::GraphDef;
|
||||
|
||||
void LogDumpGraphDef(int log_level, const string& message,
|
||||
void LogDumpGraphDef(int log_level, const std::string& message,
|
||||
const GraphDef& tf_graph) {
|
||||
if (!VLOG_IS_ON(log_level)) {
|
||||
return;
|
||||
}
|
||||
std::set<string> ops;
|
||||
std::set<std::string> ops;
|
||||
for (const auto& node : tf_graph.node()) {
|
||||
ops.insert(node.op());
|
||||
}
|
||||
string dump;
|
||||
std::string dump;
|
||||
toco::port::AppendF(&dump, R"MSG(
|
||||
BEGIN DUMP OF TENSORFLOW GRAPHDEF (%s)
|
||||
There are %d nodes.
|
||||
|
@ -24,7 +24,7 @@ limitations under the License.
|
||||
|
||||
namespace toco {
|
||||
|
||||
void LogDumpGraphDef(int log_level, const string& message,
|
||||
void LogDumpGraphDef(int log_level, const std::string& message,
|
||||
const tensorflow::GraphDef& tf_graph);
|
||||
|
||||
} // namespace toco
|
||||
|
@ -21,7 +21,7 @@ limitations under the License.
|
||||
#include "tensorflow/lite/toco/toco_convert.h"
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
toco::string msg;
|
||||
std::string msg;
|
||||
toco::ParsedTocoFlags parsed_toco_flags;
|
||||
toco::ParsedModelFlags parsed_model_flags;
|
||||
|
||||
|
@ -29,7 +29,7 @@ limitations under the License.
|
||||
namespace toco {
|
||||
|
||||
bool ParseTocoFlagsFromCommandLineFlags(
|
||||
int* argc, char* argv[], string* msg,
|
||||
int* argc, char* argv[], std::string* msg,
|
||||
ParsedTocoFlags* parsed_toco_flags_ptr) {
|
||||
using tensorflow::Flag;
|
||||
ParsedTocoFlags& parsed_flags = *parsed_toco_flags_ptr;
|
||||
@ -212,7 +212,7 @@ enum class FlagRequirement {
|
||||
|
||||
// Enforces the FlagRequirements are met for a given flag.
|
||||
template <typename T>
|
||||
void EnforceFlagRequirement(const T& flag, const string& flag_name,
|
||||
void EnforceFlagRequirement(const T& flag, const std::string& flag_name,
|
||||
FlagRequirement requirement) {
|
||||
if (requirement == FlagRequirement::kMustBeSpecified) {
|
||||
QCHECK(flag.specified()) << "Missing required flag " << flag_name;
|
||||
@ -317,7 +317,7 @@ void ReadTocoFlagsFromCommandLineFlags(const ParsedTocoFlags& parsed_toco_flags,
|
||||
"type of input arrays, use --input_data_type. If you are trying to "
|
||||
"control the quantization/dequantization of real-numbers input "
|
||||
"arrays in the output file, use --inference_input_type.";
|
||||
std::vector<string> input_types =
|
||||
std::vector<std::string> input_types =
|
||||
absl::StrSplit(parsed_toco_flags.input_types.value(), ',');
|
||||
QCHECK(!input_types.empty());
|
||||
for (int i = 1; i < input_types.size(); i++) {
|
||||
|
@ -25,7 +25,8 @@ namespace toco {
|
||||
// Parse and remove arguments handled from toco. Returns true if parsing
|
||||
// is successful. msg has the usage string if there was an error or
|
||||
// "--help" was specified
|
||||
bool ParseTocoFlagsFromCommandLineFlags(int* argc, char* argv[], string* msg,
|
||||
bool ParseTocoFlagsFromCommandLineFlags(int* argc, char* argv[],
|
||||
std::string* msg,
|
||||
ParsedTocoFlags* parsed_toco_flags_ptr);
|
||||
// Populate the TocoFlags proto with parsed_toco_flags data.
|
||||
void ReadTocoFlagsFromCommandLineFlags(const ParsedTocoFlags& parsed_toco_flags,
|
||||
|
@ -29,7 +29,7 @@ TEST(TocoCmdlineFlagsTest, DefaultValue) {
|
||||
// TF flag parsing lib is relaying on this invariant.
|
||||
const char* args[] = {"toco", nullptr};
|
||||
|
||||
string message;
|
||||
std::string message;
|
||||
ParsedTocoFlags result_flags;
|
||||
|
||||
EXPECT_TRUE(ParseTocoFlagsFromCommandLineFlags(
|
||||
@ -41,7 +41,7 @@ TEST(TocoCmdlineFlagsTest, ParseFlags) {
|
||||
int argc = 2;
|
||||
const char* args[] = {"toco", "--allow_dynamic_tensors=false", nullptr};
|
||||
|
||||
string message;
|
||||
std::string message;
|
||||
ParsedTocoFlags result_flags;
|
||||
|
||||
EXPECT_TRUE(ParseTocoFlagsFromCommandLineFlags(
|
||||
|
@ -32,7 +32,7 @@ namespace toco {
|
||||
namespace {
|
||||
|
||||
// Checks the permissions of the output file to ensure it is writeable.
|
||||
void CheckOutputFilePermissions(const Arg<string>& output_file) {
|
||||
void CheckOutputFilePermissions(const Arg<std::string>& output_file) {
|
||||
QCHECK(output_file.specified()) << "Missing required flag --output_file.\n";
|
||||
QCHECK(port::file::Writable(output_file.value()).ok())
|
||||
<< "Specified output_file is not writable: " << output_file.value()
|
||||
@ -40,7 +40,7 @@ void CheckOutputFilePermissions(const Arg<string>& output_file) {
|
||||
}
|
||||
|
||||
// Checks the permissions of the frozen model file.
|
||||
void CheckFrozenModelPermissions(const Arg<string>& input_file) {
|
||||
void CheckFrozenModelPermissions(const Arg<std::string>& input_file) {
|
||||
QCHECK(input_file.specified()) << "Missing required flag --input_file.\n";
|
||||
QCHECK(port::file::Exists(input_file.value(), port::file::Defaults()).ok())
|
||||
<< "Specified input_file does not exist: " << input_file.value() << ".\n";
|
||||
@ -55,7 +55,7 @@ void CheckFrozenModelPermissions(const Arg<string>& input_file) {
|
||||
void ReadInputData(const ParsedTocoFlags& parsed_toco_flags,
|
||||
const ParsedModelFlags& parsed_model_flags,
|
||||
TocoFlags* toco_flags, ModelFlags* model_flags,
|
||||
string* graph_def_contents) {
|
||||
std::string* graph_def_contents) {
|
||||
port::CheckInitGoogleIsDone("InitGoogle is not done yet.\n");
|
||||
|
||||
// Ensure savedmodel_directory is not set.
|
||||
@ -71,10 +71,10 @@ void ReadInputData(const ParsedTocoFlags& parsed_toco_flags,
|
||||
}
|
||||
} // namespace
|
||||
|
||||
tensorflow::Status Convert(const string& graph_def_contents,
|
||||
tensorflow::Status Convert(const std::string& graph_def_contents,
|
||||
const TocoFlags& toco_flags,
|
||||
const ModelFlags& model_flags,
|
||||
string* output_file_contents,
|
||||
std::string* output_file_contents,
|
||||
int64* arithmetic_ops_count = nullptr) {
|
||||
std::unique_ptr<Model> model =
|
||||
Import(toco_flags, model_flags, graph_def_contents);
|
||||
@ -95,12 +95,12 @@ tensorflow::Status Convert(const ParsedTocoFlags& parsed_toco_flags,
|
||||
TocoFlags toco_flags;
|
||||
ReadTocoFlagsFromCommandLineFlags(parsed_toco_flags, &toco_flags);
|
||||
|
||||
string graph_def_contents;
|
||||
std::string graph_def_contents;
|
||||
ReadInputData(parsed_toco_flags, parsed_model_flags, &toco_flags,
|
||||
&model_flags, &graph_def_contents);
|
||||
CheckOutputFilePermissions(parsed_toco_flags.output_file);
|
||||
|
||||
string output_file_contents;
|
||||
std::string output_file_contents;
|
||||
TF_RETURN_IF_ERROR(Convert(graph_def_contents, toco_flags, model_flags,
|
||||
&output_file_contents));
|
||||
|
||||
|
@ -22,10 +22,10 @@ limitations under the License.
|
||||
|
||||
namespace toco {
|
||||
|
||||
tensorflow::Status Convert(const string& graph_def_contents,
|
||||
tensorflow::Status Convert(const std::string& graph_def_contents,
|
||||
const TocoFlags& toco_flags,
|
||||
const ModelFlags& model_flags,
|
||||
string* output_file_contents,
|
||||
std::string* output_file_contents,
|
||||
int64* arithmetic_ops_count = nullptr);
|
||||
|
||||
tensorflow::Status Convert(const ParsedTocoFlags& parsed_toco_flags,
|
||||
|
@ -32,8 +32,8 @@ TEST(TocoTest, BadInputFormat) {
|
||||
TocoFlags toco_flags;
|
||||
ModelFlags model_flags;
|
||||
|
||||
string input;
|
||||
string output;
|
||||
std::string input;
|
||||
std::string output;
|
||||
|
||||
EXPECT_DEATH(Convert(input, toco_flags, model_flags, &output).ok(),
|
||||
"Unhandled input_format='FILE_FORMAT_UNKNOWN'");
|
||||
@ -44,8 +44,8 @@ TEST(TocoTest, MissingOutputArrays) {
|
||||
ModelFlags model_flags;
|
||||
|
||||
toco_flags.set_input_format(TENSORFLOW_GRAPHDEF);
|
||||
string input;
|
||||
string output;
|
||||
std::string input;
|
||||
std::string output;
|
||||
|
||||
EXPECT_DEATH(Convert(input, toco_flags, model_flags, &output).ok(),
|
||||
"This model does not define output arrays, so a --output_arrays "
|
||||
@ -58,8 +58,8 @@ TEST(TocoTest, BadOutputArray) {
|
||||
|
||||
toco_flags.set_input_format(TENSORFLOW_GRAPHDEF);
|
||||
model_flags.add_output_arrays("output1");
|
||||
string input;
|
||||
string output;
|
||||
std::string input;
|
||||
std::string output;
|
||||
|
||||
EXPECT_DEATH(Convert(input, toco_flags, model_flags, &output).ok(),
|
||||
"Specified output array .output1. is not produced by any op "
|
||||
@ -72,7 +72,7 @@ TEST(TocoTest, BadOutputFormat) {
|
||||
|
||||
toco_flags.set_input_format(TENSORFLOW_GRAPHDEF);
|
||||
model_flags.add_output_arrays("output1");
|
||||
string input = R"GraphDef(
|
||||
std::string input = R"GraphDef(
|
||||
node {
|
||||
name: "output1"
|
||||
input: "input1"
|
||||
@ -82,7 +82,7 @@ TEST(TocoTest, BadOutputFormat) {
|
||||
}
|
||||
)GraphDef";
|
||||
|
||||
string output;
|
||||
std::string output;
|
||||
|
||||
EXPECT_DEATH(Convert(input, toco_flags, model_flags, &output).ok(),
|
||||
"Unhandled output_format='FILE_FORMAT_UNKNOWN'");
|
||||
@ -97,7 +97,7 @@ TEST(TocoTest, SimpleFloatModel) {
|
||||
|
||||
// Inputs are automatically selected (but that might not be a good idea).
|
||||
model_flags.add_output_arrays("output1");
|
||||
string input = R"GraphDef(
|
||||
std::string input = R"GraphDef(
|
||||
node {
|
||||
name: "input1"
|
||||
op: "Placeholder"
|
||||
@ -117,7 +117,7 @@ TEST(TocoTest, SimpleFloatModel) {
|
||||
}
|
||||
)GraphDef";
|
||||
|
||||
string output;
|
||||
std::string output;
|
||||
EXPECT_TRUE(Convert(input, toco_flags, model_flags, &output).ok());
|
||||
EXPECT_TRUE(!output.empty());
|
||||
}
|
||||
@ -139,7 +139,7 @@ TEST(TocoTest, TransientStringTensors) {
|
||||
indices_1->set_name("indices1");
|
||||
|
||||
model_flags.add_output_arrays("output1");
|
||||
string input = R"GraphDef(
|
||||
std::string input = R"GraphDef(
|
||||
node {
|
||||
name: "input1"
|
||||
op: "Placeholder"
|
||||
@ -169,7 +169,7 @@ TEST(TocoTest, TransientStringTensors) {
|
||||
}
|
||||
)GraphDef";
|
||||
|
||||
string output;
|
||||
std::string output;
|
||||
|
||||
EXPECT_TRUE(Convert(input, toco_flags, model_flags, &output).ok());
|
||||
EXPECT_TRUE(!output.empty());
|
||||
|
@ -28,7 +28,7 @@ double round(double x) { return ::round(x); }
|
||||
|
||||
namespace toco {
|
||||
namespace port {
|
||||
void CopyToBuffer(const string& src, char* dest) {
|
||||
void CopyToBuffer(const std::string& src, char* dest) {
|
||||
memcpy(dest, src.data(), src.size());
|
||||
}
|
||||
|
||||
@ -84,7 +84,7 @@ toco::port::file::Options ToOptions(const ::file::Options& options) {
|
||||
return Options();
|
||||
}
|
||||
|
||||
tensorflow::Status Writable(const string& filename) {
|
||||
tensorflow::Status Writable(const std::string& filename) {
|
||||
File* f = nullptr;
|
||||
const auto status = ::file::Open(filename, "w", &f, ::file::Defaults());
|
||||
if (f) {
|
||||
@ -93,28 +93,30 @@ tensorflow::Status Writable(const string& filename) {
|
||||
return ToStatus(status);
|
||||
}
|
||||
|
||||
tensorflow::Status Readable(const string& filename,
|
||||
tensorflow::Status Readable(const std::string& filename,
|
||||
const file::Options& options) {
|
||||
return ToStatus(::file::Readable(filename, ::file::Defaults()));
|
||||
}
|
||||
|
||||
tensorflow::Status Exists(const string& filename,
|
||||
tensorflow::Status Exists(const std::string& filename,
|
||||
const file::Options& options) {
|
||||
auto status = ::file::Exists(filename, ::file::Defaults());
|
||||
return ToStatus(status);
|
||||
}
|
||||
|
||||
tensorflow::Status GetContents(const string& filename, string* contents,
|
||||
tensorflow::Status GetContents(const std::string& filename,
|
||||
std::string* contents,
|
||||
const file::Options& options) {
|
||||
return ToStatus(::file::GetContents(filename, contents, ::file::Defaults()));
|
||||
}
|
||||
|
||||
tensorflow::Status SetContents(const string& filename, const string& contents,
|
||||
tensorflow::Status SetContents(const std::string& filename,
|
||||
const std::string& contents,
|
||||
const file::Options& options) {
|
||||
return ToStatus(::file::SetContents(filename, contents, ::file::Defaults()));
|
||||
}
|
||||
|
||||
string JoinPath(const string& a, const string& b) {
|
||||
std::string JoinPath(const std::string& a, const std::string& b) {
|
||||
return ::file::JoinPath(a, b);
|
||||
}
|
||||
|
||||
|
@ -68,21 +68,23 @@ inline Options Defaults() {
|
||||
Options o;
|
||||
return o;
|
||||
}
|
||||
tensorflow::Status GetContents(const string& filename, string* contents,
|
||||
tensorflow::Status GetContents(const std::string& filename,
|
||||
std::string* contents, const Options& options);
|
||||
tensorflow::Status SetContents(const std::string& filename,
|
||||
const std::string& contents,
|
||||
const Options& options);
|
||||
tensorflow::Status SetContents(const string& filename, const string& contents,
|
||||
const Options& options);
|
||||
string JoinPath(const string& base, const string& filename);
|
||||
tensorflow::Status Writable(const string& filename);
|
||||
tensorflow::Status Readable(const string& filename, const Options& options);
|
||||
tensorflow::Status Exists(const string& filename, const Options& options);
|
||||
std::string JoinPath(const std::string& base, const std::string& filename);
|
||||
tensorflow::Status Writable(const std::string& filename);
|
||||
tensorflow::Status Readable(const std::string& filename,
|
||||
const Options& options);
|
||||
tensorflow::Status Exists(const std::string& filename, const Options& options);
|
||||
} // namespace file
|
||||
|
||||
// Copy `src` string to `dest`. User must ensure `dest` has enough space.
|
||||
#if defined(PLATFORM_GOOGLE)
|
||||
void CopyToBuffer(const ::absl::Cord& src, char* dest);
|
||||
#endif // PLATFORM_GOOGLE
|
||||
void CopyToBuffer(const string& src, char* dest);
|
||||
void CopyToBuffer(const std::string& src, char* dest);
|
||||
|
||||
inline uint32 ReverseBits32(uint32 n) {
|
||||
n = ((n >> 1) & 0x55555555) | ((n & 0x55555555) << 1);
|
||||
|
@ -37,7 +37,7 @@ namespace toco {
|
||||
namespace {
|
||||
// CHECK-fails if the model contains a kUnsupported operation.
|
||||
void CheckUnsupportedOperations(const Model& model) {
|
||||
std::set<string> unsupported_ops;
|
||||
std::set<std::string> unsupported_ops;
|
||||
for (auto& op : model.operators) {
|
||||
if (op->type == OperatorType::kUnsupported) {
|
||||
unsupported_ops.insert(
|
||||
@ -172,7 +172,7 @@ void SetFinalDataTypeOnInputs(const TocoFlags& toco_flags, Model* model) {
|
||||
}
|
||||
|
||||
for (int i = 0; i < model->flags.input_arrays_size(); i++) {
|
||||
string const& array_name = model->flags.input_arrays(i).name();
|
||||
std::string const& array_name = model->flags.input_arrays(i).name();
|
||||
auto* array = &model->GetArray(array_name);
|
||||
// Note that the notion of changing data types only applies to real-numbers
|
||||
// arrays (see the documentation for inference_input_type).
|
||||
@ -209,7 +209,7 @@ void SetFinalDataTypeOnInputs(const TocoFlags& toco_flags, Model* model) {
|
||||
|
||||
std::unique_ptr<Model> Import(const TocoFlags& toco_flags,
|
||||
const ModelFlags& model_flags,
|
||||
const string& input_file_contents) {
|
||||
const std::string& input_file_contents) {
|
||||
std::unique_ptr<Model> model;
|
||||
switch (toco_flags.input_format()) {
|
||||
case TENSORFLOW_GRAPHDEF: {
|
||||
@ -473,7 +473,8 @@ tensorflow::Status TransformWithStatus(const TocoFlags& toco_flags,
|
||||
}
|
||||
|
||||
tensorflow::Status Export(const TocoFlags& toco_flags, const Model& model,
|
||||
bool allow_custom_ops, string* output_file_contents) {
|
||||
bool allow_custom_ops,
|
||||
std::string* output_file_contents) {
|
||||
switch (toco_flags.output_format()) {
|
||||
case TENSORFLOW_GRAPHDEF:
|
||||
ExportTensorFlowGraphDef(model, output_file_contents);
|
||||
|
@ -27,7 +27,7 @@ namespace toco {
|
||||
// Imports the input file into a Model object.
|
||||
std::unique_ptr<Model> Import(const TocoFlags& toco_flags,
|
||||
const ModelFlags& model_flags,
|
||||
const string& input_file_contents);
|
||||
const std::string& input_file_contents);
|
||||
|
||||
// Transforms a Model. The resulting Model is ready to be passed
|
||||
// to Export with the exact same toco_flags.
|
||||
@ -42,11 +42,12 @@ inline void Transform(const TocoFlags& toco_flags, Model* model) {
|
||||
// Transform, to a file of the format given by
|
||||
// toco_flags.output_format().
|
||||
tensorflow::Status Export(const TocoFlags& toco_flags, const Model& model,
|
||||
bool allow_custom_ops, string* output_file_contents);
|
||||
bool allow_custom_ops,
|
||||
std::string* output_file_contents);
|
||||
|
||||
// This if for backward-compatibility with internal tools.
|
||||
inline void Export(const TocoFlags& toco_flags, const Model& model,
|
||||
string* output_file_contents) {
|
||||
std::string* output_file_contents) {
|
||||
auto status = Export(toco_flags, model, true, output_file_contents);
|
||||
if (!status.ok()) {
|
||||
LOG(QFATAL) << status.error_message();
|
||||
|
@ -53,8 +53,8 @@ absl::string_view FindLongestCommonPrefix(absl::string_view a,
|
||||
return absl::string_view(a.data(), count);
|
||||
}
|
||||
|
||||
string LogName(const Operator& op) {
|
||||
const string& opname = HelpfulOperatorTypeName(op);
|
||||
std::string LogName(const Operator& op) {
|
||||
const std::string& opname = HelpfulOperatorTypeName(op);
|
||||
if (op.outputs.empty()) {
|
||||
return toco::port::StringF("{%s operator}", opname);
|
||||
} else {
|
||||
@ -63,7 +63,7 @@ string LogName(const Operator& op) {
|
||||
}
|
||||
}
|
||||
|
||||
string ArrayDataTypeName(ArrayDataType data_type) {
|
||||
std::string ArrayDataTypeName(ArrayDataType data_type) {
|
||||
switch (data_type) {
|
||||
case ArrayDataType::kFloat:
|
||||
return "float";
|
||||
@ -96,7 +96,7 @@ string ArrayDataTypeName(ArrayDataType data_type) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsInputArray(const Model& model, const string& array_name) {
|
||||
bool IsInputArray(const Model& model, const std::string& array_name) {
|
||||
for (const auto& input_array : model.flags.input_arrays()) {
|
||||
if (array_name == input_array.name()) {
|
||||
return true;
|
||||
@ -105,7 +105,7 @@ bool IsInputArray(const Model& model, const string& array_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsOutputArray(const Model& model, const string& array_name) {
|
||||
bool IsOutputArray(const Model& model, const std::string& array_name) {
|
||||
for (const auto& output_array : model.flags.output_arrays()) {
|
||||
if (array_name == output_array) {
|
||||
return true;
|
||||
@ -114,7 +114,7 @@ bool IsOutputArray(const Model& model, const string& array_name) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IsArrayConsumed(const Model& model, const string& name) {
|
||||
bool IsArrayConsumed(const Model& model, const std::string& name) {
|
||||
if (GetOpWithInput(model, name)) {
|
||||
return true;
|
||||
}
|
||||
@ -131,7 +131,7 @@ bool IsArrayConsumed(const Model& model, const string& name) {
|
||||
|
||||
int CountTrueOutputs(const Model& model, const Operator& op) {
|
||||
int count = 0;
|
||||
for (const string& output : op.outputs) {
|
||||
for (const std::string& output : op.outputs) {
|
||||
if (IsArrayConsumed(model, output)) {
|
||||
++count;
|
||||
}
|
||||
@ -139,7 +139,7 @@ int CountTrueOutputs(const Model& model, const Operator& op) {
|
||||
return count;
|
||||
}
|
||||
|
||||
int CountOpsWithInput(const Model& model, const string& array_name) {
|
||||
int CountOpsWithInput(const Model& model, const std::string& array_name) {
|
||||
int count = 0;
|
||||
for (const auto& op : model.operators) {
|
||||
for (auto& input : op->inputs) {
|
||||
@ -155,7 +155,7 @@ int CountOpsWithInput(const Model& model, const string& array_name) {
|
||||
return count;
|
||||
}
|
||||
|
||||
bool DeleteArrayIfUnused(const string& array_name, Model* model) {
|
||||
bool DeleteArrayIfUnused(const std::string& array_name, Model* model) {
|
||||
if (IsDiscardableArray(*model, array_name) &&
|
||||
CountOpsWithInput(*model, array_name) == 0 &&
|
||||
GetOpWithOutput(*model, array_name) == nullptr) {
|
||||
@ -165,7 +165,7 @@ bool DeleteArrayIfUnused(const string& array_name, Model* model) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeleteArrayIfUnusedOutsideOfOp(const string& array_name,
|
||||
bool DeleteArrayIfUnusedOutsideOfOp(const std::string& array_name,
|
||||
const Operator* op, Model* model) {
|
||||
if (!IsDiscardableArray(*model, array_name)) {
|
||||
return false;
|
||||
@ -187,10 +187,10 @@ bool DeleteArrayIfUnusedOutsideOfOp(const string& array_name,
|
||||
}
|
||||
|
||||
void DeleteOpAndArrays(Model* model, const Operator* op) {
|
||||
for (const string& array_name : op->inputs) {
|
||||
for (const std::string& array_name : op->inputs) {
|
||||
DeleteArrayIfUnusedOutsideOfOp(array_name, op, model);
|
||||
}
|
||||
for (const string& array_name : op->outputs) {
|
||||
for (const std::string& array_name : op->outputs) {
|
||||
DeleteArrayIfUnusedOutsideOfOp(array_name, op, model);
|
||||
}
|
||||
auto op_it = FindOp(*model, op);
|
||||
@ -199,7 +199,7 @@ void DeleteOpAndArrays(Model* model, const Operator* op) {
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::const_iterator FindOpWithOutput(
|
||||
const Model& model, const string& array_name) {
|
||||
const Model& model, const std::string& array_name) {
|
||||
for (auto it = model.operators.begin(); it != model.operators.end(); ++it) {
|
||||
for (auto& output : it->get()->outputs) {
|
||||
if (output == array_name) {
|
||||
@ -211,7 +211,7 @@ std::vector<std::unique_ptr<Operator>>::const_iterator FindOpWithOutput(
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::iterator FindOpWithOutput(
|
||||
Model& model, const string& array_name) {
|
||||
Model& model, const std::string& array_name) {
|
||||
for (auto it = model.operators.begin(); it != model.operators.end(); ++it) {
|
||||
for (auto& output : it->get()->outputs) {
|
||||
if (output == array_name) {
|
||||
@ -222,14 +222,14 @@ std::vector<std::unique_ptr<Operator>>::iterator FindOpWithOutput(
|
||||
return model.operators.end();
|
||||
}
|
||||
|
||||
Operator* GetOpWithOutput(const Model& model, const string& array_name) {
|
||||
Operator* GetOpWithOutput(const Model& model, const std::string& array_name) {
|
||||
auto it = FindOpWithOutput(model, array_name);
|
||||
return it == model.operators.end() ? nullptr : it->get();
|
||||
}
|
||||
|
||||
// GetFirstOpWithInput assumes that this finds the first op.
|
||||
std::vector<std::unique_ptr<Operator>>::const_iterator FindOpWithInput(
|
||||
const Model& model, const string& array_name) {
|
||||
const Model& model, const std::string& array_name) {
|
||||
for (auto it = model.operators.begin(); it != model.operators.end(); ++it) {
|
||||
for (auto& input : it->get()->inputs) {
|
||||
if (input == array_name) {
|
||||
@ -241,7 +241,7 @@ std::vector<std::unique_ptr<Operator>>::const_iterator FindOpWithInput(
|
||||
}
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::iterator FindOpWithInput(
|
||||
Model& model, const string& array_name) {
|
||||
Model& model, const std::string& array_name) {
|
||||
for (auto it = model.operators.begin(); it != model.operators.end(); ++it) {
|
||||
for (auto& input : it->get()->inputs) {
|
||||
if (input == array_name) {
|
||||
@ -272,18 +272,19 @@ std::vector<std::unique_ptr<Operator>>::iterator FindOp(Model& model,
|
||||
return model.operators.end();
|
||||
}
|
||||
|
||||
Operator* GetOpWithInput(const Model& model, const string& array_name) {
|
||||
Operator* GetOpWithInput(const Model& model, const std::string& array_name) {
|
||||
auto it = FindOpWithInput(model, array_name);
|
||||
return it == model.operators.end() ? nullptr : it->get();
|
||||
}
|
||||
|
||||
Operator* GetFirstOpWithInput(const Model& model, const string& array_name) {
|
||||
Operator* GetFirstOpWithInput(const Model& model,
|
||||
const std::string& array_name) {
|
||||
auto it = FindOpWithInput(model, array_name);
|
||||
return it == model.operators.end() ? nullptr : it->get();
|
||||
}
|
||||
|
||||
void ReplaceArrayUsage(Model* model, const string& old_array_name,
|
||||
const string& new_array_name) {
|
||||
void ReplaceArrayUsage(Model* model, const std::string& old_array_name,
|
||||
const std::string& new_array_name) {
|
||||
for (auto& op_it : model->operators) {
|
||||
Operator* op = op_it.get();
|
||||
for (size_t i = 0; i < op->inputs.size(); ++i) {
|
||||
@ -299,11 +300,12 @@ void ReplaceArrayUsage(Model* model, const string& old_array_name,
|
||||
}
|
||||
}
|
||||
|
||||
string FormatArraysList(const Model& model, const std::vector<string>& list) {
|
||||
std::string FormatArraysList(const Model& model,
|
||||
const std::vector<std::string>& list) {
|
||||
if (list.empty()) {
|
||||
return "[]";
|
||||
}
|
||||
string result = "";
|
||||
std::string result = "";
|
||||
if (list.size() > 1) {
|
||||
result += "[ ";
|
||||
}
|
||||
@ -459,7 +461,7 @@ const char* OperatorTypeName(OperatorType type) {
|
||||
}
|
||||
}
|
||||
|
||||
string HelpfulOperatorTypeName(const Operator& op) {
|
||||
std::string HelpfulOperatorTypeName(const Operator& op) {
|
||||
if (op.type == OperatorType::kUnsupported) {
|
||||
return toco::port::StringF(
|
||||
"(Unsupported TensorFlow op: %s)",
|
||||
@ -503,7 +505,7 @@ void LogSummary(int log_level, const Model& model) {
|
||||
}
|
||||
}
|
||||
|
||||
void LogArray(int log_level, const Model& model, const string& name) {
|
||||
void LogArray(int log_level, const Model& model, const std::string& name) {
|
||||
VLOG(log_level) << "Array: " << name;
|
||||
if (!model.HasArray(name)) {
|
||||
VLOG(log_level) << " DOES NOT EXIST";
|
||||
@ -524,7 +526,7 @@ void LogArray(int log_level, const Model& model, const string& name) {
|
||||
if (array_shape.dimensions_count() == 0) {
|
||||
VLOG(log_level) << " (Zero dimensions)";
|
||||
} else {
|
||||
string message = " Dims: ";
|
||||
std::string message = " Dims: ";
|
||||
bool first = true;
|
||||
for (const int dim : array_shape.dims()) {
|
||||
if (!first) {
|
||||
@ -568,10 +570,10 @@ void DumpGraphvizVideoFrame(const Model& model) {
|
||||
// this new video-dumping feature.
|
||||
static int dump_id = 0;
|
||||
static std::unordered_set<std::size_t> dump_hashes;
|
||||
string graphviz_dump;
|
||||
std::string graphviz_dump;
|
||||
DumpGraphviz(model, &graphviz_dump,
|
||||
toco::port::StringF("VIDEO frame:%05d", dump_id));
|
||||
std::size_t hash = std::hash<string>{}(graphviz_dump);
|
||||
std::size_t hash = std::hash<std::string>{}(graphviz_dump);
|
||||
if (!dump_hashes.count(hash)) {
|
||||
LOG(INFO) << "DUMPING GRAPHVIZ VIDEO FRAME: " << dump_id;
|
||||
dump_hashes.insert(hash);
|
||||
@ -585,13 +587,13 @@ void DumpGraphvizVideoFrame(const Model& model) {
|
||||
}
|
||||
}
|
||||
|
||||
void LogDump(int log_level, const string& message, const Model& model) {
|
||||
void LogDump(int log_level, const std::string& message, const Model& model) {
|
||||
namespace port = toco::port;
|
||||
const auto& dump_options = *GraphVizDumpOptions::singleton();
|
||||
|
||||
DumpGraphvizVideoFrame(model);
|
||||
if (!dump_options.dump_graphviz.empty()) {
|
||||
string graphviz_dump;
|
||||
std::string graphviz_dump;
|
||||
|
||||
DumpGraphviz(model, &graphviz_dump, message);
|
||||
const auto result = port::file::SetContents(
|
||||
@ -608,7 +610,7 @@ void LogDump(int log_level, const string& message, const Model& model) {
|
||||
}
|
||||
VLOG(log_level) << "BEGIN DUMP OF TOCO MODEL (" << message << ")";
|
||||
LogSummary(log_level, model);
|
||||
std::unordered_set<string> already_printed_arrays;
|
||||
std::unordered_set<std::string> already_printed_arrays;
|
||||
for (const auto& op : model.operators) {
|
||||
for (const auto& input : op->inputs) {
|
||||
if (!already_printed_arrays.count(input)) {
|
||||
@ -759,7 +761,7 @@ int RequiredBufferSizeForShape(const Shape& shape) {
|
||||
return max_offset;
|
||||
}
|
||||
|
||||
bool IsConstantParameterArray(const Model& model, const string& name) {
|
||||
bool IsConstantParameterArray(const Model& model, const std::string& name) {
|
||||
if (!model.HasArray(name)) {
|
||||
return false;
|
||||
}
|
||||
@ -858,7 +860,7 @@ bool CompareConstantArrays(const Array& lhs_array, const Array& rhs_array) {
|
||||
namespace {
|
||||
// Take an array name, which may be something like "name:3_5" and make it
|
||||
// acceptable as a TF node name, say "name_3_5";
|
||||
string SanitizeNameForTFNode(const string& array_name) {
|
||||
std::string SanitizeNameForTFNode(const std::string& array_name) {
|
||||
auto node_name = array_name;
|
||||
std::replace(node_name.begin(), node_name.end(), ':', '_');
|
||||
return node_name;
|
||||
@ -866,7 +868,7 @@ string SanitizeNameForTFNode(const string& array_name) {
|
||||
|
||||
void CheckInputArraysAreNotOutputArrays(const ModelFlags& model_flags) {
|
||||
for (const auto& input_array : model_flags.input_arrays()) {
|
||||
for (const string& output_array : model_flags.output_arrays()) {
|
||||
for (const std::string& output_array : model_flags.output_arrays()) {
|
||||
QCHECK_NE(input_array.name(), output_array)
|
||||
<< "The array " << output_array
|
||||
<< " is listed in both --input_arrays and --output_arrays.";
|
||||
@ -874,7 +876,7 @@ void CheckInputArraysAreNotOutputArrays(const ModelFlags& model_flags) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsAsciiPrintable(const string& name) {
|
||||
bool IsAsciiPrintable(const std::string& name) {
|
||||
for (char c : name) {
|
||||
if (!absl::ascii_isprint(c)) {
|
||||
return false;
|
||||
@ -883,8 +885,8 @@ bool IsAsciiPrintable(const string& name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string DumpAscii(const string& name) {
|
||||
string result;
|
||||
std::string DumpAscii(const std::string& name) {
|
||||
std::string result;
|
||||
port::AppendF(&result, "ASCII | Hex\n");
|
||||
port::AppendF(&result, "------+----\n");
|
||||
for (char c : name) {
|
||||
@ -909,7 +911,7 @@ void CheckNonAsciiIOArrays(const ModelFlags& model_flags) {
|
||||
<< "Here is a dump of the string:\n\n"
|
||||
<< DumpAscii(input_array.name());
|
||||
}
|
||||
for (const string& output_array : model_flags.output_arrays()) {
|
||||
for (const std::string& output_array : model_flags.output_arrays()) {
|
||||
QCHECK(IsAsciiPrintable(output_array))
|
||||
<< "Non-ASCII-printable character found in --output_arrays: "
|
||||
<< output_array << ". Pass --allow_nonascii_arrays to allow that. "
|
||||
@ -932,7 +934,7 @@ void CheckNonExistentIOArrays(const Model& model) {
|
||||
"Is it a typo? This should not happen. If you trigger this error "
|
||||
"please send a bug report (with code to reproduce this error), to the "
|
||||
"TensorFlow Lite team.";
|
||||
for (const string& output_array : model.flags.output_arrays()) {
|
||||
for (const std::string& output_array : model.flags.output_arrays()) {
|
||||
if (IsConstantParameterArray(model, output_array)) {
|
||||
continue; // It is OK to request that a constant be an output.
|
||||
}
|
||||
@ -984,7 +986,7 @@ void FixNoMissingArray(Model* model) {
|
||||
}
|
||||
}
|
||||
if (model->flags.allow_nonexistent_arrays()) {
|
||||
for (const string& output_array : model->flags.output_arrays()) {
|
||||
for (const std::string& output_array : model->flags.output_arrays()) {
|
||||
model->GetOrCreateArray(output_array);
|
||||
}
|
||||
for (const auto& rnn_state : model->flags.rnn_states()) {
|
||||
@ -995,7 +997,7 @@ void FixNoMissingArray(Model* model) {
|
||||
}
|
||||
|
||||
void CheckNoOrphanedArray(const Model& model) {
|
||||
std::unordered_set<string> arrays_without_known_use;
|
||||
std::unordered_set<std::string> arrays_without_known_use;
|
||||
for (const auto& array : model.GetArrayMap()) {
|
||||
if (IsDiscardableArray(model, array.first)) {
|
||||
arrays_without_known_use.insert(array.first);
|
||||
@ -1022,7 +1024,7 @@ void CheckNoOrphanedArray(const Model& model) {
|
||||
}
|
||||
|
||||
void FixNoOrphanedArray(Model* model) {
|
||||
std::unordered_set<string> arrays_without_known_use;
|
||||
std::unordered_set<std::string> arrays_without_known_use;
|
||||
for (const auto& array : model->GetArrayMap()) {
|
||||
arrays_without_known_use.insert(array.first);
|
||||
}
|
||||
@ -1071,11 +1073,11 @@ void CheckEachArray(const Model& model) {
|
||||
|
||||
// Check name. Either "name_with_suffix_8", "name_with_port:3", but not
|
||||
// "name_with_both:3_8".
|
||||
const string& name = array_entry.first;
|
||||
const std::string& name = array_entry.first;
|
||||
auto colon_pos = name.find_first_of(":");
|
||||
if (colon_pos != string::npos) {
|
||||
if (colon_pos != std::string::npos) {
|
||||
CHECK_EQ(name.substr(colon_pos + 1).find_first_not_of("0123456789"),
|
||||
string::npos)
|
||||
std::string::npos)
|
||||
<< "Array '" << name << "' has non-digit characters after colon.";
|
||||
}
|
||||
CHECK_GT(colon_pos, 0) << "Array '" << name
|
||||
@ -1084,7 +1086,7 @@ void CheckEachArray(const Model& model) {
|
||||
}
|
||||
|
||||
void CheckOperatorOrdering(const Model& model) {
|
||||
std::unordered_set<string> arrays_behind_us;
|
||||
std::unordered_set<std::string> arrays_behind_us;
|
||||
for (const auto& array_entry : model.GetArrayMap()) {
|
||||
if (!GetOpWithOutput(model, array_entry.first)) {
|
||||
arrays_behind_us.insert(array_entry.first);
|
||||
@ -1103,13 +1105,13 @@ void CheckOperatorOrdering(const Model& model) {
|
||||
arrays_behind_us.insert(output);
|
||||
}
|
||||
}
|
||||
for (const string& output_array : model.flags.output_arrays()) {
|
||||
for (const std::string& output_array : model.flags.output_arrays()) {
|
||||
CHECK(arrays_behind_us.count(output_array));
|
||||
}
|
||||
}
|
||||
|
||||
void FixOperatorOrdering(Model* model) {
|
||||
std::unordered_set<string> arrays_behind_us;
|
||||
std::unordered_set<std::string> arrays_behind_us;
|
||||
for (const auto& array_entry : model->GetArrayMap()) {
|
||||
if (!GetOpWithOutput(*model, array_entry.first)) {
|
||||
arrays_behind_us.insert(array_entry.first);
|
||||
@ -1123,7 +1125,7 @@ void FixOperatorOrdering(Model* model) {
|
||||
for (std::size_t i = 0; i < old_operators.size(); i++) {
|
||||
remaining.insert(i);
|
||||
}
|
||||
std::unordered_map<string, string> reason_why_leftover;
|
||||
std::unordered_map<std::string, std::string> reason_why_leftover;
|
||||
while (true) {
|
||||
bool inserted_something = false;
|
||||
for (const auto& i : remaining) {
|
||||
@ -1133,7 +1135,7 @@ void FixOperatorOrdering(Model* model) {
|
||||
for (const auto& input : op->inputs) {
|
||||
if (!IsConstantParameterArray(*model, input) &&
|
||||
!arrays_behind_us.count(input)) {
|
||||
for (const string& output : op->outputs) {
|
||||
for (const std::string& output : op->outputs) {
|
||||
reason_why_leftover[output] = input;
|
||||
}
|
||||
can_insert = false;
|
||||
@ -1166,15 +1168,15 @@ void FixOperatorOrdering(Model* model) {
|
||||
LOG(ERROR) << "BEGIN TRACE OF OPERATOR WITH BAD INPUT";
|
||||
LOG(ERROR) << "Here is the first-encountered operator with a bad input: ";
|
||||
const Operator* bad_op = old_operators[*remaining.begin()].get();
|
||||
std::unordered_set<string> bad_inputs_already_traced;
|
||||
std::unordered_set<std::string> bad_inputs_already_traced;
|
||||
// The following while(true) loop should always end with a LOG(FATAL).
|
||||
while (true) {
|
||||
LOG(ERROR) << HelpfulOperatorTypeName(*bad_op) << " : "
|
||||
<< FormatArraysList(*model, bad_op->inputs) << " -> "
|
||||
<< FormatArraysList(*model, bad_op->outputs);
|
||||
bool found_bad_output = false;
|
||||
string bad_output;
|
||||
for (const string& output : bad_op->outputs) {
|
||||
std::string bad_output;
|
||||
for (const std::string& output : bad_op->outputs) {
|
||||
if (reason_why_leftover.count(output)) {
|
||||
found_bad_output = true;
|
||||
bad_output = output;
|
||||
@ -1182,7 +1184,7 @@ void FixOperatorOrdering(Model* model) {
|
||||
}
|
||||
}
|
||||
CHECK(found_bad_output);
|
||||
const string& bad_input = reason_why_leftover[bad_output];
|
||||
const std::string& bad_input = reason_why_leftover[bad_output];
|
||||
LOG(ERROR) << "The bad input here is: " << bad_input;
|
||||
if (bad_inputs_already_traced.count(bad_input)) {
|
||||
LOG(FATAL)
|
||||
@ -1198,7 +1200,7 @@ void FixOperatorOrdering(Model* model) {
|
||||
bad_op = nullptr;
|
||||
for (const auto& i : remaining) {
|
||||
const Operator* op = old_operators[i].get();
|
||||
for (const string& output : op->outputs) {
|
||||
for (const std::string& output : op->outputs) {
|
||||
if (bad_input == output) {
|
||||
bad_op = op;
|
||||
break;
|
||||
@ -1233,7 +1235,7 @@ void CheckInvariants(const Model& model) {
|
||||
}
|
||||
|
||||
void CheckCountInRange(const ::toco::ModelFlags::ModelCheck& model_check,
|
||||
const int count, const string& count_description) {
|
||||
const int count, const std::string& count_description) {
|
||||
if (model_check.count_min() >= 0) {
|
||||
CHECK_GE(count, model_check.count_min())
|
||||
<< "Mismatch in " << count_description << ": count was " << count
|
||||
@ -1251,7 +1253,7 @@ void CheckCountInRange(const ::toco::ModelFlags::ModelCheck& model_check,
|
||||
|
||||
void CheckModelCounts(const Model& model) {
|
||||
std::unordered_multiset<OperatorType> ops_by_type;
|
||||
std::unordered_map<string, OperatorType> op_type_by_name;
|
||||
std::unordered_map<std::string, OperatorType> op_type_by_name;
|
||||
if (model.flags.model_checks_size() == 0) {
|
||||
return;
|
||||
}
|
||||
@ -1261,7 +1263,7 @@ void CheckModelCounts(const Model& model) {
|
||||
op_type_by_name[OperatorTypeName(op->type)] = op->type;
|
||||
}
|
||||
for (const auto& model_check : model.flags.model_checks()) {
|
||||
string count_type = model_check.count_type();
|
||||
std::string count_type = model_check.count_type();
|
||||
if (count_type == "None") {
|
||||
continue;
|
||||
} else if (count_type == "Arrays") {
|
||||
@ -1284,12 +1286,12 @@ void CheckModelCounts(const Model& model) {
|
||||
}
|
||||
|
||||
void FixEdgeArrays(Model* model) {
|
||||
for (const string& output_array_name : model->flags.output_arrays()) {
|
||||
for (const std::string& output_array_name : model->flags.output_arrays()) {
|
||||
if (!GetOpWithOutput(*model, output_array_name)) {
|
||||
// Output has no operator producing it. Change that by inserting a copy.
|
||||
LOG(WARNING) << "Fixing constant output array " << output_array_name
|
||||
<< " by inserting a copy. This is not optimal.";
|
||||
string intermediate_array_name =
|
||||
std::string intermediate_array_name =
|
||||
AvailableArrayName(*model, output_array_name + "_copy");
|
||||
CloneArray(model, output_array_name, intermediate_array_name);
|
||||
InsertCopyOperator(model, intermediate_array_name, output_array_name);
|
||||
@ -1378,8 +1380,8 @@ void CopyArrayAttribs(const Array& source_array, Array* target_array) {
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void InsertCopyOperator(Model* model, const string& source_array_name,
|
||||
const string& target_array_name) {
|
||||
void InsertCopyOperator(Model* model, const std::string& source_array_name,
|
||||
const std::string& target_array_name) {
|
||||
// Reshape to the same size. This should be a no-op.
|
||||
const Array& source_array = model->GetArray(source_array_name);
|
||||
std::vector<int> shape = source_array.shape().dims();
|
||||
@ -1404,8 +1406,8 @@ void InsertCopyOperator(Model* model, const string& source_array_name,
|
||||
model->operators.emplace_back(copy_op);
|
||||
}
|
||||
|
||||
void CloneArray(Model* model, const string& source_array_name,
|
||||
const string& target_array_name) {
|
||||
void CloneArray(Model* model, const std::string& source_array_name,
|
||||
const std::string& target_array_name) {
|
||||
CHECK(!model->HasArray(target_array_name));
|
||||
const Array& source_array = model->GetArray(source_array_name);
|
||||
Array& target_array = model->GetOrCreateArray(target_array_name);
|
||||
@ -1479,7 +1481,7 @@ void MakeArrayDims(int num_dims, int batch, int height, int width, int depth,
|
||||
}
|
||||
}
|
||||
|
||||
void CreateOrCheckRnnStateArray(const string& name, int size,
|
||||
void CreateOrCheckRnnStateArray(const std::string& name, int size,
|
||||
int state_num_dims, Model* model) {
|
||||
int batch = 1;
|
||||
int num_dims = -1;
|
||||
@ -1781,7 +1783,7 @@ int ElementSize(ArrayDataType data_type) {
|
||||
}
|
||||
}
|
||||
|
||||
void DropMinMax(Model* model, const string& array_name) {
|
||||
void DropMinMax(Model* model, const std::string& array_name) {
|
||||
auto& array = model->GetArray(array_name);
|
||||
if (!!array.minmax) {
|
||||
LOG(WARNING) << "Dropping MinMax information in array " << array_name
|
||||
@ -1790,7 +1792,8 @@ void DropMinMax(Model* model, const string& array_name) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsAllocatableTransientArray(const Model& model, const string& array_name) {
|
||||
bool IsAllocatableTransientArray(const Model& model,
|
||||
const std::string& array_name) {
|
||||
// Optional array is not transient
|
||||
if (model.IsOptionalArray(array_name)) return false;
|
||||
// The model's input and output arrays are externally allocated.
|
||||
@ -1818,15 +1821,15 @@ bool IsAllocatableTransientArray(const Model& model, const string& array_name) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string AvailableArrayName(const Model& model, const string& name) {
|
||||
string sanitized_name = SanitizeNameForTFNode(name);
|
||||
std::string AvailableArrayName(const Model& model, const std::string& name) {
|
||||
std::string sanitized_name = SanitizeNameForTFNode(name);
|
||||
if (!model.HasArray(sanitized_name) &&
|
||||
!model.IsOptionalArray(sanitized_name)) {
|
||||
return sanitized_name;
|
||||
}
|
||||
const int kNumSuffixesToTry = 1000;
|
||||
for (int i = 0; i < kNumSuffixesToTry; i++) {
|
||||
const string& name_with_suffix =
|
||||
const std::string& name_with_suffix =
|
||||
toco::port::StringF("%s_%d", sanitized_name, i);
|
||||
if (!model.HasArray(name_with_suffix) &&
|
||||
!model.IsOptionalArray(name_with_suffix)) {
|
||||
@ -1839,7 +1842,7 @@ string AvailableArrayName(const Model& model, const string& name) {
|
||||
return "";
|
||||
}
|
||||
|
||||
string ShapeToString(const Shape& shape) {
|
||||
std::string ShapeToString(const Shape& shape) {
|
||||
if (shape.dimensions_count() == 0) {
|
||||
return "[]";
|
||||
}
|
||||
@ -1847,7 +1850,7 @@ string ShapeToString(const Shape& shape) {
|
||||
return absl::StrCat("[ ", absl::StrJoin(shape.dims(), ", "), " ]");
|
||||
}
|
||||
|
||||
void PrintArrayShape(Model* model, const string& name) {
|
||||
void PrintArrayShape(Model* model, const std::string& name) {
|
||||
if (!model->GetArray(name).has_shape()) {
|
||||
LOG(INFO) << name << " has no shape";
|
||||
return;
|
||||
@ -1856,7 +1859,7 @@ void PrintArrayShape(Model* model, const string& name) {
|
||||
<< " has shape: " << ShapeToString(model->GetArray(name).shape());
|
||||
}
|
||||
|
||||
bool IsArrayFullyConnectedWeights(const Model& model, const string& name) {
|
||||
bool IsArrayFullyConnectedWeights(const Model& model, const std::string& name) {
|
||||
bool is_fc_weights = false;
|
||||
bool is_something_else = false;
|
||||
for (const auto& op : model.operators) {
|
||||
@ -1874,8 +1877,8 @@ bool IsArrayFullyConnectedWeights(const Model& model, const string& name) {
|
||||
return is_fc_weights;
|
||||
}
|
||||
|
||||
string CreateInt32Array(Model* model, const string& param_name,
|
||||
const std::vector<int>& value) {
|
||||
std::string CreateInt32Array(Model* model, const std::string& param_name,
|
||||
const std::vector<int>& value) {
|
||||
auto param_array_name = AvailableArrayName(*model, param_name);
|
||||
auto& param_array = model->GetOrCreateArray(param_array_name);
|
||||
param_array.mutable_shape()->ReplaceDims({static_cast<int>(value.size())});
|
||||
@ -2031,7 +2034,7 @@ bool EstimateArithmeticOpsCount(const Model& model, int64* result) {
|
||||
return true;
|
||||
}
|
||||
|
||||
string FormattedNumber(int64 x) {
|
||||
std::string FormattedNumber(int64 x) {
|
||||
const int64 million = 1000000;
|
||||
const int64 billion = 1000000000;
|
||||
if (x < 10000) {
|
||||
@ -2222,7 +2225,7 @@ int AxesCount(AxesOrder axes_order) {
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDiscardableArray(const Model& model, const string& array_name) {
|
||||
bool IsDiscardableArray(const Model& model, const std::string& array_name) {
|
||||
if (IsInputArray(model, array_name) || IsOutputArray(model, array_name)) {
|
||||
return false;
|
||||
}
|
||||
@ -2338,9 +2341,9 @@ void FinishBuildingRNNStates(Model* model) {
|
||||
|
||||
// Returns the array names that match the ArraysExtraInfo's name and
|
||||
// name_regexp. The regexp match is for a full match.
|
||||
std::unordered_set<string> ScanArrayNames(
|
||||
std::unordered_set<std::string> ScanArrayNames(
|
||||
const Model& model, const toco::ArraysExtraInfo_Entry& entry) {
|
||||
std::unordered_set<string> matches;
|
||||
std::unordered_set<std::string> matches;
|
||||
if (model.HasArray(entry.name())) {
|
||||
matches.insert(entry.name());
|
||||
}
|
||||
@ -2409,7 +2412,7 @@ void UndoWeightsShuffling(Model* model) {
|
||||
if (fc_op.weights_format == FullyConnectedWeightsFormat::kDefault) {
|
||||
continue;
|
||||
}
|
||||
const string& weights_name = fc_op.inputs[1];
|
||||
const std::string& weights_name = fc_op.inputs[1];
|
||||
QCHECK_EQ(CountOpsWithInput(*model, weights_name), 1);
|
||||
auto& weights_array = model->GetArray(weights_name);
|
||||
QCHECK(weights_array.data_type == ArrayDataType::kUint8);
|
||||
|
@ -54,44 +54,45 @@ constexpr int kLogLevelModelUnchanged = 2;
|
||||
|
||||
absl::string_view FindLongestCommonPrefix(absl::string_view a,
|
||||
absl::string_view b);
|
||||
string LogName(const Operator& op);
|
||||
std::string LogName(const Operator& op);
|
||||
|
||||
string ArrayDataTypeName(ArrayDataType data_type);
|
||||
std::string ArrayDataTypeName(ArrayDataType data_type);
|
||||
|
||||
// Returns true if the given array is specified as a model input array.
|
||||
bool IsInputArray(const Model& model, const string& array_name);
|
||||
bool IsInputArray(const Model& model, const std::string& array_name);
|
||||
// Returns true if the given array is specified as a model output array.
|
||||
bool IsOutputArray(const Model& model, const string& array_name);
|
||||
bool IsOutputArray(const Model& model, const std::string& array_name);
|
||||
|
||||
bool IsArrayConsumed(const Model& model, const string& name);
|
||||
bool IsArrayConsumed(const Model& model, const std::string& name);
|
||||
int CountTrueOutputs(const Model& model, const Operator& op);
|
||||
|
||||
int CountOpsWithInput(const Model& model, const string& array_name);
|
||||
bool DeleteArrayIfUnused(const string& array_name, Model* model);
|
||||
int CountOpsWithInput(const Model& model, const std::string& array_name);
|
||||
bool DeleteArrayIfUnused(const std::string& array_name, Model* model);
|
||||
|
||||
// Deletes the op and any of its input and output arrays if they are unused
|
||||
// after the op has been deleted.
|
||||
void DeleteOpAndArrays(Model* model, const Operator* op);
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::const_iterator FindOpWithOutput(
|
||||
const Model& model, const string& array_name);
|
||||
Operator* GetOpWithOutput(const Model& model, const string& array_name);
|
||||
const Model& model, const std::string& array_name);
|
||||
Operator* GetOpWithOutput(const Model& model, const std::string& array_name);
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::iterator FindOpWithOutput(
|
||||
Model& model, const string& array_name);
|
||||
Model& model, const std::string& array_name);
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::const_iterator FindOpWithInput(
|
||||
const Model& model, const string& array_name);
|
||||
const Model& model, const std::string& array_name);
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::iterator FindOpWithInput(
|
||||
Model& model, const string& array_name);
|
||||
Model& model, const std::string& array_name);
|
||||
|
||||
Operator* GetOpWithInput(const Model& model, const string& array_name);
|
||||
Operator* GetFirstOpWithInput(const Model& model, const string& array_name);
|
||||
Operator* GetOpWithInput(const Model& model, const std::string& array_name);
|
||||
Operator* GetFirstOpWithInput(const Model& model,
|
||||
const std::string& array_name);
|
||||
|
||||
// Replaces all uses of the |old_array_name| with the |new_array_name|.
|
||||
void ReplaceArrayUsage(Model* model, const string& old_array_name,
|
||||
const string& new_array_name);
|
||||
void ReplaceArrayUsage(Model* model, const std::string& old_array_name,
|
||||
const std::string& new_array_name);
|
||||
|
||||
std::vector<std::unique_ptr<Operator>>::const_iterator FindOp(
|
||||
const Model& model, const Operator* op);
|
||||
@ -99,15 +100,15 @@ std::vector<std::unique_ptr<Operator>>::iterator FindOp(Model& model,
|
||||
const Operator* op);
|
||||
|
||||
const char* OperatorTypeName(OperatorType type);
|
||||
string HelpfulOperatorTypeName(const Operator& op);
|
||||
std::string HelpfulOperatorTypeName(const Operator& op);
|
||||
|
||||
// Whether the operator can be fused with an activation function. Note that this
|
||||
// will return false by default for new operators; fusing support is opt-in.
|
||||
bool OperatorSupportsFusedActivation(OperatorType type);
|
||||
|
||||
void DumpGraphvizVideoFrame(const Model& model);
|
||||
void LogDump(int log_level, const string& message, const Model& model);
|
||||
void LogSummary(int log_level, const string& message, const Model& model);
|
||||
void LogDump(int log_level, const std::string& message, const Model& model);
|
||||
void LogSummary(int log_level, const std::string& message, const Model& model);
|
||||
|
||||
// TODO(b/36075966): Clean up when dims superseded by array shape.
|
||||
void ExtendShape(Shape* shape, int new_shape_size);
|
||||
@ -143,12 +144,12 @@ inline ::tflite::RuntimeShape ToRuntimeShape(const Shape& shape) {
|
||||
return ::tflite::RuntimeShape(shape.dimensions_count(), shape.dims().data());
|
||||
}
|
||||
|
||||
bool IsArrayFullyConnectedWeights(const Model& model, const string& name);
|
||||
bool IsArrayFullyConnectedWeights(const Model& model, const std::string& name);
|
||||
|
||||
// If there is a wildcard dimension (-1), this may return a negative value.
|
||||
int RequiredBufferSizeForShape(const Shape& shape);
|
||||
|
||||
bool IsConstantParameterArray(const Model& model, const string& name);
|
||||
bool IsConstantParameterArray(const Model& model, const std::string& name);
|
||||
|
||||
// Compares two constant parameter arrays for exact equality.
|
||||
bool CompareConstantArrays(const Array& lhs_array, const Array& rhs_array);
|
||||
@ -193,12 +194,12 @@ void CopyArrayBuffer(const Array& source_array, Array* target_array) {
|
||||
|
||||
// Inserts a no-op reshape operator between the source array and the target
|
||||
// array. This effectively just copies the data.
|
||||
void InsertCopyOperator(Model* model, const string& source_array_name,
|
||||
const string& target_array_name);
|
||||
void InsertCopyOperator(Model* model, const std::string& source_array_name,
|
||||
const std::string& target_array_name);
|
||||
|
||||
// Clones an array with all data and parameters.
|
||||
void CloneArray(Model* model, const string& source_array_name,
|
||||
const string& target_array_name);
|
||||
void CloneArray(Model* model, const std::string& source_array_name,
|
||||
const std::string& target_array_name);
|
||||
|
||||
void ResolveModelFlags(const ModelFlags& model_flags, Model* model);
|
||||
|
||||
@ -245,32 +246,33 @@ inline std::vector<int> ReverseOffset(const Shape& shape, int index) {
|
||||
|
||||
int ElementSize(ArrayDataType data_type);
|
||||
|
||||
void DropMinMax(Model* model, const string& array_name);
|
||||
void DropMinMax(Model* model, const std::string& array_name);
|
||||
|
||||
bool IsAllocatableTransientArray(const Model& model, const string& array_name);
|
||||
bool IsAllocatableTransientArray(const Model& model,
|
||||
const std::string& array_name);
|
||||
|
||||
void CreateOrCheckRnnStateArray(const string& name, int size,
|
||||
void CreateOrCheckRnnStateArray(const std::string& name, int size,
|
||||
int state_num_dims, Model* model);
|
||||
|
||||
string AvailableArrayName(const Model& model, const string& name);
|
||||
std::string AvailableArrayName(const Model& model, const std::string& name);
|
||||
|
||||
// Formats a shape as a string: [ dims(0), dims(1), ..., dims(num_dims-1) ].
|
||||
string ShapeToString(const Shape& shape);
|
||||
std::string ShapeToString(const Shape& shape);
|
||||
|
||||
void PrintArrayShape(Model* model, const string& name);
|
||||
void PrintArrayShape(Model* model, const std::string& name);
|
||||
|
||||
void MakeArrayDims(int num_dims, int batch, int height, int width, int depth,
|
||||
std::vector<int>* out_dims);
|
||||
|
||||
// Defines a constant int32 array with the provided values formatted for use
|
||||
// as op parameters.
|
||||
string CreateInt32Array(Model* model, const string& param_name,
|
||||
const std::vector<int>& value);
|
||||
std::string CreateInt32Array(Model* model, const std::string& param_name,
|
||||
const std::vector<int>& value);
|
||||
|
||||
bool EstimateArithmeticOpsCount(const Model& model, const Operator& op,
|
||||
int64* result);
|
||||
bool EstimateArithmeticOpsCount(const Model& model, int64* result);
|
||||
string FormattedNumber(int64 x);
|
||||
std::string FormattedNumber(int64 x);
|
||||
|
||||
int AxesCount(AxesOrder axes_order);
|
||||
|
||||
@ -297,7 +299,7 @@ void ShuffleArray(const Shape& input_shape, AxesOrder input_axes_order,
|
||||
// that array. The idea is that we can't ever discard arrays that are either
|
||||
// an input or an output of the whole graph, or that appear in RNN back-edges,
|
||||
// as that would undercut explicit flags that the user might pass.
|
||||
bool IsDiscardableArray(const Model& model, const string& array_name);
|
||||
bool IsDiscardableArray(const Model& model, const std::string& array_name);
|
||||
|
||||
void CheckFinalDataTypesSatisfied(const Model& model);
|
||||
|
||||
@ -362,7 +364,7 @@ void CopyMinMaxAndQuantizationRelatedFields(const Array& src, Array* dst);
|
||||
|
||||
// Delete Array if it's discardable and not referenced as input or output array
|
||||
// by any other op than the specified op.
|
||||
bool DeleteArrayIfUnusedOutsideOfOp(const string& array_name,
|
||||
bool DeleteArrayIfUnusedOutsideOfOp(const std::string& array_name,
|
||||
const Operator* op, Model* model);
|
||||
|
||||
} // namespace toco
|
||||
|
Loading…
x
Reference in New Issue
Block a user