1 /*
2
3 Copyright (C) 2008-2021 Michele Martone
4
5 This file is part of librsb.
6
7 librsb is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published
9 by the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 librsb is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
15 License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with librsb; see the file COPYING.
19 If not, see <http://www.gnu.org/licenses/>.
20
21 */
22 /* @cond INNERDOC */
23 /*!
24 @file
25 @author Michele Martone
26 @brief
27 This is the main program used to benchmark and test our library.
28 This should be the swiss army knife program for our library.
29 */
30 /*
31 This not an example program: to be built, it needs all of the internal library headers.
32 */
33
34 #include <stdlib.h>
35 #include "rsb.h"
36 #include "rsb_test_matops.h"
37 #include "rsb_failure_tests.h"
38 #include "rsb_internals.h"
39 #if RSB_WITH_SPARSE_BLAS_INTERFACE
40 #include "rsb_libspblas_handle.h"
41 #endif /* RSB_WITH_SPARSE_BLAS_INTERFACE */
42 #include "rsb_libspblas_tests.h"
43 //#include "rsb-config.h"
44 #if RSB_WANT_ACTION
45 #include <signal.h>
46 #if defined(RSB_WANT_ACTION_SIGNAL)
47 #else /* defined(RSB_WANT_ACTION_SIGNAL) */
48 #include <bits/sigaction.h>
49 #endif /* defined(RSB_WANT_ACTION_SIGNAL) */
50 #endif /* RSB_WANT_ACTION */
51
52 #define RSB_WANT_PERMISSIVE_RSBENCH 1
53 #define RSB_SHALL_UPDATE_COMPLETEBENCHS 1
54 #define RSB_WANT_REDUCED_RSB_M4_MATRIX_META_OPS 1
55
56
57 #if RSB_WITH_LIKWID
58 #define RSB_RSBENCH_EXEC(FEXP) {rsb_err_t errval;RSB_LIKWID_MARKER_INIT;errval=RSB_ERR_TO_PROGRAM_ERROR(FEXP);RSB_LIKWID_MARKER_EXIT;return errval;}
59 #else /* RSB_WITH_LIKWID */
60 #define RSB_RSBENCH_EXEC(FEXP) {return RSB_ERR_TO_PROGRAM_ERROR(FEXP);}
61 #endif /* RSB_WITH_LIKWID */
62
63 #if RSB_WANT_ACTION
64 int rsb__quit_rsbench;
65 #if defined(RSB_WANT_ACTION_SIGNAL)
66 #else /* defined(RSB_WANT_ACTION_SIGNAL) */
67 struct sigaction rsb_osa;
68 #endif /* defined(RSB_WANT_ACTION_SIGNAL) */
69
rsb__chk_srt(void)70 static rsb_err_t rsb__chk_srt(void)
71 {
72 rsb_err_t errval = RSB_ERR_INTERNAL_ERROR;
73
74 RSBENCH_STDOUT("SORT CHECK: BEGIN\n");
75
76 {
77 const rsb_flags_t flags = RSB_FLAG_NOFLAGS;
78 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
79 const rsb_nnz_idx_t nnz = 2;
80 const rsb_coo_idx_t nr = 1000000;
81 const rsb_coo_idx_t nc = 1000000;
82 rsb_coo_idx_t IA[] = { 463325, 417887};
83 rsb_coo_idx_t JA[] = { 463231, 417880};
84 RSB_DEFAULT_TYPE VA[] = {1,1};
85
86 errval = rsb_coo_sort(VA, IA, JA, nnz, nr, nc, typecode, flags);
87
88 if(RSB_SOME_ERROR(errval))
89 RSB_PERR_GOTO(err,RSB_ERRM_ES);
90
91 if( IA[0] != 417887)
92 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
93 if( JA[0] != 417880)
94 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
95 }
96
97 #define RSB_EXPECT_2P_SORT_BUG 0
98 {
99 // trigger double pass
100 const struct rsb_mtx_partitioning_info_t * pinfop = NULL;
101 const rsb_flags_t flags = RSB_FLAG_NOFLAGS;
102 const enum rsb_op_flags_t op_flags = RSB_OP_FLAG_DEFAULT;
103 const int bs = RSB_DEFAULT_BLOCKING;
104 const size_t wb = 0;
105 const int br = bs, bc = bs;
106 void * WA = NULL;
107 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
108 const rsb_nnz_idx_t nnz = 2;
109 const rsb_coo_idx_t nr = 1000000;
110 const rsb_coo_idx_t nc = 1000000;
111 rsb_coo_idx_t IA[] = { 463325, 417887};
112 rsb_coo_idx_t JA[] = { 463231, 417880};
113 rsb_coo_idx_t rIA[] = { 463325, 417887};
114 rsb_coo_idx_t rJA[] = { 463231, 417880};
115 RSB_DEFAULT_TYPE VA[] = {1,1};
116 RSB_DEFAULT_TYPE rVA[] = {1,1};
117
118 errval = rsb__do_index_based_bcsr_sort( IA, JA, VA, rIA, rJA, rVA, nr, nc, br, bc, nnz, typecode, flags, op_flags, WA, wb);
119
120 if(RSB_SOME_ERROR(errval))
121 RSB_PERR_GOTO(err,RSB_ERRM_ES);
122
123 #if RSB_EXPECT_2P_SORT_BUG
124 if( rIA[0] == 417887)
125 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
126 if( rJA[0] == 417880)
127 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
128 #else
129 if( rIA[0] != 417887)
130 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
131 if( rJA[0] != 417880)
132 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
133 #endif
134 }
135
136 #define RSB_EXPECT_IP2P_SORT_BUG 0
137 {
138 // trigger double pass
139 const struct rsb_mtx_partitioning_info_t * pinfop = NULL;
140 const rsb_flags_t flags = RSB_FLAG_EXPERIMENTAL_IN_PLACE_PERMUTATION_SORT;
141 const enum rsb_op_flags_t op_flags = RSB_OP_FLAG_DEFAULT;
142 const int bs = RSB_DEFAULT_BLOCKING;
143 const size_t wb = 0;
144 const int br = bs, bc = bs;
145 void * WA = NULL;
146 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
147 const rsb_nnz_idx_t nnz = 7;
148 const rsb_coo_idx_t nr = 2*RSB_MAX_VALUE_FOR_TYPE(rsb_half_idx_t);
149 const rsb_coo_idx_t nc = 2*RSB_MAX_VALUE_FOR_TYPE(rsb_half_idx_t);
150 rsb_coo_idx_t IA[] = {0,1,2,3,4,5,1};
151 rsb_coo_idx_t JA[] = {0,1,2,3,4,5,0};
152 RSB_DEFAULT_TYPE VA[] = {1,1,1,1,1,1,2};
153 RSB_DEFAULT_TYPE rVA[nnz];
154 rsb_coo_idx_t rIA[nnz];
155 rsb_coo_idx_t rJA[nnz];
156
157 errval = rsb__do_index_based_bcsr_sort( IA, JA, VA, rIA, rJA, rVA, nr, nc, br, bc, nnz, typecode, flags, op_flags, WA, wb);
158 #if RSB_EXPECT_IP2P_SORT_BUG
159 if( rIA[1] != 1 )
160 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
161 if( rJA[1] != 1 )
162 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
163 if( rVA[1] != 1 )
164 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
165 #else
166 if( rIA[1] != 1 )
167 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
168 if( rJA[1] != 0 )
169 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
170 if( rVA[1] != 2 )
171 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
172 #endif
173 }
174
175 {
176 // do not trigger double pass
177 const struct rsb_mtx_partitioning_info_t * pinfop = NULL;
178 const rsb_flags_t flags = RSB_FLAG_EXPERIMENTAL_IN_PLACE_PERMUTATION_SORT;
179 const enum rsb_op_flags_t op_flags = RSB_OP_FLAG_DEFAULT;
180 const int bs = RSB_DEFAULT_BLOCKING;
181 const size_t wb = 0;
182 const int br = bs, bc = bs;
183 void * WA = NULL;
184 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
185 const rsb_nnz_idx_t nnz = 7;
186 const rsb_coo_idx_t nr = 6;
187 const rsb_coo_idx_t nc = 6;
188 rsb_coo_idx_t IA[] = {0,1,2,3,4,5,1};
189 rsb_coo_idx_t JA[] = {0,1,2,3,4,5,0};
190 RSB_DEFAULT_TYPE VA[] = {1,1,1,1,1,1,2};
191 RSB_DEFAULT_TYPE rVA[nnz];
192 rsb_coo_idx_t rIA[nnz];
193 rsb_coo_idx_t rJA[nnz];
194
195 errval = rsb__do_index_based_bcsr_sort( IA, JA, VA, rIA, rJA, rVA, nr, nc, br, bc, nnz, typecode, flags, op_flags, WA, wb);
196
197 if(RSB_SOME_ERROR(errval))
198 RSB_PERR_GOTO(err,RSB_ERRM_ES);
199
200 if( rIA[1] != 1 )
201 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
202 if( rJA[1] != 0 )
203 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
204 if( rVA[1] != 2 )
205 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
206 }
207
208 RSBENCH_STDOUT("SORT CHECK: END\n");
209 //errval = RSB_ERR_NO_ERROR;
210 goto err;
211 merr:
212 errval = RSB_ERR_INTERNAL_ERROR;
213 err:
214 if(RSB_SOME_ERROR(errval))
215 RSBENCH_STDOUT("SORT CHECK: FAIL\n");
216 return errval;
217 }
218
rsb__chk_trtr(void)219 static rsb_err_t rsb__chk_trtr(void)
220 {
221 rsb_err_t errval = RSB_ERR_INTERNAL_ERROR;
222 struct rsb_mtx_t *mtxAp = NULL; /* matrix structure pointer */
223
224 RSBENCH_STDOUT("REGRESSION TEST: BEGIN\n");
225
226 #define RSB_EXPECT_TRTR_BUG_COO 0
227
228 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
229 {
230 const int bs = RSB_DEFAULT_BLOCKING;
231 const int brA = bs, bcA = bs;
232 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE;
233 const rsb_nnz_idx_t nnzA = 3;
234 const rsb_coo_idx_t incX = 1, incY = 1;
235 const rsb_coo_idx_t nrA = 3;
236 const rsb_coo_idx_t ncA = 1;
237 const rsb_coo_idx_t IA[] = {0,1,2};
238 const rsb_coo_idx_t JA[] = {0,0,0};
239 const double VA[] = {1,1,1};
240 const double X[] = {1,1,1};
241 double Y[] = {1,1,1};
242 const double alpha = 1.0;
243 const double beta = 0.0;
244 const rsb_trans_t transA = RSB_TRANSPOSITION_C;
245
246 mtxAp = rsb_mtx_alloc_from_coo_const(
247 VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
248 RSB_FLAG_DEFAULT_COO_MATRIX_FLAGS|RSB_FLAG_USE_HALFWORD_INDICES
249 , &errval);
250
251 if((!mtxAp) || RSB_SOME_ERROR(errval))
252 RSB_PERR_GOTO(err,RSB_ERRM_ES);
253
254 if( Y[0] != 1 || Y[1] != 1 )
255 RSB_PERR_GOTO(err,RSB_ERRM_ES);
256 errval = rsb_spmv(transA, &alpha, mtxAp, X, incX, &beta, Y, incY);
257 if(RSB_SOME_ERROR(errval))
258 RSB_PERR_GOTO(err,RSB_ERRM_ES);
259 #if RSB_EXPECT_TRTR_BUG_COO
260 if( Y[0] != 3 || Y[2] != 0 )
261 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
262 // bug: Y[0:2] have been zeroed, instead of Y[0:1]
263 #else
264 if( Y[0] != 3 || Y[2] != 1 )
265 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
266 // ok : only Y[0:1] should have been zeroed
267 #endif
268
269 RSB_MTX_FREE(mtxAp);
270 }
271 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
272
273 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
274 {
275 const int bs = RSB_DEFAULT_BLOCKING;
276 const int brA = bs, bcA = bs;
277 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE;
278 const rsb_nnz_idx_t nnzA = 3;
279 const rsb_coo_idx_t incX = 1, incY = 1;
280 const rsb_coo_idx_t nrA = 1;
281 const rsb_coo_idx_t ncA = 3;
282 const rsb_coo_idx_t IA[] = {0,0,0};
283 const rsb_coo_idx_t JA[] = {0,1,2};
284 const double VA[] = {1,1,1};
285 const double X[] = {1,1,1};
286 double Y[] = {1,1,1};
287 const double alpha = 1.0;
288 const double beta = 0.0;
289 const rsb_trans_t transA = RSB_TRANSPOSITION_C;
290
291 mtxAp = rsb_mtx_alloc_from_coo_const(
292 VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
293 RSB_FLAG_DEFAULT_COO_MATRIX_FLAGS|RSB_FLAG_USE_HALFWORD_INDICES
294 , &errval);
295
296 if((!mtxAp) || RSB_SOME_ERROR(errval))
297 RSB_PERR_GOTO(err,RSB_ERRM_ES);
298
299 if( Y[0] != 1 || Y[1] != 1 )
300 RSB_PERR_GOTO(err,RSB_ERRM_ES);
301 errval = rsb_spmv(transA, &alpha, mtxAp, X, incX, &beta, Y, incY);
302 if(RSB_SOME_ERROR(errval))
303 RSB_PERR_GOTO(err,RSB_ERRM_ES);
304 #if RSB_EXPECT_TRTR_BUG_COO
305 if( Y[0] != 1 || Y[1] != 2 ) // bug: Y[1] should have been zeroed before add
306 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
307 #else
308 if( Y[0] != 1 || Y[1] != 1 ) // ok : Y[1] should have been zeroed before add
309 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
310 #endif
311
312 RSB_MTX_FREE(mtxAp);
313 }
314 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
315
316 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
317 {
318 const int bs = RSB_DEFAULT_BLOCKING;
319 const int brA = bs, bcA = bs;
320 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE;
321 const rsb_nnz_idx_t nnzA = 4;
322 const rsb_coo_idx_t incX = 1, incY = 1;
323 const rsb_coo_idx_t nrA = 3;
324 const rsb_coo_idx_t ncA = 2;
325 const rsb_coo_idx_t IA[] = {0,1,2,2};
326 const rsb_coo_idx_t JA[] = {0,0,0,1};
327 const double VA[] = {1,1,1,1};
328 const double X[] = {1,1,1};
329 double Y[] = {1,1,1};
330 const double alpha = 1.0;
331 const double beta = 0.0;
332 const rsb_trans_t transA = RSB_TRANSPOSITION_C;
333
334 mtxAp = rsb_mtx_alloc_from_coo_const(
335 VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
336 RSB_FLAG_DEFAULT_CSR_MATRIX_FLAGS|RSB_FLAG_USE_HALFWORD_INDICES
337 , &errval);
338
339 if((!mtxAp) || RSB_SOME_ERROR(errval))
340 RSB_PERR_GOTO(err,RSB_ERRM_ES);
341
342 if( Y[0] != 1 || Y[1] != 1 )
343 RSB_PERR_GOTO(err,RSB_ERRM_ES);
344 errval = rsb_spmv(transA, &alpha, mtxAp, X, incX, &beta, Y, incY);
345 if(RSB_SOME_ERROR(errval))
346 RSB_PERR_GOTO(err,RSB_ERRM_ES);
347 #if RSB_EXPECT_TRTR_BUG_COO
348 if( Y[0] != 3 || Y[2] != 0 )
349 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
350 // bug: Y[0:2] have been zeroed, instead of Y[0:1]
351 #else
352 if( Y[0] != 3 || Y[2] != 1 )
353 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
354 // ok : only Y[0:1] should have been zeroed
355 #endif
356
357 RSB_MTX_FREE(mtxAp);
358 }
359 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
360
361 #ifdef RSB_NUMERICAL_TYPE_DOUBLE_COMPLEX
362 {
363 const int bs = RSB_DEFAULT_BLOCKING;
364 const int brA = bs, bcA = bs;
365 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE_COMPLEX;
366 const rsb_nnz_idx_t nnzA = 5;
367 const rsb_coo_idx_t nrA = 3;
368 const rsb_coo_idx_t ncA = 3;
369 const rsb_coo_idx_t IA[] = {0,2,1,0,2};
370 const rsb_coo_idx_t CP[] = {0,2,3,5};
371 const double VA[] = {1,1, 1,0, 1,0, 1,0, 1,0};
372
373 mtxAp = rsb_mtx_alloc_from_csc_const(
374 VA,IA,CP,nnzA,typecode,nrA,ncA,brA,bcA,
375 RSB_FLAG_LOWER_HERMITIAN|RSB_FLAG_TRIANGULAR
376 , &errval);
377
378 if((!mtxAp) || RSB_SOME_ERROR(errval))
379 RSB_PERR_GOTO(err,RSB_ERRM_ES);
380
381 if ( mtxAp->nnz != 4 )
382 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
383
384 RSB_MTX_FREE(mtxAp);
385 }
386 #endif /* RSB_NUMERICAL_TYPE_DOUBLE_COMPLEX */
387
388 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
389 #define RSB_EXPECT_RECT_IMPDIA_NRHS_BUG 0
390 {
391 const int bs = RSB_DEFAULT_BLOCKING;
392 const int brA = bs, bcA = bs;
393 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE;
394 const rsb_nnz_idx_t nnzA = 2;
395 const rsb_coo_idx_t nrA = 2;
396 const rsb_coo_idx_t ncA = 1;
397 const rsb_coo_idx_t IA[] = {0,1};
398 const rsb_coo_idx_t JA[] = {0,0};
399 const rsb_coo_idx_t nrhs = 2;
400 const double VA[] = {1,1};
401 const double X[] = {1,1};
402 double Y[] = {0,0,0,0};
403 const double alpha = 1.0;
404 const double beta = 1.0;
405 const rsb_trans_t transA = RSB_TRANSPOSITION_N;
406
407 mtxAp = rsb_mtx_alloc_from_coo_const(
408 VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
409 RSB_FLAG_UNIT_DIAG_IMPLICIT
410 , &errval);
411
412 if((!mtxAp) || RSB_SOME_ERROR(errval))
413 RSB_PERR_GOTO(err,RSB_ERRM_ES);
414
415 errval = rsb_spmm(transA, &alpha, mtxAp, nrhs, RSB_FLAG_WANT_COLUMN_MAJOR_ORDER, X, 1, &beta, Y, 2);
416 if(RSB_SOME_ERROR(errval))
417 RSB_PERR_GOTO(err,RSB_ERRM_ES);
418 #if RSB_EXPECT_RECT_IMPDIA_NRHS_BUG
419 if( Y[1] != 2 || Y[3] != 1 )
420 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
421 // bug: Y[1] has been added an extra 1
422 #else
423 if( Y[1] != 1 || Y[3] != 1 )
424 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
425 // ok : Y[1] has been added no extra 1
426 #endif
427
428 RSB_MTX_FREE(mtxAp);
429 }
430 #undef RSB_EXPECT_RECT_IMPDIA_NRHS_BUG
431 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
432
433 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
434 #define RSB_EXPECT_TUNE_BROKEN_FOR_ROWS_MAJOR 0
435 {
436 const int bs = RSB_DEFAULT_BLOCKING;
437 const int brA = bs, bcA = bs;
438 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE;
439 const rsb_nnz_idx_t nnzA = 2;
440 const rsb_coo_idx_t incX = 1, incY = 1;
441 const rsb_coo_idx_t nrA = 3; // overzealous rsb_tune_spmm bug triggers on e.g. ldB<nrA (like when RSB_FLAG_WANT_ROW_MAJOR_ORDER)
442 const rsb_coo_idx_t ncA = 1;
443 const rsb_coo_idx_t IA[] = {0,1};
444 const rsb_coo_idx_t JA[] = {0,0};
445 const rsb_coo_idx_t nrhs = 2;
446 const rsb_coo_idx_t ldB = nrhs;
447 const rsb_coo_idx_t ldC = nrhs;
448 const double VA[] = {1,1};
449 const double B[] = {1,1};
450 double C[] = {0,0,0,0};
451 const double alpha = 1.0;
452 const double beta = 1.0;
453 const rsb_trans_t transA = RSB_TRANSPOSITION_N;
454
455 mtxAp = rsb_mtx_alloc_from_coo_const(
456 VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
457 RSB_FLAG_UNIT_DIAG_IMPLICIT
458 , &errval);
459
460 if((!mtxAp) || RSB_SOME_ERROR(errval))
461 RSB_PERR_GOTO(err,RSB_ERRM_ES);
462
463 errval = rsb_tune_spmm(NULL, NULL, NULL, 0.0, 0.0, transA, &alpha, mtxAp, nrhs, RSB_FLAG_WANT_ROW_MAJOR_ORDER, B, ldB, &beta, C, ldC);
464
465 #if RSB_EXPECT_TUNE_BROKEN_FOR_ROWS_MAJOR
466 if(!RSB_SOME_ERROR(errval))
467 {
468 errval = RSB_ERR_INTERNAL_ERROR;
469 RSB_PERR_GOTO(err,RSB_ERRM_ES);
470 }
471 #else
472 if( RSB_SOME_ERROR(errval))
473 RSB_PERR_GOTO(err,RSB_ERRM_ES);
474 #endif
475
476 RSB_MTX_FREE(mtxAp);
477 }
478 #undef RSB_EXPECT_TUNE_BROKEN_FOR_ROWS_MAJOR
479 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
480
481 #ifdef RSB_NUMERICAL_TYPE_DOUBLE
482 {
483 const int bs = RSB_DEFAULT_BLOCKING;
484 const int brA = bs, bcA = bs;
485 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE;
486 const rsb_nnz_idx_t nnzA = 1;
487 const rsb_coo_idx_t nrA = 1;
488 const rsb_coo_idx_t ncA = 1;
489 const rsb_coo_idx_t IA[] = {0};
490 const rsb_coo_idx_t JA[] = {0};
491 const rsb_coo_idx_t nrhs = 2;
492 const rsb_coo_idx_t ldB = nrhs;
493 const rsb_coo_idx_t ldC = nrhs + 1;
494 const double VA[] = {1};
495 const double B[] = {1,2,3,4};
496 double C[] = {0,0,0,0};
497 const double alpha = 1.0;
498 const double beta = 1.0;
499 const rsb_trans_t transA = RSB_TRANSPOSITION_N;
500
501 mtxAp = rsb_mtx_alloc_from_coo_const(
502 VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
503 RSB_FLAG_UNIT_DIAG_IMPLICIT,
504 &errval);
505
506 if((!mtxAp) || RSB_SOME_ERROR(errval))
507 RSB_PERR_GOTO(err,RSB_ERRM_ES);
508
509 errval = rsb_spmm(transA, &alpha, mtxAp, nrhs, RSB_FLAG_WANT_ROW_MAJOR_ORDER, B, ldB, &beta, C, ldC);
510
511 if( C[0] != 1 || C[1] != 2 || C[2] != 0 || C[3] != 0 )
512 RSB_PERR_GOTO(merr,RSB_ERRM_ES);
513
514 RSB_MTX_FREE(mtxAp);
515 }
516 #endif /* RSB_NUMERICAL_TYPE_DOUBLE */
517
518 RSBENCH_STDOUT("REGRESSION TEST: END\n");
519 errval = RSB_ERR_NO_ERROR;
520 goto err;
521 merr:
522 errval = RSB_ERR_INTERNAL_ERROR;
523 err:
524 if(RSB_SOME_ERROR(errval))
525 RSBENCH_STDOUT("REGRESSION TEST: FAIL\n");
526 RSB_MTX_FREE(mtxAp);
527 return errval;
528 }
529
530 RSB_INTERNALS_COMMON_HEAD_DECLS /* for RSB_INFO */
531
rsb__chk_sppsp(void)532 static rsb_err_t rsb__chk_sppsp(void)
533 {
534 rsb_err_t errval = RSB_ERR_INTERNAL_ERROR;
535 struct rsb_mtx_t *mtxAp = NULL; /* matrix structure pointer */
536 struct rsb_mtx_t *mtxCp = NULL; /* matrix structure pointer */
537
538 RSB_INFO("MATRIX SUMS TEST: BEGIN\n");
539 {
540 const int bs = RSB_DEFAULT_BLOCKING;
541 const int brA = bs, bcA = bs;
542 const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
543 const rsb_nnz_idx_t nnzA = 6;
544 const rsb_coo_idx_t nrA = 4;
545 const rsb_coo_idx_t ncA = 4;
546 const rsb_coo_idx_t IT[] = {1,1,1,2,2,4};
547 const rsb_coo_idx_t JL[] = {1,3,4,1,2,4};
548 const RSB_DEFAULT_TYPE VT[] = {11,13,14,-21,22,44};
549
550 const void *alphap = NULL;
551 const void *betap = NULL;
552 struct rsb_mtx_t *mtxBp = NULL;
553 const rsb_trans_t transA = RSB_TRANSPOSITION_T;
554 const rsb_trans_t transB = RSB_TRANSPOSITION_T;
555
556 mtxAp = rsb_mtx_alloc_from_coo_const(
557 VT,IT,JL,nnzA,typecode,nrA,ncA,brA,bcA,
558 RSB_FLAG_DEFAULT_RSB_MATRIX_FLAGS
559 | RSB_FLAG_DUPLICATES_SUM
560 | RSB_FLAG_FORTRAN_INDICES_INTERFACE
561 , &errval);
562
563 if((!mtxAp) || RSB_SOME_ERROR(errval))
564 RSB_PERR_GOTO(err,RSB_ERRM_ES);
565
566 mtxBp = mtxAp;
567 mtxCp = rsb_sppsp(typecode, transA, alphap, mtxAp, transB, betap, mtxBp, &errval);
568
569 if((!mtxCp) || RSB_SOME_ERROR(errval))
570 RSB_PERR_GOTO(err,RSB_ERRM_ES);
571
572 if(mtxAp->nnz != mtxCp->nnz)
573 RSB_PERR_GOTO(err,RSB_ERRM_ES);
574 }
575 RSB_INFO("MATRIX SUMS TEST: END\n");
576 goto ret;
577 err:
578 RSB_INFO("MATRIX SUMS TEST: FAIL\n");
579 errval = RSB_ERR_INTERNAL_ERROR;
580 ret:
581 RSB_MTX_FREE(mtxAp);
582 RSB_MTX_FREE(mtxCp);
583 return errval;
584 }
585
rsb__sigh(int signal)586 void rsb__sigh(int signal)
587 {
588 /* TODO: extend this mechanism optionally to the library itself. */
589
590 if( rsb__quit_rsbench == 0 )
591 {
592 RSBENCH_STDOUT("\n");
593 RSBENCH_STDOUT("====================================================\n");
594 RSBENCH_STDOUT("Caught signal %d: will terminate as soon as possible.\n",signal);
595 RSBENCH_STDOUT(" ( next time won't catch the signal anymore ).\n");
596 RSBENCH_STDOUT("====================================================\n");
597 RSBENCH_STDOUT("\n");
598 rsb__quit_rsbench++;
599 }
600 else
601 if( rsb__quit_rsbench == 1 )
602 {
603 #if defined(RSB_WANT_ACTION_SIGNAL)
604 #else /* defined(RSB_WANT_ACTION_SIGNAL) */
605 sigaction(SIGINT,&rsb_osa,NULL);
606 #endif /* defined(RSB_WANT_ACTION_SIGNAL) */
607 }
608 }
609
rsb__sigr(void)610 void rsb__sigr(void)
611 {
612 rsb__quit_rsbench = 0;
613 {
614 #if RSB_WANT_ACTION_SIGNAL
615 /* signal() is part of C99 */
616 signal(SIGINT,&rsb__sigh); /* not to be called from a threaded environment ... */
617 #else /* RSB_WANT_ACTION_SIGNAL */
618 /* sigaction() is part of POSIX, not part of C99 */
619 struct sigaction act;
620 RSB_BZERO_P(&act);
621 RSB_BZERO_P(&rsb_osa);
622 act.sa_handler = rsb__sigh;
623 sigemptyset(&act.sa_mask);
624 sigaction(SIGINT, &act,&rsb_osa);
625 /*
626 sigaction(SIGUSR1, &act, &rsb_osa);
627 sigaction(SIGUSR2, &act, &rsb_osa);
628
629 sigaction(SIGQUIT,&act,&rsb_osa);
630 sigaction(SIGTERM,&act,&rsb_osa);
631
632 sigaction(SIGABRT,&act,&rsb_osa);
633 sigaction(SIGTSTP,&act,&rsb_osa);
634
635 sigaction(SIGBUS, &act,&rsb_osa);
636 sigaction(SIGILL, &act,&rsb_osa);
637 sigaction(SIGSEGV,&act,&rsb_osa);
638 */
639 #endif /* RSB_WANT_ACTION_SIGNAL */
640 }
641 }
642 #endif /* RSB_WANT_ACTION */
643
rsb__print_configuration_string_rsbench(const char * pn,rsb_char_t * cs,rsb_bool_t wci)644 rsb_err_t rsb__print_configuration_string_rsbench(const char *pn, rsb_char_t * cs, rsb_bool_t wci)
645 {
646 /* TODO: output buffer length check */
647 rsb_err_t errval = RSB_ERR_NO_ERROR;
648 #if RSB_WANT_MKL
649 #ifdef mkl_get_version
650 MKLVersion mv;
651 #endif /* mkl_get_version */
652 #endif /* RSB_WANT_MKL */
653 if(!cs)
654 {
655 errval = RSB_ERR_BADARGS;
656 goto err;
657 }
658 errval = rsb__print_configuration_string(pn, cs, wci);
659 if(wci == RSB_BOOL_FALSE)
660 goto err;
661 #if RSB_WANT_MKL
662 #ifdef mkl_get_version
663 mkl_get_version(&mv);
664 sprintf(cs+strlen(cs),"MKL:%d.%d-%d, %s, %s, %s, %s\n",mv.MajorVersion,mv.MinorVersion,mv.UpdateVersion,mv.ProductStatus,mv.Build,mv.Processor,mv.Platform);
665 #else /* mkl_get_version */
666 sprintf(cs+strlen(cs),"MKL:version unknown.\n");
667 #endif /* mkl_get_version */
668 #else /* RSB_WANT_MKL */
669 sprintf(cs+strlen(cs),"MKL:not linked.\n");
670 #endif /* RSB_WANT_MKL */
671 #if RSB_WANT_XDR_SUPPORT
672 sprintf(cs+strlen(cs),"XDR support: on.\n");
673 #else /* RSB_WANT_XDR_SUPPORT */
674 sprintf(cs+strlen(cs),"XDR support: off.\n");
675 #endif /* RSB_WANT_XDR_SUPPORT */
676 #if RSB_WANT_ZLIB_SUPPORT
677 sprintf(cs+strlen(cs),"ZLIB support: on.\n");
678 #else /* RSB_WANT_ZLIB_SUPPORT */
679 sprintf(cs+strlen(cs),"ZLIB support: off.\n");
680 #endif /* RSB_WANT_ZLIB_SUPPORT */
681 err:
682 return errval;
683 }
684
rsb__main_help(const int argc,char * const argv[],int default_program_operation,const char * program_codes,rsb_option * options)685 static int rsb__main_help(const int argc, char * const argv[], int default_program_operation, const char * program_codes, rsb_option *options)
686 {
687 const char * pbn = rsb__basename(argv[0]);
688
689 //RSB_STDOUT(
690 printf(
691 /*"[OBSOLETE DOCUMENTATION] \n"*/
692 "Usage: %s [OPTIONS] \n"
693 " or: %s [ -o OPCODE] [ -O {subprogram-code}] [ {subprogram-specific-arguments} ] \n"
694 "%s "RSB_INFOMSG_SAK"."
695 "\n"
696 "\n"
697 //"\tOne may choose {option} among:\n"
698 //"\t-I for getting system information and some micro benchmarking\n"
699 "\t\n"
700 "Choose {subprogram-code} among:\n\n"
701 "\tr for the reference benchmark (will produce a machine specific file)\n\n"
702 "\tc for the complete benchmark\n\n"
703 "\te for the matrix experimentation code\n\n"
704 "\td for a single matrix dumpout\n\n"
705 "\tb for the (current, going to be obsoleted) benchmark\n\n"
706 "\tt for some matrix construction tests\n\n"
707 "\to obsolete, will soon be removed\n"
708 "\n"
709 "{subprogram-specific-arguments} will be available from the subprograms.\n\n"
710 "\te.g.: %s -O b -h will show the current benchmark subprogram's options\n\n"
711 "\te.g.: %s -o a -O b -h will show the spmv benchmark subprogram's options\n\n"
712 "\te.g.: %s -o n -O b -h will show the negation benchmark subprogram's options\n\n"
713 // "\te.g.: %s -o A -O b will run all of the benchmark programs.\n"
714 "\nThe default {subprogram-code} is '%c'\n"
715 "\n\tWith OPCODE among '%s'\n"/* TODO: fix this description, as it is too laconic. */
716 "\n"
717 ,pbn
718 ,pbn
719 ,pbn
720 ,pbn
721 ,pbn
722 ,pbn
723 ,default_program_operation
724 ,program_codes
725 );
726 if(options)
727 rsb_test_help_and_exit(pbn,options,0);
728 return 0;
729 }
730
731 int rsb_genmm_main(int argc,char *argv[]);
732 int rsb_mtx_ls_main(int argc,char *argv[]);
733
main(const int argc,char * argv[])734 int main(const int argc, char * argv[])
735 {
736 rsb_option options[] = {
737 {"help", no_argument, NULL, 'h' },
738 {"matrix-operation", required_argument, NULL, 'o' },
739 {"subprogram-operation", required_argument, NULL, 'O' },
740 {"information", no_argument, NULL, 'I' },
741 {"configuration", no_argument, NULL, 'C' },
742 {"hardware-counters", no_argument, NULL, 'H' },
743 {"experiments", no_argument, NULL, 'e' },
744 {"version", no_argument, NULL, 'v' },
745 {"blas-testing", no_argument, NULL, 'B' },
746 {"quick-blas-testing", required_argument, NULL, 'Q' },
747 {"error-testing", required_argument, NULL, 'E' },
748 {"fp-bench", no_argument, NULL, 'F' },
749 {"transpose-test", no_argument, NULL, 't' },
750 {"limits-testing", no_argument, NULL, 0x6c696d74 },
751 {"guess-blocking", no_argument, NULL, 'G' }, /* will pass guess parameters here some day (FIXME: obsolete) */
752 {"generate-matrix", no_argument, NULL, 'g' }, /* should be synced to rsb_genmm_main */
753 {"plot-matrix", no_argument, NULL, 0x50505050},/* should be synced to rsb__dump_postscript */
754 {"matrix-ls", no_argument, NULL, 0x006D6C73},/* should be synced to rsb_mtx_ls_main */
755 {"read-performance-record", required_argument, NULL, 0x7270720a},/* */
756 {"help-read-performance-record", no_argument, NULL, 0x72707268},/* */
757 {0,0,0,0}
758 };
759
760 /*
761 * NOTE: this implies that unless an argument reset mechanism is implemented here,
762 * the o and O options will be forwarded to the host program!
763 * */
764 //const char default_operation='v';
765 const char default_operation='a';
766 char operation=default_operation;
767 //const char default_program_operation='r';
768 const char default_program_operation='b';
769 char program_operation=default_program_operation;
770 rsb_err_t errval = RSB_ERR_NO_ERROR;
771 #if RSB_WANT_REDUCED_RSB_M4_MATRIX_META_OPS
772 const char * program_codes = "a"
773 #else /* RSB_WANT_REDUCED_RSB_M4_MATRIX_META_OPS */
774 const char * program_codes = "avms"
775 #endif /* RSB_WANT_REDUCED_RSB_M4_MATRIX_META_OPS */
776 #if !RSB_SHALL_UPDATE_COMPLETEBENCHS
777 "c"
778 #endif /* RSB_SHALL_UPDATE_COMPLETEBENCHS */
779 #ifdef RSB_OPTYPE_INDEX_SPSV_UXUA
780 "t"
781 #endif
782 "inS";
783 int program_not_chosen=1;
784 struct rsb_tester_options_t to;
785 rsb_char_t cs[RSB_MAX_VERSION_STRING_LENGTH];
786 int c;
787
788 rsb_blas_tester_options_init(&to);
789
790 for (;program_not_chosen;)
791 {
792 int opt_index = 0;
793 c = rsb_getopt_long(argc,argv,"CP:"
794 "gBGvMHIho:O:"
795 /* #if RSB_WANT_EXPERIMENTS_CODE
796 "e"
797 #endif */ /* RSB_WANT_EXPERIMENTS_CODE */
798 "FQ:E:",options,&opt_index);
799 if (c == -1)break;
800 switch (c)
801 {
802 case 'F':
803 /*
804 * Floating point mini-benchmark
805 * */
806 return (rsb_lib_init(RSB_NULL_INIT_OPTIONS) == RSB_ERR_NO_ERROR && rsb__fp_benchmark() == RSB_ERR_NO_ERROR) ?RSB_PROGRAM_ERROR:RSB_PROGRAM_SUCCESS;
807 break;
808 case 'G':
809 /*
810 * Sparse GEMM preliminary code.
811 * TODO: remove this temporary case, as it may break other functionality with the G flag.
812 * */
813 return RSB_ERR_TO_PROGRAM_ERROR(rsb__do_spgemm_test_code(argc-1,argv+1));
814 case 'g':
815 return RSB_ERR_TO_PROGRAM_ERROR(rsb_genmm_main(argc,argv));
816 break;
817 case 0x006D6C73:
818 return RSB_ERR_TO_PROGRAM_ERROR(rsb_mtx_ls_main(argc,argv));
819 break;
820 case 0x7270720a:
821 case 0x72707268:
822 goto qos;
823 break;
824 case 0x50505050:
825 return RSB_ERR_TO_PROGRAM_ERROR(rsb__dump_postscript(argc,argv));
826 break;
827 case 0x6c696d74:
828 {
829 if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS)) != RSB_ERR_NO_ERROR)
830 goto berr;
831 RSB_DO_ERROR_CUMULATE(errval,rsb_blas_limit_cases_tester());
832 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))goto ferr;
833 return RSB_ERR_TO_PROGRAM_ERROR(errval);
834 }
835 break;
836 case 'E':
837 {
838 if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS)) != RSB_ERR_NO_ERROR)
839 goto berr;
840 RSB_DO_ERROR_CUMULATE(errval,rsb_blas_failure_tester(optarg));
841 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))goto ferr;
842 return RSB_ERR_TO_PROGRAM_ERROR(errval);
843 }
844 case 'Q':
845 to.mtt = rsb__util_atof(optarg);
846 if(strstr(optarg,"R")!=NULL)to.rrm=RSB_BOOL_TRUE;
847 if(strstr(optarg,"U")!=NULL)to.tur=RSB_BOOL_TRUE;
848 if(strstr(optarg,"Q")!=NULL)to.wqt=RSB_BOOL_TRUE;
849 if(strstr(optarg,"q")!=NULL)to.wqc=RSB_BOOL_TRUE;
850 if(strstr(optarg,"C")!=NULL)to.wcs=RSB_BOOL_TRUE;
851 case 'B':
852 RSB_SIGHR
853 /* Sparse BLAS test. */
854 //#if RSB_WITH_SPARSE_BLAS_INTERFACE
855 #if 1
856 {
857 if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS)) != RSB_ERR_NO_ERROR)
858 goto berr;
859 #if RSB_ALLOW_INTERNAL_GETENVS
860 if(getenv("RSB_RSBENCH_BBMB") && rsb__util_atoi(getenv("RSB_RSBENCH_BBMB")) )
861 goto bbmb;
862 #endif /* RSB_ALLOW_INTERNAL_GETENVS */
863 RSB_DO_ERROR_CUMULATE(errval,rsb_blas_runtime_limits_tester());
864 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))goto ferr;
865 #if 0
866 /* TODO: this is here temporarily */
867 RSB_DO_ERROR_CUMULATE(errval,rsb__do_lock_test());
868 #endif
869 RSB_DO_ERROR_CUMULATE(errval,rsb__chk_srt());
870 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))goto ferr;
871 RSB_DO_ERROR_CUMULATE(errval,rsb__chk_trtr());
872 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))goto ferr;
873 RSB_DO_ERROR_CUMULATE(errval,rsb__chk_sppsp());
874 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))goto ferr;
875 RSB_DO_ERROR_CUMULATE(errval,rsb_blas_mini_tester());
876 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))goto ferr;
877 //RSB_LIKWID_MARKER_INIT;
878 //RSB_LIKWID_MARKER_R_START("RSB-QUICKTEST");
879 #if RSB_ALLOW_INTERNAL_GETENVS
880 bbmb:
881 #endif /* RSB_ALLOW_INTERNAL_GETENVS */
882 RSB_DO_ERROR_CUMULATE(errval,rsb_blas_bigger_matrices_tester(&to));/* TODO: options should be passed here */
883 //RSB_LIKWID_MARKER_R_STOP("RSB-QUICKTEST");
884 //RSB_LIKWID_MARKER_EXIT;
885 if((!RSB_WANT_PERMISSIVE_RSBENCH) && RSB_SOME_ERROR(errval))
886 goto ferr;
887 goto ferr;
888 }
889 #else
890 RSB_STDERR("no Sparse BLAS interface built.\n");
891 //return -1;
892 return 0;
893 #endif
894 break;
895 case 'C':
896 if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS)) != RSB_ERR_NO_ERROR)
897 RSB_STDERR(RSB_ERRM_SILTC);
898 errval = rsb__print_configuration_string_rsbench(argv[0],cs,RSB_BOOL_TRUE);
899 printf("%s",cs);
900 goto verr;
901 break;
902 case 'v':
903 if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS)) != RSB_ERR_NO_ERROR)
904 RSB_STDERR(RSB_ERRM_SILTC);
905 errval = rsb__print_configuration_string_rsbench(argv[0],cs,RSB_BOOL_FALSE);
906 printf("%s",cs);
907 goto verr;
908 break;
909 case 'M':
910 if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS)) != RSB_ERR_NO_ERROR)
911 RSB_PERR_GOTO(err,RSB_ERRM_ES);
912 return RSB_ERR_TO_PROGRAM_ERROR(rsb__memory_benchmark());
913 break;
914 case 'H':
915 return RSB_ERR_TO_PROGRAM_ERROR(rsb_hc_main()); /* preliminary */
916 break;
917 case 'I':
918 rsb_lib_init(RSB_NULL_INIT_OPTIONS);
919 return
920 RSB_ERR_TO_PROGRAM_ERROR(rsb_perror(NULL,rsb__sys_info()));
921 break;
922 /*
923 #if RSB_WANT_EXPERIMENTS_CODE
924 case 'e':
925 return rsb_exp_bcsr_guess_experiments(argc,argv);
926 break;
927 #endif */ /* RSB_WANT_EXPERIMENTS_CODE */
928 case 'P':
929 {
930 errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS);
931 if(RSB_SOME_ERROR(errval))
932 goto err;
933 {
934 struct rsb_mtx_t * mtxAp = rsb_file_mtx_load(optarg,RSB_FLAG_DEFAULT_MATRIX_FLAGS,RSB_NUMERICAL_TYPE_DEFAULT,NULL);
935 errval = rsb_file_mtx_save(mtxAp,NULL);
936 RSB_MTX_FREE(mtxAp);
937 }
938 RSB_MASK_OUT_SOME_ERRORS(errval)
939 goto verr;
940 }
941 break;
942 case 'o':
943 operation=*optarg;
944 break;
945 case 'O':
946 program_operation=*optarg;
947 program_not_chosen=0;
948 break;
949 case 'h':
950 /* getsubopt may come in help here */
951 return rsb__main_help(argc, argv,default_program_operation,program_codes,options);
952 break;
953 /*
954 case 't':
955 return rsb__main_transpose(argc,argv);
956 break;
957 */
958 default:
959 {
960 }
961 }
962 }
963
964 qos: /* quit option selection */
965
966 if(c == 0x72707268)
967 {
968 errval = rsb__pr_dumpfiles(NULL,0);
969 return RSB_ERR_TO_PROGRAM_ERROR(errval);
970 }
971 if(c == 0x7270720a)
972 {
973 /*
974 if(argc == 3)
975 return rsb__pr_dumpfile(optarg);
976 if(argc == 3)
977 return rsb__pr_dumpfiles(&optarg,1);
978 */
979
980 if(argc >= 3)
981 {
982 const int RSB__PR_DUMP_MAXARGS = 1024; /* TODO: temporary */
983 const rsb_char_t*fna[RSB__PR_DUMP_MAXARGS];
984 int i;
985 for(i=2;i<RSB_MIN(RSB__PR_DUMP_MAXARGS,argc);++i)
986 fna[i-2] = argv[i];
987 errval = rsb__pr_dumpfiles(fna,i-2);
988 return RSB_ERR_TO_PROGRAM_ERROR(errval);
989 }
990 }
991
992 if(program_not_chosen)
993 return rsb__main_help(argc, argv,default_program_operation,program_codes,options);
994
995 switch (program_operation) /* O */
996 {
997 case 'r':
998 {
999 /*
1000 * A benchmark to compute (machine,compiled) reference performance values.
1001 * */
1002 errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS);
1003 if(errval == RSB_ERR_NO_ERROR)
1004 goto verr;
1005 errval = rsb__do_referencebenchmark(); /* FIXME: probably obsolete */
1006 RSB_MASK_OUT_SOME_ERRORS(errval)
1007 goto verr;
1008 }
1009 break;
1010 case 'R':
1011 /**/
1012 /*
1013 * Dump current (hardcoded) performance info without computing anything.
1014 * */
1015 errval = rsb__dump_current_global_reference_performance_info(); /* FIXME: probably obsolete */
1016 RSB_MASK_OUT_SOME_ERRORS(errval)
1017 goto verr;
1018 break;
1019 #if !RSB_SHALL_UPDATE_COMPLETEBENCHS
1020 case 'c':
1021 /* A complete benchmark. TODO: this is broken / old; needs a revamp, or oblivion */
1022 errval = rsb_do_completebenchmark(argc,argv); /* FIXME: probably obsolete */
1023 RSB_MASK_OUT_SOME_ERRORS(errval)
1024 goto verr;
1025 break;
1026 #endif /* RSB_SHALL_UPDATE_COMPLETEBENCHS */
1027 case 'd':
1028 /*
1029 * A single matrix dump (almost useless).
1030 * */
1031 return rsb__test_dump_main(argc,argv); /* FIXME: probably obsolete */
1032 break;
1033 case 'e':
1034 /*
1035 * The matrix experimentation code.
1036 * */
1037 RSB_STDERR("this option was obsoleted by -oS -Ob\n");
1038 /*return rsb_test_main_block_partitioned_matrix_stats(argc,argv); */ /* FIXME: probably obsolete */
1039 return -1;
1040 break;
1041 case 'b':
1042 {
1043 /*
1044 * The current reference benchmark.
1045 * */
1046 RSB_SIGHR
1047 switch(operation) /* o */
1048 {
1049 #ifdef RSB_HAVE_OPTYPE_SPMV_UAUA
1050 case 'a':
1051 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_spmv_uaua(argc,argv));
1052 break;
1053 #endif /* RSB_HAVE_OPTYPE_SPMV_UAUA */
1054 #if !RSB_WANT_REDUCED_RSB_M4_MATRIX_META_OPS
1055 #ifdef RSB_HAVE_OPTYPE_SPMV_UAUZ
1056 case 'v':
1057 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_spmv_uauz(argc,argv));
1058 break;
1059 #endif /* RSB_HAVE_OPTYPE_SPMV_UAUZ */
1060 #ifdef RSB_HAVE_OPTYPE_SPMM_AZ
1061 case 'm':
1062 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_spmm_az(argc,argv));
1063 break;
1064 #endif /* RSB_HAVE_OPTYPE_SPMM_AZ */
1065 #ifdef RSB_HAVE_OPTYPE_SCALE
1066 case 's':
1067 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_scale(argc,argv));
1068 break;
1069 #endif /* RSB_HAVE_OPTYPE_SCALE */
1070 #ifdef RSB_HAVE_OPTYPE_SPMV_UXUX
1071 case 'c':
1072 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_spmv_uxux(argc,argv));
1073 break;
1074 #endif /* RSB_HAVE_OPTYPE_SPMV_UXUX */
1075 #ifdef RSB_HAVE_OPTYPE_INFTY_NORM
1076 case 'i':
1077 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_infty_norm(argc,argv));
1078 break;
1079 #endif /* RSB_HAVE_OPTYPE_INFTY_NORM */
1080 #ifdef RSB_HAVE_OPTYPE_NEGATION
1081 case 'n':
1082 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_negation(argc,argv));
1083 break;
1084 #endif /* RSB_HAVE_OPTYPE_NEGATION */
1085 #endif /* RSB_WANT_REDUCED_RSB_M4_MATRIX_META_OPS */
1086 #ifdef RSB_OPTYPE_INDEX_SPSV_UXUA
1087 case 't':
1088 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_spsv_uxua(argc,argv));
1089 break;
1090 #endif /* RSB_OPTYPE_INDEX_SPSV_UXUA */
1091 #if 1 /* this is a special case */
1092 case 'S':
1093 //return rsb__main_block_partitioned_sort_only(argc,argv);//old
1094 return RSB_ERR_TO_PROGRAM_ERROR(rsb__main_block_partitioned_mat_stats(argc,argv));//new
1095 break;
1096 #endif
1097 default:
1098 RSB_STDERR(
1099 "You did not choose a correct operation code.\n"
1100 "Choose one among %s.\n",program_codes
1101 );
1102 errval = RSB_ERR_UNSUPPORTED_OPERATION;
1103 RSB_DO_ERR_RETURN(errval)
1104 }
1105 }
1106 break;
1107 #if 0
1108 case 't': /* to reintegrate, add 't' to program_codes */
1109 /*
1110 * A whole matrix repartitioning test.
1111 * */
1112 return RSB_ERR_TO_PROGRAM_ERROR(rsb_test_main_block_partitioned_construction_test(argc,argv));
1113 break;
1114 #endif
1115 default:
1116 RSB_STDERR("You did not choose an action. See help:\n");
1117 return rsb__main_help(argc, argv,default_program_operation,program_codes,NULL);
1118 return RSB_PROGRAM_SUCCESS;
1119 }
1120 goto err;
1121 ferr:
1122 /* rsb__getrusage(); */
1123 RSB_DO_ERROR_CUMULATE(errval,rsb_lib_exit(RSB_NULL_EXIT_OPTIONS));
1124 berr:
1125 if(RSB_SOME_ERROR(errval))
1126 rsb_perror(NULL,errval);
1127 verr:
1128 return RSB_ERR_TO_PROGRAM_ERROR(errval);
1129 err:
1130 if(RSB_SOME_ERROR(errval))
1131 rsb_perror(NULL,errval);
1132 return RSB_PROGRAM_ERROR;
1133 }
1134
1135 /* @endcond */
1136