Cgl 0.59.7

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
CoinAbcHelperFunctions.hpp
Go to the documentation of this file.
1 /* $Id: CoinAbcHelperFunctions.hpp 2042 2014-07-22 10:38:37Z forrest $ */
2 // Copyright (C) 2003, International Business Machines
3 // Corporation and others, Copyright (C) 2012, FasterCoin. All Rights Reserved.
4 // This code is licensed under the terms of the Eclipse Public License (EPL).
5
6 #ifndef CoinAbcHelperFunctions_H
7 #define CoinAbcHelperFunctions_H
8
9 #include "ClpConfig.h"
10 #ifdef HAVE_CMATH
11 # include <cmath>
12 #else
13 # ifdef HAVE_MATH_H
14 # include <math.h>
15 # else
16 # include <cmath>
17 # endif
18 #endif
19 #include "CoinAbcCommon.hpp"
20 #ifndef abc_assert
21 #define abc_assert(condition) \
22 { if (!condition) {printf("abc_assert in %s at line %d - %s is false\n", \
23 __FILE__, __LINE__, __STRING(condition)); abort();} }
24 #endif
25 // cilk_for granularity.
26 #define CILK_FOR_GRAINSIZE 128
27 //#define AVX2 2
28 #if AVX2==1
29 #include "emmintrin.h"
30 #elif AVX2==2
31 #include <immintrin.h>
32 #elif AVX2==3
33 #include "avx2intrin.h"
34 #endif
35 //#define __AVX__ 1
36 //#define __AVX2__ 1
43 #define UNROLL_SCATTER 2
44 #define INLINE_SCATTER 1
45 #if INLINE_SCATTER==0
46 void CoinAbcScatterUpdate(int number,CoinFactorizationDouble pivotValue,
47 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
48 const int * COIN_RESTRICT thisIndex,
49 CoinFactorizationDouble * COIN_RESTRICT region);
50 #else
51 void ABC_INLINE inline CoinAbcScatterUpdate(int number,CoinFactorizationDouble pivotValue,
52 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
53 const int * COIN_RESTRICT thisIndex,
54 CoinFactorizationDouble * COIN_RESTRICT region)
55 {
56 #if UNROLL_SCATTER==0
57 for (CoinBigIndex j=number-1 ; j >=0; j-- ) {
58 CoinSimplexInt iRow = thisIndex[j];
59 CoinFactorizationDouble regionValue = region[iRow];
60 CoinFactorizationDouble value = thisElement[j];
61 assert (value);
62 region[iRow] = regionValue - value * pivotValue;
63 }
64 #elif UNROLL_SCATTER==1
65 if ((number&1)!=0) {
66 number--;
67 CoinSimplexInt iRow = thisIndex[number];
68 CoinFactorizationDouble regionValue = region[iRow];
69 CoinFactorizationDouble value = thisElement[number];
70 region[iRow] = regionValue - value * pivotValue;
71 }
72 for (CoinBigIndex j=number-1 ; j >=0; j-=2 ) {
73 CoinSimplexInt iRow0 = thisIndex[j];
74 CoinSimplexInt iRow1 = thisIndex[j-1];
75 CoinFactorizationDouble regionValue0 = region[iRow0];
76 CoinFactorizationDouble regionValue1 = region[iRow1];
77 region[iRow0] = regionValue0 - thisElement[j] * pivotValue;
78 region[iRow1] = regionValue1 - thisElement[j-1] * pivotValue;
79 }
80 #elif UNROLL_SCATTER==2
81 if ((number&1)!=0) {
82 number--;
83 CoinSimplexInt iRow = thisIndex[number];
84 CoinFactorizationDouble regionValue = region[iRow];
85 CoinFactorizationDouble value = thisElement[number];
86 region[iRow] = regionValue - value * pivotValue;
87 }
88 if ((number&2)!=0) {
89 CoinSimplexInt iRow0 = thisIndex[number-1];
90 CoinFactorizationDouble regionValue0 = region[iRow0];
91 CoinFactorizationDouble value0 = thisElement[number-1];
92 CoinSimplexInt iRow1 = thisIndex[number-2];
93 CoinFactorizationDouble regionValue1 = region[iRow1];
94 CoinFactorizationDouble value1 = thisElement[number-2];
95 region[iRow0] = regionValue0 - value0 * pivotValue;
96 region[iRow1] = regionValue1 - value1 * pivotValue;
97 number-=2;
98 }
99 #pragma cilk grainsize=CILK_FOR_GRAINSIZE
100 cilk_for (CoinBigIndex j=number-1 ; j >=0; j-=4 ) {
101 CoinSimplexInt iRow0 = thisIndex[j];
102 CoinSimplexInt iRow1 = thisIndex[j-1];
103 CoinFactorizationDouble regionValue0 = region[iRow0];
104 CoinFactorizationDouble regionValue1 = region[iRow1];
105 region[iRow0] = regionValue0 - thisElement[j] * pivotValue;
106 region[iRow1] = regionValue1 - thisElement[j-1] * pivotValue;
107 CoinSimplexInt iRow2 = thisIndex[j-2];
108 CoinSimplexInt iRow3 = thisIndex[j-3];
109 CoinFactorizationDouble regionValue2 = region[iRow2];
110 CoinFactorizationDouble regionValue3 = region[iRow3];
111 region[iRow2] = regionValue2 - thisElement[j-2] * pivotValue;
112 region[iRow3] = regionValue3 - thisElement[j-3] * pivotValue;
113 }
114 #elif UNROLL_SCATTER==3
115 CoinSimplexInt iRow0;
116 CoinSimplexInt iRow1;
117 CoinFactorizationDouble regionValue0;
118 CoinFactorizationDouble regionValue1;
119 switch(static_cast<unsigned int>(number)) {
120 case 0:
121 break;
122 case 1:
123 iRow0 = thisIndex[0];
124 regionValue0 = region[iRow0];
125 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
126 break;
127 case 2:
128 iRow0 = thisIndex[0];
129 iRow1 = thisIndex[1];
130 regionValue0 = region[iRow0];
131 regionValue1 = region[iRow1];
132 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
133 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
134 break;
135 case 3:
136 iRow0 = thisIndex[0];
137 iRow1 = thisIndex[1];
138 regionValue0 = region[iRow0];
139 regionValue1 = region[iRow1];
140 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
141 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
142 iRow0 = thisIndex[2];
143 regionValue0 = region[iRow0];
144 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
145 break;
146 case 4:
147 iRow0 = thisIndex[0];
148 iRow1 = thisIndex[1];
149 regionValue0 = region[iRow0];
150 regionValue1 = region[iRow1];
151 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
152 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
153 iRow0 = thisIndex[2];
154 iRow1 = thisIndex[3];
155 regionValue0 = region[iRow0];
156 regionValue1 = region[iRow1];
157 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
158 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
159 break;
160 case 5:
161 iRow0 = thisIndex[0];
162 iRow1 = thisIndex[1];
163 regionValue0 = region[iRow0];
164 regionValue1 = region[iRow1];
165 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
166 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
167 iRow0 = thisIndex[2];
168 iRow1 = thisIndex[3];
169 regionValue0 = region[iRow0];
170 regionValue1 = region[iRow1];
171 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
172 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
173 iRow0 = thisIndex[4];
174 regionValue0 = region[iRow0];
175 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
176 break;
177 case 6:
178 iRow0 = thisIndex[0];
179 iRow1 = thisIndex[1];
180 regionValue0 = region[iRow0];
181 regionValue1 = region[iRow1];
182 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
183 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
184 iRow0 = thisIndex[2];
185 iRow1 = thisIndex[3];
186 regionValue0 = region[iRow0];
187 regionValue1 = region[iRow1];
188 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
189 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
190 iRow0 = thisIndex[4];
191 iRow1 = thisIndex[5];
192 regionValue0 = region[iRow0];
193 regionValue1 = region[iRow1];
194 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
195 region[iRow1] = regionValue1 - thisElement[5] * pivotValue;
196 break;
197 case 7:
198 iRow0 = thisIndex[0];
199 iRow1 = thisIndex[1];
200 regionValue0 = region[iRow0];
201 regionValue1 = region[iRow1];
202 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
203 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
204 iRow0 = thisIndex[2];
205 iRow1 = thisIndex[3];
206 regionValue0 = region[iRow0];
207 regionValue1 = region[iRow1];
208 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
209 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
210 iRow0 = thisIndex[4];
211 iRow1 = thisIndex[5];
212 regionValue0 = region[iRow0];
213 regionValue1 = region[iRow1];
214 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
215 region[iRow1] = regionValue1 - thisElement[5] * pivotValue;
216 iRow0 = thisIndex[6];
217 regionValue0 = region[iRow0];
218 region[iRow0] = regionValue0 - thisElement[6] * pivotValue;
219 break;
220 case 8:
221 iRow0 = thisIndex[0];
222 iRow1 = thisIndex[1];
223 regionValue0 = region[iRow0];
224 regionValue1 = region[iRow1];
225 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
226 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
227 iRow0 = thisIndex[2];
228 iRow1 = thisIndex[3];
229 regionValue0 = region[iRow0];
230 regionValue1 = region[iRow1];
231 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
232 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
233 iRow0 = thisIndex[4];
234 iRow1 = thisIndex[5];
235 regionValue0 = region[iRow0];
236 regionValue1 = region[iRow1];
237 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
238 region[iRow1] = regionValue1 - thisElement[5] * pivotValue;
239 iRow0 = thisIndex[6];
240 iRow1 = thisIndex[7];
241 regionValue0 = region[iRow0];
242 regionValue1 = region[iRow1];
243 region[iRow0] = regionValue0 - thisElement[6] * pivotValue;
244 region[iRow1] = regionValue1 - thisElement[7] * pivotValue;
245 break;
246 default:
247 if ((number&1)!=0) {
248 number--;
249 CoinSimplexInt iRow = thisIndex[number];
250 CoinFactorizationDouble regionValue = region[iRow];
251 CoinFactorizationDouble value = thisElement[number];
252 region[iRow] = regionValue - value * pivotValue;
253 }
254 for (CoinBigIndex j=number-1 ; j >=0; j-=2 ) {
255 CoinSimplexInt iRow0 = thisIndex[j];
256 CoinSimplexInt iRow1 = thisIndex[j-1];
257 CoinFactorizationDouble regionValue0 = region[iRow0];
258 CoinFactorizationDouble regionValue1 = region[iRow1];
259 region[iRow0] = regionValue0 - thisElement[j] * pivotValue;
260 region[iRow1] = regionValue1 - thisElement[j-1] * pivotValue;
261 }
262 break;
263 }
264 #endif
265 }
266 void ABC_INLINE inline CoinAbcScatterUpdate(int number,CoinFactorizationDouble pivotValue,
267 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
268 CoinFactorizationDouble * COIN_RESTRICT region)
269 {
270 #if UNROLL_SCATTER==0
271 const int * COIN_RESTRICT thisIndex = reinterpret_cast<const int *>(thisElement+number);
272 for (CoinBigIndex j=number-1 ; j >=0; j-- ) {
273 CoinSimplexInt iRow = thisIndex[j];
274 CoinFactorizationDouble regionValue = region[iRow];
275 CoinFactorizationDouble value = thisElement[j];
276 assert (value);
277 region[iRow] = regionValue - value * pivotValue;
278 }
279 #elif UNROLL_SCATTER==1
280 const int * COIN_RESTRICT thisIndex = reinterpret_cast<const int *>(thisElement+number);
281 if ((number&1)!=0) {
282 number--;
283 CoinSimplexInt iRow = thisIndex[number];
284 CoinFactorizationDouble regionValue = region[iRow];
285 CoinFactorizationDouble value = thisElement[number];
286 region[iRow] = regionValue - value * pivotValue;
287 }
288 for (CoinBigIndex j=number-1 ; j >=0; j-=2 ) {
289 CoinSimplexInt iRow0 = thisIndex[j];
290 CoinSimplexInt iRow1 = thisIndex[j-1];
291 CoinFactorizationDouble regionValue0 = region[iRow0];
292 CoinFactorizationDouble regionValue1 = region[iRow1];
293 region[iRow0] = regionValue0 - thisElement[j] * pivotValue;
294 region[iRow1] = regionValue1 - thisElement[j-1] * pivotValue;
295 }
296 #elif UNROLL_SCATTER==2
297 const int * COIN_RESTRICT thisIndex = reinterpret_cast<const int *>(thisElement+number);
298 if ((number&1)!=0) {
299 number--;
300 CoinSimplexInt iRow = thisIndex[number];
301 CoinFactorizationDouble regionValue = region[iRow];
302 CoinFactorizationDouble value = thisElement[number];
303 region[iRow] = regionValue - value * pivotValue;
304 }
305 if ((number&2)!=0) {
306 CoinSimplexInt iRow0 = thisIndex[number-1];
307 CoinFactorizationDouble regionValue0 = region[iRow0];
308 CoinFactorizationDouble value0 = thisElement[number-1];
309 CoinSimplexInt iRow1 = thisIndex[number-2];
310 CoinFactorizationDouble regionValue1 = region[iRow1];
311 CoinFactorizationDouble value1 = thisElement[number-2];
312 region[iRow0] = regionValue0 - value0 * pivotValue;
313 region[iRow1] = regionValue1 - value1 * pivotValue;
314 number-=2;
315 }
316 #if AVX2==22
317 CoinFactorizationDouble temp[4] __attribute__ ((aligned (32)));
318 __m256d pv = _mm256_broadcast_sd(&pivotValue);
319 for (CoinBigIndex j=number-1 ; j >=0; j-=4 ) {
320 __m256d elements=_mm256_loadu_pd(thisElement+j-3);
321 CoinSimplexInt iRow0 = thisIndex[j-3];
322 CoinSimplexInt iRow1 = thisIndex[j-2];
323 CoinSimplexInt iRow2 = thisIndex[j-1];
324 CoinSimplexInt iRow3 = thisIndex[j-0];
325 temp[0] = region[iRow0];
326 temp[1] = region[iRow1];
327 temp[2] = region[iRow2];
328 temp[3] = region[iRow3];
329 __m256d t0=_mm256_load_pd(temp);
330 t0 -= pv*elements;
331 _mm256_store_pd (temp, t0);
332 region[iRow0] = temp[0];
333 region[iRow1] = temp[1];
334 region[iRow2] = temp[2];
335 region[iRow3] = temp[3];
336 }
337 #else
338 #pragma cilk grainsize=CILK_FOR_GRAINSIZE
339 cilk_for (CoinBigIndex j=number-1 ; j >=0; j-=4 ) {
340 CoinSimplexInt iRow0 = thisIndex[j];
341 CoinSimplexInt iRow1 = thisIndex[j-1];
342 CoinFactorizationDouble regionValue0 = region[iRow0];
343 CoinFactorizationDouble regionValue1 = region[iRow1];
344 region[iRow0] = regionValue0 - thisElement[j] * pivotValue;
345 region[iRow1] = regionValue1 - thisElement[j-1] * pivotValue;
346 CoinSimplexInt iRow2 = thisIndex[j-2];
347 CoinSimplexInt iRow3 = thisIndex[j-3];
348 CoinFactorizationDouble regionValue2 = region[iRow2];
349 CoinFactorizationDouble regionValue3 = region[iRow3];
350 region[iRow2] = regionValue2 - thisElement[j-2] * pivotValue;
351 region[iRow3] = regionValue3 - thisElement[j-3] * pivotValue;
352 }
353 #endif
354 #elif UNROLL_SCATTER==3
355 const int * COIN_RESTRICT thisIndex = reinterpret_cast<const int *>(thisElement+number);
356 CoinSimplexInt iRow0;
357 CoinSimplexInt iRow1;
358 CoinFactorizationDouble regionValue0;
359 CoinFactorizationDouble regionValue1;
360 switch(static_cast<unsigned int>(number)) {
361 case 0:
362 break;
363 case 1:
364 iRow0 = thisIndex[0];
365 regionValue0 = region[iRow0];
366 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
367 break;
368 case 2:
369 iRow0 = thisIndex[0];
370 iRow1 = thisIndex[1];
371 regionValue0 = region[iRow0];
372 regionValue1 = region[iRow1];
373 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
374 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
375 break;
376 case 3:
377 iRow0 = thisIndex[0];
378 iRow1 = thisIndex[1];
379 regionValue0 = region[iRow0];
380 regionValue1 = region[iRow1];
381 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
382 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
383 iRow0 = thisIndex[2];
384 regionValue0 = region[iRow0];
385 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
386 break;
387 case 4:
388 iRow0 = thisIndex[0];
389 iRow1 = thisIndex[1];
390 regionValue0 = region[iRow0];
391 regionValue1 = region[iRow1];
392 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
393 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
394 iRow0 = thisIndex[2];
395 iRow1 = thisIndex[3];
396 regionValue0 = region[iRow0];
397 regionValue1 = region[iRow1];
398 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
399 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
400 break;
401 case 5:
402 iRow0 = thisIndex[0];
403 iRow1 = thisIndex[1];
404 regionValue0 = region[iRow0];
405 regionValue1 = region[iRow1];
406 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
407 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
408 iRow0 = thisIndex[2];
409 iRow1 = thisIndex[3];
410 regionValue0 = region[iRow0];
411 regionValue1 = region[iRow1];
412 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
413 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
414 iRow0 = thisIndex[4];
415 regionValue0 = region[iRow0];
416 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
417 break;
418 case 6:
419 iRow0 = thisIndex[0];
420 iRow1 = thisIndex[1];
421 regionValue0 = region[iRow0];
422 regionValue1 = region[iRow1];
423 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
424 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
425 iRow0 = thisIndex[2];
426 iRow1 = thisIndex[3];
427 regionValue0 = region[iRow0];
428 regionValue1 = region[iRow1];
429 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
430 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
431 iRow0 = thisIndex[4];
432 iRow1 = thisIndex[5];
433 regionValue0 = region[iRow0];
434 regionValue1 = region[iRow1];
435 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
436 region[iRow1] = regionValue1 - thisElement[5] * pivotValue;
437 break;
438 case 7:
439 iRow0 = thisIndex[0];
440 iRow1 = thisIndex[1];
441 regionValue0 = region[iRow0];
442 regionValue1 = region[iRow1];
443 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
444 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
445 iRow0 = thisIndex[2];
446 iRow1 = thisIndex[3];
447 regionValue0 = region[iRow0];
448 regionValue1 = region[iRow1];
449 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
450 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
451 iRow0 = thisIndex[4];
452 iRow1 = thisIndex[5];
453 regionValue0 = region[iRow0];
454 regionValue1 = region[iRow1];
455 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
456 region[iRow1] = regionValue1 - thisElement[5] * pivotValue;
457 iRow0 = thisIndex[6];
458 regionValue0 = region[iRow0];
459 region[iRow0] = regionValue0 - thisElement[6] * pivotValue;
460 break;
461 case 8:
462 iRow0 = thisIndex[0];
463 iRow1 = thisIndex[1];
464 regionValue0 = region[iRow0];
465 regionValue1 = region[iRow1];
466 region[iRow0] = regionValue0 - thisElement[0] * pivotValue;
467 region[iRow1] = regionValue1 - thisElement[1] * pivotValue;
468 iRow0 = thisIndex[2];
469 iRow1 = thisIndex[3];
470 regionValue0 = region[iRow0];
471 regionValue1 = region[iRow1];
472 region[iRow0] = regionValue0 - thisElement[2] * pivotValue;
473 region[iRow1] = regionValue1 - thisElement[3] * pivotValue;
474 iRow0 = thisIndex[4];
475 iRow1 = thisIndex[5];
476 regionValue0 = region[iRow0];
477 regionValue1 = region[iRow1];
478 region[iRow0] = regionValue0 - thisElement[4] * pivotValue;
479 region[iRow1] = regionValue1 - thisElement[5] * pivotValue;
480 iRow0 = thisIndex[6];
481 iRow1 = thisIndex[7];
482 regionValue0 = region[iRow0];
483 regionValue1 = region[iRow1];
484 region[iRow0] = regionValue0 - thisElement[6] * pivotValue;
485 region[iRow1] = regionValue1 - thisElement[7] * pivotValue;
486 break;
487 default:
488 if ((number&1)!=0) {
489 number--;
490 CoinSimplexInt iRow = thisIndex[number];
491 CoinFactorizationDouble regionValue = region[iRow];
492 CoinFactorizationDouble value = thisElement[number];
493 region[iRow] = regionValue - value * pivotValue;
494 }
495 for (CoinBigIndex j=number-1 ; j >=0; j-=2 ) {
496 CoinSimplexInt iRow0 = thisIndex[j];
497 CoinSimplexInt iRow1 = thisIndex[j-1];
498 CoinFactorizationDouble regionValue0 = region[iRow0];
499 CoinFactorizationDouble regionValue1 = region[iRow1];
500 region[iRow0] = regionValue0 - thisElement[j] * pivotValue;
501 region[iRow1] = regionValue1 - thisElement[j-1] * pivotValue;
502 }
503 break;
504 }
505 #endif
506 }
507 #endif
508 //#define COIN_PREFETCH
509 #ifdef COIN_PREFETCH
510 #if 1
511 #define coin_prefetch(mem) \
512 __asm__ __volatile__ ("prefetchnta %0" : : "m" (*(reinterpret_cast<char *>(mem))))
513 #define coin_prefetch_const(mem) \
514 __asm__ __volatile__ ("prefetchnta %0" : : "m" (*(reinterpret_cast<const char *>(mem))))
515 #else
516 #define coin_prefetch(mem) \
517 __asm__ __volatile__ ("prefetch %0" : : "m" (*(reinterpret_cast<char *>(mem))))
518 #define coin_prefetch_const(mem) \
519 __asm__ __volatile__ ("prefetch %0" : : "m" (*(reinterpret_cast<const char *>(mem))))
520 #endif
521 #else
522 // dummy
523 #define coin_prefetch(mem)
524 #define coin_prefetch_const(mem)
525 #endif
526 #define NEW_CHUNK_SIZE 4
527 #define NEW_CHUNK_SIZE_INCREMENT (NEW_CHUNK_SIZE+NEW_CHUNK_SIZE/2);
528 #define NEW_CHUNK_SIZE_OFFSET (NEW_CHUNK_SIZE/2)
529 // leaf, pure, nothrow and hot give warnings
530 // fastcall and sseregparm give wrong results
531 //#define SCATTER_ATTRIBUTE __attribute__ ((leaf,fastcall,pure,sseregparm,nothrow,hot))
532 #define SCATTER_ATTRIBUTE
533 typedef void (*scatterUpdate) (int,CoinFactorizationDouble,const CoinFactorizationDouble *, double *) SCATTER_ATTRIBUTE ;
534 typedef struct {
535 scatterUpdate functionPointer;
536 CoinBigIndex offset;
537 int number;
538 } scatterStruct;
539 void CoinAbcScatterUpdate0(int numberIn, CoinFactorizationDouble multiplier,
540 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
541 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
542 void CoinAbcScatterUpdate1(int numberIn, CoinFactorizationDouble multiplier,
543 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
544 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
545 void CoinAbcScatterUpdate2(int numberIn, CoinFactorizationDouble multiplier,
546 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
547 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
548 void CoinAbcScatterUpdate3(int numberIn, CoinFactorizationDouble multiplier,
549 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
550 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
551 void CoinAbcScatterUpdate4(int numberIn, CoinFactorizationDouble multiplier,
552 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
553 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
554 void CoinAbcScatterUpdate5(int numberIn, CoinFactorizationDouble multiplier,
555 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
556 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
557 void CoinAbcScatterUpdate6(int numberIn, CoinFactorizationDouble multiplier,
558 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
559 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
560 void CoinAbcScatterUpdate7(int numberIn, CoinFactorizationDouble multiplier,
561 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
562 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
563 void CoinAbcScatterUpdate8(int numberIn, CoinFactorizationDouble multiplier,
564 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
565 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
566 void CoinAbcScatterUpdate4N(int numberIn, CoinFactorizationDouble multiplier,
567 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
568 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
569 void CoinAbcScatterUpdate4NPlus1(int numberIn, CoinFactorizationDouble multiplier,
570 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
571 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
572 void CoinAbcScatterUpdate4NPlus2(int numberIn, CoinFactorizationDouble multiplier,
573 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
574 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
575 void CoinAbcScatterUpdate4NPlus3(int numberIn, CoinFactorizationDouble multiplier,
576 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
577 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
578 void CoinAbcScatterUpdate1Subtract(int numberIn, CoinFactorizationDouble multiplier,
579 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
580 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
581 void CoinAbcScatterUpdate2Subtract(int numberIn, CoinFactorizationDouble multiplier,
582 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
583 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
584 void CoinAbcScatterUpdate3Subtract(int numberIn, CoinFactorizationDouble multiplier,
585 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
586 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
587 void CoinAbcScatterUpdate4Subtract(int numberIn, CoinFactorizationDouble multiplier,
588 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
589 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
590 void CoinAbcScatterUpdate5Subtract(int numberIn, CoinFactorizationDouble multiplier,
591 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
592 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
593 void CoinAbcScatterUpdate6Subtract(int numberIn, CoinFactorizationDouble multiplier,
594 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
595 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
596 void CoinAbcScatterUpdate7Subtract(int numberIn, CoinFactorizationDouble multiplier,
597 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
598 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
599 void CoinAbcScatterUpdate8Subtract(int numberIn, CoinFactorizationDouble multiplier,
600 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
601 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
602 void CoinAbcScatterUpdate4NSubtract(int numberIn, CoinFactorizationDouble multiplier,
603 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
604 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
605 void CoinAbcScatterUpdate4NPlus1Subtract(int numberIn, CoinFactorizationDouble multiplier,
606 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
607 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
608 void CoinAbcScatterUpdate4NPlus2Subtract(int numberIn, CoinFactorizationDouble multiplier,
609 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
610 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
611 void CoinAbcScatterUpdate4NPlus3Subtract(int numberIn, CoinFactorizationDouble multiplier,
612 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
613 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
614 void CoinAbcScatterUpdate1Add(int numberIn, CoinFactorizationDouble multiplier,
615 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
616 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
617 void CoinAbcScatterUpdate2Add(int numberIn, CoinFactorizationDouble multiplier,
618 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
619 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
620 void CoinAbcScatterUpdate3Add(int numberIn, CoinFactorizationDouble multiplier,
621 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
622 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
623 void CoinAbcScatterUpdate4Add(int numberIn, CoinFactorizationDouble multiplier,
624 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
625 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
626 void CoinAbcScatterUpdate5Add(int numberIn, CoinFactorizationDouble multiplier,
627 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
628 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
629 void CoinAbcScatterUpdate6Add(int numberIn, CoinFactorizationDouble multiplier,
630 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
631 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
632 void CoinAbcScatterUpdate7Add(int numberIn, CoinFactorizationDouble multiplier,
633 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
634 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
635 void CoinAbcScatterUpdate8Add(int numberIn, CoinFactorizationDouble multiplier,
636 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
637 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
638 void CoinAbcScatterUpdate4NAdd(int numberIn, CoinFactorizationDouble multiplier,
639 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
640 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
641 void CoinAbcScatterUpdate4NPlus1Add(int numberIn, CoinFactorizationDouble multiplier,
642 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
643 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
644 void CoinAbcScatterUpdate4NPlus2Add(int numberIn, CoinFactorizationDouble multiplier,
645 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
646 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
647 void CoinAbcScatterUpdate4NPlus3Add(int numberIn, CoinFactorizationDouble multiplier,
648 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
649 CoinFactorizationDouble * COIN_RESTRICT region) SCATTER_ATTRIBUTE ;
650 #if INLINE_SCATTER==0
651 void CoinAbcScatterUpdate(int number,CoinFactorizationDouble pivotValue,
652 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
653 const int * COIN_RESTRICT thisIndex,
654 CoinFactorizationDouble * COIN_RESTRICT region,
655 double * COIN_RESTRICT work);
656 #else
657 #if 0
658 void ABC_INLINE inline CoinAbcScatterUpdate(int number,CoinFactorizationDouble pivotValue,
659 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
660 const int * COIN_RESTRICT thisIndex,
661 CoinFactorizationDouble * COIN_RESTRICT region,
662 double * COIN_RESTRICT /*work*/)
663 {
664 #if UNROLL_SCATTER==0
665 for (CoinBigIndex j=number-1 ; j >=0; j-- ) {
666 CoinSimplexInt iRow = thisIndex[j];
667 CoinFactorizationDouble regionValue = region[iRow];
668 CoinFactorizationDouble value = thisElement[j];
669 assert (value);
670 region[iRow] = regionValue - value * pivotValue;
671 }
672 #elif UNROLL_SCATTER==1
673 if ((number&1)!=0) {
674 CoinSimplexInt iRow = thisIndex[0];
675 thisIndex++;
676 CoinFactorizationDouble regionValue = region[iRow];
677 CoinFactorizationDouble value = thisElement[0];
678 thisElement++;
679 region[iRow] = regionValue - value * pivotValue;
680 }
681 number = number>>1;
682 CoinFactorizationDouble work2[4];
683 for ( ; number !=0; number-- ) {
684 CoinSimplexInt iRow0 = thisIndex[0];
685 CoinSimplexInt iRow1 = thisIndex[1];
686 work2[0] = region[iRow0];
687 work2[1] = region[iRow1];
688 #if 0
689 work2[2] = region[iRow0];
690 work2[3] = region[iRow1];
691 //__v4df b = __builtin_ia32_maskloadpd256(work2);
692 __v4df b = __builtin_ia32_loadupd256(work2);
693 //__v4df b = _mm256_load_pd(work2);
694 #endif
695 work2[0] -= thisElement[0] * pivotValue;
696 work2[1] -= thisElement[1] * pivotValue;
697 region[iRow0] = work2[0];
698 region[iRow1] = work2[1];
699 thisIndex+=2;
700 thisElement+=2;
701 }
702 #endif
703 }
704 #endif
705 #endif
706 #define UNROLL_GATHER 0
707 #define INLINE_GATHER 1
708 #if INLINE_GATHER==0
709 CoinFactorizationDouble CoinAbcGatherUpdate(CoinSimplexInt number,
710 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
711 const int * COIN_RESTRICT thisIndex,
712 CoinFactorizationDouble * COIN_RESTRICT region);
713 #else
714 CoinFactorizationDouble ABC_INLINE inline CoinAbcGatherUpdate(CoinSimplexInt number,
715 const CoinFactorizationDouble * COIN_RESTRICT thisElement,
716 const int * COIN_RESTRICT thisIndex,
717 CoinFactorizationDouble * COIN_RESTRICT region)
718 {
719 #if UNROLL_GATHER==0
720 CoinFactorizationDouble pivotValue=0.0;
721 for (CoinBigIndex j = 0; j < number; j ++ ) {
722 CoinFactorizationDouble value = thisElement[j];
723 CoinSimplexInt jRow = thisIndex[j];
724 value *= region[jRow];
725 pivotValue -= value;
726 }
727 return pivotValue;
728 #else
729 #error code
730 #endif
731 }
732 #endif
733 #define UNROLL_MULTIPLY_INDEXED 0
734 #define INLINE_MULTIPLY_INDEXED 0
735 #if INLINE_MULTIPLY_INDEXED==0
736 void CoinAbcMultiplyIndexed(int number,
737 const double * COIN_RESTRICT multiplier,
738 const int * COIN_RESTRICT thisIndex,
739 CoinFactorizationDouble * COIN_RESTRICT region);
740 void CoinAbcMultiplyIndexed(int number,
741 const long double * COIN_RESTRICT multiplier,
742 const int * COIN_RESTRICT thisIndex,
743 long double * COIN_RESTRICT region);
744 #else
745 void ABC_INLINE inline CoinAbcMultiplyIndexed(int number,
746 const double * COIN_RESTRICT multiplier,
747 const int * COIN_RESTRICT thisIndex,
748 CoinFactorizationDouble * COIN_RESTRICT region)
749 {
750 }
751 #endif
752 double CoinAbcMaximumAbsElement(const double * region, int size);
753 void CoinAbcMinMaxAbsElement(const double * region, int size,double & minimum , double & maximum);
754 void CoinAbcMinMaxAbsNormalValues(const double * region, int size,double & minimum , double & maximum);
755 void CoinAbcScale(double * region, double multiplier,int size);
756 void CoinAbcScaleNormalValues(double * region, double multiplier,double killIfLessThanThis,int size);
758 double CoinAbcMaximumAbsElementAndScale(double * region, double multiplier,int size);
759 void CoinAbcSetElements(double * region, int size, double value);
760 void CoinAbcMultiplyAdd(const double * region1, int size, double multiplier1,
761 double * regionChanged, double multiplier2);
762 double CoinAbcInnerProduct(const double * region1, int size, const double * region2);
763 void CoinAbcGetNorms(const double * region, int size, double & norm1, double & norm2);
765 void CoinAbcScatterTo(const double * regionFrom, double * regionTo, const int * index,int number);
767 void CoinAbcGatherFrom(const double * regionFrom, double * regionTo, const int * index,int number);
769 void CoinAbcScatterZeroTo(double * regionTo, const int * index,int number);
771 void CoinAbcScatterToList(const double * regionFrom, double * regionTo,
772 const int * indexList, const int * indexScatter ,int number);
774 void CoinAbcInverseSqrts(double * array, int n);
775 void CoinAbcReciprocal(double * array, int n, const double *input);
776 void CoinAbcMemcpyLong(double * array,const double * arrayFrom,int size);
777 void CoinAbcMemcpyLong(int * array,const int * arrayFrom,int size);
778 void CoinAbcMemcpyLong(unsigned char * array,const unsigned char * arrayFrom,int size);
779 void CoinAbcMemset0Long(double * array,int size);
780 void CoinAbcMemset0Long(int * array,int size);
781 void CoinAbcMemset0Long(unsigned char * array,int size);
782 void CoinAbcMemmove(double * array,const double * arrayFrom,int size);
783 void CoinAbcMemmove(int * array,const int * arrayFrom,int size);
784 void CoinAbcMemmove(unsigned char * array,const unsigned char * arrayFrom,int size);
786 void CoinAbcMemmoveAndZero(double * array,double * arrayFrom,int size);
788 int CoinAbcCompact(int numberSections,int alreadyDone,double * array,const int * starts, const int * lengths);
790 int CoinAbcCompact(int numberSections,int alreadyDone,int * array,const int * starts, const int * lengths);
791 #endif
792 #if ABC_CREATE_SCATTER_FUNCTION
793 SCATTER_ATTRIBUTE void functionName(ScatterUpdate1)(int numberIn, CoinFactorizationDouble multiplier,
794 const CoinFactorizationDouble * COIN_RESTRICT element,
795 CoinFactorizationDouble * COIN_RESTRICT region)
796 {
797 #ifndef NDEBUG
798 assert (numberIn==1);
799 #endif
800 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+1);
801 int iColumn0=thisColumn[0];
802 double value0=region[iColumn0];
803 value0 OPERATION multiplier*element[0];
804 region[iColumn0]=value0;
805 }
806 SCATTER_ATTRIBUTE void functionName(ScatterUpdate2)(int numberIn, CoinFactorizationDouble multiplier,
807 const CoinFactorizationDouble * COIN_RESTRICT element,
808 CoinFactorizationDouble * COIN_RESTRICT region)
809 {
810 #ifndef NDEBUG
811 assert (numberIn==2);
812 #endif
813 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+2);
814 #if NEW_CHUNK_SIZE==2
815 int nFull=2&(~(NEW_CHUNK_SIZE-1));
816 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
817 coin_prefetch(element+NEW_CHUNK_SIZE_INCREMENT);
818 int iColumn0=thisColumn[0];
819 int iColumn1=thisColumn[1];
820 CoinFactorizationDouble value0=region[iColumn0];
821 CoinFactorizationDouble value1=region[iColumn1];
822 value0 OPERATION multiplier*element[0+NEW_CHUNK_SIZE_OFFSET];
823 value1 OPERATION multiplier*element[1+NEW_CHUNK_SIZE_OFFSET];
824 region[iColumn0]=value0;
825 region[iColumn1]=value1;
826 element+=NEW_CHUNK_SIZE_INCREMENT;
827 thisColumn = reinterpret_cast<const int *>(element);
828 }
829 #endif
830 #if NEW_CHUNK_SIZE==4
831 int iColumn0=thisColumn[0];
832 int iColumn1=thisColumn[1];
833 CoinFactorizationDouble value0=region[iColumn0];
834 CoinFactorizationDouble value1=region[iColumn1];
835 value0 OPERATION multiplier*element[0];
836 value1 OPERATION multiplier*element[1];
837 region[iColumn0]=value0;
838 region[iColumn1]=value1;
839 #endif
840 }
841 SCATTER_ATTRIBUTE void functionName(ScatterUpdate3)(int numberIn, CoinFactorizationDouble multiplier,
842 const CoinFactorizationDouble * COIN_RESTRICT element,
843 CoinFactorizationDouble * COIN_RESTRICT region)
844 {
845 #ifndef NDEBUG
846 assert (numberIn==3);
847 #endif
848 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+3);
849 #if AVX2==1
850 double temp[2];
851 #endif
852 #if NEW_CHUNK_SIZE==2
853 int nFull=3&(~(NEW_CHUNK_SIZE-1));
854 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
855 //coin_prefetch_const(element+NEW_CHUNK_SIZE_INCREMENT);
856 int iColumn0=thisColumn[0];
857 int iColumn1=thisColumn[1];
858 CoinFactorizationDouble value0=region[iColumn0];
859 CoinFactorizationDouble value1=region[iColumn1];
860 value0 OPERATION multiplier*element[0];
861 value1 OPERATION multiplier*element[1];
862 region[iColumn0]=value0;
863 region[iColumn1]=value1;
864 element+=NEW_CHUNK_SIZE;
865 thisColumn+ = NEW_CHUNK_SIZE;
866 }
867 #endif
868 #if NEW_CHUNK_SIZE==2
869 int iColumn0=thisColumn[0];
870 double value0=region[iColumn0];
871 value0 OPERATION multiplier*element[0];
872 region[iColumn0]=value0;
873 #else
874 int iColumn0=thisColumn[0];
875 int iColumn1=thisColumn[1];
876 int iColumn2=thisColumn[2];
877 #if AVX2==1
878 __v2df bb;
879 double value2=region[iColumn2];
880 value2 OPERATION multiplier*element[2];
881 set_const_v2df(bb,multiplier);
882 temp[0]=region[iColumn0];
883 temp[1]=region[iColumn1];
884 region[iColumn2]=value2;
885 __v2df v0 = __builtin_ia32_loadupd (temp);
886 __v2df a = __builtin_ia32_loadupd (element);
887 a *= bb;
888 v0 OPERATION a;
889 __builtin_ia32_storeupd (temp, v0);
890 region[iColumn0]=temp[0];
891 region[iColumn1]=temp[1];
892 #else
893 double value0=region[iColumn0];
894 double value1=region[iColumn1];
895 double value2=region[iColumn2];
896 value0 OPERATION multiplier*element[0];
897 value1 OPERATION multiplier*element[1];
898 value2 OPERATION multiplier*element[2];
899 region[iColumn0]=value0;
900 region[iColumn1]=value1;
901 region[iColumn2]=value2;
902 #endif
903 #endif
904 }
905 SCATTER_ATTRIBUTE void functionName(ScatterUpdate4)(int numberIn, CoinFactorizationDouble multiplier,
906 const CoinFactorizationDouble * COIN_RESTRICT element,
907 CoinFactorizationDouble * COIN_RESTRICT region)
908 {
909 #ifndef NDEBUG
910 assert (numberIn==4);
911 #endif
912 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+4);
913 int nFull=4&(~(NEW_CHUNK_SIZE-1));
914 #if AVX2==1
915 double temp[4];
916 #endif
917 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
918 //coin_prefetch_const(element+NEW_CHUNK_SIZE_INCREMENT);
919 #if NEW_CHUNK_SIZE==2
920 int iColumn0=thisColumn[0];
921 int iColumn1=thisColumn[1];
922 double value0=region[iColumn0];
923 double value1=region[iColumn1];
924 value0 OPERATION multiplier*element[0];
925 value1 OPERATION multiplier*element[1];
926 region[iColumn0]=value0;
927 region[iColumn1]=value1;
928 #elif NEW_CHUNK_SIZE==4
929 int iColumn0=thisColumn[0];
930 int iColumn1=thisColumn[1];
931 int iColumn2=thisColumn[2];
932 int iColumn3=thisColumn[3];
933 #if AVX2==1
934 __v2df bb;
935 set_const_v2df(bb,multiplier);
936 temp[0]=region[iColumn0];
937 temp[1]=region[iColumn1];
938 temp[2]=region[iColumn2];
939 temp[3]=region[iColumn3];
940 __v2df v0 = __builtin_ia32_loadupd (temp);
941 __v2df v1 = __builtin_ia32_loadupd (temp+2);
942 __v2df a = __builtin_ia32_loadupd (element);
943 a *= bb;
944 v0 OPERATION a;
945 a = __builtin_ia32_loadupd (element+2);
946 a *= bb;
947 v1 OPERATION a;
948 __builtin_ia32_storeupd (temp, v0);
949 __builtin_ia32_storeupd (temp+2, v1);
950 region[iColumn0]=temp[0];
951 region[iColumn1]=temp[1];
952 region[iColumn2]=temp[2];
953 region[iColumn3]=temp[3];
954 #else
955 double value0=region[iColumn0];
956 double value1=region[iColumn1];
957 double value2=region[iColumn2];
958 double value3=region[iColumn3];
959 value0 OPERATION multiplier*element[0];
960 value1 OPERATION multiplier*element[1];
961 value2 OPERATION multiplier*element[2];
962 value3 OPERATION multiplier*element[3];
963 region[iColumn0]=value0;
964 region[iColumn1]=value1;
965 region[iColumn2]=value2;
966 region[iColumn3]=value3;
967 #endif
968 #else
969 abort();
970 #endif
971 element+=NEW_CHUNK_SIZE;
972 thisColumn += NEW_CHUNK_SIZE;
973 }
974 }
975 SCATTER_ATTRIBUTE void functionName(ScatterUpdate5)(int numberIn, CoinFactorizationDouble multiplier,
976 const CoinFactorizationDouble * COIN_RESTRICT element,
977 CoinFactorizationDouble * COIN_RESTRICT region)
978 {
979 #ifndef NDEBUG
980 assert (numberIn==5);
981 #endif
982 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+5);
983 int nFull=5&(~(NEW_CHUNK_SIZE-1));
984 #if AVX2==1
985 double temp[4];
986 #endif
987 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
988 //coin_prefetch_const(element+NEW_CHUNK_SIZE_INCREMENT);
989 #if NEW_CHUNK_SIZE==2
990 int iColumn0=thisColumn[0];
991 int iColumn1=thisColumn[1];
992 double value0=region[iColumn0];
993 double value1=region[iColumn1];
994 value0 OPERATION multiplier*element[0];
995 value1 OPERATION multiplier*element[1];
996 region[iColumn0]=value0;
997 region[iColumn1]=value1;
998 #elif NEW_CHUNK_SIZE==4
999 int iColumn0=thisColumn[0];
1000 int iColumn1=thisColumn[1];
1001 int iColumn2=thisColumn[2];
1002 int iColumn3=thisColumn[3];
1003 #if AVX2==1
1004 __v2df bb;
1005 set_const_v2df(bb,multiplier);
1006 temp[0]=region[iColumn0];
1007 temp[1]=region[iColumn1];
1008 temp[2]=region[iColumn2];
1009 temp[3]=region[iColumn3];
1010 __v2df v0 = __builtin_ia32_loadupd (temp);
1011 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1012 __v2df a = __builtin_ia32_loadupd (element);
1013 a *= bb;
1014 v0 OPERATION a;
1015 a = __builtin_ia32_loadupd (element+2);
1016 a *= bb;
1017 v1 OPERATION a;
1018 __builtin_ia32_storeupd (temp, v0);
1019 __builtin_ia32_storeupd (temp+2, v1);
1020 region[iColumn0]=temp[0];
1021 region[iColumn1]=temp[1];
1022 region[iColumn2]=temp[2];
1023 region[iColumn3]=temp[3];
1024 #else
1025 double value0=region[iColumn0];
1026 double value1=region[iColumn1];
1027 double value2=region[iColumn2];
1028 double value3=region[iColumn3];
1029 value0 OPERATION multiplier*element[0];
1030 value1 OPERATION multiplier*element[1];
1031 value2 OPERATION multiplier*element[2];
1032 value3 OPERATION multiplier*element[3];
1033 region[iColumn0]=value0;
1034 region[iColumn1]=value1;
1035 region[iColumn2]=value2;
1036 region[iColumn3]=value3;
1037 #endif
1038 #else
1039 abort();
1040 #endif
1041 element+=NEW_CHUNK_SIZE;
1042 thisColumn += NEW_CHUNK_SIZE;
1043 }
1044 int iColumn0=thisColumn[0];
1045 double value0=region[iColumn0];
1046 value0 OPERATION multiplier*element[0];
1047 region[iColumn0]=value0;
1048 }
1049 SCATTER_ATTRIBUTE void functionName(ScatterUpdate6)(int numberIn, CoinFactorizationDouble multiplier,
1050 const CoinFactorizationDouble * COIN_RESTRICT element,
1051 CoinFactorizationDouble * COIN_RESTRICT region)
1052 {
1053 #ifndef NDEBUG
1054 assert (numberIn==6);
1055 #endif
1056 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+6);
1057 int nFull=6&(~(NEW_CHUNK_SIZE-1));
1058 #if AVX2==1
1059 double temp[4];
1060 #endif
1061 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
1062 coin_prefetch_const(element+6);
1063 #if NEW_CHUNK_SIZE==2
1064 int iColumn0=thisColumn[0];
1065 int iColumn1=thisColumn[1];
1066 double value0=region[iColumn0];
1067 double value1=region[iColumn1];
1068 value0 OPERATION multiplier*element[0];
1069 value1 OPERATION multiplier*element[1];
1070 region[iColumn0]=value0;
1071 region[iColumn1]=value1;
1072 #elif NEW_CHUNK_SIZE==4
1073 int iColumn0=thisColumn[0];
1074 int iColumn1=thisColumn[1];
1075 int iColumn2=thisColumn[2];
1076 int iColumn3=thisColumn[3];
1077 #if AVX2==1
1078 __v2df bb;
1079 set_const_v2df(bb,multiplier);
1080 temp[0]=region[iColumn0];
1081 temp[1]=region[iColumn1];
1082 temp[2]=region[iColumn2];
1083 temp[3]=region[iColumn3];
1084 __v2df v0 = __builtin_ia32_loadupd (temp);
1085 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1086 __v2df a = __builtin_ia32_loadupd (element);
1087 a *= bb;
1088 v0 OPERATION a;
1089 a = __builtin_ia32_loadupd (element+2);
1090 a *= bb;
1091 v1 OPERATION a;
1092 __builtin_ia32_storeupd (temp, v0);
1093 __builtin_ia32_storeupd (temp+2, v1);
1094 region[iColumn0]=temp[0];
1095 region[iColumn1]=temp[1];
1096 region[iColumn2]=temp[2];
1097 region[iColumn3]=temp[3];
1098 #else
1099 double value0=region[iColumn0];
1100 double value1=region[iColumn1];
1101 double value2=region[iColumn2];
1102 double value3=region[iColumn3];
1103 value0 OPERATION multiplier*element[0];
1104 value1 OPERATION multiplier*element[1];
1105 value2 OPERATION multiplier*element[2];
1106 value3 OPERATION multiplier*element[3];
1107 region[iColumn0]=value0;
1108 region[iColumn1]=value1;
1109 region[iColumn2]=value2;
1110 region[iColumn3]=value3;
1111 #endif
1112 #else
1113 abort();
1114 #endif
1115 element+=NEW_CHUNK_SIZE;
1116 thisColumn += NEW_CHUNK_SIZE;
1117 }
1118 #if NEW_CHUNK_SIZE==4
1119 int iColumn0=thisColumn[0];
1120 int iColumn1=thisColumn[1];
1121 double value0=region[iColumn0];
1122 double value1=region[iColumn1];
1123 value0 OPERATION multiplier*element[0];
1124 value1 OPERATION multiplier*element[1];
1125 region[iColumn0]=value0;
1126 region[iColumn1]=value1;
1127 #endif
1128 }
1129 SCATTER_ATTRIBUTE void functionName(ScatterUpdate7)(int numberIn, CoinFactorizationDouble multiplier,
1130 const CoinFactorizationDouble * COIN_RESTRICT element,
1131 CoinFactorizationDouble * COIN_RESTRICT region)
1132 {
1133 #ifndef NDEBUG
1134 assert (numberIn==7);
1135 #endif
1136 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+7);
1137 int nFull=7&(~(NEW_CHUNK_SIZE-1));
1138 #if AVX2==1
1139 double temp[4];
1140 #endif
1141 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
1142 coin_prefetch_const(element+6);
1143 #if NEW_CHUNK_SIZE==2
1144 int iColumn0=thisColumn[0];
1145 int iColumn1=thisColumn[1];
1146 double value0=region[iColumn0];
1147 double value1=region[iColumn1];
1148 value0 OPERATION multiplier*element[0];
1149 value1 OPERATION multiplier*element[1];
1150 region[iColumn0]=value0;
1151 region[iColumn1]=value1;
1152 #elif NEW_CHUNK_SIZE==4
1153 int iColumn0=thisColumn[0];
1154 int iColumn1=thisColumn[1];
1155 int iColumn2=thisColumn[2];
1156 int iColumn3=thisColumn[3];
1157 #if AVX2==1
1158 __v2df bb;
1159 set_const_v2df(bb,multiplier);
1160 temp[0]=region[iColumn0];
1161 temp[1]=region[iColumn1];
1162 temp[2]=region[iColumn2];
1163 temp[3]=region[iColumn3];
1164 __v2df v0 = __builtin_ia32_loadupd (temp);
1165 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1166 __v2df a = __builtin_ia32_loadupd (element);
1167 a *= bb;
1168 v0 OPERATION a;
1169 a = __builtin_ia32_loadupd (element+2);
1170 a *= bb;
1171 v1 OPERATION a;
1172 __builtin_ia32_storeupd (temp, v0);
1173 __builtin_ia32_storeupd (temp+2, v1);
1174 region[iColumn0]=temp[0];
1175 region[iColumn1]=temp[1];
1176 region[iColumn2]=temp[2];
1177 region[iColumn3]=temp[3];
1178 #else
1179 double value0=region[iColumn0];
1180 double value1=region[iColumn1];
1181 double value2=region[iColumn2];
1182 double value3=region[iColumn3];
1183 value0 OPERATION multiplier*element[0];
1184 value1 OPERATION multiplier*element[1];
1185 value2 OPERATION multiplier*element[2];
1186 value3 OPERATION multiplier*element[3];
1187 region[iColumn0]=value0;
1188 region[iColumn1]=value1;
1189 region[iColumn2]=value2;
1190 region[iColumn3]=value3;
1191 #endif
1192 #else
1193 abort();
1194 #endif
1195 element+=NEW_CHUNK_SIZE;
1196 thisColumn += NEW_CHUNK_SIZE;
1197 }
1198 #if NEW_CHUNK_SIZE==2
1199 int iColumn0=thisColumn[0];
1200 double value0=region[iColumn0];
1201 value0 OPERATION multiplier*element[0];
1202 region[iColumn0]=value0;
1203 #else
1204 int iColumn0=thisColumn[0];
1205 int iColumn1=thisColumn[1];
1206 int iColumn2=thisColumn[2];
1207 double value0=region[iColumn0];
1208 double value1=region[iColumn1];
1209 double value2=region[iColumn2];
1210 value0 OPERATION multiplier*element[0];
1211 value1 OPERATION multiplier*element[1];
1212 value2 OPERATION multiplier*element[2];
1213 region[iColumn0]=value0;
1214 region[iColumn1]=value1;
1215 region[iColumn2]=value2;
1216 #endif
1217 }
1218 SCATTER_ATTRIBUTE void functionName(ScatterUpdate8)(int numberIn, CoinFactorizationDouble multiplier,
1219 const CoinFactorizationDouble * COIN_RESTRICT element,
1220 CoinFactorizationDouble * COIN_RESTRICT region)
1221 {
1222 #ifndef NDEBUG
1223 assert (numberIn==8);
1224 #endif
1225 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+8);
1226 int nFull=8&(~(NEW_CHUNK_SIZE-1));
1227 #if AVX2==1
1228 double temp[4];
1229 #endif
1230 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
1231 coin_prefetch_const(element+6);
1232 #if NEW_CHUNK_SIZE==2
1233 int iColumn0=thisColumn[0];
1234 int iColumn1=thisColumn[1];
1235 double value0=region[iColumn0];
1236 double value1=region[iColumn1];
1237 value0 OPERATION multiplier*element[0];
1238 value1 OPERATION multiplier*element[1];
1239 region[iColumn0]=value0;
1240 region[iColumn1]=value1;
1241 #elif NEW_CHUNK_SIZE==4
1242 int iColumn0=thisColumn[0];
1243 int iColumn1=thisColumn[1];
1244 int iColumn2=thisColumn[2];
1245 int iColumn3=thisColumn[3];
1246 #if AVX2==1
1247 __v2df bb;
1248 set_const_v2df(bb,multiplier);
1249 temp[0]=region[iColumn0];
1250 temp[1]=region[iColumn1];
1251 temp[2]=region[iColumn2];
1252 temp[3]=region[iColumn3];
1253 __v2df v0 = __builtin_ia32_loadupd (temp);
1254 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1255 __v2df a = __builtin_ia32_loadupd (element);
1256 a *= bb;
1257 v0 OPERATION a;
1258 a = __builtin_ia32_loadupd (element+2);
1259 a *= bb;
1260 v1 OPERATION a;
1261 __builtin_ia32_storeupd (temp, v0);
1262 __builtin_ia32_storeupd (temp+2, v1);
1263 region[iColumn0]=temp[0];
1264 region[iColumn1]=temp[1];
1265 region[iColumn2]=temp[2];
1266 region[iColumn3]=temp[3];
1267 #else
1268 double value0=region[iColumn0];
1269 double value1=region[iColumn1];
1270 double value2=region[iColumn2];
1271 double value3=region[iColumn3];
1272 value0 OPERATION multiplier*element[0];
1273 value1 OPERATION multiplier*element[1];
1274 value2 OPERATION multiplier*element[2];
1275 value3 OPERATION multiplier*element[3];
1276 region[iColumn0]=value0;
1277 region[iColumn1]=value1;
1278 region[iColumn2]=value2;
1279 region[iColumn3]=value3;
1280 #endif
1281 #else
1282 abort();
1283 #endif
1284 element+=NEW_CHUNK_SIZE;
1285 thisColumn += NEW_CHUNK_SIZE;
1286 }
1287 }
1288 SCATTER_ATTRIBUTE void functionName(ScatterUpdate4N)(int numberIn, CoinFactorizationDouble multiplier,
1289 const CoinFactorizationDouble * COIN_RESTRICT element,
1290 CoinFactorizationDouble * COIN_RESTRICT region)
1291 {
1292 assert ((numberIn&3)==0);
1293 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+numberIn);
1294 int nFull=numberIn&(~(NEW_CHUNK_SIZE-1));
1295 #if AVX2==1
1296 double temp[4];
1297 #endif
1298 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
1299 coin_prefetch_const(element+16);
1300 coin_prefetch_const(thisColumn+32);
1301 #if NEW_CHUNK_SIZE==2
1302 int iColumn0=thisColumn[0];
1303 int iColumn1=thisColumn[1];
1304 double value0=region[iColumn0];
1305 double value1=region[iColumn1];
1306 value0 OPERATION multiplier*element[0];
1307 value1 OPERATION multiplier*element[1];
1308 region[iColumn0]=value0;
1309 region[iColumn1]=value1;
1310 #elif NEW_CHUNK_SIZE==4
1311 int iColumn0=thisColumn[0];
1312 int iColumn1=thisColumn[1];
1313 int iColumn2=thisColumn[2];
1314 int iColumn3=thisColumn[3];
1315 #if AVX2==1
1316 __v2df bb;
1317 set_const_v2df(bb,multiplier);
1318 temp[0]=region[iColumn0];
1319 temp[1]=region[iColumn1];
1320 temp[2]=region[iColumn2];
1321 temp[3]=region[iColumn3];
1322 __v2df v0 = __builtin_ia32_loadupd (temp);
1323 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1324 __v2df a = __builtin_ia32_loadupd (element);
1325 a *= bb;
1326 v0 OPERATION a;
1327 a = __builtin_ia32_loadupd (element+2);
1328 a *= bb;
1329 v1 OPERATION a;
1330 __builtin_ia32_storeupd (temp, v0);
1331 __builtin_ia32_storeupd (temp+2, v1);
1332 region[iColumn0]=temp[0];
1333 region[iColumn1]=temp[1];
1334 region[iColumn2]=temp[2];
1335 region[iColumn3]=temp[3];
1336 #else
1337 double value0=region[iColumn0];
1338 double value1=region[iColumn1];
1339 double value2=region[iColumn2];
1340 double value3=region[iColumn3];
1341 value0 OPERATION multiplier*element[0];
1342 value1 OPERATION multiplier*element[1];
1343 value2 OPERATION multiplier*element[2];
1344 value3 OPERATION multiplier*element[3];
1345 region[iColumn0]=value0;
1346 region[iColumn1]=value1;
1347 region[iColumn2]=value2;
1348 region[iColumn3]=value3;
1349 #endif
1350 #else
1351 abort();
1352 #endif
1353 element+=NEW_CHUNK_SIZE;
1354 thisColumn += NEW_CHUNK_SIZE;
1355 }
1356 }
1357 SCATTER_ATTRIBUTE void functionName(ScatterUpdate4NPlus1)(int numberIn, CoinFactorizationDouble multiplier,
1358 const CoinFactorizationDouble * COIN_RESTRICT element,
1359 CoinFactorizationDouble * COIN_RESTRICT region)
1360 {
1361 assert ((numberIn&3)==1);
1362 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+numberIn);
1363 int nFull=numberIn&(~(NEW_CHUNK_SIZE-1));
1364 #if AVX2==1
1365 double temp[4];
1366 #endif
1367 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
1368 coin_prefetch_const(element+16);
1369 coin_prefetch_const(thisColumn+32);
1370 #if NEW_CHUNK_SIZE==2
1371 int iColumn0=thisColumn[0];
1372 int iColumn1=thisColumn[1];
1373 double value0=region[iColumn0];
1374 double value1=region[iColumn1];
1375 value0 OPERATION multiplier*element[0];
1376 value1 OPERATION multiplier*element[1];
1377 region[iColumn0]=value0;
1378 region[iColumn1]=value1;
1379 #elif NEW_CHUNK_SIZE==4
1380 int iColumn0=thisColumn[0];
1381 int iColumn1=thisColumn[1];
1382 int iColumn2=thisColumn[2];
1383 int iColumn3=thisColumn[3];
1384 #if AVX2==1
1385 __v2df bb;
1386 set_const_v2df(bb,multiplier);
1387 temp[0]=region[iColumn0];
1388 temp[1]=region[iColumn1];
1389 temp[2]=region[iColumn2];
1390 temp[3]=region[iColumn3];
1391 __v2df v0 = __builtin_ia32_loadupd (temp);
1392 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1393 __v2df a = __builtin_ia32_loadupd (element);
1394 a *= bb;
1395 v0 OPERATION a;
1396 a = __builtin_ia32_loadupd (element+2);
1397 a *= bb;
1398 v1 OPERATION a;
1399 __builtin_ia32_storeupd (temp, v0);
1400 __builtin_ia32_storeupd (temp+2, v1);
1401 region[iColumn0]=temp[0];
1402 region[iColumn1]=temp[1];
1403 region[iColumn2]=temp[2];
1404 region[iColumn3]=temp[3];
1405 #else
1406 double value0=region[iColumn0];
1407 double value1=region[iColumn1];
1408 double value2=region[iColumn2];
1409 double value3=region[iColumn3];
1410 value0 OPERATION multiplier*element[0];
1411 value1 OPERATION multiplier*element[1];
1412 value2 OPERATION multiplier*element[2];
1413 value3 OPERATION multiplier*element[3];
1414 region[iColumn0]=value0;
1415 region[iColumn1]=value1;
1416 region[iColumn2]=value2;
1417 region[iColumn3]=value3;
1418 #endif
1419 #else
1420 abort();
1421 #endif
1422 element+=NEW_CHUNK_SIZE;
1423 thisColumn += NEW_CHUNK_SIZE;
1424 }
1425 int iColumn0=thisColumn[0];
1426 double value0=region[iColumn0];
1427 value0 OPERATION multiplier*element[0];
1428 region[iColumn0]=value0;
1429 }
1430 SCATTER_ATTRIBUTE void functionName(ScatterUpdate4NPlus2)(int numberIn, CoinFactorizationDouble multiplier,
1431 const CoinFactorizationDouble * COIN_RESTRICT element,
1432 CoinFactorizationDouble * COIN_RESTRICT region)
1433 {
1434 assert ((numberIn&3)==2);
1435 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+numberIn);
1436 int nFull=numberIn&(~(NEW_CHUNK_SIZE-1));
1437 #if AVX2==1
1438 double temp[4];
1439 #endif
1440 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
1441 coin_prefetch_const(element+16);
1442 coin_prefetch_const(thisColumn+32);
1443 #if NEW_CHUNK_SIZE==2
1444 int iColumn0=thisColumn[0];
1445 int iColumn1=thisColumn[1];
1446 double value0=region[iColumn0];
1447 double value1=region[iColumn1];
1448 value0 OPERATION multiplier*element[0];
1449 value1 OPERATION multiplier*element[1];
1450 region[iColumn0]=value0;
1451 region[iColumn1]=value1;
1452 #elif NEW_CHUNK_SIZE==4
1453 int iColumn0=thisColumn[0];
1454 int iColumn1=thisColumn[1];
1455 int iColumn2=thisColumn[2];
1456 int iColumn3=thisColumn[3];
1457 #if AVX2==1
1458 __v2df bb;
1459 set_const_v2df(bb,multiplier);
1460 temp[0]=region[iColumn0];
1461 temp[1]=region[iColumn1];
1462 temp[2]=region[iColumn2];
1463 temp[3]=region[iColumn3];
1464 __v2df v0 = __builtin_ia32_loadupd (temp);
1465 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1466 __v2df a = __builtin_ia32_loadupd (element);
1467 a *= bb;
1468 v0 OPERATION a;
1469 a = __builtin_ia32_loadupd (element+2);
1470 a *= bb;
1471 v1 OPERATION a;
1472 __builtin_ia32_storeupd (temp, v0);
1473 __builtin_ia32_storeupd (temp+2, v1);
1474 region[iColumn0]=temp[0];
1475 region[iColumn1]=temp[1];
1476 region[iColumn2]=temp[2];
1477 region[iColumn3]=temp[3];
1478 #else
1479 double value0=region[iColumn0];
1480 double value1=region[iColumn1];
1481 double value2=region[iColumn2];
1482 double value3=region[iColumn3];
1483 value0 OPERATION multiplier*element[0];
1484 value1 OPERATION multiplier*element[1];
1485 value2 OPERATION multiplier*element[2];
1486 value3 OPERATION multiplier*element[3];
1487 region[iColumn0]=value0;
1488 region[iColumn1]=value1;
1489 region[iColumn2]=value2;
1490 region[iColumn3]=value3;
1491 #endif
1492 #else
1493 abort();
1494 #endif
1495 element+=NEW_CHUNK_SIZE;
1496 thisColumn += NEW_CHUNK_SIZE;
1497 }
1498 #if NEW_CHUNK_SIZE==4
1499 int iColumn0=thisColumn[0];
1500 int iColumn1=thisColumn[1];
1501 double value0=region[iColumn0];
1502 double value1=region[iColumn1];
1503 value0 OPERATION multiplier*element[0];
1504 value1 OPERATION multiplier*element[1];
1505 region[iColumn0]=value0;
1506 region[iColumn1]=value1;
1507 #endif
1508 }
1509 SCATTER_ATTRIBUTE void functionName(ScatterUpdate4NPlus3)(int numberIn, CoinFactorizationDouble multiplier,
1510 const CoinFactorizationDouble * COIN_RESTRICT element,
1511 CoinFactorizationDouble * COIN_RESTRICT region)
1512 {
1513 assert ((numberIn&3)==3);
1514 const int * COIN_RESTRICT thisColumn = reinterpret_cast<const int *>(element+numberIn);
1515 int nFull=numberIn&(~(NEW_CHUNK_SIZE-1));
1516 #if AVX2==1
1517 double temp[4];
1518 #endif
1519 for (int j=0;j<nFull;j+=NEW_CHUNK_SIZE) {
1520 coin_prefetch_const(element+16);
1521 coin_prefetch_const(thisColumn+32);
1522 #if NEW_CHUNK_SIZE==2
1523 int iColumn0=thisColumn[0];
1524 int iColumn1=thisColumn[1];
1525 double value0=region[iColumn0];
1526 double value1=region[iColumn1];
1527 value0 OPERATION multiplier*element[0];
1528 value1 OPERATION multiplier*element[1];
1529 region[iColumn0]=value0;
1530 region[iColumn1]=value1;
1531 #elif NEW_CHUNK_SIZE==4
1532 int iColumn0=thisColumn[0];
1533 int iColumn1=thisColumn[1];
1534 int iColumn2=thisColumn[2];
1535 int iColumn3=thisColumn[3];
1536 #if AVX2==1
1537 __v2df bb;
1538 set_const_v2df(bb,multiplier);
1539 temp[0]=region[iColumn0];
1540 temp[1]=region[iColumn1];
1541 temp[2]=region[iColumn2];
1542 temp[3]=region[iColumn3];
1543 __v2df v0 = __builtin_ia32_loadupd (temp);
1544 __v2df v1 = __builtin_ia32_loadupd (temp+2);
1545 __v2df a = __builtin_ia32_loadupd (element);
1546 a *= bb;
1547 v0 OPERATION a;
1548 a = __builtin_ia32_loadupd (element+2);
1549 a *= bb;
1550 v1 OPERATION a;
1551 __builtin_ia32_storeupd (temp, v0);
1552 __builtin_ia32_storeupd (temp+2, v1);
1553 region[iColumn0]=temp[0];
1554 region[iColumn1]=temp[1];
1555 region[iColumn2]=temp[2];
1556 region[iColumn3]=temp[3];
1557 #else
1558 double value0=region[iColumn0];
1559 double value1=region[iColumn1];
1560 double value2=region[iColumn2];
1561 double value3=region[iColumn3];
1562 value0 OPERATION multiplier*element[0];
1563 value1 OPERATION multiplier*element[1];
1564 value2 OPERATION multiplier*element[2];
1565 value3 OPERATION multiplier*element[3];
1566 region[iColumn0]=value0;
1567 region[iColumn1]=value1;
1568 region[iColumn2]=value2;
1569 region[iColumn3]=value3;
1570 #endif
1571 #else
1572 abort();
1573 #endif
1574 element+=NEW_CHUNK_SIZE;
1575 thisColumn += NEW_CHUNK_SIZE;
1576 }
1577 #if NEW_CHUNK_SIZE==2
1578 int iColumn0=thisColumn[0];
1579 double value0=region[iColumn0];
1580 value0 OPERATION multiplier*element[0];
1581 region[iColumn0]=value0;
1582 #else
1583 int iColumn0=thisColumn[0];
1584 int iColumn1=thisColumn[1];
1585 int iColumn2=thisColumn[2];
1586 double value0=region[iColumn0];
1587 double value1=region[iColumn1];
1588 double value2=region[iColumn2];
1589 value0 OPERATION multiplier*element[0];
1590 value1 OPERATION multiplier*element[1];
1591 value2 OPERATION multiplier*element[2];
1592 region[iColumn0]=value0;
1593 region[iColumn1]=value1;
1594 region[iColumn2]=value2;
1595 #endif
1596 }
1597 #endif
CoinAbcScatterUpdate7Subtract
void CoinAbcScatterUpdate7Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate4N
void CoinAbcScatterUpdate4N(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcMaximumAbsElementAndScale
double CoinAbcMaximumAbsElementAndScale(double *region, double multiplier, int size)
maximum fabs(region[i]) and then region[i]*=multiplier
CoinAbcGatherUpdate
CoinFactorizationDouble ABC_INLINE CoinAbcGatherUpdate(CoinSimplexInt number, const CoinFactorizationDouble *COIN_RESTRICT thisElement, const int *COIN_RESTRICT thisIndex, CoinFactorizationDouble *COIN_RESTRICT region)
Definition: CoinAbcHelperFunctions.hpp:714
CoinAbcScatterUpdate8Subtract
void CoinAbcScatterUpdate8Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
NEW_CHUNK_SIZE_OFFSET
#define NEW_CHUNK_SIZE_OFFSET
Definition: CoinAbcHelperFunctions.hpp:528
CoinAbcScatterUpdate6Subtract
void CoinAbcScatterUpdate6Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcCommon.hpp
scatterStruct::number
int number
Definition: CoinAbcHelperFunctions.hpp:537
CoinAbcScatterUpdate4NPlus3
void CoinAbcScatterUpdate4NPlus3(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate4NAdd
void CoinAbcScatterUpdate4NAdd(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
void
typedef void(COINLINKAGE_CB *clp_callback)(Clp_Simplex *model
typedef for user call back.
CoinAbcGetNorms
void CoinAbcGetNorms(const double *region, int size, double &norm1, double &norm2)
CoinAbcScatterUpdate0
void CoinAbcScatterUpdate0(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcInnerProduct
double CoinAbcInnerProduct(const double *region1, int size, const double *region2)
CoinAbcScatterUpdate8
void CoinAbcScatterUpdate8(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate1Subtract
void CoinAbcScatterUpdate1Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate4NPlus1Subtract
void CoinAbcScatterUpdate4NPlus1Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcMemmoveAndZero
void CoinAbcMemmoveAndZero(double *array, double *arrayFrom, int size)
This moves down and zeroes out end.
CoinAbcScatterTo
void CoinAbcScatterTo(const double *regionFrom, double *regionTo, const int *index, int number)
regionTo[index[i]]=regionFrom[i]
CoinAbcScatterUpdate5Add
void CoinAbcScatterUpdate5Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate4NPlus1
void CoinAbcScatterUpdate4NPlus1(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
cilk_for
#define cilk_for
Definition: CoinAbcCommon.hpp:54
CoinAbcScatterUpdate2Subtract
void CoinAbcScatterUpdate2Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcReciprocal
void CoinAbcReciprocal(double *array, int n, const double *input)
CoinAbcScatterUpdate4NPlus3Subtract
void CoinAbcScatterUpdate4NPlus3Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
scatterStruct::functionPointer
scatterUpdate functionPointer
Definition: CoinAbcHelperFunctions.hpp:535
CoinAbcScatterUpdate4NPlus2Add
void CoinAbcScatterUpdate4NPlus2Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate3Subtract
void CoinAbcScatterUpdate3Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
ClpConfig.h
COIN_RESTRICT
#define COIN_RESTRICT
Definition: ClpMatrixBase.hpp:21
CoinAbcScatterUpdate3
void CoinAbcScatterUpdate3(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
scatterUpdate
void(* scatterUpdate)(int, CoinFactorizationDouble, const CoinFactorizationDouble *, double *) SCATTER_ATTRIBUTE
Definition: CoinAbcHelperFunctions.hpp:533
CoinAbcScatterUpdate2
void CoinAbcScatterUpdate2(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcMemset0Long
void CoinAbcMemset0Long(double *array, int size)
CoinAbcCompact
int CoinAbcCompact(int numberSections, int alreadyDone, double *array, const int *starts, const int *lengths)
This compacts several sections and zeroes out end (returns number)
CoinAbcScale
void CoinAbcScale(double *region, double multiplier, int size)
CoinAbcGatherFrom
void CoinAbcGatherFrom(const double *regionFrom, double *regionTo, const int *index, int number)
regionTo[i]=regionFrom[index[i]]
CoinAbcScaleNormalValues
void CoinAbcScaleNormalValues(double *region, double multiplier, double killIfLessThanThis, int size)
CoinAbcScatterUpdate7Add
void CoinAbcScatterUpdate7Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinFactorizationDouble
double CoinFactorizationDouble
Definition: CoinTypes.hpp:57
CoinAbcScatterZeroTo
void CoinAbcScatterZeroTo(double *regionTo, const int *index, int number)
regionTo[index[i]]=0.0
CoinAbcScatterUpdate4NPlus3Add
void CoinAbcScatterUpdate4NPlus3Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
NEW_CHUNK_SIZE
#define NEW_CHUNK_SIZE
Definition: CoinAbcHelperFunctions.hpp:526
coin_prefetch
#define coin_prefetch(mem)
Definition: CoinAbcHelperFunctions.hpp:523
CoinAbcScatterUpdate4NPlus2Subtract
void CoinAbcScatterUpdate4NPlus2Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
coin_prefetch_const
#define coin_prefetch_const(mem)
Definition: CoinAbcHelperFunctions.hpp:524
CoinAbcScatterUpdate4NSubtract
void CoinAbcScatterUpdate4NSubtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcMaximumAbsElement
double CoinAbcMaximumAbsElement(const double *region, int size)
CoinAbcScatterUpdate1
void CoinAbcScatterUpdate1(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate2Add
void CoinAbcScatterUpdate2Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcMultiplyIndexed
void CoinAbcMultiplyIndexed(int number, const double *COIN_RESTRICT multiplier, const int *COIN_RESTRICT thisIndex, CoinFactorizationDouble *COIN_RESTRICT region)
CoinAbcScatterUpdate8Add
void CoinAbcScatterUpdate8Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate4NPlus1Add
void CoinAbcScatterUpdate4NPlus1Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcMemcpyLong
void CoinAbcMemcpyLong(double *array, const double *arrayFrom, int size)
SCATTER_ATTRIBUTE
#define SCATTER_ATTRIBUTE
Definition: CoinAbcHelperFunctions.hpp:532
CoinAbcMemmove
void CoinAbcMemmove(double *array, const double *arrayFrom, int size)
CoinAbcScatterToList
void CoinAbcScatterToList(const double *regionFrom, double *regionTo, const int *indexList, const int *indexScatter, int number)
regionTo[indexScatter[indexList[i]]]=regionFrom[indexList[i]]
CoinAbcSetElements
void CoinAbcSetElements(double *region, int size, double value)
CoinAbcScatterUpdate1Add
void CoinAbcScatterUpdate1Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinBigIndex
int CoinBigIndex
Definition: Coin_C_defines.h:105
NEW_CHUNK_SIZE_INCREMENT
#define NEW_CHUNK_SIZE_INCREMENT
Definition: CoinAbcHelperFunctions.hpp:527
CoinAbcMinMaxAbsNormalValues
void CoinAbcMinMaxAbsNormalValues(const double *region, int size, double &minimum, double &maximum)
CoinAbcScatterUpdate
void ABC_INLINE CoinAbcScatterUpdate(int number, CoinFactorizationDouble pivotValue, const CoinFactorizationDouble *COIN_RESTRICT thisElement, const int *COIN_RESTRICT thisIndex, CoinFactorizationDouble *COIN_RESTRICT region)
Definition: CoinAbcHelperFunctions.hpp:51
scatterStruct
Definition: CoinAbcHelperFunctions.hpp:534
CoinAbcScatterUpdate4NPlus2
void CoinAbcScatterUpdate4NPlus2(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate6Add
void CoinAbcScatterUpdate6Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcMinMaxAbsElement
void CoinAbcMinMaxAbsElement(const double *region, int size, double &minimum, double &maximum)
ABC_INLINE
#define ABC_INLINE
Definition: CoinAbcCommon.hpp:30
CoinAbcScatterUpdate6
void CoinAbcScatterUpdate6(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinSimplexInt
int CoinSimplexInt
Definition: CoinAbcCommon.hpp:22
scatterStruct::offset
CoinBigIndex offset
Definition: CoinAbcHelperFunctions.hpp:536
CoinAbcMultiplyAdd
void CoinAbcMultiplyAdd(const double *region1, int size, double multiplier1, double *regionChanged, double multiplier2)
CoinAbcScatterUpdate3Add
void CoinAbcScatterUpdate3Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate4Subtract
void CoinAbcScatterUpdate4Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate4Add
void CoinAbcScatterUpdate4Add(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate5
void CoinAbcScatterUpdate5(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcInverseSqrts
void CoinAbcInverseSqrts(double *array, int n)
array[i]=1.0/sqrt(array[i])
CoinAbcScatterUpdate4
void CoinAbcScatterUpdate4(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate7
void CoinAbcScatterUpdate7(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE
CoinAbcScatterUpdate5Subtract
void CoinAbcScatterUpdate5Subtract(int numberIn, CoinFactorizationDouble multiplier, const CoinFactorizationDouble *COIN_RESTRICT thisElement, CoinFactorizationDouble *COIN_RESTRICT region) SCATTER_ATTRIBUTE