Creates a TF_Operation. Args: graph: a `Graph`. node_def: `node_def_pb2.NodeDef` for the operation to create. inputs: A list of `Tensor`s (corresponding to scalar inputs) and lists of `Tensor`s (corresponding to sequence inputs, e.g. "int64 * N", "list(int64)"). The length
(graph, node_def, inputs, control_inputs)
| 1565 | |
| 1566 | |
| 1567 | def _create_c_op(graph, node_def, inputs, control_inputs): |
| 1568 | """Creates a TF_Operation. |
| 1569 | |
| 1570 | Args: |
| 1571 | graph: a `Graph`. |
| 1572 | node_def: `node_def_pb2.NodeDef` for the operation to create. |
| 1573 | inputs: A list of `Tensor`s (corresponding to scalar inputs) and lists of |
| 1574 | `Tensor`s (corresponding to sequence inputs, e.g. "int64 * N", |
| 1575 | "list(int64)"). The length of the list should be equal to the number of |
| 1576 | inputs specified by this operation's op def. |
| 1577 | control_inputs: A list of `Operation`s to set as control dependencies. |
| 1578 | |
| 1579 | Returns: |
| 1580 | A wrapped TF_Operation*. |
| 1581 | """ |
| 1582 | # pylint: disable=protected-access |
| 1583 | op_desc = c_api.TF_NewOperation(graph._c_graph, compat.as_str(node_def.op), |
| 1584 | compat.as_str(node_def.name)) |
| 1585 | if node_def.device: |
| 1586 | c_api.TF_SetDevice(op_desc, compat.as_str(node_def.device)) |
| 1587 | # Add inputs |
| 1588 | for op_input in inputs: |
| 1589 | if isinstance(op_input, (list, tuple)): |
| 1590 | c_api.TF_AddInputList(op_desc, [t._as_tf_output() for t in op_input]) |
| 1591 | else: |
| 1592 | c_api.TF_AddInput(op_desc, op_input._as_tf_output()) |
| 1593 | |
| 1594 | # Add control inputs |
| 1595 | for control_input in control_inputs: |
| 1596 | c_api.TF_AddControlInput(op_desc, control_input._c_op) |
| 1597 | # pylint: enable=protected-access |
| 1598 | |
| 1599 | # Add attrs |
| 1600 | for name, attr_value in node_def.attr.items(): |
| 1601 | serialized = attr_value.SerializeToString() |
| 1602 | # TODO(skyewm): this creates and deletes a new TF_Status for every attr. |
| 1603 | # It might be worth creating a convenient way to re-use the same status. |
| 1604 | c_api.TF_SetAttrValueProto(op_desc, compat.as_str(name), serialized) |
| 1605 | |
| 1606 | try: |
| 1607 | c_op = c_api.TF_FinishOperation(op_desc) |
| 1608 | except errors.InvalidArgumentError as e: |
| 1609 | # Convert to ValueError for backwards compatibility. |
| 1610 | raise ValueError(str(e)) |
| 1611 | |
| 1612 | return c_op |
| 1613 | |
| 1614 | |
| 1615 | @tf_export("Operation") |
no test coverage detected