コンテンツにスキップ

システムF

システムHからシステムFを利用する手順を説明します。 システムFにはOQTOPUSが導入されており、OQTOPUSのAPIにてジョブの実行管理を行えます。

Note

システムFは利用者が限定されており、産総研との共同研究契約に基づき利用できます。

参考: ABCI-Q量子コンピュータの外部提供を開始 (2026年3月24日)

仮想環境の作成

インタラクティブノードでPythonの仮想環境を作成しquri-parts-oqtopusをインストールします。

[username@qes01 ~]$ module load python/3.12/3.12.12
[username@qes01 ~]$ python3 -m venv <venv_name>
[username@qes01 ~]$ source <venv_name>/bin/activate
(venv_name)[username@qes01 ~]$ pip install quri-parts-oqtopus

venv_name:任意の仮想環境名に置き換えてください。

設定ファイル(.oqtopus)の作成

インタラクティブノードで、ホームディレクトリに.oqtopus ファイルを作成し、以下の内容を記載します。

[oqtopus-dev]
url=<address>
api_token=<token>
  • address:管理者から連絡のあったaddressに置き換えてください。
  • token:管理者から発行されたトークンに置き換えてください。

ホーム領域に仮想環境を準備できたらインタラクティブジョブ及びバッチジョブを投入します。

実行可能なjobの種類

以下の制約があります。

  • Samplerのみ対応
    • Estimatorには未対応
  • 量子計算の途中で量子ビットを読出し、その結果に応じて次の処理を変える機能(例 if_else)は使用できない

sampling jobを投げると以下の操作が可能です。

  • 投入したジョブの結果取得
  • 投入したジョブの状況取得
  • 投入したジョブのキャンセル
    • ジョブの status によってキャンセルできない場合があります。

インタラクティブジョブ

インタラクティブジョブでのジョブ投入から量子回路実行までの流れを以下で説明します。

ジョブ投入

資源タイプrt_QFを指定してジョブ投入します。

[username@qes01 ~]$ qsub -l rt_QF=1 -W group_list=grpname -I

grpname:所属するグループ名に置き換えてください。

環境設定

Pythonモジュールをロードします。

[username@qh001 ~]$ module load python/3.12/3.12.12

仮想環境のアクティベート

事前に作成した仮想環境をアクティベートします。

[username@qh001 ~]$ source <venv_name>/bin/activate

Pythonコードの作成

以下のサンプルコードを参考にPythonコードを作成します。

サンプルコード

from quri_parts_oqtopus.backend import OqtopusConfig, OqtopusSamplingBackend

program = """OPENQASM 3;
include "stdgates.inc";
qubit[2] q;
bit[2] c;

h q[0];
cx q[0], q[1];
c[0] = measure q[0];
c[1] = measure q[1];
"""

backend = OqtopusSamplingBackend (OqtopusConfig.from_file("oqtopus-dev"))

transpiler_info =  {
    "initial_layout": "[1, 2]",
}

job = backend.sample_qasm(
    program,
    device_id="abciq-f-1",
    transpiler_info=transpiler_info,
    shots=500,
)

print(job)

量子bitの相互作用には方向性がありますが、initial_layoutで指定する量子bitの番号の順番を入れ替えても内部で変換されるため実行できます。

・出力例

{'description': '',
 'device_id': 'abciq-f-1',
 'ended_at': None,
 'execution_time': None,
 'job_id': '06a0a7cc-f497-717a-8000-3171042a420e',
 'job_info': {'combined_program': None,
              'message': None,
              'operator': None,
              'program': ['OPENQASM 3;\n'
                          'include "stdgates.inc";\n'
                          '\n'
                          'qubit[2] q;\n'
                          'bit[2] c;\n'
                          '\n'
                          'h q[0];\n'
                          'cx q[0], q[1];\n'
                          '\n'
                          'measure q[0] -> c[0];\n'
                          'measure q[1] -> c[1];\n'],
              'result': None,
              'transpile_result': None},
 'job_type': 'sampling',
 'mitigation_info': {},
 'name': '',
 'ready_at': None,
 'running_at': None,
 'shots': 500,
 'simulator_info': {},
 'status': 'submitted',
 'submitted_at': datetime.datetime(2026, 5, 18, 2, 43, 27, tzinfo=tzutc()),
 'transpiler_info': {}}

Pythonコードの実行

作成したPythonコードを実行します。

(venv_name)[username@qh001 ~]$ python3 <python_code_name>

