PythonからIPにデータのアドレスを設定する
FPGAに実装した行列計算IPにnumpyのndarrayのデータが格納されたアドレスを設定したいことがあったのでメモ
ndarrayの場合、実行しているプロセスの仮想アドレスは下記で取得できる
vaddr = a.__array_interface__['data'][0]
ここ とか ここ をみると、/proc/{pid}/pagemap
を見れば物理アドレスが取得できそうなことがわかったので、それを利用する。ほぼ2つめのサイトのpythonコードだが、物理アドレスを返すように修正した。
def get_physaddr(addr, size=8): pid = os.getpid() offset = (addr // mmap.PAGESIZE) * size with open('/proc/{}/pagemap'.format(pid), 'rb') as f: f.seek(offset, 0) entry = struct.unpack('Q', f.read(size))[0] return (entry & 0x7FFFFFFFFFFFFF) * mmap.PAGESIZE + (addr % mmap.PAGESIZE)
あとは、前回IPをpythonから操作した のと同じように、行列計算IPを設定する。
xadd = fpga.ip('xadd.json') a = np.random.randint(0, 10, (3, 3), np.uint32) b = np.random.randint(0, 10, (3, 3), np.uint32) c = np.random.randint(0, 10, (3, 3), np.uint32) aa = get_physaddr(a.__array_interface__['data'][0]) ba = get_physaddr(b.__array_interface__['data'][0]) ca = get_physaddr(c.__array_interface__['data'][0]) xadd.px(aa) # 入力1 のアドレス xadd.py(ba) # 入力2 のアドレス xadd.pz(ca) # 出力のアドレス xadd.n(9) # 要素数 xadd.ctrl(1) # 実行 print('{}\n+\n{}\n=\n{}'.format(a, b, c))
実行結果
[[2 7 4] [6 5 0] [3 5 4]] + [[2 7 2] [8 3 7] [0 6 8]] = [[ 4 14 6] [14 8 7] [ 3 11 12]]