- Квантовые исследования
- Блог
Дата
22 октября 2026 г.
Авторы
Команда Qiskit
Основные положения:
- Qiskit SDK v2.6 — это выпуск, ориентированный на C API, который предоставляет компилируемым языкам инфраструктуру менеджер-проходов компилятора, сериализацию QPY и пользовательские операции.
- Новая инфраструктура менеджера проходов на C API позволяет писать пользовательские проходы компилятора и транслировать («lower») схемы через несколько промежуточных представлений с проверкой типов.
- Сериализация QPY теперь доступна в C API, что позволяет программам на других языках, включая C, C++ и Julia, сохранять и обмениваться схемами, совместимыми с qiskit.qpy в Python.
- Вы можете определять пользовательские квантовые операции, включая аппаратные нативные гейты, напрямую из C API без объектной модели Python.
- Qiskit v2.6 продвигает вперед возможность использования C API в средах, где Python не установлен.
- Формат QPY версии 18 теперь используется по умолчанию и уменьшает размер сериализованных схем; минимальная версия Python остается 3.10, для сборки из исходного кода требуется Rust 1.89.
Мы рады объявить о выпуске Qiskit SDK v2.6! Последний минорный выпуск в серии v2.x продолжает наши усилия по укреплению базовой инфраструктуры SDK, делая ее более быстродействующей, расширяемой и мощной в качестве высокопроизводительного компилятора для квантовых вычислений.
Главной темой недавних выпусков стала эволюция Qiskit за пределы Python: его высокопроизводительное ядро на Rust предоставляется через C API, который взаимодействует практически с любым языком и открывает двери для тесно связанных рабочих процессов квантово-центричных суперкомпьютеров (QCSC), востребованных в средах HPC. Qiskit v2.6 — это прежде всего выпуск C API: он приносит в C API инфраструктуру менеджера проходов компилятора, сериализацию QPY и пользовательские операции, а также продолжает закулисную работу по обеспечению возможности использования C API без установленного Python.
Эти возможности — больше, чем просто удобство для пользователей, не работающих с Python. Компилятор, который транслирует программу через несколько промежуточных представлений, формат сериализации, перемещающий схемы между языками и системами, и модель выполнения, которая дает композитное управление в руки пользователя — все это является базовой основой для того, что будет дальше.
Эта работа закладывает фундамент для будущих задач QCSC и отказоустойчивых вычислений, в то время как Qiskit продолжает приносить реальную пользу для задач ближайшего будущего уже сегодня. Qiskit создается как производительный программный стек, к которому пользователи обращаются во всем этом спектре — не только для текущих задач, где он уже приносит реальную пользу, но и для конвейеров с коррекцией ошибок.
Краткое содержание (TL;DR)
Qiskit SDK v2.6 — это выпуск, сфокусированный на C API. Предыдущие выпуски давали пользователям C API возможность создавать схемы и запускать их через транспайлер Qiskit; версия 2.6 дает им гораздо больше контроля — настраиваемую, расширяемую инфраструктуру менеджера проходов (включая трансляцию через несколько IR), сериализацию QPY и возможность определять собственные операции — и все это без Python. Основные моменты включают:
- Новая инфраструктура менеджера проходов в C API. Теперь вы можете писать и выполнять проходы компилятора напрямую из C, а также транслировать программу через несколько промежуточных представлений (IR) с помощью конвейеров с проверкой типов и поддержкой разных языков.
- Сериализация QPY в C API. Портативный бинарный формат схем Qiskit теперь может записываться и читаться из C, работая с нативными схемами без необходимости обратного преобразования в Python и оставаясь совместимым с QPY, созданным в Python.
- Пользовательские операции, определяемые из C. Теперь вы можете полностью определять квантовые операции непосредственно из C API и добавлять их в любую схему.
- Продолжение работы над тем, чтобы сделать Python опциональным. Закулисная работа приближает автономную библиотеку C к запуску без установленного Python — это шаг к тому, например, чтобы позволить пользователям Julia-on-Windows запускать Qiskit.
- Новая версия формата QPY (v18). В версии 2.6 в формат QPY внесен ряд улучшений (см. раздел «Рекомендации по обновлению»).
Главные новые функции и улучшения
Новая инфраструктура менеджера проходов в C API
Qiskit v2.6 представляет универсальную инфраструктуру менеджера проходов в C API. Пользователи C API уже могли запускать предустановленный конвейер транспапиляции Qiskit; теперь они могут создавать свои собственные, создавая отдельные проходы компилятора и объединяя их в пользовательские менеджеры проходов, и все это из компилируемых языков.
Новый объект QkPassManager управляет выполнением. Он может наполняться объектами QkPass с помощью qk_passmanager_push_pass и запускаться с помощью qk_passmanager_run_simple; менеджер проходов и его проходы сообщают об ошибках через QkCompilationError. Функциональность прохода определяется с помощью таблицы виртуальных методов (QkPassVtable). Проходы объявляют свои входные и выходные IR с помощью QkIrHandle, который может описывать как динамически определяемый C IR, так и встроенный Qiskit IR (на сегодняшний день это QkCircuit и QkDag). Менеджер проходов использует эти дескрипторы для проверки конвейера, обеспечивая компиляционные конвейеры с проверкой типов.
Крайне важно, что это тот самый компонент, который позволяет транслировать программу через несколько IR: поскольку каждый проход объявляет тип IR, который он потребляет и производит, менеджер проходов может проверить правильность формирования многоэтапного конвейера трансляции, а расширения могут свободно определять свои собственные типы IR в дополнение к встроенным в Qiskit.
Это продолжает концепцию многопредставленческого компилятора, представленную в v2.5, привнося эту многоуровневую модель компилятора с последовательной трансляцией в C API. Это фундаментальный шаг к компилятору, который может переводить программу от высокоуровневого описания до специфичных для оборудования операций на разных уровнях оптимизации.
В примере ниже определяется пользовательский проход — в данном вызове он удаляет гейты, эквивалентные единичным, путем вызова существующей подпрограммы Qiskit, — регистрируется в таблице виртуальных методов и запускается на схеме через QkPassManager:
#include <qiskit.h> /// Структура для хранения конфигурации пасса. typedef struct { QkTarget *target; } RemoveIdentity; /// Выполнение пасса (или функция `run`). QkCircuit *run_remove_identity(RemoveIdentity *self, QkCircuit *ir, QkPassContext *context, QkCompilationError **error) { // В этой функции вы можете реализовать собственную логику. Здесь // мы вызываем предопределенную функцию Qiskit для удаления тождественных вентилей (identity). qk_transpiler_pass_standalone_remove_identity_equivalent(ir, self->target, 1.0); return ir; } /// Виртуальная таблица (vtable), определяющая пасс. static const QkVtableEntry remove_identity_slots[] = { {.slot = QkPassSlot_RunOwned, .ptr = run_remove_identity}, {.slot = -1, .ptr = NULL}, }; int main(void) { // Хскер (handle) для IR, на котором определен пасс. Он также может быть определен // как пользовательский IR; см. `qk_ir_handle_new`. QkIrHandle *ir = qk_ir_handle_builtin(QkIrBuiltin_Circuit); // Экземпляр виртуальной таблицы, которая также определяет имя и входной/выходной IR. QkPassVtable *vtable = qk_pass_vtable_new("remove_identity", ir, ir, remove_identity_slots); // Настройка пасса... QkTarget *target = qk_target_new(10); RemoveIdentity this = {target}; QkPass *pass = qk_pass_new((void *)&this, vtable); // ... и добавление его в менеджер пассов. QkPassManager *pm = qk_passmanager_new(); qk_passmanager_push_pass(pm, pass); // Теперь мы можем выполнить его для квантовой схемы. QkCircuit *circuit = qk_circuit_new(10, 0); uint32_t q0[1] = {0}; double almost_zero[1] = {1e-20}; double nonzero[1] = {1.23}; qk_circuit_gate(circuit, QkGate_H, q0, NULL); qk_circuit_gate(circuit, QkGate_RX, q0, almost_zero); qk_circuit_gate(circuit, QkGate_RZ, q0, nonzero); qk_circuit_gate(circuit, QkGate_H, q0, NULL); // примечание: Менеджер пассов принимает на себя владение входным IR, который больше // не нужно освобождать — требуется освобождать только выходной IR. QkCircuit *out = (QkCircuit *)qk_passmanager_run_simple(pm, (void *)circuit, ir, ir, NULL); qk_circuit_free(out); qk_target_free(target); qk_passmanager_free(pm); qk_pass_vtable_free(vtable); qk_ir_handle_free(ir); return 0; }
Пасс объявляет один и тот же встроенный IR (QkIrBuiltin_Circuit) как для входа, так и для выхода; пасс понижения (lowering pass), напротив, объявлял бы разные дескрипторы входного и выходного IR, а менеджер пассов проверял бы соответствие типов при переходе.
Сериализация QPY в C API
QPY — переносимый кроссплатформенный бинарный формат Qiskit для хранения квантовых схем — теперь доступен из C API. Множество объектов QkCircuit можно сериализовать в единый поток QPY, либо в буфер в памяти (qk_qpy_dump_buffer), либо в файл (qk_qpy_dump_file), используя варианты с суффиксом `*_with_version` для фиксации используемой версии QPY. Схемы можно загрузить обратно с помощью qk_qpy_load_file/qk_qpy_load_buffer. В Qiskit v2.6 также представлена версия формата QPY v18 (теперь являющаяся стандартной по умолчанию), которая уменьшает размер сериализованных схем.
Эти функции работают с нативными схемами без взаимодействия с Python, а производимые ими данные совместимы с интерфейсом `qiskit.qpy` в Python — поэтому схему, сериализованную из программы на C (или любого другого языка, вызывающего C API), можно загрузить в Python, и наоборот. (Если вы используете C API изнутри расширения Python, вам все равно следует использовать функции `qpy.dump`/`qpy.load` в Python; функции C возвращают ошибку, если для создания или загрузки полезной нагрузки требуется Python.)
Для пользователей компилируемых языков и систем высокопроизводительных вычислений (HPC) это открывает два конкретных сценария использования:
- Сохранение между запусками. QPY изначально разрабатывался для сохранения схем на диск и их повторной загрузки при последующем выполнении, однако до Qiskit v2.6 это было возможно только из Python. Теперь вы можете собрать и скомпилировать схему на C — или на другом компилируемом языке через его C FFI, таком как C++, Julia или Fortran — закэшировать ее на диске и перезагрузить при последующем запуске без необходимости задействовать интерпретатор Python.
- Отправка заданий. QPY — это также формат, который Qiskit использует для отправки схем на платформу IBM Quantum Platform. Предоставление к нему доступа через C API упрощает поддержку клиента qiskit-ibm-runtime-c, так как он может опираться на сам Qiskit в вопросах работы с QPY, вместо того чтобы переписывать формат заново. Это также делает написание собственного клиентского слоя на другом языке гораздо более практичным, если вы предпочитаете не зависеть от qk-ibm-runtime-c.
На практике сохранение скомпилированной схемы из программы на C сводится к одному вызову — а Python подхватывает ее с помощью уже имеющегося у него интерфейса QPY:
#include <stdio.h> // Предположим, что `qc` — это созданная вами ранее схема `QkCircuit *`. const QkCircuit *circuits[] = { qc }; // Сериализация одной или нескольких схем в один файл QPY. // Здесь мы передаем NULL для указателя на ошибку, но вы можете передать char**, чтобы // записать сообщение об ошибке в случае ее возникновения. QkExitCode result = qk_qpy_dump_file(circuits, 1, "circuits.qpy", NULL); if (result != QkExitCode_Success) { // Возвращает ошибку, если для сериализации полезной нагрузки требуется Python. fprintf(stderr, "Ошибка дампа QPY\n"); return 1; }
Затем, на этапе анализа в Python, файл загружается без каких-либо специальных манипуляций:
from qiskit import qpy with open("circuits.qpy", "rb") as f: circuits = qpy.load(f) # стандартный qiskit.qpy, ничем не отличается от любого другого файла .qpy
Определение пользовательских операций на C
Qiskit v2.6 позволяет определять собственные операции, включая пользовательские вентили, напрямую из C API. Пользовательские операции следуют тому же шаблону расширяемости, который используется во всем C API Qiskit. Точно так же, как пользовательские пассы и пользовательские IR в новом фреймворке менеджера пассов, функциональность QkCustomOp определяется виртуальной таблицей (vtable), состоящей из слотов QkVtableEntry. После определения вы можете добавить свою операцию в схему с помощью qk_circuit_custom_operation или в граф DAG с помощью qk_dag_apply_custom_operation.
Виртуальная таблица — это интерфейс, который модель данных Qiskit использует для работы с вашей операцией. В ней объявляется набор функций, которые Qiskit ожидает от операции и которые вы реализуете на C. Вы предоставляете набор слотов, определяющих поведение вашей операции, включая, помимо прочего, ее имя, количество кубитов, определение, является ли она унитарной, а также поведение проверки на равенство, клонирования и удаления.
Требуются только два слота: имя и количество кубитов, передаваемые через слоты QkCustomOpSlot_Name и QkCustomOpSlot_NumQubits. Остальные параметры — включая необязательные слоты для метки (label) или для пометки операции в качестве директивы — при пропуске возвращаются к разумным значениям по умолчанию. После этого схема работает с вашей операцией посредством динамического диспетчеризации, поэтому ей никогда не нужно знать конкретный тип вашей операции, и в то же время она может использовать ее точно так же, как любую встроенную операцию.
Полный и авторитетный список слотов см. в документации по QkCustomOp в нашей документации по C API.
Эта модель расширяемости позволяет внедрять высокопроизводительные аппаратные пользовательские вентили в схемы Qiskit без объектной модели Python. Например, вот пользовательский вентиль с именем foo, который содержит собственное количество кубитов, а его действие определяется как слой вентилей Адамара:
#include <stdlib.h> #include <string.h> #include <qiskit.h> typedef struct { uint32_t num_qubits; } FooGate; static const char *foo_name(const FooGate *gate) { (void)gate; // Unused. return "foo"; } static uint32_t foo_num_qubits(const FooGate *gate) { return gate->num_qubits; } static bool foo_eq(const FooGate *gate, const FooGate *other) { return (gate->num_qubits == other->num_qubits); } static FooGate *foo_clone(const FooGate *gate) { FooGate *out = malloc(sizeof(*out)); memcpy(out, gate, sizeof(*out)); return out; } /// The definition of the gate in terms of a `QkCircuit*`. Here the /// gate is defined by a simple layer of Hadamard gates. QkCircuit *foo_definition(const FooGate *gate, QkParam **params) { (void)params; // Unused. QkCircuit *def = qk_circuit_new(gate->num_qubits, 0); for (uint32_t i = 0; i < gate->num_qubits; i++) { qk_circuit_gate(def, QkGate_H, (uint32_t[1]){i}, NULL); } return def; } /// The vtable entries -- note this is the same infrastructure as for the custom passes and IRs. static const QkVtableEntry foo_entries[] = { {.slot = QkCustomOpSlot_Name, .ptr = foo_name}, {.slot = QkCustomOpSlot_NumQubits, .ptr = foo_num_qubits}, {.slot = QkCustomOpSlot_Eq, .ptr = foo_eq}, {.slot = QkCustomOpSlot_Definition, .ptr = foo_definition}, {.slot = QkCustomOpSlot_Clone, .ptr = foo_clone}, {.slot = QkCustomOpSlot_Delete, .ptr = free}, {.slot = -1, .ptr = NULL}, }; int main(void) { // The QkCustomOp takes ownership so we need to explicitly allocate the object. FooGate *foo_config = malloc(sizeof(FooGate)); foo_config->num_qubits = 3; const QkCustomOpVtable *foo_vtable = qk_custom_operation_vtable_new(foo_entries); QkCustomOp *foo = qk_custom_operation_new(foo_config, foo_vtable); QkCircuit *circuit = qk_circuit_new(3, 0); uint32_t qubits[3] = {0, 1, 2}; qk_circuit_custom_operation(circuit, foo, qubits, NULL, NULL); qk_circuit_free(circuit); qk_custom_operation_vtable_free(foo_vtable); return 0; }
На пути к Qiskit без обязательного использования Python
C API поддерживает два режима работы: автономную общую библиотеку для работы с Qiskit из компилируемых языков без зависимости от интерпретатора Python во время выполнения и режим расширения Python для создания расширений Python, которые напрямую взаимодействуют с объектами Rust в Qiskit для повышения производительности.
Одним из давних ограничений автономного режима является то, что, несмотря на отсутствие запуска интерпретатора Python, он всё равно требовал установки Python. Это связано с тем, что внутренняя модель данных Qiskit на Rust частично определяется через типы Python, и компоновщику требуются эти символы, даже если C API никогда их не использует (issue #14240). В Qiskit v2.6 достигнут значительный прогресс в устранении этого ограничения, и мы надеемся завершить эту работу в версии v2.7. Данное изменение откроет возможности использования C API в средах, где установка Python ранее была непрактичной.
Рекомендации по обновлению
Мы ожидаем, что для большинства пользователей обновление до Qiskit v2.6 не потребует изменений в коде. Приведённые ниже пункты могут оказаться важными в зависимости от того, как вы используете SDK, особенно если вы работаете с сериализацией QPY, собираете Qiskit из исходного кода или используете C API.
Версия формата QPY
В Qiskit v2.6 представлена новая версия формата QPY — v18, которую qiskit.qpy.dump() теперь генерирует по умолчанию. Практическим следствием является односторонняя совместимость: файлы QPY, записанные в версии 2.6, могут не загружаться в старых релизах Qiskit.
Если вам нужно создать файл QPY, который сможет загрузить старый выпуск Qiskit, вы можете запросить более старую версию формата. Используйте аргумент версии функции qiskit.qpy.dump() в Python или функции qk_qpy_dump_*_with_version() в C API, чтобы указать версию QPY старше 18. Проверьте историю версий формата, чтобы узнать, какие версии поддерживаются конкретными релизами Qiskit.
Изменения в версии v18 в основном представляют собой внутреннюю очистку, а также более компактное кодирование регистров на диске. Разница незначительна для большинства схем, но схемы с очень большими или множеством классических регистров могут продемонстрировать существенное уменьшение размера файла.
Минимальная поддерживаемая версия Python
Минимальной поддерживаемой версией Python остается 3.10 (requires-python = ">=3.10" в ветке 2.6). Это последняя версия Qiskit, которая будет поддерживать 3.10. Начиная с Qiskit 2.7, потребуется Python 3.11 или новее.
Требования к сборке и зависимостям
Для сборки Qiskit из исходного кода теперь требуется Rust 1.89 (повышение MSRV в ветке). Это не влияет на пользователей, устанавливающих предварительно собранные колёса (wheels) через pip. В этом релизе нет изменений совместимости с glibc.
Стабильность C API / бинарная совместимость
В Qiskit v2.6 мы еще не объявляем C API стабильным. Тем не менее стоит отметить, что между версиями v2.5 и v2.6 не было нарушающих обратную совместимость изменений в C API. Изменения в этом релизе носят аддитивный характер, поэтому существующий код на C должен продолжать компилироваться и компоноваться с версией 2.6 без каких-либо модификаций.
Заключительные примечания
Вот и всё! Самые важные обновления в Qiskit v2.6.
Если вы хотите помочь в определении дальнейшего развития Qiskit, вы всегда можете открыть тикет на GitHub, чтобы запросить функцию или сообщить об ошибке, а также следить за нашими планами на дорожной карте Qiskit.
Особая благодарность многочисленным разработчикам, внесшим свой вклад в этот релиз (в алфавитном порядке):
Abby Mitchell, Aditya Srivastava, Alexander Ivrii, Aly Abouzaid, Andrew Eddins, Anita George, Arpit Jha, Aziz Chebil, Bryan Johnnson, Daksh Singh, Daniel Gaskins, David F. Cohen, Dennis Wayo, Dikran Meliksetian, Doraking, dp1345, Elad Venezian, Eli Arbel, Ella Barkan, Esteban Ramírez, Evan McKinney, Gadi Aleksandrowicz, Greg Neighbors, HaEumKim, Ian Hincks, Jake Lishman, Jessie Yu, Jim Garrison, José Miguel Alvarez Marques De Miranda, Joshua Skanes-Norman, Julien Gacon, Kazuki Tsuoka, Kevin Hartman, kmbys, Luciano Bello, Matteo AC Rossi, Matthew Treinish, Max Rossmannek, Mehar Ali, metamyte, Miriyala Jeevan Kumar, Mohamed Mahameed, Mozammil Hassan, Patrick Hopf, Pedro Henrique de Oliveira, Peter Chen J., philipjpark, Pramod Anandarao, Raynel Sanchez, Rebecca Dimock, Ross Peili, Sam Odler, Shelly Garion, shreyasavadatti, Simona Rabinovici-Cohen, Sivan Ravid, Sona Jomon, Tal Kozlovski, Tilock Sadhukhan, Vempati Harsha, Vyom Patel, Yevgeny Yaroker, Yosef Bunick, zeb33n
Следите за блогом IBM Quantum, чтобы узнать больше о C API, языковых привязках и о том, что ждет компилятор Qiskit в будущем.










