Octopus
operate.c
Go to the documentation of this file.
1/*
2 Copyright (C) 2006 X. Andrade
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17 02110-1301, USA.
18
19*/
20
21#include <config.h>
23#include <stddef.h>
24
25#include <assert.h>
26#include <vectors.h>
27
28#include <string.h>
29
42void FC_FUNC_(doperate_ri_vec,
43 DOPERATE_RI_VEC)(const int *opn, const double *restrict w,
44 const int *opnri, const int *opri,
45 const int *rimap_inv, const int *rimap_inv_max,
46 const double *restrict fi, const int *ldfp,
47 double *restrict fo) {
48 const size_t ldf = ldfp[0];
49
50 /* check whether we got aligned vectors or not */
51 int aligned = 1;
52 aligned = aligned && (((long long)fi) % (8 * VEC_SIZE) == 0);
53 aligned = aligned && (((long long)fo) % (8 * VEC_SIZE) == 0);
54 aligned = aligned && ((1 << ldf) % VEC_SIZE == 0);
55
56 if (aligned) {
57#define ALIGNED
58#include "operate_inc.c"
59#undef ALIGNED
60
61 } else {
62 /* not aligned */
63#include "operate_inc.c"
64 }
65}
67void FC_FUNC_(doperate_ri_sym_vec,
68 DOPERATE_RI_SYM_VEC)(const int *opn, const double *restrict wpair, const double *restrict wcenter,
69 const int *opnri, const int *opri_pos, const int *opri_neg,
70 const int *rimap_inv, const int *rimap_inv_max,
71 const double *restrict fi, const int *ldfp,
72 double *restrict fo) {
73 const size_t ldf = ldfp[0];
74
75 /* check whether we got aligned vectors or not */
76 int aligned = 1;
77 aligned = aligned && (((long long)fi) % (8 * VEC_SIZE) == 0);
78 aligned = aligned && (((long long)fo) % (8 * VEC_SIZE) == 0);
79 aligned = aligned && ((1 << ldf) % VEC_SIZE == 0);
80
81 if (aligned) {
82#define ALIGNED
83#include "operate_sym_inc.c"
84#undef ALIGNED
85
86 } else {
87 /* not aligned */
88 #include "operate_sym_inc.c"
89 }
90}
91
92void FC_FUNC_(doperate_ri_antisym_vec,
93 DOPERATE_RI_ANTISYM_VEC)(const int *opn, const double *restrict wpair,
94 const int *opnri, const int *opri_pos, const int *opri_neg,
95 const int *rimap_inv, const int *rimap_inv_max,
96 const double *restrict fi, const int *ldfp,
97 double *restrict fo) {
98 const size_t ldf = ldfp[0];
99
100 /* check whether we got aligned vectors or not */
101 int aligned = 1;
102 aligned = aligned && (((long long)fi) % (8 * VEC_SIZE) == 0);
103 aligned = aligned && (((long long)fo) % (8 * VEC_SIZE) == 0);
104 aligned = aligned && ((1 << ldf) % VEC_SIZE == 0);
105
106 if (aligned) {
107#define ALIGNED
108#include "operate_antisym_inc.c"
109#undef ALIGNED
110
111 } else {
112 /* not aligned */
113#include "operate_antisym_inc.c"
114 }
115}
116
117
118/* the same as doperate_ri_vec, but allows giving each an appropriate Fortan
119 interface in which fi and fo are actually complex in Fortran Could be inline,
120 but in that case pgcc will not put it in the symbol table. */
121void FC_FUNC_(zoperate_ri_vec,
122 ZOPERATE_RI_VEC)(const int *opn, const double *restrict w,
123 const int *opnri, const int *opri,
124 const int *rimap_inv, const int *rimap_inv_max,
125 const double *restrict fi, const int *ldfp,
126 double *restrict fo) {
127 FC_FUNC_(doperate_ri_vec, DOPERATE_RI_VEC)
128 (opn, w, opnri, opri, rimap_inv, rimap_inv_max, fi, ldfp, fo);
129}
130
131void FC_FUNC_(zoperate_ri_sym_vec,
132 ZOPERATE_RI_SYM_VEC)(const int *opn, const double *restrict w,
133 const double *restrict wcenter,
134 const int *opnri, const int *opri_pos, const int *opri_neg,
135 const int *rimap_inv, const int *rimap_inv_max,
136 const double *restrict fi, const int *ldfp,
137 double *restrict fo) {
138 FC_FUNC_(doperate_ri_sym_vec, DOPERATE_RI_SYM_VEC)
139 (opn, w, wcenter, opnri, opri_pos, opri_neg, rimap_inv, rimap_inv_max, fi, ldfp, fo);
140}
141
142void FC_FUNC_(zoperate_ri_antisym_vec,
143 ZOPERATE_RI_ANTISYM_VEC)(const int *opn, const double *restrict w,
144 const int *opnri, const int *opri_pos, const int *opri_neg,
145 const int *rimap_inv, const int *rimap_inv_max,
146 const double *restrict fi, const int *ldfp,
147 double *restrict fo) {
148 FC_FUNC_(doperate_ri_antisym_vec, DOPERATE_RI_SYM_VEC)
149 (opn, w, opnri, opri_pos, opri_neg, rimap_inv, rimap_inv_max, fi, ldfp, fo);
150}
151
152
153void FC_FUNC_(dgauss_seidel,
154 DGAUSS_SEIDEL)(const int *opn, const double *restrict w,
155 const int *opnri, const int *opri,
156 const int *rimap_inv, const int *rimap_inv_max,
157 const double *restrict factor, double *pot,
158 const double *restrict rho) {
159
160 const int n = opn[0];
161 const int nri = opnri[0];
162
163 int l, i, j;
164 const int *index;
165 register double a0;
166 register const double fac = *factor;
167
168 for (l = 0; l < nri; l++) {
169 index = opri + n * l;
170 i = rimap_inv[l];
171
172 for (; i < rimap_inv_max[l]; i++) {
173 a0 = w[0] * pot[i + index[0]];
174 for (j = 1; j < n; j++)
175 a0 += w[j] * pot[i + index[j]];
176 pot[i] += fac * (a0 - rho[i]);
178 }
179}
181
182// Returns the compile-time vectorization level
183void get_vectorization_level(char * level) {
184 char * vector = VECTORIZATION_LEVEL;
185 size_t len = strlen(vector) + 1;
186 strncpy(level, vector, len);
187}
188
void FC_FUNC_(doperate_ri_sym_vec, DOPERATE_RI_SYM_VEC) const
Definition: operate.c:652
void get_vectorization_level(char *level)
Definition: operate.c:1492
const ptrdiff_t nri
ptrdiff_t l
ptrdiff_t i
ptrdiff_t j
const int *restrict index
Definition: operate_inc.c:13