Skip to content

Commit

Permalink
Merge branch 'main' into gpuGuide
Browse files Browse the repository at this point in the history
  • Loading branch information
alonkukl authored Oct 8, 2024
2 parents c551604 + 5fadf75 commit af24992
Show file tree
Hide file tree
Showing 86 changed files with 4,860 additions and 833 deletions.
16 changes: 8 additions & 8 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ ci:
skip: [mypy]
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.6.0
hooks:
- id: trailing-whitespace
- id: end-of-file-fixer
Expand Down Expand Up @@ -30,7 +30,7 @@ repos:
- --wrap-summaries=80
- --wrap-descriptions=80
- repo: https://github.com/pre-commit/mirrors-autopep8
rev: v2.0.2
rev: v2.0.4
hooks:
- id: autopep8
args:
Expand All @@ -39,13 +39,13 @@ repos:
- --ignore=E731
exclude: 'tests/ext.*'
- repo: https://github.com/asottile/pyupgrade
rev: v3.10.1
rev: v3.17.0
hooks:
- id: pyupgrade
args:
- --py38-plus
- repo: https://github.com/asottile/reorder_python_imports
rev: v3.10.0
rev: v3.13.0
hooks:
- id: reorder-python-imports
args:
Expand All @@ -54,25 +54,25 @@ repos:
- --py37-plus
exclude: 'tests/ext.*'
- repo: https://github.com/asottile/add-trailing-comma
rev: v3.0.1
rev: v3.1.0
hooks:
- id: add-trailing-comma
args:
- --py36-plus
- repo: https://github.com/PyCQA/autoflake
rev: v2.2.0
rev: v2.3.1
hooks:
- id: autoflake
args:
- --in-place
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.5.0
rev: v1.11.1
hooks:
- id: mypy
exclude: tests/qis/test_pauli.py
additional_dependencies: ["numpy>=1.21"]
- repo: https://github.com/PyCQA/flake8
rev: 6.1.0
rev: 7.1.1
hooks:
- id: flake8
args:
Expand Down
99 changes: 17 additions & 82 deletions bqskit/__init__.py
Original file line number Diff line number Diff line change
@@ -1,91 +1,29 @@
"""The Berkeley Quantum Synthesis Toolkit Python Package."""
from __future__ import annotations

import logging
from sys import stdout as _stdout
from typing import Any

from .version import __version__ # noqa: F401
from .version import __version_info__ # noqa: F401
from bqskit.compiler.compile import compile
from bqskit.compiler.machine import MachineModel
from bqskit.ir.circuit import Circuit
from bqskit.ir.lang import register_language as _register_language
from bqskit.ir.lang.qasm2 import OPENQASM2Language as _qasm
from bqskit._logging import disable_logging
from bqskit._logging import enable_logging
from bqskit._version import __version__ # noqa: F401
from bqskit._version import __version_info__ # noqa: F401

# Initialize Logging
_logging_initialized = False

def __getattr__(name: str) -> Any:
# Lazy imports
if name == 'compile':
from bqskit.compiler.compile import compile
return compile

def enable_logging(verbose: bool = False) -> None:
"""
Enable logging for BQSKit.
if name == 'Circuit':
from bqskit.ir.circuit import Circuit
return Circuit

Args:
verbose (bool): If set to True, will print more verbose messages.
Defaults to False.
"""
global _logging_initialized
if not _logging_initialized:
_logger = logging.getLogger('bqskit')
_handler = logging.StreamHandler(_stdout)
_handler.setLevel(0)
_fmt_header = '%(asctime)s.%(msecs)03d - %(levelname)-8s |'
_fmt_message = ' %(name)s: %(message)s'
_fmt = _fmt_header + _fmt_message
_formatter = logging.Formatter(_fmt, '%H:%M:%S')
_handler.setFormatter(_formatter)
_logger.addHandler(_handler)
_logging_initialized = True
if name == 'MachineModel':
from bqskit.compiler.machine import MachineModel
return MachineModel

level = logging.DEBUG if verbose else logging.INFO
logging.getLogger('bqskit').setLevel(level)


def disable_logging() -> None:
"""Disable logging for BQSKit."""
logging.getLogger('bqskit').setLevel(logging.CRITICAL)


def enable_dashboard() -> None:
import warnings
warnings.warn(
'Dask has been removed from BQSKit. As a result, the'
' enable_dashboard method has been removed.'
'This warning will turn into an error in a future update.',
DeprecationWarning,
)


