Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.

Simulators with missing gates throw NullReferenceException #513

@cgranade

Description

@cgranade

Describe the bug

If a simulator in the C# runtime does not implement the interface for a given intrinsic operation / gate, then when the corresponding operation is called from Q#, the simulator throws a NullReferenceException.

To Reproduce

The experimental open systems simulator at

public partial class OpenSystemsSimulator : SimulatorBase, IType1Core, IDisposable
implements the IType1Core interface, but not the IQSharpCore interface, such that the IGate_Z interface is not implemented by Microsoft.Quantum.Experimental.OpenSystemsSimulator. If Z is called from a Q# program, a NullReferenceException is thrown.

Expected behavior

The IType1Core interface should allow for the Z operation to be implemented by the ApplyUncontrolledZ__Body C# method.

Actual behavior

Unhandled exception: System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.Quantum.Intrinsic.Z.<get___Body__>b__9_0(Qubit __in__)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Microsoft.Quantum.Simulation.Core.ICallable<I,O>.Apply(I args)      
   at Microsoft.Quantum.Synthesis.ApplyDirectly1C.<get___Body__>b__31_0(ValueTuple`2 __in__)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Microsoft.Quantum.Simulation.Core.ICallable<I,O>.Apply(I args)      
   at Microsoft.Quantum.Synthesis.Apply1C.<get___Body__>b__15_0(ValueTuple`2 __in__)
   at Microsoft.Quantum.Simulation.Core.OperationPartial`3.<get___Body__>b__22_0(P a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Microsoft.Quantum.Simulation.Core.ICallable.Apply(Object args)      
   at Microsoft.Quantum.Canon.ApplyToEach`1.<get___Body__>b__12_0(ValueTuple`2 __in__)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply[GenO](Object args)
   at Microsoft.Quantum.Simulation.Core.GenericCallable.Apply[O](Object args)
   at Microsoft.Quantum.Simulation.Core.GenericCallable.Microsoft.Quantum.Simulation.Core.ICallable.Apply(Object args)
   at Microsoft.Quantum.Characterization.[omitted].<get___Body__>b__30_0(Int64 __in__)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Microsoft.Quantum.Simulation.Core.ICallable<I,O>.Apply(I args)      
   at Microsoft.Quantum.Characterization.[omitted].<get___Body__>b__11_0(ValueTuple`2 __in__)  
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Microsoft.Quantum.Simulation.Core.ICallable<I,O>.Apply(I args)      
   at Microsoft.Quantum.Experimental.[omitted].<get___Body__>b__23_0(ValueTuple`2 __in__) in [omitted]
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Microsoft.Quantum.Simulation.Core.ICallable<I,O>.Apply(I args)      
   at Microsoft.Quantum.Experimental.[omitted].<get___Body__>b__12_0(QVoid __in__) in [omitted]
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply(I a)
   at Microsoft.Quantum.Simulation.Core.Operation`2.Apply[GenO](Object args)
   at Microsoft.Quantum.Simulation.Common.SimulatorBase.Execute[T,I,O](I args)
   at Microsoft.Quantum.Simulation.Common.SimulatorBase.<>c__DisplayClass64_0`3.<Run>b__0()
   at System.Threading.Tasks.Task`1.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__274_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location where exception was thrown ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.Quantum.EntryPointDriver.Simulation`3.RunSimulator(IEntryPoint`2 entryPoint, ParseResult parseResult, Func`1 createSimulator)
   at Microsoft.Quantum.EntryPointDriver.Simulation`3.Simulate(DriverSettings settings, IEntryPoint`2 entryPoint, ParseResult parseResult, String simulator)
   at Microsoft.Quantum.EntryPointDriver.Driver`3.Simulate(ParseResult parseResult, String simulator)
   at System.CommandLine.Invocation.CommandHandler.GetResultCodeAsync(Object value, InvocationContext context)
   at System.CommandLine.Invocation.ModelBindingCommandHandler.InvokeAsync(InvocationContext context)
   at System.CommandLine.Invocation.InvocationPipeline.<>c__DisplayClass4_0.<<BuildInvocationChain>b__0>d.MoveNext()    
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseParseErrorReporting>b__20_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass15_0.<<UseHelp>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass24_0.<<UseVersionOption>b__0>d.MoveNext()--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass22_0.<<UseTypoCorrections>b__0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseSuggestDirective>b__21_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseParseDirective>b__19_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<UseDebugDirective>b__11_0>d.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c.<<RegisterWithDotnetSuggest>b__10_0>d.MoveNext()      
--- End of stack trace from previous location where exception was thrown ---
   at System.CommandLine.Builder.CommandLineBuilderExtensions.<>c__DisplayClass13_0.<<UseExceptionHandler>b__0>d.MoveNext()

Additional context

Looking at Z.g.cs, the issue seems to be the use of as to cast the operation factory to an IGate_Z instance:

// Z.g.cs
public Z(IOperationFactory m) : base(m)
{
    this.Gate = m as IGate_Z; // this cast fails, but doesn't throw immediately
}
private protected IGate_Z Gate
{
    get;
}
public override Func<Qubit, QVoid> __Body__ => (__in__) =>
{
    var qubit = __in__;
    Gate.Z__Body(qubit); // 💣
    return QVoid.Instance;
}

As @swernli pointed out in offline discussion, the issue can be mitigated by modifying *.csproj files:

<Project Sdk="Microsoft.Quantum.Sdk/0.15.210223170-alpha">
    <PropertyGroup>
        <OutputType>Exe</OutputType>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <DefaultSimulator>Microsoft.Quantum.Experimental.OpenSystemsSimulator</DefaultSimulator>
        <IncludeQSharpCorePackages>false</IncludeQSharpCorePackages>
    </PropertyGroup>
    <ItemGroup>
        <PackageReference Include="Microsoft.Quantum.EntryPointDriver" Version="0.15.210223170-alpha" />
        <PackageReference Include="Microsoft.Quantum.Type1.Core" Version="0.15.210223170-alpha" />
    </ItemGroup>
</Project>

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions