Using the Mathematical Acceleration Subsystem (MASS)

The MASS libraries consist of a library of scalar XL C/C++ functions or XL Fortran routines, described in Using the scalar library; and a set of vector libraries tuned for specific architectures, described in Using the vector libraries. The functions contained in both scalar and vector libraries are automatically called at certain levels of optimization, but you can also call them explicitly in your programs. Note that the accuracy and exception handling might not be identical in MASS functions and system library functions.

Compiling and linking a program with MASS describes how to compile and link a program that uses the MASS libraries, and how to selectively use the MASS scalar library functions in concert with the regular system library scalar functions.

Using the scalar library

The MASS scalar library, libmass.a, contains an accelerated set of frequently used math intrinsic functions that provide improved performance over the corresponding standard system library functions. When you compile programs with any of the following options:

the compiler automatically uses the faster MASS functions for all math library functions (with the exception of atan2, dnint, sqrt, rsqrt). In fact, the compiler first tries to "vectorize" calls to math library functions by replacing them with the equivalent MASS vector functions; if it cannot do so, it uses the MASS scalar functions. When the compiler performs this automatic replacement of math library functions, it uses versions of the MASS functions contained in the system library libxlopt.a; you do not need to add any special calls to the MASS functions in your code, or to link to the libxlopt library.

If you are not using any of the optimization options listed above, and/or want to explicitly call the MASS scalar functions, you can do so as follows:

For XL C/C++
  1. Provide the prototypes for the functions (except dnint, cosisin, rsqrt, and sincos), by including math.h in your source files.
  2. Provide the prototypes for dnint, cosisin, rsqrt and sincos, by including mass.h in your source files.
  3. Link the MASS scalar library libmass.a with your application. For instructions, see Compiling and linking a program with MASS.
For XL Fortran
  1. Link the MASS scalar library libmass.a with your application. For instructions, see Compiling and linking a program with MASS
  2. All the MASS scalar routines except cosisin, expml, loglp, rsqrt, and sincos are recognized by XL Fortran as intrinsic functions, so no explicit interface block is needed. To provide an interface block for cosisin, expml, loglp, rsqrt, and sincos, include mass.include in your source file.

The MASS scalar functions accept double-precision parameters and return a double-precision result, except sincos which gives 2 double-precision results. They are summarized in Table 6.

Table 6. MASS scalar functions
Function Description Prototype
sqrt Returns the square root of x double sqrt (double x);
rsqrt Returns the reciprocal of the square root of x double rsqrt (double x);
exp Returns the exponential function of x double exp (double x);
expm1 Returns (the exponential function of x) - 1 double expm1 (double x);
log Returns the natural logarithm of x double log (double x);
log1p Returns the natural logarithm of (x + 1) double log1p (double x);
sin Returns the sine of x double sin (double x);
sincos Sets *s to the sine of x and *c to the cosine of x. void sincos (double x, double* s, double* c);
cos Returns the cosine of x double cos (double x);
cosisin Returns a complex number with the real part the cosine of x and the imaginary part the sine of x. double_Complex cosisin (double);
tan Returns the tangent of x double tan (double x);
atan Returns the arc tangent of x double atan (double x);
atan2 Returns the arc tangent of x/y double atan2 (double x, double y);
sinh Returns the hyperbolic sine of x double sinh (double x);
cosh Returns the hyperbolic cosine of x double cosh (double x);
tanh Returns the hyperbolic tangent of x double tanh (double x);
dnint Returns the nearest integer to x (as a double) double dnint (double x);
pow (C/C++) Returns x raised to the power y double pow (double x, double y);
x**y (XL Fortran) Returns x raised to the power y N/A

The following example shows the XL Fortran interface declaration for the rsqrt scalar function:

      interface

      real*8 function rsqrt (%val(x))
        real*8 x      ! Returns the reciprocal of the square root of x.
      end function rsqrt

      end interface

The trigonometric functions (sin, cos, tan) return NaN (Not-a-Number) for large arguments (abs(x)>2**50*pi).

Note:
In some cases the MASS functions are not as accurate as the libm.a library, and they might handle edge cases differently (sqrt(Inf), for example).

Using the vector libraries

When you compile programs with any of the following options:

the compiler automatically attempts to vectorize calls to system math functions by calling the equivalent MASS vector functions (with the exceptions of functions vatan2 (XLF), vsatan2(XLF), vdnint, vdint, vsincos, vssincos, vcosisin, vscosisin, vqdrt, vsqdrt, vrqdrt, vsrqdrt, vpopcnt4, and vpopcnt8). For automatic vectorization, the compiler uses versions of the MASS functions contained in the system library libxlopt.a; you do not need to add any special calls to the MASS functions in your code, or to link to the libxlopt library.

If you are not using any of the optimization options listed above, and/or want to explicitly call any of the MASS vector functions, you can do so by including the XL C/C++ header massv.h or the XL Fortran massv.include file in your source files and linking your application with the libmassv.a vector library. (Information on linking is provided in Compiling and linking a program with MASS.)

The single-precision and double-precision floating-point functions contained in the vector libraries are summarized in Table 7 (XL C/C++) and Table 8(XL Fortran). The integer functions contained in the vector libraries are summarized in Table 9. Note that in C and C++ applications, only call by reference is supported, even for scalar arguments.

With the exception of a few functions (described below), all of the floating-point functions in the vector libraries accept three parameters:

The functions are of the form

function_name (y,x,n)

where y is the target vector, x is the source vector, and n is the vector length. The parameters y and x are assumed to be double-precision for functions with the prefix v, and single-precision for functions with the prefix vs. As examples, the following XL C/C++ code:

#include <massv.h>

double x[500], y[500];
int n;
n = 500;
...
vexp (y, x, &n);
outputs a vector y of length 500 whose elements are exp(x[i]), where i=0,...,499

.

The following XL Fortran code:

include 'massv.include'

real*8 x(500), y(500)
integer n
n = 500
...
call vexp (y, x, n)

outputs a vector y of length 500 whose elements are exp(x(i)), where i=1,...,500.

The functions vdiv, vsincos, vpow, and vatan2 (and their single-precision versions, vsdiv, vssincos, vspow, and vsatan2) take four parameters. The functions vdiv, vpow, and vatan2 take the parameters (z,x,y,n). The function vdiv outputs a vector z whose elements are x[i]/y[i], where i=0,..,*n-1. The function vpow outputs a vector z whose elements are x[i]y[i], where i=0,..,*n-1. The function vatan2 outputs a vector z whose elements are atan(x[i]/y[i]), where i=0,..,*n-1. The function vsincos takes the parameters (y,z,x,n), and outputs two vectors, y and z, whose elements are sin(x[i]) and cos(x[i]), respectively.

In vcosisin(y,x,n) and vscosisin(y,x,n), x is a vector of n elements and the function outputs a vector y of n complex elements of the form (cos(x[i]),sin(x[i])).

Table 7. MASS floating-point vector functions (XL C/C++)
Double-precision function Single-precision function Description Double-precision function prototype Single-precision function prototype
vacos vsacos Sets y[i] to the arc cosine of x[i], for i=0,..,*n-1 void vacos (double y[], double x[], int *n); void vsacos (float y[], float x[], int *n);
vacosh vsacosh Sets y[i] to the hyperbolic arc cosine of x[i], for i=0,..,*n-1 void vacosh (double y[], double x[], int *n); void vsacosh (float y[], float x[], int *n);
vasin vsasin Sets y[i] to the arc sine of x[i], for i=0,..,*n-1 void vasin (double y[], double x[], int *n); void vsasin (float y[], float x[], int *n);
vasinh vsasinh Sets y[i] to the hyperbolic arc sine of x[i], for i=0,..,*n-1 void vasinh (double y[], double x[], int *n); void vsasinh (float y[], float x[], int *n);
vatan2 vsatan2 Sets z[i] to the arc tangent of x[i]/y[i], for i=0,..,*n-1 void vatan2 (double z[], double x[], double y[], int *n); void vsatan2 (float z[], float x[], float y[], int *n);
vatanh vsatanh Sets y[i] to the hyperbolic arc tangent of x[i], for i=0,..,*n-1 void vatanh (double y[], double x[], int *n); void vsatanh (float y[], float x[], int *n);
vcbrt vscbrt Sets y[i] to the cube root of x[i], for i=0,..,*n-1 void vcbrt (double y[], double x[], int *n); void vscbrt (float y[], float x[], int *n);
vcos vscos Sets y[i] to the cosine of x[i], for i=0,..,*n-1 void vcos (double y[], double x[], int *n); void vscos (float y[], float x[], int *n);
vcosh vscosh Sets y[i] to the hyperbolic cosine of x[i], for i=0,..,*n-1 void vcosh (double y[], double x[], int *n); void vscosh (float y[], float x[], int *n);
vcosisin vscosisin Sets the real part of y[i] to the cosine of x[i] and the imaginary part of y[i] to the sine of x[i], for i=0,..,*n-1 void vcosisin (double _Complex y[], double x[], int *n); void vscosisin (float _Complex y[], float x[], int *n);
vdint Sets y[i] to the integer truncation of x[i], for i=0,..,*n-1 void vdint (double y[], double x[], int *n);
vdiv vsdiv Sets z[i] to x[i]/y[i], for i=0,..,*n-1 void vdiv (double z[], double x[], double y[], int *n); void vsdiv (float z[], float x[], float y[], int *n);
vdnint Sets y[i] to the nearest integer to x[i], for i=0,..,n-1 void vdnint (double y[], double x[], int *n);
vexp vsexp Sets y[i] to the exponential function of x[i], for i=0,..,*n-1 void vexp (double y[], double x[], int *n); void vsexp (float y[], float x[], int *n);
vexpm1 vsexpm1 Sets y[i] to (the exponential function of x[i])-1, for i=0,..,*n-1 void vexpm1 (double y[], double x[], int *n); void vsexpm1 (float y[], float x[], int *n);
vlog vslog Sets y[i] to the natural logarithm of x[i], for i=0,..,*n-1 void vlog (double y[], double x[], int *n); void vslog (float y[], float x[], int *n);
vlog10 vslog10 Sets y[i] to the base-10 logarithm of x[i], for i=0,..,*n-1 void vlog10 (double y[], double x[], int *n); void vslog10 (float y[], float x[], int *n);
vlog1p vslog1p Sets y[i] to the natural logarithm of (x[i]+1), for i=0,..,*n-1 void vlog1p (double y[], double x[], int *n); void vslog1p (float y[], float x[], int *n);
vpow vspow Sets z[i] to x[i] raised to the power y[i], for i=0,..,*n-1 void vpow (double z[], double x[], double y[], int *n); void vspow (float z[], float x[], float y[], int *n);
vqdrt vsqdrt Sets y[i] to the fourth root of x[i], for i=0,..,*n-1 void vqdrt (double y[], double x[], int *n); void vsqdrt (float y[], float x[], int *n);
vrcbrt vsrcbrt Sets y[i] to the reciprocal of the cube root of x[i], for i=0,..,*n-1 void vrcbrt (double y[], double x[], int *n); void vsrcbrt (float y[], float x[], int *n);
vrec vsrec Sets y[i] to the reciprocal of x[i], for i=0,..,*n-1 void vrec (double y[], double x[], int *n); void vsrec (float y[], float x[], int *n);
vrqdrt vsrqdrt Sets y[i] to the reciprocal of the fourth root of x[i], for i=0,..,*n-1 void vrqdrt (double y[], double x[], int *n); void vsrqdrt (float y[], float x[], int *n);
vrsqrt vsrsqrt Sets y[i] to the reciprocal of the square root of x[i], for i=0,..,*n-1 void vrsqrt (double y[], double x[], int *n); void vsrsqrt (float y[], float x[], int *n);
vsin vssin Sets y[i] to the sine of x[i], for i=0,..,*n-1 void vsin (double y[], double x[], int *n); void vssin (float y[], float x[], int *n);
vsincos vssincos Sets y[i] to the sine of x[i] and z[i] to the cosine of x[i], for i=0,..,*n-1 void vsincos (double y[], double z[], double x[], int *n); void vssincos (float y[], float z[], float x[], int *n);
vsinh vssinh Sets y[i] to the hyperbolic sine of x[i], for i=0,..,*n-1 void vsinh (double y[], double x[], int *n); void vssinh (float y[], float x[], int *n);
vsqrt vssqrt Sets y[i] to the square root of x[i], for i=0,..,*n-1 void vsqrt (double y[], double x[], int *n); void vssqrt (float y[], float x[], int *n);
vtan vstan Sets y[i] to the tangent of x[i], for i=0,..,*n-1 void vtan (double y[], double x[], int *n); void vstan (float y[], float x[], int *n);
vtanh vstanh Sets y[i] to the hyperbolic tangent of x[i], for i=0,..,*n-1 void vtanh (double y[], double x[], int *n); void vstanh (float y[], float x[], int *n);
Table 8
Table 8. MASS floating-point vector library functions (XL Fortran)
Double-precision function Single-precision function Arguments Description
vacos vsacos (y,x,n) Sets y(i) to the arc cosine of x(i), for i=1,..,n
vacosh vsacosh (y,x,n) Sets y(i) to the hyperbolic arc cosine of x(i), for i=1,..,n
vasin vsasin (y,x,n) Sets y(i) to the arc sine of x(i), for i=1,..,n
vasinh vsasinh (y,x,n) Sets y(i) to the arc hyperbolic sine of x(i), for i=1,..,n
vatan2 vsatan2 (z,x,y,n) Sets z(i) to the arc tangent of x(i)/y(i), for i=1,..,n
vatanh vsatanh (y,x,n) Sets y(i) to the arc hyperbolic tangent of x(i), for i=1,..,n
vcbrt vscbrt (y,x,n) Sets y(i) to the cube root of x(i), for i=1,..,n
vcos vscos (y,x,n) Sets y(i) to the cosine of x(i), for i=1,..,n
vcosh vscosh (y,x,n) Sets y(i) to the hyperbolic cosine of x(i), for i=1,..,n
vcosisin vscosisin (y,x,n) Sets the real part of y(i) to the cosine of x(i) and the imaginary part of y(i) to the sine of x(i), for i=1,..,n
vdint (y,x,n) Sets y(i) to the integer truncation of x(i), for i=1,..,n
vdiv vsdiv (z,x,y,n) Sets z(i) to x(i)/y(i), for i=1,..,n
vdnint (y,x,n) Sets y(i) to the nearest integer to x(i), for i=1,..,n
vexp vsexp (y,x,n) Sets y(i) to the exponential function of x(i), for i=1,..,n
vexpm1 vsexpm1 (y,x,n) Sets y(i) to (the exponential function of x(i))-1, for i=1,..,n
vlog vslog (y,x,n) Sets y(i) to the natural logarithm of x(i), for i=1,..,n
vlog10 vslog10 (y,x,n) Sets y(i) to the base-10 logarithm of x(i), for i=1,..,n
vlog1p vslog1p (y,x,n) Sets y(i) to the natural logarithm of (x(i)+1), for i=1,..,n
vpow vspow (z,x,y,n) Sets z(i) to x(i) raised to the power y(i), for i=1,..,n
vqdrt vsqdrt (y,x,n) Sets y(i) to the 4th root of x(i), for i=1,..,n
vrcbrt vsrcbrt (y,x,n) Sets y(i) to the reciprocal of the cube root of x(i), for i=1,..,n
vrec vsrec (y,x,n) Sets y(i) to the reciprocal of x(i), for i=1,..,n
vrqdrt vsrqdrt (y,x,n) Sets y(i) to the reciprocal of the 4th root of x(i), for i=1,..,n
vrsqrt vsrsqrt (y,x,n) Sets y(i) to the reciprocal of the square root of x(i), for i=1,..,n
vsin vssin (y,x,n) Sets y(i) to the sine of x(i), for i=1,..,n
vsincos vssincos (y,z,x,n) Sets y(i) to the sine of x(i) and z(i) to the cosine of x(i), for i=1,..,n
vsinh vssinh (y,x,n) Sets y(i) to the hyperbolic sine of x(i), for i=1,..,n
vsqrt vssqrt (y,x,n) Sets y(i) to the square root of x(i), for i=1,..,n
vtan vstan (y,x,n) Sets y(i) to the tangent of x(i), for i=1,..,n
vtanh vstanh (y,x,n) Sets y(i) to the hyperbolic tangent of x(i), for i=1,..,n

