locked
How to track down "System.NullReferenceException"?

    Question

  • I've built a fairly large belief network (Printer Nightmare example from David Barber Bayesian Reasoning and Machine Learning book). Multiple random variables, their parameter and associated prior variables are defined and used in a graph. I used the Sprinkler demo from samples as a guidance and for the structure for the code.

    When running the inference, the Infer.NET compiler stumbles upon the first "Engine.Infer<Beta>(probFuse)" statement. The error message is not very informative, nor is the call trace. For example, I cannot see RV names in the error message which could help me to pin down the null reference object. I tried to do debugging and check if any of RVs is null but everything appears to be fine (I am sure something is not defined properly somewhere).

    Is there a way to track down what exactly is null reference? What are the best techniques?

    The code is on Github: https://github.com/usptact/PrinterNightmare/blob/master/PrinterNightmare.cs

    Thanks


    • Edited by usptact Wednesday, November 1, 2017 8:12 AM
    Wednesday, November 1, 2017 8:09 AM

Answers

  • Thanks for the stack trace, that told me where the bug is.  You have found a bug in Infer.NET.  It will be fixed in the next version.  Meanwhile, you can work around by using the following code:

        public static VariableArray<bool> AddChildFromThreeParents(VariableArray<bool> parent1, VariableArray<bool> parent2, VariableArray<bool> parent3, VariableArray<VariableArray<VariableArray<double>, double[][]>, double[][][]> cpt)
        {
            var n = parent1.Range;
            var child = Variable.Array<bool>(n);
            using (Variable.ForEach(n))
            {
                var parent2n = parent2[n] & Variable.Bernoulli(1.0);
                using (Variable.If(parent1[n]))
                {
                    using (Variable.If(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][0][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][0][1]);
                    }
                    using (Variable.IfNot(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][1][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][1][1]);
                    }
                }
                using (Variable.IfNot(parent1[n]))
                {
                    using (Variable.If(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][0][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][0][1]);
                    }
                    using (Variable.IfNot(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][1][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][1][1]);
                    }
                }
            }
            return child;
        }
    

    • Marked as answer by usptact Wednesday, November 1, 2017 7:44 PM
    Wednesday, November 1, 2017 7:14 PM
    Owner
  • Infer.NET version 2.7 is now out and fixes this problem.
    • Marked as answer by usptact Monday, April 2, 2018 3:47 PM
    Sunday, April 1, 2018 2:51 PM
    Owner

All replies

  • The best technique is to enable debugging in the generated code, described at Debugging inference.
    Wednesday, November 1, 2017 2:39 PM
    Owner
  • Thanks. The problem is that there is no generated code. Apparently, something fails pretty early and the GeneratedSources folder is never created and populated.

    For the record, I set these fields in the engine:

    engine.Compiler.GenerateInMemory = false;
    engine.Compiler.WriteSourceFiles = true;
    engine.Compiler.IncludeDebugInformation = true;



    • Edited by usptact Wednesday, November 1, 2017 4:14 PM
    Wednesday, November 1, 2017 4:13 PM
  • The complete error message:

    Exception thrown: 'System.NullReferenceException' in Infer.Compiler.dll
    An unhandled exception of type 'System.NullReferenceException' occurred in Infer.Compiler.dll
    Object reference not set to an instance of an object.

    Wednesday, November 1, 2017 5:08 PM
  • I think I have identified the problem. The "AddChildFromThreeParents" function builds a VariablArray<bool> and has 3 levels of branching.

    public static VariableArray<bool> AddChildFromThreeParents(VariableArray<bool> parent1, VariableArray<bool> parent2, VariableArray<bool> parent3, VariableArray<VariableArray<VariableArray<double>, double[][]>, double[][][]> cpt)
        {
            var n = parent1.Range;
            var child = Variable.Array<bool>(n);
            using (Variable.ForEach(n))
            {
                using (Variable.If(parent1[n]))
                {
                    using (Variable.If(parent2[n]))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][0][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][0][1]);
                    }
                    using (Variable.IfNot(parent2[n]))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][1][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][1][1]);
                    }
                }
                using (Variable.IfNot(parent1[n]))
                {
                    using (Variable.If(parent2[n]))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][0][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][0][1]);
                    }
                    using (Variable.IfNot(parent2[n]))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][1][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][1][1]);
                    }
                }
            }
            return child;
        }

    The other two functions for adding a child from one and two parents respectively work well (inference runs). There is something bad with branching at 3 levels...

    Wednesday, November 1, 2017 5:47 PM
  • You should get a more complete error message (with stack trace) if you compile with Debugging enabled.
    Wednesday, November 1, 2017 5:59 PM
    Owner
  • Unfortunately, this is the stack trace that I am able to get. I don't see variable names that could help me to find the problem.

    Compiling model...System.NullReferenceException: Object reference not set to an
    instance of an object.
       at MicrosoftResearch.Infer.CompilerAttributes.Containers.ContainerGetHashCode
    (IStatement st) in c:\Builds\2\infernet\External\src\infernet\Compiler\Infer\Com
    pilerAttributes\Containers.cs:line 319
       at MicrosoftResearch.Infer.CompilerAttributes.Containers.ContainerComparer.Ge
    tHashCode(IStatement st) in c:\Builds\2\infernet\External\src\infernet\Compiler\
    Infer\CompilerAttributes\Containers.cs:line 333
       at MicrosoftResearch.Infer.Utils.Hash.GetHashCodeAsSet[T](IEnumerable`1 set,
    IEqualityComparer`1 comparer) in c:\Builds\2\infernet\External\src\infernet\Runt
    ime\Core\Utils\Hash.cs:line 125
       at MicrosoftResearch.Infer.CompilerAttributes.Containers.GetHashCode() in c:\
    Builds\2\infernet\External\src\infernet\Compiler\Infer\CompilerAttributes\Contai
    ners.cs:line 231
       at System.Collections.Generic.ObjectEqualityComparer`1.GetHashCode(T obj)
       at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boo
    lean add)
       at MicrosoftResearch.Infer.Collections.Set`1.Add(T item) in c:\Builds\2\infer
    net\External\src\infernet\Runtime\Core\Collections\Set.cs:line 120
       at MicrosoftResearch.Transforms.AttributeRegistry`2.Set(TObject obj, TAttribu
    te attr) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramewo
    rk\AttributeRegistry.cs:line 219
       at #h.#ln.#Db(IExpression #j) in c:\Builds\2\infernet\External\src\infernet\C
    ompiler\Infer\Transforms\ReplicationTransform.cs:line 392
       at #h.#ln.ConvertArrayIndexer(IArrayIndexerExpression #T) in c:\Builds\2\infe
    rnet\External\src\infernet\Compiler\Infer\Transforms\ReplicationTransform.cs:lin
    e 100
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertExpression(IExpression
     expr) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework
    \CopyTransform.cs:line 616
       at MicrosoftResearch.Transforms.CopyTransform.ConvertExpression(IExpression e
    xpr) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\C
    opyTransform.cs:line 602
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertCollection(IList`
    1 exprColl) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFram
    ework\ShallowCopyTransform.cs:line 417
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertMethodInvoke(IMet
    hodInvokeExpression imie) in c:\Builds\2\infernet\External\src\infernet\Compiler
    \TransformFramework\ShallowCopyTransform.cs:line 435
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertExpression(IExpression
     expr) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework
    \CopyTransform.cs:line 610
       at MicrosoftResearch.Transforms.CopyTransform.ConvertExpression(IExpression e
    xpr) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\C
    opyTransform.cs:line 602
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertAssign(IAssignExp
    ression iae) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFra
    mework\ShallowCopyTransform.cs:line 401
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertExpression(IExpression
     expr) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework
    \CopyTransform.cs:line 609
       at MicrosoftResearch.Transforms.CopyTransform.ConvertExpression(IExpression e
    xpr) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\C
    opyTransform.cs:line 602
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertExpressionStateme
    nt(IExpressionStatement ies) in c:\Builds\2\infernet\External\src\infernet\Compi
    ler\TransformFramework\ShallowCopyTransform.cs:line 102
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertStatement(IStatement i
    st) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Co
    pyTransform.cs:line 464
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatement(IStatement ist
    ) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Copy
    Transform.cs:line 446
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatements(IList`1 outpu
    ts, IList`1 inputs) in c:\Builds\2\infernet\External\src\infernet\Compiler\Trans
    formFramework\CopyTransform.cs:line 396
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertBlockAlreadyOpen(
    IBlockStatement inputBlock) in c:\Builds\2\infernet\External\src\infernet\Compil
    er\TransformFramework\ShallowCopyTransform.cs:line 74
       at MicrosoftResearch.Transforms.CopyTransform.ConvertBlock(IBlockStatement in
    putBlock) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramew
    ork\CopyTransform.cs:line 346
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertCondition(ICondit
    ionStatement ics) in c:\Builds\2\infernet\External\src\infernet\Compiler\Transfo
    rmFramework\ShallowCopyTransform.cs:line 91
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertStatement(IStatement i
    st) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Co
    pyTransform.cs:line 472
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatement(IStatement ist
    ) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Copy
    Transform.cs:line 446
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatements(IList`1 outpu
    ts, IList`1 inputs) in c:\Builds\2\infernet\External\src\infernet\Compiler\Trans
    formFramework\CopyTransform.cs:line 396
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertBlockAlreadyOpen(
    IBlockStatement inputBlock) in c:\Builds\2\infernet\External\src\infernet\Compil
    er\TransformFramework\ShallowCopyTransform.cs:line 74
       at MicrosoftResearch.Transforms.CopyTransform.ConvertBlock(IBlockStatement in
    putBlock) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramew
    ork\CopyTransform.cs:line 346
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertCondition(ICondit
    ionStatement ics) in c:\Builds\2\infernet\External\src\infernet\Compiler\Transfo
    rmFramework\ShallowCopyTransform.cs:line 91
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertStatement(IStatement i
    st) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Co
    pyTransform.cs:line 472
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatement(IStatement ist
    ) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Copy
    Transform.cs:line 446
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatements(IList`1 outpu
    ts, IList`1 inputs) in c:\Builds\2\infernet\External\src\infernet\Compiler\Trans
    formFramework\CopyTransform.cs:line 396
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertBlockAlreadyOpen(
    IBlockStatement inputBlock) in c:\Builds\2\infernet\External\src\infernet\Compil
    er\TransformFramework\ShallowCopyTransform.cs:line 74
       at MicrosoftResearch.Transforms.CopyTransform.ConvertBlock(IBlockStatement in
    putBlock) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramew
    ork\CopyTransform.cs:line 346
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertFor(IForStatement
     ifs) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\
    ShallowCopyTransform.cs:line 116
       at #h.#ln.ConvertFor(IForStatement #V) in c:\Builds\2\infernet\External\src\i
    nfernet\Compiler\Infer\Transforms\ReplicationTransform.cs:line 45
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertStatement(IStatement i
    st) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Co
    pyTransform.cs:line 476
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatement(IStatement ist
    ) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Copy
    Transform.cs:line 446
       at MicrosoftResearch.Transforms.CopyTransform.ConvertStatements(IList`1 outpu
    ts, IList`1 inputs) in c:\Builds\2\infernet\External\src\infernet\Compiler\Trans
    formFramework\CopyTransform.cs:line 396
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertMethodBody(IList`1 out
    puts, IList`1 inputs) in c:\Builds\2\infernet\External\src\infernet\Compiler\Tra
    nsformFramework\CopyTransform.cs:line 321
       at MicrosoftResearch.Transforms.CopyTransform.DoConvertMethod(IMethodDeclarat
    ion md, IMethodDeclaration imd) in c:\Builds\2\infernet\External\src\infernet\Co
    mpiler\TransformFramework\CopyTransform.cs:line 305
       at MicrosoftResearch.Transforms.ShallowCopyTransform.DoConvertMethod(IMethodD
    eclaration md, IMethodDeclaration imd) in c:\Builds\2\infernet\External\src\infe
    rnet\Compiler\TransformFramework\ShallowCopyTransform.cs:line 53
       at MicrosoftResearch.Transforms.CopyTransform.ConvertMethod(IMethodDeclaratio
    n imd) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework
    \CopyTransform.cs:line 156
       at MicrosoftResearch.Transforms.CopyTransform.ConvertMethods(ITypeDeclaration
     td, ITypeDeclaration itd) in c:\Builds\2\infernet\External\src\infernet\Compile
    r\TransformFramework\CopyTransform.cs:line 137
       at MicrosoftResearch.Transforms.CopyTransform.ConvertType(ITypeDeclaration it
    d) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\Cop
    yTransform.cs:line 64
       at MicrosoftResearch.Transforms.ShallowCopyTransform.ConvertType(ITypeDeclara
    tion itd) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramew
    ork\ShallowCopyTransform.cs:line 20
       at MicrosoftResearch.Transforms.CopyTransform.Transform(ITypeDeclaration itd)
     in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFramework\CopyT
    ransform.cs:line 46
       at MicrosoftResearch.Transforms.CodeTransformer.TransformToDeclaration(ITypeD
    eclaration typeDecl) in c:\Builds\2\infernet\External\src\infernet\Compiler\Tran
    sformFramework\CodeTransformer.cs:line 55
       at MicrosoftResearch.Transforms.TransformerChain.TransformToDeclaration(IType
    Declaration itd, AttributeRegistry`2 inputAttributes, Boolean trackTransform, Bo
    olean showProgress, List`1& warnings, Boolean catchExceptions, Boolean treatWarn
    ingsAsErrors) in c:\Builds\2\infernet\External\src\infernet\Compiler\TransformFr
    amework\TransformerChain.cs:line 63
       at MicrosoftResearch.Infer.ModelCompiler.GetTransformedDeclaration(ITypeDecla
    ration itd, MethodBase method, AttributeRegistry`2 inputAttributes) in c:\Builds
    \2\infernet\External\src\infernet\Compiler\Infer\ModelCompiler.cs:line 704
       at MicrosoftResearch.Infer.ModelCompiler.CompileWithoutParams(ITypeDeclaratio
    n itd, MethodBase method, AttributeRegistry`2 inputAttributes) in c:\Builds\2\in
    fernet\External\src\infernet\Compiler\Infer\ModelCompiler.cs:line 757
       at MicrosoftResearch.Infer.InferenceEngine.Compile() in c:\Builds\2\infernet\
    External\src\infernet\Compiler\Infer\InferenceEngine.cs:line 223
       at MicrosoftResearch.Infer.InferenceEngine.BuildAndCompile(Boolean inferOnlyS
    pecifiedVars, IEnumerable`1 vars) in c:\Builds\2\infernet\External\src\infernet\
    Compiler\Infer\InferenceEngine.cs:line 637
       at MicrosoftResearch.Infer.InferenceEngine.GetCompiledInferenceAlgorithm(Bool
    ean inferOnlySpecifiedVars, IVariable var) in c:\Builds\2\infernet\External\src\
    infernet\Compiler\Infer\InferenceEngine.cs:line 598
       at MicrosoftResearch.Infer.InferenceEngine.Infer[TReturn](IVariable var) in c
    :\Builds\2\infernet\External\src\infernet\Compiler\Infer\InferenceEngine.cs:line
     272
       at PrinterNightmare.LearnParameters(Boolean[] fuse, Boolean[] drum, Boolean[]
     toner, Boolean[] paper, Boolean[] roller, Boolean[] burning, Boolean[] quality,
     Boolean[] wrinkled, Boolean[] multPages, Boolean[] paperJam) in C:\Users\vladis
    lavsd\Documents\Visual Studio 2017\Projects\PrinterNightmare\PrinterNightmare.cs
    :line 191
       at PrinterNightmare.Main() in C:\Users\vladislavsd\Documents\Visual Studio 20
    17\Projects\PrinterNightmare\PrinterNightmare.cs:line 313
    

    Wednesday, November 1, 2017 6:10 PM
  • Thanks for the stack trace, that told me where the bug is.  You have found a bug in Infer.NET.  It will be fixed in the next version.  Meanwhile, you can work around by using the following code:

        public static VariableArray<bool> AddChildFromThreeParents(VariableArray<bool> parent1, VariableArray<bool> parent2, VariableArray<bool> parent3, VariableArray<VariableArray<VariableArray<double>, double[][]>, double[][][]> cpt)
        {
            var n = parent1.Range;
            var child = Variable.Array<bool>(n);
            using (Variable.ForEach(n))
            {
                var parent2n = parent2[n] & Variable.Bernoulli(1.0);
                using (Variable.If(parent1[n]))
                {
                    using (Variable.If(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][0][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][0][1]);
                    }
                    using (Variable.IfNot(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][1][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[0][1][1]);
                    }
                }
                using (Variable.IfNot(parent1[n]))
                {
                    using (Variable.If(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][0][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][0][1]);
                    }
                    using (Variable.IfNot(parent2n))
                    {
                        using (Variable.If(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][1][0]);
                        using (Variable.IfNot(parent3[n]))
                            child[n] = Variable.Bernoulli(cpt[1][1][1]);
                    }
                }
            }
            return child;
        }
    

    • Marked as answer by usptact Wednesday, November 1, 2017 7:44 PM
    Wednesday, November 1, 2017 7:14 PM
    Owner
  • Thank you very much, Tom! I was tinkering with this function and noticed that the error appeared whenever the 3rd branching with Variable.If() / Variable.IfNot() was created.

    Your workaround works!

    Is the new release coming any time soon, if I may ask? Will it be more like bug fixing or there will be some breaking changes? Just curious what is in store.

    Wednesday, November 1, 2017 7:47 PM
  • The upcoming changes are listed at release change history.
    Wednesday, November 1, 2017 9:30 PM
    Owner
  • Infer.NET version 2.7 is now out and fixes this problem.
    • Marked as answer by usptact Monday, April 2, 2018 3:47 PM
    Sunday, April 1, 2018 2:51 PM
    Owner
  • This is great news! I am very excited!

    Tom, thank you for the great work on the framework and for the support in the forum here! Thank you a lot!

    Monday, April 2, 2018 3:48 PM