TfLiteStatus Subgraph::AddNodeWithParameters( const std::vector<int>& inputs, const std::vector<int>& outputs, const char* init_data, size_t init_data_size, void* builtin_data, const TfLiteRegistration* registration, int* node_index) { if (state_ == kStateInvokableAndImmutable) { ReportError("AddNodeWithParameters is disallowed when graph is immutable."); return kTfLiteError; } state_ = kStateUninvokable; std::unique_ptr<void, decltype(free)*> builtin_data_deleter(builtin_data, free); TF_LITE_ENSURE_OK(context_, CheckTensorIndices("node inputs", inputs.data(), inputs.size())); TF_LITE_ENSURE_OK( &context_, CheckTensorIndices("node outputs", outputs.data(), outputs.size()));
ここまでで引数等をチェック。
int new_node_index = nodes_and_registration_.size(); if (node_index) *node_index = new_node_index; nodes_and_registration_.resize(nodes_and_registration_.size() + 1);
nodes_and_registration_ の最後に1つのノードを追加。
auto& node_and_reg = nodes_and_registration_.back();
その最後のノードを使う。
TfLiteNode& node = node_and_reg.first; if (node.inputs) TfLiteIntArrayFree(node.inputs); if (node.outputs) TfLiteIntArrayFree(node.outputs); if (node.temporaries) TfLiteIntArrayFree(node.temporaries);
ノードの inputs, outputs, temporaries が存在するときは、解放する。
// NOTE, here we are not using move semantics yet, since our internal // representation isn't std::vector, but in the future we would like to avoid // copies, so we want the interface to take r-value references now. node.inputs = ConvertVectorToTfLiteIntArray(inputs); node.outputs = ConvertVectorToTfLiteIntArray(outputs); node.temporaries = TfLiteIntArrayCreate(0);
ノードに、引数の inputs と outputs を設定。
if (init_data) { node.user_data = OpInit(*registration, init_data, init_data_size); } else { node.user_data = OpInit(*registration, reinterpret_cast<const char*>(builtin_data_deleter.get()), 0); }
初期データを node.user_data に設定。メソッド名の WithParameters に相当する部分。
node.builtin_data = builtin_data_deleter.release(); // TODO(ycling): Filling `custom_initial_data` and `custom_initial_data_size` // properly for nodes generated by ReplaceNodeSubsetsWithDelegateKernels. if (registration->builtin_code == BuiltinOperator_CUSTOM) { // When it's a CUSTOM op, the `custom_options` field in the Flatbuffer // `Operator` table is passed in. node.custom_initial_data = init_data; node.custom_initial_data_size = init_data_size; } else { node.custom_initial_data = nullptr; node.custom_initial_data_size = 0; } node.delegate = nullptr; node_and_reg.second = *registration; execution_plan_.push_back(new_node_index); return kTfLiteOk; }
その他の初期化。