lsils/mockturtle

feature request: is_po

Closed this issue · 5 comments

The network interface API contains foreach_pi and foreach_po. However it has is_pi but seemingly no is_po. Looking at the implementations of is_pi, it seems like maybe this is deliberate as there isn't a way to implement it efficiently? Seems like one can roll their own as something like:

// untested
bool is_po(const aig_network &net, const node &n) {
  bool match = false;
  net.foreach_po([&](const signal &s) {
    if (node_to_index(n) == s.index) {
      match = true;
      return false;
    }
    return true;
  });
  return match;
}

Do you think this is suitable for inclusion in mockturtle?

An early design decision in mockturtle has been not to have is_po in the API. Note that in contrast to other network APIs, mockturtle also does not store PO nodes in its DAGs.

Fair enough. I suspected there might be some rationale like that. Is the foreach_po approach I suggested a workable implementation? I subsequently discovered that there may be some difference between signal indexes and node indexes. Wondering if the code I posted is wrong anyway.

is_pi exists to check if a node is a PI because algorithms that iterate over all nodes often have to deal with them differently. However, mockturtle does not store extra nodes for POs, such that there is no need for is_po.

Of course, you can iterate over the list of outputs and compare their nodes to some other node. Note that one node may appear multiple times in the list of outputs.

I would write it as follows:

bool is_po_driver(const aig_network &net, const aig_network::node &n) {
  bool match = false;
  net.foreach_po([&](const signal &s) {
    if (net.get_node(s) == n) {
      match = true;
      return false;
    }
    return true;
  });
  return match;
}

Note that primary outputs are signals into the network (aig_network::signal). For example, the following single node AIG computes constant 6 = 0b110.

aig_network aig;
aig.create_po( aig.get_constant( false ) );
aig.create_po( aig.get_constant( true ) );
aig.create_po( aig.get_constant( true ) );

There is one node that is a PO node in the above sense, but there are 3 primary outputs. Therefore, I would call it a PO driver.

Ah I think I follow. is_po is a question that does not necessarily make sense from mockturtle's perspective because it's really the signal that is the output, not a node itself which may also serve other roles. I think @msoeken's implementation fits my current use case though. I overlooked the fact that I can just compare nodes and not deal with indexes. Thanks!