Repository: microsoft/qsharp
Pull request #1701 (2024-07-08 18:21:23)

Update to v0.7.4 of sparse simulator
This includes the latest bug fixes and perf improvements.

github-actions[bot]: ## Benchmark for 13f18d0
  <details>
    <summary>Click to view benchmark</summary>

| Test | Base         | PR               | % |
|------|--------------|------------------|---|
| Array append evaluation | 332.6±8.69µs | 334.4±4.80µs | +0.54% |
| Array literal evaluation | **186.6±2.54µs** | 194.8±4.25µs | **+4.39%** |
| Array update evaluation | 410.7±6.11µs | 414.6±5.01µs | +0.95% |
| Core + Standard library compilation | 21.3±0.77ms | 21.0±0.60ms | -1.41% |
| Deutsch-Jozsa evaluation | 5.1±0.04ms | **4.8±0.10ms** | **-5.88%** |
| Large file parity evaluation | **34.1±0.09ms** | 34.5±0.53ms | **+1.17%** |
| Large input file compilation | 12.2±0.20ms | 12.2±0.25ms | 0.00% |
| Large input file compilation (interpreter) | 48.6±1.66ms | 48.2±1.25ms | -0.82% |
| Large nested iteration | 32.2±0.22ms | 32.2±0.20ms | 0.00% |
| Perform Runtime Capabilities Analysis (RCA) on Deutsch-Jozsa sample | 1557.0±29.02µs | 1562.8±40.74µs | +0.37% |
| Perform Runtime Capabilities Analysis (RCA) on large file sample | **7.7±0.08ms** | 7.8±0.08ms | **+1.30%** |
| Perform Runtime Capabilities Analysis (RCA) on teleport sample | 1418.7±31.54µs | 1428.0±43.52µs | +0.66% |
| Perform Runtime Capabilities Analysis (RCA) on the core and std libraries | 28.0±0.21ms | 28.1±0.45ms | +0.36% |
| Teleport evaluation | 89.2±3.38µs | 89.1±6.67µs | -0.11% |

  </details>
  

Patch:
diff --git a/Cargo.lock b/Cargo.lock
index d3f651ba..f9b36c96 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1297,8 +1297,8 @@ dependencies = [
 
 [[package]]
 name = "quantum-sparse-sim"
-version = "0.7.1"
-source = "git+https://github.com/qir-alliance/qir-runner?rev=2fac7354f4e98c3efc05f8fd4180a02d0b712907#2fac7354f4e98c3efc05f8fd4180a02d0b712907"
+version = "0.7.4"
+source = "git+https://github.com/qir-alliance/qir-runner?tag=v0.7.4#7b41f9313609f8309317ce91afccf0a2c7fe5a6f"
 dependencies = [
  "ndarray",
  "num-bigint",
diff --git a/Cargo.toml b/Cargo.toml
index 53930e9b..bb7a17c0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -70,7 +70,7 @@ wasm-bindgen-futures = "0.4"
 rand = "0.8"
 serde_json = "1.0"
 pyo3 = "0.20"
-quantum-sparse-sim = { git = "https://github.com/qir-alliance/qir-runner", rev = "2fac7354f4e98c3efc05f8fd4180a02d0b712907" }
+quantum-sparse-sim = { git = "https://github.com/qir-alliance/qir-runner", tag = "v0.7.4" }
 async-trait = "0.1"
 tokio = { version = "1.35", features = ["macros", "rt"] }
 
diff --git a/compiler/qsc_project/src/lib.rs b/compiler/qsc_project/src/lib.rs
index 5fe2d9ba..af299b63 100644
--- a/compiler/qsc_project/src/lib.rs
+++ b/compiler/qsc_project/src/lib.rs
@@ -19,7 +19,7 @@ pub use error::StdFsError;
 #[cfg(feature = "fs")]
 pub use fs::StdFs;
 pub use js::{JSFileEntry, JSProjectHost};
-pub use manifest::{Manifest, ManifestDescriptor, PackageRef, MANIFEST_FILE_NAME};
+pub use manifest::{Manifest, ManifestDescriptor, PackageRef, PackageType, MANIFEST_FILE_NAME};
 pub use project::FileSystemAsync;
 pub use project::{
     key_for_package_ref, package_ref_from_key, DirEntry, EntryType, Error, FileSystem,
diff --git a/compiler/qsc_project/src/manifest.rs b/compiler/qsc_project/src/manifest.rs
index ba3b1cae..8f3a20cf 100644
--- a/compiler/qsc_project/src/manifest.rs
+++ b/compiler/qsc_project/src/manifest.rs
@@ -30,6 +30,16 @@ pub struct Manifest {
     pub dependencies: FxHashMap<String, PackageRef>,
     #[serde(default)]
     pub files: Vec<String>,
+    #[serde(default)]
+    pub package_type: Option<PackageType>,
+}
+
+#[derive(Deserialize, Serialize, Debug, Clone, Copy)]
+pub enum PackageType {
+    #[serde(rename = "exe")]
+    Exe,
+    #[serde(rename = "lib")]
+    Lib,
 }
 
 #[derive(Deserialize, Serialize, Debug, Clone)]
diff --git a/compiler/qsc_project/src/project.rs b/compiler/qsc_project/src/project.rs
index 04b18dd7..e4b4064b 100644
--- a/compiler/qsc_project/src/project.rs
+++ b/compiler/qsc_project/src/project.rs
@@ -1,7 +1,10 @@
 // Copyright (c) Microsoft Corporation.
 // Licensed under the MIT License.
 
-use crate::{manifest::GitHubRef, Manifest, ManifestDescriptor, PackageRef};
+use crate::{
+    manifest::{GitHubRef, PackageType},
+    Manifest, ManifestDescriptor, PackageRef,
+};
 use async_trait::async_trait;
 use futures::FutureExt;
 use miette::Diagnostic;
@@ -48,6 +51,7 @@ impl Project {
                     sources: vec![(name.clone(), contents)],
                     language_features: LanguageFeatures::default(),
                     dependencies: FxHashMap::default(),
+                    package_type: None,
                 },
                 packages: FxHashMap::default(),
             },
@@ -380,6 +384,7 @@ pub trait FileSystemAsync {
             sources,
             language_features: LanguageFeatures::from_iter(&manifest.manifest.language_features),
             dependencies,
+            package_type: manifest.manifest.package_type,
         })
     }
 
