Skip to content

C and Python API

Implement a C and Python API for LibKet.

  1. A good documentation for writing C wrappers around C++ objects and methods is given here https://nachtimwald.com/2017/08/18/wrapping-c-objects-in-c/

    The C API should be inspired by the CUDA Runtime API, e.g.

    • qError_t qStreamCreate(qStream_t* pStream)
    • qError_t qStreamDestroy(qStream_t* stream)
    • qError_t qStreamQuery(qStream_t stream)
    • qError_t qStreamSynchronize(qStream_t stream)

    Since exceptions are not available in C all functions will return their status via qError_t, which like cudaError_t is implemented as enumerator

    enum qError
    {
       qSuccess = 0,
       qErrorInvalidValue = 1,
       qErrorNotYetImplemented = 31,
       qErrorNotReady = 300
    };
    typedef enum qError qError_t;

    For compatibility reasons, we try to use the same return codes if there exists a counterpart in CUDA.

    A first version of a possible C API is implemented in the directory c_api for the QJob and the QStream classes for demonstration purposes. Once we agreed on a stable API for filters, gates, and circuits, the corresponding C functions will be implemented. The overall idea is to let the C functions generate a string representation of the C++ expressions, which gets just-in-time compiled upon execution.

    Suggestions for the C API

    Consider the following C++ code snippet

    auto expr = cnot( 
                      range<3,5>(),
                      sel<0,1,2>(
                                 init()
                                )
                    );
    
    QData<6, QBackend::cQASMv1> data_cQASMv1;
    utils::json result = data_cQASMv1.execute();
    std::cout << result["histogram"] << std::endl;

    A possible C API could look as follows

    // Create a generic quantum expression object that will store the string representation internally and provides factory functions for all supported quantum gates and circuits
    qExpression_t* expr;
    assert (qExpressionCreate(expr) == qSuccess);
    
    // Create a generic quantum filter object
    qFilter_t* filter;
    assert (qFilterCreate(filter) == qSuccess);
    
    // Compose quantum expression
    expr.init();                  // apply init() to all qubits (default behavior); 
                                  // also possible expr.init(filter.all());
    expr.cnot(filter.range(3,5),  // apply cnot() to selected qubits
              filter.sel(0,1,2)
             );
    
    // Create quantum backend object
    qCQASMv1Backend_t* data;
    assert (qCQASMv1BackendCreate(data, 6) == qSuccess);
    
    // Create JSON result object
    qJSON_t* result;
    assert (qJSONCreate(result) == qSuccess);
    
    // Execute quantum expression on quantum backend
    assert (qCQASMv1BackendExecute(data, expr, result /*, possible JSON configuration */)
    
    // Destroy quantum expression object
    assert (qExpressionDestroy(expr) == qSuccess);
    
    // Destroy quantum backend object
    assert (qCQASMv1BackendDestroy(data) == qSuccess);
    
    // Destroy JSON result object
    assert (qJSONDestroy(result) == qSuccess);
  2. Based on the C API write a Python API using one of the following approaches

    Building on the C API the above C++ code snippet could be implemented as follows

    >>> try:
    ...     expr   = Expression()
    ...     filter = Filter()
    ...
    ...     expr.init()
    ...     expr.cnot(filter.range(3,5),
    ...               filter.sel(0,1,2))
    ...
    ...     data = Backend(6, "cQASMv1")
    ... except Exception as e:

    As in the C++ API, the Python methods throw exceptions of an error occurs.

Edited by Matthias Möller