163 lines
4.1 KiB
C++
163 lines
4.1 KiB
C++
// Copyright (C) 2020-2024 Free Software Foundation, Inc.
|
|
//
|
|
// This file is part of the GNU ISO C++ Library. This library is free
|
|
// software; you can redistribute it and/or modify it under the
|
|
// terms of the GNU General Public License as published by the
|
|
// Free Software Foundation; either version 3, or (at your option)
|
|
// any later version.
|
|
//
|
|
// This library 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 General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU General Public License along
|
|
// with this library; see the file COPYING3. If not see
|
|
// <http://www.gnu.org/licenses/>.
|
|
|
|
#ifndef SIMD_TESTS_BITS_MATHREFERENCE_H_
|
|
#define SIMD_TESTS_BITS_MATHREFERENCE_H_
|
|
#include <tuple>
|
|
#include <utility>
|
|
#include <cstdio>
|
|
|
|
template <typename T>
|
|
struct SincosReference
|
|
{
|
|
T x, s, c;
|
|
|
|
std::tuple<const T &, const T &, const T &>
|
|
as_tuple() const
|
|
{ return std::tie(x, s, c); }
|
|
};
|
|
|
|
template <typename T>
|
|
struct Reference {
|
|
T x, ref;
|
|
|
|
std::tuple<const T &, const T &>
|
|
as_tuple() const
|
|
{ return std::tie(x, ref); }
|
|
};
|
|
|
|
template <typename T>
|
|
struct Array
|
|
{
|
|
std::size_t size_;
|
|
const T *data_;
|
|
|
|
Array()
|
|
: size_(0), data_(nullptr) {}
|
|
|
|
Array(size_t s, const T *p)
|
|
: size_(s), data_(p) {}
|
|
|
|
const T*
|
|
begin() const
|
|
{ return data_; }
|
|
|
|
const T*
|
|
end() const
|
|
{ return data_ + size_; }
|
|
|
|
std::size_t
|
|
size() const
|
|
{ return size_; }
|
|
};
|
|
|
|
namespace function {
|
|
struct sincos{ static constexpr const char *const str = "sincos"; };
|
|
struct atan { static constexpr const char *const str = "atan"; };
|
|
struct asin { static constexpr const char *const str = "asin"; };
|
|
struct acos { static constexpr const char *const str = "acos"; };
|
|
struct log { static constexpr const char *const str = "ln"; };
|
|
struct log2 { static constexpr const char *const str = "log2"; };
|
|
struct log10 { static constexpr const char *const str = "log10"; };
|
|
}
|
|
|
|
template <class F>
|
|
struct testdatatype_for_function
|
|
{
|
|
template <class T>
|
|
using type = Reference<T>;
|
|
};
|
|
|
|
template <>
|
|
struct testdatatype_for_function<function::sincos>
|
|
{
|
|
template <class T>
|
|
using type = SincosReference<T>;
|
|
};
|
|
|
|
template <class F, class T>
|
|
using testdatatype_for_function_t
|
|
= typename testdatatype_for_function<F>::template type<T>;
|
|
|
|
template<typename T>
|
|
struct StaticDeleter
|
|
{
|
|
const T *ptr;
|
|
|
|
StaticDeleter(const T *p)
|
|
: ptr(p) {}
|
|
|
|
~StaticDeleter()
|
|
{ delete[] ptr; }
|
|
};
|
|
|
|
template <class F, class T>
|
|
inline std::string filename()
|
|
{
|
|
static_assert(std::is_floating_point<T>::value, "");
|
|
static const auto cache
|
|
= std::string("reference-") + F::str
|
|
+ (sizeof(T) == 4 && std::__digits_v<T> == 24
|
|
&& std::__max_exponent_v<T> == 128
|
|
? "-sp"
|
|
: (sizeof(T) == 8
|
|
&& std::__digits_v<T> == 53
|
|
&& std::__max_exponent_v<T> == 1024
|
|
? "-dp"
|
|
: (sizeof(T) == 16 && std::__digits_v<T> == 64
|
|
&& std::__max_exponent_v<T> == 16384
|
|
? "-ep"
|
|
: (sizeof(T) == 16 && std::__digits_v<T> == 113
|
|
&& std::__max_exponent_v<T> == 16384
|
|
? "-qp"
|
|
: "-unknown"))))
|
|
+ ".dat";
|
|
return cache;
|
|
}
|
|
|
|
template <class Fun, class T, class Ref = testdatatype_for_function_t<Fun, T>>
|
|
Array<Ref>
|
|
referenceData()
|
|
{
|
|
static Array<Ref> data;
|
|
if (data.data_ == nullptr)
|
|
{
|
|
FILE* file = std::fopen(filename<Fun, T>().c_str(), "rb");
|
|
if (file)
|
|
{
|
|
std::fseek(file, 0, SEEK_END);
|
|
const size_t size = std::ftell(file) / sizeof(Ref);
|
|
std::rewind(file);
|
|
auto mem = new Ref[size];
|
|
static StaticDeleter<Ref> _cleanup(data.data_);
|
|
data.size_ = std::fread(mem, sizeof(Ref), size, file);
|
|
data.data_ = mem;
|
|
std::fclose(file);
|
|
}
|
|
else
|
|
{
|
|
__builtin_fprintf(
|
|
stderr,
|
|
"%s:%d: the reference data %s does not exist in the current "
|
|
"working directory.\n",
|
|
__FILE__, __LINE__, filename<Fun, T>().c_str());
|
|
__builtin_abort();
|
|
}
|
|
}
|
|
return data;
|
|
}
|
|
#endif // SIMD_TESTS_BITS_MATHREFERENCE_H_
|