Skip to content

solving PF memory growth issue #324

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Oct 14, 2014
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/blog/DBLOGUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static void removeVarsAtDiffTimestep(Timestep largest,
BasicVar var = (BasicVar) varIt.next();
Timestep timestep = var.maxTimestep();
if (timestep != null && timestep.compareTo(largest) < 0) {
world.setValue(var, null);
world.forceRemoveVar(var);
}
}
}
Expand Down
19 changes: 10 additions & 9 deletions src/main/java/blog/bn/RandFuncAppVar.java
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@
*/
package blog.bn;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import blog.ObjectIdentifier;
import blog.common.Util;
import blog.model.DependencyModel;
Expand All @@ -44,10 +49,6 @@
import blog.model.Term;
import blog.model.Type;
import blog.sample.EvalContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
* A random variable whose value is the value of a certain random function on a
Expand Down Expand Up @@ -110,11 +111,11 @@ public DependencyModel.Distrib getDistrib(EvalContext context) {
DependencyModel depModel = f.getDepModel();
if (depModel == null) {
Util.fatalErrorWithoutStack("Can't get distribution for random variable because function "
+ f.getSig() + " has no dependency statement.");
+ f.getSig() + " has no dependency statement.");
}

DependencyModel.Distrib distrib = depModel.getDistribWithBinding(context,
f.getArgVars(), args(), Model.NULL);
f.getArgVars(), args(), Model.NULL);
context.popEvaluee();
return distrib;
}
Expand All @@ -127,12 +128,12 @@ public FuncAppTerm getCanonicalTerm(Map logicalVarForObj) {
if (term == null) {
if (arg instanceof ObjectIdentifier) {
throw new IllegalArgumentException(
"No logical variable specified for object identifier " + arg);
"No logical variable specified for object identifier " + arg);
}
term = f.getArgTypes()[i].getCanonicalTerm(arg);
if (term == null) {
throw new UnsupportedOperationException(
"Can't get canonical term for object " + arg + " of type "
"Can't get canonical term for object " + arg + " of type "
+ f.getArgTypes()[i]);
}
}
Expand Down Expand Up @@ -186,7 +187,7 @@ public String toString() {
buf.append(args[i]);
}
buf.append(")");
str = buf.toString();
str = buf.toString().intern();
return str;
}

