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

Commit 1efa79c

Browse files
authored
QEP 2: Enhanced Array Literals (#643)
* Add C# gen for sized array * Implement QArray.Repeat * Add more array tests * Add doc comments * More efficient array creation * Remove TODO, leave exception type untested * Formatting * Update packages * Add tests for ref counts in array-of-arrays * Capture value expression * Undo QscVerbosity * Clean up QArrayInner.Extend * Increment ref count N times * Add comment about exception type * Update packages * Fix partial application code gen test * Update SDK package * Update Microsoft.Quantum.CSharpGeneration.fsproj * Update Microsoft.Quantum.CSharpGeneration.fsproj * Update C# generation tests for microsoft/qsharp-compiler#952 * Update global.json
1 parent 9aa4e93 commit 1efa79c

29 files changed

+187
-99
lines changed

global.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
22
"msbuild-sdks": {
3-
"Microsoft.Quantum.Sdk": "0.15.210425594-alpha"
3+
"Microsoft.Quantum.Sdk": "0.15.210425813-alpha"
44
}
55
}

src/Simulation/CSharpGeneration.Tests/SimulationCodeTests.fs

Lines changed: 34 additions & 27 deletions
Large diffs are not rendered by default.

src/Simulation/CSharpGeneration/Microsoft.Quantum.CSharpGeneration.fsproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
<ItemGroup>
2424
<PackageReference Update="FSharp.Core" Version="4.7.0" />
25-
<PackageReference Include="Microsoft.Quantum.Compiler" Version="0.15.210324735-alpha" />
25+
<PackageReference Include="Microsoft.Quantum.Compiler" Version="0.15.210425459-pull" />
2626
</ItemGroup>
2727

2828
<ItemGroup>

src/Simulation/CSharpGeneration/SimulationCode.fs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,7 @@ module SimulationCode =
409409
| NamedItem (ex, acc) -> buildNamedItem ex acc
410410
| ArrayItem (a, i) -> buildArrayItem a i
411411
| ValueArray elems -> buildValueArray ex.ResolvedType elems
412+
| SizedArray (value, size) -> buildSizedArray value size
412413
| NewArray (t, expr) -> buildNewArray t expr
413414
| AdjointApplication op -> (buildExpression op) <|.|> (``ident`` "Adjoint")
414415
| ControlledApplication op -> (buildExpression op) <|.|> (``ident`` "Controlled")
@@ -591,6 +592,10 @@ module SimulationCode =
591592
// TODO: diagnostics.
592593
| _ -> failwith ""
593594

595+
and buildSizedArray value size =
596+
let supplier = ``() =>`` [] (captureExpression value) :> ExpressionSyntax
597+
ident "QArray" <.> (ident "Filled", [ supplier; buildExpression size ])
598+
594599
and buildNewArray b count =
595600
let arrayType = (ArrayType b |> QArrayType).Value
596601
arrayType <.> (``ident`` "Create", [count |> buildExpression])

src/Simulation/Core/QArray.cs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -135,16 +135,22 @@ public void UnsafeSetElement(long index, T value)
135135

136136
public void Extend(long newLength)
137137
{
138-
var newLengthInt = Convert.ToInt32(newLength);
139-
if (storage is null)
140-
{
141-
storage = new List<T>(newLengthInt);
142-
}
143-
else if (storage.Capacity < newLengthInt)
144-
{
145-
storage.Capacity = newLengthInt;
146-
}
147-
storage.AddRange(Enumerable.Repeat(Default.OfType<T>(), newLengthInt - storage.Count));
138+
var value = Default.OfType<T>();
139+
Extend(() => value, Convert.ToInt32(newLength - Length));
140+
}
141+
142+
/// <summary>
143+
/// Extends the length of the array by calling <paramref name="supplier"/> <paramref name="count"/> times to
144+
/// supply a value for each new index.
145+
/// </summary>
146+
internal void Extend(Func<T> supplier, long count)
147+
{
148+
var total = Convert.ToInt32(Length + count);
149+
storage ??= new List<T>(total);
150+
storage.Capacity = Math.Max(storage.Capacity, total);
151+
storage.AddRange(Enumerable
152+
.Repeat<object>(null, Convert.ToInt32(count))
153+
.Select(_ => supplier()));
148154
}
149155
}
150156

@@ -232,15 +238,26 @@ public QArray(params T[] collection)
232238
}
233239

234240
/// <summary>
235-
/// Creates an array of size given by capacity and default-initializes
236-
/// array elements. Uses C# keyword <code>default</code> to initialize array elements.
241+
/// Creates an array of size given by capacity and initializes each array element to the default value it has in
242+
/// Q#.
237243
/// </summary>
238244
public static QArray<T> Create(long capacity) => new QArray<T>
239245
{
240246
storage = new QArrayInner(capacity),
241247
Length = capacity
242248
};
243249