バッチジョブ

既にPythonコードを作成している場合はバッチジョブによる実行も可能です。 バッチジョブでの実行の流れを以下で説明します。

ジョブスクリプト

ジョブスクリプト内で資源タイプをrt_QF指定します。

#!/bin/sh

#PBS -l rt_QF=1
#PBS -j oe
#PBS -W group_list=<grpname>

# pythonモジュールロード
module load python/3.12/3.12.12

# 仮想環境のアクティベート
source <venv_name>/bin/activate

# pythonコードの実行
python3 <python_code_name>
  • <grpname>:所属するグループ名に置き換えてください。
  • <venv_name>:任意の仮想環境名に置き換えてください。

ジョブ投入

[username@qes01 ~]$ qsub run.sh

量子回路実行結果取得

量子回路の実行結果を取得します。

サンプルコード

from quri_parts_oqtopus.backend import OqtopusConfig, OqtopusSamplingBackend
import sys

backend = OqtopusSamplingBackend (OqtopusConfig.from_file("oqtopus-dev"))

job_id = "<job_id>"
job = backend.retrieve_job(job_id)

# print job
print("# # # job")
print(job.job_id)
print (f"Status: ",job.status)
result = job.result()
print (f"# # # result")
print (result.counts)

作成したPythonコードを実行します。

(venv_name)[username@qh001 ~]$ python <python_code_name>

job_id:ジョブを投入した際に取得したジョブのIDを指定します。

実行例

# # # job
<job_id>
Status:  succeeded
# # # result
Counter({3: 254, 0: 246})

量子回路実行状況参照

量子回路の実行状況を参照します。

サンプルコード

from quri_parts_oqtopus.backend import OqtopusConfig, OqtopusSamplingBackend
import sys

backend = OqtopusSamplingBackend(OqtopusConfig.from_file("oqtopus-dev"))

job_id = "<job_id>"
job = backend.retrieve_job(job_id)

# print job
print("### job")
print (job.job_id)
print(f"Status: ", job.status)

作成したPythonコードを実行します。

(venv_name)[username@qh001 ~]$ python <python_code_name>

実行例

### job
<job_id>
Status:  succeeded

量子回路実行キャンセル

量子回路の実行をキャンセルします。

サンプルコード

from quri_parts_oqtopus.backend import OqtopusConfig, OqtopusSamplingBackend
import sys

backend = OqtopusSamplingBackend(OqtopusConfig.from_file("oqtopus-dev"))

job_id = "<job_id>"

job = backend. retrieve_job(job_id)
job.cancel()
print (job)

作成したPythonコードを実行します。

(venv_name)[username@qh001 ~]$ python <python_code_name>

実行例

Job failed or no result available
Status: cancelled
Backend message: None
Job ended with status cancelled.

較正情報参照

較正情報を参照します。

サンプルコード

from quri_parts_oqtopus.backend import OqtopusConfig, OqtopusDeviceBackend

backend = OqtopusDeviceBackend(OqtopusConfig.from_file("oqtopus-dev"))

#get the device list
device = backend.get_devices()

#print the device list
print (f"###### %% device for  {device[0].device_id}")
print (f"device_info:  {device[0].device_info}")
print(f"calibrated_at:  {device[0].calibrated_at}")

作成したPythonコードを実行します。

(venv_name)[username@qh001 ~]$ python <python_code_name>

・実行例

###### %% device for  abciq-f-1
device_info: { 省略 }

サンプルコードを実行した結果について

qubit_connectivity のカッコ内の数字は 2 量子ゲートにおける量子ビット間の方向を示します。

例: [0, 1]
0: コントロールビット、1: ターゲットビット

量子ビット間の方向は固定です。

ジョブ一覧表示

ジョブの一覧を表示します。

サンプルコード1

CONFIG_FILE="$HOME/.oqtopus"

# 設定セクション名
SECTION="oqtopus-dev"

URL=$(awk -F'=' -v t="[$SECTION]" '$0==t {p=1;next} p&&/^\s*\[/ {exit} p&&/^url=/ {print $2}' $CONFIG_FILE)
API_TOKEN=$(awk -F'=' -v t="[$SECTION]" '$0==t {p=1;next} p&&/^\s*\[/ {exit} p&&/^api_token=/ {print $2}' $CONFIG_FILE)

curl -X GET "$URL/jobs?" -H "q-api-token: $API_TOKEN" -H "content-type: application/json" | jq .

