Git Product home page Git Product logo

microsoft / qsharp Goto Github PK

View Code? Open in Web Editor NEW
341.0 19.0 61.0 7.48 MB

Azure Quantum Development Kit, including the Q# programming language, resource estimator, and Quantum Katas

Home Page: https://microsoft.github.io/qsharp/

License: MIT License

Rust 73.67% Q# 10.73% Python 3.11% TypeScript 10.25% JavaScript 1.70% HTML 0.05% CSS 0.30% Jupyter Notebook 0.06% LLVM 0.04% Dockerfile 0.01% Shell 0.06%
qsharp quantum quantum-computing quantum-programming quantum-programming-language tutorials quantum-resource-estimation

qsharp's Introduction

Azure Quantum Development Kit

Welcome to the Azure Quantum Development Kit!

This repository contains tooling for the Q# language, specifically:

  • compiler: core compiler logic and command-line tooling
  • fuzz: fuzz testing infrastructure
  • jupyterlab: JupyterLab extension
  • language_service: Q# language service and editor features
  • library: Q# standard library
  • npm: Q# npm package
  • pip: Q# Python pip package
  • playground: simple website for interacting with Q#
  • resource_estimator: Implementation for the Azure Quantum Resource Estimator
  • vscode: Visual Studio Code extension
  • wasm: The bindings and logic for the WebAssembly module
  • widgets: The Q# Jupyter widgets Python package

There are also the tutorials and samples in the ./katas and ./samples directories, respectively.

Code from this repository powers the Q# development experience on https://quantum.microsoft.com.

Building

To build this repository there are 4 dependencies that need to be installed. These are:

The build script will check these dependencies and their versions and fail if not met. (Or run python ./prereqs.py directly to check if the minimum required versions are installed).

To build, in the root directory run python ./build.py. By default this will run a release build of each project, including running tests and checks such as linting. Run with the --help option for detailed usage.

Playground

To run the "playground" locally, build the repository, then cd into the playground directory, and run npm start. This will launch a local web server and output the URL to the console; copy that URL and open it in a browser to use the playground. If you only want to build the functionality necessary to run the playground, you can use python .\build.py --wasm --npm --play.

Python

When building the Python packages (pip and jupyterlab), if the build script does not detect a current Python virtual environment, it will automatically create one under pip/.venv or jupyterlab/.venv. When developing locally, you can use these virtual environments to run the tests by running source .venv/bin/activate (Linux/MacOS) or .venv/Scripts/activate.bat (Windows).

Code editing

The easiest way to develop in this repo is to use VS Code. When you open the project root, by default VS Code will recommend you install the extensions listed in .vscode/extensions.json. These extensions provide language services for editing, as well as linters and formatters to ensure the code meets the requirements (which are checked by the build.py script and CI).

