Skip to content

Commit 82b2da2

Browse files
frankharkinsmrossinekCryorismtreinish
authored
Make C API docs publishable (#14101)
* Get C API docs building Co-authored-by: Max Rossmannek <rmax@ethz.ch> Co-authored-by: Julien Gacon <jul@zurich.ibm.com> * Separate `docs` from `docs-c` in `tox.ini` * Move each group to its own page * Reorganise docs page layout * Fix some group namings * Get enums working * Update tox docs-clean * Add exit codes page * Add "Data types" heading * Update docs/cdoc/index.rst Co-authored-by: Matthew Treinish <mtreinish@kortar.org> * QkObs docs and nits * add bit term note that the Members section should be updated to match doxygen's enum style before merging, the table is a placeholder * Re-format index RST * update members * iterating on layout * better enums (follow Glib style because it looks great) * fix linebreaks * minor fixes (brackets, missing whitespace) * try fix tables * Fix RST formatting quirks * Install doxygen in CI * document exit codes * rm trailing ] * more enum work * Fix table * QkExitCode and remove rustdoc links * Rename exit codes page * Update docs/cdoc/index.rst Co-authored-by: Julien Gacon <gaconju@gmail.com> * Fix xrefs and toc * Fix CI? * Remove bad xrefs * Update docs/cdoc/qk-obs.rst * Document doxygen is required for docs builds now --------- Co-authored-by: Max Rossmannek <rmax@ethz.ch> Co-authored-by: Julien Gacon <jul@zurich.ibm.com> Co-authored-by: Matthew Treinish <mtreinish@kortar.org> Co-authored-by: Julien Gacon <jules.gacon@googlemail.com> Co-authored-by: Julien Gacon <gaconju@gmail.com>
1 parent 8c21753 commit 82b2da2

16 files changed

Lines changed: 509 additions & 19 deletions

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ qiskit/quantum_info/states/cython/*.cpp
141141
/docs/_build
142142
/docs/stubs
143143
/docs/locale
144+
/docs/xml
144145
/executed_tutorials
145146

146147
# Notebook testing images

CONTRIBUTING.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -788,6 +788,10 @@ tox -e docs
788788
The documentation output will be located at `docs/_build/html`.
789789
Open the `index.html` file there in your browser to find the main page.
790790

791+
To build the documentation you will need to have Doxygen installed and in
792+
your PATH environment variable as tox will run `doxygen` to build the API
793+
documentation for the C API. You can download doxygen from [here](https://www.doxygen.nl/download.html).
794+
791795
### Troubleshooting docs builds
792796

793797
When you build documentation, you might get errors that look like

crates/cext/src/exit_codes.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,12 +27,19 @@ pub enum CInputError {
2727
/// Integer exit codes returned to C.
2828
#[repr(u32)]
2929
pub enum ExitCode {
30-
Success = 0, // these need to be fixed for backward compat
30+
/// Success.
31+
Success = 0,
32+
/// Error related to data input.
3133
CInputError = 100,
34+
/// Unexpected null pointer.
3235
NullPointerError = 101,
36+
/// Pointer is not aligned to expected data.
3337
AlignmentError = 102,
38+
/// Index out of bounds.
3439
IndexError = 103,
40+
/// Error related to arithmetic operations or similar.
3541
ArithmeticError = 200,
42+
/// Mismatching number of qubits.
3643
MismatchedQubits = 201,
3744
}
3845

crates/cext/src/sparse_observable.rs

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,7 @@ use pyo3::{Py, Python};
2424
#[cfg(feature = "python_binding")]
2525
use qiskit_accelerate::sparse_observable::PySparseObservable;
2626

27-
/// @ingroup QkObsTerm
28-
/// A term in a [SparseObservable].
27+
/// A term in a ``QkObs``.
2928
///
3029
/// This contains the coefficient (``coeff``), the number of qubits of the observable
3130
/// (``num_qubits``) and pointers to the ``bit_terms`` and ``indices`` arrays, which have
@@ -34,14 +33,19 @@ use qiskit_accelerate::sparse_observable::PySparseObservable;
3433
///
3534
/// # Safety
3635
///
37-
/// * ``bit_terms`` must be a non-null, aligned pointer to ``len`` elements of type ``BitTerm``.
36+
/// * ``bit_terms`` must be a non-null, aligned pointer to ``len`` elements of type ``QkBitTerm``.
3837
/// * ``indices`` must be a non-null, aligned pointer to ``len`` elements of type ``uint32_t``.
3938
#[repr(C)]
4039
pub struct CSparseTerm {
40+
/// The coefficient of the observable term.
4141
coeff: Complex64,
42+
/// Length of the ``bit_terms`` and ``indices`` arrays.
4243
len: usize,
44+
/// A non-null, aligned pointer to ``len`` elements of type ``QkBitTerm``.
4345
bit_terms: *mut BitTerm,
46+
/// A non-null, aligned pointer to ``len`` elements of type ``uint32_t``.
4447
indices: *mut u32,
48+
/// The number of qubits the observable term is defined on.
4549
num_qubits: u32,
4650
}
4751

@@ -228,8 +232,7 @@ pub unsafe extern "C" fn qk_obs_new(
228232
///
229233
/// # Safety
230234
///
231-
/// Behavior is undefined if ``obs`` is not either null or a valid pointer to a
232-
/// [SparseObservable].
235+
/// Behavior is undefined if ``obs`` is not either null or a valid pointer to a ``QkObs``.
233236
#[no_mangle]
234237
#[cfg(feature = "cbinding")]
235238
pub unsafe extern "C" fn qk_obs_free(obs: *mut SparseObservable) {
@@ -296,14 +299,14 @@ pub unsafe extern "C" fn qk_obs_add_term(
296299
/// @ingroup QkObs
297300
/// Get an observable term by reference.
298301
///
299-
/// A [CSparseTerm] contains pointers to the indices and bit terms in the term, which
302+
/// A ``QkObsTerm`` contains pointers to the indices and bit terms in the term, which
300303
/// can be used to modify the internal data of the observable. This can leave the observable
301304
/// in an incoherent state and should be avoided, unless great care is taken. It is generally
302305
/// safer to construct a new observable instead of attempting in-place modifications.
303306
///
304307
/// @param obs A pointer to the observable.
305308
/// @param index The index of the term to get.
306-
/// @param out A pointer to a [CSparseTerm] used to return the observable term.
309+
/// @param out A pointer to a ``QkObsTerm`` used to return the observable term.
307310
///
308311
/// @return An exit code.
309312
///
@@ -821,9 +824,9 @@ pub unsafe extern "C" fn qk_obs_equal(
821824
}
822825

823826
/// @ingroup QkObs
824-
/// Return a string representation of a ``SparseObservable``.
827+
/// Return a string representation of a ``QkObs``.
825828
///
826-
/// @param obs A pointer to the ``SparseObservable`` to get the string for.
829+
/// @param obs A pointer to the ``QkObs`` to get the string for.
827830
///
828831
/// @return A pointer to a nul-terminated char array of the string representation for ``obs``
829832
///
@@ -920,7 +923,7 @@ pub unsafe extern "C" fn qk_obsterm_str(term: *const CSparseTerm) -> *mut c_char
920923
///
921924
/// # Safety
922925
///
923-
/// The behavior is undefined if ``bit_term`` is not a valid ``uint8_t`` value of a [BitTerm].
926+
/// The behavior is undefined if ``bit_term`` is not a valid ``uint8_t`` value of a ``QkBitTerm``.
924927
#[no_mangle]
925928
#[cfg(feature = "cbinding")]
926929
pub extern "C" fn qk_bitterm_label(bit_term: BitTerm) -> u8 {
@@ -933,12 +936,12 @@ pub extern "C" fn qk_bitterm_label(bit_term: BitTerm) -> u8 {
933936
.expect("Label has exactly one character") as u8
934937
}
935938

936-
/// @ingroup SparseObservable
937-
/// Convert to a Python-space [PySparseObservable].
939+
/// @ingroup QkObs
940+
/// Convert to a Python-space ``SparseObservable``.
938941
///
939-
/// @param obs The C-space [SparseObservable] pointer.
942+
/// @param obs The C-space ``QkObs`` pointer.
940943
///
941-
/// @return A Python object representing the [PySparseObservable].
944+
/// @return A Python object representing the ``SparseObservable``.
942945
///
943946
/// # Safety
944947
///

docs/Doxyfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
INPUT = docs/cdoc/ dist/c/include/qiskit.h
2+
3+
4+
EXTRACT_ALL = YES
5+
6+
GENERATE_XML = YES
7+
XML_OUTPUT = docs/xml
8+
PREDEFINED = QISKIT_C_PYTHON_INTERFACE=1
9+
10+
GENERATE_HTML = NO
11+
GENERATE_LATEX = NO

docs/cdoc/index.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/**
2+
* @defgroup QkObs QkObs
3+
*/
4+
5+
/**
6+
* @defgroup QkObsTerm QkObsTerm
7+
*/
8+
9+
/**
10+
* @defgroup QkBitTerm QkBitTerm
11+
*/

docs/cdoc/index.rst

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
===========================
2+
Qiskit C API (``qiskit.h``)
3+
===========================
4+
5+
The Qiskit C API is a low level interface to the core data model of Qiskit. It
6+
is designed to provide a high performance interface to Qiskit for compiled
7+
languages and provides a defined ABI to the internal Rust data model that is
8+
used to create the Python API. There are two expected modes of operation for
9+
the C API:
10+
11+
* A standalone shared library for creating and working with Qiskit objects from
12+
compiled languages without a runtime dependency on Python, and
13+
* For building Python extensions that are using Qiskit but interface directly
14+
with the Rust objects from the extension code without using Python for better
15+
performance.
16+
17+
To get started, see `Install the Qiskit C API <https://docs.quantum.ibm.com/guides/install-c-api>`_.
18+
To combine the C API with custom Python extensions, see
19+
`Extend Qiskit in Python with C <https://docs.quantum.ibm.com/guides/c-extension-for-python>`_.
20+
21+
As this interface is still new in Qiskit it should be considered experimental
22+
and the interface might change between minor version releases.
23+
24+
-------------------
25+
Quantum information
26+
-------------------
27+
28+
.. toctree::
29+
:maxdepth: 1
30+
31+
qk-obs
32+
qk-obs-term
33+
qk-bit-term
34+
qk-exit-code

docs/cdoc/qk-bit-term.rst

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
=========
2+
QkBitTerm
3+
=========
4+
5+
..
6+
This is documented manually here because the C-space `enum` is generated
7+
programmatically from Rust and is not the correct C-level documentation.
8+
9+
.. code-block:: c
10+
11+
enum QkBitTerm
12+
13+
An enum that to represent each of the single-qubit alphabet terms enumerated below.
14+
15+
Values
16+
------
17+
18+
* ``QkBitTerm_X``
19+
The Pauli :math:`X` operator.
20+
21+
Value: 2 (``0b0010``)
22+
23+
* ``QkBitTerm_Y``
24+
The Pauli :math:`Y` operator.
25+
26+
Value: 3 (``0b0011``)
27+
28+
* ``QkBitTerm_Z``
29+
The Pauli :math:`Z` operator.
30+
31+
Value: 1 (``0b0001``)
32+
33+
* ``QkBitTerm_Plus``
34+
The projector :math:`\lvert +\rangle\langle +\rvert` to the positive :math:`X` eigenstate.
35+
36+
Value: 10 (``0b1010``)
37+
38+
* ``QkBitTerm_Minus``
39+
The projector :math:`\lvert -\rangle\langle -\rvert` to the negative :math:`X` eigenstate.
40+
41+
Value: 6 (``0b0110``)
42+
43+
* ``QkBitTerm_Right``
44+
The projector :math:`\lvert r\rangle\langle r\rvert` to the positive :math:`Y` eigenstate.
45+
46+
Value: 11 (``0b1011``)
47+
48+
* ``QkBitTerm_Left``
49+
The projector :math:`\lvert l\rangle\langle l\rvert` to the negative :math:`Y` eigenstate.
50+
51+
Value: 7 (``0b1011``)
52+
53+
* ``QkBitTerm_Zero``
54+
The projector :math:`\lvert 0\rangle\langle 0\rvert` to the positive :math:`Z` eigenstate.
55+
56+
Value: 9 (``0b1001``)
57+
58+
* ``QkBitTerm_One``
59+
The projector :math:`\lvert 1\rangle\langle 1\rvert` to the negative :math:`Z` eigenstate.
60+
61+
Value: 5 (``0b0101``)
62+
63+
Representation
64+
--------------
65+
66+
The enum is stored as single byte, its elements are represented as unsigned 8-bit integer.
67+
68+
.. code-block:: c
69+
70+
typedef uint8_t QkBitTerm
71+
72+
.. warning::
73+
74+
Not all ``uint8_t`` values are valid bit terms. Passing invalid values is undefined behavior.
75+
76+
The numeric structure of these is that they are all four-bit values of which the low two
77+
bits are the (phase-less) symplectic representation of the Pauli operator related to the
78+
object, where the low bit denotes a contribution by :math:`Z` and the second lowest a
79+
contribution by :math:`X`, while the upper two bits are ``00`` for a Pauli operator, ``01``
80+
for the negative-eigenstate projector, and ``10`` for the positive-eigenstate projector.
81+
82+
Functions
83+
---------
84+
85+
.. doxygengroup:: QkBitTerm
86+
:content-only:

docs/cdoc/qk-exit-code.rst

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
==========
2+
QkExitCode
3+
==========
4+
5+
.. code-block:: c
6+
7+
enum QkExitCode
8+
9+
Function exit codes.
10+
11+
Values
12+
------
13+
14+
* ``QkExitCode_Success``
15+
Success.
16+
17+
Value: 0
18+
19+
* ``QkExitCode_CInputError``
20+
Error related to data input.
21+
22+
Value: 100
23+
24+
* ``QkExitCode_NullPointerError``
25+
Unexpected null pointer.
26+
27+
Value: 101
28+
29+
* ``QkExitCode_AlignmentError``
30+
Pointer is not aligned to expected data.
31+
32+
Value: 102
33+
34+
* ``QkExitCode_IndexError``
35+
Index out of bounds.
36+
37+
Value: 103
38+
39+
* ``QkExitCode_ArithmeticError``
40+
Error related to arithmetic operations or similar.
41+
42+
Value: 200
43+
44+
* ``QkExitCode_MismatchedQubits``
45+
Mismatching number of qubits.
46+
47+
Value: 201

docs/cdoc/qk-obs-term.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
=========
2+
QkObsTerm
3+
=========
4+
5+
This is a group of functions for interacting with an opaque (Rust-space)
6+
SparseTerm instance.
7+
8+
----------
9+
Data types
10+
----------
11+
12+
.. doxygenstruct:: QkObsTerm
13+
:members:
14+
:undoc-members:
15+
16+
17+
---------
18+
Functions
19+
---------
20+
21+
.. doxygengroup:: QkObsTerm
22+
:content-only:

0 commit comments

Comments
 (0)