common.title

Docs
Quantum Circuit
TYTAN CLOUD

QUANTUM GAMING


autoQAOA
Desktop RAG

Overview
Terms of service

Privacy policy

Contact
Research

Sign in
Sign up
common.title

マルチGPUでのcuQuantum Appliance版cuQuantumのcuTensorNetベンチマークや使い方。

Yuichiro Minato

2024/02/08 06:57

こんにちは。GPUを使った量子コンピューティングの中でもcuQuantumは少し特殊です。複数のGPUやマシンを使う場合にはcuQuantum Applianceと言うものをインストール必要があります。今回少し質問をもらいましたので、いつもはcuStateVecの方を行っていましたが、今回はcuTensorNetの方をフォローしたいと思います。

マルチGPU / マルチノード版cuQuantum

https://catalog.ngc.nvidia.com/orgs/nvidia/containers/cuquantum-appliance

cuStateVecは伝統的な状態ベクトルシミュレータで王道です。一方cuTensorNetは開発中の新型シミュレータです。

cuTensorNetはテンソルネットワークと呼ばれる手法で実装されたシミュレータです。Google CirqやIBM Qiskitなどの量子回路を一度テンソルネットワーク方式に変換し、それをcuTensorNetに入力することで計算がされます。

コードはこちらを利用します。

NVIDIA cuQuantum / cuTensorNet + Google Cirq で状態ベクトルの求め方

https://blueqat.com/yuichiro_minato2/9907c9bb-f337-453a-86f3-173d5db5f78f

cuStateVecはQiskitやCirq内部から呼び出して使いますが、cuTensorNetは普通は一度量子回路を変換してcuTensorNetで計算します。

import cirq
from cirq.testing import random_circuit
import cupy as cp
import numpy as np
from cuquantum import contract, CircuitToEinsum

num_qubits = 10
n_moments = 6
op_density = 0.9
gate_domain = {cirq.H: 1, 
        cirq.S: 1, 
        cirq.T: 1, 
        cirq.CNOT: 2, 
        cirq.CZ: 2}
circuit = random_circuit(num_qubits, n_moments, op_density=op_density, gate_domain=gate_domain, random_state=6)
print(circuit)

myconverter = CircuitToEinsum(circuit, dtype='complex128', backend=cp)
expression, operands = myconverter.state_vector()
sv = contract(expression, *operands)
sv.reshape(1, 2**num_qubits)

ランダムサーキットを入れています。CircuitToEinsumというのが変換になります。コンバーターで量子化色を変換したのち、計算を決めます。今回は状態ベクトルを求めてみるので、状態ベクトルようの変換がさらに入ります。量子回路そのままで計算できない場合があるので、目的に応じてそこからさらに量子回路を使って求めたい値が得られるようにグラフを変換するのがcuTensorNetです。

最終的に計算はcontractというところで、expressionとoperandsの組み合わせによって実行されます。縮約という操作をしますが、順番やその縮約に対応する演算子が記述されています。

今回はcuTensorNetのシングルノードマルチGPUでベンチマークをとってみます。

singularity exec --nv cuquantum-appliance.img mpiexec -n 8 python3 tn.py

量子回路は、

┌──┐   ┌───┐   ┌───┐   ┌────┐   ┌──┐   ┌────┐

0: ───────────H───────H────────────────T──────X───────

1: ─────@───────@──────@───────@────────@─────┼──@────

│       │      │       │        │     │  │

2: ─────┼───────┼─────T┼───────┼@──────T┼─────┼@─┼────

│       │      │       ││       │     ││ │

3: ────@┼─────X─┼──────┼@──────┼┼@─────T┼─────┼┼@┼────

││     │ │      ││      │││      │     ││││

4: ────┼┼─────┼S┼─────T┼┼─────S┼┼┼─────@┼─────@┼┼┼────

││     │ │      ││      │││     ││      │││

5: ────@┼─────┼T┼──────┼@──────┼┼@─────@┼──────@┼┼────

│     │ │      │       ││       │       ││

6: ────H┼─────@─┼─────X┼──────@┼┼──────T┼─────@─┼┼────

│       │     ││      │││       │     │ ││

7: ────T┼───────@─────┼┼──────┼X┼──────H┼─────┼─┼X────

│             ││      │ │       │     │ │

8: ────H┼─────T───────┼X──────@─┼───────@─────┼─@─────

│             │         │             │

9: ─────@─────────────@─────────@─────────────X───────

└──┘   └───┘   └───┘   └────┘   └──┘   └────┘

速度は、

1GPU - NVIDIA V100 * 1

8並列

0.99s

でした。-n 8というオプションで計算したらよかったのですが、これは並列数はGPU数と対応しているわけではなさそうですよね???

メモリ不足にならない程度に計算しました。

順調に早いですね。

4GPU - NVIDIA V100 * 4

8並列

0.83s

これくらいのサイズだと1GPUでも早いです。もちょい大きさを大きくしてみます。

num_qubits = 20
n_moments = 10

にしてみました。

1GPU - NVIDIA V100 * 1

8並列

1.22s

4GPU - NVIDIA V100 * 4

8並列

1.00s

まぁ、なんというか十分早い気がします。

テンソルネットワークの場合には、量子ビット数だけでなく、深さ方向のパラメータも聞いてきますので、全体の回路のサイズを推定して計算しましょう。以上です。

© 2025, blueqat Inc. All rights reserved