FFTW3はFFTの有名なライブラリで、いくつかのアーキテクチャ向けにSIMD命令を使ったバージョンも含まれている。
いろいろと調べてみると、RISC-V RVV1.0に対応したFFTW3も有志が開発しているようなので、それを試してみることにした。
そもそも、FFTW3の使い方をさっぱり忘れているのでそれを思い出すところから始まる。
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