如何在C#中正确管理Qubit的生存期

时间:2018-06-30 16:07:09

标签: c# q#

我正在玩Q#,它使用C#作为驱动程序。我想将Qubit对象传递给Q#代码,但是它没有按预期工作。

C#驱动程序

using Microsoft.Quantum.Simulation.Core;
using Microsoft.Quantum.Simulation.Simulators;

namespace Quantum.QSharpApplication1 {
    class Driver {
        static void Main(string[] args) {
            using (var sim = new QuantumSimulator()) {
                var x = new Microsoft.Quantum.Simulation.Common.QubitManager(10);
                Qubit q1 = x.Allocate();
                Solve.Run(sim, q1, 1);
                }
            System.Console.WriteLine("Press any key to continue...");
            System.Console.ReadKey();
            }
        }
    }

Q#

namespace Quantum.QSharpApplication1
{
    open Microsoft.Quantum.Primitive;
    open Microsoft.Quantum.Canon;

operation Solve (q : Qubit, sign : Int) : ()
    {
        body
        {
            let qp = M(q);
            if (qp != Zero)
            {
                X(q);
            }     
            H(q);
        }
    }
}

当我运行此代码时,它会一直运行直到到达System.Console。*行,而不会出错,此时,它会在Q#代码中引发以下异常

System.AccessViolationException
  HResult=0x80004003
  Message=Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
  Source=<Cannot evaluate the exception source>
  StackTrace:
<Cannot evaluate the exception stack trace>

调试器将此与“ let qp = M(q);”相关联Q#中的行。

请注意,这确实发生在Solve.Run调用中,实际代码具有多个Solve调用,并且输出显示正确。它仅在使用完QuantumSimulator范围后出现。我记得曾读过一篇文章,在发布Qubit之前必须将其重置为零。我不确定这是否是问题所在,但我看不到C#的解决方法。有趣的是,我删除了控制台行,该程序将无错误运行(定时?)。

1 个答案:

答案 0 :(得分:2)

您用来创建量子位的QubitManager实例不是单例(每个Simulator都有自己的QubitManager),因此Simulator并不知道{ {1}}试图操纵Q​​#代码,即Qubit

通常,不支持在驱动程序上创建Qubit。您可以在Q#中使用only allocate qubits using the allocate and borrowing条语句。建议在Q#中创建一个入口点,以分配执行qubit分配的qubit,并从驱动程序中调用它,例如:

AccessViolationException

最后,请注意,在驱动程序代码中您具有以下内容: // MyOp.qs operation EntryPoint() : () { body { using (register = Qubit[2]) { myOp(register); } } } // Driver.cs EntryPoint.Run().Wait();

Solve.Run(sim, q1, 1); 方法返回异步执行的任务。通常,您必须添加Run以确保其完成执行: Wait()

如果这样做,您会发现在 EntryPoint.Run(sim, 1).Wait(); 而不是Run期间发生了故障。