Some settings are recommended (but not enforced) to make development easier. These are in the .vscode/*.shared.json files. If the Workspace Config+ extension is installed, this will automatically apply these settings, as well as overrides from your own corresponding .vscode/*.local.json settings. If you don't install this extension, you can use these as a reference for editing your own .vscode/*.json settings files. (See the extension home page for more details).

Debugging

Besides the usual debugging tools for Rust code and web sites, there is some logging in the code that may be enabled to help troubleshoot. The qsc command-line compiler makes use of the Rust crate env_logger, which enables logging via environment variables, for example RUST_LOG=debug ./target/release/qsc ./samples/Grover.qs.

Citation

If you use Q#, Azure Quantum Development Kit, or Azure Quantum Resource Estimator, please cite as follows:

  • Azure Quantum Development Kit:
@software{Microsoft_Azure_Quantum_Development,
   author = {{Microsoft}},
   license = {MIT},
   title = {{Azure Quantum Development Kit}},
   url = {https://github.com/microsoft/qsharp} }
  • Q# programming language:
@inproceedings{Svore_2018, series={RWDSL2018},
   title={{Q\#: Enabling Scalable Quantum Computing and Development with a High-level DSL}},
   url={http://dx.doi.org/10.1145/3183895.3183901},
   DOI={10.1145/3183895.3183901},
   booktitle={Proceedings of the Real World Domain Specific Languages Workshop 2018},
   publisher={ACM},
   author={Svore, Krysta and Geller, Alan and Troyer, Matthias and Azariah, John and Granade, Christopher and Heim, Bettina and Kliuchnikov, Vadym and Mykhailova, Mariia and Paz, Andres and Roetteler, Martin},
   year={2018},
   month=feb, collection={RWDSL2018} }
  • Azure Quantum Resource Estimator:
@inproceedings{Azure_Quantum_Resource_Estimator,
   author = {van Dam, Wim and Mykhailova, Mariia and Soeken, Mathias},
   title = {{Using Azure Quantum Resource Estimator for Assessing Performance of Fault Tolerant Quantum Computation}},
   year = {2023},
   isbn = {9798400707858},
   publisher = {Association for Computing Machinery},
   address = {New York, NY, USA},
   url = {https://doi.org/10.1145/3624062.3624211},
   doi = {10.1145/3624062.3624211},
   booktitle = {Proceedings of the SC '23 Workshops of The International Conference on High Performance Computing, Network, Storage, and Analysis},
   pages = {1414–1419},
   numpages = {6},
   series = {SC-W '23} }

Feedback

If you have feedback about the content in this repository, please let us know by filing a new issue!

Reporting Security Issues

Security issues and bugs should be reported privately following our security issue documentation.

Contributing

This project welcomes contributions and suggestions. Most contributions require you to agree to a Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.

When you submit a pull request, a CLA bot will automatically determine whether you need to provide a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions provided by the bot. You will only need to do this once across all repos using our CLA.

This project has adopted the Microsoft Open Source Code of Conduct. For more information see the Code of Conduct FAQ or contact [email protected] with any additional questions or comments.

For more details, please see CONTRIBUTING.md.

Legal and Licensing

Trademarks

This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft trademarks or logos is subject to and must follow Microsoft's Trademark & Brand Guidelines. Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship. Any use of third-party trademarks or logos are subject to those third-party's policies.

qsharp's People

Contributors

aarthims avatar benburrill avatar billti avatar cesarzc avatar colommar avatar deepbrain avatar dependabot[bot] avatar dmitryvasilevsky avatar eureka-cpu avatar filipw avatar idavis avatar ivanbasov avatar kuzminrobin avatar microsoftopensource avatar minestarks avatar msoeken avatar orpuente-ms avatar quackduck avatar samarsha avatar scottcarda-ms avatar sezna avatar swernli avatar tcnickolas avatar v-philkane avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qsharp's Issues

Type checking should verify functor support on callable arguments

The current type checking implementation does not protect against supplying callable arguments without the proper functor support. For example, an operation like:

operation Foo(q : Qubit) : Unit {}

can be passed as an argument to something expecting an adjointable operation, like:

operation Bar(op : Qubit => Unit is Adj) : Unit is Adj {}

At the same time, something that supports more than the required functors should be allowed, like:

operation Baz(q : Qubit) : Unit is Adj + Ctl {}

So the following combinations should be appropriate allowed or denied:

Bar(Foo); // Should be type error, because Foo is not adjointable
Bar(Baz); // Should be allowed, because Baz is adjointable

To detect this type error properly, we need to determine which design we want to implement:

  • Subtyping: matches the design of the legacy compiler, but comes with headaches
  • Automatic Coercions: operation types with more functors can be coerced to types with fewer functors at certain locations in a Q# program
  • User-facing type classes?
  • Some other design?

Worth considering is that the solution affects potential designs for arguments being generic over functors which has previously been called out as a pain point in the libraries (legacy compiler design required patterns like Op, OpA, OpC, and OpCA in defined callables to handle this).

NPM package

Tasks

  1. 2 of 2
    billti cesarzc

Loop type unification

We need a pass to convert the different types of loops in Q# into one consolidated type of loop or loop-representation in the HIR.

Fuzz: Panic: 'float token should be parsable: ParseFloatError { kind: Invalid }'

(Fuzzer found)
The input file with contents namespace Test {function Answer() : Int {0e causes the compiler to panic.
Another input to test: namespace Test {function Answer() : Int {1e&
Repro:

echo namespace Test {function Answer() : Int {0e > crash.qs
qsc.exe - < crash.qs

Message:
thread 'main' panicked at 'float token should be parsable: ParseFloatError { kind: Invalid }', compiler\qsc_frontend\src\parse\expr.rs:296:40

Stack:

Stack trace in fuzzer run (click the triangle on the left):
   0: rust_begin_unwind
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/panicking.rs:67:14
   2: core::result::unwrap_failed
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/result.rs:1687:5
   3: core::result::Result<T,E>::expect
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/result.rs:1046:23
   4: qsc_frontend::parse::expr::lit_token
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/expr.rs:296:25
   5: qsc_frontend::parse::expr::lit
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/expr.rs:270:24
   6: core::ops::function::FnMut::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:166:5
   7: qsc_frontend::parse::prim::opt
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:141:11
   8: qsc_frontend::parse::expr::expr_base
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/expr.rs:152:29
   9: qsc_frontend::parse::expr::expr_op
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/expr.rs:73:9
  10: qsc_frontend::parse::expr::expr
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/expr.rs:59:5
  11: qsc_frontend::parse::stmt::stmt
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/stmt.rs:46:17
  12: core::ops::function::FnMut::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:166:5
  13: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:298:13
  14: qsc_frontend::parse::prim::opt
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:141:11
  15: qsc_frontend::parse::prim::many
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:150:25
  16: qsc_frontend::parse::top::callable_body
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/top.rs:200:21
  17: qsc_frontend::parse::top::callable_decl
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/top.rs:180:16
  18: core::ops::function::FnMut::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:166:5
  19: qsc_frontend::parse::prim::opt
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:141:11
  20: qsc_frontend::parse::top::item
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/top.rs:51:36
  21: core::ops::function::FnMut::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:166:5
  22: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:298:13
  23: qsc_frontend::parse::prim::opt
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:141:11
  24: qsc_frontend::parse::prim::many
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:150:25
  25: qsc_frontend::parse::top::namespace
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/top.rs:34:17
  26: core::ops::function::FnMut::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:166:5
  27: core::ops::function::impls::<impl core::ops::function::FnMut<A> for &mut F>::call_mut
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/ops/function.rs:298:13
  28: qsc_frontend::parse::prim::opt
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:141:11
  29: qsc_frontend::parse::prim::many
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/prim.rs:150:25
  30: qsc_frontend::parse::top::namespaces
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse/top.rs:24:22
  31: qsc_frontend::parse::namespaces
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/parse.rs:52:11
  32: qsc_frontend::compile::parse_all
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/compile.rs:244:50
  33: qsc_frontend::compile::compile
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/compile.rs:170:48
  34: qsc_eval::stateless::create_execution_context
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_eval/src/stateless.rs:172:16
  35: qsc_eval::stateless::compile_execution_context
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_eval/src/stateless.rs:109:5
  36: qsc_wasm::run_internal
             at ./src/lib.rs:306:19
  37: run_internal::_::__libfuzzer_sys_run
             at ./fuzz/fuzz_targets/run_internal.rs:14:17
  38: rust_fuzzer_test_input
             at /home/rokuzmin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libfuzzer-sys-0.4.6/src/lib.rs:224:17
  (Further frames are fuzzer's. Available if needed)

System information

  • Commit:
commit d6de27819fe20989abfce6a2bad74d9e6b366caf (HEAD -> kuzminrobin/fuzz, origin/main, origin/HEAD, main)
Author: Sarah Marshall <[email protected]>
Date:   Wed Apr 12 12:45:51 2023 -0700
    Parse empty statements (#147)
  • OS: Fuzzer found in WSL. The repro steps confirm in Win.

App building and ecosystem

How does this fit into broader application development? Are there bindings to other languages and environments? For example, can I build a GUI app and link in the qsharp generated code and a simulator?

With the existing QDK there were samples that took advantage of the .NET ecosystem and bindings to pull in packages and build GUI apps etc. that leveraged the QDK. We should have a plan for what our story is in this regard.

Q# standard library MVP

Tasks

LLVM dependency management

The biggest and most challenging dependency we have in the codebase will be LLVM (hopefully). We should capture discussions here and be explicit about managing that dependency (e.g. how to consume it in the build - be that CI/CD, dev machines, etc., when/how to move forward on versions, etc.)

Telemetry

We need to land a telemetry story (i.e. if/what to measure, how to opt in/out, how users can view what is being sent, how to configure different telemetry endpoints for different environments, the technology used to implement telemetry and how to wire it throughout the codebase, etc.)

Support closures (for lambdas and partial application)

As of now, closures are not supported, which means neither lambdas nor partial application are supported. What's missing:

  • Type checking support for either inferring or explicitly specifying functors for lambdas/partial application
    #341
  • Evaluator support for creating captured local state inside of a Value::Closure type
    #317
  • Closure conversion to callable declarations for code generation
    #317
  • Converting partial applications into lambdas to unify support
    #349

Commit to design for User Defined Types

The Q# language spec describes specific syntax and patterns for user defined types:

// Declaration
newtype Complex = (Real: Double, Imaginary: Double);

// Creation
let compl = Complex(1.0, 0.0);

// Named field access
let real = compl::Real;

// Unwrap to decompose the underlying type
let (real, imag) = compl!;

This feature is used in some places in the existing libraries, but the syntax and Q# developer ergonomics are not very good. While there are TODO comments (and todo!() panics) in the code related to UDT handling for type inference and evaluation, we should not jump to building support for the existing syntax if we have the chance to support updated/improved syntax from the beginning.

We need to decide if we will A) implement the existing language feature/syntax design, or B) define new syntax and patterns and implement those.

Evaluator can incorrectly release qubits that are let bound in a lower scope.

Right now, when a qubit leaves a scope it will be released unless the leave_scope is passed false. However, this can still result in qubits that get let-bound in lower scopes to incorrectly call release. Instead, the evluator should track qubits separately in the scopes that they were allocated to correctly release them. This will remove the need for leave_scope to take a bool and the Value::release function can also be removed.

Decide on support for string interpolation

We need a concrete decision on whether the old string interpolation syntax (ie: $"Value: {val}") is going to be supported or not. It turns out to be difficult to efficiently and cleanly parse. For now, the supported approach is to use a standard library generic intrinsic, AsString, and string concatenation. There are other alternative syntax/patterns that we can explore as well.

Open-ended ranges in for-loops are not handled gracefully

When running this code:

namespace input { operation Foo(): Unit { for i in 0... {} } }

I get an error:
× iterable ranges cannot be open-ended
thread 'main' panicked at 'failed printing to stderr: formatter error', library\std\src\io\stdio.rs:1009:9

I would expect the error to surface more gracefully, as other errors do.

I can see that this error is only checked during the eval, and not during compilation, which may be relevant. This could be an issue with how runtime-only issues are surfaced.

Support 'targeting' in the compiler

Design how the compiler will allow target capabilities to be specified at build time, and how errors and warning will be detected and reported if the code cannot be compiled for the target specified (e.g. different hardware capabilities). Should the compiler support "broad" targets (e.g. the name of a piece of hardware or set of capabilities), or "fine grained" targets (e.g. list explicitly supported operations, types, etc.). Should there be a config file where you specify both? (e.g. define "profiles" that map names to sets of capabilities).

This ties in closely with #10.

Comment affects the compilation result

(Spawned from #174)
The Q# code comment changes the behavior between the commands qsc.exe t3.qs and qsc.exe - < t3.qs.

Commands log (click)
@rem Add an empty comment in front of a code fragment:
echo //>t3.qs
echo namespace N{operation P(a:i):D{}}>> t3.qs

qsc.exe t3.qs

  × `i` not found in this scope
   ╭─[t3.qs:1:1]
 1 │ //
 2 │ namespace N{operation P(a:i):D{}}
   ·                           ┬
   ·                           ╰── not found
   ╰────


  × `D` not found in this scope
   ╭─[t3.qs:1:1]
 1 │ //
 2 │ namespace N{operation P(a:i):D{}}
   ·                              ┬
   ·                              ╰── not found
   ╰────


  × mismatched types
   ╭─[t3.qs:1:1]
 1 │ //
 2 │ namespace N{operation P(a:i):D{}}
   ·                               ─┬
   ·                                ╰── expected ?, found ()
   ╰────

qsc.exe - < t3.qs

  × entry point not found
  help: a single callable with the `@EntryPoint()` attribute must be present if no entry expression is provided

The identical compilation result was expected.

System information

  • Found in a branch based on commit in main:
commit e51a8b6f145be23fc2358b2cf0bab6707a7a46a0
Author: Bill Ticehurst <[email protected]>
Date:   Wed Apr 19 10:42:03 2023 -0700

    Fix mapping of spans for non-ASCII code (#182)
    
    This builds on the branch for the PR at
    https://github.com/microsoft/qsharp/pull/180 (which fixes the code
    sharing issue with non-ASCII chars), not not strictly dependent.
    
    The excessive comments on the `mapUtf8UnitsToUtf16Units` function should
    outline why this is needed and what it fixes.

Automatically evaluate `main` with no args if no entry expression provided

This is based on feedback we've received from users and some design brainstorming around how to handle some of our scenarios. The idea is to still respect the entry expression, but when none is provided there should be an option to invoke the evaluator with logic to look for main instead. The name main can be treated like a callable declared as body intrinsic where it must be unique across all namespaces, and specifically uses the lowercase "m" in its name to differentiate it (Q# style guide says callables should start with capital letters) and make it more like a keyword. It should support no arguments, but can have any return type.

qsci fails to execute expressions from source file provided with `--use`

If I have a file like this:

namespace Test {
    function Hello() : String {
        "hello there..."
    }

    operation Main() : Unit {
        Hello()
    }
}

then I try to run cargo run --bin qsci -- --use .\test.qs --exec --entry "Test.Main()" it will fail with a panic saying "binding is not resolved." However, using the expression Test.Hello() does work. It seems there is something wrong with how symbol resolutions are being carried out by the incremental compiler when paired with compilation of the input file, such that calls inside that file are not fully resolved.

Build and release process

This issue is to discuss how we build & release the bits this repo contains. Topics include release pipelines, security requirements (e.g. code scanning, signing, etc.), if/when we branch for release, release schedule, if/how we will support multiple release "channels" (e.g. official, beta, nightly, etc.), the distribution mechanisms (e.g., npm, pip, VS Code marketplace, GitHub releases, etc.), and so forth.

I expect this to be a long running issue as we iterate and adapt over time.

Proposals and discussion to follow...

Improve WASM layer error handling

The qsc_wasm layer does not fully handle the errors reported by check_internal, as some information gets lost in translation (secondary labels, help text, etc). In addition, run_internal API currently only supports returning a single error rather than a list, which might not work for errors from passes like extracting entry point. We need to update the error handling to support multiple, detailed errors, and work on the compilation/execution context caching semantics to better provide actionable errors to the user via WASM.

Tasks

Repo management

This is an issue to discuss the broad topic of 'repo management'. Here we should discuss (and hopefully agree on) topics such as managing issues (labels, milestones, triage, closing, etc), planning and tracking work, the process for design discussions and documentation, accepting PRs, etc.

Note: Development guidelines and building/branching/releasing process will be tracked in separate issues.

I expect this to be a long-running issue as we iterate. Proposals and discussions to follow...

Tasks

Add Fuzzing (+Code Coverage)

Is your feature request related to a problem? Please describe.
We need to be sure that whatever Q# input is provided to the Q# compiler, the compiler does not panic and does not hang.
The Q# input may contain arbitrary edits or copy-paste/cut-paste (pasting can be from unrelated sources, i.e. can contain non-printable characters).
The Q# compiler can be invoked at any moment of editing, at least from the WebAssembly layer.

Describe the solution you'd like
The compilation must either succeed or complain, but must not hang or panic.

Describe alternatives you've considered
Testing multiple inputs is not expected to be more efficient than the fuzzing against multiple input seeds (multiple entries as corpus).


Limitations Found.

  • Fuzzing conflicts with wasm_bindgen functions. Build error.
  • Fuzzed functions need to be public (invokable from the fuzzing tool).

Functions to be fuzzed:

Validation Pass

As temporary protection before type inference and broader feature support exists, we need some validation passes that check for specific disallowed patterns in Q# that warns users early and protects later transformation passes from needing to handle invalid patterns.

Tasks

Fuzz: Panic: 'path should be resolved'.

(Fuzzer found)
The input file with contents namespace N{operation P(a:i):D{}} causes a panic
thread 'main' panicked at 'path should be resolved', compiler\qsc_frontend\src\typeck\rules.rs:126:22

Looks like the reason is the parameter type. If the type is anything other than Int or Double or Qubit (or array of them) then there is a panic.

Repro:

echo namespace N{operation P(a:i):D{}}> t.qs

@rem Both
qsc.exe t.qs
@rem and
qsc.exe - < t.qs
@rem Result in panic.

However! Related or not, the comment affects the panic:

@rem Add an empty comment in front of the fragment that causes panic:
echo //>t3.qs
echo namespace N{operation P(a:i):D{}}>> t3.qs

@rem See the file content:
type t3.qs 

//
namespace N{operation P(a:i):D{}}

qsc.exe t3.qs
@rem Panic

qsc.exe - < t3.qs
@rem No panic. Compilation error instead:
  × entry point not found
  help: a single callable with the `@EntryPoint()` attribute must be present if no entry expression is provided

Stack:

Stack trace for "t.qs" in fuzzer run (click the triangle on the left):
   0: rust_begin_unwind
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/panicking.rs:67:14
   2: core::panicking::panic_display
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/panicking.rs:150:5
   3: core::panicking::panic_str
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/panicking.rs:134:5
   4: core::option::expect_failed
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/option.rs:2025:5
   5: core::option::Option<T>::expect
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/option.rs:913:21
   6: qsc_frontend::typeck::rules::Context::infer_ty
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:126:22
   7: qsc_frontend::typeck::rules::Context::infer_pat
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:524:26
   8: qsc_frontend::typeck::rules::Context::infer_pat
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:530:38
   9: qsc_frontend::typeck::rules::Context::infer_spec
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:87:30
  10: qsc_frontend::typeck::rules::spec
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:603:5
  11: qsc_frontend::typeck::check::Checker::check_spec
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/check.rs:93:22
  12: <qsc_frontend::typeck::check::Checker as qsc_ast::visit::Visitor>::visit_callable_decl
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/check.rs:120:43
  13: qsc_ast::visit::walk_item
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:91:37
  14: qsc_ast::visit::Visitor::visit_item
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:20:9
  15: qsc_ast::visit::walk_namespace::{{closure}}
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:84:41
  16: <core::slice::iter::Iter<T> as core::iter::traits::iterator::Iterator>::for_each
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/slice/iter/macros.rs:201:21
  17: qsc_ast::visit::walk_namespace
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:84:5
  18: qsc_ast::visit::Visitor::visit_namespace
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:16:9
  19: <qsc_frontend::typeck::check::Checker as qsc_ast::visit::Visitor>::visit_package
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/check.rs:106:13
  20: qsc_frontend::compile::typeck_all
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/compile.rs:305:5
  21: qsc_frontend::compile::compile
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/compile.rs:176:28
  22: qsc_eval::stateless::create_execution_context
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_eval/src/stateless.rs:172:16
  23: qsc_eval::stateless::compile_execution_context
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_eval/src/stateless.rs:109:5
  24: qsc_wasm::run_internal
             at ./src/lib.rs:307:19
  25: run_internal::_::__libfuzzer_sys_run
             at ./fuzz/fuzz_targets/run_internal.rs:10:17
  26: rust_fuzzer_test_input
             at /home/rokuzmin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libfuzzer-sys-0.4.6/src/lib.rs:224:17
  27: libfuzzer_sys::test_input_wrap::{{closure}}
             at /home/rokuzmin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libfuzzer-sys-0.4.6/src/lib.rs:61:9
  28: std::panicking::try::do_call
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/std/src/panicking.rs:485:40
  29: __rust_try
  (Further frames are fuzzer's. Available if needed)

System information

  • OS: Fuzzer found in WSL. The repro steps are run in Win.
  • Commit (in branch "kuzminrobin/fuzz"):
commit 5092ecf88e609120761f1aa1c488a33fefbbd0f7 (HEAD -> kuzminrobin/fuzz)
Author: Robin Kuzmin <[email protected]>
Date:   Mon Apr 17 16:26:03 2023 -0700
    Renamed some corpus files.
  • Based on commit in main:
commit d6de27819fe20989abfce6a2bad74d9e6b366caf (origin/main, origin/HEAD, main)
Author: Sarah Marshall <[email protected]>
Date:   Wed Apr 12 12:45:51 2023 -0700
    Parse empty statements (#147)

Introduce High-level Intermediate Representation (HIR)

We need an HIR in order to embed additional information in the data structure (such as type information and resolved symbols), as well as to allow the HIR to deviate from the Syntax Tree (which should stay 1:1 with actual Q# syntax).

Tasks

Type inference should have appropriate errors for ambiguous types

In circumstances where generics don't have enough information to resolve to a concrete type, type inference should have an error about ambiguous types. For example:

let x = Length([]);

The type of the array is not known, so the generic on Length cannot be made concrete. This does not interfere with the evaluator, which does not care about generics, but could become a problem for code generation.

Detailed Error Reporting (Syntax & Symbols)

Expand the error reporting to include actionable details to help educate users on Q# syntax.

Tasks

Design and implement logging

To aid in troubleshooting and debugging (especially when running WebAssembly where its not practical to "step through the code" currently), we should have a robust and consistent logging story that can be enabled at runtime. This should include categories and levels (e.g. turn on 'verbose' logs for the 'type-checker'). Ideally this will also include the ability to track performance (e.g. start/end events).

VS Code has a concept of channels and levels we could leverage (or at least try to align closely with), as that environment will be a common runtime environment and it will then integrate more easily (see https://code.visualstudio.com/api/references/vscode-api#LogOutputChannel).

The browser has performance events https://developer.mozilla.org/en-US/docs/Web/API/Performance we could shim to and leverage when running the browser (or electron/VS Code) environments https://developer.mozilla.org/en-US/docs/Web/API/Performance.

Support Verbose State Dump

We need to support a mechanism for communicating verbose state dumps in a format that is easy to consume from the WASM bindings. For better interop and debugging of Q# code, we should also tie this to how output from Message shows up, though that is not yet supported by the library at time of writing. The implementation of qir_backend's __quantum__qis__dumpmachine__body just prints to stdout in a human readable format but does not have any mechanism for changing the output location or format, so we'll need to coordinate an update there to provide a Rust API for capturing relevant state info and making it available from within the evaluator.

Tasks

Fuzz: Panic: 'local variable should have inferred type'.

Input Q# file:

namespace N {
    newtype S = (
         VerboseMessage: String -> Unit
    );
    function DefaultS() : S {
        return Default<S>()
            w/ VerboseMessage <- Message;
    }
}

Panic:
thread '<unnamed>' panicked at 'local variable should have inferred type', compiler/qsc_frontend/src/typeck/rules.rs:326:30

Stack:
   0: rust_begin_unwind
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/std/src/panicking.rs:577:5
   1: core::panicking::panic_fmt
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/panicking.rs:67:14
   2: core::panicking::panic_display
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/panicking.rs:150:5
   3: core::panicking::panic_str
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/panicking.rs:134:5
   4: core::option::expect_failed
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/option.rs:2025:5
   5: core::option::Option<T>::expect
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/option.rs:913:21
   6: qsc_frontend::typeck::rules::Context::infer_expr
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:323:47
   7: qsc_frontend::typeck::rules::Context::infer_binop
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:445:32
   8: qsc_frontend::typeck::rules::Context::infer_expr
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:217:56
   9: qsc_frontend::typeck::rules::Context::infer_binop
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:444:32
  10: qsc_frontend::typeck::rules::Context::infer_expr
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:217:56
  11: qsc_frontend::typeck::rules::Context::infer_update
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:509:38
  12: qsc_frontend::typeck::rules::Context::infer_expr
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:368:27
  13: qsc_frontend::typeck::rules::Context::infer_expr
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:351:26
  14: qsc_frontend::typeck::rules::Context::infer_stmt
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:172:27
  15: qsc_frontend::typeck::rules::Context::infer_block
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:143:35
  16: qsc_frontend::typeck::rules::Context::infer_spec
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:106:21
  17: qsc_frontend::typeck::rules::spec
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/rules.rs:610:5
  18: qsc_frontend::typeck::check::Checker::check_spec
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/check.rs:105:22
  19: <qsc_frontend::typeck::check::Checker as qsc_ast::visit::Visitor>::visit_callable_decl
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/check.rs:131:48
  20: qsc_ast::visit::walk_item
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:94:37
  21: qsc_ast::visit::Visitor::visit_item
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:20:9
  22: qsc_ast::visit::walk_namespace::{{closure}}
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:86:41
  23: <core::slice::iter::Iter<T> as core::iter::traits::iterator::Iterator>::for_each
             at /rustc/88fb1b922b047981fc0cfc62aa1418b4361ae72e/library/core/src/slice/iter/macros.rs:201:21
  24: qsc_ast::visit::walk_namespace
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:86:5
  25: qsc_ast::visit::Visitor::visit_namespace
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_ast/src/visit.rs:16:9
  26: <qsc_frontend::typeck::check::Checker as qsc_ast::visit::Visitor>::visit_package
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/typeck/check.rs:118:13
  27: qsc_frontend::compile::typeck_all
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/compile.rs:318:5
  28: qsc_frontend::compile::compile
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_frontend/src/compile.rs:175:28
  29: qsc_eval::stateless::create_execution_context
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_eval/src/stateless.rs:175:20
  30: qsc_eval::stateless::compile_execution_context
             at /mnt/c/ed/dev/QSharpCompiler/qsharp-runtime/qsharp/compiler/qsc_eval/src/stateless.rs:110:5
  31: qsc_wasm::run_internal
             at ./src/lib.rs:316:19
  32: run_internal::_::__libfuzzer_sys_run
             at ./fuzz/fuzz_targets/run_internal.rs:10:17

System information

  • Found in a branch based on commit in main:
commit e51a8b6f145be23fc2358b2cf0bab6707a7a46a0 (origin/main, origin/HEAD, main)
Author: Bill Ticehurst <[email protected]>
Date:   Wed Apr 19 10:42:03 2023 -0700
    Fix mapping of spans for non-ASCII code (#182)
    This builds on the branch for the PR at
    https://github.com/microsoft/qsharp/pull/180 (which fixes the code
    sharing issue with non-ASCII chars), not not strictly dependent.
    The excessive comments on the `mapUtf8UnitsToUtf16Units` function should
    outline why this is needed and what it fixes.

Development guidelines

This issue is to track our development guidelines, such as supported development languages (e.g. Rust, Python, etc.), dependencies for working in the code (e.g. Python 3.11, Node.js 16.x etc.), the platforms we support (e.g. Windows >= 10, x64 & ARM64, etc.), coding & style guidelines, PR requirements, branching strategy, etc.

I expect this to be a long running issue as we iterate over time.

Proposals and discussion to follow...

Block followed by tuple is parsed as call expression

{
    let x = 1;
    x
}
(x, 2)

This is parsed as the block being called with the argument (x, 2), but this is confusing, so it should probably be parsed as two separate statements. Calling a block should require parentheses around the block.

Design the libraries approach for the new compiler

What encompasses the "standard library" and how it is consumed by the compiler. How are other libraries consumed? Does the compiler support different 'capabilities' that a library can target (e.g. does or doesn't support hybrid code, function calls, mid-circuit measurement, etc), and how do you signify that in the library (if at all), etc.

Tasks

  1. 3 of 3
    TrackFeatureCandidate
    swernli

Pretty Printing AST

To assist with testing broadly, but more specifically on transformation passes that go from AST to AST, we want to have Display trait implemented for the AST. That will allow more human readable tests without losing information that isn't present in original Q# syntax, such as the spans and node ids.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.