MCPcopy Create free account
hub / github.com/DeepRec-AI/DeepRec / ConvertLstmCellOperator

Function ConvertLstmCellOperator

tensorflow/lite/toco/export_tensorflow.cc:1452–1617  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1450} // namespace
1451
1452void ConvertLstmCellOperator(const Model& model, const LstmCellOperator& src_op,
1453 GraphDef* tensorflow_graph) {
1454 // Find the base name
1455 const string base(
1456 FindLongestCommonPrefix(src_op.outputs[LstmCellOperator::STATE_OUTPUT],
1457 src_op.outputs[LstmCellOperator::ACTIV_OUTPUT]));
1458
1459 // Concatenate inputs
1460 const string concat_output = base + "basic_lstm_cell/concat";
1461 // Op names have been chosen to match the tf.slim LSTM naming
1462 // as closely as possible.
1463 const int axis =
1464 model.GetArray(src_op.inputs[LstmCellOperator::PREV_ACTIV_INPUT])
1465 .shape()
1466 .dimensions_count() -
1467 1;
1468 // Note that DATA_INPUT may have extra size 1 dimensions, but TF concat
1469 // works the same since the tensor has the same underlying data layout.
1470 const string axis_output = concat_output + "/axis";
1471 CreateDummyConcatDimTensorConst(axis_output, axis, tensorflow_graph);
1472 tensorflow::NodeDef* concat_op = tensorflow_graph->add_node();
1473 concat_op->set_op("ConcatV2");
1474 concat_op->set_name(concat_output);
1475 *concat_op->add_input() = src_op.inputs[LstmCellOperator::DATA_INPUT];
1476 *concat_op->add_input() = src_op.inputs[LstmCellOperator::PREV_ACTIV_INPUT];
1477 *concat_op->add_input() = axis_output;
1478 (*concat_op->mutable_attr())["T"].set_type(DT_FLOAT);
1479 (*concat_op->mutable_attr())["Tidx"].set_type(DT_INT32);
1480 (*concat_op->mutable_attr())["N"].set_i(2); // Number of inputs
1481
1482 // Write weights
1483 const string weights_output = base + "weights";
1484 CHECK(model.HasArray(src_op.inputs[LstmCellOperator::WEIGHTS_INPUT]));
1485 const string weights_name = WalkUpToConstantArray(
1486 model, src_op.inputs[LstmCellOperator::WEIGHTS_INPUT]);
1487 const auto& weights_array = model.GetArray(weights_name);
1488 // Convert 4D FullyConnected weights into 2D matrix
1489 const auto& weights_shape = weights_array.shape();
1490 CHECK_EQ(weights_shape.dimensions_count(), 2);
1491 CHECK(weights_array.buffer);
1492 CHECK(weights_array.buffer->type == ArrayDataType::kFloat);
1493 const float* weights_data =
1494 weights_array.GetBuffer<ArrayDataType::kFloat>().data.data();
1495 ConvertFloatTensorConst(weights_output, weights_shape, weights_data,
1496 AxesOrder::kCR, AxesOrder::kRC, tensorflow_graph);
1497
1498 // Fully connected matrix multiply
1499 const string matmul_output = base + "MatMul";
1500 tensorflow::NodeDef* matmul_op = tensorflow_graph->add_node();
1501 matmul_op->set_op("MatMul");
1502 matmul_op->set_name(matmul_output);
1503 *matmul_op->add_input() = concat_output;
1504 *matmul_op->add_input() = weights_output;
1505 (*matmul_op->mutable_attr())["transpose_a"].set_b(false);
1506 (*matmul_op->mutable_attr())["transpose_b"].set_b(false);
1507 (*matmul_op->mutable_attr())["T"].set_type(DT_FLOAT);
1508
1509 // Write biases

Callers 1

ConvertOperatorFunction · 0.85

Calls 12

WalkUpToConstantArrayFunction · 0.85
ConvertFloatTensorConstFunction · 0.85
UnextendShapeFunction · 0.85
dimensions_countMethod · 0.80
set_opMethod · 0.80
HasArrayMethod · 0.80
FindLongestCommonPrefixFunction · 0.70
shapeMethod · 0.45
set_nameMethod · 0.45
add_inputMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected