Software

LibKet: Kwantum Expression Template Library

LibKet logo

The open-source expression template library LibKet makes it possible to develop quantum-accelerated scientific applications and test them on different gate-based quantum computing platforms like QuTech's Quantum Inspire, IBM's Quantum Experience and Rigetti's Quantum Cloud Services without the need to reimplement quantum algorithms in vendor-specific SDKs like Qiskit and PyQuil. LibKet is designed as C++14 expression template library that allows to formulate quantum algorithms as generic expressions, which are synthesized to backend-optimized quantum kernels that can be executed in quantum simulators and cloud-based quantum computers. Next to the basic quantum gates, LibKet comes with a growing collection of customizable quantum algorithms and building blocks like the Quantum Fourier transformation (QFT) that simplify the development of quantum-accelerated applications.

The following code snippet shows how to generate the quantum kernel for an n-qubit QFT and execute it first on the Quantum Inspire simulator platform using 6-qubits and then on IBM's Quantum Experience cloud service using one of the 5-qubit quantum processors:

            #include <LibKet.hpp>

using namespace LibKet;
using namespace LibKet::circuits;
using namespace LibKet::filters;
using namespace LibKet::gates;

// Create generic quantum expression
auto expr = qft(init());

// Execute QFT<6> on Quantum-Inspire platform
try {
  QDevice<QDeviceType::qi_26_simulator, 6> qi; qi(expr);
  utils::json result = qi.execute();
                      
  QInfo << result << std::endl;

  QInfo << "job ID     : " << qi.get<QResultType::id>(result)               << std::endl;
  QInfo << "time stamp : " << qi.get<QResultType::timestamp>(result)        << std::endl;
  QInfo << "duration   : " << qi.get<QResultType::duration>(result).count() << std::endl;
  QInfo << "best       : " << qi.get<QResultType::best>(result)             << std::endl;
  QInfo << "histogram  : " << qi.get<QResultType::histogram>(result)        << std::endl;
                                         
} catch(const std::exception &e) {
  QWarn << e.what() << std::endl;
}

// Execute QFT<5> on IBM Quantum Experience platform
try {
  QDevice<QDeviceType::ibmq_5_london, 5> ibmq; ibmq(expr);
  utils::json result = ibmq.execute();
                       
  QInfo << result << std::endl;

  QInfo << "job ID     : " << qi.get<QResultType::id>(result)               << std::endl;
  QInfo << "time stamp : " << qi.get<QResultType::timestamp>(result)        << std::endl;
  QInfo << "duration   : " << qi.get<QResultType::duration>(result).count() << std::endl;
  QInfo << "best       : " << qi.get<QResultType::best>(result)             << std::endl;
  QInfo << "histogram  : " << qi.get<QResultType::histogram>(result)        << std::endl;
                                                                                                                                           
} catch(const std::exception &e) {
  QWarn << e.what() << std::endl;
}
          
The result JSON object holds the raw data received from the quantum backend, whose format differs from one backend to the other making it difficult to write portable code. The result from executing the 6-qubit QFT on the Quantum Inspire platform reads:
            {"calibration":null,"created_at":"2020-04-24T07:56:51.811632Z","execution_time_in_seconds":24.595468044281,"histogram":{"0":0.0126953125,"1":0.0205078125,"10":0.01953125,"11":0.0146484375,"12":0.013671875,"13":0.01953125,"14":0.0068359375,"15":0.0126953125,"16":0.0185546875,"17":0.0146484375,"18":0.0166015625,"19":0.025390625,"2":0.0205078125,"20":0.0166015625,"21":0.0107421875,"22":0.015625,"23":0.0146484375,"24":0.013671875,"25":0.0185546875,"26":0.0126953125,"27":0.021484375,"28":0.017578125,"29":0.01953125,"3":0.015625,"30":0.017578125,"31":0.0087890625,"32":0.0126953125,"33":0.017578125,"34":0.0126953125,"35":0.013671875,"36":0.01953125,"37":0.013671875,"38":0.0146484375,"39":0.0166015625,"4":0.01171875,"40":0.017578125,"41":0.0185546875,"42":0.0166015625,"43":0.017578125,"44":0.0166015625,"45":0.0166015625,"46":0.017578125,"47":0.0126953125,"48":0.0166015625,"49":0.0078125,"5":0.0107421875,"50":0.009765625,"51":0.0185546875,"52":0.0185546875,"53":0.0205078125,"54":0.01171875,"55":0.0126953125,"56":0.01953125,"57":0.0166015625,"58":0.0126953125,"59":0.01171875,"6":0.0166015625,"60":0.0205078125,"61":0.0087890625,"62":0.013671875,"63":0.0166015625,"7":0.013671875,"8":0.0185546875,"9":0.0185546875},"histogram_url":"https://api.quantum-inspire.com/results/6778649/histogram/c1ae5d30ca07c579d24c01cdd3e367ff74089e075544c500ca0ebc815e67f86d/","id":6778649,"job":"https://api.quantum-inspire.com/jobs/6781372/","measurement_mask":0,"measurement_register_url":"https://api.quantum-inspire.com/results/6778649/measurement-register/c1ae5d30ca07c579d24c01cdd3e367ff74089e075544c500ca0ebc815e67f86d/","number_of_qubits":6,"quantum_states_url":"https://api.quantum-inspire.com/results/6778649/quantum-states/c1ae5d30ca07c579d24c01cdd3e367ff74089e075544c500ca0ebc815e67f86d/","raw_data_url":"https://api.quantum-inspire.com/results/6778649/raw-data/c1ae5d30ca07c579d24c01cdd3e367ff74089e075544c500ca0ebc815e67f86d/","raw_text":"","url":"https://api.quantum-inspire.com/results/6778649/"}
          
With the aid of LibKet's commodity functions, relevant data fields such as the state with highest probability (QResultType::best) or the duration of the quantum kernel execution (QResultType::duraction) as reported by the backend can be accessed in a unified way and in terms of C++ data types that can be processed further:
            job ID     : 6778649
time stamp : 1587707811
duration   : 24.5955
best       : 19
histogram  : 0.012695312500000000,0.020507812500000000,0.020507812500000000,0.015625000000000000,0.011718750000000000,0.010742187500000000,0.016601562500000000,0.013671875000000000,0.018554687500000000,0.018554687500000000,0.019531250000000000,0.014648437500000000,0.013671875000000000,0.019531250000000000,0.006835937500000000,0.012695312500000000,0.018554687500000000,0.014648437500000000,0.016601562500000000,0.025390625000000000,0.016601562500000000,0.010742187500000000,0.015625000000000000,0.014648437500000000,0.013671875000000000,0.018554687500000000,0.012695312500000000,0.021484375000000000,0.017578125000000000,0.019531250000000000,0.017578125000000000,0.008789062500000000,0.012695312500000000,0.017578125000000000,0.012695312500000000,0.013671875000000000,0.019531250000000000,0.013671875000000000,0.014648437500000000,0.016601562500000000,0.017578125000000000,0.018554687500000000,0.016601562500000000,0.017578125000000000,0.016601562500000000,0.016601562500000000,0.017578125000000000,0.012695312500000000,0.016601562500000000,0.007812500000000000,0.009765625000000000,0.018554687500000000,0.018554687500000000,0.020507812500000000,0.011718750000000000,0.012695312500000000,0.019531250000000000,0.016601562500000000,0.012695312500000000,0.011718750000000000,0.020507812500000000,0.008789062500000000,0.013671875000000000,0.016601562500000000
          
Further features of LibKet are demonstrated in a forthcoming paper

Contributors

Tim Driebergen (TU Delft), Mike van der Lans (TU Delft), Kelvin Loh (TNO Delft), Menno Looman (TU Delft), Merel Schalkers (TU Delft), Otmar Ubbens (TU Delft), Richard Versluis (TNO Delft)

News

Selected contributions

  • Koen Mesman, Zaid Al-Ars, and Matthias Möller. Qpack: Quantum approximate optimization algorithms as universal benchmark for quantum computers, 2021. [ arXiv ]
  • Matthias Möller and Merel Schalkers. Libket: A cross-platform programming framework for quantum-accelerated scientific computing. In Valeria V. Krzhizhanovskaya, Gábor Závodszky, Michael H. Lees, Jack J. Dongarra, Peter M. A. Sloot, Sérgio Brissos, and João Teixeira, editors, Computational Science - ICCS 2020, pages 451--464, Cham, 2020. Springer International Publishing. [ DOI | http ]