5-OpenJij GPU

Open in Colab

(追記: 2021/05)このセクションは2021/05 現在、サポートされていません。次の章へ進むことをおすすめします。

このセクションではGPUを用いてSimulated Quantum Annealing(SQA)を行う方法をご紹介します。

Google Colabでの設定とインストール

一般のPCにはCUDA環境が整っていない、もしくはCUDAに対応するNVIDIAのGPUが搭載されていないこともあります。しかしGoogle colaboratoryを使えば誰でもGPGPUを使うことができます。

GPU設定

GPU実行したいJupyter NotebookをGoogle Colabで開きます。

ランタイム > ランタイムのタイプを変更 > ハードウェアアクセラレータをGPUに選択

この設定を行うことでGPUを用いたJupyter Notebookの実行が可能となります。

OpenJijのインストール

OpenJijからGPUを用いたモジュールを呼び出すためには、まずpipからのインストールの際にOpenJijをソースコードからビルドする必要があります。 この操作のためにCMakeと呼ばれるツールが必要ですが、Google ColabにプリインストールされているCMakeは古いバージョンです。まずはそれをバージョンアップしましょう。

[ ]:
!pip install -U cmake

その後、OpenJijをインストールし直します。一度アンインストールしてから、ソースコードからビルドするオプションである --no-binary :all:をpipに付け加えてインストールします。 インストールにはしばらく時間がかかります。 > 通常pipは一度インストールしたことのあるアプリケーションであればキャッシュからデータを取ってきてしまうので、それも無効化する --no--cache-dirもつけます。初めてOpenJijをインストールする際にはこのオプションは不要です。

[ ]:
!pip uninstall openjij -y
!pip install openjij --no-binary :all: --no-cache-dir

GPUSQA計算

OpenJijのGPUでサポートしているのはキメラグラフ上でのモンテカルロ計算です。
まずは GPUSQASampler のインスタンスを作ります。 もし、GPU関連のモジュールが見つからないとエラーが出た際には、以前のバージョンが読み込まれている可能性があるので、一度再起動するといいかもしれません。
[1]:
import openjij as oj

sampler = oj.GPUChimeraSQASampler(num_reads=100, unit_num_L=2)
ここで unit_num_L はキメラユニットセルが並ぶ2次元格子の1辺の長さを指定します。
上の例では 2×2=4つのキメラユニットセルが並んでいる系を作成しています。キメラユニットセルは8bitで1つを構成しているため、総ビット数は

\({\rm total\_num} = {\rm unit\_num\_L}^2 \times 8\)

のように計算されます。

GPUSQASamplerでは、のちに sample_qubo などで少ない変数を指定しても、ここで作ったキメラグラフの系のサイズだけSQA計算を行います。
unit_num_Lは無駄に大きすぎないように注意しましょう。またunit_num_Lはコンストラクタで指定しなくても、sample_quboを実行するときの引数としても指定できます。

実行

ではSQAを実行してみましょう。これまで紹介してきたSamplerと同様に、sample_qubo (or sample_ising) で計算を行うことができます。 ただし、キメラグラフを満たさない添字の相互作用を指定するとエラーになります。

[2]:
Q = {(0, 4): -1, (0, 5): -1, (4, 12): 1}
response = sampler.sample_qubo(Q)
response
[2]:
Response(rec.array([([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1),
           ([1, 1, 1, 0], -2., 1), ([1, 1, 1, 0], -2., 1)],
          dtype=[('sample', 'i1', (4,)), ('energy', '<f8'), ('num_occurrences', '<i8')]), [0, 4, 5, 12], {'system': [], 'sampling_time': 689034.2819970101, 'execution_time': 5976.18150019116, 'list_exec_times': array([76328.54099938,  7530.31800195,  7715.94400067,  7510.68699901,
        7787.2940019 ,  7512.42399929,  7352.67699929,  7332.60900233,
        7284.00799926,  7312.71800032,  7284.09800286,  7233.33899805,
        6989.54900145,  6796.05900223,  6726.42200152,  6837.33000187,
        6793.93099927,  6824.61099859,  6693.40600143,  6772.17100019,
        6788.3619995 ,  6788.34800055,  6761.98400106,  6818.01799874,
        6860.50599688,  6735.12700087,  6726.58600161,  6680.12800088,
        6669.64500124,  6631.90600244,  6647.62699671,  6668.59500052,
        6733.77299972,  6725.34799742,  6780.18899998,  6743.88599873,
        6646.95599698,  6676.33299963,  6360.07000139,  4574.99900222,
        4392.35500016,  4334.32299906,  4210.20800059,  4228.12000033,
        4252.30999826,  4257.1069971 ,  4158.3150014 ,  4189.84000135,
        4206.58399889,  4182.14999809,  4202.39699815,  4218.48000042,
        4165.10200012,  4231.43999797,  4240.46400076,  4241.20000025,
        4202.66500078,  4199.92800016,  4168.96200113,  4213.14699997,
        4235.60900163,  4205.72599978,  4233.40400084,  4227.56999978,
        4187.44800118,  4163.88200028,  4231.00700209,  4187.86500086,
        4188.6709987 ,  4152.51400045,  4202.75400029,  4194.30900001,
        4198.0720016 ,  4240.42300074,  4285.01699935,  4305.28099969,
        4215.97699824,  4225.1800005 ,  4163.24800244,  4252.90499697,
        4178.68700242,  4195.24300014,  4241.57200177,  4212.6690023 ,
        4228.39599923,  4194.24500069,  4215.65000215,  4240.26400287,
        4252.68699837,  4220.24699947,  4185.00500018,  4219.33899997,
        4194.66599851,  4208.64400076,  4177.97600312,  4194.74700175,
        4173.36499959,  4242.68899951,  4194.9890001 ,  4218.5889979 ]), 'schedule': {'beta': 10.0, 'gamma': 1, 'num_sweeps': 100}}, 'BINARY')

全結合模型のキメラグラフへの埋め込み

これまで説明したものは、相互作用がキメラグラフ上に存在するもののみの計算でした。以下では全結合の問題のように、相互作用が複雑なものをキメラグラフに埋め込む場合のスクリプトをご紹介します。
キメラグラフへの埋め込みを行うために、dwaveEmbeddingCompositeを併用しましょう。pipを用いてdwave-systemをインストールします。
[ ]:
!pip install dwave-system

そしてsampler部分のスクリプトを以下のように書き換えます。

[15]:
from dwave.system.composites import EmbeddingComposite

gpusqa = oj.GPUSQASampler(num_reads=100, unit_num_L=2)
sampler = EmbeddingComposite(gpusqa)