def disable_dashboard() -> None:
import warnings
warnings.warn(
'Dask has been removed from BQSKit. As a result, the'
' disable_dashboard method has been removed.'
'This warning will turn into an error in a future update.',
DeprecationWarning,
)


def disable_parallelism() -> None:
import warnings
warnings.warn(
'The disable_parallelism method has been removed.'
' Instead, set the "num_workers" parameter to 1 during '
'Compiler construction. This warning will turn into'
'an error in a future update.',
DeprecationWarning,
)


def enable_parallelism() -> None:
import warnings
warnings.warn(
'The enable_parallelism method has been removed.'
' Instead, set the "num_workers" parameter to 1 during '
'Compiler construction. This warning will turn into'
'an error in a future update.',
DeprecationWarning,
)
raise AttributeError(f'module {__name__} has no attribute {name}')


__all__ = [
Expand All @@ -95,6 +33,3 @@ def enable_parallelism() -> None:
'enable_logging',
'disable_logging',
]

# Register supported languages
_register_language('qasm', _qasm())
38 changes: 38 additions & 0 deletions bqskit/_logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
"""This module contains the logging configuration and methods for BQSKit."""
from __future__ import annotations

import logging
from sys import stdout as _stdout


_logging_initialized = False


def enable_logging(verbose: bool = False) -> None:
"""
Enable logging for BQSKit.
Args:
verbose (bool): If set to True, will print more verbose messages.
Defaults to False.
"""
global _logging_initialized
if not _logging_initialized:
_logger = logging.getLogger('bqskit')
_handler = logging.StreamHandler(_stdout)
_handler.setLevel(0)
_fmt_header = '%(asctime)s.%(msecs)03d - %(levelname)-8s |'
_fmt_message = ' %(name)s: %(message)s'
_fmt = _fmt_header + _fmt_message
_formatter = logging.Formatter(_fmt, '%H:%M:%S')
_handler.setFormatter(_formatter)
_logger.addHandler(_handler)
_logging_initialized = True

level = logging.DEBUG if verbose else logging.INFO
logging.getLogger('bqskit').setLevel(level)


def disable_logging() -> None:
"""Disable logging for BQSKit."""
logging.getLogger('bqskit').setLevel(logging.CRITICAL)
2 changes: 1 addition & 1 deletion bqskit/version.py → bqskit/_version.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""This module contains the version information for BQSKit."""
from __future__ import annotations
__version_info__ = ('1', '1', '2')
__version_info__ = ('1', '2', '0')
__version__ = '.'.join(__version_info__[:3]) + ''.join(__version_info__[3:])
16 changes: 15 additions & 1 deletion bqskit/compiler/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@
"""
from __future__ import annotations

from typing import Any

from bqskit.compiler.basepass import BasePass
from bqskit.compiler.compile import compile
from bqskit.compiler.compiler import Compiler
from bqskit.compiler.gateset import GateSet
from bqskit.compiler.gateset import GateSetLike
Expand All @@ -49,6 +50,19 @@
from bqskit.compiler.workflow import Workflow
from bqskit.compiler.workflow import WorkflowLike


def __getattr__(name: str) -> Any:
# Lazy imports
if name == 'compile':
# TODO: fix this (high-priority), overlap between module and function
from bqskit.compiler.compile import compile
return compile

# TODO: Move compile to a different subpackage and deprecate import

raise AttributeError(f'module {__name__} has no attribute {name}')


