1dnl **********************************************************************
2dnl * Perform  sum <- SUM_{i=0, n-1} x[i]                                *
3dnl **********************************************************************
4dnl
5#include "blas_extended.h"
6#include "blas_extended_private.h"
7include(cblas.m4)dnl
8include(sum-common.m4)dnl
9dnl
10dnl
11define(`SUM_COMMENT',`
12/*
13 * Purpose
14 * =======
15 *
16 * This routine computes the summation:
17 *
18 *     sum <- SUM_{i=0, n-1} x[i].
19 *
20 * Arguments
21 * =========
22 *
23 * n      (input) int
24 *        The length of vector x.
25 *
26 * x      (input) const $1_array
27 *        Array of length n.
28 *
29 * incx   (input) int
30 *        The stride used to access components x[i].
31 *
32 * sum    (output) $1_array
33 *
34PREC_COMMENT($2)dnl
35 */')dnl
36dnl
37dnl
38define(`SUM',
39  `SUM_HEAD($1, $2)
40   SUM_COMMENT($1, $2) {
41     static const char routine_name[] = "SUM_NAME($1, $2)";
42     ifelse(`$2', `_x', `SUM_X_BODY($1_type, $2_type)',
43       `SUM_BODY($1_type, $1_type)')
44   }')dnl
45dnl
46dnl
47dnl Usage:  SUM($1, $2, [$3])
48dnl
49dnl    $1 -- type of x (input vector).
50dnl    $2 -- type of accumulator tmp
51dnl    $3 -- [optional] String `FPU' passed if FPU fix
52dnl          is needed.  Otherwise, it is an empty string.
53dnl
54define(`SUM_BODY', `
55  int i, xi;
56  PTR_CAST(sum, $1)
57  PTR_CAST(x, $1, `const')
58  DECLARE(x_elem, $1)
59  DECLARE(tmp, $2)
60  ifelse(`$3', `FPU', `FPU_FIX_DECL;')
61
62  /* Test the input parameters. */
63  if ( n < 0 )
64    BLAS_error(routine_name,  -1,  n, NULL);
65  if ( incx == 0 )
66    BLAS_error(routine_name,  -3,  incx, NULL);
67
68  /* Immediate return. */
69  if ( n <= 0 ) {
70    ZERO_OUT(sum_i, $1)
71    return;
72  }
73
74  ifelse(`$3', `FPU', `FPU_FIX_START;')
75
76  ZERO(tmp, $2)
77
78  INC_ADJUST(incx, $1)
79  if (incx < 0)
80    xi = -(n-1)*incx;
81  else
82    xi = 0;
83
84  for (i = 0; i < n; i++, xi += incx) {
85    GET_VECTOR_ELEMENT(x_elem, x_i, xi, $1)
86    ADD(tmp, $2, tmp, $2, x_elem, $1)
87  }
88  ROUND(sum, $1, tmp, $2)
89
90  ifelse(`$3', `FPU', `FPU_FIX_STOP;')
91')dnl
92dnl
93dnl
94dnl Usage: SWITCH_prec($1, $2, $3, $4)
95dnl   $1 -- type of sum / input vector
96dnl   $2 -- type of temp in single case
97dnl   $3 -- type of temp in double/indigenous case
98dnl   $4 -- type of temp in extra case
99define(`SWITCH_prec', `switch (prec) {
100    case blas_prec_single: ifelse(`$4&&$5', `$6&&$7', `{
101      SUM_BODY($1, $2)
102      break;
103    }
104    ')dnl
105    case blas_prec_double:
106    case blas_prec_indigenous: {
107      SUM_BODY($1, $3)
108      break;
109    }
110
111    case blas_prec_extra:
112      { SUM_BODY($1, $4, FPU) }
113      break;
114  }')dnl
115dnl
116dnl
117define(`SUM_X_BODY', `ifelse(
118  `$1', `real_S',
119  `SWITCH_prec($1, real_S, real_D, real_E)',
120
121  `$1', `real_D',
122  `SWITCH_prec($1, real_D, real_D, real_E)',
123
124  `$1', `complex_S',
125  `SWITCH_prec($1, complex_S, complex_D, complex_E)',
126
127  `$1', `complex_D',
128  `SWITCH_prec($1, complex_D, complex_D, complex_E)'
129)')dnl
130dnl
131dnl
132