diff mbox series

[FFmpeg-devel,3/3] riscv: add float vector-scalar multiplication

Message ID 20220903190147.196927-3-remi@remlab.net
State New
Headers show
Series Float DSP for RISC-V Vector extension - part I | expand

Checks

Context Check Description
yinshiyou/make_loongarch64 success Make finished
yinshiyou/make_fate_loongarch64 fail Make fate failed
andriy/make_x86 success Make finished
andriy/make_fate_x86 fail Make fate failed

Commit Message

Rémi Denis-Courmont Sept. 3, 2022, 7:01 p.m. UTC
From: Rémi Denis-Courmont <remi@remlab.net>

This is based on existing code from the VLC git tree, though the size
and scalar arguments are swapped.
---
 libavutil/float_dsp.c            |  2 ++
 libavutil/float_dsp.h            |  1 +
 libavutil/riscv/Makefile         |  4 ++-
 libavutil/riscv/float_dsp_init.c | 42 ++++++++++++++++++++++
 libavutil/riscv/float_dsp_rvv.S  | 60 ++++++++++++++++++++++++++++++++
 5 files changed, 108 insertions(+), 1 deletion(-)
 create mode 100644 libavutil/riscv/float_dsp_init.c
 create mode 100644 libavutil/riscv/float_dsp_rvv.S

Comments

Lynne Sept. 3, 2022, 7:11 p.m. UTC | #1
Sep 3, 2022, 21:01 by remi@remlab.net:

> From: Rémi Denis-Courmont <remi@remlab.net>
>
> This is based on existing code from the VLC git tree, though the size
> and scalar arguments are swapped.
> ---
>  libavutil/float_dsp.c            |  2 ++
>  libavutil/float_dsp.h            |  1 +
>  libavutil/riscv/Makefile         |  4 ++-
>  libavutil/riscv/float_dsp_init.c | 42 ++++++++++++++++++++++
>  libavutil/riscv/float_dsp_rvv.S  | 60 ++++++++++++++++++++++++++++++++
>  5 files changed, 108 insertions(+), 1 deletion(-)
>  create mode 100644 libavutil/riscv/float_dsp_init.c
>  create mode 100644 libavutil/riscv/float_dsp_rvv.S
>
> diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c
> index 8676c8b0f8..742dd679d2 100644
> --- a/libavutil/float_dsp.c
> +++ b/libavutil/float_dsp.c
> @@ -156,6 +156,8 @@ av_cold AVFloatDSPContext *avpriv_float_dsp_alloc(int bit_exact)
>  ff_float_dsp_init_arm(fdsp);
>  #elif ARCH_PPC
>  ff_float_dsp_init_ppc(fdsp, bit_exact);
> +#elif ARCH_RISCV
> +    ff_float_dsp_init_riscv(fdsp);
>  #elif ARCH_X86
>  ff_float_dsp_init_x86(fdsp);
>  #elif ARCH_MIPS
> diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h
> index 9c664592bd..7cad9fc622 100644
> --- a/libavutil/float_dsp.h
> +++ b/libavutil/float_dsp.h
> @@ -205,6 +205,7 @@ float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len);
>  void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp);
>  void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp);
>  void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict);
> +void ff_float_dsp_init_riscv(AVFloatDSPContext *fdsp);
>  void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp);
>  void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp);
>  
> diff --git a/libavutil/riscv/Makefile b/libavutil/riscv/Makefile
> index 1f818043dc..6bf8243e8d 100644
> --- a/libavutil/riscv/Makefile
> +++ b/libavutil/riscv/Makefile
> @@ -1 +1,3 @@
> -OBJS += riscv/cpu.o
> +OBJS += riscv/cpu.o \
> +        riscv/float_dsp_init.o \
> +        riscv/float_dsp_rvv.o
> diff --git a/libavutil/riscv/float_dsp_init.c b/libavutil/riscv/float_dsp_init.c
> new file mode 100644
> index 0000000000..9a5b981917
> --- /dev/null
> +++ b/libavutil/riscv/float_dsp_init.c
> @@ -0,0 +1,42 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include <stdint.h>
> +
> +#include "libavutil/attributes.h"
> +#include "libavutil/cpu.h"
> +#include "libavutil/float_dsp.h"
> +
> +void ff_vector_fmul_scalar_rvv(float *dst, const float *src, float mul,
> +                                int len);
> +
> +void ff_vector_dmul_scalar_rvv(double *dst, const double *src, double mul,
> +                                int len);
> +
> +av_cold void ff_float_dsp_init_riscv(AVFloatDSPContext *fdsp)
> +{
> +    int flags = av_get_cpu_flags();
> +
> +    if (flags & AV_CPU_FLAG_ZVE32F) {
> +        fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_rvv;
> +
> +        if (flags & AV_CPU_FLAG_ZVE64D) {
> +            fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_rvv;H
> +        }
>

Style.


> +    }
> +}
> diff --git a/libavutil/riscv/float_dsp_rvv.S b/libavutil/riscv/float_dsp_rvv.S
> new file mode 100644
> index 0000000000..54ea1d9d6d
> --- /dev/null
> +++ b/libavutil/riscv/float_dsp_rvv.S
> @@ -0,0 +1,60 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * FFmpeg is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#include "config.h"
> +#include "asm.h"
> +
> +        .option  arch, +v
> +
> +func ff_vector_fmul_scalar_rvv
> +#if !defined (__riscv_float_abi_soft)
> +        srli     a2, a2, 2
> +#else
> +        fmv.w.x  fa0, a2
> +        srli     a2, a3, 2
> +#endif
>