__all__ = [
'BasePass',
'compile',
Expand Down
59 changes: 54 additions & 5 deletions bqskit/compiler/compile.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from __future__ import annotations

import logging
import math
import warnings
from typing import Any
from typing import Literal
Expand All @@ -10,11 +11,14 @@
from typing import TYPE_CHECKING
from typing import Union

import numpy as np

from bqskit.compiler.compiler import Compiler
from bqskit.compiler.machine import MachineModel
from bqskit.compiler.passdata import PassData
from bqskit.compiler.registry import _compile_circuit_registry
from bqskit.compiler.registry import _compile_statemap_registry
from bqskit.compiler.registry import _compile_stateprep_registry
from bqskit.compiler.registry import _compile_unitary_registry
from bqskit.compiler.registry import model_registered_target_types
from bqskit.compiler.workflow import Workflow
from bqskit.compiler.workflow import WorkflowLike
from bqskit.ir.circuit import Circuit
Expand Down Expand Up @@ -582,7 +586,7 @@ def type_and_check_input(input: CompilationInputLike) -> CompilationInput:
if error_threshold is not None:
for i, data in enumerate(datas):
error = data.error
nonsq_error = 1 - np.sqrt(max(1 - (error * error), 0))
nonsq_error = 1 - math.sqrt(max(1 - (error * error), 0))
if nonsq_error > error_threshold:
warnings.warn(
'Upper bound on error is greater than set threshold:'
Expand Down Expand Up @@ -622,16 +626,19 @@ def type_and_check_input(input: CompilationInputLike) -> CompilationInput:
if isinstance(typed_input, Circuit):
in_circuit = typed_input

elif isinstance(typed_input, UnitaryMatrix):
in_circuit = Circuit.from_unitary(typed_input)

else:
in_circuit = Circuit(1)
in_circuit = Circuit(typed_input.num_qudits, typed_input.radixes)

# Perform the compilation
out, data = compiler.compile(in_circuit, workflow, True)

# Log error if necessary
if error_threshold is not None:
error = data.error
nonsq_error = 1 - np.sqrt(max(1 - (error * error), 0))
nonsq_error = 1 - math.sqrt(max(1 - (error * error), 0))
if nonsq_error > error_threshold:
warnings.warn(
'Upper bound on error is greater than set threshold:'
Expand Down Expand Up @@ -669,6 +676,8 @@ def build_workflow(
if model is None:
model = MachineModel(input.num_qudits, radixes=input.radixes)

model_registered_types = model_registered_target_types(model)

if isinstance(input, Circuit):
if input.num_qudits > max_synthesis_size:
if any(
Expand All @@ -685,6 +694,16 @@ def build_workflow(
'Unable to compile circuit with gate larger than'
' max_synthesis_size.\nConsider adjusting it.',
)
# Use a registered workflow if model is found in the circuit registry
# for a given optimization_level
if model in _compile_circuit_registry:
if optimization_level in _compile_circuit_registry[model]:
return _compile_circuit_registry[model][optimization_level]
elif len(model_registered_types) > 0:
m = f'MachineModel {model} is registered for inputs of type in '
m += f'{model_registered_types}, but input is {type(input)}. '
m += f'You may need to register a Workflow for type {type(input)}.'
warnings.warn(m)

return _circuit_workflow(
model,
Expand All @@ -702,6 +721,16 @@ def build_workflow(
'Unable to compile unitary with size larger than'
' max_synthesis_size.\nConsider adjusting it.',
)
# Use a registered workflow if model is found in the unitary registry
# for a given optimization_level
if model in _compile_unitary_registry:
if optimization_level in _compile_unitary_registry[model]:
return _compile_unitary_registry[model][optimization_level]
elif len(model_registered_types) > 0:
m = f'MachineModel {model} is registered for inputs of type in '
m += f'{model_registered_types}, but input is {type(input)}. '
m += f'You may need to register a Workflow for type {type(input)}.'
warnings.warn(m)

return _synthesis_workflow(
input,
Expand All @@ -720,6 +749,16 @@ def build_workflow(
'Unable to compile states with size larger than'
' max_synthesis_size.\nConsider adjusting it.',
)
# Use a registered workflow if model is found in the stateprep registry
# for a given optimization_level
if model in _compile_stateprep_registry:
if optimization_level in _compile_stateprep_registry[model]:
return _compile_stateprep_registry[model][optimization_level]
elif len(model_registered_types) > 0:
m = f'MachineModel {model} is registered for inputs of type in '
m += f'{model_registered_types}, but input is {type(input)}. '
m += f'You may need to register a Workflow for type {type(input)}.'
warnings.warn(m)

return _stateprep_workflow(
input,
Expand All @@ -738,6 +777,16 @@ def build_workflow(
'Unable to compile state systems with size larger than'
' max_synthesis_size.\nConsider adjusting it.',
)
# Use a registered workflow if model is found in the statemap registry
# for a given optimization_level
if model in _compile_statemap_registry:
if optimization_level in _compile_statemap_registry[model]:
return _compile_statemap_registry[model][optimization_level]
elif len(model_registered_types) > 0:
m = f'MachineModel {model} is registered for inputs of type in '
m += f'{model_registered_types}, but input is {type(input)}. '
m += f'You may need to register a Workflow for type {type(input)}.'
warnings.warn(m)

return _statemap_workflow(
input,
Expand Down
Loading

0 comments on commit af24992

Please sign in to comment.