
//==--------- builtins_marray_gen.hpp - SYCL generated built-in functions ---------==//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// NOTE: This file was generated and should not be changed!

#pragma once

#include <sycl/builtins_scalar_gen.hpp>
#include <sycl/builtins_vector_gen.hpp>

// TODO Decide whether to mark functions with this attribute.
#define __NOEXC /*noexcept*/

namespace sycl {
inline namespace _V1 {

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> acos(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = acos(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = acos(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> acosh(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = acosh(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = acosh(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> acospi(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = acospi(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = acospi(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> asin(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = asin(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = asin(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> asinh(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = asinh(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = asinh(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> asinpi(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = asinpi(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = asinpi(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> atan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = atan(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = atan(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> atan2(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = atan2(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = atan2(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> atanh(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = atanh(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = atanh(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> atanpi(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = atanpi(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = atanpi(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> atan2pi(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = atan2pi(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = atan2pi(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> cbrt(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = cbrt(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = cbrt(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> ceil(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = ceil(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = ceil(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> copysign(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = copysign(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = copysign(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> cos(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = cos(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = cos(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> cosh(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = cosh(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = cosh(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> cospi(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = cospi(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = cospi(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> erfc(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = erfc(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = erfc(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> erf(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = erf(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = erf(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> exp(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = exp(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = exp(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> exp2(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = exp2(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = exp2(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> exp10(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = exp10(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = exp10(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> expm1(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = expm1(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = expm1(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> fabs(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fabs(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fabs(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> fdim(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fdim(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fdim(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> floor(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = floor(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = floor(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> fma(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fma(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fma(a0[N - 1], a1[N - 1], a2[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> fmax(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fmax(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fmax(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> fmax(T0 a0, detail::get_elem_type_t<T0> a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fmax(detail::to_vec2(a0, I * 2), a1);
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fmax(a0[N - 1], a1);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> fmin(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fmin(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fmin(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> fmin(T0 a0, detail::get_elem_type_t<T0> a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fmin(detail::to_vec2(a0, I * 2), a1);
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fmin(a0[N - 1], a1);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> fmod(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = fmod(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = fmod(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_multi_ptr_v<T1> && detail::has_writeable_addr_space_v<T1> && detail::is_valid_elem_type_v<T1, detail::simplify_if_swizzle_t<T0>>), T0> fract(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = fract(a0[I], address_space_cast<T1::address_space, detail::get_multi_ptr_decoration_v<T1>, detail::get_elem_type_t<detail::simplify_if_swizzle_t<T0>>>(&(*a1)[I]));
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_multi_ptr_v<T1> && detail::has_writeable_addr_space_v<T1> && detail::is_valid_elem_type_v<T1, detail::change_elements_t<int, T0>>), T0> frexp(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = frexp(a0[I], address_space_cast<T1::address_space, detail::get_multi_ptr_decoration_v<T1>, detail::get_elem_type_t<detail::change_elements_t<int, T0>>>(&(*a1)[I]));
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> hypot(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = hypot(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = hypot(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), detail::int_elements_t<T0>> ilogb(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::int_elements_t<T0> Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = ilogb(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = ilogb(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, int>), T0> ldexp(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = ldexp(a0[I], a1[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> ldexp(T0 a0, int a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = ldexp(detail::to_vec2(a0, I * 2), a1);
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = ldexp(a0[N - 1], a1);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> lgamma(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = lgamma(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = lgamma(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_multi_ptr_v<T1> && detail::has_writeable_addr_space_v<T1> && detail::is_valid_elem_type_v<T1, detail::change_elements_t<int, T0>>), T0> lgamma_r(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = lgamma_r(a0[I], address_space_cast<T1::address_space, detail::get_multi_ptr_decoration_v<T1>, detail::get_elem_type_t<detail::change_elements_t<int, T0>>>(&(*a1)[I]));
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> log(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = log(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = log(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> log2(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = log2(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = log2(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> log10(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = log10(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = log10(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> log1p(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = log1p(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = log1p(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> logb(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = logb(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = logb(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mad(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mad(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mad(a0[N - 1], a1[N - 1], a2[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> maxmag(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = maxmag(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = maxmag(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> minmag(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = minmag(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = minmag(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_multi_ptr_v<T1> && detail::has_writeable_addr_space_v<T1> && detail::is_valid_elem_type_v<T1, detail::simplify_if_swizzle_t<T0>>), T0> modf(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = modf(a0[I], address_space_cast<T1::address_space, detail::get_multi_ptr_decoration_v<T1>, detail::get_elem_type_t<detail::simplify_if_swizzle_t<T0>>>(&(*a1)[I]));
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned int>), detail::nan_return_unswizzled_t<T0>> nan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::nan_return_unswizzled_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = nan(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned long, unsigned long long>), detail::nan_return_unswizzled_t<T0>> nan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::nan_return_unswizzled_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = nan(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned short>), detail::nan_return_unswizzled_t<T0>> nan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::nan_return_unswizzled_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = nan(a0[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> nextafter(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = nextafter(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = nextafter(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> pow(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = pow(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = pow(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, int>), T0> pown(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = pown(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> powr(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = powr(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = powr(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> remainder(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = remainder(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = remainder(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1> && (detail::is_multi_ptr_v<T2> && detail::has_writeable_addr_space_v<T2> && detail::is_valid_elem_type_v<T2, detail::change_elements_t<int, T0>>), T0> remquo(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = remquo(a0[I], a1[I], address_space_cast<T2::address_space, detail::get_multi_ptr_decoration_v<T2>, detail::get_elem_type_t<detail::change_elements_t<int, T0>>>(&(*a2)[I]));
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> rint(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = rint(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = rint(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, int>), T0> rootn(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = rootn(a0[I], a1[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> round(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = round(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = round(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> rsqrt(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = rsqrt(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = rsqrt(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> sin(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = sin(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = sin(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && (detail::is_multi_ptr_v<T1> && detail::has_writeable_addr_space_v<T1> && detail::is_valid_elem_type_v<T1, detail::simplify_if_swizzle_t<T0>>), T0> sincos(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = sincos(a0[I], address_space_cast<T1::address_space, detail::get_multi_ptr_decoration_v<T1>, detail::get_elem_type_t<detail::simplify_if_swizzle_t<T0>>>(&(*a1)[I]));
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> sinh(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = sinh(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = sinh(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> sinpi(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = sinpi(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = sinpi(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> sqrt(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = sqrt(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = sqrt(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> tan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = tan(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = tan(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> tanh(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = tanh(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = tanh(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> tanpi(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = tanpi(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = tanpi(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> tgamma(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = tgamma(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = tgamma(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> trunc(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = trunc(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = trunc(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> abs_diff(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = abs_diff(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> abs_diff(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = abs_diff(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> add_sat(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = add_sat(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> add_sat(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = add_sat(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> hadd(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = hadd(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> hadd(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = hadd(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> rhadd(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = rhadd(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> rhadd(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = rhadd(a0[I], a1[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>), T0> clz(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = clz(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>), T0> ctz(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = ctz(a0[I]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mad_hi(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = mad_hi(a0[I], a1[I], a2[I]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mad_hi(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = mad_hi(a0[I], a1[I], a2[I]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mad_sat(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = mad_sat(a0[I], a1[I], a2[I]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mad_sat(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = mad_sat(a0[I], a1[I], a2[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> mul_hi(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = mul_hi(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> mul_hi(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = mul_hi(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> rotate(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = rotate(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> sub_sat(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = sub_sat(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> sub_sat(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = sub_sat(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, int8_t>) && (detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, uint8_t>), detail::upsampled_int_t<T0>> upsample(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::upsampled_int_t<T0> Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = upsample(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = upsample(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, uint8_t>) && detail::check_all_same_op_type_v<T0, T1>, detail::upsampled_int_t<T0>> upsample(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::upsampled_int_t<T0> Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = upsample(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = upsample(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, int16_t>) && (detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, uint16_t>), detail::upsampled_int_t<T0>> upsample(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::upsampled_int_t<T0> Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = upsample(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = upsample(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, uint16_t>) && detail::check_all_same_op_type_v<T0, T1>, detail::upsampled_int_t<T0>> upsample(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::upsampled_int_t<T0> Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = upsample(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = upsample(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, int32_t>) && (detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, uint32_t>), detail::upsampled_int_t<T0>> upsample(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::upsampled_int_t<T0> Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = upsample(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = upsample(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, uint32_t>) && detail::check_all_same_op_type_v<T0, T1>, detail::upsampled_int_t<T0>> upsample(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::upsampled_int_t<T0> Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = upsample(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = upsample(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>), T0> popcount(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = popcount(a0[I]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, int32_t>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mad24(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mad24(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mad24(a0[N - 1], a1[N - 1], a2[N - 1]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, uint32_t>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mad24(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mad24(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mad24(a0[N - 1], a1[N - 1], a2[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, int32_t>) && detail::check_all_same_op_type_v<T0, T1>, T0> mul24(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mul24(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mul24(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, uint32_t>) && detail::check_all_same_op_type_v<T0, T1>, T0> mul24(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mul24(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mul24(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> clamp(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = clamp(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = clamp(a0[N - 1], a1[N - 1], a2[N - 1]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> clamp(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = clamp(a0[I], a1[I], a2[I]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> clamp(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = clamp(a0[I], a1[I], a2[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, float, double, half>), T0> clamp(T0 a0, detail::get_elem_type_t<T0> a1, detail::get_elem_type_t<T0> a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = clamp(a0[I], a1, a2);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> degrees(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = degrees(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = degrees(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> (max)(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = (max)(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = (max)(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> (max)(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = (max)(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> (max)(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = (max)(a0[I], a1[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, float, double, half>), T0> (max)(T0 a0, detail::get_elem_type_t<T0> a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = (max)(a0[I], a1);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> (min)(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = (min)(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = (min)(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> (min)(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = (min)(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>) && detail::check_all_same_op_type_v<T0, T1>, T0> (min)(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = (min)(a0[I], a1[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, float, double, half>), T0> (min)(T0 a0, detail::get_elem_type_t<T0> a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = (min)(a0[I], a1);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> mix(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mix(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mix(a0[N - 1], a1[N - 1], a2[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>) && detail::check_all_same_op_type_v<T0, T1>, T0> mix(T0 a0, T1 a1, float a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mix(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), a2);
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mix(a0[N - 1], a1[N - 1], a2);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double>) && detail::check_all_same_op_type_v<T0, T1>, T0> mix(T0 a0, T1 a1, double a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mix(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), a2);
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mix(a0[N - 1], a1[N - 1], a2);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> mix(T0 a0, T1 a1, half a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = mix(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), a2);
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = mix(a0[N - 1], a1[N - 1], a2);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> radians(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = radians(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = radians(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, T0> step(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = step(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = step(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T1>
std::enable_if_t<(detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, float>), T1> step(float a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T1>::value;
  T1 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = step(a0, detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = step(a0, a1[N - 1]);
  return Res;
}

template <typename T1>
std::enable_if_t<(detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, double>), T1> step(double a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T1>::value;
  T1 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = step(a0, detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = step(a0, a1[N - 1]);
  return Res;
}

template <typename T1>
std::enable_if_t<(detail::is_marray_v<T1> && detail::is_valid_elem_type_v<T1, half>), T1> step(half a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T1>::value;
  T1 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = step(a0, detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = step(a0, a1[N - 1]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> smoothstep(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = smoothstep(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2), detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = smoothstep(a0[N - 1], a1[N - 1], a2[N - 1]);
  return Res;
}

template <typename T2>
std::enable_if_t<(detail::is_marray_v<T2> && detail::is_valid_elem_type_v<T2, float>), T2> smoothstep(float a0, float a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T2>::value;
  T2 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = smoothstep(a0, a1, detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = smoothstep(a0, a1, a2[N - 1]);
  return Res;
}

template <typename T2>
std::enable_if_t<(detail::is_marray_v<T2> && detail::is_valid_elem_type_v<T2, double>), T2> smoothstep(double a0, double a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T2>::value;
  T2 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = smoothstep(a0, a1, detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = smoothstep(a0, a1, a2[N - 1]);
  return Res;
}

template <typename T2>
std::enable_if_t<(detail::is_marray_v<T2> && detail::is_valid_elem_type_v<T2, half>), T2> smoothstep(half a0, half a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T2>::value;
  T2 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = smoothstep(a0, a1, detail::to_vec2(a2, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = smoothstep(a0, a1, a2[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> sign(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = sign(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = sign(a0[N - 1]);
  return Res;
}

template <typename T0>
__SYCL_DEPRECATED("abs for floating point types is non-standard and has been deprecated. Please use fabs instead.")
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), T0> abs(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = abs(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = abs(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>), T0> abs(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = abs(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long>), T0> abs(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = abs(a0[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, T0> cross(T0 a0, T1 a1) __NOEXC {
  return detail::to_marray(cross(detail::to_vec(a0), detail::to_vec(a1)));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, T0> cross(T0 a0, T1 a1) __NOEXC {
  return detail::to_marray(cross(detail::to_vec(a0), detail::to_vec(a1)));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, T0> cross(T0 a0, T1 a1) __NOEXC {
  return detail::to_marray(cross(detail::to_vec(a0), detail::to_vec(a1)));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, float> dot(T0 a0, T1 a1) __NOEXC {
  return dot(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, double> dot(T0 a0, T1 a1) __NOEXC {
  return dot(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, half> dot(T0 a0, T1 a1) __NOEXC {
  return dot(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, float> distance(T0 a0, T1 a1) __NOEXC {
  return distance(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, double> distance(T0 a0, T1 a1) __NOEXC {
  return distance(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, half> distance(T0 a0, T1 a1) __NOEXC {
  return distance(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), float> length(T0 a0) __NOEXC {
  return length(detail::to_vec(a0));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), double> length(T0 a0) __NOEXC {
  return length(detail::to_vec(a0));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), half> length(T0 a0) __NOEXC {
  return length(detail::to_vec(a0));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), T0> normalize(T0 a0) __NOEXC {
  return detail::to_marray(normalize(detail::to_vec(a0)));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), T0> normalize(T0 a0) __NOEXC {
  return detail::to_marray(normalize(detail::to_vec(a0)));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), T0> normalize(T0 a0) __NOEXC {
  return detail::to_marray(normalize(detail::to_vec(a0)));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, float> fast_distance(T0 a0, T1 a1) __NOEXC {
  return fast_distance(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, double> fast_distance(T0 a0, T1 a1) __NOEXC {
  return fast_distance(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 1, 2, 3, 4>) && detail::check_all_same_op_type_v<T0, T1>, half> fast_distance(T0 a0, T1 a1) __NOEXC {
  return fast_distance(detail::to_vec(a0), detail::to_vec(a1));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), float> fast_length(T0 a0) __NOEXC {
  return fast_length(detail::to_vec(a0));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), double> fast_length(T0 a0) __NOEXC {
  return fast_length(detail::to_vec(a0));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), half> fast_length(T0 a0) __NOEXC {
  return fast_length(detail::to_vec(a0));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), T0> fast_normalize(T0 a0) __NOEXC {
  return detail::to_marray(fast_normalize(detail::to_vec(a0)));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, double> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), T0> fast_normalize(T0 a0) __NOEXC {
  return detail::to_marray(fast_normalize(detail::to_vec(a0)));
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, half> && detail::is_valid_size_v<T0, 1, 2, 3, 4>), T0> fast_normalize(T0 a0) __NOEXC {
  return detail::to_marray(fast_normalize(detail::to_vec(a0)));
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> isequal(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isequal(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> isnotequal(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isnotequal(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> isgreater(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isgreater(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> isgreaterequal(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isgreaterequal(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> isless(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isless(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> islessequal(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = islessequal(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> islessgreater(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = islessgreater(a0[I], a1[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), detail::bool_elements_t<T0>> isfinite(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isfinite(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), detail::bool_elements_t<T0>> isinf(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isinf(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), detail::bool_elements_t<T0>> isnan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isnan(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), detail::bool_elements_t<T0>> isnormal(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isnormal(a0[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> isordered(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isordered(a0[I], a1[I]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>) && detail::check_all_same_op_type_v<T0, T1>, detail::bool_elements_t<T0>> isunordered(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = isunordered(a0[I], a1[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float, double, half>), detail::bool_elements_t<T0>> signbit(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  detail::bool_elements_t<T0> Res;
  for (int I = 0; I < N; ++I)
    Res[I] = signbit(a0[I]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>), bool> any(T0 a0) __NOEXC {
  return std::any_of(a0.begin(), a0.end(), [](detail::get_elem_type_t<T0> X) { return any(X); });
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long>), bool> all(T0 a0) __NOEXC {
  return std::all_of(a0.begin(), a0.end(), [](detail::get_elem_type_t<T0> X) { return all(X); });
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, float, double, half>) && detail::check_all_same_op_type_v<T0, T1, T2>, T0> bitselect(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = bitselect(a0[I], a1[I], a2[I]);
  return Res;
}

template <typename T0, typename T1, typename T2>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, char, signed char, short, int, long, long long, unsigned char, unsigned short, unsigned int, unsigned long, unsigned long long, float, double, half>) && detail::check_all_same_op_type_v<T0, T1> && (detail::is_marray_v<T2> && detail::is_valid_elem_type_v<T2, bool>), T0> select(T0 a0, T1 a1, T2 a2) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (int I = 0; I < N; ++I)
    Res[I] = select(a0[I], a1[I], a2[I]);
  return Res;
}

namespace native {
template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> cos(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::cos(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::cos(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>) && detail::check_all_same_op_type_v<T0, T1>, T0> divide(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::divide(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::divide(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> exp(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::exp(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::exp(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> exp2(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::exp2(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::exp2(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> exp10(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::exp10(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::exp10(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> log(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::log(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::log(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> log2(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::log2(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::log2(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> log10(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::log10(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::log10(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>) && detail::check_all_same_op_type_v<T0, T1>, T0> powr(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::powr(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::powr(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> recip(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::recip(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::recip(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> rsqrt(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::rsqrt(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::rsqrt(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> sin(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::sin(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::sin(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> sqrt(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::sqrt(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::sqrt(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> tan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = native::tan(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = native::tan(a0[N - 1]);
  return Res;
}
} // namespace native

namespace half_precision {
template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> cos(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::cos(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::cos(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>) && detail::check_all_same_op_type_v<T0, T1>, T0> divide(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::divide(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::divide(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> exp(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::exp(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::exp(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> exp2(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::exp2(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::exp2(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> exp10(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::exp10(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::exp10(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> log(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::log(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::log(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> log2(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::log2(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::log2(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> log10(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::log10(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::log10(a0[N - 1]);
  return Res;
}

template <typename T0, typename T1>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>) && detail::check_all_same_op_type_v<T0, T1>, T0> powr(T0 a0, T1 a1) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::powr(detail::to_vec2(a0, I * 2), detail::to_vec2(a1, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::powr(a0[N - 1], a1[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> recip(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::recip(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::recip(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> rsqrt(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::rsqrt(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::rsqrt(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> sin(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::sin(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::sin(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> sqrt(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::sqrt(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::sqrt(a0[N - 1]);
  return Res;
}

template <typename T0>
std::enable_if_t<(detail::is_marray_v<T0> && detail::is_valid_elem_type_v<T0, float>), T0> tan(T0 a0) __NOEXC {
  constexpr size_t N = detail::num_elements<T0>::value;
  T0 Res;
  for (size_t I = 0; I < N / 2; ++I) {
    auto PartialRes = half_precision::tan(detail::to_vec2(a0, I * 2));
    std::memcpy(&Res[I * 2], &PartialRes, sizeof(decltype(PartialRes)));
  }
  if (N % 2)
    Res[N - 1] = half_precision::tan(a0[N - 1]);
  return Res;
}
} // namespace half_precision

} // namespace _V1
} // namespace sycl

#undef __NOEXC
