(root)/
gcc-13.2.0/
libstdc++-v3/
testsuite/
experimental/
simd/
tests/
bits/
mathreference.h
       1  // Copyright (C) 2020-2023 Free Software Foundation, Inc.
       2  //
       3  // This file is part of the GNU ISO C++ Library.  This library is free
       4  // software; you can redistribute it and/or modify it under the
       5  // terms of the GNU General Public License as published by the
       6  // Free Software Foundation; either version 3, or (at your option)
       7  // any later version.
       8  //
       9  // This library is distributed in the hope that it will be useful,
      10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12  // GNU General Public License for more details.
      13  //
      14  // You should have received a copy of the GNU General Public License along
      15  // with this library; see the file COPYING3.  If not see
      16  // <http://www.gnu.org/licenses/>.
      17  
      18  #ifndef SIMD_TESTS_BITS_MATHREFERENCE_H_
      19  #define SIMD_TESTS_BITS_MATHREFERENCE_H_
      20  #include <tuple>
      21  #include <utility>
      22  #include <cstdio>
      23  
      24  template <typename T>
      25    struct SincosReference
      26    {
      27      T x, s, c;
      28  
      29      std::tuple<const T &, const T &, const T &>
      30      as_tuple() const
      31      { return std::tie(x, s, c); }
      32    };
      33  
      34  template <typename T>
      35    struct Reference {
      36      T x, ref;
      37  
      38      std::tuple<const T &, const T &>
      39      as_tuple() const
      40      { return std::tie(x, ref); }
      41    };
      42  
      43  template <typename T>
      44    struct Array
      45    {
      46      std::size_t size_;
      47      const T *data_;
      48  
      49      Array()
      50      : size_(0), data_(nullptr) {}
      51  
      52      Array(size_t s, const T *p)
      53      : size_(s), data_(p) {}
      54  
      55      const T*
      56      begin() const
      57      { return data_; }
      58  
      59      const T*
      60      end() const
      61      { return data_ + size_; }
      62  
      63      std::size_t
      64      size() const
      65      { return size_; }
      66    };
      67  
      68  namespace function {
      69    struct sincos{ static constexpr const char *const str = "sincos"; };
      70    struct atan  { static constexpr const char *const str = "atan"; };
      71    struct asin  { static constexpr const char *const str = "asin"; };
      72    struct acos  { static constexpr const char *const str = "acos"; };
      73    struct log   { static constexpr const char *const str = "ln"; };
      74    struct log2  { static constexpr const char *const str = "log2"; };
      75    struct log10 { static constexpr const char *const str = "log10"; };
      76  }
      77  
      78  template <class F>
      79    struct testdatatype_for_function
      80    {
      81      template <class T>
      82        using type = Reference<T>;
      83    };
      84  
      85  template <>
      86    struct testdatatype_for_function<function::sincos>
      87    {
      88      template <class T>
      89        using type = SincosReference<T>;
      90    };
      91  
      92  template <class F, class T>
      93    using testdatatype_for_function_t
      94      = typename testdatatype_for_function<F>::template type<T>;
      95  
      96  template<typename T>
      97    struct StaticDeleter
      98    {
      99      const T *ptr;
     100  
     101      StaticDeleter(const T *p)
     102      : ptr(p) {}
     103  
     104      ~StaticDeleter()
     105      { delete[] ptr; }
     106    };
     107  
     108  template <class F, class T>
     109    inline std::string filename()
     110    {
     111      static_assert(std::is_floating_point<T>::value, "");
     112      static const auto cache
     113        = std::string("reference-") + F::str
     114        + (sizeof(T) == 4 && std::__digits_v<T> == 24
     115  	 && std::__max_exponent_v<T> == 128
     116  	 ? "-sp"
     117  	 : (sizeof(T) == 8
     118  	    && std::__digits_v<T> == 53
     119  	    && std::__max_exponent_v<T> == 1024
     120  	    ? "-dp"
     121  	    : (sizeof(T) == 16 && std::__digits_v<T> == 64
     122  	       && std::__max_exponent_v<T> == 16384
     123  	       ? "-ep"
     124  	       : (sizeof(T) == 16 && std::__digits_v<T> == 113
     125  		  && std::__max_exponent_v<T> == 16384
     126  		  ? "-qp"
     127  		  : "-unknown"))))
     128        + ".dat";
     129      return cache;
     130    }
     131  
     132  template <class Fun, class T, class Ref = testdatatype_for_function_t<Fun, T>>
     133    Array<Ref>
     134    referenceData()
     135    {
     136      static Array<Ref> data;
     137      if (data.data_ == nullptr)
     138        {
     139  	FILE* file = std::fopen(filename<Fun, T>().c_str(), "rb");
     140  	if (file)
     141  	  {
     142  	    std::fseek(file, 0, SEEK_END);
     143  	    const size_t size = std::ftell(file) / sizeof(Ref);
     144  	    std::rewind(file);
     145  	    auto                      mem = new Ref[size];
     146  	    static StaticDeleter<Ref> _cleanup(data.data_);
     147  	    data.size_ = std::fread(mem, sizeof(Ref), size, file);
     148  	    data.data_ = mem;
     149  	    std::fclose(file);
     150  	  }
     151  	else
     152  	  {
     153  	    __builtin_fprintf(
     154  		stderr,
     155  		"%s:%d: the reference data %s does not exist in the current "
     156  		"working directory.\n",
     157  		__FILE__, __LINE__, filename<Fun, T>().c_str());
     158  	    __builtin_abort();
     159  	  }
     160        }
     161      return data;
     162    }
     163  #endif  // SIMD_TESTS_BITS_MATHREFERENCE_H_