/*
(C) 2008-2026 Advanced Micro Devices, Inc. All Rights Reserved.

Advanced Micro Devices, Inc.
Software License Agreement

IMPORTANT-READ CAREFULLY:  Do not load or use the Software until you have
carefully read and agreed to the following terms and conditions.  This is a
legal agreement ("Agreement") between you (either an individual or an entity)
("Licensee") and Advanced Micro Devices, Inc. ("AMD"). If Licensee does not
agree to the terms of this Agreement, do not install or use this software or
any portion thereof.  By loading or using the object code version only of the
software obtained herewith, which may include associated install scripts and
online or electronic documentation or any portion thereof, that is made
available by AMD to download from any media ("Software"), Licensee agrees to
all of the terms of this Agreement.

1.  LICENSE:

    a.  Subject to the terms and conditions of this Agreement, AMD grants
    Licensee the following non-exclusive, non-transferable, royalty-free,
    limited copyright license to download, copy, use, distribute and sublicense
    the foregoing rights through multiple tiers of sublicenses the object code
    version of the Software and materials associated with this Agreement,
    including without limitation printed documentation, (collectively,
    "Materials"), provided that Licensee agrees to include all copyright
    legends and other legal notices that may appear in the Materials.  The
    foregoing license is conditioned upon Licensee distributing the object code
    version of the Software only and under this software license agreement.
    Except for the limited license granted herein, Licensee shall have no other
    rights in the Materials, whether express, implied, arising by estoppel or
    otherwise.

    b.  Except as expressly set forth in Section 1(a), Licensee does not have
    the right to (i) distribute, rent, lease, sell, sublicense, assign, or
    otherwise transfer the Materials, in whole or in part, to third parties for
    commercial or for non-commercial use; or (ii) modify, disassemble, reverse
    engineer, or decompile the Software, or otherwise reduce any part of the
    Software to any human readable form.  All rights in and to the Materials
    not expressly granted to Licensee in this Agreement are reserved to AMD.

2.  FEEDBACK:  Licensee may provide AMD feedback, suggestions or opinions as to
the Software, its features, and desired enhancements or changes.  If Licensee
provides feedback, suggestions or opinions to AMD regarding any new features,
use, functionality, or change to the Software or any materials related to the
Software, Licensee hereby agrees to grant, and does grant, AMD all rights
needed for AMD to incorporate, modify, distribute, use and commercialize any
new feature, use, functionality, or change at no charge or encumbrance to AMD.
Licensee agrees that AMD may disclose such feedback, suggestions or opinions to
any third party in any manner, and Licensee agrees that AMD has the ability to
sublicense any of the foregoing rights in any feedback, suggestions or opinions
or AMD products or services in any form to any third party without restriction.

3.  OWNERSHIP AND COPYRIGHT OF MATERIALS: Licensee agrees that the Materials
are owned by AMD and are protected by United States and foreign intellectual
property laws (e.g. patent and copyright laws) and international treaty
provisions.  Licensee will not remove the copyright notice from the Materials.
Licensee agrees to prevent any unauthorized copying of the Materials.  All
title and copyrights in and to the Materials, all copies thereof (in whole or
in part, and in any form), and all rights therein shall remain vested in AMD.
Except as expressly provided herein, AMD does not grant any express or implied
right to Licensee under AMD patents, copyrights, trademarks, or trade secret
information.

4.  WARRANTY DISCLAIMER: THE MATERIALS ARE PROVIDED "AS IS" WITHOUT ANY EXPRESS
OR IMPLIED WARRANTY OF ANY KIND INCLUDING WARRANTIES OF MERCHANTABILITY,
NONINFRINGEMENT OF THIRD-PARTY INTELLECTUAL PROPERTY, TITLE, OR FITNESS FOR ANY
PARTICULAR PURPOSE, OR THOSE ARISING FROM CUSTOM OF TRADE OR COURSE OF USAGE.
THE ENTIRE RISK ARISING OUT OF USE OR PERFORMANCE OF THE MATERIALS REMAINS WITH
LICENSEE.  AMD DOES NOT WARRANT, GUARANTEE, OR MAKE ANY REPRESENTATIONS AS TO
THE CORRECTNESS, ACCURACY, COMPLETENESS, QUALITY, OR RELIABILITY OF THE
MATERIALS.

AMD DOES NOT WARRANT THAT OPERATION OF THE MATERIALS WILL BE UNINTERRUPTED OR
ERROR-FREE.  YOU ARE RESPONSIBLE FOR DETERMINING THE APPROPRIATENESS OF USING
THE SOFTWARE AND ASSUME ALL RISKS ASSOCIATED WITH THE USE OF THE MATERIALS,
INCLUDING BUT NOT LIMITED TO THE RISKS OF PROGRAM ERRORS, DAMAGE TO OR LOSS OF
DATA, PROGRAMS OR EQUIPMENT, AND UNAVAILABILITY OR INTERRUPTION OF OPERATIONS.
SOME JURISDICTIONS DO NOT ALLOW FOR THE EXCLUSION OR LIMITATION OF IMPLIED
WARRANTIES, SO THE ABOVE LIMITATIONS OR EXCLUSIONS MAY NOT APPLY TO LICENSEE.

5.  LIMITATION OF LIABILITY:  IN NO EVENT SHALL AMD OR ITS DIRECTORS, OFFICERS,
EMPLOYEES AND AGENTS, ITS SUPPLIERS OR ITS LICENSORS BE LIABLE TO LICENSEE OR
ANY THIRD PARTIES IN RECEIPT OF THE MATERIALS FOR CONSEQUENTIAL, INCIDENTAL,
PUNITIVE OR SPECIAL DAMAGES, INCLUDING, BUT NOT LIMITED TO LOSS OF PROFITS,
BUSINESS INTERRUPTION, OR LOSS OF INFORMATION ARISING OUT OF THE USE OF OR
INABILITY TO USE THE MATERIALS, EVEN IF AMD HAS BEEN ADVISED OF THE POSSIBILITY
OF SUCH DAMAGES.  AMD DOES NOT ASSUME ANY RESPONSIBILITY TO SUPPORT OR UPDATE
THE MATERIALS.  BY USING THE MATERIALS WITHOUT CHARGE, YOU ACCEPT THIS
ALLOCATION OF RISK.  BECAUSE SOME JURSIDICTIONS PROHIBIT THE EXCLUSION OR
LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE
LIMITATION MAY NOT APPLY TO LICENSEE.

6.  U.S. GOVERNMENT RESTRICTED RIGHTS: The Materials are provided with
"RESTRICTED RIGHTS."  Use, duplication or disclosure by the Government is
subject to restrictions as set forth in FAR52.227-14 and DFAR252.227-7013, et
seq., or its successor.  Use of the Materials by the Government constitutes
acknowledgment of AMD's proprietary rights in them.

7.  TERMINATION OF LICENSE: This Agreement will terminate immediately without
notice from AMD or judicial resolution if Licensee fails to comply with any
provisions of this Agreement.  Upon termination of this Agreement, Licensee
must delete or destroy all copies of the Materials.

8.  SUPPORT.  Under this Agreement, AMD is under no obligation to assist in the
use of the Materials, to provide support to licensees of the Materials, or to
provide maintenance, correction, modification, enhancement, or upgrades to the
Materials.  If AMD determines, in its sole discretion, to support, maintain,
correct, modify, enhance, or upgrade the Software, such support, maintenance,
correction, modification, enhancement or upgrade shall be considered part of
the Materials, and shall be subject to this Agreement.

9.  SURVIVAL:  Sections 1(b), 2, 3, 4, 5, 6, and 8 through 14 shall survive any
expiration or termination of this Agreement.

10. APPLICABLE LAWS:  Any claim arising under or relating to this Agreement
shall be governed by and construed in accordance with the substantive laws of
the State of California, without regard to principles of conflict of laws.
Each party hereto submits to the jurisdiction of the state and federal courts
of Santa Clara County and the Northern District of California for the purposes
of all legal proceedings arising out of or relating to this Agreement or the
subject matter hereof.  Each party waives any objection which it may have to
contest such forum.

11. IMPORT/EXPORT/RE-EXPORT/USE/RELEASE/TRANSFER RESTRICTIONS AND COMPLIANCE
WITH LAWS:  Licensee is hereby provided notice, and agrees and acknowledges,
that the Software, its source code, any accompanying media, material or
information, and any product of the foregoing, may be subject to restrictions
on use, release, transfer, importation, exportation and/or re- exportation
under the laws and regulations of the United States or other countries
("Applicable Laws"), which include but are not limited to U.S. export control
laws such as the Export Administration Regulations and national security
controls as defined thereunder, as well as State Department controls under the
U.S. Munitions List.  Licensee further agrees that the Software, its source
code, any accompanying media, material or information, and any product of the
foregoing, will not be used, released, transferred, imported, exported and/or
re-exported in any manner prohibited under Applicable Laws, including U.S.
export control laws regarding specifically designated persons, countries and
nationals of countries subject to national security controls as provided in
License Exception TSR of the Export Administration Regulations and any
successor regulations.

12. SEVERABILITY:  Should any term of this Agreement be declared void or
unenforceable by any court of competent jurisdiction, such declaration shall
have no effect on the remaining terms hereof.

13. NO WAIVER:  The failure of either party to enforce any rights granted
hereunder or to take action against the other party in the event of any breach
hereunder shall not be deemed a waiver by that party as to subsequent
enforcement of rights or subsequent actions in the event of future breaches.

14. ENTIRE AGREEMENT:  This Agreement constitutes the entire agreement between
the parties and supersedes any prior or contemporaneous oral or written
agreements with respect to the subject matter of this Agreement.
*/


