Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial Python telemetry #1972

Merged
merged 19 commits into from
Oct 30, 2024
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
7 changes: 7 additions & 0 deletions pip/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ operation BellState() : Unit {
BellState()
```

## Telemetry

This library sends telemetry. Minimal anonymous data is collected to help measure feature usage and performance.
All telemetry events can be seen in the source file [telemetry_events.py](https://github.com/microsoft/qsharp/tree/main/pip/qsharp/telemetry_events.py).

To disable sending telemetry from this package, set the environment variable `QSHARP_PYTHON_TELEMETRY=none`

## Support

For more information about the Azure Quantum Development Kit, visit [https://aka.ms/AQ/Documentation](https://aka.ms/AQ/Documentation).
Expand Down
3 changes: 3 additions & 0 deletions pip/qsharp/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

from . import telemetry_events
from ._qsharp import (
init,
eval,
Expand All @@ -20,6 +21,8 @@
PhaseFlipNoise,
)

telemetry_events.on_import()

from ._native import Result, Pauli, QSharpError, TargetProfile

# IPython notebook specific features
Expand Down
35 changes: 30 additions & 5 deletions pip/qsharp/_qsharp.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

from . import telemetry_events
from ._native import (
Interpreter,
TargetProfile,
Expand All @@ -23,8 +24,10 @@
from .estimator._estimator import EstimatorResult, EstimatorParams
import json
import os
from time import monotonic

_interpreter = None
_config = None

# Check if we are running in a Jupyter notebook to use the IPython display function
_in_jupyter = False
Expand Down Expand Up @@ -161,6 +164,7 @@ def init(
from ._http import fetch_github

global _interpreter
global _config

if isinstance(target_name, str):
target = target_name.split(".")[0].lower()
Expand Down Expand Up @@ -198,9 +202,10 @@ def init(
fetch_github,
)

_config = Config(target_profile, language_features, manifest_contents, project_root)
# Return the configuration information to provide a hint to the
# language service through the cell output.
return Config(target_profile, language_features, manifest_contents, project_root)
return _config


def get_interpreter() -> Interpreter:
Expand Down Expand Up @@ -286,6 +291,9 @@ def run(
if shots < 1:
raise QSharpError("The number of shots must be greater than 0.")

telemetry_events.on_run(shots)
start_time = monotonic()

results: List[ShotResult] = []

def print_output(output: Output) -> None:
Expand Down Expand Up @@ -317,6 +325,9 @@ def on_save_events(output: Output) -> None:
# compilation.
entry_expr = None

durationMs = (monotonic() - start_time) * 1000
billti marked this conversation as resolved.
Show resolved Hide resolved
telemetry_events.on_run_end(durationMs, shots)

if save_events:
return results
else:
Expand Down Expand Up @@ -366,10 +377,15 @@ def compile(entry_expr: str) -> QirInputData:
file.write(str(program))
"""
ipython_helper()

start = monotonic()
global _config
target_profile = _config._config.get("targetProfile", "unspecified")
telemetry_events.on_compile(target_profile)
ll_str = get_interpreter().qir(entry_expr)
return QirInputData("main", ll_str)

res = QirInputData("main", ll_str)
durationMs = (monotonic() - start) * 1000
telemetry_events.on_compile_end(durationMs, target_profile)
return res

def circuit(
entry_expr: Optional[str] = None, *, operation: Optional[str] = None
Expand Down Expand Up @@ -421,9 +437,18 @@ def _coerce_estimator_params(

params = _coerce_estimator_params(params)
param_str = json.dumps(params)

telemetry_events.on_estimate()
start = monotonic()
res_str = get_interpreter().estimate(entry_expr, param_str)
res = json.loads(res_str)

try:
qubits = res[0]["logicalCounts"]["numQubits"]
except (KeyError, IndexError):
qubits = "unknown"

durationMs = (monotonic() - start) * 1000
telemetry_events.on_estimate_end(durationMs, qubits)
return EstimatorResult(res)


Expand Down
Loading
Loading