@@ -448,6 +453,7 @@ pub trait FileSystemAsync {
                 .into_iter()
                 .map(|(k, v)| (k.into(), key_for_package_ref(&v)))
                 .collect(),
+            package_type: manifest.package_type,
         })
     }
 
@@ -585,6 +591,7 @@ pub struct PackageInfo {
     pub sources: Sources,
     pub language_features: LanguageFeatures,
     pub dependencies: FxHashMap<PackageAlias, PackageKey>,
+    pub package_type: Option<PackageType>,
 }
 
 #[derive(Clone, Debug)]
@@ -655,12 +662,14 @@ impl PackageGraphSources {
     pub fn with_no_dependencies(
         sources: Vec<(Arc<str>, Arc<str>)>,
         language_features: LanguageFeatures,
+        package_type: Option<PackageType>,
     ) -> Self {
         Self {
             root: PackageInfo {
                 sources,
                 language_features,
                 dependencies: FxHashMap::default(),
+                package_type,
             },
             packages: FxHashMap::default(),
         }
diff --git a/jupyterlab/src/index.ts b/jupyterlab/src/index.ts
index de2de4b0..3db6c167 100644
--- a/jupyterlab/src/index.ts
+++ b/jupyterlab/src/index.ts
@@ -46,7 +46,7 @@ function registerQSharpLanguage(
     },
     {
       token: "keyword",
-      regex: String.raw`(namespace|open|as|operation|function|body|adjoint|newtype|controlled|internal)\b`,
+      regex: String.raw`(namespace|open|import|export|as|operation|function|body|adjoint|newtype|struct|new|controlled|internal)\b`,
       beginWord: true,
     },
     {
diff --git a/language_service/src/state.rs b/language_service/src/state.rs
index 9f1e46d3..bc838210 100644
--- a/language_service/src/state.rs
+++ b/language_service/src/state.rs
@@ -228,6 +228,12 @@ impl<'a> CompilationStateUpdater<'a> {
                     loaded_project.package_graph_sources.root.language_features,
                 ),
                 lints_config: loaded_project.lints,
+                package_type: loaded_project.package_graph_sources.root.package_type.map(
+                    |x| match x {
+                        qsc_project::PackageType::Exe => qsc::PackageType::Exe,
+                        qsc_project::PackageType::Lib => qsc::PackageType::Lib,
+                    },
+                ),
                 ..PartialConfiguration::default()
             };
 
diff --git a/pip/src/interpreter.rs b/pip/src/interpreter.rs
index 26c3f3bf..cb84288f 100644
--- a/pip/src/interpreter.rs
+++ b/pip/src/interpreter.rs
@@ -125,6 +125,7 @@ impl Interpreter {
             let graph = PackageGraphSources::with_no_dependencies(
                 Vec::default(),
                 LanguageFeatures::from_iter(language_features),
+                None,
             );
             BuildableProgram::new(target.into(), graph)
         };
diff --git a/playground/src/main.tsx b/playground/src/main.tsx
index 267f9bb1..0d6066e7 100644
--- a/playground/src/main.tsx
+++ b/playground/src/main.tsx
@@ -251,7 +251,7 @@ function registerMonacoLanguageServiceProviders(
   monaco.languages.setLanguageConfiguration("qsharp", {
     // This pattern is duplicated in /vscode/language-configuration.json . Please keep them in sync.
     wordPattern: new RegExp(
-      "(-?\\d*\\.\\d\\w*)|(@\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\<\\>\\/\\?\\s]+)",
+      "(-?\\d*\\.\\d\\w*)|(@\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\.\\'\\\"\\,\\<\\>\\/\\?\\s]+)",
     ),
   });
   monaco.languages.registerCompletionItemProvider("qsharp", {
diff --git a/vscode/language-configuration.json b/vscode/language-configuration.json
index 173bcaf6..1f3ef07c 100644
--- a/vscode/language-configuration.json
+++ b/vscode/language-configuration.json
@@ -36,5 +36,5 @@
   // for attributes and namespaces, by explicitly invoking completions after typing '@', '@Entr', 'Microsoft.Q', etc.
   //
   // This setting is duplicated for the Monaco setting for the playground: playground/src/main.tsx
-  "wordPattern": "(-?\\d*\\.\\d\\w*)|(@\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\'\\\"\\,\\<\\>\\/\\?\\s]+)"
+  "wordPattern": "(-?\\d*\\.\\d\\w*)|(@\\w*)|([^\\`\\~\\!\\@\\#\\%\\^\\&\\*\\(\\)\\-\\=\\+\\[\\{\\]\\}\\\\\\|\\;\\:\\.\\'\\\"\\,\\<\\>\\/\\?\\s]+)"
 }
diff --git a/vscode/syntaxes/qsharp.tmLanguage.json b/vscode/syntaxes/qsharp.tmLanguage.json
index b10301d5..051efa23 100644
--- a/vscode/syntaxes/qsharp.tmLanguage.json
+++ b/vscode/syntaxes/qsharp.tmLanguage.json
@@ -43,7 +43,7 @@
         },
         {
           "name": "keyword.other.qsharp",
-          "match": "\\b(namespace|open|as|internal|newtype|operation|function|body|(a|A)djoint|(c|C)ontrolled|self|auto|distribute|invert|intrinsic)\\b"
+          "match": "\\b(namespace|open|import|export|as|internal|newtype|struct|operation|function|new|body|(a|A)djoint|(c|C)ontrolled|self|auto|distribute|invert|intrinsic)\\b"
         }
       ]
     },
diff --git a/wasm/src/project_system.rs b/wasm/src/project_system.rs
index 429a30b8..f1b7b626 100644
--- a/wasm/src/project_system.rs
+++ b/wasm/src/project_system.rs
@@ -227,6 +227,13 @@ impl From<qsc_project::PackageInfo> for PackageInfo {
                 .into_iter()
                 .map(|(k, v)| (k.to_string(), v.to_string()))
                 .collect(),
+            package_type: value.package_type.map(|x| {
+                match x {
+                    qsc_project::PackageType::Exe => "exe",
+                    qsc_project::PackageType::Lib => "lib",
+                }
+                .into()
+            }),
         }
     }
 }
