1  #!/usr/bin/python3
       2  # Copyright (C) 2023 Free Software Foundation, Inc.
       3  # This file is part of the GNU C Library.
       4  #
       5  # The GNU C Library is free software; you can redistribute it and/or
       6  # modify it under the terms of the GNU Lesser General Public
       7  # License as published by the Free Software Foundation; either
       8  # version 2.1 of the License, or (at your option) any later version.
       9  #
      10  # The GNU C Library is distributed in the hope that it will be useful,
      11  # but WITHOUT ANY WARRANTY; without even the implied warranty of
      12  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      13  # Lesser General Public License for more details.
      14  #
      15  # You should have received a copy of the GNU Lesser General Public
      16  # License along with the GNU C Library; if not, see
      17  # <https://www.gnu.org/licenses/>.
      18  
      19  import sys
      20  
      21  TEMPLATE = """
      22  #include <math.h>
      23  #include <arm_neon.h>
      24  
      25  #define STRIDE {stride}
      26  
      27  #define CALL_BENCH_FUNC(v, i) (__extension__ ({{                         \\
      28     {rtype} mx0 = {fname}(vld1q_f{prec_short} (variants[v].in[i].arg0));  \\
      29     mx0; }}))
      30  
      31  struct args
      32  {{
      33    {stype} arg0[STRIDE];
      34    double timing;
      35  }};
      36  
      37  struct _variants
      38  {{
      39    const char *name;
      40    int count;
      41    const struct args *in;
      42  }};
      43  
      44  static const struct args in0[{rowcount}] = {{
      45  {in_data}
      46  }};
      47  
      48  static const struct _variants variants[1] = {{
      49    {{"", {rowcount}, in0}},
      50  }};
      51  
      52  #define NUM_VARIANTS 1
      53  #define NUM_SAMPLES(i) (variants[i].count)
      54  #define VARIANT(i) (variants[i].name)
      55  
      56  static {rtype} volatile ret;
      57  
      58  #define BENCH_FUNC(i, j) ({{ ret = CALL_BENCH_FUNC(i, j); }})
      59  #define FUNCNAME "{fname}"
      60  #include <bench-libmvec-skeleton.c>
      61  """
      62  
      63  def main(name):
      64      _, prec, _, func = name.split("-")
      65      scalar_to_advsimd_type = {"double": "float64x2_t", "float": "float32x4_t"}
      66  
      67      stride = {"double": 2, "float": 4}[prec]
      68      rtype = scalar_to_advsimd_type[prec]
      69      atype = scalar_to_advsimd_type[prec]
      70      fname = f"_ZGVnN{stride}v_{func}{'f' if prec == 'float' else ''}"
      71      prec_short = {"double": 64, "float": 32}[prec]
      72  
      73      with open(f"../benchtests/libmvec/{func}-inputs") as f:
      74          in_vals = [l.strip() for l in f.readlines() if l and not l.startswith("#")]
      75      in_vals = [in_vals[i:i+stride] for i in range(0, len(in_vals), stride)]
      76      rowcount= len(in_vals)
      77      in_data = ",\n".join("{{" + ", ".join(row) + "}, 0}" for row in in_vals)
      78  
      79      print(TEMPLATE.format(stride=stride,
      80                            rtype=rtype,
      81                            atype=atype,
      82                            fname=fname,
      83                            prec_short=prec_short,
      84                            in_data=in_data,
      85                            rowcount=rowcount,
      86                            stype=prec))
      87  
      88  
      89  if __name__ == "__main__":
      90      main(sys.argv[1])