FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-V Vectorized FFTW3を試す (1. RISC-V向けにビルドを試す)

FFTW3はFFTの有名なライブラリで、いくつかのアーキテクチャ向けにSIMD命令を使ったバージョンも含まれている。

いろいろと調べてみると、RISC-V RVV1.0に対応したFFTW3も有志が開発しているようなので、それを試してみることにした。

そもそも、FFTW3の使い方をさっぱり忘れているのでそれを思い出すところから始まる。

github.com

sudo apt install ocaml ocamlbuild autoconf automake indent libtool fig2dev
git clone https://github.com/sh-zheng/fftw3.git fftw3-zheng
cd fftw3-zheng
./bootstrap.sh --host=riscv64-unknown-elf --disable-threads
./configure --enable-maintainer-mode --enable-rvv --host=riscv64-unknown-elf "CC=riscv64-unknown-elf-gcc -march=rv64gcv"
make -j$(nproc)

現在使用しているRVV対応GCCのIntrinsicが古いので、一部ヘッダファイルを書き換えてコンパイルを通すようにしている。しかしこれはGCCをアップデートすれば問題ないはずだ。

diff --git a/simd-support/rvv.c b/simd-support/rvv.c
index eb2096c8..7591fe85 100644
--- a/simd-support/rvv.c
+++ b/simd-support/rvv.c
@@ -26,6 +26,6 @@
 /* don't know how to autodetect RVV; assume it is present */
   int X(have_simd_rvv)(int rs)
   {
-       return __riscv_vsetvlmax_e64m1() == (rs / 64);
+       return vsetvlmax_e64m1() == (rs / 64);
   }
 #endif
diff --git a/simd-support/simd-rvv.h b/simd-support/simd-rvv.h
index 6cd38b76..43121d45 100644
--- a/simd-support/simd-rvv.h
+++ b/simd-support/simd-rvv.h
@@ -31,18 +31,18 @@

 #ifdef FFTW_SINGLE
 #  define DS(d,s) s /* single-precision option */
-#  define TYPE(name) __riscv_ ## name ## _f32m1
-#  define TYPEUINT(name) __riscv_ ## name ## _u32m1
-#  define TYPEINTERPRETF2U(name) __riscv_ ## name ## _f32m1_u32m1
-#  define TYPEINTERPRETU2F(name) __riscv_ ## name ## _u32m1_f32m1
-#  define TYPEMEM(name) __riscv_ ## name ## e32_v_f32m1
+#  define TYPE(name) name ## _f32m1
+#  define TYPEUINT(name) name ## _u32m1
+#  define TYPEINTERPRETF2U(name) name ## _f32m1_u32m1
+#  define TYPEINTERPRETU2F(name) name ## _u32m1_f32m1
+#  define TYPEMEM(name) name ## e32_v_f32m1
 #else
 #  define DS(d,s) d /* double-precision option */
-#  define TYPE(name) __riscv_ ## name ## _f64m1
-#  define TYPEUINT(name) __riscv_ ## name ## _u64m1
-#  define TYPEINTERPRETF2U(name) __riscv_ ## name ## _f64m1_u64m1
-#  define TYPEINTERPRETU2F(name) __riscv_ ## name ## _u64m1_f64m1
-#  define TYPEMEM(name) __riscv_ ## name ## e64_v_f64m1
+#  define TYPE(name) name ## _f64m1
+#  define TYPEUINT(name) name ## _u64m1
+#  define TYPEINTERPRETF2U(name) name ## _f64m1_u64m1
+#  define TYPEINTERPRETU2F(name) name ## _u64m1_f64m1
+#  define TYPEMEM(name) name ## e64_v_f64m1
 #endif

 #if RVV_VLEN == 65536

これで一応RISC-V Vectorizationの入ったライブラリがビルドできる。./.libs/libfftw3.aにライブラリができている?

riscv64-unknown-elf-objdump -D ./.libs/libfftw3.a
/* 一部抜粋 */
00000000000001ce <.L53>:
 1ce:   c22027f3                csrr    a5,vlenb
 1d2:   878d                    srai    a5,a5,0x3
 1d4:   02f88333                mul     t1,a7,a5
 1d8:   05807757                vsetvli a4,zero,e64,m1,ta,mu
 1dc:   5208ad57                vid.v   v26
 1e0:   5208acd7                vid.v   v25
 1e4:   97a8ed57                vmul.vx v26,v26,a7
 1e8:   97986cd7                vmul.vx v25,v25,a6
 1ec:   02f807b3                mul     a5,a6,a5