For XL C/C++, the integer functions are of the form function_name (x[], *n), where x[] is a vector of 4-byte (for vpopcnt4) or 8-byte (for vpopcnt8) numeric objects (integral or floating-point), and *n is the vector length.

Table 9. MASS integer vector library functions (XL C/C++)
Function Description Prototype
vpopcnt4 Returns the total number of 1 bits in the concatenation of the binary representation of x[i], for i=0,..,*n-1 , where x is a vector of 32-bit objects. unsigned int vpopcnt4 (void *x, int *n)
vpopcnt8 Returns the total number of 1 bits in the concatenation of the binary representation of x[i], for i=0,..,*n-1 , where x is a vector of 64-bit objects. unsigned int vpopcnt8 (void *x, int *n)

For XL Fortran, the integer routines are of the form function_name (x, n), where x is a vector of 4-byte (for vpopcnt4) or 8-byte (for vpopcnt8) numeric objects (integer or floating-point), and n is the vector length. The vector integer routines are summarized in Table 9.

Table 10. MASS integer vector library functions (XL Fortran)
Function Description Interface
vpopcnt4 Returns the total number of 1 bits in the concatenation of the binary representation of x(i), for i=1,...,n, where x is vector of 32-bit objects integer*4 function vpopcnt4 (x, n) integer*4 x(*), n
vpopcnt8 Returns the total number of 1 bits in the concatenation of the binary representation of x(i), for i=1,...,n, where x is vector of 64-bit objects integer*4 function vpopcnt8 (x, n) integer*8 x(*)