Can't this be handled by a macro, like it's done by arm64 and x86?
Rémi Denis-Courmont Sept. 3, 2022, 7:34 p.m. UTC | #2
Le lauantaina 3. syyskuuta 2022, 22.11.26 EEST Lynne a écrit :
> > diff --git a/libavutil/riscv/float_dsp_rvv.S
> > b/libavutil/riscv/float_dsp_rvv.S new file mode 100644
> > index 0000000000..54ea1d9d6d
> > --- /dev/null
> > +++ b/libavutil/riscv/float_dsp_rvv.S
> > @@ -0,0 +1,60 @@
> > +/*
> > + * This file is part of FFmpeg.
> > + *
> > + * FFmpeg is free software; you can redistribute it and/or
> > + * modify it under the terms of the GNU Lesser General Public
> > + * License as published by the Free Software Foundation; either
> > + * version 2.1 of the License, or (at your option) any later version.
> > + *
> > + * FFmpeg is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> > + * Lesser General Public License for more details.
> > + *
> > + * You should have received a copy of the GNU Lesser General Public
> > + * License along with FFmpeg; if not, write to the Free Software
> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> > 02110-1301 USA + */
> > +
> > +#include "config.h"
> > +#include "asm.h"
> > +
> > +        .option  arch, +v
> > +
> > +func ff_vector_fmul_scalar_rvv
> > +#if !defined (__riscv_float_abi_soft)
> > +        srli     a2, a2, 2
> > +#else
> > +        fmv.w.x  fa0, a2
> > +        srli     a2, a3, 2
> > +#endif
> 
> Can't this be handled by a macro, like it's done by arm64 and x86?

Err, from a quick glance, the float DSP code for AArch64 just assumes a 
hardware floating ABI, and has no conditionals, so I'm not sure what you mean 
by that. Do you mean something like VFP/NOVFP on AArch32?
Lynne Sept. 3, 2022, 7:48 p.m. UTC | #3
Sep 3, 2022, 21:34 by remi@remlab.net:

> Le lauantaina 3. syyskuuta 2022, 22.11.26 EEST Lynne a écrit :
>
>> > diff --git a/libavutil/riscv/float_dsp_rvv.S
>> > b/libavutil/riscv/float_dsp_rvv.S new file mode 100644
>> > index 0000000000..54ea1d9d6d
>> > --- /dev/null
>> > +++ b/libavutil/riscv/float_dsp_rvv.S
>> > @@ -0,0 +1,60 @@
>> > +/*
>> > + * This file is part of FFmpeg.
>> > + *
>> > + * FFmpeg is free software; you can redistribute it and/or
>> > + * modify it under the terms of the GNU Lesser General Public
>> > + * License as published by the Free Software Foundation; either
>> > + * version 2.1 of the License, or (at your option) any later version.
>> > + *
>> > + * FFmpeg is distributed in the hope that it will be useful,
>> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
>> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
>> > + * Lesser General Public License for more details.
>> > + *
>> > + * You should have received a copy of the GNU Lesser General Public
>> > + * License along with FFmpeg; if not, write to the Free Software
>> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
>> > 02110-1301 USA + */
>> > +
>> > +#include "config.h"
>> > +#include "asm.h"
>> > +
>> > +        .option  arch, +v
>> > +
>> > +func ff_vector_fmul_scalar_rvv
>> > +#if !defined (__riscv_float_abi_soft)
>> > +        srli     a2, a2, 2
>> > +#else
>> > +        fmv.w.x  fa0, a2
>> > +        srli     a2, a3, 2
>> > +#endif
>>
>> Can't this be handled by a macro, like it's done by arm64 and x86?
>>
>
> Err, from a quick glance, the float DSP code for AArch64 just assumes a 
> hardware floating ABI, and has no conditionals, so I'm not sure what you mean 
> by that. Do you mean something like VFP/NOVFP on AArch32?
>

I meant all ABI stuff to be handled by macros, either `func` or the instructions
themselves.
Rémi Denis-Courmont Sept. 3, 2022, 8:01 p.m. UTC | #4
Le lauantaina 3. syyskuuta 2022, 22.48.45 EEST Lynne a écrit :
> Sep 3, 2022, 21:34 by remi@remlab.net:
> > Le lauantaina 3. syyskuuta 2022, 22.11.26 EEST Lynne a écrit :
> >> > diff --git a/libavutil/riscv/float_dsp_rvv.S
> >> > b/libavutil/riscv/float_dsp_rvv.S new file mode 100644
> >> > index 0000000000..54ea1d9d6d
> >> > --- /dev/null
> >> > +++ b/libavutil/riscv/float_dsp_rvv.S
> >> > @@ -0,0 +1,60 @@
> >> > +/*
> >> > + * This file is part of FFmpeg.
> >> > + *
> >> > + * FFmpeg is free software; you can redistribute it and/or
> >> > + * modify it under the terms of the GNU Lesser General Public
> >> > + * License as published by the Free Software Foundation; either
> >> > + * version 2.1 of the License, or (at your option) any later version.
> >> > + *
> >> > + * FFmpeg is distributed in the hope that it will be useful,
> >> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> >> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> >> > + * Lesser General Public License for more details.
> >> > + *
> >> > + * You should have received a copy of the GNU Lesser General Public
> >> > + * License along with FFmpeg; if not, write to the Free Software
> >> > + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
> >> > 02110-1301 USA + */
> >> > +
> >> > +#include "config.h"
> >> > +#include "asm.h"
> >> > +
> >> > +        .option  arch, +v
> >> > +
> >> > +func ff_vector_fmul_scalar_rvv
> >> > +#if !defined (__riscv_float_abi_soft)
> >> > +        srli     a2, a2, 2
> >> > +#else
> >> > +        fmv.w.x  fa0, a2
> >> > +        srli     a2, a3, 2
> >> > +#endif
> >> 
> >> Can't this be handled by a macro, like it's done by arm64 and x86?
> > 
> > Err, from a quick glance, the float DSP code for AArch64 just assumes a
> > hardware floating ABI, and has no conditionals, so I'm not sure what you
> > mean by that. Do you mean something like VFP/NOVFP on AArch32?
> 
> I meant all ABI stuff to be handled by macros, either `func` or the
> instructions themselves.

I don't think that's possible here, at least not with reasonably low 
complexity. AArch32 has the same challenge and the func/endfunc macros don't 
handle it.
diff mbox series

Patch

diff --git a/libavutil/float_dsp.c b/libavutil/float_dsp.c
index 8676c8b0f8..742dd679d2 100644
--- a/libavutil/float_dsp.c
+++ b/libavutil/float_dsp.c
@@ -156,6 +156,8 @@  av_cold AVFloatDSPContext *avpriv_float_dsp_alloc(int bit_exact)
     ff_float_dsp_init_arm(fdsp);
 #elif ARCH_PPC
     ff_float_dsp_init_ppc(fdsp, bit_exact);
+#elif ARCH_RISCV
+    ff_float_dsp_init_riscv(fdsp);
 #elif ARCH_X86
     ff_float_dsp_init_x86(fdsp);
 #elif ARCH_MIPS