/** @file amdlibm_vec.h
 *  @brief AOCL-LibM header file for vector variant.
 *
 *  This file declares the public APIs from AOCL-LibM library.
 */

#ifndef __AMDLIBM_VEC_H__
#define __AMDLIBM_VEC_H__


#include <emmintrin.h>
#include <immintrin.h>


#if defined(_WIN64) || defined(_WIN32)
  /* Windows */
  #if defined(__AVX512F__)
    #if __has_include(<avx512fintrin.h>)
      #include <avx512fintrin.h>
    #endif
  #endif /* __AVX512F__ */
#endif


#ifdef __cplusplus
extern "C" {
#endif

#if defined (__AVX__)
/* Trigonometric */
  /**
   * @brief Computes sine for two double-precision lanes.
   * @param x Vector of two angles in radians.
   * @return Vector of sines.
   */
  __m128d amd_vrd2_sin (__m128d x);
  /**
   * @brief Computes sine for four single-precision lanes.
   * @param x Vector of four angles in radians.
   * @return Vector of sines.
   */
  __m128 amd_vrs4_sinf (__m128 x);

  /**
   * @brief Computes cosine for two double-precision lanes.
   * @param x Vector of two angles in radians.
   * @return Vector of cosines.
   */
  __m128d amd_vrd2_cos (__m128d x);
  /**
   * @brief Computes cosine for four single-precision lanes.
   * @param x Vector of four angles in radians.
   * @return Vector of cosines.
   */
  __m128 amd_vrs4_cosf (__m128 x);

  /**
   * @brief Computes tangent for two double-precision lanes.
   * @param x Vector of two angles in radians.
   * @return Vector of tangents.
   */
  __m128d amd_vrd2_tan (__m128d x);
  /**
   * @brief Computes tangent for four single-precision lanes.
   * @param x Vector of four angles in radians.
   * @return Vector of tangents.
   */
  __m128 amd_vrs4_tanf (__m128 x);

  /**
   * @brief Computes both sine and cosine for two double-precision lanes.
   * @param x Vector of two angles in radians.
   * @param sin Output pointer for vector of sines.
   * @param cos Output pointer for vector of cosines.
   */
  void amd_vrd2_sincos (__m128d x, __m128d *sin, __m128d *cos);
  /**
   * @brief Computes both sine and cosine for four single-precision lanes.
   * @param x Vector of four angles in radians.
   * @param sin Output pointer for vector of sines.
   * @param cos Output pointer for vector of cosines.
   */
  void amd_vrs4_sincosf (__m128 x, __m128 *sin, __m128 *cos);

/* Inverse Trigonometric */
  /**
   * @brief Computes arc-sine for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-sines in radians.
   */
  __m128d amd_vrd2_asin (__m128d x);
  /**
   * @brief Computes arc-sine for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-sines in radians.
   */
  __m128 amd_vrs4_asinf (__m128 x);

  /**
   * @brief Computes arc-cosine for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-cosines in radians.
   */
  __m128d amd_vrd2_acos (__m128d x);
  /**
   * @brief Computes arc-cosine for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-cosines in radians.
   */
  __m128 amd_vrs4_acosf (__m128 x);

  /**
   * @brief Computes arc-tangent for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-tangents in radians.
   */
  __m128d amd_vrd2_atan (__m128d x);
  /**
   * @brief Computes arc-tangent for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-tangents in radians.
   */
  __m128 amd_vrs4_atanf (__m128 x);

/* Hyperbolic */
  /**
   * @brief Computes hyperbolic cosine for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of cosh values.
   */
  __m128d amd_vrd2_cosh (__m128d x);
  /**
   * @brief Computes hyperbolic cosine for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of cosh values.
   */
  __m128 amd_vrs4_coshf (__m128 x);

  /**
   * @brief Computes hyperbolic tangent for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of tanh values.
   */
  __m128 amd_vrs4_tanhf (__m128 x);

/* Exponential */
  /**
   * @brief Computes e^x for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of exponentials.
   */
  __m128d amd_vrd2_exp (__m128d x);
  /**
   * @brief Computes e^x for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of exponentials.
   */
  __m128 amd_vrs4_expf (__m128 x);

  /**
   * @brief Computes 2^x for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of base-2 exponentials.
   */
  __m128d amd_vrd2_exp2 (__m128d x);
  /**
   * @brief Computes 2^x for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of base-2 exponentials.
   */
  __m128 amd_vrs4_exp2f (__m128 x);

  /**
   * @brief Computes 10^x for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of base-10 exponentials.
   */
  __m128d amd_vrd2_exp10 (__m128d x);
  /**
   * @brief Computes 10^x for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of base-10 exponentials.
   */
  __m128 amd_vrs4_exp10f (__m128 x);
  /**
   * @brief Computes exp(x)-1 for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of expm1 values.
   */
  __m128 amd_vrs4_expm1f (__m128 x);


/* Logarithmic */
  /**
   * @brief Computes natural logarithm for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of ln values.
   */
  __m128d amd_vrd2_log (__m128d x);
  /**
   * @brief Computes natural logarithm for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of ln values.
   */
  __m128 amd_vrs4_logf (__m128 x);

  /**
   * @brief Computes base-2 logarithm for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of log2 values.
   */
  __m128d amd_vrd2_log2 (__m128d x);
  /**
   * @brief Computes base-2 logarithm for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of log2 values.
   */
  __m128 amd_vrs4_log2f (__m128 x);

  /**
   * @brief Computes base-10 logarithm for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of log10 values.
   */
  __m128d amd_vrd2_log10 (__m128d x);
  /**
   * @brief Computes base-10 logarithm for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of log10 values.
   */
  __m128 amd_vrs4_log10f (__m128 x);

  /**
   * @brief Computes log(1+x) for two double-precision lanes.
   * @param x Input vector.
   * @return Vector of log1p values.
   */
  __m128d amd_vrd2_log1p (__m128d x);
  /**
   * @brief Computes log(1+x) for four single-precision lanes.
   * @param x Input vector.
   * @return Vector of log1p values.
   */
  __m128 amd_vrs4_log1pf (__m128 x);


/* Power & Root */
  /**
   * @brief Raises elements of x to powers in y (two double-precision lanes).
   * @param x Base vector.
   * @param y Exponent vector.
   * @return Vector of x^y.
   */
  __m128d amd_vrd2_pow  (__m128d x, __m128d y);
  /**
   * @brief Raises elements of x to powers in y (four single-precision lanes).
   * @param x Base vector.
   * @param y Exponent vector.
   * @return Vector of x^y.
   */
  __m128 amd_vrs4_powf  (__m128 x, __m128 y);

  /**
   * @brief Raises elements of x to a scalar double-precision exponent.
   * @param x Base vector.
   * @param y Scalar exponent.
   * @return Vector of x^y.
   */
  __m128d amd_vrd2_powx (__m128d x, double y);
  /**
   * @brief Raises elements of x to a scalar single-precision exponent.
   * @param x Base vector.
   * @param y Scalar exponent.
   * @return Vector of x^y.
   */
  __m128 amd_vrs4_powxf (__m128 x, float y);

  /**
   * @brief Computes square root per-lane for two double-precision elements.
   * @param x Input vector.
   * @return Vector of square roots.
   */
  __m128d amd_vrd2_sqrt (__m128d x);
  /**
   * @brief Computes square root per-lane for four single-precision elements.
   * @param x Input vector.
   * @return Vector of square roots.
   */
  __m128 amd_vrs4_sqrtf (__m128 x);

  /**
   * @brief Computes cube root per-lane for two double-precision elements.
   * @param x Input vector.
   * @return Vector of cube roots.
   */
  __m128d amd_vrd2_cbrt (__m128d x);
  /**
   * @brief Computes cube root per-lane for four single-precision elements.
   * @param x Input vector.
   * @return Vector of cube roots.
   */
  __m128 amd_vrs4_cbrtf (__m128 x);


/* Error */
  /**
   * @brief Computes erf per-lane for two double-precision elements.
   * @param x Input vector.
   * @return Vector of erf values.
   */
  __m128d amd_vrd2_erf (__m128d x);
  /**
   * @brief Computes erf per-lane for four single-precision elements.
   * @param x Input vector.
   * @return Vector of erf values.
   */
  __m128 amd_vrs4_erff (__m128 x);

/* Complementary Error */
  /**
   * @brief Computes erfc per-lane for two double-precision elements.
   * @param x Input vector.
   * @return Vector of erfc values.
   */
  __m128d amd_vrd2_erfc (__m128d x);
  /**
   * @brief Computes erfc per-lane for four single-precision elements.
   * @param x Input vector.
   * @return Vector of erfc values.
   */
  __m128 amd_vrs4_erfcf (__m128 x);

/* Inverse Error */
  /**
   * @brief Computes Inverse Error function per-lane for two double-precision elements.
   * @param x Input vector.
   * @return Vector of erfinv values.
   */
  __m128d amd_vrd2_erfinv (__m128d x);
  /**
   * @brief Computes Inverse Error function per-lane for four double-precision elements.
   * @param x Input vector.
   * @return Vector of erfinv values.
   */
  __m256d amd_vrd4_erfinv (__m256d x);
/* Inverse Complementary Error */
  /**
   * @brief Computes erfcinv per-lane for two double-precision elements.
   * @param x Input vector.
   * @return Vector of erfcinv values.
   */
  __m128d amd_vrd2_erfcinv (__m128d x);

/* Inverse Cumulative Normal Distribution */
  /**
   * @brief Computes cdfnorminv per-lane for two double-precision elements.
   * @param x Input vector with values in (0, 1).
   * @return Vector of cdfnorminv values.
   */
  __m128d amd_vrd2_cdfnorminv (__m128d x);
/* Remainder */
  /**
   * @brief Computes absolute value per-lane for two double-precision elements.
   * @param x Input vector.
   * @return Vector of absolute values.
   */
  __m128d amd_vrd2_fabs (__m128d x);
  /**
   * @brief Computes absolute value per-lane for four single-precision elements.
   * @param x Input vector.
   * @return Vector of absolute values.
   */
  __m128 amd_vrs4_fabsf (__m128 x);

/* Nearest Integer */
  /**
   * @brief Computes round per-lane for two double-precision elements.
   * @param x Input vector x.
   * @return Vector of rounded value.
   */
  __m128d amd_vrd2_round (__m128d x);
  /**
   * @brief Computes round per-lane for four single-precision elements.
   * @param x Input vector x.
   * @return Vector of rounded value.
   */
  __m128 amd_vrs4_roundf (__m128 x);

/* Cumulative Normal Distribution */
  /**
   * @brief Computes cumulative normal distribution for two double-precision elements.
   * @param x Input vector x
   * @return Vector of cdfnorm values
   */
  __m128d amd_vrd2_cdfnorm (__m128d x);

/* Linearfrac */
  /**
   * @brief Computes a linear fractional transform for two double-precision lanes.
   * @param x Input vector x.
   * @param y Input vector y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @return Result vector of the transform.
   */
  __m128d amd_vrd2_linearfrac (__m128d x, __m128d y,
                               double scx, double shx,
                               double scy, double shy);

  /**
   * @brief Computes a linear fractional transform for four single-precision lanes.
   * @param x Input vector x.
   * @param y Input vector y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @return Result vector of the transform.
   */
  __m128 amd_vrs4_linearfracf (__m128 x, __m128 y,
                               float scx, float shx,
                               float scy, float shy);

#endif /* __AVX__ */


#if defined (__AVX2__)
/* Trigonometric */
  /**
   * @brief Computes sine for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of sines.
   */
  __m256d amd_vrd4_sin (__m256d x);
  /**
   * @brief Computes sine for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of sines.
   */
  __m256 amd_vrs8_sinf (__m256 x);

  /**
   * @brief Computes cosine for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of cosines.
   */
  __m256d amd_vrd4_cos (__m256d x);
  /**
   * @brief Computes cosine for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of cosines.
   */
  __m256 amd_vrs8_cosf (__m256 x);

  /**
   * @brief Computes tangent for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of tangents.
   */
  __m256d amd_vrd4_tan (__m256d x);
  /**
   * @brief Computes tangent for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of tangents.
   */
  __m256 amd_vrs8_tanf (__m256 x);

  /**
   * @brief Computes both sine and cosine per-lane for four double-precision elements.
   * @param x Input vector.
   * @param sin Output pointer for sines.
   * @param cos Output pointer for cosines.
   */
  void amd_vrd4_sincos (__m256d x, __m256d *sin, __m256d *cos);
  /**
   * @brief Computes both sine and cosine per-lane for eight single-precision elements.
   * @param x Input vector.
   * @param sin Output pointer for sines.
   * @param cos Output pointer for cosines.
   */
  void amd_vrs8_sincosf (__m256 x, __m256 *sin, __m256 *cos);

/* Inverse Trigonometric */
  /**
   * @brief Computes arc-sine for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-sines in radians.
   */
  __m256d amd_vrd4_asin (__m256d x);
  /**
   * @brief Computes arc-sine for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-sines in radians.
   */
  __m256 amd_vrs8_asinf (__m256 x);

  /**
   * @brief Computes arc-cosine for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-cosines in radians.
   */
  __m256d amd_vrd4_acos (__m256d x);
  /**
   * @brief Computes arc-cosine for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-cosines in radians.
   */
  __m256 amd_vrs8_acosf (__m256 x);

  /**
   * @brief Computes arc-tangent for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-tangents in radians.
   */
  __m256d amd_vrd4_atan (__m256d x);
  /**
   * @brief Computes arc-tangent for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-tangents in radians.
   */
  __m256 amd_vrs8_atanf (__m256 x);


/* Hyperbolic */
  /**
   * @brief Computes hyperbolic cosine for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of cosh values.
   */
  __m256 amd_vrs8_coshf (__m256 x);
  /**
   * @brief Computes hyperbolic tangent for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of tanh values.
   */
  __m256 amd_vrs8_tanhf (__m256 x);

/* Exponential */
  /**
   * @brief Computes e^x for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of exponentials.
   */
  __m256d amd_vrd4_exp (__m256d x);
  /**
   * @brief Computes e^x for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of exponentials.
   */
  __m256 amd_vrs8_expf (__m256 x);

  /**
   * @brief Computes 2^x for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of base-2 exponentials.
   */
  __m256d amd_vrd4_exp2 (__m256d x);
  /**
   * @brief Computes 2^x for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of base-2 exponentials.
   */
  __m256 amd_vrs8_exp2f (__m256 x);

/* Logarithmic */
  /**
   * @brief Computes natural logarithm for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of ln values.
   */
  __m256d amd_vrd4_log (__m256d x);
  /**
   * @brief Computes natural logarithm for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of ln values.
   */
  __m256 amd_vrs8_logf (__m256 x);

  /**
   * @brief Computes base-2 logarithm for four double-precision lanes.
   * @param x Input vector.
   * @return Vector of log2 values.
   */
  __m256d amd_vrd4_log2 (__m256d x);
  /**
   * @brief Computes base-2 logarithm for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of log2 values.
   */
  __m256 amd_vrs8_log2f (__m256 x);

  /**
   * @brief Computes base-10 logarithm for eight single-precision lanes.
   * @param x Input vector.
   * @return Vector of log10 values.
   */
  __m256 amd_vrs8_log10f (__m256 x);

/* Power & Root */
  /**
   * @brief Raises elements of x to powers in y (four double-precision lanes).
   * @param x Base vector.
   * @param y Exponent vector.
   * @return Vector of x^y.
   */
  __m256d amd_vrd4_pow (__m256d x, __m256d y);
  /**
   * @brief Raises elements of x to powers in y (eight single-precision lanes).
   * @param x Base vector.
   * @param y Exponent vector.
   * @return Vector of x^y.
   */
  __m256 amd_vrs8_powf (__m256 x, __m256 y);

  /**
   * @brief Raises elements of x to a scalar double-precision exponent.
   * @param x Base vector.
   * @param y Scalar exponent.
   * @return Vector of x^y.
   */
  __m256d amd_vrd4_powx (__m256d x, double y);
  /**
   * @brief Raises elements of x to a scalar single-precision exponent.
   * @param x Base vector.
   * @param y Scalar exponent.
   * @return Vector of x^y.
   */
  __m256 amd_vrs8_powxf (__m256 x, float y);

  /**
   * @brief Computes square root per-lane for four double-precision elements.
   * @param x Input vector.
   * @return Vector of square roots.
   */
  __m256d amd_vrd4_sqrt (__m256d x);
  /**
   * @brief Computes square root per-lane for eight single-precision elements.
   * @param x Input vector.
   * @return Vector of square roots.
   */
  __m256 amd_vrs8_sqrtf (__m256 x);

/* Error */
  /**
   * @brief Computes erf per-lane for four double-precision elements.
   * @param x Input vector.
   * @return Vector of erf values.
   */
  __m256d amd_vrd4_erf (__m256d x);
  /**
   * @brief Computes erf per-lane for eight single-precision elements.
   * @param x Input vector.
   * @return Vector of erf values.
   */
  __m256 amd_vrs8_erff (__m256 x);

/* Complementary Error */
  /**
   * @brief Computes erfc per-lane for four double-precision elements.
   * @param x Input vector.
   * @return Vector of erfc values.
   */
  __m256d amd_vrd4_erfc (__m256d x);
  /**
   * @brief Computes erfc per-lane for eight single-precision elements.
   * @param x Input vector.
   * @return Vector of erfc values.
   */
  __m256 amd_vrs8_erfcf (__m256 x);

/* Cumulative Normal Distribution */
  /**
   * @brief Computes cumulative normal distribution for four double-precision elements.
   * @param x Input vector x
   * @return Vector of cdfnorm values
   */
  __m256d amd_vrd4_cdfnorm (__m256d x);

/* Round */
  /**
   * @brief Computes round per-lane for eight single-precision elements.
   * @param x Input vector x.
   * @return Vector of rounded value.
   */
  __m256 amd_vrs8_roundf (__m256 x);
/* Inverse Complementary Error */
  /**
   * @brief Computes erfcinv per-lane for four double-precision elements.
   * @param x Input vector.
   * @return Vector of erfcinv values.
   */
  __m256d amd_vrd4_erfcinv (__m256d x);

/* Inverse Cumulative Normal Distribution */
  /**
   * @brief Computes cdfnorminv per-lane for four double-precision elements.
   * @param x Input vector with values in (0, 1).
   * @return Vector of cdfnorminv values.
   */
  __m256d amd_vrd4_cdfnorminv (__m256d x);

/* Remainder */
  /**
   * @brief Computes absolute value per-lane for four double-precision elements.
   * @param x Input vector.
   * @return Vector of absolute values.
   */
  __m256d amd_vrd4_fabs (__m256d x);
  /**
   * @brief Computes absolute value per-lane for eight single-precision elements.
   * @param x Input vector.
   * @return Vector of absolute values.
   */
  __m256 amd_vrs8_fabsf (__m256 x);

/* Nearest Integer */
  /**
   * @brief Computes round per-lane for four double-precision elements.
   * @param x Input vector x.
   * @return Vector of rounded value.
   */
  __m256d amd_vrd4_round (__m256d x);

/* Linearfrac */
  /**
   * @brief Computes a linear fractional transform for four double-precision lanes.
   * @param x Input vector x.
   * @param y Input vector y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @return Result vector of the transform.
   */
  __m256d amd_vrd4_linearfrac (__m256d x, __m256d y,
                               double scx, double shx,
                               double scy, double shy);

  /**
   * @brief Computes a linear fractional transform for eight single-precision lanes.
   * @param x Input vector x.
   * @param y Input vector y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @return Result vector of the transform.
   */
  __m256 amd_vrs8_linearfracf (__m256 x, __m256 y,
                               float scx, float shx,
                               float scy, float shy);
#endif /* __AVX2__ */


#if defined (__AVX512F__)
/* Trigonometric */
  /**
   * @brief Computes sine for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of sines.
   */
  __m512d amd_vrd8_sin (__m512d x);
  /**
   * @brief Computes sine for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of sines.
   */
  __m512 amd_vrs16_sinf (__m512 x);

  /**
   * @brief Computes cosine for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of cosines.
   */
  __m512d amd_vrd8_cos (__m512d x);
  /**
   * @brief Computes cosine for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of cosines.
   */
  __m512 amd_vrs16_cosf (__m512 x);

  /**
   * @brief Computes tangent for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of tangents.
   */
  __m512d amd_vrd8_tan (__m512d x);
  /**
   * @brief Computes tangent for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of tangents.
   */
  __m512 amd_vrs16_tanf (__m512 x);

  /**
   * @brief Computes both sine and cosine for eight double-precision lanes.
   * @param x Input vector.
   * @param sin Output pointer for sines.
   * @param cos Output pointer for cosines.
   */
  void amd_vrd8_sincos (__m512d x, __m512d *sin, __m512d *cos);
  /**
   * @brief Computes both sine and cosine for sixteen single-precision lanes.
   * @param x Input vector.
   * @param sin Output pointer for sines.
   * @param cos Output pointer for cosines.
   */
  void amd_vrs16_sincosf (__m512 x, __m512 *sin, __m512 *cos);

/* Inverse Trigonometric */
  /**
   * @brief Computes arc-sine for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-sines in radians.
   */
  __m512d amd_vrd8_asin (__m512d x);
  /**
   * @brief Computes arc-sine for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-sines in radians.
   */
  __m512 amd_vrs16_asinf (__m512 x);

  /**
   * @brief Computes arc-cosine for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-cosines in radians.
   */
  __m512 amd_vrs16_acosf (__m512 x);

  /**
   * @brief Computes arc-tangent for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-tangents in radians.
   */
  __m512d amd_vrd8_atan (__m512d x);
  /**
   * @brief Computes arc-tangent for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of arc-tangents in radians.
   */
  __m512 amd_vrs16_atanf (__m512 x);

/* Hyperbolic */
  /**
   * @brief Computes hyperbolic tangent for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of tanh values.
   */
  __m512 amd_vrs16_tanhf (__m512 x);

/* Exponential */
  /**
   * @brief Computes e^x for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of exponentials.
   */
  __m512d amd_vrd8_exp (__m512d x);
  /**
   * @brief Computes e^x for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of exponentials.
   */
  __m512 amd_vrs16_expf (__m512 x);

  /**
   * @brief Computes 2^x for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of base-2 exponentials.
   */
  __m512d amd_vrd8_exp2 (__m512d x);
  /**
   * @brief Computes 2^x for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of base-2 exponentials.
   */
  __m512 amd_vrs16_exp2f (__m512 x);

/* Logarithmic */
  /**
   * @brief Computes natural logarithm for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of ln values.
   */
  __m512d amd_vrd8_log (__m512d x);
  /**
   * @brief Computes natural logarithm for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of ln values.
   */
  __m512 amd_vrs16_logf (__m512 x);

  /**
   * @brief Computes base-2 logarithm for eight double-precision lanes.
   * @param x Input vector.
   * @return Vector of log2 values.
   */
  __m512d amd_vrd8_log2 (__m512d x);
  /**
   * @brief Computes base-2 logarithm for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of log2 values.
   */
  __m512 amd_vrs16_log2f (__m512 x);

  /**
   * @brief Computes base-10 logarithm for sixteen single-precision lanes.
   * @param x Input vector.
   * @return Vector of log10 values.
   */
  __m512 amd_vrs16_log10f (__m512 x);

/* Power & Root */
  /**
   * @brief Raises elements of x to powers in y (eight double-precision lanes).
   * @param x Base vector.
   * @param y Exponent vector.
   * @return Vector of x^y.
   */
  __m512d amd_vrd8_pow (__m512d x, __m512d y);
  /**
   * @brief Raises elements of x to powers in y (sixteen single-precision lanes).
   * @param x Base vector.
   * @param y Exponent vector.
   * @return Vector of x^y.
   */
  __m512 amd_vrs16_powf (__m512 x, __m512 y);

  /**
   * @brief Raises elements of x to a scalar double-precision exponent.
   * @param x Base vector.
   * @param y Scalar exponent.
   * @return Vector of x^y.
   */
  __m512d amd_vrd8_powx (__m512d x, double y);
  /**
   * @brief Raises elements of x to a scalar single-precision exponent.
   * @param x Base vector.
   * @param y Scalar exponent.
   * @return Vector of x^y.
   */
  __m512 amd_vrs16_powxf (__m512 x, float y);

  /**
   * @brief Computes square root per-lane for eight double-precision elements.
   * @param x Input vector.
   * @return Vector of square roots.
   */
  __m512d amd_vrd8_sqrt (__m512d x);
  /**
   * @brief Computes square root per-lane for sixteen single-precision elements.
   * @param x Input vector.
   * @return Vector of square roots.
   */
  __m512 amd_vrs16_sqrtf (__m512 x);

/* Error */
  /**
   * @brief Computes erf per-lane for eight double-precision elements.
   * @param x Input vector.
   * @return Vector of erf values.
   */
  __m512d amd_vrd8_erf (__m512d x);
  /**
   * @brief Computes erf per-lane for sixteen single-precision elements.
   * @param x Input vector.
   * @return Vector of erf values.
   */
  __m512 amd_vrs16_erff (__m512 x);

/* Complementary Error */
  /**
   * @brief Computes erfc per-lane for eight double-precision elements.
   * @param x Input vector.
   * @return Vector of erfc values.
   */
  __m512d amd_vrd8_erfc (__m512d x);
  /**
   * @brief Computes erfc per-lane for sixteen single-precision elements.
   * @param x Input vector.
   * @return Vector of erfc values.
   */
  __m512 amd_vrs16_erfcf (__m512 x);

/* Inverse Error */
  /**
   * @brief Computes Inverse Error function per-lane for eight double-precision elements.
   * @param x Input vector.
   * @return Vector of erfinv values.
   */
  __m512d amd_vrd8_erfinv (__m512d x);

/* Cumulative Normal Distribution */
  /**
   * @brief Computes cumulative normal distribution for eight double-precision elements.
   * @param x Input vector x
   * @return Vector of cdfnorm values
   */
  __m512d amd_vrd8_cdfnorm (__m512d x);

/* Nearest Integer */
  /**
   * @brief Computes round per-lane for eight double-precision elements.
   * @param x Input vector x.
   * @return Vector of rounded value.
   */
  __m512d amd_vrd8_round (__m512d x);
  /**
   * @brief Computes round per-lane for sixteen single-precision elements.
   * @param x Input vector x.
   * @return Vector of rounded value.
   */
  __m512 amd_vrs16_roundf (__m512 x);
/* Inverse Complementary Error */
  /**
   * @brief Computes erfcinv per-lane for eight double-precision elements.
   * @param x Input vector.
   * @return Vector of erfcinv values.
   */
  __m512d amd_vrd8_erfcinv (__m512d x);

/* Inverse Cumulative Normal Distribution */
  /**
   * @brief Computes cdfnorminv per-lane for eight double-precision elements.
   * @param x Input vector with values in (0, 1).
   * @return Vector of cdfnorminv values.
   */
  __m512d amd_vrd8_cdfnorminv (__m512d x);

/* Linearfrac */
  /**
   * @brief Computes a linear fractional transform for eight double-precision lanes.
   * @param x Input vector x.
   * @param y Input vector y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @return Result vector of the transform.
   */
  __m512d amd_vrd8_linearfrac (__m512d x, __m512d y,
                                double scx, double shx,
                                double scy, double shy);

  /**
   * @brief Computes a linear fractional transform for sixteen single-precision lanes.
   * @param x Input vector x.
   * @param y Input vector y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @return Result vector of the transform.
   */
  __m512 amd_vrs16_linearfracf (__m512 x, __m512 y,
                                 float scx, float shx,
                                 float scy, float shy);
#endif /* __AVX512F__ */


/*
 * Array Variants
 */

/* Trigonometric */
#if defined (__AVX2__)
  /**
   * @brief Computes sine elementwise for double array.
   * @param len Number of elements.
   * @param src Input array of length len.
   * @param dst Output array of length len for sines.
   */
  void amd_vrda_sin (int len, const double *src, double *dst);
  /**
   * @brief Computes sine elementwise for float array.
   * @param len Number of elements.
   * @param src Input array of length len.
   * @param dst Output array of length len for sines.
   */
  void amd_vrsa_sinf (int len, const float *src, float *dst);

  /**
   * @brief Computes cosine elementwise for double array.
   * @param len Number of elements.
   * @param src Input array of length len.
   * @param dst Output array of length len for cosines.
   */
  void amd_vrda_cos (int len, const double *src, double *dst);
  /**
   * @brief Computes cosine elementwise for float array.
   * @param len Number of elements.
   * @param src Input array of length len.
   * @param dst Output array of length len for cosines.
   */
  void amd_vrsa_cosf (int len, const float *src, float *dst);

  /**
   * @brief Computes tangent elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for tangents.
   */
  void amd_vrda_tan (int len, const double *src, double *dst);
  /**
   * @brief Computes tangent elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for tangents.
   */
  void amd_vrsa_tanf (int len, const float *src, float *dst);

  /**
   * @brief Computes sine and cosine elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param sin Output array for sines.
   * @param cos Output array for cosines.
   */
  void amd_vrda_sincos (int len, const double *src, double *sin, double *cos);
  /**
   * @brief Computes sine and cosine elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param sin Output array for sines.
   * @param cos Output array for cosines.
   */
  void amd_vrsa_sincosf (int len, const float *src, float *sin, float *cos);
#endif


/* Inverse Trigonometric */
#if defined (__AVX2__)
  /**
   * @brief Computes arc-sine elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for arc-sines in radians.
   */
  void amd_vrda_asin (int len, const double *src, double *dst);
  /**
   * @brief Computes arc-sine elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for arc-sines in radians.
   */
  void amd_vrsa_asinf (int len, const float *src, float *dst);

  /**
   * @brief Computes arc-cosine elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for arc-cosines in radians.
   */
  void amd_vrda_acos (int len, const double *src, double *dst);
  /**
   * @brief Computes arc-cosine elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for arc-cosines in radians.
   */
  void amd_vrsa_acosf (int len, const float *src, float *dst);

  /**
   * @brief Computes arc-tangent elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for arc-tangents in radians.
   */
  void amd_vrda_atan (int len, const double *src, double *dst);
  /**
   * @brief Computes arc-tangent elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for arc-tangents in radians.
   */
  void amd_vrsa_atanf (int len, const float *src, float *dst);
#endif


/* Hyperbolic */
#if defined (__AVX__)
  /**
   * @brief Computes hyperbolic cosine elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for cosh values.
   */
  void amd_vrda_cosh (int len, const double *src, double *dst);
#endif

#if defined (__AVX2__)
  /**
   * @brief Computes hyperbolic cosine elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for cosh values.
   */
  void amd_vrsa_coshf (int len, const float *src, float *dst);
  /**
   * @brief Computes hyperbolic tangent elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array for tanh values.
   */
  void amd_vrsa_tanhf (int len, const float *src, float *dst);
#endif


/* Exponential */
#if defined (__AVX2__)
  /**
   * @brief Computes e^x elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of exponentials.
   */
  void amd_vrda_exp (int len, const double *src, double *dst);
  /**
   * @brief Computes e^x elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of exponentials.
   */
  void amd_vrsa_expf (int len, const float *src, float *dst);

  /**
   * @brief Computes 2^x elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of base-2 exponentials.
   */
  void amd_vrda_exp2 (int len, const double *src, double *dst);
  /**
   * @brief Computes 2^x elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of base-2 exponentials.
   */
  void amd_vrsa_exp2f (int len, const float *src, float *dst);
#endif

  /**
   * @brief Computes 10^x elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of base-10 exponentials.
   */
  void amd_vrda_exp10  (int len, const double *src, double *dst);

#if defined (__AVX__)
  /**
   * @brief Computes 10^x elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of base-10 exponentials.
   */
  void amd_vrsa_exp10f (int len, const float *src, float *dst);
#endif

  /**
   * @brief Computes exp(x)-1 elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of expm1 values.
   */
  void amd_vrda_expm1 (int len, const double *src, double *dst);


#if defined (__AVX__)
  /**
   * @brief Computes exp(x)-1 elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of expm1 values.
   */
  void amd_vrsa_expm1f (int len, const float *src, float *dst);
#endif


/* Logarithmic */
#if defined (__AVX2__)
  /**
   * @brief Computes natural logarithm elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of ln values.
   */
  void amd_vrda_log (int len, const double *src, double *dst);
  /**
   * @brief Computes natural logarithm elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of ln values.
   */
  void amd_vrsa_logf (int len, const float *src, float *dst);

  /**
   * @brief Computes base-2 logarithm elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of log2 values.
   */
  void amd_vrda_log2 (int len, const double *src, double *dst);
  /**
   * @brief Computes base-2 logarithm elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of log2 values.
   */
  void amd_vrsa_log2f (int len, const float *src, float *dst);
#endif

  /**
   * @brief Computes base-10 logarithm elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of log10 values.
   */
  void amd_vrda_log10 (int len, const double *src, double *dst);

#if defined (__AVX2__)
  /**
   * @brief Computes base-10 logarithm elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of log10 values.
   */
  void amd_vrsa_log10f (int len, const float *src, float *dst);
#endif

  /**
   * @brief Computes log(1+x) elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of log1p values.
   */
  void amd_vrda_log1p (int len, const double *src, double *dst);

#if defined (__AVX__)
  /**
   * @brief Computes log(1+x) elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of log1p values.
   */
  void amd_vrsa_log1pf (int len, const float *src, float *dst);
#endif


/* Power & Root */
#if defined (__AVX2__)
  /**
   * @brief Computes elementwise power for double arrays.
   * @param len Number of elements.
   * @param src1 Base array.
   * @param src2 Exponent array.
   * @param dst Output array of powers.
   */
  void amd_vrda_pow (int len, const double *src1, const double *src2, double *dst);
  /**
   * @brief Computes elementwise power for float arrays.
   * @param len Number of elements.
   * @param src1 Base array.
   * @param src2 Exponent array.
   * @param dst Output array of powers.
   */
  void amd_vrsa_powf (int len, const float *src1, const float *src2, float *dst);

  /**
   * @brief Raises elements of x to a scalar single-precision exponent.
   * @param len Number of elements.
   * @param src Input array.
   * @param y Scalar exponent.
   * @param dst Output array of x^y.
   */
  void amd_vrsa_powxf(int len, const float *src, float y, float *dst);

  /**
   * @brief Raises elements of x to a scalar double-precision exponent.
   * @param len Number of elements.
   * @param src Input array.
   * @param y Scalar exponent.
   * @param dst Output array of x^y.
   */
  void amd_vrda_powx(int len, const double *src, double y, double *dst);

  /**
   * @brief Computes elementwise square root for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of square roots.
   */
  void amd_vrda_sqrt (int len, const double *src, double *dst);
  /**
   * @brief Computes elementwise square root for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of square roots.
   */
  void amd_vrsa_sqrtf (int len, const float *src, float *dst);
#endif

  /**
   * @brief Computes elementwise cube root for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of cube roots.
   */
  void amd_vrda_cbrt (int len, const double *src, double *dst);

#if defined (__AVX__)
  /**
   * @brief Computes elementwise cube root for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of cube roots.
   */
  void amd_vrsa_cbrtf (int len, const float *src, float *dst);
#endif


#if defined (__AVX2__)
/* Error */
  /**
   * @brief Computes erf elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of erf values.
   */
  void amd_vrda_erf (int len, const double *src, double *dst);
  /**
   * @brief Computes erf elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of erf values.
   */
  void amd_vrsa_erff (int len, const float *src, float *dst);

/* Complementary Error */
  /**
   * @brief Computes erfc elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of erfc values.
   */
  void amd_vrda_erfc (int len, const double *src, double *dst);
  /**
   * @brief Computes inverse error function for variable-length double array.
   * @param len Number of elements to process.
   * @param src Source array.
   * @param dst Destination array.
   */
  void amd_vrda_erfinv (int len, const double *src, double *dst);
  /**
   * @brief Computes erfc elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of erfc values.
   */
  void amd_vrsa_erfcf (int len, const float *src, float *dst);

/* Cumulative Normal Distribution */
/**
   * @brief Computes cumulative normal distribution of double array
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of cdfnorm values.
   */
  void amd_vrda_cdfnorm (int len, const double *src, double *dst);

/* Inverse Cumulative Normal Distribution */
  /**
   * @brief Computes cdfnorminv elementwise for double array.
   * @param len Number of elements.
   * @param src Input array with values in (0, 1).
   * @param dst Output array of cdfnorminv values.
   */
  void amd_vrda_cdfnorminv (int len, const double *src, double *dst);
/* Inverse Complementary Error */
  /**
   * @brief Computes erfcinv elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of erfcinv values.
   */
  void amd_vrda_erfcinv (int len, const double *src, double *dst);
#endif


#if defined (__AVX2__)
/* Remainder */
  /**
   * @brief Computes absolute value elementwise for double array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of absolute values.
   */
  void amd_vrda_fabs (int len, const double *src, double *dst);
  /**
   * @brief Computes absolute value elementwise for float array.
   * @param len Number of elements.
   * @param src Input array.
   * @param dst Output array of absolute values.
   */
  void amd_vrsa_fabsf (int len, const float *src, float *dst);

/* Nearest Integer */
  /**
   * @brief Computes rounded value elementwise for double array.
   * @param len Number of elements.
   * @param src Input array x.
   * @param dst Output array y.
   */
  void amd_vrda_round (int len, const double *src, double *dst);
  /**
   * @brief Computes rounded value elementwise for float array.
   * @param len Number of elements.
   * @param src Input array x.
   * @param dst Output array y.
   */
  void amd_vrsa_roundf (int len, const float *src, float *dst);

/* Linearfrac */
  /**
   * @brief Computes a linear fractional transform elementwise for double arrays.
   * @param len Number of elements.
   * @param x Input array x.
   * @param y Input array y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @param dst Output array for results.
   */
  void amd_vrda_linearfrac (int len, const double *x, const double *y, double scx,
                            double shx, double scy, double shy, double *dst);

  /**
   * @brief Computes a linear fractional transform elementwise for float arrays.
   * @param len Number of elements.
   * @param x Input array x.
   * @param y Input array y.
   * @param scx Scale for x.
   * @param shx Shift for x.
   * @param scy Scale for y.
   * @param shy Shift for y.
   * @param dst Output array for results.
   */
  void amd_vrsa_linearfracf (int len, const float *x, const float *y, float scx,
                             float shx, float scy, float shy, float *dst);
#endif


/* Maximum and Minimum */
  /**
   * @brief Computes elementwise maximum for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of maxima.
   */
  void amd_vrda_fmax (int len, const double *lhs, const double *rhs, double *dst);
  /**
   * @brief Computes elementwise maximum for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of maxima.
   */
  void amd_vrsa_fmaxf (int len, const float *lhs, const float *rhs, float *dst);

  /**
   * @brief Computes elementwise minimum for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of minima.
   */
  void amd_vrda_fmin (int len, const double *lhs, const double *rhs, double *dst);
  /**
   * @brief Computes elementwise minimum for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of minima.
   */
  void amd_vrsa_fminf (int len, const float *lhs, const float *rhs, float *dst);

/* Arithmetic */
  /**
   * @brief Computes elementwise sum for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of sums.
   */
  void amd_vrda_add (int len, const double *lhs, const double *rhs, double *dst);
  /**
   * @brief Computes elementwise sum for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of sums.
   */
  void amd_vrsa_addf (int len, const float *lhs, const float *rhs, float *dst);

  /**
   * @brief Computes elementwise difference for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of differences.
   */
  void amd_vrda_sub (int len, const double *lhs, const double *rhs, double *dst);
  /**
   * @brief Computes elementwise difference for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of differences.
   */
  void amd_vrsa_subf (int len, const float *lhs, const float *rhs, float *dst);

  /**
   * @brief Computes elementwise product for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of products.
   */
  void amd_vrda_mul (int len, const double *lhs, const double *rhs, double *dst);
  /**
   * @brief Computes elementwise product for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param rhs Right-hand array.
   * @param dst Output array of products.
   */
  void amd_vrsa_mulf (int len, const float *lhs, const float *rhs, float *dst);

  /**
   * @brief Computes elementwise quotient for double arrays.
   * @param len Number of elements.
   * @param lhs Numerator array.
   * @param rhs Denominator array.
   * @param dst Output array of quotients.
   */
  void amd_vrda_div (int len, const double *lhs, const double *rhs, double *dst);
  /**
   * @brief Computes elementwise quotient for float arrays.
   * @param len Number of elements.
   * @param lhs Numerator array.
   * @param rhs Denominator array.
   * @param dst Output array of quotients.
   */
  void amd_vrsa_divf (int len, const float *lhs, const float *rhs, float *dst);

/* Indexed Arithmetic */
  /**
   * @brief Computes elementwise sum with strides for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrda_addi (int len, const double *lhs, int inc_a,
                      const double *rhs, int inc_b, double *dst, int inc_res);
  /**
   * @brief Computes elementwise sum with strides for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrsa_addfi (int len, const float *lhs, int inc_a,
                       const float *rhs, int inc_b, float *dst, int inc_res);

  /**
   * @brief Computes elementwise difference with strides for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrda_subi (int len, const double *lhs, int inc_a,
                      const double *rhs, int inc_b, double *dst, int inc_res);
  /**
   * @brief Computes elementwise difference with strides for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrsa_subfi (int len, const float *lhs, int inc_a,
                       const float *rhs, int inc_b, float *dst, int inc_res );

  /**
   * @brief Computes elementwise product with strides for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrda_muli (int len, const double *lhs, int inc_a,
                      const double *rhs, int inc_b, double *dst, int inc_res);
  /**
   * @brief Computes elementwise product with strides for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrsa_mulfi (int len, const float *lhs, int inc_a,
                       const float *rhs, int inc_b, float *dst, int inc_res);

  /**
   * @brief Computes elementwise quotient with strides for double arrays.
   * @param len Number of elements.
   * @param lhs Numerator array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Denominator array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrda_divi (int len, const double *lhs, int inc_a,
                      const double *rhs, int inc_b, double *dst, int inc_res);
  /**
   * @brief Computes elementwise quotient with strides for float arrays.
   * @param len Number of elements.
   * @param lhs Numerator array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Denominator array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrsa_divfi (int len, const float *lhs, int inc_a,
                       const float *rhs, int inc_b, float *dst, int inc_res);

/* Indexed Maximum & Minimum */
  /**
   * @brief Computes elementwise maximum with strides for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrda_fmaxi (int len, const double *lhs, int inc_a,
                       const double *rhs, int inc_b, double *dst, int inc_res);
  /**
   * @brief Computes elementwise maximum with strides for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrsa_fmaxfi (int len, const float *lhs, int inc_a,
                        const float *rhs, int inc_b, float *dst, int inc_res);

  /**
   * @brief Computes elementwise minimum with strides for double arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrda_fmini (int len, const double *lhs, int inc_a,
                       const double *rhs, int inc_b, double *dst, int inc_res);
  /**
   * @brief Computes elementwise minimum with strides for float arrays.
   * @param len Number of elements.
   * @param lhs Left-hand array.
   * @param inc_a Stride for lhs (in elements).
   * @param rhs Right-hand array.
   * @param inc_b Stride for rhs (in elements).
   * @param dst Output array.
   * @param inc_res Stride for output (in elements).
   */
  void amd_vrsa_fminfi (int len, const float *lhs, int inc_a,
                        const float *rhs, int inc_b, float *dst, int inc_res);

#ifdef __cplusplus
}
#endif


#endif /* __AMDLIBM_VEC_H__ */
