mirror of https://github.com/Qiskit/qiskit-aer.git
* Added support for using the QV Simulator as Qiskit Addon
This commit is contained in:
parent
3499a9c1c5
commit
e9476602fa
|
@ -10,7 +10,7 @@
|
||||||
# Additionaly, OpenMP support is only available in clang from
|
# Additionaly, OpenMP support is only available in clang from
|
||||||
|
|
||||||
cmake_minimum_required(VERSION 3.6)
|
cmake_minimum_required(VERSION 3.6)
|
||||||
project(aer_simulator_cpp LANGUAGES CXX)
|
project(aer_simulator_cpp LANGUAGES CXX C)
|
||||||
|
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||||
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
list(APPEND CMAKE_PREFIX_PATH ${CMAKE_SOURCE_DIR}/cmake)
|
||||||
|
@ -163,4 +163,4 @@ if(BUILD_TESTS)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Cyhton build
|
# Cyhton build
|
||||||
add_subdirectory(src/bindings/python)
|
add_subdirectory(aer/qv_addon/qiskit_addon_qv)
|
|
@ -1,104 +0,0 @@
|
||||||
"""
|
|
||||||
Cython quantum circuit simulator.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import warnings
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
# Import QISKit classes
|
|
||||||
from qiskit._result import Result
|
|
||||||
from qiskit.backends import BaseBackend
|
|
||||||
from qiskit.backends.local.localjob import LocalJob
|
|
||||||
|
|
||||||
# Import Simulator tools
|
|
||||||
from helpers import SimulatorJSONEncoder, qobj2schema
|
|
||||||
from aer_qv_wrapper import AerSimulatorWrapper
|
|
||||||
|
|
||||||
# Logger
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class AerSimulator(BaseBackend):
|
|
||||||
"""Cython quantum circuit simulator"""
|
|
||||||
|
|
||||||
DEFAULT_CONFIGURATION = {
|
|
||||||
'name': 'local_aer_simulator',
|
|
||||||
'url': 'NA',
|
|
||||||
'simulator': True,
|
|
||||||
'local': True,
|
|
||||||
'description': 'A C++ statevector simulator for qobj files',
|
|
||||||
'coupling_map': 'all-to-all',
|
|
||||||
"basis_gates": 'u0,u1,u2,u3,cx,cz,id,x,y,z,h,s,sdg,t,tdg,rzz'
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, configuration=None):
|
|
||||||
super().__init__(configuration or self.DEFAULT_CONFIGURATION.copy())
|
|
||||||
self.simulator = AerSimulatorWrapper()
|
|
||||||
|
|
||||||
def run(self, qobj):
|
|
||||||
"""Run a QOBJ on the the backend."""
|
|
||||||
return LocalJob(self._run_job, qobj)
|
|
||||||
|
|
||||||
def _run_job(self, qobj):
|
|
||||||
self._validate(qobj)
|
|
||||||
qobj_str = json.dumps(qobj2schema(qobj), cls=SimulatorJSONEncoder)
|
|
||||||
result = json.loads(self.simulator.execute(qobj_str))
|
|
||||||
# TODO: get schema in line with result object
|
|
||||||
return result # Result(result)
|
|
||||||
|
|
||||||
def load_noise_model(self, noise_model):
|
|
||||||
self.simulator.load_noise_model(json.dumps(noise_model, cls=SimulatorJSONEncoder))
|
|
||||||
|
|
||||||
def clear_noise_model(self):
|
|
||||||
self.simulator.clear_noise_model()
|
|
||||||
|
|
||||||
def load_config(self, engine=None, state=None):
|
|
||||||
if engine is not None:
|
|
||||||
self.simulator.load_engine_config(json.dumps(engine, cls=SimulatorJSONEncoder))
|
|
||||||
if state is not None:
|
|
||||||
self.simulator.load_state_config(json.dumps(state, cls=SimulatorJSONEncoder))
|
|
||||||
|
|
||||||
def set_max_threads_shot(self, threads):
|
|
||||||
"""
|
|
||||||
Set the maximum threads used for parallel shot execution.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
threads (int): the thread limit, set to -1 to use maximum available
|
|
||||||
|
|
||||||
Note that using parallel shot evaluation disables parallel circuit
|
|
||||||
evaluation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.simulator.set_max_threads_shot(int(threads))
|
|
||||||
|
|
||||||
def set_max_threads_circuit(self, threads):
|
|
||||||
"""
|
|
||||||
Set the maximum threads used for parallel circuit execution.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
threads (int): the thread limit, set to -1 to use maximum available
|
|
||||||
|
|
||||||
Note that using parallel circuit evaluation disables parallel shot
|
|
||||||
evaluation.
|
|
||||||
"""
|
|
||||||
self.simulator.set_max_threads_circuit(int(threads))
|
|
||||||
|
|
||||||
def set_max_threads_state(self, threads):
|
|
||||||
"""
|
|
||||||
Set the maximum threads used for state update parallel routines.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
threads (int): the thread limit, set to -1 to use maximum available.
|
|
||||||
|
|
||||||
Note that using parallel circuit or shot execution takes precidence over
|
|
||||||
parallel state evaluation.
|
|
||||||
"""
|
|
||||||
self.simulator.set_max_threads_state(int(threads))
|
|
||||||
|
|
||||||
def _validate(self, qobj):
|
|
||||||
# TODO
|
|
||||||
return
|
|
|
@ -1,50 +0,0 @@
|
||||||
import json
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
class SimulatorJSONEncoder(json.JSONEncoder):
|
|
||||||
"""
|
|
||||||
JSON encoder for NumPy arrays and complex numbers.
|
|
||||||
|
|
||||||
This functions as the standard JSON Encoder but adds support
|
|
||||||
for encoding:
|
|
||||||
complex numbers z as lists [z.real, z.imag]
|
|
||||||
ndarrays as nested lists.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# pylint: disable=method-hidden,arguments-differ
|
|
||||||
def default(self, obj):
|
|
||||||
if isinstance(obj, np.ndarray):
|
|
||||||
return obj.tolist()
|
|
||||||
if isinstance(obj, complex):
|
|
||||||
return [obj.real, obj.imag]
|
|
||||||
return json.JSONEncoder.default(self, obj)
|
|
||||||
|
|
||||||
|
|
||||||
def qobj2schema(qobj):
|
|
||||||
"""
|
|
||||||
Convert current Qiskit qobj in line with schema spec qobj for simulator testing.
|
|
||||||
"""
|
|
||||||
shots = qobj.get("config",{}).get("shots", 1)
|
|
||||||
qobj["type"] = "QASM"
|
|
||||||
if "circuits" in qobj:
|
|
||||||
qobj["experiments"] = qobj.pop("circuits")
|
|
||||||
if "experiments" in qobj:
|
|
||||||
for i, experiment in enumerate(qobj["experiments"]):
|
|
||||||
# adjust labels
|
|
||||||
if "compiled_circuit" in experiment:
|
|
||||||
experiment["compiled_circuit"].pop("header", None)
|
|
||||||
experiment["instructions"] = experiment.pop("compiled_circuit", {}).pop("operations", [])
|
|
||||||
for k, op in enumerate(experiment["instructions"]):
|
|
||||||
if op.get("name") == "measure":
|
|
||||||
op["memory"] = op.pop("clbits")
|
|
||||||
op["register"] = op["memory"]
|
|
||||||
experiment["instructions"][k] = op
|
|
||||||
experiment["config"] = {"shots": shots}
|
|
||||||
# clear compiled qasm
|
|
||||||
experiment.pop("compiled_circuit_qasm", '')
|
|
||||||
# clear old header
|
|
||||||
if "name" in experiment:
|
|
||||||
experiment["header"] = {"name": experiment.pop("name")}
|
|
||||||
qobj["experiments"][i] = experiment
|
|
||||||
return qobj
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
find_package(PythonExtensions REQUIRED)
|
||||||
|
find_package(Cython REQUIRED)
|
||||||
|
find_package(PythonLibs REQUIRED)
|
||||||
|
|
||||||
|
add_cython_target(aer_qv_wrapper aer_qv_wrapper.pyx CXX)
|
||||||
|
add_library(aer_qv_wrapper MODULE ${aer_qv_wrapper})
|
||||||
|
set_target_properties(aer_qv_wrapper PROPERTIES
|
||||||
|
LINKER_LANGUAGE CXX
|
||||||
|
CXX_STANDARD 14)
|
||||||
|
target_include_directories(aer_qv_wrapper
|
||||||
|
PRIVATE ${AER_SIMULATOR_CPP_SRC_DIR}
|
||||||
|
PRIVATE ${AER_SIMULATOR_CPP_EXTERNAL_LIBS}
|
||||||
|
PRIVATE ${PYTHON_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(aer_qv_wrapper
|
||||||
|
${PYTHON_LIBRARIES}
|
||||||
|
${AER_LIBRARIES})
|
||||||
|
python_extension_module(aer_qv_wrapper
|
||||||
|
LINKED_MODULES_VAR linked_module_list
|
||||||
|
FORWARD_DECL_MODULES_VAR fdecl_module_list)
|
||||||
|
|
||||||
|
# application executable -- generated header file + other source files
|
||||||
|
python_modules_header(modules
|
||||||
|
FORWARD_DECL_MODULES_LIST ${fdecl_module_list})
|
||||||
|
include_directories(${modules_INCLUDE_DIRS})
|
||||||
|
|
||||||
|
set(SITE_PACKAGES "${PYTHON_RELATIVE_SITE_PACKAGES_DIR}")
|
||||||
|
install(TARGETS aer_qv_wrapper LIBRARY DESTINATION ${SITE_PACKAGES})
|
|
@ -0,0 +1,4 @@
|
||||||
|
from .aer_qv_provider import AerQvProvider
|
||||||
|
from aer_qv_wrapper import AerQvSimulatorWrapper
|
||||||
|
|
||||||
|
__version__ = '0.0.1'
|
|
@ -0,0 +1,42 @@
|
||||||
|
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
# Copyright 2018, IBM.
|
||||||
|
#
|
||||||
|
# This source code is licensed under the Apache License, Version 2.0 found in
|
||||||
|
# the LICENSE.txt file in the root directory of this source tree.
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name, bad-continuation
|
||||||
|
|
||||||
|
"""Provider for the local AER QV backend."""
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
from qiskit.backends import BaseProvider
|
||||||
|
from aer_qv_wrapper import AerQvSimulatorWrapper
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
class AerQvProvider(BaseProvider):
|
||||||
|
"""Provider for the local JKU backend."""
|
||||||
|
|
||||||
|
def __init__(self, *args, **kwargs):
|
||||||
|
super().__init__(args, kwargs)
|
||||||
|
|
||||||
|
# Populate the list of local AER QV backends.
|
||||||
|
self.backends = {'local_qv_simulator': AerQvSimulatorWrapper()}
|
||||||
|
|
||||||
|
def get_backend(self, name):
|
||||||
|
return self.backends[name]
|
||||||
|
|
||||||
|
def available_backends(self, filters=None):
|
||||||
|
# pylint: disable=arguments-differ
|
||||||
|
backends = self.backends
|
||||||
|
|
||||||
|
filters = filters or {}
|
||||||
|
for key, value in filters.items():
|
||||||
|
backends = {name: instance for name, instance in backends.items()
|
||||||
|
if instance.configuration.get(key) == value}
|
||||||
|
|
||||||
|
return list(backends.values())
|
|
@ -40,7 +40,7 @@ cdef extern from "simulators/qubitvector/qv_state.hpp" namespace "AER::QubitVect
|
||||||
State() except +
|
State() except +
|
||||||
|
|
||||||
|
|
||||||
cdef class AerSimulatorWrapper:
|
cdef class AerQvSimulatorWrapper:
|
||||||
|
|
||||||
cdef Interface *thisptr
|
cdef Interface *thisptr
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
from skbuild import setup
|
||||||
|
from setuptools import find_packages
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='qiskit_addon_qv',
|
||||||
|
packages=['qiskit_addon_qv'],
|
||||||
|
cmake_source_dir='../..',
|
||||||
|
description="AER - QV Quantum Simulator addon for Qiskit",
|
||||||
|
author="AER Development Team",
|
||||||
|
author_email="qiskit@us.ibm.com",
|
||||||
|
license="Apache 2.0",
|
||||||
|
classifiers=[
|
||||||
|
"Environment :: Console",
|
||||||
|
"License :: OSI Approved :: Apache Software License",
|
||||||
|
"Intended Audience :: Developers",
|
||||||
|
"Intended Audience :: Science/Research",
|
||||||
|
"Operating System :: Microsoft :: Windows",
|
||||||
|
"Operating System :: MacOS",
|
||||||
|
"Operating System :: POSIX :: Linux",
|
||||||
|
"Programming Language :: C++",
|
||||||
|
"Programming Language :: Python :: 3.5",
|
||||||
|
"Programming Language :: Python :: 3.6",
|
||||||
|
"Topic :: Scientific/Engineering",
|
||||||
|
],
|
||||||
|
keywords="qiskit simulator quantum addon backend"
|
||||||
|
)
|
|
@ -0,0 +1,574 @@
|
||||||
|
#.rst:
|
||||||
|
#
|
||||||
|
# This module defines CMake functions to build Python extension modules and
|
||||||
|
# stand-alone executables.
|
||||||
|
#
|
||||||
|
# The following variables are defined:
|
||||||
|
# ::
|
||||||
|
#
|
||||||
|
# PYTHON_PREFIX - absolute path to the current Python
|
||||||
|
# distribution's prefix
|
||||||
|
# PYTHON_SITE_PACKAGES_DIR - absolute path to the current Python
|
||||||
|
# distribution's site-packages directory
|
||||||
|
# PYTHON_RELATIVE_SITE_PACKAGES_DIR - path to the current Python
|
||||||
|
# distribution's site-packages directory
|
||||||
|
# relative to its prefix
|
||||||
|
# PYTHON_SEPARATOR - separator string for file path
|
||||||
|
# components. Equivalent to ``os.sep`` in
|
||||||
|
# Python.
|
||||||
|
# PYTHON_PATH_SEPARATOR - separator string for PATH-style
|
||||||
|
# environment variables. Equivalent to
|
||||||
|
# ``os.pathsep`` in Python.
|
||||||
|
# PYTHON_EXTENSION_MODULE_SUFFIX - suffix of the compiled module. For example, on
|
||||||
|
# Linux, based on environment, it could be ``.cpython-35m-x86_64-linux-gnu.so``.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# The following functions are defined:
|
||||||
|
#
|
||||||
|
# .. cmake:command:: python_extension_module
|
||||||
|
#
|
||||||
|
# For libraries meant to be used as Python extension modules, either dynamically
|
||||||
|
# loaded or directly linked. Amend the configuration of the library target
|
||||||
|
# (created using ``add_library``) with additional options needed to build and
|
||||||
|
# use the referenced library as a Python extension module.
|
||||||
|
#
|
||||||
|
# python_extension_module(<Target>
|
||||||
|
# [LINKED_MODULES_VAR <LinkedModVar>]
|
||||||
|
# [FORWARD_DECL_MODULES_VAR <ForwardDeclModVar>]
|
||||||
|
# [MODULE_SUFFIX <ModuleSuffix>])
|
||||||
|
#
|
||||||
|
# Only extension modules that are configured to be built as MODULE libraries can
|
||||||
|
# be runtime-loaded through the standard Python import mechanism. All other
|
||||||
|
# modules can only be included in standalone applications that are written to
|
||||||
|
# expect their presence. In addition to being linked against the libraries for
|
||||||
|
# these modules, such applications must forward declare their entry points and
|
||||||
|
# initialize them prior to use. To generate these forward declarations and
|
||||||
|
# initializations, see ``python_modules_header``.
|
||||||
|
#
|
||||||
|
# If ``<Target>`` does not refer to a target, then it is assumed to refer to an
|
||||||
|
# extension module that is not linked at all, but compiled along with other
|
||||||
|
# source files directly into an executable. Adding these modules does not cause
|
||||||
|
# any library configuration modifications, and they are not added to the list of
|
||||||
|
# linked modules. They still must be forward declared and initialized, however,
|
||||||
|
# and so are added to the forward declared modules list.
|
||||||
|
#
|
||||||
|
# If the associated target is of type ``MODULE_LIBRARY``, the LINK_FLAGS target
|
||||||
|
# property is used to set symbol visibility and export only the module init function.
|
||||||
|
# This applies to GNU and MSVC compilers.
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
#
|
||||||
|
# ``LINKED_MODULES_VAR <LinkedModVar>``
|
||||||
|
# Name of the variable referencing a list of extension modules whose libraries
|
||||||
|
# must be linked into the executables of any stand-alone applications that use
|
||||||
|
# them. By default, the global property ``PY_LINKED_MODULES_LIST`` is used.
|
||||||
|
#
|
||||||
|
# ``FORWARD_DECL_MODULES_VAR <ForwardDeclModVar>``
|
||||||
|
# Name of the variable referencing a list of extension modules whose entry
|
||||||
|
# points must be forward declared and called by any stand-alone applications
|
||||||
|
# that use them. By default, the global property
|
||||||
|
# ``PY_FORWARD_DECL_MODULES_LIST`` is used.
|
||||||
|
#
|
||||||
|
# ``MODULE_SUFFIX <ModuleSuffix>``
|
||||||
|
# Suffix appended to the python extension module file.
|
||||||
|
# The default suffix is retrieved using ``sysconfig.get_config_var("SO")"``,
|
||||||
|
# if not available, the default is then ``.so`` on unix and ``.pyd`` on
|
||||||
|
# windows.
|
||||||
|
# Setting the variable ``PYTHON_EXTENSION_MODULE_SUFFIX`` in the caller
|
||||||
|
# scope defines the value used for all extensions not having a suffix
|
||||||
|
# explicitly specified using ``MODULE_SUFFIX`` parameter.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# .. cmake:command:: python_standalone_executable
|
||||||
|
#
|
||||||
|
# python_standalone_executable(<Target>)
|
||||||
|
#
|
||||||
|
# For standalone executables that initialize their own Python runtime
|
||||||
|
# (such as when building source files that include one generated by Cython with
|
||||||
|
# the --embed option). Amend the configuration of the executable target
|
||||||
|
# (created using ``add_executable``) with additional options needed to properly
|
||||||
|
# build the referenced executable.
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# .. cmake:command:: python_modules_header
|
||||||
|
#
|
||||||
|
# Generate a header file that contains the forward declarations and
|
||||||
|
# initialization routines for the given list of Python extension modules.
|
||||||
|
# ``<Name>`` is the logical name for the header file (no file extensions).
|
||||||
|
# ``<HeaderFilename>`` is the actual destination filename for the header file
|
||||||
|
# (e.g.: decl_modules.h).
|
||||||
|
#
|
||||||
|
# python_modules_header(<Name> [HeaderFilename]
|
||||||
|
# [FORWARD_DECL_MODULES_LIST <ForwardDeclModList>]
|
||||||
|
# [HEADER_OUTPUT_VAR <HeaderOutputVar>]
|
||||||
|
# [INCLUDE_DIR_OUTPUT_VAR <IncludeDirOutputVar>])
|
||||||
|
#
|
||||||
|
# If only ``<Name>`` is provided, and it ends in the ".h" extension, then it
|
||||||
|
# is assumed to be the ``<HeaderFilename>``. The filename of the header file
|
||||||
|
# without the extension is used as the logical name. If only ``<Name>`` is
|
||||||
|
# provided, and it does not end in the ".h" extension, then the
|
||||||
|
# ``<HeaderFilename>`` is assumed to ``<Name>.h``.
|
||||||
|
#
|
||||||
|
# The exact contents of the generated header file depend on the logical
|
||||||
|
# ``<Name>``. It should be set to a value that corresponds to the target
|
||||||
|
# application, or for the case of multiple applications, some identifier that
|
||||||
|
# conveyes its purpose. It is featured in the generated multiple inclusion
|
||||||
|
# guard as well as the names of the generated initialization routines.
|
||||||
|
#
|
||||||
|
# The generated header file includes forward declarations for all listed
|
||||||
|
# modules, as well as implementations for the following class of routines:
|
||||||
|
#
|
||||||
|
# ``int <Name>_<Module>(void)``
|
||||||
|
# Initializes the python extension module, ``<Module>``. Returns an integer
|
||||||
|
# handle to the module.
|
||||||
|
#
|
||||||
|
# ``void <Name>_LoadAllPythonModules(void)``
|
||||||
|
# Initializes all listed python extension modules.
|
||||||
|
#
|
||||||
|
# ``void CMakeLoadAllPythonModules(void);``
|
||||||
|
# Alias for ``<Name>_LoadAllPythonModules`` whose name does not depend on
|
||||||
|
# ``<Name>``. This function is excluded during preprocessing if the
|
||||||
|
# preprocessing macro ``EXCLUDE_LOAD_ALL_FUNCTION`` is defined.
|
||||||
|
#
|
||||||
|
# ``void Py_Initialize_Wrapper();``
|
||||||
|
# Wrapper arpund ``Py_Initialize()`` that initializes all listed python
|
||||||
|
# extension modules. This function is excluded during preprocessing if the
|
||||||
|
# preprocessing macro ``EXCLUDE_PY_INIT_WRAPPER`` is defined. If this
|
||||||
|
# function is generated, then ``Py_Initialize()`` is redefined to a macro
|
||||||
|
# that calls this function.
|
||||||
|
#
|
||||||
|
# Options:
|
||||||
|
#
|
||||||
|
# ``FORWARD_DECL_MODULES_LIST <ForwardDeclModList>``
|
||||||
|
# List of extension modules for which to generate forward declarations of
|
||||||
|
# their entry points and their initializations. By default, the global
|
||||||
|
# property ``PY_FORWARD_DECL_MODULES_LIST`` is used.
|
||||||
|
#
|
||||||
|
# ``HEADER_OUTPUT_VAR <HeaderOutputVar>``
|
||||||
|
# Name of the variable to set to the path to the generated header file. By
|
||||||
|
# default, ``<Name>`` is used.
|
||||||
|
#
|
||||||
|
# ``INCLUDE_DIR_OUTPUT_VAR <IncludeDirOutputVar>``
|
||||||
|
# Name of the variable to set to the path to the directory containing the
|
||||||
|
# generated header file. By default, ``<Name>_INCLUDE_DIRS`` is used.
|
||||||
|
#
|
||||||
|
# Defined variables:
|
||||||
|
#
|
||||||
|
# ``<HeaderOutputVar>``
|
||||||
|
# The path to the generated header file
|
||||||
|
#
|
||||||
|
# ``<IncludeDirOutputVar>``
|
||||||
|
# Directory containing the generated header file
|
||||||
|
#
|
||||||
|
#
|
||||||
|
# Example usage
|
||||||
|
# ^^^^^^^^^^^^^
|
||||||
|
#
|
||||||
|
# .. code-block:: cmake
|
||||||
|
#
|
||||||
|
# find_package(PythonInterp)
|
||||||
|
# find_package(PythonLibs)
|
||||||
|
# find_package(PythonExtensions)
|
||||||
|
# find_package(Cython)
|
||||||
|
# find_package(Boost COMPONENTS python)
|
||||||
|
#
|
||||||
|
# # Simple Cython Module -- no executables
|
||||||
|
# add_cython_target(_module.pyx)
|
||||||
|
# add_library(_module MODULE ${_module})
|
||||||
|
# python_extension_module(_module)
|
||||||
|
#
|
||||||
|
# # Mix of Cython-generated code and C++ code using Boost Python
|
||||||
|
# # Stand-alone executable -- no modules
|
||||||
|
# include_directories(${Boost_INCLUDE_DIRS})
|
||||||
|
# add_cython_target(main.pyx CXX EMBED_MAIN)
|
||||||
|
# add_executable(main boost_python_module.cxx ${main})
|
||||||
|
# target_link_libraries(main ${Boost_LIBRARIES})
|
||||||
|
# python_standalone_executable(main)
|
||||||
|
#
|
||||||
|
# # stand-alone executable with three extension modules:
|
||||||
|
# # one statically linked, one dynamically linked, and one loaded at runtime
|
||||||
|
# #
|
||||||
|
# # Freely mixes Cython-generated code, code using Boost-Python, and
|
||||||
|
# # hand-written code using the CPython API.
|
||||||
|
#
|
||||||
|
# # module1 -- statically linked
|
||||||
|
# add_cython_target(module1.pyx)
|
||||||
|
# add_library(module1 STATIC ${module1})
|
||||||
|
# python_extension_module(module1
|
||||||
|
# LINKED_MODULES_VAR linked_module_list
|
||||||
|
# FORWARD_DECL_MODULES_VAR fdecl_module_list)
|
||||||
|
#
|
||||||
|
# # module2 -- dynamically linked
|
||||||
|
# include_directories({Boost_INCLUDE_DIRS})
|
||||||
|
# add_library(module2 SHARED boost_module2.cxx)
|
||||||
|
# target_link_libraries(module2 ${Boost_LIBRARIES})
|
||||||
|
# python_extension_module(module2
|
||||||
|
# LINKED_MODULES_VAR linked_module_list
|
||||||
|
# FORWARD_DECL_MODULES_VAR fdecl_module_list)
|
||||||
|
#
|
||||||
|
# # module3 -- loaded at runtime
|
||||||
|
# add_cython_target(module3a.pyx)
|
||||||
|
# add_library(module1 MODULE ${module3a} module3b.cxx)
|
||||||
|
# target_link_libraries(module3 ${Boost_LIBRARIES})
|
||||||
|
# python_extension_module(module3
|
||||||
|
# LINKED_MODULES_VAR linked_module_list
|
||||||
|
# FORWARD_DECL_MODULES_VAR fdecl_module_list)
|
||||||
|
#
|
||||||
|
# # application executable -- generated header file + other source files
|
||||||
|
# python_modules_header(modules
|
||||||
|
# FORWARD_DECL_MODULES_LIST ${fdecl_module_list})
|
||||||
|
# include_directories(${modules_INCLUDE_DIRS})
|
||||||
|
#
|
||||||
|
# add_cython_target(mainA)
|
||||||
|
# add_cython_target(mainC)
|
||||||
|
# add_executable(main ${mainA} mainB.cxx ${mainC} mainD.c)
|
||||||
|
#
|
||||||
|
# target_link_libraries(main ${linked_module_list} ${Boost_LIBRARIES})
|
||||||
|
# python_standalone_executable(main)
|
||||||
|
#
|
||||||
|
#=============================================================================
|
||||||
|
# Copyright 2011 Kitware, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
#=============================================================================
|
||||||
|
|
||||||
|
find_package(PythonInterp REQUIRED)
|
||||||
|
find_package(PythonLibs)
|
||||||
|
include(targetLinkLibrariesWithDynamicLookup)
|
||||||
|
|
||||||
|
set(_command "
|
||||||
|
import distutils.sysconfig
|
||||||
|
import itertools
|
||||||
|
import os
|
||||||
|
import os.path
|
||||||
|
import site
|
||||||
|
import sys
|
||||||
|
import sysconfig
|
||||||
|
|
||||||
|
result = None
|
||||||
|
rel_result = None
|
||||||
|
candidate_lists = []
|
||||||
|
|
||||||
|
try:
|
||||||
|
candidate_lists.append((distutils.sysconfig.get_python_lib(),))
|
||||||
|
except AttributeError: pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
candidate_lists.append(site.getsitepackages())
|
||||||
|
except AttributeError: pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
candidate_lists.append((site.getusersitepackages(),))
|
||||||
|
except AttributeError: pass
|
||||||
|
|
||||||
|
candidates = itertools.chain.from_iterable(candidate_lists)
|
||||||
|
|
||||||
|
for candidate in candidates:
|
||||||
|
rel_candidate = os.path.relpath(
|
||||||
|
candidate, sys.prefix)
|
||||||
|
if not rel_candidate.startswith(\"..\"):
|
||||||
|
result = candidate
|
||||||
|
rel_result = rel_candidate
|
||||||
|
break
|
||||||
|
|
||||||
|
sys.stdout.write(\";\".join((
|
||||||
|
os.sep,
|
||||||
|
os.pathsep,
|
||||||
|
sys.prefix,
|
||||||
|
result,
|
||||||
|
rel_result,
|
||||||
|
sysconfig.get_config_var('SO')
|
||||||
|
)))
|
||||||
|
")
|
||||||
|
|
||||||
|
execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "${_command}"
|
||||||
|
OUTPUT_VARIABLE _list
|
||||||
|
RESULT_VARIABLE _result)
|
||||||
|
|
||||||
|
list(GET _list 0 _item)
|
||||||
|
set(PYTHON_SEPARATOR "${_item}")
|
||||||
|
mark_as_advanced(PYTHON_SEPARATOR)
|
||||||
|
|
||||||
|
list(GET _list 1 _item)
|
||||||
|
set(PYTHON_PATH_SEPARATOR "${_item}")
|
||||||
|
mark_as_advanced(PYTHON_PATH_SEPARATOR)
|
||||||
|
|
||||||
|
list(GET _list 2 _item)
|
||||||
|
set(PYTHON_PREFIX "${_item}")
|
||||||
|
mark_as_advanced(PYTHON_PREFIX)
|
||||||
|
|
||||||
|
list(GET _list 3 _item)
|
||||||
|
set(PYTHON_SITE_PACKAGES_DIR "${_item}")
|
||||||
|
mark_as_advanced(PYTHON_SITE_PACKAGES_DIR)
|
||||||
|
|
||||||
|
list(GET _list 4 _item)
|
||||||
|
set(PYTHON_RELATIVE_SITE_PACKAGES_DIR "${_item}")
|
||||||
|
mark_as_advanced(PYTHON_RELATIVE_SITE_PACKAGES_DIR)
|
||||||
|
|
||||||
|
if(NOT DEFINED PYTHON_EXTENSION_MODULE_SUFFIX)
|
||||||
|
list(GET _list 5 _item)
|
||||||
|
set(PYTHON_EXTENSION_MODULE_SUFFIX "${_item}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
function(_set_python_extension_symbol_visibility _target)
|
||||||
|
if(PYTHON_VERSION_MAJOR VERSION_GREATER 2)
|
||||||
|
set(_modinit_prefix "PyInit_")
|
||||||
|
else()
|
||||||
|
set(_modinit_prefix "init")
|
||||||
|
endif()
|
||||||
|
message("_modinit_prefix:${_modinit_prefix}")
|
||||||
|
if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC")
|
||||||
|
set_target_properties(${_target} PROPERTIES LINK_FLAGS
|
||||||
|
"/EXPORT:${_modinit_prefix}${_target}"
|
||||||
|
)
|
||||||
|
elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
|
||||||
|
set(_script_path
|
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/${_target}-version-script.map
|
||||||
|
)
|
||||||
|
file(WRITE ${_script_path}
|
||||||
|
"{global: ${_modinit_prefix}${_target}; local: *; };"
|
||||||
|
)
|
||||||
|
set_property(TARGET ${_target} APPEND_STRING PROPERTY LINK_FLAGS
|
||||||
|
" -Wl,--version-script=${_script_path}"
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(python_extension_module _target)
|
||||||
|
set(one_ops LINKED_MODULES_VAR FORWARD_DECL_MODULES_VAR MODULE_SUFFIX)
|
||||||
|
cmake_parse_arguments(_args "" "${one_ops}" "" ${ARGN})
|
||||||
|
|
||||||
|
set(_lib_type "NA")
|
||||||
|
if(TARGET ${_target})
|
||||||
|
get_property(_lib_type TARGET ${_target} PROPERTY TYPE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_is_non_lib TRUE)
|
||||||
|
|
||||||
|
set(_is_static_lib FALSE)
|
||||||
|
if(_lib_type STREQUAL "STATIC_LIBRARY")
|
||||||
|
set(_is_static_lib TRUE)
|
||||||
|
set(_is_non_lib FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_is_shared_lib FALSE)
|
||||||
|
if(_lib_type STREQUAL "SHARED_LIBRARY")
|
||||||
|
set(_is_shared_lib TRUE)
|
||||||
|
set(_is_non_lib FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
set(_is_module_lib FALSE)
|
||||||
|
if(_lib_type STREQUAL "MODULE_LIBRARY")
|
||||||
|
set(_is_module_lib TRUE)
|
||||||
|
set(_is_non_lib FALSE)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_is_static_lib OR _is_shared_lib OR _is_non_lib)
|
||||||
|
|
||||||
|
if(_is_static_lib OR _is_shared_lib)
|
||||||
|
if(_args_LINKED_MODULES_VAR)
|
||||||
|
set(${_args_LINKED_MODULES_VAR}
|
||||||
|
${${_args_LINKED_MODULES_VAR}} ${_target} PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
set_property(GLOBAL APPEND PROPERTY PY_LINKED_MODULES_LIST ${_target})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_args_FORWARD_DECL_MODULES_VAR)
|
||||||
|
set(${_args_FORWARD_DECL_MODULES_VAR}
|
||||||
|
${${_args_FORWARD_DECL_MODULES_VAR}} ${_target} PARENT_SCOPE)
|
||||||
|
else()
|
||||||
|
set_property(GLOBAL APPEND PROPERTY
|
||||||
|
PY_FORWARD_DECL_MODULES_LIST ${_target})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT _is_non_lib)
|
||||||
|
include_directories("${PYTHON_INCLUDE_DIRS}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_is_module_lib)
|
||||||
|
set_target_properties(${_target} PROPERTIES
|
||||||
|
PREFIX "${PYTHON_MODULE_PREFIX}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_is_module_lib OR _is_shared_lib)
|
||||||
|
if(_is_module_lib)
|
||||||
|
|
||||||
|
if(NOT _args_MODULE_SUFFIX)
|
||||||
|
set(_args_MODULE_SUFFIX "${PYTHON_EXTENSION_MODULE_SUFFIX}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_args_MODULE_SUFFIX STREQUAL "" AND WIN32 AND NOT CYGWIN)
|
||||||
|
set(_args_MODULE_SUFFIX ".pyd")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(NOT _args_MODULE_SUFFIX STREQUAL "")
|
||||||
|
set_target_properties(${_target}
|
||||||
|
PROPERTIES SUFFIX ${_args_MODULE_SUFFIX})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
target_link_libraries_with_dynamic_lookup(${_target} ${PYTHON_LIBRARIES})
|
||||||
|
|
||||||
|
if(_is_module_lib)
|
||||||
|
_set_python_extension_symbol_visibility(${_target})
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(python_standalone_executable _target)
|
||||||
|
include_directories(${PYTHON_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${_target} ${PYTHON_LIBRARIES})
|
||||||
|
endfunction()
|
||||||
|
|
||||||
|
function(python_modules_header _name)
|
||||||
|
set(one_ops FORWARD_DECL_MODULES_LIST
|
||||||
|
HEADER_OUTPUT_VAR
|
||||||
|
INCLUDE_DIR_OUTPUT_VAR)
|
||||||
|
cmake_parse_arguments(_args "" "${one_ops}" "" ${ARGN})
|
||||||
|
|
||||||
|
list(GET _args_UNPARSED_ARGUMENTS 0 _arg0)
|
||||||
|
# if present, use arg0 as the input file path
|
||||||
|
if(_arg0)
|
||||||
|
set(_source_file ${_arg0})
|
||||||
|
|
||||||
|
# otherwise, must determine source file from name, or vice versa
|
||||||
|
else()
|
||||||
|
get_filename_component(_name_ext "${_name}" EXT)
|
||||||
|
|
||||||
|
# if extension provided, _name is the source file
|
||||||
|
if(_name_ext)
|
||||||
|
set(_source_file ${_name})
|
||||||
|
get_filename_component(_name "${_source_file}" NAME_WE)
|
||||||
|
|
||||||
|
# otherwise, assume the source file is ${_name}.h
|
||||||
|
else()
|
||||||
|
set(_source_file ${_name}.h)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(_args_FORWARD_DECL_MODULES_LIST)
|
||||||
|
set(static_mod_list ${_args_FORWARD_DECL_MODULES_LIST})
|
||||||
|
else()
|
||||||
|
get_property(static_mod_list GLOBAL PROPERTY PY_FORWARD_DECL_MODULES_LIST)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
string(REPLACE "." "_" _header_name "${_name}")
|
||||||
|
string(TOUPPER ${_header_name} _header_name_upper)
|
||||||
|
set(_header_name_upper "_${_header_name_upper}_H")
|
||||||
|
set(generated_file ${CMAKE_CURRENT_BINARY_DIR}/${_source_file})
|
||||||
|
|
||||||
|
set(generated_file_tmp "${generated_file}.in")
|
||||||
|
file(WRITE ${generated_file_tmp}
|
||||||
|
"/* Created by CMake. DO NOT EDIT; changes will be lost. */\n")
|
||||||
|
|
||||||
|
set(_chunk "")
|
||||||
|
set(_chunk "${_chunk}#ifndef ${_header_name_upper}\n")
|
||||||
|
set(_chunk "${_chunk}#define ${_header_name_upper}\n")
|
||||||
|
set(_chunk "${_chunk}\n")
|
||||||
|
set(_chunk "${_chunk}#include <Python.h>\n")
|
||||||
|
set(_chunk "${_chunk}\n")
|
||||||
|
set(_chunk "${_chunk}#ifdef __cplusplus\n")
|
||||||
|
set(_chunk "${_chunk}extern \"C\" {\n")
|
||||||
|
set(_chunk "${_chunk}#endif /* __cplusplus */\n")
|
||||||
|
set(_chunk "${_chunk}\n")
|
||||||
|
set(_chunk "${_chunk}#if PY_MAJOR_VERSION < 3\n")
|
||||||
|
file(APPEND ${generated_file_tmp} "${_chunk}")
|
||||||
|
|
||||||
|
foreach(_module ${static_mod_list})
|
||||||
|
file(APPEND ${generated_file_tmp}
|
||||||
|
"PyMODINIT_FUNC init${PYTHON_MODULE_PREFIX}${_module}(void);\n")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
file(APPEND ${generated_file_tmp} "#else /* PY_MAJOR_VERSION >= 3*/\n")
|
||||||
|
|
||||||
|
foreach(_module ${static_mod_list})
|
||||||
|
file(APPEND ${generated_file_tmp}
|
||||||
|
"PyMODINIT_FUNC PyInit_${PYTHON_MODULE_PREFIX}${_module}(void);\n")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
set(_chunk "")
|
||||||
|
set(_chunk "${_chunk}#endif /* PY_MAJOR_VERSION >= 3*/\n\n")
|
||||||
|
set(_chunk "${_chunk}#ifdef __cplusplus\n")
|
||||||
|
set(_chunk "${_chunk}}\n")
|
||||||
|
set(_chunk "${_chunk}#endif /* __cplusplus */\n")
|
||||||
|
set(_chunk "${_chunk}\n")
|
||||||
|
file(APPEND ${generated_file_tmp} "${_chunk}")
|
||||||
|
|
||||||
|
foreach(_module ${static_mod_list})
|
||||||
|
set(_import_function "${_header_name}_${_module}")
|
||||||
|
set(_prefixed_module "${PYTHON_MODULE_PREFIX}${_module}")
|
||||||
|
|
||||||
|
set(_chunk "")
|
||||||
|
set(_chunk "${_chunk}int ${_import_function}(void)\n")
|
||||||
|
set(_chunk "${_chunk}{\n")
|
||||||
|
set(_chunk "${_chunk} static char name[] = \"${_prefixed_module}\";\n")
|
||||||
|
set(_chunk "${_chunk} #if PY_MAJOR_VERSION < 3\n")
|
||||||
|
set(_chunk "${_chunk} return PyImport_AppendInittab(")
|
||||||
|
set(_chunk "${_chunk}name, init${_prefixed_module});\n")
|
||||||
|
set(_chunk "${_chunk} #else /* PY_MAJOR_VERSION >= 3 */\n")
|
||||||
|
set(_chunk "${_chunk} return PyImport_AppendInittab(")
|
||||||
|
set(_chunk "${_chunk}name, PyInit_${_prefixed_module});\n")
|
||||||
|
set(_chunk "${_chunk} #endif /* PY_MAJOR_VERSION >= 3 */\n")
|
||||||
|
set(_chunk "${_chunk}}\n\n")
|
||||||
|
file(APPEND ${generated_file_tmp} "${_chunk}")
|
||||||
|
endforeach()
|
||||||
|
|
||||||
|
file(APPEND ${generated_file_tmp}
|
||||||
|
"void ${_header_name}_LoadAllPythonModules(void)\n{\n")
|
||||||
|
foreach(_module ${static_mod_list})
|
||||||
|
file(APPEND ${generated_file_tmp} " ${_header_name}_${_module}();\n")
|
||||||
|
endforeach()
|
||||||
|
file(APPEND ${generated_file_tmp} "}\n\n")
|
||||||
|
|
||||||
|
set(_chunk "")
|
||||||
|
set(_chunk "${_chunk}#ifndef EXCLUDE_LOAD_ALL_FUNCTION\n")
|
||||||
|
set(_chunk "${_chunk}void CMakeLoadAllPythonModules(void)\n")
|
||||||
|
set(_chunk "${_chunk}{\n")
|
||||||
|
set(_chunk "${_chunk} ${_header_name}_LoadAllPythonModules();\n")
|
||||||
|
set(_chunk "${_chunk}}\n")
|
||||||
|
set(_chunk "${_chunk}#endif /* !EXCLUDE_LOAD_ALL_FUNCTION */\n\n")
|
||||||
|
|
||||||
|
set(_chunk "${_chunk}#ifndef EXCLUDE_PY_INIT_WRAPPER\n")
|
||||||
|
set(_chunk "${_chunk}static void Py_Initialize_Wrapper()\n")
|
||||||
|
set(_chunk "${_chunk}{\n")
|
||||||
|
set(_chunk "${_chunk} ${_header_name}_LoadAllPythonModules();\n")
|
||||||
|
set(_chunk "${_chunk} Py_Initialize();\n")
|
||||||
|
set(_chunk "${_chunk}}\n")
|
||||||
|
set(_chunk "${_chunk}#define Py_Initialize Py_Initialize_Wrapper\n")
|
||||||
|
set(_chunk "${_chunk}#endif /* !EXCLUDE_PY_INIT_WRAPPER */\n\n")
|
||||||
|
|
||||||
|
set(_chunk "${_chunk}#endif /* !${_header_name_upper} */\n")
|
||||||
|
file(APPEND ${generated_file_tmp} "${_chunk}")
|
||||||
|
|
||||||
|
# with configure_file() cmake complains that you may not use a file created
|
||||||
|
# using file(WRITE) as input file for configure_file()
|
||||||
|
execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different
|
||||||
|
"${generated_file_tmp}" "${generated_file}"
|
||||||
|
OUTPUT_QUIET ERROR_QUIET)
|
||||||
|
|
||||||
|
set(_header_output_var ${_name})
|
||||||
|
if(_args_HEADER_OUTPUT_VAR)
|
||||||
|
set(_header_output_var ${_args_HEADER_OUTPUT_VAR})
|
||||||
|
endif()
|
||||||
|
set(${_header_output_var} ${generated_file} PARENT_SCOPE)
|
||||||
|
|
||||||
|
set(_include_dir_var ${_name}_INCLUDE_DIRS)
|
||||||
|
if(_args_INCLUDE_DIR_OUTPUT_VAR)
|
||||||
|
set(_include_dir_var ${_args_INCLUDE_DIR_OUTPUT_VAR})
|
||||||
|
endif()
|
||||||
|
set(${_include_dirs_var} ${CMAKE_CURRENT_BINARY_DIR} PARENT_SCOPE)
|
||||||
|
endfunction()
|
||||||
|
|
37
setup.py
37
setup.py
|
@ -1,27 +1,20 @@
|
||||||
from skbuild import setup
|
from distutils.core import setup
|
||||||
|
from Cython.Build import cythonize
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
#sys.path.append(os.path.abspath('./'))
|
sys.path.append(os.path.abspath('./src/simulators'))
|
||||||
|
from simulator_extension import simulator_extension
|
||||||
|
|
||||||
|
# Simulator extension
|
||||||
|
package_name = 'aer.backends.aer_qv_wrapper'
|
||||||
|
source_files = [os.path.abspath('src/simulators/qubitvector/qv_wrapper.pyx')]
|
||||||
|
include_dirs = [os.path.abspath('./src')]
|
||||||
|
|
||||||
|
simulator = simulator_extension(package_name, source_files, include_dirs=include_dirs)
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='aer_qv_wrapper',
|
name=package_name,
|
||||||
packages=['aer_qv_wrapper'],
|
packages=[package_name],
|
||||||
version="0.0.1",
|
ext_modules=cythonize(simulator)
|
||||||
description="QV Quantum Simulator",
|
|
||||||
author="AER Development Team",
|
|
||||||
author_email="qiskit@us.ibm.com",
|
|
||||||
license="Apache 2.0",
|
|
||||||
classifiers=[
|
|
||||||
"Environment :: Console",
|
|
||||||
"License :: OSI Approved :: Apache Software License",
|
|
||||||
"Intended Audience :: Developers",
|
|
||||||
"Intended Audience :: Science/Research",
|
|
||||||
"Operating System :: Microsoft :: Windows",
|
|
||||||
"Operating System :: MacOS",
|
|
||||||
"Operating System :: POSIX :: Linux",
|
|
||||||
"Programming Language :: Python :: 3.5",
|
|
||||||
"Programming Language :: Python :: 3.6",
|
|
||||||
"Topic :: Scientific/Engineering",
|
|
||||||
],
|
|
||||||
keywords="qiskit simulator quantum"
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.6.0)
|
|
||||||
project(aer_qv_wrapper LANGUAGES CXX)
|
|
||||||
|
|
||||||
find_package(Cython REQUIRED)
|
|
||||||
find_package(PythonLibs REQUIRED)
|
|
||||||
|
|
||||||
add_cython_target(aer_qv_wrapper qv_wrapper.pyx)
|
|
||||||
add_library(aer_qv_wrapper MODULE ${aer_qv_wrapper})
|
|
||||||
set_target_properties(aer_qv_wrapper PROPERTIES
|
|
||||||
LINKER_LANGUAGE CXX
|
|
||||||
CXX_STANDARD 14)
|
|
||||||
target_include_directories(aer_qv_wrapper
|
|
||||||
PRIVATE ${AER_SIMULATOR_CPP_SRC_DIR}
|
|
||||||
PRIVATE ${AER_SIMULATOR_CPP_EXTERNAL_LIBS}
|
|
||||||
PRIVATE ${PYTHON_INCLUDE_DIRS})
|
|
||||||
target_link_libraries(aer_qv_wrapper
|
|
||||||
${PYTHON_LIBRARIES}
|
|
||||||
${AER_LIBRARIES})
|
|
||||||
install(TARGETS aer_qv_wrapper LIBRARY DESTINATION aer_qv_wrapper)
|
|
|
@ -1,104 +0,0 @@
|
||||||
"""
|
|
||||||
Cython quantum circuit simulator.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
import json
|
|
||||||
import logging
|
|
||||||
import warnings
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
# Import QISKit classes
|
|
||||||
from qiskit._result import Result
|
|
||||||
from qiskit.backends import BaseBackend
|
|
||||||
from qiskit.backends.local.localjob import LocalJob
|
|
||||||
|
|
||||||
# Import Simulator tools
|
|
||||||
from helpers import SimulatorJSONEncoder, qobj2schema
|
|
||||||
from aer_qv_wrapper import AerSimulatorWrapper
|
|
||||||
|
|
||||||
# Logger
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class AerSimulator(BaseBackend):
|
|
||||||
"""Cython quantum circuit simulator"""
|
|
||||||
|
|
||||||
DEFAULT_CONFIGURATION = {
|
|
||||||
'name': 'local_aer_simulator',
|
|
||||||
'url': 'NA',
|
|
||||||
'simulator': True,
|
|
||||||
'local': True,
|
|
||||||
'description': 'A C++ statevector simulator for qobj files',
|
|
||||||
'coupling_map': 'all-to-all',
|
|
||||||
"basis_gates": 'u0,u1,u2,u3,cx,cz,id,x,y,z,h,s,sdg,t,tdg,rzz'
|
|
||||||
}
|
|
||||||
|
|
||||||
def __init__(self, configuration=None):
|
|
||||||
super().__init__(configuration or self.DEFAULT_CONFIGURATION.copy())
|
|
||||||
self.simulator = AerSimulatorWrapper()
|
|
||||||
|
|
||||||
def run(self, qobj):
|
|
||||||
"""Run a QOBJ on the the backend."""
|
|
||||||
return LocalJob(self._run_job, qobj)
|
|
||||||
|
|
||||||
def _run_job(self, qobj):
|
|
||||||
self._validate(qobj)
|
|
||||||
qobj_str = json.dumps(qobj2schema(qobj), cls=SimulatorJSONEncoder)
|
|
||||||
result = json.loads(self.simulator.execute(qobj_str))
|
|
||||||
# TODO: get schema in line with result object
|
|
||||||
return result # Result(result)
|
|
||||||
|
|
||||||
def load_noise_model(self, noise_model):
|
|
||||||
self.simulator.load_noise_model(json.dumps(noise_model, cls=SimulatorJSONEncoder))
|
|
||||||
|
|
||||||
def clear_noise_model(self):
|
|
||||||
self.simulator.clear_noise_model()
|
|
||||||
|
|
||||||
def load_config(self, engine=None, state=None):
|
|
||||||
if engine is not None:
|
|
||||||
self.simulator.load_engine_config(json.dumps(engine, cls=SimulatorJSONEncoder))
|
|
||||||
if state is not None:
|
|
||||||
self.simulator.load_state_config(json.dumps(state, cls=SimulatorJSONEncoder))
|
|
||||||
|
|
||||||
def set_max_threads_shot(self, threads):
|
|
||||||
"""
|
|
||||||
Set the maximum threads used for parallel shot execution.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
threads (int): the thread limit, set to -1 to use maximum available
|
|
||||||
|
|
||||||
Note that using parallel shot evaluation disables parallel circuit
|
|
||||||
evaluation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
self.simulator.set_max_threads_shot(int(threads))
|
|
||||||
|
|
||||||
def set_max_threads_circuit(self, threads):
|
|
||||||
"""
|
|
||||||
Set the maximum threads used for parallel circuit execution.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
threads (int): the thread limit, set to -1 to use maximum available
|
|
||||||
|
|
||||||
Note that using parallel circuit evaluation disables parallel shot
|
|
||||||
evaluation.
|
|
||||||
"""
|
|
||||||
self.simulator.set_max_threads_circuit(int(threads))
|
|
||||||
|
|
||||||
def set_max_threads_state(self, threads):
|
|
||||||
"""
|
|
||||||
Set the maximum threads used for state update parallel routines.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
threads (int): the thread limit, set to -1 to use maximum available.
|
|
||||||
|
|
||||||
Note that using parallel circuit or shot execution takes precidence over
|
|
||||||
parallel state evaluation.
|
|
||||||
"""
|
|
||||||
self.simulator.set_max_threads_state(int(threads))
|
|
||||||
|
|
||||||
def _validate(self, qobj):
|
|
||||||
# TODO
|
|
||||||
return
|
|
|
@ -1,544 +0,0 @@
|
||||||
{
|
|
||||||
"cells": [
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"# Cython C++ QASM Simulator\n",
|
|
||||||
"\n",
|
|
||||||
"Author: Christopher J. Wood (cjwood@us.ibm.com)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Building the simulator\n",
|
|
||||||
"\n",
|
|
||||||
"The simulator backend can be compiled by running the following code cell"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "markdown",
|
|
||||||
"metadata": {},
|
|
||||||
"source": [
|
|
||||||
"## Using the simulator as a QISKit engine\n",
|
|
||||||
"\n",
|
|
||||||
"We now import the cython simulator and use it as a qiskit backend"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 1,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# Import QISKIT\n",
|
|
||||||
"import numpy as np\n",
|
|
||||||
"import qiskit\n",
|
|
||||||
"from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister\n",
|
|
||||||
"\n",
|
|
||||||
"# Import Cython QASM Simulator Backend\n",
|
|
||||||
"from aer_simulator import AerSimulator\n",
|
|
||||||
"\n",
|
|
||||||
"# Backends\n",
|
|
||||||
"aer = AerSimulator()\n",
|
|
||||||
"aer.set_max_threads_shot(-1)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 2,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"# Create a test circuit\n",
|
|
||||||
"num_qubits = 10\n",
|
|
||||||
"num_gates = 100\n",
|
|
||||||
"qr = QuantumRegister(num_qubits)\n",
|
|
||||||
"cr = ClassicalRegister(num_qubits)\n",
|
|
||||||
"circ = QuantumCircuit(qr, cr)\n",
|
|
||||||
"for j in range(num_gates):\n",
|
|
||||||
" q = np.random.randint(0, num_qubits)\n",
|
|
||||||
" r = np.random.randint(0, 4)\n",
|
|
||||||
" if r == 0: \n",
|
|
||||||
" circ.cx(qr[q], qr[(q + 1) % num_qubits])\n",
|
|
||||||
" elif r == 1:\n",
|
|
||||||
" circ.h(qr[q])\n",
|
|
||||||
" elif r == 2:\n",
|
|
||||||
" circ.s(qr[q])\n",
|
|
||||||
" elif r == 3:\n",
|
|
||||||
" circ.t(qr[q])\n",
|
|
||||||
"for j in range(num_qubits):\n",
|
|
||||||
" circ.measure(qr[j], cr[j])"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"{'backend_name': 'qiskit_aer_simulator',\n",
|
|
||||||
" 'backend_version': 'alpha 0.1',\n",
|
|
||||||
" 'date': 'TODO',\n",
|
|
||||||
" 'id': '284835d8-8617-4ba3-9192-785ad484358a',\n",
|
|
||||||
" 'metadata': {'omp_available_threads': 4,\n",
|
|
||||||
" 'omp_circuit_threads': 1,\n",
|
|
||||||
" 'omp_enabled': True,\n",
|
|
||||||
" 'time_taken': 0.17163972600000002},\n",
|
|
||||||
" 'qobj_id': 'TODO',\n",
|
|
||||||
" 'result': [{'data': {'counts': {'0x100': 2,\n",
|
|
||||||
" '0x102': 8,\n",
|
|
||||||
" '0x103': 2,\n",
|
|
||||||
" '0x10c': 3,\n",
|
|
||||||
" '0x10d': 3,\n",
|
|
||||||
" '0x10f': 3,\n",
|
|
||||||
" '0x114': 7,\n",
|
|
||||||
" '0x115': 4,\n",
|
|
||||||
" '0x116': 7,\n",
|
|
||||||
" '0x117': 5,\n",
|
|
||||||
" '0x118': 4,\n",
|
|
||||||
" '0x119': 4,\n",
|
|
||||||
" '0x11a': 9,\n",
|
|
||||||
" '0x11b': 4,\n",
|
|
||||||
" '0x120': 4,\n",
|
|
||||||
" '0x121': 5,\n",
|
|
||||||
" '0x122': 3,\n",
|
|
||||||
" '0x123': 10,\n",
|
|
||||||
" '0x12c': 4,\n",
|
|
||||||
" '0x12d': 8,\n",
|
|
||||||
" '0x12e': 5,\n",
|
|
||||||
" '0x12f': 8,\n",
|
|
||||||
" '0x134': 2,\n",
|
|
||||||
" '0x135': 1,\n",
|
|
||||||
" '0x136': 3,\n",
|
|
||||||
" '0x138': 3,\n",
|
|
||||||
" '0x139': 4,\n",
|
|
||||||
" '0x13a': 2,\n",
|
|
||||||
" '0x13b': 2,\n",
|
|
||||||
" '0x14': 1,\n",
|
|
||||||
" '0x140': 8,\n",
|
|
||||||
" '0x141': 6,\n",
|
|
||||||
" '0x142': 4,\n",
|
|
||||||
" '0x143': 3,\n",
|
|
||||||
" '0x14c': 4,\n",
|
|
||||||
" '0x14d': 5,\n",
|
|
||||||
" '0x14e': 8,\n",
|
|
||||||
" '0x14f': 3,\n",
|
|
||||||
" '0x154': 5,\n",
|
|
||||||
" '0x155': 2,\n",
|
|
||||||
" '0x156': 2,\n",
|
|
||||||
" '0x157': 1,\n",
|
|
||||||
" '0x15a': 2,\n",
|
|
||||||
" '0x16': 1,\n",
|
|
||||||
" '0x160': 3,\n",
|
|
||||||
" '0x161': 3,\n",
|
|
||||||
" '0x162': 1,\n",
|
|
||||||
" '0x163': 1,\n",
|
|
||||||
" '0x16d': 3,\n",
|
|
||||||
" '0x16f': 3,\n",
|
|
||||||
" '0x174': 4,\n",
|
|
||||||
" '0x175': 4,\n",
|
|
||||||
" '0x176': 7,\n",
|
|
||||||
" '0x177': 3,\n",
|
|
||||||
" '0x178': 8,\n",
|
|
||||||
" '0x179': 4,\n",
|
|
||||||
" '0x17a': 4,\n",
|
|
||||||
" '0x17b': 7,\n",
|
|
||||||
" '0x180': 3,\n",
|
|
||||||
" '0x181': 2,\n",
|
|
||||||
" '0x182': 8,\n",
|
|
||||||
" '0x183': 7,\n",
|
|
||||||
" '0x18c': 4,\n",
|
|
||||||
" '0x18d': 5,\n",
|
|
||||||
" '0x18e': 4,\n",
|
|
||||||
" '0x18f': 5,\n",
|
|
||||||
" '0x19': 2,\n",
|
|
||||||
" '0x194': 1,\n",
|
|
||||||
" '0x195': 1,\n",
|
|
||||||
" '0x196': 2,\n",
|
|
||||||
" '0x197': 3,\n",
|
|
||||||
" '0x198': 2,\n",
|
|
||||||
" '0x199': 2,\n",
|
|
||||||
" '0x19a': 3,\n",
|
|
||||||
" '0x19b': 2,\n",
|
|
||||||
" '0x1a': 1,\n",
|
|
||||||
" '0x1a0': 2,\n",
|
|
||||||
" '0x1a1': 1,\n",
|
|
||||||
" '0x1a2': 1,\n",
|
|
||||||
" '0x1a3': 3,\n",
|
|
||||||
" '0x1ac': 3,\n",
|
|
||||||
" '0x1ad': 2,\n",
|
|
||||||
" '0x1ae': 1,\n",
|
|
||||||
" '0x1af': 2,\n",
|
|
||||||
" '0x1b': 1,\n",
|
|
||||||
" '0x1b4': 10,\n",
|
|
||||||
" '0x1b5': 4,\n",
|
|
||||||
" '0x1b7': 3,\n",
|
|
||||||
" '0x1b8': 7,\n",
|
|
||||||
" '0x1b9': 4,\n",
|
|
||||||
" '0x1ba': 5,\n",
|
|
||||||
" '0x1bb': 3,\n",
|
|
||||||
" '0x1c0': 1,\n",
|
|
||||||
" '0x1c3': 1,\n",
|
|
||||||
" '0x1cc': 1,\n",
|
|
||||||
" '0x1cd': 1,\n",
|
|
||||||
" '0x1d4': 3,\n",
|
|
||||||
" '0x1d5': 3,\n",
|
|
||||||
" '0x1d6': 6,\n",
|
|
||||||
" '0x1d7': 6,\n",
|
|
||||||
" '0x1d8': 6,\n",
|
|
||||||
" '0x1d9': 2,\n",
|
|
||||||
" '0x1da': 2,\n",
|
|
||||||
" '0x1db': 5,\n",
|
|
||||||
" '0x1e0': 8,\n",
|
|
||||||
" '0x1e1': 8,\n",
|
|
||||||
" '0x1e2': 4,\n",
|
|
||||||
" '0x1e3': 1,\n",
|
|
||||||
" '0x1ec': 1,\n",
|
|
||||||
" '0x1ed': 2,\n",
|
|
||||||
" '0x1ee': 4,\n",
|
|
||||||
" '0x1ef': 4,\n",
|
|
||||||
" '0x1f4': 2,\n",
|
|
||||||
" '0x1f5': 1,\n",
|
|
||||||
" '0x1f6': 2,\n",
|
|
||||||
" '0x1f7': 1,\n",
|
|
||||||
" '0x1f8': 4,\n",
|
|
||||||
" '0x1fa': 3,\n",
|
|
||||||
" '0x1fb': 3,\n",
|
|
||||||
" '0x20': 1,\n",
|
|
||||||
" '0x20f': 1,\n",
|
|
||||||
" '0x21': 2,\n",
|
|
||||||
" '0x215': 1,\n",
|
|
||||||
" '0x217': 2,\n",
|
|
||||||
" '0x218': 1,\n",
|
|
||||||
" '0x21b': 1,\n",
|
|
||||||
" '0x22': 1,\n",
|
|
||||||
" '0x220': 2,\n",
|
|
||||||
" '0x222': 1,\n",
|
|
||||||
" '0x22c': 4,\n",
|
|
||||||
" '0x22d': 3,\n",
|
|
||||||
" '0x22e': 2,\n",
|
|
||||||
" '0x236': 1,\n",
|
|
||||||
" '0x23b': 2,\n",
|
|
||||||
" '0x240': 2,\n",
|
|
||||||
" '0x241': 2,\n",
|
|
||||||
" '0x242': 1,\n",
|
|
||||||
" '0x243': 1,\n",
|
|
||||||
" '0x24c': 1,\n",
|
|
||||||
" '0x24d': 4,\n",
|
|
||||||
" '0x24e': 1,\n",
|
|
||||||
" '0x254': 1,\n",
|
|
||||||
" '0x263': 1,\n",
|
|
||||||
" '0x26d': 2,\n",
|
|
||||||
" '0x26e': 1,\n",
|
|
||||||
" '0x274': 2,\n",
|
|
||||||
" '0x275': 1,\n",
|
|
||||||
" '0x277': 1,\n",
|
|
||||||
" '0x27b': 1,\n",
|
|
||||||
" '0x280': 1,\n",
|
|
||||||
" '0x281': 1,\n",
|
|
||||||
" '0x283': 1,\n",
|
|
||||||
" '0x28f': 1,\n",
|
|
||||||
" '0x298': 2,\n",
|
|
||||||
" '0x299': 1,\n",
|
|
||||||
" '0x2b4': 1,\n",
|
|
||||||
" '0x2b6': 1,\n",
|
|
||||||
" '0x2b7': 1,\n",
|
|
||||||
" '0x2b8': 1,\n",
|
|
||||||
" '0x2ba': 1,\n",
|
|
||||||
" '0x2bb': 1,\n",
|
|
||||||
" '0x2cc': 1,\n",
|
|
||||||
" '0x2ce': 1,\n",
|
|
||||||
" '0x2d': 1,\n",
|
|
||||||
" '0x2d5': 1,\n",
|
|
||||||
" '0x2d9': 1,\n",
|
|
||||||
" '0x2db': 2,\n",
|
|
||||||
" '0x2e0': 3,\n",
|
|
||||||
" '0x2e1': 1,\n",
|
|
||||||
" '0x2e2': 2,\n",
|
|
||||||
" '0x2ec': 2,\n",
|
|
||||||
" '0x2ee': 1,\n",
|
|
||||||
" '0x2ef': 2,\n",
|
|
||||||
" '0x2f9': 2,\n",
|
|
||||||
" '0x2fb': 1,\n",
|
|
||||||
" '0x301': 2,\n",
|
|
||||||
" '0x302': 3,\n",
|
|
||||||
" '0x303': 1,\n",
|
|
||||||
" '0x30c': 2,\n",
|
|
||||||
" '0x30d': 1,\n",
|
|
||||||
" '0x30e': 3,\n",
|
|
||||||
" '0x30f': 4,\n",
|
|
||||||
" '0x314': 8,\n",
|
|
||||||
" '0x315': 3,\n",
|
|
||||||
" '0x316': 2,\n",
|
|
||||||
" '0x317': 4,\n",
|
|
||||||
" '0x318': 3,\n",
|
|
||||||
" '0x319': 7,\n",
|
|
||||||
" '0x31a': 4,\n",
|
|
||||||
" '0x31b': 4,\n",
|
|
||||||
" '0x320': 7,\n",
|
|
||||||
" '0x321': 5,\n",
|
|
||||||
" '0x322': 2,\n",
|
|
||||||
" '0x323': 5,\n",
|
|
||||||
" '0x32c': 4,\n",
|
|
||||||
" '0x32d': 4,\n",
|
|
||||||
" '0x32e': 6,\n",
|
|
||||||
" '0x32f': 6,\n",
|
|
||||||
" '0x334': 1,\n",
|
|
||||||
" '0x335': 2,\n",
|
|
||||||
" '0x336': 3,\n",
|
|
||||||
" '0x338': 3,\n",
|
|
||||||
" '0x339': 1,\n",
|
|
||||||
" '0x33a': 1,\n",
|
|
||||||
" '0x33b': 2,\n",
|
|
||||||
" '0x340': 4,\n",
|
|
||||||
" '0x341': 7,\n",
|
|
||||||
" '0x342': 2,\n",
|
|
||||||
" '0x343': 7,\n",
|
|
||||||
" '0x34c': 6,\n",
|
|
||||||
" '0x34d': 2,\n",
|
|
||||||
" '0x34e': 6,\n",
|
|
||||||
" '0x34f': 3,\n",
|
|
||||||
" '0x354': 3,\n",
|
|
||||||
" '0x356': 1,\n",
|
|
||||||
" '0x358': 4,\n",
|
|
||||||
" '0x359': 2,\n",
|
|
||||||
" '0x35a': 4,\n",
|
|
||||||
" '0x35b': 1,\n",
|
|
||||||
" '0x360': 1,\n",
|
|
||||||
" '0x361': 2,\n",
|
|
||||||
" '0x362': 1,\n",
|
|
||||||
" '0x363': 1,\n",
|
|
||||||
" '0x36c': 3,\n",
|
|
||||||
" '0x36d': 1,\n",
|
|
||||||
" '0x36e': 1,\n",
|
|
||||||
" '0x374': 5,\n",
|
|
||||||
" '0x375': 10,\n",
|
|
||||||
" '0x376': 5,\n",
|
|
||||||
" '0x377': 10,\n",
|
|
||||||
" '0x378': 4,\n",
|
|
||||||
" '0x379': 3,\n",
|
|
||||||
" '0x37a': 3,\n",
|
|
||||||
" '0x37b': 2,\n",
|
|
||||||
" '0x380': 5,\n",
|
|
||||||
" '0x381': 5,\n",
|
|
||||||
" '0x382': 4,\n",
|
|
||||||
" '0x383': 4,\n",
|
|
||||||
" '0x38c': 6,\n",
|
|
||||||
" '0x38d': 10,\n",
|
|
||||||
" '0x38e': 7,\n",
|
|
||||||
" '0x38f': 9,\n",
|
|
||||||
" '0x394': 1,\n",
|
|
||||||
" '0x395': 2,\n",
|
|
||||||
" '0x396': 2,\n",
|
|
||||||
" '0x397': 1,\n",
|
|
||||||
" '0x398': 1,\n",
|
|
||||||
" '0x399': 1,\n",
|
|
||||||
" '0x39a': 2,\n",
|
|
||||||
" '0x39b': 1,\n",
|
|
||||||
" '0x3a0': 4,\n",
|
|
||||||
" '0x3a1': 2,\n",
|
|
||||||
" '0x3a2': 1,\n",
|
|
||||||
" '0x3a3': 2,\n",
|
|
||||||
" '0x3ac': 2,\n",
|
|
||||||
" '0x3ad': 2,\n",
|
|
||||||
" '0x3af': 1,\n",
|
|
||||||
" '0x3b4': 5,\n",
|
|
||||||
" '0x3b5': 8,\n",
|
|
||||||
" '0x3b6': 4,\n",
|
|
||||||
" '0x3b7': 4,\n",
|
|
||||||
" '0x3b8': 6,\n",
|
|
||||||
" '0x3b9': 5,\n",
|
|
||||||
" '0x3ba': 7,\n",
|
|
||||||
" '0x3bb': 6,\n",
|
|
||||||
" '0x3c0': 2,\n",
|
|
||||||
" '0x3c1': 2,\n",
|
|
||||||
" '0x3cd': 1,\n",
|
|
||||||
" '0x3ce': 1,\n",
|
|
||||||
" '0x3cf': 1,\n",
|
|
||||||
" '0x3d4': 8,\n",
|
|
||||||
" '0x3d5': 7,\n",
|
|
||||||
" '0x3d6': 1,\n",
|
|
||||||
" '0x3d7': 6,\n",
|
|
||||||
" '0x3d8': 4,\n",
|
|
||||||
" '0x3d9': 3,\n",
|
|
||||||
" '0x3da': 9,\n",
|
|
||||||
" '0x3db': 8,\n",
|
|
||||||
" '0x3e1': 6,\n",
|
|
||||||
" '0x3e2': 5,\n",
|
|
||||||
" '0x3e3': 9,\n",
|
|
||||||
" '0x3ec': 6,\n",
|
|
||||||
" '0x3ed': 4,\n",
|
|
||||||
" '0x3ee': 5,\n",
|
|
||||||
" '0x3ef': 6,\n",
|
|
||||||
" '0x3f5': 1,\n",
|
|
||||||
" '0x3f6': 1,\n",
|
|
||||||
" '0x3f7': 3,\n",
|
|
||||||
" '0x3f8': 2,\n",
|
|
||||||
" '0x3f9': 4,\n",
|
|
||||||
" '0x3fa': 2,\n",
|
|
||||||
" '0x3fb': 3,\n",
|
|
||||||
" '0x41': 1,\n",
|
|
||||||
" '0x43': 1,\n",
|
|
||||||
" '0x4f': 3,\n",
|
|
||||||
" '0x56': 1,\n",
|
|
||||||
" '0x59': 1,\n",
|
|
||||||
" '0x76': 3,\n",
|
|
||||||
" '0x78': 1,\n",
|
|
||||||
" '0x80': 1,\n",
|
|
||||||
" '0x81': 1,\n",
|
|
||||||
" '0x82': 1,\n",
|
|
||||||
" '0x83': 1,\n",
|
|
||||||
" '0x8c': 1,\n",
|
|
||||||
" '0x8e': 1,\n",
|
|
||||||
" '0x8f': 1,\n",
|
|
||||||
" '0x94': 1,\n",
|
|
||||||
" '0xad': 1,\n",
|
|
||||||
" '0xb4': 2,\n",
|
|
||||||
" '0xb6': 1,\n",
|
|
||||||
" '0xb7': 2,\n",
|
|
||||||
" '0xb8': 3,\n",
|
|
||||||
" '0xb9': 1,\n",
|
|
||||||
" '0xba': 2,\n",
|
|
||||||
" '0xbb': 1,\n",
|
|
||||||
" '0xc2': 1,\n",
|
|
||||||
" '0xc3': 1,\n",
|
|
||||||
" '0xd5': 1,\n",
|
|
||||||
" '0xd6': 1,\n",
|
|
||||||
" '0xd8': 1,\n",
|
|
||||||
" '0xd9': 2,\n",
|
|
||||||
" '0xe1': 1,\n",
|
|
||||||
" '0xe2': 1,\n",
|
|
||||||
" '0xe3': 2,\n",
|
|
||||||
" '0xed': 1,\n",
|
|
||||||
" '0xee': 2,\n",
|
|
||||||
" '0xef': 1,\n",
|
|
||||||
" '0xf5': 2}},\n",
|
|
||||||
" 'header': {'name': 'circuit1'},\n",
|
|
||||||
" 'metadata': {'omp_shot_threads': 4,\n",
|
|
||||||
" 'omp_state_threads': 1,\n",
|
|
||||||
" 'seed': 1925572646,\n",
|
|
||||||
" 'shots': 1000,\n",
|
|
||||||
" 'time_taken': 0.17120264200000002},\n",
|
|
||||||
" 'status': 'DONE',\n",
|
|
||||||
" 'success': True}],\n",
|
|
||||||
" 'status': 'COMPLETED',\n",
|
|
||||||
" 'success': True}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 3,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"result = qiskit.execute(circ, aer, shots=1000).result()\n",
|
|
||||||
"result"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 4,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"noise_model = {\n",
|
|
||||||
" \"errors\": [\n",
|
|
||||||
" {\n",
|
|
||||||
" \"type\": \"kraus\",\n",
|
|
||||||
" \"operations\": [\"h\"],\n",
|
|
||||||
" \"probabilities\": [1],\n",
|
|
||||||
" \"matrices\": [np.array([[1, 0], [0, 0.5]]),\n",
|
|
||||||
" np.array([[0, 0.86602540378], [0, 0]])]\n",
|
|
||||||
" }\n",
|
|
||||||
" ]\n",
|
|
||||||
"}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 5,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": [
|
|
||||||
"aer.load_noise_model(noise_model)"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [
|
|
||||||
{
|
|
||||||
"data": {
|
|
||||||
"text/plain": [
|
|
||||||
"{'backend_name': 'qiskit_aer_simulator',\n",
|
|
||||||
" 'backend_version': 'alpha 0.1',\n",
|
|
||||||
" 'date': 'TODO',\n",
|
|
||||||
" 'id': '2fad1b6a-7031-49b8-a486-876240caf385',\n",
|
|
||||||
" 'metadata': {'omp_available_threads': 4,\n",
|
|
||||||
" 'omp_circuit_threads': 1,\n",
|
|
||||||
" 'omp_enabled': True,\n",
|
|
||||||
" 'time_taken': 0.34858704900000004},\n",
|
|
||||||
" 'qobj_id': 'TODO',\n",
|
|
||||||
" 'result': [{'data': {'counts': {'0x1ff': 364,\n",
|
|
||||||
" '0x2ff': 8,\n",
|
|
||||||
" '0x3ff': 620,\n",
|
|
||||||
" '0xbf': 1,\n",
|
|
||||||
" '0xff': 31}},\n",
|
|
||||||
" 'header': {'name': 'circuit1'},\n",
|
|
||||||
" 'metadata': {'omp_shot_threads': 4,\n",
|
|
||||||
" 'omp_state_threads': 1,\n",
|
|
||||||
" 'seed': 3182171174,\n",
|
|
||||||
" 'shots': 1024,\n",
|
|
||||||
" 'time_taken': 0.34713111900000004},\n",
|
|
||||||
" 'status': 'DONE',\n",
|
|
||||||
" 'success': True}],\n",
|
|
||||||
" 'status': 'COMPLETED',\n",
|
|
||||||
" 'success': True}"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"execution_count": 6,
|
|
||||||
"metadata": {},
|
|
||||||
"output_type": "execute_result"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"source": [
|
|
||||||
"result = qiskit.execute(circ, aer).result()\n",
|
|
||||||
"result"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"cell_type": "code",
|
|
||||||
"execution_count": null,
|
|
||||||
"metadata": {},
|
|
||||||
"outputs": [],
|
|
||||||
"source": []
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"metadata": {
|
|
||||||
"kernelspec": {
|
|
||||||
"display_name": "Python (qiskit)",
|
|
||||||
"language": "python",
|
|
||||||
"name": "qiskit"
|
|
||||||
},
|
|
||||||
"language_info": {
|
|
||||||
"codemirror_mode": {
|
|
||||||
"name": "ipython",
|
|
||||||
"version": 3
|
|
||||||
},
|
|
||||||
"file_extension": ".py",
|
|
||||||
"mimetype": "text/x-python",
|
|
||||||
"name": "python",
|
|
||||||
"nbconvert_exporter": "python",
|
|
||||||
"pygments_lexer": "ipython3",
|
|
||||||
"version": "3.6.5"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"nbformat": 4,
|
|
||||||
"nbformat_minor": 2
|
|
||||||
}
|
|
|
@ -1,50 +0,0 @@
|
||||||
import json
|
|
||||||
import numpy as np
|
|
||||||
|
|
||||||
|
|
||||||
class SimulatorJSONEncoder(json.JSONEncoder):
|
|
||||||
"""
|
|
||||||
JSON encoder for NumPy arrays and complex numbers.
|
|
||||||
|
|
||||||
This functions as the standard JSON Encoder but adds support
|
|
||||||
for encoding:
|
|
||||||
complex numbers z as lists [z.real, z.imag]
|
|
||||||
ndarrays as nested lists.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# pylint: disable=method-hidden,arguments-differ
|
|
||||||
def default(self, obj):
|
|
||||||
if isinstance(obj, np.ndarray):
|
|
||||||
return obj.tolist()
|
|
||||||
if isinstance(obj, complex):
|
|
||||||
return [obj.real, obj.imag]
|
|
||||||
return json.JSONEncoder.default(self, obj)
|
|
||||||
|
|
||||||
|
|
||||||
def qobj2schema(qobj):
|
|
||||||
"""
|
|
||||||
Convert current Qiskit qobj in line with schema spec qobj for simulator testing.
|
|
||||||
"""
|
|
||||||
shots = qobj.get("config",{}).get("shots", 1)
|
|
||||||
qobj["type"] = "QASM"
|
|
||||||
if "circuits" in qobj:
|
|
||||||
qobj["experiments"] = qobj.pop("circuits")
|
|
||||||
if "experiments" in qobj:
|
|
||||||
for i, experiment in enumerate(qobj["experiments"]):
|
|
||||||
# adjust labels
|
|
||||||
if "compiled_circuit" in experiment:
|
|
||||||
experiment["compiled_circuit"].pop("header", None)
|
|
||||||
experiment["instructions"] = experiment.pop("compiled_circuit", {}).pop("operations", [])
|
|
||||||
for k, op in enumerate(experiment["instructions"]):
|
|
||||||
if op.get("name") == "measure":
|
|
||||||
op["memory"] = op.pop("clbits")
|
|
||||||
op["register"] = op["memory"]
|
|
||||||
experiment["instructions"][k] = op
|
|
||||||
experiment["config"] = {"shots": shots}
|
|
||||||
# clear compiled qasm
|
|
||||||
experiment.pop("compiled_circuit_qasm", '')
|
|
||||||
# clear old header
|
|
||||||
if "name" in experiment:
|
|
||||||
experiment["header"] = {"name": experiment.pop("name")}
|
|
||||||
qobj["experiments"][i] = experiment
|
|
||||||
return qobj
|
|
|
@ -1,106 +0,0 @@
|
||||||
"""
|
|
||||||
Cython interface to C++ quantum circuit simulator.
|
|
||||||
"""
|
|
||||||
|
|
||||||
# Import C++ Classes
|
|
||||||
from libcpp.string cimport string
|
|
||||||
|
|
||||||
# Import C++ simulator Interface class
|
|
||||||
cdef extern from "framework/interface.hpp" namespace "AER":
|
|
||||||
cdef cppclass Interface:
|
|
||||||
Interface() except+
|
|
||||||
string execute[STATE, STATECLASS](string &qobj) except +
|
|
||||||
|
|
||||||
void load_noise_model(string &qobj) except +
|
|
||||||
void load_engine_config(string &qobj) except +
|
|
||||||
void load_state_config(string &qobj) except +
|
|
||||||
|
|
||||||
void clear_noise_model()
|
|
||||||
void clear_engine_config()
|
|
||||||
void clear_state_config()
|
|
||||||
|
|
||||||
void set_max_threads(int threads)
|
|
||||||
void set_max_threads_circuit(int threads)
|
|
||||||
void set_max_threads_shot(int threads)
|
|
||||||
void set_max_threads_state(int threads)
|
|
||||||
|
|
||||||
int get_max_threads()
|
|
||||||
int get_max_threads_circuit()
|
|
||||||
int get_max_threads_shot()
|
|
||||||
int get_max_threads_state()
|
|
||||||
|
|
||||||
# QubitVector State class
|
|
||||||
cdef extern from "simulators/qubitvector/qubitvector.hpp" namespace "QV":
|
|
||||||
cdef cppclass QubitVector:
|
|
||||||
State() except +
|
|
||||||
|
|
||||||
# QubitVector State class
|
|
||||||
cdef extern from "simulators/qubitvector/qv_state.hpp" namespace "AER::QubitVector":
|
|
||||||
cdef cppclass State:
|
|
||||||
State() except +
|
|
||||||
|
|
||||||
|
|
||||||
cdef class AerSimulatorWrapper:
|
|
||||||
|
|
||||||
cdef Interface *thisptr
|
|
||||||
|
|
||||||
def __cinit__(self):
|
|
||||||
self.thisptr = new Interface()
|
|
||||||
|
|
||||||
def __dealloc__(self):
|
|
||||||
del self.thisptr
|
|
||||||
|
|
||||||
def execute(self, qobj):
|
|
||||||
# Convert input to C++ string
|
|
||||||
cdef string qobj_enc = str(qobj).encode('UTF-8')
|
|
||||||
# Execute
|
|
||||||
return self.thisptr.execute[QubitVector, State](qobj_enc)
|
|
||||||
|
|
||||||
def load_noise_model(self, config):
|
|
||||||
# Convert input to C++ string
|
|
||||||
cdef string config_enc = str(config).encode('UTF-8')
|
|
||||||
self.thisptr.load_noise_model(config_enc)
|
|
||||||
|
|
||||||
def load_state_config(self, config):
|
|
||||||
# Convert input to C++ string
|
|
||||||
cdef string config_enc = str(config).encode('UTF-8')
|
|
||||||
self.thisptr.load_state_config(config_enc)
|
|
||||||
|
|
||||||
def load_engine_config(self, config):
|
|
||||||
# Convert input to C++ string
|
|
||||||
cdef string config_enc = str(config).encode('UTF-8')
|
|
||||||
self.thisptr.load_engine_config(config_enc)
|
|
||||||
|
|
||||||
def clear_noise_model(self):
|
|
||||||
self.thisptr.clear_noise_model()
|
|
||||||
|
|
||||||
def clear_state_config(self):
|
|
||||||
|
|
||||||
self.thisptr.clear_state_config()
|
|
||||||
|
|
||||||
def clear_engine_config(self):
|
|
||||||
self.thisptr.clear_engine_config()
|
|
||||||
|
|
||||||
def set_max_threads(self, threads):
|
|
||||||
self.thisptr.set_max_threads(int(threads))
|
|
||||||
|
|
||||||
def set_max_threads_circuit(self, threads):
|
|
||||||
self.thisptr.set_max_threads_circuit(int(threads))
|
|
||||||
|
|
||||||
def set_max_threads_shot(self, threads):
|
|
||||||
self.thisptr.set_max_threads_shot(int(threads))
|
|
||||||
|
|
||||||
def set_max_threads_state(self, threads):
|
|
||||||
self.thisptr.set_max_threads_state(int(threads))
|
|
||||||
|
|
||||||
def get_max_threads(self):
|
|
||||||
return self.thisptr.get_max_threads()
|
|
||||||
|
|
||||||
def get_max_threads_circuit(self):
|
|
||||||
return self.thisptr.get_max_threads_circuit()
|
|
||||||
|
|
||||||
def get_max_threads_shot(self):
|
|
||||||
return self.thisptr.get_max_threads_shot()
|
|
||||||
|
|
||||||
def get_max_threads_state(self):
|
|
||||||
return self.thisptr.get_max_threads_state()
|
|
Loading…
Reference in New Issue