diff --git a/libavutil/float_dsp.h b/libavutil/float_dsp.h
index 9c664592bd..7cad9fc622 100644
--- a/libavutil/float_dsp.h
+++ b/libavutil/float_dsp.h
@@ -205,6 +205,7 @@  float avpriv_scalarproduct_float_c(const float *v1, const float *v2, int len);
 void ff_float_dsp_init_aarch64(AVFloatDSPContext *fdsp);
 void ff_float_dsp_init_arm(AVFloatDSPContext *fdsp);
 void ff_float_dsp_init_ppc(AVFloatDSPContext *fdsp, int strict);
+void ff_float_dsp_init_riscv(AVFloatDSPContext *fdsp);
 void ff_float_dsp_init_x86(AVFloatDSPContext *fdsp);
 void ff_float_dsp_init_mips(AVFloatDSPContext *fdsp);
 
diff --git a/libavutil/riscv/Makefile b/libavutil/riscv/Makefile
index 1f818043dc..6bf8243e8d 100644
--- a/libavutil/riscv/Makefile
+++ b/libavutil/riscv/Makefile
@@ -1 +1,3 @@ 
-OBJS += riscv/cpu.o
+OBJS += riscv/cpu.o \
+        riscv/float_dsp_init.o \
+        riscv/float_dsp_rvv.o
diff --git a/libavutil/riscv/float_dsp_init.c b/libavutil/riscv/float_dsp_init.c
new file mode 100644
index 0000000000..9a5b981917
--- /dev/null
+++ b/libavutil/riscv/float_dsp_init.c
@@ -0,0 +1,42 @@ 
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include <stdint.h>
+
+#include "libavutil/attributes.h"
+#include "libavutil/cpu.h"
+#include "libavutil/float_dsp.h"
+
+void ff_vector_fmul_scalar_rvv(float *dst, const float *src, float mul,
+                                int len);
+
+void ff_vector_dmul_scalar_rvv(double *dst, const double *src, double mul,
+                                int len);
+
+av_cold void ff_float_dsp_init_riscv(AVFloatDSPContext *fdsp)
+{
+    int flags = av_get_cpu_flags();
+
+    if (flags & AV_CPU_FLAG_ZVE32F) {
+        fdsp->vector_fmul_scalar = ff_vector_fmul_scalar_rvv;
+
+        if (flags & AV_CPU_FLAG_ZVE64D) {
+            fdsp->vector_dmul_scalar = ff_vector_dmul_scalar_rvv;
+        }
+    }
+}
diff --git a/libavutil/riscv/float_dsp_rvv.S b/libavutil/riscv/float_dsp_rvv.S
new file mode 100644
index 0000000000..54ea1d9d6d
--- /dev/null
+++ b/libavutil/riscv/float_dsp_rvv.S
@@ -0,0 +1,60 @@ 
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * FFmpeg is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with FFmpeg; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "config.h"
+#include "asm.h"
+
+        .option  arch, +v
+
+func ff_vector_fmul_scalar_rvv
+#if !defined (__riscv_float_abi_soft)
+        srli     a2, a2, 2
+#else
+        fmv.w.x  fa0, a2
+        srli     a2, a3, 2
+#endif
+1:      vsetvli  t0, a2, e32, m8, ta, ma
+        slli     t1, t0, 2
+        vle32.v  v16, (a1)
+        add      a1, a1, t1
+        vfmul.vf v16, v16, fa0
+        sub      a2, a2, t0
+        vse32.v  v16, (a0)
+        add      a0, a0, t1
+        bnez     a2, 1b
+        ret
+endfunc
+
+func ff_vector_dmul_scalar_rvv
+#if !(defined (__riscv_float_abi_soft) || defined (__riscv_float_abi_single))
+        srli     a2, a2, 3
+#else
+        fmv.d.x  fa0, a2
+        srli     a2, a3, 3
+#endif
+1:      vsetvli  t0, a2, e64, m8, ta, ma
+        slli     t1, t0, 3
+        vle64.v  v16, (a1)
+        add      a1, a1, t1
+        vfmul.vf v16, v16, fa0
+        sub      a2, a2, t0
+        vse64.v  v16, (a0)
+        add      a0, a0, t1
+        bnez     a2, 1b
+	ret
+endfunc