250+
/// <summary>
251+
/// Creates an array filled by calling <paramref name="supplier"/> <paramref name="count"/> times to supply a
252+
/// value for each index.
253+
/// </summary>
254+
internal static QArray<T> Filled(Func<T> supplier, long count)
255+
{
256+
var array = new QArray<T> { Length = count };
257+
array.storage.Extend(supplier, count);
258+
return array;
259+
}
260+
244261
/// <summary>
245262
/// Creates a copy of this array.
246263
/// </summary>
@@ -517,6 +534,17 @@ public static implicit operator QArray<object>(QArray<T> arg) =>
517534
arg;
518535
}
519536

537+
/// <summary>
538+
/// Contains static methods for creating <see cref="QArray"/>s.
539+
/// </summary>
540+
public static class QArray
541+
{
542+
/// <summary>
543+
/// Creates an array filled by calling <paramref name="supplier"/> <paramref name="count"/> times to supply a
544+
/// value for each index.
545+
/// </summary>
546+
public static QArray<T> Filled<T>(Func<T> supplier, long count) => QArray<T>.Filled(supplier, count);
547+
}
520548

521549
/// <summary>
522550
/// This JsonConverter converts instances of IQArray['T] as QArray['T]
@@ -557,4 +585,3 @@ public override bool CanConvert(Type objectType) =>
557585
objectType.GetGenericTypeDefinition() == typeof(QArray<>);
558586
}
559587
}
560-

src/Simulation/QCTraceSimulator.Tests/Tests.Microsoft.Quantum.Simulation.QCTraceSimulatorRuntime.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.Quantum.Sdk">
1+
<Project Sdk="Microsoft.Quantum.Sdk">
22

33
<Import Project="..\Common\AssemblyCommon.props" />
44
<Import Project="..\Common\Simulators.Dev.props" />

src/Simulation/QSharpCore/Microsoft.Quantum.QSharp.Core.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.Quantum.Sdk">
1+
<Project Sdk="Microsoft.Quantum.Sdk">
22
<Import Project="..\TargetDefinitions\TargetPackages\QSharpCore.Package.props" />
33

44
<PropertyGroup>

src/Simulation/QSharpFoundation/Microsoft.Quantum.QSharp.Foundation.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.Quantum.Sdk">
1+
<Project Sdk="Microsoft.Quantum.Sdk">
22

33
<Import Project="..\Common\AssemblyCommon.props" />
44
<Import Project="..\Common\DebugSymbols.props" />
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
namespace Microsoft.Quantum.Simulation.Simulators.Tests.Circuits {
5+
open Microsoft.Quantum.Diagnostics;
6+
open Microsoft.Quantum.Intrinsic;
7+
8+
operation MapF<'T, 'U>(mapper : ('T -> 'U), source : 'T[]) : 'U[] {
9+
mutable result = new 'U[Length(source)];
10+
for (i in 0 .. Length(source) - 1) {
11+
let m = mapper(source[i]);
12+
set result = result w/ i <- m;
13+
}
14+
15+
return result;
16+
}
17+
18+
operation LengthTest() : Unit {
19+
let a1 = [One, Zero];
20+
let a2 = [Zero, Zero, Zero];
21+
22+
AssertEqual(2, Length(a1));
23+
AssertEqual(3, Length(a2));
24+
25+
let values = MapF(Length<Result>, [a1, a2]);
26+
AssertEqual(2, values[0]);
27+
AssertEqual(3, values[1]);
28+
}
29+
30+
@Test("QuantumSimulator")
31+
function CreateArrayWithPositiveSize() : Unit {
32+
let xs = [true, size = 3];
33+
AssertEqual([true, true, true], xs);
34+
}
35+
36+
@Test("QuantumSimulator")
37+
function CreateArrayWithZeroSize() : Unit {
38+
let xs = [true, size = 0];
39+
AssertEqual(0, Length(xs));
40+
}
41+
42+
function CreateArrayWithNegativeSize() : Bool[] {
43+
return [true, size = -1];
44+
}
45+
46+
@Test("QuantumSimulator")
47+
function CreateArrayWithSizeExpression() : Unit {
48+
let n = 2;
49+
let xs = [7, size = n + 1];
50+
AssertEqual([7, 7, 7], xs);
51+
}
52+
53+
@Test("QuantumSimulator")
54+
function CreateArrayWithValueExpression() : Unit {
55+
let x = "foo";
56+
let xs = [x + "bar", size = 3];
57+
AssertEqual(["foobar", "foobar", "foobar"], xs);
58+
}
59+
60+
@Test("QuantumSimulator")
61+
function SizedArrayShouldIncrementArrayItemRefCount() : Unit {
62+
mutable item = [1];
63+
let items = [item, size = 2];
64+
set item w/= 0 <- 2;
65+
66+
AssertEqual([2], item);
67+
AssertEqual([[1], [1]], items);
68+
}
69+
70+
@Test("QuantumSimulator")
71+
function ArrayOfArraysShouldCopyOnUpdate() : Unit {
72+
mutable items = [[1], size = 2];
73+
set items w/= 0 <- items[0] w/ 0 <- 2;
74+
75+
AssertEqual([[2], [1]], items);
76+
}
77+
}

src/Simulation/Simulators.Tests/Circuits/Length.qs

Lines changed: 0 additions & 33 deletions
This file was deleted.

0 commit comments

Comments
 (0)