@@ -266,11 +273,15 @@ serializable_type! {
         pub sources: Vec<(String, String)>,
         pub language_features: Vec<String>,
         pub dependencies: FxHashMap<PackageAlias,PackageKey>,
+        pub package_type: Option<String>,
     },
-    r#"export interface IPackageInfo {
+    r#"
+    
+    export interface IPackageInfo {
         sources: [string, string][];
         languageFeatures: string[];
         dependencies: Record<string,string>;
+        packageType?: "exe" | "lib";
     }"#
 }
 
@@ -351,6 +362,13 @@ impl From<PackageInfo> for qsc_project::PackageInfo {
                 .into_iter()
                 .map(|(k, v)| (Arc::from(k), Arc::from(v)))
                 .collect(),
+            package_type: value.package_type.map(|x| match x.as_str() {
+                "exe" => qsc_project::PackageType::Exe,
+                "lib" => qsc_project::PackageType::Lib,
+                _ => unreachable!(
+                    "expected one of 'exe' or 'lib' -- should be guaranteed by TS types"
+                ),
+            }),
         }
     }
 }


Test patch:
diff --git a/compiler/qsc/src/packages/tests.rs b/compiler/qsc/src/packages/tests.rs
index d935a8bf..b34206e8 100644
--- a/compiler/qsc/src/packages/tests.rs
+++ b/compiler/qsc/src/packages/tests.rs
@@ -22,6 +22,7 @@ fn mock_program() -> Project {
                     Arc::from("SomeLibraryAlias"),
                     Arc::from("SomeLibraryKey"),
                 )]),
