1

I am trying to build a BDD for monotone multiplication and need to use the negation of the input bits.

I am using the following code:

DdNode *x[N], *y[N], *nx[N], *ny[N];

gbm = Cudd_Init(0,0,CUDD_UNIQUE_SLOTS,CUDD_CACHE_SLOTS,0); /* Initialize a new BDD manager. */

for(k=0;k<N;k++)
{
   x[k] = Cudd_bddNewVar(gbm);
   nx[k] = Cudd_Not(x[k]);  
   y[k] = Cudd_bddNewVar(gbm);
   ny[k] = Cudd_Not(y[k]);  
}

The error that I am getting is:

cuddGarbageCollect: problem in table 0
  dead count != deleted
  This problem is often due to a missing call to Cudd_Ref
  or to an extra call to Cudd_RecursiveDeref.
  See the CUDD Programmer's Guide for additional details.Aborted (core dumped)

The multiplier compiles and runs fine when I am using

   x[k] = Cudd_bddNewVar(gbm);
   nx[k] = Cudd_bddNewVar(gbm);  
   y[k] = Cudd_bddNewVar(gbm);
   ny[k] = Cudd_bddNewVar(gbm);  

What should I do, the manual does not help not truing to ref x[k],nx[k]...

DCTLib
  • 1,016
  • 8
  • 22

1 Answers1

2

Every BDD node that is not referenced is subject to deletion by any Cudd operation. If you want to make sure that all nodes stored in your array remain valid, you need to Cudd_Ref them immediately after they are returned by CUDD. Hence, you need to correct your code to:

for(k=0;k<N;k++)
{
   x[k] = Cudd_bddNewVar(gbm);
   Cudd_Ref(x[k]);
   nx[k] = Cudd_Not(x[k]);  
   Cudd_Ref(nx[k]);
   y[k] = Cudd_bddNewVar(gbm);
   Cudd_Ref(y[k]);
   ny[k] = Cudd_Not(y[k]);  
   Cudd_Ref(yn[k]);
}

Before deallocating the Cudd manager, you then need to dereference the nodes:

for(k=0;k<N;k++)
{
   Cudd_RecursiveDeref(gbm,x[k]);
   Cudd_RecursiveDeref(gbm,nx[k]);
   Cudd_RecursiveDeref(gbm,y[k]);
   Cudd_RecursiveDeref(gbm,ny[k]);
}

Note that the fact that your code works when allocating more variables does not show that referencing is not needed. It may simply be that you do not ever use enough nodes for the garbage collector to trigger -- and before that, the problem is not detected.

DCTLib
  • 1,016
  • 8
  • 22
  • thanks, I just Cudd_Ref() the nodes that used the not-gates and it worked. – Yosi Ben-Asher Jan 01 '19 at 09:18
  • 1
    @YosiBen-Asher That works in this special case as CUDD the x[k] and nx[k] nodes are actually the same nodes, except that CUDD stores a "negated flag" in the DdNode for nx[k]. As they are the same node, Ref'fing one of them suffices, provided that you also later only DeRef one of them and not both of them. – DCTLib Jan 01 '19 at 11:49