Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
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/Simulation/Core/Operations/Operation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ public Operation(IOperationFactory m) : base(m)
{
Label = ((ICallable)this).Name,
FormattedNonQubitArgs = args.GetNonQubitArgumentsAsString() ?? "",
Targets = args.GetQubits(),
Targets = args.GetQubits() ?? new List<Qubit>(),
};

public O Apply(I a)
Expand Down
5 changes: 2 additions & 3 deletions src/Simulation/Core/RuntimeMetadata.cs
Original file line number Diff line number Diff line change
Expand Up @@ -44,16 +44,15 @@ public class RuntimeMetadata
/// </summary>
/// </summary>
/// <remarks>
/// Currently not used as this is intended for composite operations,
/// such as <c>ApplyToEach</c>.
/// This is used in composite operations, such as <c>ApplyToEach</c>.
/// </remarks>
public bool IsComposite { get; set; }

/// <summary>
/// Group of operations for each classical branch (<c>true</c> and <c>false</c>).
/// </summary>
/// <remarks>
/// Currently not used as this is intended for classically-controlled operations.
/// This is used in classically-controlled operations.
/// </remarks>
public IEnumerable<IEnumerable<RuntimeMetadata>>? Children { get; set; }

Expand Down
11 changes: 5 additions & 6 deletions src/Simulation/Core/TypeExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;

Expand Down Expand Up @@ -155,15 +156,13 @@ public static Type[] GetTupleFieldTypes(this Type arg)
{
var t = o.GetType();

// If object is a Qubit, ignore it (i.e. return null)
if (o is Qubit) return null;
// If object is a Qubit, QVoid, or array of Qubits, ignore it (i.e. return null)
if (o is Qubit || o is QVoid || o is IEnumerable<Qubit>) return null;

// If object is an IApplyData, recursively extract nested fields
// and stringify them
// If object is an IApplyData, recursively extract arguments
if (o is IApplyData data)
{
var argsString = data.Value.GetNonQubitArgumentsAsString();
return argsString.Any() ? argsString : null;
return data.Value.GetNonQubitArgumentsAsString();
}

// If object is a string, enclose it in quotations
Expand Down
17 changes: 16 additions & 1 deletion src/Simulation/Simulators.Tests/Circuits/RuntimeMetadataTest.qs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,24 @@
// Licensed under the MIT License.

namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits {


open Microsoft.Quantum.Intrinsic;

newtype FooUDT = (String, (Qubit, Double));

operation FooUDTOp (foo : FooUDT) : Unit is Ctl + Adj { }

operation Empty () : Unit is Ctl + Adj { }

operation HOp (q : Qubit) : Unit {
H(q);
Reset(q);
}

operation NestedOp () : Unit {
using (q = Qubit()) {
HOp(q);
}
}

}
89 changes: 89 additions & 0 deletions src/Simulation/Simulators.Tests/RuntimeMetadataTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,29 @@ public void CCNOT()
Assert.Equal(op.GetRuntimeMetadata(args), expected);
}

[Fact]
public void Swap()
{
var q1 = new FreeQubit(0);
var q2 = new FreeQubit(1);
var op = new QuantumSimulator().Get<Intrinsic.SWAP>();
var args = op.__dataIn((q1, q2));
var expected = new RuntimeMetadata()
{
Label = "SWAP",
FormattedNonQubitArgs = "",
IsAdjoint = false,
IsControlled = false,
IsMeasurement = false,
IsComposite = false,
Children = null,
Controls = new List<Qubit>() { },
Targets = new List<Qubit>() { q1, q2 },
};

Assert.Equal(op.GetRuntimeMetadata(args), expected);
}

[Fact]
public void Ry()
{
Expand Down Expand Up @@ -273,6 +296,28 @@ public void M()

Assert.Equal(op.GetRuntimeMetadata(args), expected);
}

[Fact]
public void ResetAll()
{
IQArray<Qubit> targets = new QArray<Qubit>(new[] { new FreeQubit(0) });
var op = new QuantumSimulator().Get<Intrinsic.ResetAll>();
var args = op.__dataIn(targets);
var expected = new RuntimeMetadata()
{
Label = "ResetAll",
FormattedNonQubitArgs = "",
IsAdjoint = false,
IsControlled = false,
IsMeasurement = false,
IsComposite = false,
Children = null,
Controls = new List<Qubit>() { },
Targets = targets,
};

Assert.Equal(op.GetRuntimeMetadata(args), expected);
}
}

