1 /*
2 
3 Copyright (C) 2008-2020 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 /*!
23  *  \file
24  *  \brief  This file declares the user interface functions and data structures for the \librsb library.
25  *  \author Michele Martone
26  * */
27 /*!
28  \mainpage
29 
30  A sparse matrix library implementing the `Recursive Sparse Blocks' (\b RSB) matrix storage.
31 
32 
33  This is the documentation for the application programming interface (API)
34  of the \e `\librsb' library.
35  \n
36  In order to use \librsb, there is no need for the user to know the RSB
37  layout and algorithms: this documentation should be sufficient.
38  \n
39  This library is dual-interfaced; it supports:
40  a native (`RSB') interface (with identifiers prefixed by `rsb_' or `RSB_'),
41  and a (mostly complete) Sparse BLAS interface, as a wrapper around the RSB interface.
42  \n
43  Many computationally intensive operations are implemented with thread
44  parallelism, by using OpenMP.
45  \n
46  Thread parallelism can be turned off at configure time, if desired, or limited
47  at execution time.
48  \n
49  Many of the computational kernels source code files (mostly internals) were
50  automatically generated.
51  \n
52  This user documentation concerns the end user API only; that is, neither the
53  internals, nor the code generator.
54  \n
55 
56  You should consult the remaining documentation (e.g. the README file, code
57  comments) to find information about how to modify the generator or the
58  library internals.
59 
60  This library is research software and as such, still \b experimental.
61  For a first approach, we suggest to go through the \ref rsb_doc_examples  documentation
62  section, or the \ref examples_section "quick start examples" section on this page.
63 
64  \n
65  Information about the supported matrix types and matrix operations
66  resides in the \link rsb_types.h rsb_types.h \endlink file.
67 
68  A C/C++ user can use the native API of RSB by including the \link rsb.h rsb.h \endlink header.
69  The same interface is available in Fortran via the ISO C Binding interface, specified in \link rsb.F90 rsb.F90\endlink.
70  \n
71 
72  The C header file for the \ref rsb_doc_sparse_blas  is \link blas_sparse.h blas_sparse.h\endlink.
73 
74  \author Michele Martone < michelemartone AT users DOT sourceforge DOT net >
75 
76  Contents of the README file :
77  \verbinclude README
78 
79  \anchor examples_section
80 
81  For a quick startup, consider the following two programs.
82 
83  The first, using the internal RSB interface:
84  \include examples/hello.c
85 
86  And the second, using the Sparse BLAS interface:
87  \include examples/hello-spblas.c
88 
89  For more, see the \ref rsb_doc_examples  section.
90 
91  */
92 
93 /*!
94  \defgroup rsb_doc_rsb The librsb library interface (rsb.h, rsb.F90)
95  \brief
96  The reference documentation of the \librsb library comes in both HTML and Unix man pages formats.
97  The following sections/man pages are available: \ref rsb_doc_rsb ; \ref rsb_doc_sparse_blas ; \ref rsb_doc_examples.
98 
99 
100  In general, users of this library are interested in high performance sparse matrix computations on cache based shared memory parallel computers.
101  For this, \librsb offers a native C interface (here documented) and a Fortran one (in \ref rsb.F90, equivalent to the C declaration headers from \ref rsb.h), in addition to a the Sparse BLAS one (both C and Fortran, documented).
102 
103  Configuration, build, and installation instructions are contained in the \c README file distributed in the sources archive.
104 
105  <b> Typical program structure </b>
106 
107  \li initialize \librsb with #rsb_lib_init()
108  \li (in any order)
109       allocate matrices (e.g.: with #rsb_mtx_alloc_from_coo_inplace() or others);
110       do any computation with them (e.g.: #rsb_spmv(), #rsb_spsv() );
111       converting matrices (e.g.: with #rsb_mtx_switch_to_coo() );
112       freeing matrices (#rsb_mtx_free() )
113  \li finalize \librsb with #rsb_lib_exit()
114 
115 
116  <b> Important usage notes </b>
117 
118  <b> General program structure </b>
119  Before calling any \librsb function, a program is required to initialize \librsb's internal status.
120  This is done by calling #rsb_lib_init() .
121  Afterwards, any \librsb function can be safely used.
122  When \librsb functions are not intended to be called anymore, a program may call #rsb_lib_exit() to free any resource.
123  Then, #rsb_lib_init() should be called for further usage of \librsb.
124 
125  <b> Manipulating matrices and vectors </b>
126  In order to use \librsb, the user is not required to use explicitly any of \librsb's data structures: their manipulation is to be performed by \librsb functions.
127  Therefore, knowledge of \librsb's matrix type (\c rsb_mtx_t) is not necessary at all: this structure is intended to be used as an opaque container.
128 
129  On the contrary, arrays for numerical vectors (or more generally, dense matrices) are expected to be managed by the user: \librsb does not furnish any specific vector type.
130  Computational functions treat dense vectors/matrices are simple arrays of a specified type; see the \ref rsb_doc_examples  .
131 
132  <b> Computational functions </b>
133  This library can be configured at build time to support a custom subset of numerical types.
134  To keep the programming interface compact, it has been decided to not replicate the computational functions to each numerical type.
135  Instead, the type is expected to be specified by the user via a type flag.
136  For instance, matrix assembly functions (e.g.: #rsb_mtx_alloc_from_coo_const() ) accept a type information and keep it stored in the matrix structure.
137  Therefore, computational functions (e.g.: #rsb_spmv() ) can fetch this information from their \c rsb_mtx_t operand, and treat accordingly the other parameters (e.g.: \a alphap, \a Xp, ...).
138  Mixed type operations are currently not supported.
139 
140 
141  <b> Memory management </b>
142 
143  Matrix structures (\c rsb_mtx_t) allocated by \librsb shall be freed only via #rsb_mtx_free() .
144 
145  <b> Benchmarking </b>
146 
147  If you want to benchmark this library, there are different possibilities:
148  \include ./examples/benchex.sh
149 
150  <b> Tuning and Customization </b>
151 
152  There are different \c ./configure  options you may look at for tuning or customizing the library.
153 
154 
155 
156  \defgroup rsb_doc_examples	Example programs and code
157  \brief	Examples of usage of \librsb.
158 
159  	The following fully working example programs illustrate correct ways of using the library.
160 	The script displayed here should be sufficient to build them.
161  \include examples/make.sh
162 
163  \include examples/hello.c
164  \include examples/hello-spblas.c
165  \include examples/hello-spblas.c
166  \include examples/autotune.c
167  \include examples/io-spblas.c
168  \include examples/transpose.c
169  \include examples/power.c
170  \include examples/fortran.F90
171  \include examples/fortran_rsb_fi.F90
172 */
173 
174 /*!
175  \defgroup rsb_doc_sparse_blas The Sparse BLAS interface to librsb (blas_sparse.h, rsb_blas_sparse.F90)
176  \brief
177  	A Sparse BLAS interface (see http://www.netlib.org/blas/blast-forum/) to \librsb.  Level 1 (vector-vector operations) is supported in a basic way.  Level 2 (sparse matrix-dense vector operations) is supported fully.  Level 3 (sparse matrix-dense matrix operations) is supported as a wrapper around Level 2.
178 
179 We also implement a number of useful extra functions as custom extensions, giving access to other \librsb functionality.
180 
181 The usage pattern of this interface matches that of the Sparse BLAS standard, exception made for the necessity of initialization/finalization of \librsb.
182 The Sparse BLAS interface is also available for Fortran: see \ref rsb_blas_sparse.F90.
183 
184 
185 The user should be aware of the following:
186 \li Because this Sparse BLAS implementation is built around \librsb, initialization with #rsb_lib_init() and finalization with #rsb_lib_exit() is necessary. Inclusion of the \c rsb.h header is necessary.
187 \li \librsb gives users freedom of in/out arbitrarily BLAS types support at configure/build time. Hence, while all the interface functions are always included the Sparse BLAS header file, they may return an error code. Be sure of having configured correctly the library at configure time (and see the \ref blas_sparse.h header file for types configured in the current build).
188 \li According to the standard, the complex type functions for C accept scalar values by reference rather than by copy; equivalent functions for other types do not do so, so this may cause confusion. Be careful.
189 \li Error checking is weak; so for instance, passing a function the handle of a matrix of mismatching type will not be detected as an error, although it's incorrect.
190 \li According to the standard, VBR and BCSR styled constructors are supported, although these are interfaces for \librsb's own matrix representation.
191 \li Here we list functions for both Fortran and C functions. However, the Fortran functions are declared and documented with the C notation.  We may provide a better documentation in a subsequent release.
192 \li Each identifier documented here suffixed by \c _  (e.g.: #blas_susdot_()) can be used from Fortran with the name stripped by that suffix (so in this case, \c blas_susdot).
193 We will provide a proper fix to this inconvenience in a subsequent release.
194 \li Each Fortran program using \librsb's Sparse BLAS Implementation shall \c use  modules \c blas_sparse  and \c rsb.
195 \li Also Fortran programs have to call #rsb_lib_init() and #rsb_lib_exit() e.g.:
196 \verbatim
197        	USE blas_sparse             ! module implementing the Sparse BLAS on the top of librsb
198        	USE rsb                     ! rsb module
199 	...
200 	INTEGER :: istat            ! integer variable
201 	...
202        	istat = rsb_lib_init(RSB_NULL_INIT_OPTIONS) ! please note that this is not part of Sparse BLAS but it is needed by librsb
203 	if(istat.NE.0)STOP          ! a value different than zero signals an error
204 	...
205 	! code calling Sparse BLAS routines
206 	...
207        	istat = rsb_lib_exit(RSB_NULL_EXIT_OPTIONS) ! please note that this is not part of Sparse BLAS but it is needed by librsb
208 	if(istat.NE.0)STOP          ! a value different than zero signals an error
209 	...
210 \endverbatim
211 	\li For Fortran, more procedures exist, although they are not documented here. According to the Sparse BLAS (http://www.netlib.org/blas/blast-forum/), for almost each subroutine whose identifier prefixed with \c blas_X (with \c X being one of S,D,C,Z), a corresponding generic modern Fortran version exists.
212 	Please note how not all of the certain procedures identifier prefixes include the type character.
213 
214 	E.g.:
215 \code
216       ! the following code ('d' stays for 'double precision'):
217       CALL blas_duscr_begin(nr,nc,A,istat)
218       CALL blas_ussp(A,blas_lower_symmetric,istat)
219       CALL blas_duscr_insert_entries(A,nnz,VA,IA,JA,istat)
220       CALL blas_duscr_end(A,istat)
221       CALL blas_dusmv(transT,alpha,A,X,incX,B,incB,istat)
222       CALL blas_dusds(A,istat)
223       ! is equivalent to:
224       CALL duscr_begin(nr,nc,A,istat) ! here, 'd' must be retained for avoiding ambiguity
225       CALL ussp(A,blas_lower_symmetric,istat)
226       CALL uscr_insert_entries(A,nnz,VA,IA,JA,istat)
227       CALL uscr_end(A,istat)
228       CALL usmv(transT,alpha,A,X,incX,B,incB,istat)
229       CALL usds(A,istat)
230 \endcode
231 */
232 
233 /*
234  * External interface to our implementation.
235  *
236  * This is the only header file which should be included for using this library.
237  *
238  * It defines its API (Application Programming Interface).
239  * */
240 #ifndef RSB_RSB_H_INCLUDED
241 #define RSB_RSB_H_INCLUDED
242 
243 #ifdef __cplusplus
244 extern "C" {
245 #endif
246 
247 #include <stdlib.h>	/* size_t */
248 #if 0
249 #include <stdint.h>	/* uint16_t,..  */
250 #endif
251 
252 /*!
253  \name Type definitions
254  \anchor definitions_section
255 
256  These are definitions of \librsb base types.
257  */
258 /*!
259  * The block arrays index type.
260  *
261  * Could be an unsigned type.
262  * Should not overflow when indexing matrix blocks by block coordinates.
263  * */
264 typedef signed int rsb_blk_idx_t;
265 
266 /*!
267  * The coordinate arrays index type.
268  *
269  * Should not overflow when indexing matrix elements by coordinates.
270  * Legal values when specifying a matrix size should be within #RSB_MIN_MATRIX_DIM and #RSB_MAX_MATRIX_DIM
271  * */
272 typedef signed int rsb_coo_idx_t;
273 
274 /*!
275  * The nnz counter index type.
276  *
277  * Should not overflow when indexing matrix elements.
278  * On most common archs sizeof(long)>=sizeof(int).
279  * Legal values when specifying a matrix size should be within #RSB_MIN_MATRIX_NNZ and #RSB_MAX_MATRIX_NNZ
280  * */
281 typedef signed int rsb_nnz_idx_t;
282 
283 /* We would like the following typedefs to be long, but
284    they should be compatible with many int functions */
285 
286 /*!
287  A type for specifying matrix assembly or coordinate conversions option flags.
288  Should be >= 4 bytes.
289  See \ref flags_section for possible values.
290  */
291 typedef signed int rsb_flags_t;
292 
293 /*!
294  A type for specifying numerical type codes (See \ref matrix_type_symbols_section for a list of valid values).
295  */
296 typedef char rsb_type_t;
297 
298 /*!
299  A type specific for error flags.
300  Should be >= 4 bytes.
301 
302  A textual description of an error value may be obtained via #rsb_strerror_r() or #rsb_perror().
303  */
304 typedef signed int rsb_err_t; /* note that an unsigned would break the RSB_IS_COO_VALUE_MORE_THAN_HALF_BITS_LONG macros! */
305 
306 /*!
307  An integer type declaration for interface functions.
308  Should always be 'int'.
309  */
310 typedef signed    int rsb_int_t;		/*!< A signed integer type */
311 
312 /*! A boolean type. */
313 typedef rsb_flags_t rsb_bool_t;
314 
315 /*!
316  * The type for specifying transposition (See \ref matrix_transposition_flags_section)
317  */
318 typedef rsb_flags_t rsb_trans_t;
319 
320 /*!  A floating point numerical type.  */
321 typedef double rsb_real_t;
322 
323 /*!
324  A type for character strings.
325  */
326 typedef char rsb_char_t;
327 
328 /*!  A floating point numerical type for time measurements with #rsb_time().  */
329 typedef rsb_real_t rsb_time_t;
330 
331 /*!
332  \name Other constants
333 
334  Other constants for some typedefs.
335  */
336 #define RSB_BOOL_TRUE	1	/*!< A "true"  value for #rsb_bool_t. */
337 #define RSB_BOOL_FALSE	0 /*!< A "false" value for #rsb_bool_t. */
338 #define RSB_DO_FLAG_ADD(V,F)	(V) |=  (F)	/*!< The flag variable \c V gets the logical OR value with flag \c F. */
339 #define RSB_DO_FLAG_DEL(V,F)	(V) &= ~(F)	/*!< The flag variable \c V gets the logical NAND value with flag \c F. */
340 #define RSB_DO_FLAG_FILTEROUT(V,F)	((V) & ~(F))	/*!< The flag variable \c V after logical NAND value with flag \c F. */
341 #define RSB_DO_FLAG_FILTERONLY(V,F)	((V) & (F))	/*!< The flag variable \c V after logical AND value with flag \c F. */
342 #define RSB_DO_FLAG_HAS(V,F)	((((V)&(F))==(F))?RSB_BOOL_TRUE:RSB_BOOL_FALSE)	 /*!< Presence check for flag \c F. */
343 #define RSB_DO_FLAG_HAS_INTERSECTION(V,F)	(((V)&(F))?RSB_BOOL_TRUE:RSB_BOOL_FALSE)	/*!< Presence check for flag \c F.*/
344 
345 #define RSB_DEFAULT_ROW_BLOCKING 1	/*!< Reserved for future use. */
346 #define RSB_DEFAULT_COL_BLOCKING 1	/*!< Reserved for future use. */
347 #define RSB_DEFAULT_BLOCKING 1 /*!< A safe value for column blocking (reserved for future use). */
348 
349 /*  Macros to get indices types liminal values.  */
350 #define RSB_IS_SIGNED(T)   (((T)0) > (((T)-1)))
351 #define RSB_MAX_UNSIGNED(T) ((T)-1)
352 #define RSB_CHAR_BIT 8	/* bits per byte; if not 8, librsb compilation should fail */
353 #define RSB_HALF_MAX_SIGNED(T) ((T)1 << (sizeof(T)*RSB_CHAR_BIT-2))
354 #define RSB_MAX_SIGNED(T) (RSB_HALF_MAX_SIGNED(T) - 1 + RSB_HALF_MAX_SIGNED(T))
355 #define RSB_MAX_VALUE_FOR_TYPE(T) (RSB_IS_SIGNED(T)?RSB_MAX_SIGNED(T):RSB_MAX_UNSIGNED(T))
356 
357 #define RSB_MIN_MATRIX_DIM 0 /*!> Minimum allowed matrix dimension. */
358 #define RSB_MIN_MATRIX_NNZ 0 /*!> Minimum allowed matrix nonzeroes count. */
359 #define RSB_NNZ_BLK_MAX 255 /* Dense block maximal allowed size (still unused, for now internal) */
360 #define RSB_MAX_MATRIX_DIM (RSB_MAX_VALUE_FOR_TYPE(rsb_coo_idx_t)-RSB_NNZ_BLK_MAX-255) /*!> Maximum allowed matrix dimension. */
361 #define RSB_MAX_MATRIX_NNZ (RSB_MAX_VALUE_FOR_TYPE(rsb_nnz_idx_t)-RSB_NNZ_BLK_MAX) /*!> Maximum allowed matrix nonzeroes count. */
362 #define RSB_MARKER_COO_VALUE (RSB_MAX_MATRIX_DIM+1)		/* */
363 #define RSB_MARKER_NNZ_VALUE (RSB_MAX_MATRIX_NNZ+1)		/* */
364 #define RSB_INVALID_COO_IDX_VAL ((RSB_MARKER_COO_VALUE)+1)	/*< A value which is illegal for any #rsb_coo_idx_t variable. */
365 #define RSB_INVALID_NNZ_IDX_VAL ((RSB_MARKER_NNZ_VALUE)+1)	/*< A value which is illegal for any #rsb_nnz_idx_t variable. */
366 
367 /*! \anchor rsb_mtx_t  struct rsb_mtx_t declaration is in a separate, internal include file */
368 
369 /*!
370  \ingroup rsb_doc_rsb
371  \name Matrix assembly flags
372  \anchor flags_section
373 
374  These are flags which could be combined to specify the assembly of sparse matrices and in various matrix-related operations.
375  \n
376  If unsure what flags to use to a function, #RSB_FLAG_NOFLAGS shall be a good default in most cases.
377  */
378 /*!@{*/
379 
380 /*! Default storage flags. */
381 #define RSB_FLAG_DEFAULT_STORAGE_FLAGS		 	(RSB_FLAG_WANT_BCSS_STORAGE|RSB_FLAG_WANT_COO_STORAGE)
382 
383 /*! A flag combination specifying a pure COO matrix.  */
384 #define RSB_FLAG_DEFAULT_COO_MATRIX_FLAGS		 	RSB_FLAG_WANT_COO_STORAGE
385 
386 /*! A flag combination specifying a pure CSR matrix.  */
387 #define RSB_FLAG_DEFAULT_CSR_MATRIX_FLAGS		 	RSB_FLAG_WANT_BCSS_STORAGE
388 
389 /*! A flag combination specifying a pure RSB matrix.  */
390 #define RSB_FLAG_DEFAULT_RSB_MATRIX_FLAGS (RSB_FLAG_QUAD_PARTITIONING|RSB_FLAG_USE_HALFWORD_INDICES|RSB_FLAG_WANT_COO_STORAGE|RSB_FLAG_WANT_BCSS_STORAGE)
391 
392 /*! A flag combination specifying a matrix in a default, supported format.  */
393 #define RSB_FLAG_DEFAULT_MATRIX_FLAGS			RSB_FLAG_DEFAULT_RSB_MATRIX_FLAGS
394 
395 /*! The null (empty) flag. */
396 #define RSB_FLAG_NOFLAGS		 		0x000000
397 
398 /*! The identical flag (used in cloning function #rsb_mtx_clone). */
399 #define RSB_FLAG_IDENTICAL_FLAGS RSB_FLAG_NOFLAGS
400 
401 /*! If set, the input/output coordinate indices will be assumed to be 1 based. */
402 #define RSB_FLAG_FORTRAN_INDICES_INTERFACE		0x000001
403 
404 /*! If set, the input/output coordinate indices will be assumed to be 0 based (default). */
405 #define RSB_FLAG_C_INDICES_INTERFACE		0x000000
406 
407 /*! If set, the matrix will internally use a half word (16 bit) type for indices. */
408 #define RSB_FLAG_USE_HALFWORD_INDICES	0x000002
409 
410 /*! Used to specify multi-vector (dense matrix) operations. */
411 #define RSB_FLAG_WANT_ROW_MAJOR_ORDER 			0x000000
412 
413 /*! Used to specify multi-vector (dense matrix) operations. */
414 #define RSB_FLAG_WANT_COLUMN_MAJOR_ORDER 		0x4000000
415 
416 /*! If set, the code will assume the input nonzeroes as sorted.	*/
417 #define RSB_FLAG_SORTED_INPUT				0x000004
418 
419 /*! If set, the matrix is considered as triangular. \see #RSB_FLAG_LOWER,#RSB_FLAG_UPPER. */
420 #define RSB_FLAG_TRIANGULAR 				0x000008
421 
422 /*! If set, the matrix will be stored in as lower (triangular or symmetric). \see #RSB_FLAG_TRIANGULAR,#RSB_FLAG_SYMMETRIC,#RSB_FLAG_UPPER. */
423 #define RSB_FLAG_LOWER		 			0x000010
424 
425 /*! If set, the matrix will be stored in as upper (triangular or symmetric). \see #RSB_FLAG_LOWER*/
426 #define RSB_FLAG_UPPER		 			0x000020
427 
428 /*! If set, the (whole super-)matrix will not store the diagonal, which will be assumed to be unitary. */
429 #define RSB_FLAG_UNIT_DIAG_IMPLICIT			0x000040
430 
431 /* ghost flag ( moved in a non-public header, and reserved): 0x000080	*/
432 /* ghost flag ( moved in a non-public header, and reserved): 0x80000000	*/
433 
434 /*! If set, the matrix will use COO storage, where necessary. */
435 #define RSB_FLAG_WANT_COO_STORAGE		0x000100
436 
437 /*! Keep the last nonzero duplicate, at matrix assembly time. */
438 #define RSB_FLAG_DUPLICATES_KEEP_LAST				0x000000
439 
440 /*! The default nonzeroes duplicates handling.  */
441 #define RSB_FLAG_DUPLICATES_DEFAULT_HANDLE			0x000000
442 
443 /*! Compute and keep the sum of nonzero duplicates, at matrix assembly time.  */
444 #define RSB_FLAG_DUPLICATES_SUM				0x000200
445 
446 /*! If set, explicit zeros will not be inserted	\warning: this flag is active by default	*/
447 #define RSB_FLAG_DISCARD_ZEROS				0x000400
448 
449 /* ghost flag ( moved in a non-public header, and reserved): 0x000800 */
450 /* ghost flag ( moved in a non-public header, and reserved): 0x001000 */
451 
452 /*! If set, matrix will be organized as a quad tree of submatrices. */
453 #define RSB_FLAG_QUAD_PARTITIONING 			0x002000
454 
455 /*! If set, the block partitioning will be fixed (BCSS: BCSR or BCSC, but no VBR).	*/
456 #define RSB_FLAG_WANT_BCSS_STORAGE 			0x004000
457 
458 /* ghost flag ( moved in a non-public header, and reserved): 0x008000 */
459 /* ghost flag ( moved in a non-public header, and reserved): 0x010000 */
460 /* ghost flag ( moved in a non-public header, and reserved): 0x020000 */
461 
462 /*! If set, matrices will be fit in the three input coo arrays, after conversion. */
463 #define RSB_FLAG_ASSEMBLED_IN_COO_ARRAYS		0x040000
464 
465 /*! \internal \todo: should remove this. */
466 #define RSB_FLAG_EXPERIMENTAL_IN_PLACE_PERMUTATION_SORT	0x080000
467 
468 /* ghost flag ( moved in a non-public header, and reserved): 0x100000*/
469 /* ghost flag (temporarily reserved): 0x200000*/
470 
471 /*! If set, the input matrix will be treated as symmetric (stored as a lower triangular one by default). \see #RSB_FLAG_LOWER,#RSB_FLAG_LOWER. */
472 #define RSB_FLAG_SYMMETRIC 			0x400000
473 
474 /*! If set, the input matrix will be treated as symmetric hermitian (stored as a lower triangular one). \see #RSB_FLAG_LOWER,#RSB_FLAG_LOWER. */
475 #define RSB_FLAG_HERMITIAN 			0x800000
476 
477 /*! If set, recursion on small matrices will last at least the number of active threads. */
478 #define RSB_FLAG_RECURSIVE_MORE_LEAVES_THAN_THREADS	0x1000000
479 
480 /* ghost flag ( moved in a non-public header, and reserved): 0x2000000	*/
481 
482 /*! Combined flags for a lower hermitian matrix. */
483 #define RSB_FLAG_LOWER_HERMITIAN			(RSB_FLAG_HERMITIAN | RSB_FLAG_LOWER)
484 
485 /*! Combined flags for an upper hermitian matrix. */
486 #define RSB_FLAG_UPPER_HERMITIAN			(RSB_FLAG_HERMITIAN | RSB_FLAG_UPPER)
487 
488 /*! Combined flags for a lower triangular matrix. */
489 #define RSB_FLAG_LOWER_TRIANGULAR 			(RSB_FLAG_TRIANGULAR | RSB_FLAG_LOWER)
490 
491 /*! Combined flags for an upper triangular matrix. */
492 #define RSB_FLAG_UPPER_TRIANGULAR 			(RSB_FLAG_TRIANGULAR | RSB_FLAG_UPPER)
493 
494 /*! Combined flags for a symmetric, lower-stored matrix. */
495 
496 #define RSB_FLAG_LOWER_SYMMETRIC 			(RSB_FLAG_SYMMETRIC | RSB_FLAG_LOWER)
497 
498 /*! Combined flags for a diagonal matrix. */
499 #define RSB_FLAG_DIAGONAL 				(RSB_FLAG_UPPER | RSB_FLAG_LOWER)
500 
501 /*! Combined flags for a symmetric, upper-stored matrix. */
502 #define RSB_FLAG_UPPER_SYMMETRIC 			(RSB_FLAG_SYMMETRIC | RSB_FLAG_UPPER)
503 
504 /*! If set, the matrix will be subdivided at a finer grain on diagonal blocks. */
505 #define RSB_FLAG_RECURSIVE_SUBDIVIDE_MORE_ON_DIAG 	0x8000000
506 
507 /*! If set, the input COO arrays to the assembly functions will not be freed at matrix destruction time.
508   \warning Please do NOT use this flag, for the default memory allocation handling is still not specified. Instead, use the in place allocation functions: #rsb_mtx_alloc_from_csr_inplace() and #rsb_mtx_alloc_from_coo_inplace().
509  */
510 #define RSB_FLAG_EXTERNALLY_ALLOCATED_ARRAYS 		0x40000000
511 
512 /* Reserved, undocumented flags. Not for use. */
513 #define RSB_FLAG_USE_CSR_RESERVED	0x200000
514 
515 /*! \internal Combined flags for half word CSR. */
516 #define RSB_FLAG_USE_HALFWORD_INDICES_CSR	(RSB_FLAG_USE_HALFWORD_INDICES|RSB_FLAG_USE_CSR_RESERVED)
517 
518 /*! Combined flags for half word COO. */
519 #define RSB_FLAG_USE_HALFWORD_INDICES_COO	(RSB_FLAG_USE_HALFWORD_INDICES|RSB_FLAG_WANT_COO_STORAGE)
520 
521 /*! A combination of flags which is forbidden (so don't use it). */
522 #define RSB_FLAG_MUTUALLY_EXCLUSIVE_SWITCHES	(RSB_FLAG_USE_HALFWORD_INDICES_COO|RSB_FLAG_USE_HALFWORD_INDICES_CSR)
523 /*!@}*/
524 
525 
526 /*! A macro for the error code value. */
527 #define RSB_ERR_CAST(E) (-(E))
528 
529 /* Error handling functions. */
530 rsb_err_t rsb_strerror_r(rsb_err_t errval, rsb_char_t * buf, size_t buflen);
531 rsb_err_t rsb_perror(void *stream, rsb_err_t errval);
532 
533 /*! No error occurred (success). The return value that means function operation success, in most cases.   */
534 #define RSB_ERR_NO_ERROR		RSB_ERR_CAST(0x000)
535 
536 /*! An unspecified, generic error occurred. */
537 #define RSB_ERR_GENERIC_ERROR		RSB_ERR_CAST(0x001)
538 
539 /*! The user requested an operation which is not supported (e.g.: was opted out at build time). */
540 #define RSB_ERR_UNSUPPORTED_OPERATION	RSB_ERR_CAST(0x002)
541 
542 /*! The user requested to use a type which is not supported (e.g.: was opted out at build time). */
543 #define RSB_ERR_UNSUPPORTED_TYPE	RSB_ERR_CAST(0x004)
544 
545 /*! The user requested to use a matrix storage format which is not supported (e.g.: was opted out at build time). */
546 #define RSB_ERR_UNSUPPORTED_FORMAT	RSB_ERR_CAST(0x008)
547 
548 /*! An error occurred which is not apparently caused by a user's fault (internal error). */
549 #define RSB_ERR_INTERNAL_ERROR		RSB_ERR_CAST(0x010)
550 
551 /*! The user supplied some corrupt data as argument. */
552 #define RSB_ERR_BADARGS			RSB_ERR_CAST(0x020)
553 
554 /*! There is not enough dynamical memory to perform the requested operation. */
555 #define RSB_ERR_ENOMEM			RSB_ERR_CAST(0x040)
556 
557 /*! The requested operation was not implemented yet in this code revision (but probably will be, someday). */
558 #define RSB_ERR_UNIMPLEMENTED_YET	RSB_ERR_CAST(0x100)
559 
560 /*! The requested operation could not be executed, or index overflow will happen. */
561 #define RSB_ERR_LIMITS			RSB_ERR_CAST(0x200)
562 
563 /*! A Fortran specific error occurred. */
564 #define RSB_ERR_FORTRAN_ERROR		RSB_ERR_GENERIC_ERROR
565 
566 /*! The requested feature (e.g.:blocking) is not available because it was opted out or not configured at build time. */
567 #define RSB_ERR_UNSUPPORTED_FEATURE	RSB_ERR_CAST(0x400)
568 
569 /*! A file containing user set configuration was not present. */
570 #define RSB_ERR_NO_USER_CONFIGURATION	RSB_ERR_CAST(0x800)
571 
572 /*! User supplied data (e.g.: from file) was corrupt. */
573 #define RSB_ERR_CORRUPT_INPUT_DATA	RSB_ERR_CAST(0x1000)
574 
575 /*! Memory hierarchy info failed to be detected. You can bypass this by setting a meaningful \c RSB_USER_SET_MEM_HIERARCHY_INFO environment variable. */
576 #define RSB_ERR_FAILED_MEMHIER_DETECTION	RSB_ERR_CAST(0x2000)
577 
578 /*! User gave flags for an in place assembly in a copy-based function. */
579 #define RSB_ERR_COULD_NOT_HONOUR_EXTERNALLY_ALLOCATION_FLAGS	RSB_ERR_CAST(0x4000)
580 
581 /*! User requested writing to a file stream, while this feature is configured out. */
582 #define RSB_ERR_NO_STREAM_OUTPUT_CONFIGURED_OUT	RSB_ERR_CAST(0x8000)
583 
584 /*! User gave some input with invalid numerical data. */
585 #define RSB_ERR_INVALID_NUMERICAL_DATA	RSB_ERR_CAST(0x10000)
586 
587 /*! Probable memory leak (user did not deallocate librsb structures before calling rsb_lib_exit()). */
588 #define RSB_ERR_MEMORY_LEAK	RSB_ERR_CAST(0x20000)
589 
590 /*! Collation of "unsupported" type errors. */
591 #define RSB_ERRS_UNSUPPORTED_FEATURES	(RSB_ERR_UNSUPPORTED_FEATURE|RSB_ERR_NO_STREAM_OUTPUT_CONFIGURED_OUT)
592 
593 /*! Program success error code (int). */
594 #ifdef EXIT_SUCCESS
595 #define RSB_PROGRAM_SUCCESS	(EXIT_SUCCESS)
596 #else
597 #define RSB_PROGRAM_SUCCESS		(0)
598 #endif
599 
600 /*! Program error code (int). */
601 #ifdef EXIT_FAILURE
602 #define RSB_PROGRAM_ERROR		(EXIT_FAILURE)
603 #else
604 #define RSB_PROGRAM_ERROR		(-1)
605 #endif
606 
607 /*! Program error code (int). */
608 #define RSB_ERR_TO_PROGRAM_ERROR(E)	((E)==(RSB_ERR_NO_ERROR)?RSB_PROGRAM_SUCCESS:RSB_PROGRAM_ERROR)
609 
610 
611 /*! \ingroup rsb_doc_misc rsb_doc_rsb
612 \brief library option values for \see_lib_init_funcs. */
613 enum rsb_opt_t
614 {
615 /*! #RSB_IO_WANT_VERBOSE_INIT prompts for a verbose initialization of the library: messages will be written
616  * to the file descriptor (\c FILE*) pointed by the value pointer when calling \ref rsb_lib_init.
617  */
618   RSB_IO_WANT_VERBOSE_INIT =0x000001	/* (FILE*) */
619 ,
620 /*! #RSB_IO_WANT_VERBOSE_EXIT prompts for a verbose finalization of the library: messages will be written
621  * to the file descriptor (\c FILE*) pointed by the value pointer when calling \ref rsb_lib_exit.
622  */
623   RSB_IO_WANT_VERBOSE_EXIT =0x000002	/* (FILE*) */
624 ,
625 /*! Specifies the default output stream. Output (debug info) info will be written
626  * to the file descriptor (\c FILE*) pointed by the value pointer.
627  */
628   RSB_IO_WANT_OUTPUT_STREAM =0x000003	/* (FILE*) */
629 ,
630 /*! Specifies the default sorting method. Specified as a pointed integer (#rsb_int_t) number, in {[0],1}. (internal)
631  */
632   RSB_IO_WANT_SORT_METHOD =0x000004	/* (rsb_int_t) */
633 ,
634 /*! Specifies the default cache blocking method. Specified as a pointed integer (#rsb_int_t) number, in {-1,[0],1}. (internal)
635  */
636   RSB_IO_WANT_CACHE_BLOCKING_METHOD =0x000005	/* (rsb_int_t) */
637 ,
638 /*! Specifies a multiplier for finer (if >1.0) or coarser (if <1.0) subdivisions. Specified as a pointed (#rsb_real_t) number, in {..,[1.0],..}. (internal)
639  */
640   RSB_IO_WANT_SUBDIVISION_MULTIPLIER =0x000006	/* (rsb_real_t) */
641 ,
642 /*! Prompts for a verbose error reporting: messages will be written
643  * to the file descriptor (\c FILE*) pointed by the value pointer. Only meaningful if an
644  * interface error verbosity greater than 0 was set at configure time.
645  */
646   RSB_IO_WANT_VERBOSE_ERRORS =0x000007	/* (FILE*) */
647 ,
648 /*! Prompts for bounded box computation, for a smoother submatrices locking; pointed #rsb_int_t in {0,[1]}. (internal).
649  */
650   RSB_IO_WANT_BOUNDED_BOX_COMPUTATION =0x000008	/* (rsb_int_t) */
651 ,
652 /*! Specifies the number of desired executing threads; pointed #rsb_int_t in {[0],1,..}.
653  */
654   RSB_IO_WANT_EXECUTING_THREADS =0x000009	/* (rsb_int_t) */
655 ,
656 /*! Specifies the level of interface verbosity; if setting, pointed #rsb_int_t values should be in {[0],1,..}. Support may be enabled or disabled at build time via the \c --enable-internals-error-verbosity configure option. If disabled, only getting is supported and yields -1, but setting is not supported and the #RSB_ERR_NO_STREAM_OUTPUT_CONFIGURED_OUT error will be returned.
657  */
658   RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE =0x000010	/* (rsb_int_t) */
659 ,
660 /*! Specifies a custom memory hierarchy info string; pointed \c const #rsb_char_t*; (may point to a NULL string pointer).
661  */
662   RSB_IO_WANT_MEMORY_HIERARCHY_INFO_STRING =0x000011	/* (const rsb_char_t*) */
663 ,
664 /*! Used for getting whether the library has been initialized (#RSB_BOOL_TRUE) or not (#RSB_BOOL_FALSE) ; pointed \c const #rsb_bool_t*; (this is NOT for general users).
665  */
666   RSB_IO_WANT_IS_INITIALIZED_MARKER =0x000012	/* (const rsb_bool_t*) */
667 ,
668 /*! Used for getting the count of memory allocations performed by librsb employing librsb's memory allocation wrapper (if disabled, will return zero); pointed \c const \c size_t*; (this is for debugging purposes).
669  */
670   RSB_IO_WANT_MEM_ALLOC_CNT =0x000013	/* (const size_t*) */
671 ,
672 /*! Used for getting the total amount of memory allocated by librsb employing librsb's memory allocation wrapper (if disabled, will return zero); pointed \c const \c size_t*; (this is for debugging purposes).
673  */
674   RSB_IO_WANT_MEM_ALLOC_TOT =0x000014	/* (const size_t*) */
675 ,
676 /*! Specifies whether the default multi-vector ops shall act at a leaf level (default value of 0 is yes). Specified as a pointed integer (#rsb_int_t) number, in {-1,[0]}. (internal)
677  */
678   RSB_IO_WANT_LEAF_LEVEL_MULTIVEC =0x000015	/* (rsb_int_t) */
679 ,
680 /*! Specifies an upper limit to the count of allocated memory areas (default value of 0 means no limit). Specified as a pointed \c size_t. \rsb_configure_memwrap
681  */
682   RSB_IO_WANT_MAX_MEMORY_ALLOCATIONS =0x000016	/* (size_t) */
683 ,
684 /*! Specifies an upper limit to the amount of allocated memory (default value of 0 means no limit). Specified as a pointed \c size_t. \rsb_configure_memwrap
685  */
686   RSB_IO_WANT_MAX_MEMORY_ALLOCATED =0x000017	/* (size_t) */
687 ,
688 /*! Represents time spent in librsb. Specified as a pointed #rsb_time_t. Only works if statistics collection (\c --enable-librsb-stats) was specified at configure time.
689  */
690   RSB_IO_WANT_LIBRSB_ETIME =0x000018	/* (rsb_time_t) */
691 ,
692 /*! Auto tuning verbosity level for rsb_tune_spmm/rsb_tune_spsm. If 0, no verbosity; if 1, verbose; if 2, verbose with trace files being dumped.
693  */
694   RSB_IO_WANT_VERBOSE_TUNING =0x000019	/* (rsb_int_t) */
695 };
696 
697 /*! A handy macro for invoking #rsb_lib_reinit() with a single get/set specifier.
698  * An appropriate I/O flag is supplied as first parameter; a valid pointer (according to the flag) should be passed as second parameter; either #RSB_IO_SPECIFIER_SET or #RSB_IO_SPECIFIER_GET is passed as third parameter; a #rsb_err_t variable as fourth one, in order to detect any error.
699  * \deprecated	This macro has been deprecated and will be removed in a future version: use #rsb_lib_set_opt or #rsb_lib_get_opt instead.
700  * */
701 #define RSB_REINIT_SINGLE_VALUE(IOF,IOP,IOS,ERRVAL) { enum rsb_opt_t keys[]={IOF}; void*values[]={(IOP)}; struct rsb_initopts io; io.action=(IOS); io.keys=keys; io.values=values; io.n_pairs=1; ERRVAL=rsb_lib_reinit(&io); }
702 
703 /*! Like #RSB_REINIT_SINGLE_VALUE, but considering \c IOP \c const.
704  * \deprecated	This macro has been deprecated and will be removed in a future version: use #rsb_lib_set_opt instead.
705  * */
706 #define RSB_REINIT_SINGLE_VALUE_C_IOP(IOF,IOP,IOS,ERRVAL) { enum rsb_opt_t keys[]={IOF}; const void*values[]={(IOP)}; struct rsb_initopts io; io.action=(IOS); io.keys=keys; (io.values)=(void**)values; io.n_pairs=1; ERRVAL=rsb_lib_reinit(&io); }
707 
708 /*! A handy macro for invoking #RSB_REINIT_SINGLE_VALUE with a single set specifier.
709  * An appropriate I/O flag is supplied as first parameter; a valid pointer (according to the flag) should be passed as second parameter; a #rsb_err_t variable as third one, in order to detect any error.
710  * \deprecated	This macro has been deprecated and will be removed in a future version: use #rsb_lib_set_opt instead.
711  * */
712 #define RSB_REINIT_SINGLE_VALUE_SET(IOF,IOP,ERRVAL) RSB_REINIT_SINGLE_VALUE(IOF,IOP,RSB_IO_SPECIFIER_SET,ERRVAL)
713 
714 /*! A handy macro for invoking #RSB_REINIT_SINGLE_VALUE with a single get specifier.
715  * An appropriate I/O flag is supplied as first parameter; a valid pointer (according to the flag) should be passed as second parameter; a #rsb_err_t variable as third one, in order to detect any error.
716  * \deprecated	This macro has been deprecated and will be removed in a future version: use #rsb_lib_get_opt instead.
717  * */
718 #define RSB_REINIT_SINGLE_VALUE_GET(IOF,IOP,ERRVAL) RSB_REINIT_SINGLE_VALUE(IOF,IOP,RSB_IO_SPECIFIER_GET,ERRVAL)
719 
720 
721 /*!
722  * @brief A structure specifying library (initialization) options, to be used with the \ref rsb_lib_reinit() function.
723  * \n
724  *
725  * The structure specifies, for \c i=0,..,n_pairs-1 , a list of (key,value)
726  * pairs, stored respectively as (\c keys[i],values[i]).
727  * \n
728  * Each flag specifies the type and possible range of values it accepts.
729  * \n
730  * The structure may he used to set or query various library parameters.
731  *
732  * Example:
733  * \code
734  	const int max_io=10; // the number of different options we want to set
735 	struct rsb_initopts io={NULL,NULL,0,RSB_IO_SPECIFIER_SET},
736  	*iop=&io; // pointer to the options structure
737 	void * io_values[max_io]; // an array of pointers to max_io different option values (we shall set)
738 	enum rsb_opt_t io_keys[max_io]; // an array of max_io flag values specifying the type of values we are handing over to the library
739 	io.keys=io_keys; // io.keys will now point to io_keys as its keys array
740 	io.values=io_values; // io.values will now point to io_keys as its values array
741 	io.n_pairs=0; // we have 0 pairs specified so far
742 	io.keys[io.n_pairs]=RSB_IO_WANT_BOUNDED_BOX_COMPUTATION; // the first (at index 0) option we want to specify is RSB_IO_WANT_BOUNDED_BOX_COMPUTATION
743 	io.values[io.n_pairs]=1; // the value we want to set the RSB_IO_WANT_BOUNDED_BOX_COMPUTATION option to
744 	io.n_pairs++; // io.n_pairs is set to 1: we have one option set, so even if we have (max_io-io.n_pairs) left, only the first will be read
745 	... // we are free to specify other option (type, value) pairs
746  * \endcode
747  * */
748 struct rsb_initopts
749 {
750 	/*! An array of value types key flags. */
751 	enum rsb_opt_t * keys;
752 	/*! An array of value pointers, as specified by each flag value. */
753 	void ** values;
754 	/*! The length of the \c keys and \c values arrays. */
755 	rsb_int_t n_pairs;
756 	/*! The action we are requesting (either one of #RSB_IO_SPECIFIER_GET or #RSB_IO_SPECIFIER_SET)*/
757 	rsb_int_t action;
758 };
759 
760 #define RSB_IO_SPECIFIER_GET	1 /*!< Specifies to #RSB_REINIT_SINGLE_VALUE that a given #rsb_initopts is going to be get by the user. */
761 #define RSB_IO_SPECIFIER_SET	0 /*!< Specifies to #RSB_REINIT_SINGLE_VALUE that a given #rsb_initopts is going to be set by the user. */
762 #define RSB_NULL_INIT_OPTIONS NULL /*!<  A valid value for specifying default (null) options to #rsb_lib_init().  */
763 #define RSB_NULL_EXIT_OPTIONS NULL /*!<  A valid value for specifying default (null) options to #rsb_lib_exit().  */
764 
765 rsb_err_t rsb_lib_init(struct rsb_initopts * iop);
766 rsb_err_t rsb_lib_reinit(struct rsb_initopts * iop);
767 rsb_err_t rsb_lib_set_opt_str(const rsb_char_t* opnp, const rsb_char_t* opvp);
768 rsb_err_t rsb_lib_set_opt(enum rsb_opt_t iof, const void*iop);
769 rsb_err_t rsb_lib_get_opt(enum rsb_opt_t iof, void*iop);
770 rsb_err_t rsb_lib_exit(struct rsb_initopts * iop);
771 
772 struct rsb_mtx_t * rsb_mtx_alloc_from_coo_begin(rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_flags_t flagsA, rsb_err_t * errvalp);
773 rsb_err_t rsb_mtx_alloc_from_coo_end(struct rsb_mtx_t ** mtxApp);
774 struct rsb_mtx_t * rsb_mtx_alloc_from_csr_const(const void *VA, const rsb_coo_idx_t * RP, const rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp);
775 struct rsb_mtx_t * rsb_mtx_alloc_from_csc_const(const void *VA, const rsb_coo_idx_t * IA, const rsb_coo_idx_t * CP, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp);
776 struct rsb_mtx_t * rsb_mtx_alloc_from_csr_inplace(void * VA, rsb_nnz_idx_t * RP, rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp);
777 struct rsb_mtx_t * rsb_mtx_alloc_from_coo_const(const void *VA, const rsb_coo_idx_t * IA, const rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp);
778 struct rsb_mtx_t * rsb_mtx_alloc_from_coo_inplace(void *VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_type_t typecode, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA, rsb_blk_idx_t brA, rsb_blk_idx_t bcA, rsb_flags_t flagsA, rsb_err_t * errvalp );
779 rsb_err_t rsb_mtx_clone(struct rsb_mtx_t ** mtxBpp, rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_flags_t flags);
780 struct rsb_mtx_t * rsb_mtx_free(struct rsb_mtx_t * mtxAp);
781 
782 /*! \ingroup rsb_doc_misc rsb_doc_rsb
783  \brief Extraction filter flags, to be used with #rsb_mtx_get_nrm()/#rsb_mtx_get_vec(). */
784 enum rsb_extff_t
785 {
786   RSB_EXTF_NORM_ONE	=0x00001001			/*!< #rsb_mtx_get_nrm() flag value for computing the one-norm. */
787 , RSB_EXTF_NORM_TWO	=0x00001002			/*!< #rsb_mtx_get_nrm() flag value for computing the two-norm (Frobenius norm). */
788 , RSB_EXTF_NORM_INF	=0x00001003			/*!< #rsb_mtx_get_nrm() flag value for computing the infinity-norm. */
789 , RSB_EXTF_SUMS_ROW	=0x00001004			/*!< #rsb_mtx_get_vec() flag value for computing the sum along each row. */
790 , RSB_EXTF_SUMS_COL	=0x00001005			/*!< #rsb_mtx_get_vec() flag value for computing the sum along each column. */
791 , RSB_EXTF_ASUMS_ROW	=0x00001006			/*!< #rsb_mtx_get_vec() flag value for computing the absolute values sum, along each row. */
792 , RSB_EXTF_ASUMS_COL	=0x00001007			/*!< #rsb_mtx_get_vec() flag value for computing the absolute values sum, along each column. */
793 , RSB_EXTF_DIAG		=0x00000004			/*!< #rsb_mtx_get_vec() flag value for extracting the diagonal submatrix.*/
794 };
795 
796 typedef rsb_flags_t rsb_marf_t;					/*!< Matrix rendering flags (see \ref marf_section for possible values). */
797 /*!@{*/
798 /*!
799  \ingroup rsb_doc_rsb
800  \name Matrix rendering flags
801  \anchor marf_section
802 
803  These are flags which could be combined to specify rendering options to #rsb_mtx_rndr and #rsb_file_mtx_rndr.
804  */
805 #define RSB_MARF_RGB	0x00000001			/*!< #rsb_marf_t Flag value for requesting an RGB rendering of a matrix. */
806 #define RSB_MARF_EPS_S	0x00000010			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (spy plot). */
807 #define RSB_MARF_EPS_B	0x00000020			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (blocks plot). */
808 #define RSB_MARF_EPS	0x00000030			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (spy plot + blocks). */
809 #define RSB_MARF_EPS_L	0x00000070			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (spy plot + blocks + labels). */
810 /*!@}*/
811 
812 rsb_err_t rsb_mtx_get_nrm(const struct rsb_mtx_t * mtxAp , void * Np, enum rsb_extff_t flags);
813 #define rsb_mtx_get_norm rsb_mtx_get_nrm /*!< \deprecated #rsb_mtx_get_norm has been deprecated: use #rsb_mtx_get_nrm . */
814 rsb_err_t rsb_mtx_get_vec(const struct rsb_mtx_t * mtxAp , void * Dp, enum rsb_extff_t flags);
815 rsb_err_t rsb_mtx_rndr(const rsb_char_t * filename, const struct rsb_mtx_t*mtxAp, rsb_coo_idx_t pmWidth, rsb_coo_idx_t pmHeight, rsb_marf_t rflags);
816 rsb_err_t rsb_file_mtx_rndr(void * pmp, const rsb_char_t * filename, rsb_coo_idx_t pmlWidth, rsb_coo_idx_t pmWidth, rsb_coo_idx_t pmHeight, rsb_marf_t rflags);
817 #define rsb_file_mtx_render rsb_file_mtx_rndr /*!< \deprecated #rsb_file_mtx_render has been deprecated: use #rsb_file_mtx_rndr. */
818 
819 rsb_err_t rsb_spmv(rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, const void * Xp, rsb_coo_idx_t incX, const void * betap, void * Yp, rsb_coo_idx_t incY);
820 rsb_err_t rsb_spmm(rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * Bp, rsb_nnz_idx_t ldB, const void * betap, void * Cp, rsb_nnz_idx_t ldC);
821 rsb_err_t rsb_spsv(rsb_trans_t transT, const void * alphap, const struct rsb_mtx_t * mtxTp, const void * Xp, rsb_coo_idx_t incX, void * Yp, rsb_coo_idx_t incY);
822 rsb_err_t rsb_spsm(rsb_trans_t transT, const void * alphap, const struct rsb_mtx_t * mtxTp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * betap, const void * Bp, rsb_nnz_idx_t ldB, void * Cp, rsb_nnz_idx_t ldC);
823 
824 rsb_err_t rsb_mtx_add_to_dense(const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_nnz_idx_t ldB, rsb_nnz_idx_t nrB, rsb_nnz_idx_t ncB, rsb_bool_t rowmajorB, void * Bp);
825 
826 struct rsb_mtx_t * rsb_sppsp(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_trans_t transB, const void *betap, const struct rsb_mtx_t * mtxBp, rsb_err_t * errvalp);
827 struct rsb_mtx_t * rsb_spmsp(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_trans_t transB, const void *betap, const struct rsb_mtx_t * mtxBp, rsb_err_t * errvalp);
828 rsb_err_t rsb_spmsp_to_dense(rsb_type_t typecode, rsb_trans_t transA, const void *alphap, const struct rsb_mtx_t * mtxAp, rsb_trans_t transB, const void *betap, const struct rsb_mtx_t * mtxBp , rsb_nnz_idx_t ldC, rsb_nnz_idx_t nrC, rsb_nnz_idx_t ncC, rsb_bool_t rowmajorC, void *Cp);
829 
830 rsb_err_t rsb_mtx_switch_to_coo(struct rsb_mtx_t * mtxAp, void ** VAp, rsb_coo_idx_t ** IAp, rsb_coo_idx_t ** JAp, rsb_flags_t flags);
831 rsb_err_t rsb_mtx_switch_to_csr(struct rsb_mtx_t * mtxAp, void ** VAp, rsb_coo_idx_t ** IAp, rsb_coo_idx_t ** JAp, rsb_flags_t flags);
832 rsb_err_t rsb_mtx_get_coo(const struct rsb_mtx_t * mtxAp, void * VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_flags_t flags );
833 rsb_err_t rsb_mtx_get_csr(rsb_type_t typecode, const struct rsb_mtx_t * mtxAp, void * VA, rsb_nnz_idx_t * RP, rsb_coo_idx_t * JA, rsb_flags_t flags );
834 rsb_err_t rsb_mtx_get_rows_sparse(rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, void* VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_coo_idx_t frA, rsb_coo_idx_t lrA, rsb_nnz_idx_t *rnzp, rsb_flags_t flags );
835 rsb_err_t rsb_mtx_get_coo_block(const struct rsb_mtx_t * mtxAp, void* VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_coo_idx_t frA, rsb_coo_idx_t lrA, rsb_coo_idx_t fcA, rsb_coo_idx_t lcA, const rsb_coo_idx_t * IREN, const rsb_coo_idx_t * JREN, rsb_nnz_idx_t *rnzp, rsb_flags_t flags );
836 
837 /*! \ingroup rsb_doc_misc rsb_doc_rsb
838 \brief Flags for getting matrix information via #rsb_mtx_get_info()/#rsb_mtx_get_info_str().
839 */
840 enum rsb_mif_t
841 {
842   RSB_MIF_INDEX_STORAGE_IN_BYTES__TO__SIZE_T		=0x00000001	/*!< Index storage occupation, in bytes. (size_t) */
843 , RSB_MIF_INDEX_STORAGE_IN_BYTES_PER_NNZ__TO__RSB_REAL_T	=0x00000002	/*!< Index storage occupation per nnz, in bytes. (#rsb_real_t) */
844 , RSB_MIF_MATRIX_ROWS__TO__RSB_COO_INDEX_T		=0x00000004	/*!< Rows count(#rsb_coo_idx_t) */
845 , RSB_MIF_MATRIX_COLS__TO__RSB_COO_INDEX_T		=0x00000008	/*!< Columns count (#rsb_coo_idx_t) */
846 , RSB_MIF_MATRIX_NNZ__TO__RSB_NNZ_INDEX_T		=0x00000010	/*!< Nonzeroes count (#rsb_nnz_idx_t) */
847 , RSB_MIF_TOTAL_SIZE__TO__SIZE_T			=0x00000020	/*!< Total size, in bytes (size_t) */
848 , RSB_MIF_MATRIX_FLAGS__TO__RSB_FLAGS_T			=0x00000040	/*!< Matrix flags (#rsb_flags_t) */
849 , RSB_MIF_MATRIX_TYPECODE__TO__RSB_TYPE_T		=0x00000080	/*!< Matrix type code (#rsb_type_t) */
850 , RSB_MIF_MATRIX_INFO__TO__CHAR_P			=0x00000100	/*!< Matrix info string, only for #rsb_mtx_get_info_str() (#rsb_char_t*) */
851 , RSB_MIF_LEAVES_COUNT__TO__RSB_BLK_INDEX_T		=0x00000200	/*!< Leaf submatrices count (#rsb_blk_idx_t) */
852 };
853 rsb_err_t rsb_mtx_get_info(const struct rsb_mtx_t *mtxAp, enum rsb_mif_t miflags, void* minfop);
854 rsb_err_t rsb_mtx_get_info_str(const struct rsb_mtx_t *mtxAp, const rsb_char_t *mis, void* minfop, size_t buflen);
855 
856 /*! \ingroup rsb_doc_misc rsb_doc_rsb
857 \brief Flags for specifying a particular elemental/row-wise operation with #rsb_mtx_upd_vals(). */
858 enum rsb_elopf_t
859 {
860   RSB_ELOPF_MUL		=0x00000001		/*!< Elemental multiplication of the matrix by a specified scalar (usable with #rsb_mtx_upd_vals(), binary operation). */
861 , RSB_ELOPF_DIV		=0x00000002		/*!< Elemental division by a specified scalar (usable with #rsb_mtx_upd_vals(), binary operation). */
862 , RSB_ELOPF_POW		=0x00000004		/*!< Elemental power to a specified scalar (usable with #rsb_mtx_upd_vals(), binary operation). */
863 , RSB_ELOPF_NEG		=0x00000008		/*!< Elemental negation (usable with #rsb_mtx_upd_vals(), unary operation). */
864 , RSB_ELOPF_SCALE_ROWS	=0x00000010		/*!< Row    wise scaling by a specified scaling vector (usable with #rsb_mtx_upd_vals(), binary operation). */
865 , RSB_ELOPF_SCALE_COLS	=0x00000020		/*!< Column wise scaling by a specified scaling vector (usable with #rsb_mtx_upd_vals(), binary operation). */
866 , RSB_ELOPF_SCALE_ROWS_REAL	=0x00000040	/*!< Row    wise scaling by a specified scaling vector. If matrix is of a complex type, the argument is expected to be of the corresponding real type (assumed that that type has been enabled). (usable with #rsb_mtx_upd_vals(), binary operation). */
867 , RSB_ELOPF_SCALE_COLS_REAL	=0x00000080	/*!< Column wise scaling by a specified scaling vector. If matrix is of a complex type, the argument is expected to be of the corresponding real type (assumed that that type has been enabled). (usable with #rsb_mtx_upd_vals(), binary operation). */
868 };
869 
870 rsb_err_t rsb_mtx_upd_vals(struct rsb_mtx_t * mtxAp, enum rsb_elopf_t elop_flags, const void * omegap);
871 #define rsb_mtx_upd_values rsb_mtx_upd_vals /*!< \deprecated #rsb_mtx_upd_values has been deprecated: use #rsb_mtx_upd_vals. */
872 typedef rsb_flags_t rsb_precf_t;	/*!< Basic preconditioner flags to be used with #rsb_mtx_get_prec(). */
873 #define RSB_PRECF_ILU0		0x00000001		/*!< ILU-0 preconditioner request to #rsb_mtx_get_prec(). */
874 rsb_err_t rsb_mtx_get_prec(void *opdp, const struct rsb_mtx_t * mtxAp, rsb_precf_t prec_flags, const void *ipdp);
875 #define rsb_mtx_get_preconditioner rsb_mtx_get_prec 	/*!< \deprecated #rsb_mtx_get_preconditioner has been deprecated: use #rsb_mtx_get_prec. */
876 rsb_err_t rsb_mtx_set_vals(struct rsb_mtx_t * mtxAp, const void * VA, const rsb_coo_idx_t *IA, const rsb_coo_idx_t *JA, rsb_nnz_idx_t nnz, rsb_flags_t flags);
877 #define rsb_mtx_set_values rsb_mtx_set_vals /*!< \deprecated #rsb_mtx_set_values has been deprecated: use #rsb_mtx_set_vals. */
878 rsb_err_t rsb_mtx_get_vals(const struct rsb_mtx_t * mtxAp, void * VA, const rsb_coo_idx_t *IA, const rsb_coo_idx_t *JA, rsb_nnz_idx_t nnz, rsb_flags_t flags);
879 #define rsb_mtx_get_values rsb_mtx_get_vals /*!< \deprecated #rsb_mtx_get_values has been deprecated: use #rsb_mtx_get_vals. */
880 rsb_err_t rsb_tune_spmm(struct rsb_mtx_t ** mtxOpp, rsb_real_t *sfp, rsb_int_t *tnp, rsb_int_t maxr, rsb_time_t maxt, rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * Bp, rsb_nnz_idx_t ldB, const void * betap, void * Cp, rsb_nnz_idx_t ldC);
881 rsb_err_t rsb_tune_spsm(struct rsb_mtx_t ** mtxOpp, rsb_real_t *sfp, rsb_int_t *tnp, rsb_int_t maxr, rsb_time_t maxt, rsb_trans_t transA, const void * alphap, const struct rsb_mtx_t * mtxAp, rsb_coo_idx_t nrhs, rsb_flags_t order, const void * Bp, rsb_nnz_idx_t ldB, const void * betap, void * Cp, rsb_nnz_idx_t ldC);
882 rsb_trans_t rsb_psblas_trans_to_rsb_trans(const char psbtrans);
883 rsb_err_t rsb_file_mtx_save(const struct rsb_mtx_t * mtxAp, const rsb_char_t * filename);
884 struct rsb_mtx_t * rsb_file_mtx_load(const rsb_char_t * filename, rsb_flags_t flagsA, rsb_type_t typecode, rsb_err_t *errvalp);
885 rsb_err_t rsb_file_vec_load(const rsb_char_t * filename, rsb_type_t typecode, void * Yp, rsb_coo_idx_t *yvlp);
886 rsb_err_t rsb_file_vec_save(const rsb_char_t * filename, rsb_type_t typecode, const void * Yp, rsb_coo_idx_t yvl);
887 rsb_err_t rsb_file_mtx_get_dims(const rsb_char_t * filename, rsb_coo_idx_t* nrp, rsb_coo_idx_t *ncp, rsb_coo_idx_t *nzp, rsb_flags_t*flagsp);
888 #define rsb_file_mtx_get_dimensions rsb_file_mtx_get_dims /*!< \deprecated #rsb_file_mtx_get_dimensions has been deprecated: use #rsb_file_mtx_get_dims. */
889 rsb_err_t rsb_coo_sort(void *VA, rsb_coo_idx_t * IA, rsb_coo_idx_t * JA, rsb_nnz_idx_t nnzA, rsb_coo_idx_t nrA, rsb_coo_idx_t ncA,  rsb_type_t typecode, rsb_flags_t flagsA );
890 rsb_time_t rsb_time(void);
891 
892 /*! \internal
893  NOTE: user programs should never include explicitly rsb_types.h.
894  */
895 #ifndef RSB_WANT_NO_RSB_TYPES_H
896 #include "rsb_types.h"
897 #endif /* RSB_WANT_NO_RSB_TYPES_H */
898 
899 /*! \ingroup rsb_doc_misc rsb_doc_rsb
900  Use #RSB_SIZEOF macro to get the size (in bytes) of a type supported by the library (e.g.: when allocating numerical vectors).
901  */
902 #define RSB_SIZEOF(TYPE) RSB_NUMERICAL_TYPE_SIZE(TYPE)
903 
904 #ifdef __cplusplus
905 }
906 #endif  /* __cplusplus */
907 
908 #endif	/* RSB_RSB_H_INCLUDED */
909