Skip to content

Commit

Permalink
Enforce unix line endings (#136)
Browse files Browse the repository at this point in the history
# Description

- Added a .gitattributes file to instruct git on appropriate line
endings for text files (and blocked .png from being treated as a text
file!)
- Git did the rest

An alternative approach would have been to rewrite commit histories,
forcing the change on each revision, such that the blame is preserved,
but this can get messy, changes hashes, and leaves any user-local
branches out of sync with origin. This approach might make some merges
more awkward, but is nonetheless much cleaner.


# Related issues

None.

# Checklist

This is a meta change and should not impact the usage of the repository.
- [x] I have performed a diff with --ignore-cr-at-eol to verify no
changes other than EOL-related ones have occurred (aside from the
addition of .gitattributes)
- [x] I have verified that no binary files have been modified as a
result (e.g. PNG files).
  • Loading branch information
jake-arkinstall authored Jul 9, 2024
2 parents a32146c + a20212b commit 827e270
Show file tree
Hide file tree
Showing 12 changed files with 5,634 additions and 5,631 deletions.
3 changes: 3 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
* text=auto
* text eol=lf
*.png -text
122 changes: 61 additions & 61 deletions docs/modules/structured_state.rst
Original file line number Diff line number Diff line change
@@ -1,61 +1,61 @@
Structured state evolution
==========================

.. automodule:: pytket.extensions.cutensornet.structured_state


Simulation
~~~~~~~~~~

.. autofunction:: pytket.extensions.cutensornet.structured_state.simulate

.. autoenum:: pytket.extensions.cutensornet.structured_state.SimulationAlgorithm()
:members:

.. autoclass:: pytket.extensions.cutensornet.structured_state.Config()

.. automethod:: __init__


Classes
~~~~~~~

.. autoclass:: pytket.extensions.cutensornet.structured_state.StructuredState()

.. automethod:: is_valid
.. automethod:: apply_gate
.. automethod:: apply_unitary
.. automethod:: apply_scalar
.. automethod:: vdot
.. automethod:: sample
.. automethod:: measure
.. automethod:: postselect
.. automethod:: expectation_value
.. automethod:: get_fidelity
.. automethod:: get_statevector
.. automethod:: get_amplitude
.. automethod:: get_qubits
.. automethod:: get_byte_size
.. automethod:: get_device_id
.. automethod:: update_libhandle
.. automethod:: copy

.. autoclass:: pytket.extensions.cutensornet.structured_state.TTNxGate()

.. automethod:: __init__

.. autoclass:: pytket.extensions.cutensornet.structured_state.MPSxGate()

.. automethod:: __init__
.. automethod:: add_qubit

.. autoclass:: pytket.extensions.cutensornet.structured_state.MPSxMPO()

.. automethod:: __init__
.. automethod:: add_qubit


Miscellaneous
~~~~~~~~~~~~~

.. autofunction:: pytket.extensions.cutensornet.structured_state.prepare_circuit_mps
Structured state evolution
==========================

.. automodule:: pytket.extensions.cutensornet.structured_state


Simulation
~~~~~~~~~~

.. autofunction:: pytket.extensions.cutensornet.structured_state.simulate

.. autoenum:: pytket.extensions.cutensornet.structured_state.SimulationAlgorithm()
:members:

.. autoclass:: pytket.extensions.cutensornet.structured_state.Config()

.. automethod:: __init__


Classes
~~~~~~~

.. autoclass:: pytket.extensions.cutensornet.structured_state.StructuredState()

.. automethod:: is_valid
.. automethod:: apply_gate
.. automethod:: apply_unitary
.. automethod:: apply_scalar
.. automethod:: vdot
.. automethod:: sample
.. automethod:: measure
.. automethod:: postselect
.. automethod:: expectation_value
.. automethod:: get_fidelity
.. automethod:: get_statevector
.. automethod:: get_amplitude
.. automethod:: get_qubits
.. automethod:: get_byte_size
.. automethod:: get_device_id
.. automethod:: update_libhandle
.. automethod:: copy

.. autoclass:: pytket.extensions.cutensornet.structured_state.TTNxGate()

.. automethod:: __init__

.. autoclass:: pytket.extensions.cutensornet.structured_state.MPSxGate()

.. automethod:: __init__
.. automethod:: add_qubit

.. autoclass:: pytket.extensions.cutensornet.structured_state.MPSxMPO()

.. automethod:: __init__
.. automethod:: add_qubit


Miscellaneous
~~~~~~~~~~~~~

.. autofunction:: pytket.extensions.cutensornet.structured_state.prepare_circuit_mps
18 changes: 9 additions & 9 deletions examples/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Contents

Available tutorials for users:
* `mps_tutorial.ipynb`: Use of MPS simulation and features.
* `ttn_tutorial.ipynb`: Use of TTN simulation and features.
* `mpi/`: Example on how to use MPS for embarrasingly parallel tasks with `mpi4py` see the `mpi` folder.

Developers:
* `check-examples`: The script to check that the Jupyter notebooks are generated correctly from the files in `python/`. To generate the `.ipynb` from these run the `p2j` command in this script.
# Contents

Available tutorials for users:
* `mps_tutorial.ipynb`: Use of MPS simulation and features.
* `ttn_tutorial.ipynb`: Use of TTN simulation and features.
* `mpi/`: Example on how to use MPS for embarrasingly parallel tasks with `mpi4py` see the `mpi` folder.

Developers:
* `check-examples`: The script to check that the Jupyter notebooks are generated correctly from the files in `python/`. To generate the `.ipynb` from these run the `p2j` command in this script.
* `python/`: The `.py` files that generate the `.ipynb` files. As a developer, you are expected to update these files instead of the `.ipynb` files. Remember to generate the latter using the `p2j` command before opening a pull request that changes these examples.
236 changes: 118 additions & 118 deletions pytket/extensions/cutensornet/general.py
Original file line number Diff line number Diff line change
@@ -1,118 +1,118 @@
# Copyright 2019-2024 Quantinuum
#
# 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.
from __future__ import annotations # type: ignore
import warnings
import logging
from logging import Logger

from typing import Any, Optional

try:
import cupy as cp # type: ignore
except ImportError:
warnings.warn("local settings failed to import cupy", ImportWarning)
try:
import cuquantum.cutensornet as cutn # type: ignore
except ImportError:
warnings.warn("local settings failed to import cutensornet", ImportWarning)


class CuTensorNetHandle:
"""Initialise the cuTensorNet library with automatic workspace memory
management.
Note:
Always use as ``with CuTensorNetHandle() as libhandle:`` so that cuTensorNet
handles are automatically destroyed at the end of execution.
Attributes:
handle (int): The cuTensorNet library handle created by this initialisation.
device_id (int): The ID of the device (GPU) where cuTensorNet is initialised.
If not provided, defaults to ``cp.cuda.Device()``.
"""

def __init__(self, device_id: Optional[int] = None):
self._is_destroyed = False

# Make sure CuPy uses the specified device
dev = cp.cuda.Device(device_id)
dev.use()

self.dev = dev
self.device_id = dev.id

self._handle = cutn.create()

@property
def handle(self) -> Any:
if self._is_destroyed:
raise RuntimeError(
"The cuTensorNet library handle is out of scope.",
"See the documentation of CuTensorNetHandle.",
)
return self._handle

def destroy(self) -> None:
"""Destroys the memory handle, releasing memory.
Only call this method if you are initialising a ``CuTensorNetHandle`` outside
a ``with CuTensorNetHandle() as libhandle`` statement.
"""
cutn.destroy(self._handle)
self._is_destroyed = True

def __enter__(self) -> CuTensorNetHandle:
return self

def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None:
self.destroy()

def print_device_properties(self, logger: Logger) -> None:
"""Prints local GPU properties."""
device_props = cp.cuda.runtime.getDeviceProperties(self.dev.id)
logger.debug("===== device info ======")
logger.debug("GPU-name:", device_props["name"].decode())
logger.debug("GPU-clock:", device_props["clockRate"])
logger.debug("GPU-memoryClock:", device_props["memoryClockRate"])
logger.debug("GPU-nSM:", device_props["multiProcessorCount"])
logger.debug("GPU-major:", device_props["major"])
logger.debug("GPU-minor:", device_props["minor"])
logger.debug("========================")


def set_logger(
logger_name: str,
level: int = logging.WARNING,
fmt: str = "[%(asctime)s.%(msecs)03d] %(name)s (%(levelname)s) - %(message)s",
) -> Logger:
"""Initialises and configures a logger object.
Args:
logger_name: Name for the logger object.
level: Logger output level.
fmt: Logger output format.
Returns:
New configured logger object.
"""
logger = logging.getLogger(logger_name)
logger.setLevel(level)
logger.propagate = False
if not logger.handlers:
handler = logging.StreamHandler()
handler.setLevel(level)
formatter = logging.Formatter(fmt, datefmt="%H:%M:%S")
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
# Copyright 2019-2024 Quantinuum
#
# 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.
from __future__ import annotations # type: ignore
import warnings
import logging
from logging import Logger

from typing import Any, Optional

try:
import cupy as cp # type: ignore
except ImportError:
warnings.warn("local settings failed to import cupy", ImportWarning)
try:
import cuquantum.cutensornet as cutn # type: ignore
except ImportError:
warnings.warn("local settings failed to import cutensornet", ImportWarning)


class CuTensorNetHandle:
"""Initialise the cuTensorNet library with automatic workspace memory
management.
Note:
Always use as ``with CuTensorNetHandle() as libhandle:`` so that cuTensorNet
handles are automatically destroyed at the end of execution.
Attributes:
handle (int): The cuTensorNet library handle created by this initialisation.
device_id (int): The ID of the device (GPU) where cuTensorNet is initialised.
If not provided, defaults to ``cp.cuda.Device()``.
"""

def __init__(self, device_id: Optional[int] = None):
self._is_destroyed = False

# Make sure CuPy uses the specified device
dev = cp.cuda.Device(device_id)
dev.use()

self.dev = dev
self.device_id = dev.id

self._handle = cutn.create()

@property
def handle(self) -> Any:
if self._is_destroyed:
raise RuntimeError(
"The cuTensorNet library handle is out of scope.",
"See the documentation of CuTensorNetHandle.",
)
return self._handle

def destroy(self) -> None:
"""Destroys the memory handle, releasing memory.
Only call this method if you are initialising a ``CuTensorNetHandle`` outside
a ``with CuTensorNetHandle() as libhandle`` statement.
"""
cutn.destroy(self._handle)
self._is_destroyed = True

def __enter__(self) -> CuTensorNetHandle:
return self

def __exit__(self, exc_type: Any, exc_value: Any, exc_tb: Any) -> None:
self.destroy()

def print_device_properties(self, logger: Logger) -> None:
"""Prints local GPU properties."""
device_props = cp.cuda.runtime.getDeviceProperties(self.dev.id)
logger.debug("===== device info ======")
logger.debug("GPU-name:", device_props["name"].decode())
logger.debug("GPU-clock:", device_props["clockRate"])
logger.debug("GPU-memoryClock:", device_props["memoryClockRate"])
logger.debug("GPU-nSM:", device_props["multiProcessorCount"])
logger.debug("GPU-major:", device_props["major"])
logger.debug("GPU-minor:", device_props["minor"])
logger.debug("========================")


def set_logger(
logger_name: str,
level: int = logging.WARNING,
fmt: str = "[%(asctime)s.%(msecs)03d] %(name)s (%(levelname)s) - %(message)s",
) -> Logger:
"""Initialises and configures a logger object.
Args:
logger_name: Name for the logger object.
level: Logger output level.
fmt: Logger output format.
Returns:
New configured logger object.
"""
logger = logging.getLogger(logger_name)
logger.setLevel(level)
logger.propagate = False
if not logger.handlers:
handler = logging.StreamHandler()
handler.setLevel(level)
formatter = logging.Formatter(fmt, datefmt="%H:%M:%S")
handler.setFormatter(formatter)
logger.addHandler(handler)
return logger
Loading

0 comments on commit 827e270

Please sign in to comment.