⛳
Barrett Reduction (2)
Barrett Reduction (2) - on GPU -
はじめに
前回は、簡単にBarrett Reductionについて記載しました。
今回は、Pythonで並列計算(GPU)を利用して実行する方法について備忘録を残します。
使用パッケージ
とりあえず実装
CuPyのRawKernelを用いて実装します。
import cupy as cp
BarrettReduction = cp.RawKernel(r'''
extern "C" __global__
void BarretReduction(unsigned long long a[], unsigned int q, unsigned int mu, int q_bit_length)
{
int local_tid = threadIdx.x;
unsigned long long rx;
rx = a[local_tid] >> (q_bit_length - 2);
rx = rx * mu;
rx >>= q_bit_length + 2;
rx *= q;
a[local_tid] -= rx;
a[local_tid] -= q * (a[local_tid] >= q);
}
''', 'BarretReduction')
上で定義したカーネルをPythonから呼び出して実行します。
なお、今回はグリッド数を1、スレッド数を最大の1024として呼び出します。
import ctypes
# Parameter initialization
q = 536608769
psi = 284166
psiinv = 208001377
q_bit_length = int(q.bit_length())
mu = int(cp.floor(2**(2*q_bit_length) / q))
a_cpu = cp.ones(1024, dtype=cp.uint64)
a_cpu *= 1024
a_cpu *= 393388074
d_a = cp.copy(a_cpu)
BarrettReduction((1,), (1024,), (d_a, q, mu, q_bit_length))
print(d_a)
# => [372811026 372811026 372811026 ... 372811026 372811026 372811026]
3. 今後やる予定のこと
- Barrett Reductionを用いるアルゴリズム全般の実装と速度検証
Discussion