Expand Down
15 changes: 0 additions & 15 deletions src/main/java/blog/engine/Particle.java
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,9 @@ public void take(Evidence evidence) {
sampler.initialize(evidence, new Queries(null));
sampler.setBaseWorld(curWorld);

// System.out.println("Particle taking evidence.");
// System.out.println("Evidence: " + evidence);
// System.out.println("Previous world: " + curWorld);

sampler.nextSample();
logWeight = sampler.getLatestLogWeight();
// if (Double.isNaN(logWeight)) {
// System.out.println("Particle.take: logWeight set to " + logWeight);
// System.out.println("Evidence: " + evidence);
// System.out.println("Updated world: " + curWorld);
// System.exit(-1);
// }

// System.out.println("Particle.take: logWeight set to " + logWeight);
curWorld = sampler.getLatestWorld();

// System.out.println("logWeight: " + logWeight);
// System.out.println("Updated world: " + curWorld);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/blog/engine/ParticleFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ private void takeEvidenceAndAnswerQuery() {
* {@link Particle#copy()} for it to return an object of its own class).
*/
protected Particle makeParticle(Set<? extends Type> idTypes) {
DefaultPartialWorld world = new DefaultPartialWorld(idTypes);
DefaultPartialWorld world = new DefaultPartialWorld(idTypes, false);
return new Particle(particleSampler, world);
}

Expand Down
54 changes: 39 additions & 15 deletions src/main/java/blog/world/AbstractPartialWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,10 +89,13 @@ public abstract class AbstractPartialWorld implements PartialWorld {
*
* @param idTypes
* Set of Type objects
* @param cbn
* The underlying CBN class (can be null if no need to use CBN)
*/
public AbstractPartialWorld(Set idTypes) {
public AbstractPartialWorld(Set idTypes, CBN cbn, boolean recordUsage) {
this.idTypes = new HashSet(idTypes);
this.cbn = new DefaultCBN();
this.cbn = cbn;
this.recordObjectUsage = recordUsage;
}

public Set getInstantiatedVars() {
Expand All @@ -112,7 +115,7 @@ public Object getValue(BayesNetVar var) {
return commIdToPOPApp.get(((OriginVar) var).getIdentifier());
}
if (var instanceof DerivedVar) {
if (cbn.nodes().contains(var)) {
if (cbn != null && cbn.nodes().contains(var)) {
updateParentsAndProbs();
return derivedVarToValue.get(var);
}
Expand Down Expand Up @@ -147,6 +150,7 @@ public void setValue(BasicVar var, Object value) {
basicVarToValue.remove(var);
varToUninstParent.remove(var);
nameToBasicVar.remove(var.toString());
varToLogProb.remove(var);
} else {
// checkIdentifiers(var, value); // allow any identifiers
basicVarToValue.put(var, value);
Expand All @@ -160,6 +164,14 @@ public void setValue(BasicVar var, Object value) {
((WorldListener) iter.next()).varChanged(var, oldValue, value);
}
}

@Override
public void forceRemoveVar(BasicVar var) {
basicVarToValue.remove(var);
varToUninstParent.remove(var);
nameToBasicVar.remove(var.toString());
varToLogProb.remove(var);
}

public BasicVar getBasicVarByName(String name) {
return nameToBasicVar.get(name);
Expand Down Expand Up @@ -321,7 +333,7 @@ public void assertIdentifier(ObjectIdentifier id, NumberVar newPOPApp) {
popAppToAssertedIds.add(newPOPApp, id);

OriginVar originVar = new OriginVar(id);
if (cbn.nodes().contains(originVar)) {
if ((cbn != null) && cbn.nodes().contains(originVar)) {
dirtyVars.add(originVar); // so children are updated
}

Expand Down Expand Up @@ -404,7 +416,7 @@ public Set getDerivedVars() {
}

public boolean addDerivedVar(DerivedVar var) {
if (cbn.addNode(var)) {
if ((cbn != null) && cbn.addNode(var)) {
derivedVarToValue.put(var, PartialWorld.UNDET);
dirtyVars.add(var);
return true;
Expand All @@ -413,7 +425,7 @@ public boolean addDerivedVar(DerivedVar var) {
}

public boolean removeDerivedVar(DerivedVar var) {
if (cbn.removeNode(var)) {
if ((cbn != null) && cbn.removeNode(var)) {
derivedVarToValue.remove(var);
dirtyVars.remove(var);
return true;
Expand Down Expand Up @@ -814,7 +826,9 @@ public void updateVarInfo(BayesNetVar var) {
.put(var, (value == null) ? PartialWorld.UNDET : value);
}

cbn.setParents(var, context.getParents());
if (cbn != null) {
cbn.setParents(var, context.getParents());
}
if (context.getLatestUninstParent() == null) {
varToUninstParent.remove(var);
} else {
Expand All @@ -839,8 +853,9 @@ public void updateVarInfo(BayesNetVar var) {
throw new IllegalArgumentException("Need parents for variable " + var
+ ", which is not in given Bayes net.");
}
cbn.setParents(var, givenParents);

if (cbn != null) {
cbn.setParents(var, givenParents);
}
BasicVar uninstParent = (BasicVar) givenVarUninstParents.get(var);
if (uninstParent == null) {
varToUninstParent.remove(var);
Expand Down Expand Up @@ -883,7 +898,7 @@ private void updateParentsAndProbs(VarInfoUpdater updater) {
Set dirtyVarChildren = new LinkedHashSet();
for (Iterator iter = dirtyVars.iterator(); iter.hasNext();) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lileicc Why do you want to remove this line? (About varToLogProb)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since I already put it in setValue(...)
when value is null, I already put varToLogProb.remove(var).

BayesNetVar dirtyVar = (BayesNetVar) iter.next();
Set thisVarChildren = cbn.getChildren(dirtyVar);
Set thisVarChildren = cbn == null ? null : cbn.getChildren(dirtyVar);
if (thisVarChildren != null) {
dirtyVarChildren.addAll(thisVarChildren);
}
Expand All @@ -895,12 +910,15 @@ private void updateParentsAndProbs(VarInfoUpdater updater) {
BayesNetVar var = (BayesNetVar) iter.next();
if ((var instanceof BasicVar) && (basicVarToValue.get(var) == null)) {
// var has been uninstantiated
cbn.removeNode(var);
varToLogProb.remove(var);
if (cbn != null) {
cbn.removeNode(var);
}
} else if ((var instanceof OriginVar)
&& (assertedIdToPOPApp.get(((OriginVar) var).getIdentifier()) == null)) {
// identifier has been removed
cbn.removeNode(var);
if (cbn != null) {
cbn.removeNode(var);
}
} else {
// node still belongs in Bayes net
updater.updateVarInfo(var);
Expand Down Expand Up @@ -932,8 +950,11 @@ private ObjectIdentifier addCommId(NumberVar popApp) {
return id;
}

private void updateUsageForChange(BasicVar var, Object oldValue,
protected void updateUsageForChange(BasicVar var, Object oldValue,
Object newValue) {
if (!recordObjectUsage) {
return;
}
// update usage of arguments
Object[] args = var.args();
if ((oldValue == null) && (newValue != null)) {
Expand Down Expand Up @@ -1031,7 +1052,7 @@ public void cloneFields(AbstractPartialWorld newWorld) {
newWorld.popAppToAssertedIds = new IndexedHashMultiMap(popAppToAssertedIds);
newWorld.commIdToPOPApp = (Map) ((HashMap) commIdToPOPApp).clone();
newWorld.popAppToCommIds = new IndexedHashMultiMap(popAppToCommIds);
newWorld.cbn = (CBN) ((DefaultCBN) cbn).clone();
newWorld.cbn = (cbn == null) ? null : (CBN) ((DefaultCBN) cbn).clone();
newWorld.varToUninstParent = (MapWithPreimages) ((HashMapWithPreimages) varToUninstParent)
.clone();
newWorld.varToLogProb = (Map) ((HashMap) varToLogProb).clone();
Expand Down Expand Up @@ -1128,4 +1149,7 @@ public String toString() {
protected List listeners = new ArrayList(); // of WorldListener

protected Set<? extends Type> idTypes;

protected final boolean recordObjectUsage; // record usage of objects
// as arguments and values
}
88 changes: 45 additions & 43 deletions src/main/java/blog/world/DefaultPartialWorld.java
Original file line number Diff line number Diff line change
Expand Up @@ -35,60 +35,62 @@

package blog.world;

import java.util.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Set;

import blog.common.DGraph;
import blog.common.DefaultDGraph;
import blog.bn.BasicVar;
import blog.common.HashMapWithPreimages;
import blog.common.HashMultiMap;
import blog.common.IndexedHashMultiMap;
import blog.common.IndexedMultiMap;
import blog.common.MultiMap;
import blog.bn.BasicVar;
import blog.bn.DefaultCBN;


/**
* Straightforward implementation of AbstractPartialWorld.
*/
public class DefaultPartialWorld extends AbstractPartialWorld implements
Cloneable {
Cloneable {

/**
* Creates a new DefaultPartialWorld with no instantiated variables. This
* world will not use object identifiers for any types.
*/
public DefaultPartialWorld() {
this(Collections.EMPTY_SET);
}
/**
* Creates a new DefaultPartialWorld with no instantiated variables. This
* world will not use object identifiers for any types.
*/
public DefaultPartialWorld() {
this(Collections.EMPTY_SET);
}

/**
* Creates a new DefaultPartialWorld with no instantiated variables and no
* identifiers.
*
* @param idTypes
* Set of Type objects for types that will be represented with object
* identifiers
*/
public DefaultPartialWorld(Set idTypes) {
super(idTypes);
basicVarToValue = new HashMap();
/**
* Creates a new DefaultPartialWorld with no instantiated variables and no
* identifiers.
*
* @param idTypes
* Set of Type objects for types that will be represented with object
* identifiers
* @param recordUsage
* whether to record the object usage as argument or value of
* function application var
*/
public DefaultPartialWorld(Set idTypes, boolean recordUsage) {
super(idTypes, null, recordUsage);
basicVarToValue = new HashMap();
nameToBasicVar = new HashMap<String, BasicVar>();
objToUsesAsValue = new HashMultiMap();
objToUsesAsArg = new HashMultiMap();
assertedIdToPOPApp = new HashMap();
popAppToAssertedIds = new IndexedHashMultiMap();
commIdToPOPApp = new HashMap();
popAppToCommIds = new IndexedHashMultiMap();
cbn = new DefaultCBN();
varToUninstParent = new HashMapWithPreimages();
varToLogProb = new HashMap();
derivedVarToValue = new HashMap();
}
objToUsesAsValue = new HashMultiMap();
objToUsesAsArg = new HashMultiMap();
assertedIdToPOPApp = new HashMap();
popAppToAssertedIds = new IndexedHashMultiMap();
commIdToPOPApp = new HashMap();
popAppToCommIds = new IndexedHashMultiMap();
varToUninstParent = new HashMapWithPreimages();
varToLogProb = new HashMap();
derivedVarToValue = new HashMap();
}

public DefaultPartialWorld(Set idTypes) {
this(idTypes, false);
}

public Object clone() {
DefaultPartialWorld newWorld = new DefaultPartialWorld();
cloneFields(newWorld);
return newWorld;
}
public Object clone() {
DefaultPartialWorld newWorld = new DefaultPartialWorld();
cloneFields(newWorld);
return newWorld;
}
}
Loading