From e9476602fa565707607aa5e9ebf559335fb36741 Mon Sep 17 00:00:00 2001 From: Juan Gomez Date: Mon, 3 Sep 2018 23:06:52 +0200 Subject: [PATCH] * Added support for using the QV Simulator as Qiskit Addon --- CMakeLists.txt | 4 +- aer/backends/aer_simulator.py | 104 ---- aer/backends/helpers.py | 50 -- aer/{backends => qv_addon}/example.ipynb | 0 pyproject.toml => aer/qv_addon/pyproject.toml | 0 aer/qv_addon/qiskit_addon_qv/CMakeLists.txt | 27 + aer/qv_addon/qiskit_addon_qv/__init__.py | 4 + .../qiskit_addon_qv/aer_qv_provider.py | 42 ++ .../qiskit_addon_qv/aer_qv_wrapper.pyx | 2 +- .../qv_addon/requirements-dev.txt | 0 aer/qv_addon/setup.py | 26 + cmake/FindPythonExtensions.cmake | 574 ++++++++++++++++++ setup.py | 37 +- src/bindings/python/CMakeLists.txt | 19 - src/bindings/python/aer_simulator.py | 104 ---- src/bindings/python/example.ipynb | 544 ----------------- src/bindings/python/helpers.py | 50 -- src/simulators/qubitvector/qv_wrapper.pyx | 106 ---- 18 files changed, 691 insertions(+), 1002 deletions(-) delete mode 100755 aer/backends/aer_simulator.py delete mode 100755 aer/backends/helpers.py rename aer/{backends => qv_addon}/example.ipynb (100%) mode change 100755 => 100644 rename pyproject.toml => aer/qv_addon/pyproject.toml (100%) create mode 100644 aer/qv_addon/qiskit_addon_qv/CMakeLists.txt create mode 100644 aer/qv_addon/qiskit_addon_qv/__init__.py create mode 100644 aer/qv_addon/qiskit_addon_qv/aer_qv_provider.py rename src/bindings/python/qv_wrapper.pyx => aer/qv_addon/qiskit_addon_qv/aer_qv_wrapper.pyx (98%) rename requirements-dev.txt => aer/qv_addon/requirements-dev.txt (100%) create mode 100644 aer/qv_addon/setup.py create mode 100644 cmake/FindPythonExtensions.cmake delete mode 100644 src/bindings/python/CMakeLists.txt delete mode 100755 src/bindings/python/aer_simulator.py delete mode 100755 src/bindings/python/example.ipynb delete mode 100755 src/bindings/python/helpers.py delete mode 100755 src/simulators/qubitvector/qv_wrapper.pyx diff --git a/CMakeLists.txt b/CMakeLists.txt index a5b00d71f..eca34ca1a 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ # Additionaly, OpenMP support is only available in clang from 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_PREFIX_PATH ${CMAKE_SOURCE_DIR}/cmake) @@ -163,4 +163,4 @@ if(BUILD_TESTS) endif() # Cyhton build -add_subdirectory(src/bindings/python) \ No newline at end of file +add_subdirectory(aer/qv_addon/qiskit_addon_qv) \ No newline at end of file diff --git a/aer/backends/aer_simulator.py b/aer/backends/aer_simulator.py deleted file mode 100755 index 0a0e8e98c..000000000 --- a/aer/backends/aer_simulator.py +++ /dev/null @@ -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 diff --git a/aer/backends/helpers.py b/aer/backends/helpers.py deleted file mode 100755 index c9ffeb588..000000000 --- a/aer/backends/helpers.py +++ /dev/null @@ -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 diff --git a/aer/backends/example.ipynb b/aer/qv_addon/example.ipynb old mode 100755 new mode 100644 similarity index 100% rename from aer/backends/example.ipynb rename to aer/qv_addon/example.ipynb diff --git a/pyproject.toml b/aer/qv_addon/pyproject.toml similarity index 100% rename from pyproject.toml rename to aer/qv_addon/pyproject.toml diff --git a/aer/qv_addon/qiskit_addon_qv/CMakeLists.txt b/aer/qv_addon/qiskit_addon_qv/CMakeLists.txt new file mode 100644 index 000000000..5c22f287d --- /dev/null +++ b/aer/qv_addon/qiskit_addon_qv/CMakeLists.txt @@ -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}) \ No newline at end of file diff --git a/aer/qv_addon/qiskit_addon_qv/__init__.py b/aer/qv_addon/qiskit_addon_qv/__init__.py new file mode 100644 index 000000000..12684b415 --- /dev/null +++ b/aer/qv_addon/qiskit_addon_qv/__init__.py @@ -0,0 +1,4 @@ +from .aer_qv_provider import AerQvProvider +from aer_qv_wrapper import AerQvSimulatorWrapper + +__version__ = '0.0.1' \ No newline at end of file diff --git a/aer/qv_addon/qiskit_addon_qv/aer_qv_provider.py b/aer/qv_addon/qiskit_addon_qv/aer_qv_provider.py new file mode 100644 index 000000000..0c04d7e5b --- /dev/null +++ b/aer/qv_addon/qiskit_addon_qv/aer_qv_provider.py @@ -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()) \ No newline at end of file diff --git a/src/bindings/python/qv_wrapper.pyx b/aer/qv_addon/qiskit_addon_qv/aer_qv_wrapper.pyx similarity index 98% rename from src/bindings/python/qv_wrapper.pyx rename to aer/qv_addon/qiskit_addon_qv/aer_qv_wrapper.pyx index 4daa4e2b5..a14e22a35 100755 --- a/src/bindings/python/qv_wrapper.pyx +++ b/aer/qv_addon/qiskit_addon_qv/aer_qv_wrapper.pyx @@ -40,7 +40,7 @@ cdef extern from "simulators/qubitvector/qv_state.hpp" namespace "AER::QubitVect State() except + -cdef class AerSimulatorWrapper: +cdef class AerQvSimulatorWrapper: cdef Interface *thisptr diff --git a/requirements-dev.txt b/aer/qv_addon/requirements-dev.txt similarity index 100% rename from requirements-dev.txt rename to aer/qv_addon/requirements-dev.txt diff --git a/aer/qv_addon/setup.py b/aer/qv_addon/setup.py new file mode 100644 index 000000000..d90d428ee --- /dev/null +++ b/aer/qv_addon/setup.py @@ -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" +) diff --git a/cmake/FindPythonExtensions.cmake b/cmake/FindPythonExtensions.cmake new file mode 100644 index 000000000..5d4e061a6 --- /dev/null +++ b/cmake/FindPythonExtensions.cmake @@ -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( +# [LINKED_MODULES_VAR ] +# [FORWARD_DECL_MODULES_VAR ] +# [MODULE_SUFFIX ]) +# +# 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 ```` 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 `` +# 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 `` +# 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 `` +# 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() +# +# 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. +# ```` is the logical name for the header file (no file extensions). +# ```` is the actual destination filename for the header file +# (e.g.: decl_modules.h). +# +# python_modules_header( [HeaderFilename] +# [FORWARD_DECL_MODULES_LIST ] +# [HEADER_OUTPUT_VAR ] +# [INCLUDE_DIR_OUTPUT_VAR ]) +# +# If only ```` is provided, and it ends in the ".h" extension, then it +# is assumed to be the ````. The filename of the header file +# without the extension is used as the logical name. If only ```` is +# provided, and it does not end in the ".h" extension, then the +# ```` is assumed to ``.h``. +# +# The exact contents of the generated header file depend on the logical +# ````. 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 _(void)`` +# Initializes the python extension module, ````. Returns an integer +# handle to the module. +# +# ``void _LoadAllPythonModules(void)`` +# Initializes all listed python extension modules. +# +# ``void CMakeLoadAllPythonModules(void);`` +# Alias for ``_LoadAllPythonModules`` whose name does not depend on +# ````. 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 `` +# 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 `` +# Name of the variable to set to the path to the generated header file. By +# default, ```` is used. +# +# ``INCLUDE_DIR_OUTPUT_VAR `` +# Name of the variable to set to the path to the directory containing the +# generated header file. By default, ``_INCLUDE_DIRS`` is used. +# +# Defined variables: +# +# ```` +# The path to the generated header file +# +# ```` +# 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 \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() + diff --git a/setup.py b/setup.py index e8823750d..eefa81392 100644 --- a/setup.py +++ b/setup.py @@ -1,27 +1,20 @@ -from skbuild import setup +from distutils.core import setup +from Cython.Build import cythonize import sys 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( - name='aer_qv_wrapper', - packages=['aer_qv_wrapper'], - version="0.0.1", - 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" + name=package_name, + packages=[package_name], + ext_modules=cythonize(simulator) ) diff --git a/src/bindings/python/CMakeLists.txt b/src/bindings/python/CMakeLists.txt deleted file mode 100644 index a66a75082..000000000 --- a/src/bindings/python/CMakeLists.txt +++ /dev/null @@ -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) \ No newline at end of file diff --git a/src/bindings/python/aer_simulator.py b/src/bindings/python/aer_simulator.py deleted file mode 100755 index 0a0e8e98c..000000000 --- a/src/bindings/python/aer_simulator.py +++ /dev/null @@ -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 diff --git a/src/bindings/python/example.ipynb b/src/bindings/python/example.ipynb deleted file mode 100755 index c3c223d36..000000000 --- a/src/bindings/python/example.ipynb +++ /dev/null @@ -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 -} diff --git a/src/bindings/python/helpers.py b/src/bindings/python/helpers.py deleted file mode 100755 index c9ffeb588..000000000 --- a/src/bindings/python/helpers.py +++ /dev/null @@ -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 diff --git a/src/simulators/qubitvector/qv_wrapper.pyx b/src/simulators/qubitvector/qv_wrapper.pyx deleted file mode 100755 index 4daa4e2b5..000000000 --- a/src/simulators/qubitvector/qv_wrapper.pyx +++ /dev/null @@ -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()