The following example shows XL Fortran interface declarations for some of the MASS double-precision vector routines:

interface

subroutine vsqrt (y, x, n)
  real*8 y(*), x(*)
  integer n        ! Sets y(i) to the square root of x(i), for i=1,..,n
end subroutine vsqrt

subroutine vrsqrt (y, x, n)
  real*8 y(*), x(*)
  integer n        ! Sets y(i) to the reciprocal of the square root of x(i),
                   ! for i=1,..,n
end subroutine vrsqrt

end interface

The following example shows XL Fortran interface declarations for some of the MASS single-precision vector routines:

interface

subroutine vssqrt (y, x, n)
  real*4 y(*), x(*)
  integer n       ! Sets y(i) to the square root of x(i), for i=1,..,n
end subroutine vssqrt

subroutine vsrsqrt (y, x, n)
  real*4 y(*), x(*)
  integer n       ! Sets y(i) to the reciprocal of the square root of x(i),
                   ! for i=1,..,n
end subroutine vsrsqrt

end interface

Overlap of input and output vectors

In most applications, the MASS vector functions are called with disjoint input and output vectors; that is, the two vectors do not overlap in memory. Another common usage scenario is to call them with the same vector for both input and output parameters (for example, vsin (y, y, &n)). Other kinds of overlap (where input and output vectors are neither disjoint nor identical) should be avoided, since they may produce unexpected results:

Consistency of MASS vector functions

All the functions in the MASS vector libraries are consistent, in the sense that a given input value will always produce the same result, regardless of its position in the vector, and regardless of the vector length.

Compiling and linking a program with MASS

To compile an application that calls the functions in the MASS libraries, specify mass and massv on the -l linker option.

For example, if the MASS libraries are installed in the default directory, you could specify:

blrts_xlc progc.c -o progc -lmass -lmassv

blrts_xlf progf.f -o progf -lmass -lmassv

The MASS functions must run in the round-to-nearest rounding mode and with floating-point exception trapping disabled. (These are the default compilation settings.)

Using libmass.a with the math system library

If you wish to use the libmass.a scalar library for some functions and the normal math library libm.a for other functions, follow this procedure to compile and link your program:

  1. Use the ar command to extract the object files of the desired functions from libmass.a. For most functions, the object file name is the function name followed by .s32.o.1 For example, to extract the object file for the tan function, the command would be:
    ar -x tan.s32.o libmass.a
  2. Archive the extracted object files into another library:
     ar -qv libfasttan.a tan.s32.o 
     ranlib libfasttan.a 
  3. Create the final executable using blrts_xlc, specifying -lfasttan instead of -lmass:
    blrts_xlc sample.c -o sample dir_containing_libfasttan.a -lfasttan
    This links only the tan function from MASS (now in libfasttan.a) and the remainder of the math functions from the standard system library.
Exceptions:
  1. The sin and cos functions are both contained in the object file sincos.s32.o. The cosisin and sincos functions are both contained in the object file cosisin.s32.o.