public class MeasurementTests
Expand Down Expand Up @@ -342,6 +387,50 @@ public void MResetZ()

Assert.Equal(op.GetRuntimeMetadata(args), expected);
}

[Fact]
public void EmptyOperation()
{
var measureQubit = new FreeQubit(0);
var op = new QuantumSimulator().Get<Circuits.Empty>();
var args = op.__dataIn(QVoid.Instance);
var expected = new RuntimeMetadata()
{
Label = "Empty",
FormattedNonQubitArgs = "",
IsAdjoint = false,
IsControlled = false,
IsMeasurement = false,
IsComposite = false,
Children = null,
Controls = new List<Qubit>() { },
Targets = new List<Qubit>() { },
};

Assert.Equal(op.GetRuntimeMetadata(args), expected);
}

[Fact]
public void NestedOperation()
{
var measureQubit = new FreeQubit(0);
var op = new QuantumSimulator().Get<Circuits.NestedOp>();
var args = op.__dataIn(QVoid.Instance);
var expected = new RuntimeMetadata()
{
Label = "NestedOp",
FormattedNonQubitArgs = "",
IsAdjoint = false,
IsControlled = false,
IsMeasurement = false,
IsComposite = false,
Children = null,
Controls = new List<Qubit>() { },
Targets = new List<Qubit>() { },
};

Assert.Equal(op.GetRuntimeMetadata(args), expected);
}
}

public class UDTTests
Expand Down
35 changes: 35 additions & 0 deletions src/Simulation/Simulators.Tests/TypeExtensionsTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,22 @@ public void BasicTypes()
Assert.Equal("\"\"", "".GetNonQubitArgumentsAsString());
}

[Fact]
public void QubitTypes()
{
var q = new FreeQubit(0);
Assert.Null(q.GetNonQubitArgumentsAsString());

var qs = new QArray<Qubit>(new[] { new FreeQubit(0) });
Assert.Null(qs.GetNonQubitArgumentsAsString());

qs = new QArray<Qubit>(new[] { new FreeQubit(0), new FreeQubit(1) });
Assert.Null(qs.GetNonQubitArgumentsAsString());

var qtuple = new QTuple<Qubit>(q);
Assert.Null(qtuple.GetNonQubitArgumentsAsString());
}

[Fact]
public void TupleTypes()
{
Expand All @@ -41,6 +57,9 @@ public void TupleTypes()
Assert.Equal("(\"foo\", \"bar\", \"\")", ("foo", "bar", "").GetNonQubitArgumentsAsString());
Assert.Equal("(\"foo\", (\"bar\", \"car\"))", ("foo", ("bar", "car")).GetNonQubitArgumentsAsString());
Assert.Equal("((\"foo\"), (\"bar\", \"car\"))", (("foo", new FreeQubit(0)), ("bar", "car")).GetNonQubitArgumentsAsString());

var qtuple = new QTuple<(Qubit, string)>((new FreeQubit(0), "foo"));
Assert.Equal("(\"foo\")", qtuple.GetNonQubitArgumentsAsString());
}

[Fact]
Expand Down Expand Up @@ -84,6 +103,22 @@ public void IApplyDataTypes()
};
data = new ApplyData<(FreeQubit, string)[]>(arr);
Assert.Equal("[(\"foo\"), (\"bar\")]", data.GetNonQubitArgumentsAsString());

var qtupleWithString = new QTuple<(Qubit, string)>((new FreeQubit(0), "foo"));
data = new ApplyData<QTuple<(Qubit, string)>>(qtupleWithString);
Assert.Equal("(\"foo\")", data.GetNonQubitArgumentsAsString());

var q = new FreeQubit(0);
data = new ApplyData<Qubit>(q);
Assert.Null(data.GetNonQubitArgumentsAsString());

var qs = new QArray<Qubit>(new[] { new FreeQubit(0), new FreeQubit(1) });
data = new ApplyData<IQArray<Qubit>>(qs);
Assert.Null(data.GetNonQubitArgumentsAsString());

var qtuple = new QTuple<Qubit>(q);
data = new ApplyData<QTuple<Qubit>>(qtuple);
Assert.Null(data.GetNonQubitArgumentsAsString());
}
}
}