+                package_type: Some(qsc_project::PackageType::Exe),
             },
             packages: FxHashMap::from_iter(vec![(
                 Arc::from("SomeLibraryKey"),
@@ -32,6 +33,7 @@ fn mock_program() -> Project {
                     )],
                     language_features: LanguageFeatures::default(),
                     dependencies: FxHashMap::default(),
+                    package_type: Some(qsc_project::PackageType::Lib),
                 },
             )]),
         },
diff --git a/compiler/qsc_project/src/tests.rs b/compiler/qsc_project/src/tests.rs
index d9c41d58..a1af126f 100644
--- a/compiler/qsc_project/src/tests.rs
+++ b/compiler/qsc_project/src/tests.rs
@@ -38,6 +38,7 @@ fn basic_manifest() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -75,6 +76,7 @@ fn circular_imports() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -112,6 +114,7 @@ fn different_files_same_manifest() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -141,6 +144,7 @@ fn empty_manifest() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -182,6 +186,7 @@ fn folder_structure() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -218,6 +223,7 @@ fn hidden_files() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -258,6 +264,7 @@ fn peer_file() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -287,6 +294,7 @@ fn language_feature() {
                             1,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -318,6 +326,7 @@ fn with_local_dep() {
                         dependencies: {
                             "MyDep": "{\"path\":\"local_dep\"}",
                         },
+                        package_type: None,
                     },
                     packages: {
                         "{\"path\":\"local_dep\"}": PackageInfo {
@@ -331,6 +340,7 @@ fn with_local_dep() {
                                 0,
                             ),
                             dependencies: {},
+                            package_type: None,
                         },
                     },
                 },
@@ -362,6 +372,7 @@ fn transitive_dep() {
                         dependencies: {
                             "MyDep": "{\"path\":\"with_local_dep\"}",
                         },
+                        package_type: None,
                     },
                     packages: {
                         "{\"path\":\"local_dep\"}": PackageInfo {
@@ -375,6 +386,7 @@ fn transitive_dep() {
                                 0,
                             ),
                             dependencies: {},
+                            package_type: None,
                         },
                         "{\"path\":\"with_local_dep\"}": PackageInfo {
                             sources: [
@@ -389,6 +401,7 @@ fn transitive_dep() {
                             dependencies: {
                                 "MyDep": "{\"path\":\"local_dep\"}",
                             },
+                            package_type: None,
                         },
                     },
                 },
@@ -418,6 +431,7 @@ fn explicit_files_list() {
                             0,
                         ),
                         dependencies: {},
+                        package_type: None,
                     },
                     packages: {},
                 },
@@ -449,6 +463,7 @@ fn circular_dep() {
                         dependencies: {
                             "MyCircularDep": "{\"path\":\"circular_dep\"}",
                         },
+                        package_type: None,
                     },
                     packages: {},
                 },
diff --git a/language_service/src/test_utils.rs b/language_service/src/test_utils.rs
index 8622731f..4f1a9e18 100644
--- a/language_service/src/test_utils.rs
+++ b/language_service/src/test_utils.rs
@@ -92,6 +92,7 @@ fn compile_project_with_fake_stdlib_and_markers_cursor_optional(
                         sources,
                         language_features: LanguageFeatures::default(),
                         dependencies: FxHashMap::default(),
+                        package_type: None,
                     },
                     packages: FxHashMap::default(),
                 },