一回のcurlで取得できる件数上限が100であるため、それ以上のジョブを取得するためには、apiにpageパラメータを追加します。

以下は101件目からの100件を取得する例です。

curl -X GET "$URL/jobs?page=2" -H "q-api-token: $API_TOKEN" -H "content-type: application/json" | jq .

作成したスクリプトを実行します。

[username@qh001 ~]$ sh <script_name>

サンプルコード2

インタラクティブノードで仮想環境にrequestsモジュールをインストールします。

(venv_name)[username@qh001 ~]$ pip install requests
import sys
import configparser
import os
from pathlib import Path
import requests
import subprocess
import json

path = '~/.oqtopus'
expanded = os.path.expandvars(path)
path_expanded = Path(expanded)
pat_expanduser = Path.expanduser(path_expanded)
parser = configparser.ConfigParser()
parser.read(pat_expanduser, encoding="utf-8")

api_token = f"{parser['oqtopus-dev']['api_token']}"

url = f"{parser['oqtopus-dev']['url']}/jobs?"

headers =  {
     'q-api-token': api_token,
      'content-type': 'application/json'
       }

response = requests.get(url, headers=headers)

# 応答をJSONオブジェクトに変換し、それを再度JSON文字列にダンプします
json_data = response.json()
json_input = json.dumps(json_data, indent=2, ensure_ascii=False) # indentで整形

result = subprocess.run(
     ['jq', '.'], # jqコマンドに引数 '.' を追加して全ての入力を整形します
      input=json_input,
      stdout=subprocess.PIPE,
      stderr=subprocess.PIPE,
      text=True,
      check=True
      )

print(f"抽出結果:\n {result.stdout.strip()}")

一回のリクエストで取得できる件数上限が100であるため、それ以上のジョブを取得するためには、apiにpageパラメータを追加します。

以下は101件目からの100件を取得する例です。

url = f" {parser['oqtopus-dev']['url']}/jobs?page=2"

作成したPythonコードを実行します。

(venv_name)[username@qh001 ~]$ python <python_code_name>

実行例

  {
    "job_id": "<job_id>",
    "name": "",
    "description": "",
    "job_type": "sampling",
    "status": "failed",
    "device_id": "abciq-f-1",
    "shots": 1000,
    "job_info": {
      "program": [
        "OPENQASM 3;\ninclude \"stdgates.inc\";\n\nqubit[3] q;\nbit c0;\nbit c1;\nbit c2;\n\n// optional post-rotation for state tomography\n// empty gate body => identity gate\ngate post q { }\nreset q;\nU(0.3, 0.2, 0.1) q[0];\nh q[1];\ncx q[1], q[2];\nbarrier q;\ncx q[0], q[1];\nh q[0];\n\nc0 = measure q[0];\nc1 = measure q[1];\n\nif(c0==1) z q[2];\nif(c1==1) { x q[2]; }  // braces optional in this case\npost q[2];\nc2 = measure q[2];\n"
      ],
      "combined_program": null,
      "operator": null,
      "result": null,
      "transpile_result": null,
      "message": "qasm3.load failed:\"23,3: conditions must be 'bit == const bool' or 'bitarray == const int', not 'bit == const int'\""
    },
    "transpiler_info": {
      "initial_layout": "20,21,22",
      "transpiler_options": {
        "optimization_level": 2
      }
    },
    "simulator_info": {},
    "mitigation_info": {},
    "execution_time": null,
    "submitted_at": "2025-12-16T21:51:12Z",
    "ready_at": "2025-12-16T21:51:13Z",
    "running_at": "2025-12-16T21:51:13Z",
    "ended_at": "2025-12-16T21:51:13Z"
  },

ジョブのメッセージ表示

ジョブのメッセージを表示します。

サンプルコード

from quri_parts_oqtopus.backend import OqtopusConfig, OqtopusSamplingBackend
import sys

backend = OqtopusSamplingBackend(OqtopusConfig.from_file("oqtopus-dev"))

job_id = "<job_id>"
job = backend.retrieve_job(job_id)

print (f"Job id:", job.job_id)
print (f"Status:", job.status)

#print message
if job.status != "succeeded":
    print (f"message:  {job.job_info['message']}")
    exit(0)

result = job.result()
print (result.counts)

作成したPythonコードを実行します。

(venv_name)[username@qh001 ~]$ python <python_code_name>

実行例

Job id: <job_id>
Status: failed
message:"The control-flow construct 'if_else' is not supported by the backend."