This file is indexed.

/usr/include/rsb.h is in librsb-dev 1.2.0-rc7-5.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
/*                                                                                                                            

Copyright (C) 2008-2015 Michele Martone

This file is part of librsb.

librsb is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published
by the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

librsb is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
License for more details.

You should have received a copy of the GNU Lesser General Public
License along with librsb; see the file COPYING.
If not, see <http://www.gnu.org/licenses/>.

*/
/*! 
 *  \file
 *  \brief  This file declares the user interface functions and data structures for the \librsb library.
 *  \author Michele Martone
 * */
/*!
 \mainpage
 
 A sparse matrix library implementing the `Recursive Sparse Blocks' (\b RSB) matrix storage.

 
 This is the documentation for the application programming interface (API)
 of the \e `\librsb' library.
 \n
 In order to use \librsb, there is no need for the user to know the RSB
 layout and algorithms: this documentation should be sufficient.
 \n
 This library is dual-interfaced; it supports:
 a native (`RSB') interface (with identifiers prefixed by `rsb_' or `RSB_'),
 and a (mostly complete) Sparse BLAS interface, as a wrapper around the RSB interface.
 \n
 Many computationally intensive operations are implemented with thread
 parallelism, by using OpenMP.
 \n
 Thread parallelism can be turned off at configure time, if desired, or limited
 at execution time.
 \n
 Many of the computational kernels source code files (mostly internals) were
 automatically generated.
 \n
 This user documentation concerns the end user API only; that is, neither the
 internals, nor the code generator.
 \n
 
 You should consult the remaining documentation (e.g. the README file, code 
 comments) to find information about how to modify the generator or the 
 library internals.

 This library is research software and as such, still \b experimental.  
 For a first approach, we suggest to go through the \ref rsb_doc_examples  documentation
 section, or the \ref examples_section "quick start examples" section on this page.
 
 \n
 Information about the supported matrix types and matrix operations 
 resides in the \link rsb_types.h rsb_types.h \endlink file. 

 A C/C++ user can use the native API of RSB by including the \link rsb.h rsb.h \endlink header.
 The same interface is available in Fortran via the ISO C Binding interface, specified in \link rsb.F90 rsb.F90\endlink.
 \n
 
 The C header file for the \ref rsb_doc_sparse_blas  is \link blas_sparse.h blas_sparse.h\endlink.

 \author Michele Martone < michelemartone AT users DOT sourceforge DOT net >
 
 Contents of the README file :
 \verbinclude README

 \anchor examples_section 

 For a quick startup, consider the following two programs.

 The first, using the internal RSB interface:
 \include examples/hello.c

 And the second, using the Sparse BLAS interface:
 \include examples/hello-spblas.c

 For more, see the \ref rsb_doc_examples  section.

 */

/*!
 \defgroup rsb_doc_rsb The librsb library interface (rsb.h, rsb.F90)
 \brief
 The reference documentation of the \librsb library comes in both HTML and Unix man pages formats.
 The following sections/man pages are available: \ref rsb_doc_rsb ; \ref rsb_doc_sparse_blas ; \ref rsb_doc_examples.


 In general, users of this library are interested in high performance sparse matrix computations on cache based shared memory parallel computers.
 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).

 Configuration, build, and installation instructions are contained in the \c README file distributed in the sources archive.

 <b> Typical program structure </b>

 \li initialize \librsb with #rsb_lib_init()
 \li (in any order)
      allocate matrices (e.g.: with #rsb_mtx_alloc_from_coo_inplace() or others);
      do any computation with them (e.g.: #rsb_spmv(), #rsb_spsv() );
      converting matrices (e.g.: with #rsb_mtx_switch_to_coo() );
      freeing matrices (#rsb_mtx_free() )
 \li finalize \librsb with #rsb_lib_exit()


 <b> Important usage notes </b>

 <b> General program structure </b>
 Before calling any \librsb function, a program is required to initialize \librsb's internal status.
 This is done by calling #rsb_lib_init() .
 Afterwards, any \librsb function can be safely used.
 When \librsb functions are not intended to be called anymore, a program may call #rsb_lib_exit() to free any resource.
 Then, #rsb_lib_init() should be called for further usage of \librsb.

 <b> Manipulating matrices and vectors </b>
 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.
 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.

 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.
 Computational functions treat dense vectors/matrices are simple arrays of a specified type; see the \ref rsb_doc_examples  .

 <b> Computational functions </b>
 This library can be configured at build time to support a custom subset of numerical types.
 To keep the programming interface compact, it has been decided to not replicate the computational functions to each numerical type.
 Instead, the type is expected to be specified by the user via a type flag. 
 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.
 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, ...).
 Mixed type operations are currently not supported.


 <b> Memory management </b>

 Matrix structures (\c rsb_mtx_t) allocated by \librsb shall be freed only via #rsb_mtx_free() .

 <b> Benchmarking </b>

 If you want to benchmark this library, there are different possibilities:
 \include ./examples/benchex.sh

 <b> Tuning and Customization </b>
 
 There are different \c ./configure  options you may look at for tuning or customizing the library.



 \defgroup rsb_doc_examples	Example programs and code 
 \brief	Examples of usage of \librsb.

 	The following fully working example programs illustrate correct ways of using the library.
	The script displayed here should be sufficient to build them.
 \include examples/make.sh

 \include examples/hello.c
 \include examples/hello-spblas.c
 \include examples/hello-spblas.c
 \include examples/autotune.c
 \include examples/io-spblas.c
 \include examples/transpose.c
 \include examples/power.c
 \include examples/fortran.F90
 \include examples/fortran_rsb_fi.F90
*/

/*!
 \defgroup rsb_doc_sparse_blas The Sparse BLAS interface to librsb (blas_sparse.h, rsb_blas_sparse.F90) 
 \brief
 	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.

We also implement a number of useful extra functions as custom extensions, giving access to other \librsb functionality.

The usage pattern of this interface matches that of the Sparse BLAS standard, exception made for the necessity of initialization/finalization of \librsb.
The Sparse BLAS interface is also available for Fortran: see \ref rsb_blas_sparse.F90.


The user should be aware of the following:
\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.
\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).
\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.
\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.
\li According to the standard, VBR and BCSR styled constructors are supported, although these are interfaces for \librsb's own matrix representation.
\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.
\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).
We will provide a proper fix to this inconvenience in a subsequent release.
\li Each Fortran program using \librsb's Sparse BLAS Implementation shall \c use  modules \c blas_sparse  and \c rsb.
\li Also Fortran programs have to call #rsb_lib_init() and #rsb_lib_exit() e.g.:
\verbatim
       	USE blas_sparse             ! module implementing the Sparse BLAS on the top of librsb
       	USE rsb                     ! rsb module
	...
	INTEGER :: istat            ! integer variable
	...
       	istat = rsb_lib_init(RSB_NULL_INIT_OPTIONS) ! please note that this is not part of Sparse BLAS but it is needed by librsb
	if(istat.NE.0)STOP          ! a value different than zero signals an error
	...
	! code calling Sparse BLAS routines
	...
       	istat = rsb_lib_exit(RSB_NULL_EXIT_OPTIONS) ! please note that this is not part of Sparse BLAS but it is needed by librsb
	if(istat.NE.0)STOP          ! a value different than zero signals an error
	...
\endverbatim
	\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.
	Please note how not all of the certain procedures identifier prefixes include the type character. 

	E.g.:
\code
      ! the following code ('d' stays for 'double precision'):
      CALL blas_duscr_begin(nr,nc,A,istat)
      CALL blas_ussp(A,blas_lower_symmetric,istat)
      CALL blas_duscr_insert_entries(A,nnz,VA,IA,JA,istat)
      CALL blas_duscr_end(A,istat)
      CALL blas_dusmv(transT,alpha,A,X,incX,B,incB,istat) 
      CALL blas_dusds(A,istat)
      ! is equivalent to:
      CALL duscr_begin(nr,nc,A,istat) ! here, 'd' must be retained for avoiding ambiguity
      CALL ussp(A,blas_lower_symmetric,istat)
      CALL uscr_insert_entries(A,nnz,VA,IA,JA,istat)
      CALL uscr_end(A,istat)
      CALL usmv(transT,alpha,A,X,incX,B,incB,istat) 
      CALL usds(A,istat)
\endcode
*/

/*
 * External interface to our implementation.
 *
 * This is the only header file which should be included for using this library.
 *
 * It defines its API (Application Programming Interface).
 * */
#ifndef RSB_RSB_H_INCLUDED
#define RSB_RSB_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

#include <stdlib.h>	/* size_t */
#if 0
#include <stdint.h>	/* uint16_t,..  */
#endif

/*!
 \name Type definitions
 \anchor definitions_section

 These are definitions of \librsb base types.
 */
/*!
 * The block arrays index type. 
 *
 * Could be an unsigned type.
 * Should not overflow when indexing matrix blocks by block coordinates.
 * */
typedef signed int rsb_blk_idx_t;

/*!
 * The coordinate arrays index type.
 *
 * Should not overflow when indexing matrix elements by coordinates.
 * Legal values when specifying a matrix size should be within #RSB_MIN_MATRIX_DIM and #RSB_MAX_MATRIX_DIM 
 * */
typedef signed int rsb_coo_idx_t;

/*!
 * The nnz counter index type.
 *
 * Should not overflow when indexing matrix elements.
 * On most common archs sizeof(long)>=sizeof(int).
 * Legal values when specifying a matrix size should be within #RSB_MIN_MATRIX_NNZ and #RSB_MAX_MATRIX_NNZ 
 * */
typedef signed int rsb_nnz_idx_t;	

/* We would like the following typedefs to be long, but
   they should be compatible with many int functions */

/*!
 A type for specifying matrix assembly or coordinate conversions option flags.
 Should be >= 4 bytes.
 See \ref flags_section for possible values.
 */
typedef signed int rsb_flags_t;

/*!
 A type for specifying numerical type codes (See \ref matrix_type_symbols_section for a list of valid values).
 */
typedef char rsb_type_t;

/*!
 A type specific for error flags.
 Should be >= 4 bytes.

 A textual description of an error value may be obtained via #rsb_strerror_r() or #rsb_perror().
 */
typedef signed int rsb_err_t; /* note that an unsigned would break the RSB_IS_COO_VALUE_MORE_THAN_HALF_BITS_LONG macros! */

/*!
 An integer type declaration for interface functions.
 Should always be 'int'.
 */
typedef signed    int rsb_int_t;		/*!< A signed integer type */

/*! A boolean type. */
typedef rsb_flags_t rsb_bool_t;

/*!
 * The type for specifying transposition (See \ref matrix_transposition_flags_section)
 */
typedef rsb_flags_t rsb_trans_t;

/*!  A floating point numerical type.  */
typedef double rsb_real_t;

/*!
 A type for character strings.
 */
typedef char rsb_char_t;

/*!  A floating point numerical type for time measurements with #rsb_time().  */
typedef rsb_real_t rsb_time_t;

/*!
 \name Other constants

 Other constants for some typedefs.
 */
#define RSB_BOOL_TRUE	1	/*!< A "true"  value for #rsb_bool_t. */
#define RSB_BOOL_FALSE	0 /*!< A "false" value for #rsb_bool_t. */
#define RSB_DO_FLAG_ADD(V,F)	(V) |=  (F)	/*!< The flag variable \c V gets the logical OR value with flag \c F. */
#define RSB_DO_FLAG_DEL(V,F)	(V) &= ~(F)	/*!< The flag variable \c V gets the logical NAND value with flag \c F. */
#define RSB_DO_FLAG_FILTEROUT(V,F)	((V) & ~(F))	/*!< The flag variable \c V after logical NAND value with flag \c F. */
#define RSB_DO_FLAG_FILTERONLY(V,F)	((V) & (F))	/*!< The flag variable \c V after logical AND value with flag \c F. */
#define RSB_DO_FLAG_HAS(V,F)	((((V)&(F))==(F))?RSB_BOOL_TRUE:RSB_BOOL_FALSE)	 /*!< Presence check for flag \c F. */
#define RSB_DO_FLAG_HAS_INTERSECTION(V,F)	(((V)&(F))?RSB_BOOL_TRUE:RSB_BOOL_FALSE)	/*!< Presence check for flag \c F.*/

#define RSB_DEFAULT_ROW_BLOCKING 1	/*!< Reserved for future use. */
#define RSB_DEFAULT_COL_BLOCKING 1	/*!< Reserved for future use. */
#define RSB_DEFAULT_BLOCKING 1 /*!< A safe value for column blocking (reserved for future use). */

/*  Macros to get indices types liminal values.  */
#define RSB_IS_SIGNED(T)   (((T)0) > (((T)-1)))
#define RSB_MAX_UNSIGNED(T) ((T)-1)
#define RSB_CHAR_BIT 8	/* bits per byte; if not 8, librsb compilation should fail */
#define RSB_HALF_MAX_SIGNED(T) ((T)1 << (sizeof(T)*RSB_CHAR_BIT-2))
#define RSB_MAX_SIGNED(T) (RSB_HALF_MAX_SIGNED(T) - 1 + RSB_HALF_MAX_SIGNED(T))
#define RSB_MAX_VALUE_FOR_TYPE(T) (RSB_IS_SIGNED(T)?RSB_MAX_SIGNED(T):RSB_MAX_UNSIGNED(T))

#define RSB_MIN_MATRIX_DIM 0 /*!> Minimum allowed matrix dimension. */
#define RSB_MIN_MATRIX_NNZ 0 /*!> Minimum allowed matrix nonzeroes count. */
#define RSB_NNZ_BLK_MAX 255 /* Dense block maximal allowed size (still unused, for now internal) */
#define RSB_MAX_MATRIX_DIM (RSB_MAX_VALUE_FOR_TYPE(rsb_coo_idx_t)-RSB_NNZ_BLK_MAX-255) /*!> Maximum allowed matrix dimension. */
#define RSB_MAX_MATRIX_NNZ (RSB_MAX_VALUE_FOR_TYPE(rsb_nnz_idx_t)-RSB_NNZ_BLK_MAX) /*!> Maximum allowed matrix nonzeroes count. */
#define RSB_MARKER_COO_VALUE (RSB_MAX_MATRIX_DIM+1)		/* */
#define RSB_MARKER_NNZ_VALUE (RSB_MAX_MATRIX_NNZ+1)		/* */
#define RSB_INVALID_COO_IDX_VAL ((RSB_MARKER_COO_VALUE)+1)	/*< A value which is illegal for any #rsb_coo_idx_t variable. */
#define RSB_INVALID_NNZ_IDX_VAL ((RSB_MARKER_NNZ_VALUE)+1)	/*< A value which is illegal for any #rsb_nnz_idx_t variable. */

/*! \anchor rsb_mtx_t  struct rsb_mtx_t declaration is in a separate, internal include file */

/*!
 \ingroup rsb_doc_rsb
 \name Matrix assembly flags
 \anchor flags_section

 These are flags which could be combined to specify the assembly of sparse matrices and in various matrix-related operations.
 \n
 If unsure what flags to use to a function, #RSB_FLAG_NOFLAGS shall be a good default in most cases.
 */
/*!@{*/

/*! Default storage flags. */
#define RSB_FLAG_DEFAULT_STORAGE_FLAGS		 	(RSB_FLAG_WANT_BCSS_STORAGE|RSB_FLAG_WANT_COO_STORAGE)

/*! A flag combination specifying a pure COO matrix.  */
#define RSB_FLAG_DEFAULT_COO_MATRIX_FLAGS		 	RSB_FLAG_WANT_COO_STORAGE 

/*! A flag combination specifying a pure CSR matrix.  */
#define RSB_FLAG_DEFAULT_CSR_MATRIX_FLAGS		 	RSB_FLAG_WANT_BCSS_STORAGE

/*! A flag combination specifying a pure RSB matrix.  */
#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)

/*! A flag combination specifying a matrix in a default, supported format.  */
#define RSB_FLAG_DEFAULT_MATRIX_FLAGS			RSB_FLAG_DEFAULT_RSB_MATRIX_FLAGS

/*! The null (empty) flag. */
#define RSB_FLAG_NOFLAGS		 		0x000000

/*! The identical flag (used in cloning function #rsb_mtx_clone). */
#define RSB_FLAG_IDENTICAL_FLAGS RSB_FLAG_NOFLAGS

/*! If set, the input/output coordinate indices will be assumed to be 1 based. */
#define RSB_FLAG_FORTRAN_INDICES_INTERFACE		0x000001

/*! If set, the input/output coordinate indices will be assumed to be 0 based (default). */
#define RSB_FLAG_C_INDICES_INTERFACE		0x000000

/*! If set, the matrix will internally use a half word (16 bit) type for indices. */
#define RSB_FLAG_USE_HALFWORD_INDICES	0x000002

/*! Used to specify multi-vector (dense matrix) operations. */
#define RSB_FLAG_WANT_ROW_MAJOR_ORDER 			0x000000

/*! Used to specify multi-vector (dense matrix) operations. */
#define RSB_FLAG_WANT_COLUMN_MAJOR_ORDER 		0x4000000

/*! If set, the code will assume the input nonzeroes as sorted.	*/
#define RSB_FLAG_SORTED_INPUT				0x000004

/*! If set, the matrix is considered as triangular. \see #RSB_FLAG_LOWER,#RSB_FLAG_UPPER. */ 
#define RSB_FLAG_TRIANGULAR 				0x000008

/*! If set, the matrix will be stored in as lower (triangular or symmetric). \see #RSB_FLAG_TRIANGULAR,#RSB_FLAG_SYMMETRIC,#RSB_FLAG_UPPER. */
#define RSB_FLAG_LOWER		 			0x000010

/*! If set, the matrix will be stored in as upper (triangular or symmetric). \see #RSB_FLAG_LOWER*/
#define RSB_FLAG_UPPER		 			0x000020

/*! If set, the (whole super-)matrix will not store the diagonal, which will be assumed to be unitary. */
#define RSB_FLAG_UNIT_DIAG_IMPLICIT			0x000040

/* ghost flag ( moved in a non-public header, and reserved): 0x000080	*/
/* ghost flag ( moved in a non-public header, and reserved): 0x80000000	*/

/*! If set, the matrix will use COO storage, where necessary. */
#define RSB_FLAG_WANT_COO_STORAGE		0x000100

/*! Keep the last nonzero duplicate, at matrix assembly time. */ 
#define RSB_FLAG_DUPLICATES_KEEP_LAST				0x000000

/*! The default nonzeroes duplicates handling.  */ 
#define RSB_FLAG_DUPLICATES_DEFAULT_HANDLE			0x000000

/*! Compute and keep the sum of nonzero duplicates, at matrix assembly time.  */ 
#define RSB_FLAG_DUPLICATES_SUM				0x000200

/*! If set, explicit zeros will not be inserted	\warning: this flag is active by default	*/
#define RSB_FLAG_DISCARD_ZEROS				0x000400

/* ghost flag ( moved in a non-public header, and reserved): 0x000800 */
/* ghost flag ( moved in a non-public header, and reserved): 0x001000 */

/*! If set, matrix will be organized as a quad tree of submatrices. */
#define RSB_FLAG_QUAD_PARTITIONING 			0x002000

/*! If set, the block partitioning will be fixed (BCSS: BCSR or BCSC, but no VBR).	*/
#define RSB_FLAG_WANT_BCSS_STORAGE 			0x004000

/* ghost flag ( moved in a non-public header, and reserved): 0x008000 */
/* ghost flag ( moved in a non-public header, and reserved): 0x010000 */
/* ghost flag ( moved in a non-public header, and reserved): 0x020000 */

/*! If set, matrices will be fit in the three input coo arrays, after conversion. */ 
#define RSB_FLAG_ASSEMBLED_IN_COO_ARRAYS		0x040000

/*! \internal \todo: should remove this. */ 
#define RSB_FLAG_EXPERIMENTAL_IN_PLACE_PERMUTATION_SORT	0x080000

/* ghost flag ( moved in a non-public header, and reserved): 0x100000*/
/* ghost flag (temporarily reserved): 0x200000*/

/*! 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. */
#define RSB_FLAG_SYMMETRIC 			0x400000

/*! If set, the input matrix will be treated as symmetric hermitian (stored as a lower triangular one). \see #RSB_FLAG_LOWER,#RSB_FLAG_LOWER. */
#define RSB_FLAG_HERMITIAN 			0x800000

/*! If set, recursion on small matrices will last at least the number of active threads. */
#define RSB_FLAG_RECURSIVE_MORE_LEAVES_THAN_THREADS	0x1000000

/* ghost flag ( moved in a non-public header, and reserved): 0x2000000	*/

/*! Combined flags for a lower hermitian matrix. */
#define RSB_FLAG_LOWER_HERMITIAN			(RSB_FLAG_HERMITIAN | RSB_FLAG_LOWER)

/*! Combined flags for an upper hermitian matrix. */
#define RSB_FLAG_UPPER_HERMITIAN			(RSB_FLAG_HERMITIAN | RSB_FLAG_UPPER)

/*! Combined flags for a lower triangular matrix. */
#define RSB_FLAG_LOWER_TRIANGULAR 			(RSB_FLAG_TRIANGULAR | RSB_FLAG_LOWER)

/*! Combined flags for an upper triangular matrix. */
#define RSB_FLAG_UPPER_TRIANGULAR 			(RSB_FLAG_TRIANGULAR | RSB_FLAG_UPPER)

/*! Combined flags for a symmetric, lower-stored matrix. */

#define RSB_FLAG_LOWER_SYMMETRIC 			(RSB_FLAG_SYMMETRIC | RSB_FLAG_LOWER)

/*! Combined flags for a diagonal matrix. */
#define RSB_FLAG_DIAGONAL 				(RSB_FLAG_UPPER | RSB_FLAG_LOWER)

/*! Combined flags for a symmetric, upper-stored matrix. */
#define RSB_FLAG_UPPER_SYMMETRIC 			(RSB_FLAG_SYMMETRIC | RSB_FLAG_UPPER)

/*! If set, the matrix will be subdivided at a finer grain on diagonal blocks. */
#define RSB_FLAG_RECURSIVE_SUBDIVIDE_MORE_ON_DIAG 	0x8000000

/*! If set, the input COO arrays to the assembly functions will not be freed at matrix destruction time.
  \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().
 */
#define RSB_FLAG_EXTERNALLY_ALLOCATED_ARRAYS 		0x40000000

/* Reserved, undocumented flags. Not for use. */
#define RSB_FLAG_USE_CSR_RESERVED	0x200000

/*! \internal Combined flags for half word CSR. */
#define RSB_FLAG_USE_HALFWORD_INDICES_CSR	(RSB_FLAG_USE_HALFWORD_INDICES|RSB_FLAG_USE_CSR_RESERVED)

/*! Combined flags for half word COO. */
#define RSB_FLAG_USE_HALFWORD_INDICES_COO	(RSB_FLAG_USE_HALFWORD_INDICES|RSB_FLAG_WANT_COO_STORAGE)

/*! A combination of flags which is forbidden (so don't use it). */
#define RSB_FLAG_MUTUALLY_EXCLUSIVE_SWITCHES	(RSB_FLAG_USE_HALFWORD_INDICES_COO|RSB_FLAG_USE_HALFWORD_INDICES_CSR)
/*!@}*/


/*! A macro for the error code value. */
#define RSB_ERR_CAST(E) (-(E))

/* Error handling functions. */
rsb_err_t rsb_strerror_r(rsb_err_t errval, rsb_char_t * buf, size_t buflen);
rsb_err_t rsb_perror(void *stream, rsb_err_t errval);

/*! No error occurred (success). The return value that means function operation success, in most cases.   */
#define RSB_ERR_NO_ERROR		RSB_ERR_CAST(0x000)

/*! An unspecified, generic error occurred. */
#define RSB_ERR_GENERIC_ERROR		RSB_ERR_CAST(0x001)

/*! The user requested an operation which is not supported (e.g.: was opted out at build time). */
#define RSB_ERR_UNSUPPORTED_OPERATION	RSB_ERR_CAST(0x002)

/*! The user requested to use a type which is not supported (e.g.: was opted out at build time). */
#define RSB_ERR_UNSUPPORTED_TYPE	RSB_ERR_CAST(0x004)

/*! The user requested to use a matrix storage format which is not supported (e.g.: was opted out at build time). */
#define RSB_ERR_UNSUPPORTED_FORMAT	RSB_ERR_CAST(0x008)

/*! An error occurred which is not apparently caused by a user's fault (internal error). */
#define RSB_ERR_INTERNAL_ERROR		RSB_ERR_CAST(0x010)

/*! The user supplied some corrupt data as argument. */
#define RSB_ERR_BADARGS			RSB_ERR_CAST(0x020)

/*! There is not enough dynamical memory to perform the requested operation. */
#define RSB_ERR_ENOMEM			RSB_ERR_CAST(0x040)

/*! The requested operation was not implemented yet in this code revision (but probably will be, someday). */
#define RSB_ERR_UNIMPLEMENTED_YET	RSB_ERR_CAST(0x100)

/*! The requested operation could not be executed, or index overflow will happen. */
#define RSB_ERR_LIMITS			RSB_ERR_CAST(0x200)

/*! A Fortran specific error occurred. */
#define RSB_ERR_FORTRAN_ERROR		RSB_ERR_GENERIC_ERROR

/*! The requested feature (e.g.:blocking) is not available because it was opted out or not configured at build time. */
#define RSB_ERR_UNSUPPORTED_FEATURE	RSB_ERR_CAST(0x400)

/*! A file containing user set configuration was not present. */
#define RSB_ERR_NO_USER_CONFIGURATION	RSB_ERR_CAST(0x800)

/*! User supplied data (e.g.: from file) was corrupt. */
#define RSB_ERR_CORRUPT_INPUT_DATA	RSB_ERR_CAST(0x1000)

/*! Memory hierarchy info failed to be detected. You can bypass this by setting a meaningful \c RSB_USER_SET_MEM_HIERARCHY_INFO environment variable. */
#define RSB_ERR_FAILED_MEMHIER_DETECTION	RSB_ERR_CAST(0x2000)

/*! User gave flags for an in place assembly in a copy-based function. */
#define RSB_ERR_COULD_NOT_HONOUR_EXTERNALLY_ALLOCATION_FLAGS	RSB_ERR_CAST(0x4000)

/*! User requested writing to a file stream, while this feature is configured out. */
#define RSB_ERR_NO_STREAM_OUTPUT_CONFIGURED_OUT	RSB_ERR_CAST(0x8000)

/*! User gave some input with invalid numerical data. */
#define RSB_ERR_INVALID_NUMERICAL_DATA	RSB_ERR_CAST(0x10000)

/*! Probable memory leak (user did not deallocate librsb structures before calling rsb_lib_exit()). */
#define RSB_ERR_MEMORY_LEAK	RSB_ERR_CAST(0x20000)

/*! Collation of "unsupported" type errors. */
#define RSB_ERRS_UNSUPPORTED_FEATURES	(RSB_ERR_UNSUPPORTED_FEATURE|RSB_ERR_NO_STREAM_OUTPUT_CONFIGURED_OUT)

/*! Program success error code (int). */
#ifdef EXIT_SUCCESS
#define RSB_PROGRAM_SUCCESS	(EXIT_SUCCESS)
#else
#define RSB_PROGRAM_SUCCESS		(0)
#endif

/*! Program error code (int). */
#ifdef EXIT_FAILURE
#define RSB_PROGRAM_ERROR		(EXIT_FAILURE)
#else
#define RSB_PROGRAM_ERROR		(-1)
#endif

/*! Program error code (int). */
#define RSB_ERR_TO_PROGRAM_ERROR(E)	((E)==(RSB_ERR_NO_ERROR)?RSB_PROGRAM_SUCCESS:RSB_PROGRAM_ERROR)


/*! \ingroup rsb_doc_misc rsb_doc_rsb
\brief library option values for \see_lib_init_funcs. */
enum rsb_opt_t
{
/*! #RSB_IO_WANT_VERBOSE_INIT prompts for a verbose initialization of the library: messages will be written
 * to the file descriptor (\c FILE*) pointed by the value pointer when calling \ref rsb_lib_init.
 */
  RSB_IO_WANT_VERBOSE_INIT =0x000001	/* (FILE*) */
,
/*! #RSB_IO_WANT_VERBOSE_EXIT prompts for a verbose finalization of the library: messages will be written
 * to the file descriptor (\c FILE*) pointed by the value pointer when calling \ref rsb_lib_exit.
 */
  RSB_IO_WANT_VERBOSE_EXIT =0x000002	/* (FILE*) */
,
/*! Specifies the default output stream. Output (debug info) info will be written  
 * to the file descriptor (\c FILE*) pointed by the value pointer.
 */
  RSB_IO_WANT_OUTPUT_STREAM =0x000003	/* (FILE*) */
,
/*! Specifies the default sorting method. Specified as a pointed integer (#rsb_int_t) number, in {[0],1}. (internal)
 */
  RSB_IO_WANT_SORT_METHOD =0x000004	/* (rsb_int_t) */
,
/*! Specifies the default cache blocking method. Specified as a pointed integer (#rsb_int_t) number, in {-1,[0],1}. (internal)
 */
  RSB_IO_WANT_CACHE_BLOCKING_METHOD =0x000005	/* (rsb_int_t) */
,
/*! 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)
 */
  RSB_IO_WANT_SUBDIVISION_MULTIPLIER =0x000006	/* (rsb_real_t) */
,
/*! Prompts for a verbose error reporting: messages will be written
 * to the file descriptor (\c FILE*) pointed by the value pointer. Only meaningful if an
 * interface error verbosity greater than 0 was set at configure time. 
 */
  RSB_IO_WANT_VERBOSE_ERRORS =0x000007	/* (FILE*) */
,
/*! Prompts for bounded box computation, for a smoother submatrices locking; pointed #rsb_int_t in {0,[1]}. (internal).
 */
  RSB_IO_WANT_BOUNDED_BOX_COMPUTATION =0x000008	/* (rsb_int_t) */
,
/*! Specifies the number of desired executing threads; pointed #rsb_int_t in {[0],1,..}.
 */
  RSB_IO_WANT_EXECUTING_THREADS =0x000009	/* (rsb_int_t) */
,
/*! 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.
 */
  RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE =0x000010	/* (rsb_int_t) */
,
/*! Specifies a custom memory hierarchy info string; pointed \c const #rsb_char_t*; (may point to a NULL string pointer).
 */
  RSB_IO_WANT_MEMORY_HIERARCHY_INFO_STRING =0x000011	/* (const rsb_char_t*) */
,
/*! 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).
 */
  RSB_IO_WANT_IS_INITIALIZED_MARKER =0x000012	/* (const rsb_bool_t*) */
,
/*! 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).
 */
  RSB_IO_WANT_MEM_ALLOC_CNT =0x000013	/* (const size_t*) */
,
/*! 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).
 */
  RSB_IO_WANT_MEM_ALLOC_TOT =0x000014	/* (const size_t*) */
,
/*! 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)
 */
  RSB_IO_WANT_LEAF_LEVEL_MULTIVEC =0x000015	/* (rsb_int_t) */
,
/*! 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
 */
  RSB_IO_WANT_MAX_MEMORY_ALLOCATIONS =0x000016	/* (size_t) */
,
/*! 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
 */
  RSB_IO_WANT_MAX_MEMORY_ALLOCATED =0x000017	/* (size_t) */
,
/*! 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.
 */
  RSB_IO_WANT_LIBRSB_ETIME =0x000018	/* (rsb_time_t) */
,
/*! 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.
 */
  RSB_IO_WANT_VERBOSE_TUNING =0x000019	/* (rsb_int_t) */
};

/*! A handy macro for invoking #rsb_lib_reinit() with a single get/set specifier.
 * 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.
 * \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.
 * */
#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); }

/*! Like #RSB_REINIT_SINGLE_VALUE, but considering \c IOP \c const.
 * \deprecated	This macro has been deprecated and will be removed in a future version: use #rsb_lib_set_opt instead.
 * */
#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); }

/*! A handy macro for invoking #RSB_REINIT_SINGLE_VALUE with a single set specifier.
 * 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.
 * \deprecated	This macro has been deprecated and will be removed in a future version: use #rsb_lib_set_opt instead.
 * */
#define RSB_REINIT_SINGLE_VALUE_SET(IOF,IOP,ERRVAL) RSB_REINIT_SINGLE_VALUE(IOF,IOP,RSB_IO_SPECIFIER_SET,ERRVAL)

/*! A handy macro for invoking #RSB_REINIT_SINGLE_VALUE with a single get specifier.
 * 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.
 * \deprecated	This macro has been deprecated and will be removed in a future version: use #rsb_lib_get_opt instead.
 * */
#define RSB_REINIT_SINGLE_VALUE_GET(IOF,IOP,ERRVAL) RSB_REINIT_SINGLE_VALUE(IOF,IOP,RSB_IO_SPECIFIER_GET,ERRVAL)


/*!
 * @brief A structure specifying library (initialization) options, to be used with the \ref rsb_lib_reinit() function.
 * \n
 *
 * The structure specifies, for \c i=0,..,n_pairs-1 , a list of (key,value)
 * pairs, stored respectively as (\c keys[i],values[i]).
 * \n
 * Each flag specifies the type and possible range of values it accepts. 
 * \n
 * The structure may he used to set or query various library parameters. 
 *
 * Example:
 * \code
 	const int max_io=10; // the number of different options we want to set
	struct rsb_initopts io={NULL,NULL,0,RSB_IO_SPECIFIER_SET},
 	*iop=&io; // pointer to the options structure
	void * io_values[max_io]; // an array of pointers to max_io different option values (we shall set)
	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
	io.keys=io_keys; // io.keys will now point to io_keys as its keys array
	io.values=io_values; // io.values will now point to io_keys as its values array
	io.n_pairs=0; // we have 0 pairs specified so far
	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
	io.values[io.n_pairs]=1; // the value we want to set the RSB_IO_WANT_BOUNDED_BOX_COMPUTATION option to
	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
	... // we are free to specify other option (type, value) pairs
 * \endcode
 * */
struct rsb_initopts
{
	/*! An array of value types key flags. */
	enum rsb_opt_t * keys;
	/*! An array of value pointers, as specified by each flag value. */
	void ** values;
	/*! The length of the \c keys and \c values arrays. */
	rsb_int_t n_pairs;
	/*! The action we are requesting (either one of #RSB_IO_SPECIFIER_GET or #RSB_IO_SPECIFIER_SET)*/
	rsb_int_t action;
};

#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. */
#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. */
#define RSB_NULL_INIT_OPTIONS NULL /*!<  A valid value for specifying default (null) options to #rsb_lib_init().  */
#define RSB_NULL_EXIT_OPTIONS NULL /*!<  A valid value for specifying default (null) options to #rsb_lib_exit().  */

rsb_err_t rsb_lib_init(struct rsb_initopts * iop);
rsb_err_t rsb_lib_reinit(struct rsb_initopts * iop);
rsb_err_t rsb_lib_set_opt_str(const rsb_char_t* opnp, const rsb_char_t* opvp);
rsb_err_t rsb_lib_set_opt(enum rsb_opt_t iof, const void*iop);
rsb_err_t rsb_lib_get_opt(enum rsb_opt_t iof, void*iop);
rsb_err_t rsb_lib_exit(struct rsb_initopts * iop);

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);
rsb_err_t rsb_mtx_alloc_from_coo_end(struct rsb_mtx_t ** mtxApp);
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);
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);
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);
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);
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 );
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);
struct rsb_mtx_t * rsb_mtx_free(struct rsb_mtx_t * mtxAp);

/*! \ingroup rsb_doc_misc rsb_doc_rsb
 \brief Extraction filter flags, to be used with #rsb_mtx_get_nrm()/#rsb_mtx_get_vec(). */
enum rsb_extff_t
{
  RSB_EXTF_NORM_ONE	=0x00001001			/*!< #rsb_mtx_get_nrm() flag value for computing the one-norm. */
, RSB_EXTF_NORM_TWO	=0x00001002			/*!< #rsb_mtx_get_nrm() flag value for computing the two-norm (Frobenius norm). */
, RSB_EXTF_NORM_INF	=0x00001003			/*!< #rsb_mtx_get_nrm() flag value for computing the infinity-norm. */
, RSB_EXTF_SUMS_ROW	=0x00001004			/*!< #rsb_mtx_get_vec() flag value for computing the sum along each row. */
, RSB_EXTF_SUMS_COL	=0x00001005			/*!< #rsb_mtx_get_vec() flag value for computing the sum along each column. */
, RSB_EXTF_ASUMS_ROW	=0x00001006			/*!< #rsb_mtx_get_vec() flag value for computing the absolute values sum, along each row. */
, RSB_EXTF_ASUMS_COL	=0x00001007			/*!< #rsb_mtx_get_vec() flag value for computing the absolute values sum, along each column. */
, RSB_EXTF_DIAG		=0x00000004			/*!< #rsb_mtx_get_vec() flag value for extracting the diagonal submatrix.*/
};

typedef rsb_flags_t rsb_marf_t;					/*!< Matrix rendering flags (see \ref marf_section for possible values). */
/*!@{*/
/*!
 \ingroup rsb_doc_rsb
 \name Matrix rendering flags
 \anchor marf_section

 These are flags which could be combined to specify rendering options to #rsb_mtx_rndr and #rsb_file_mtx_rndr.
 */
#define RSB_MARF_RGB	0x00000001			/*!< #rsb_marf_t Flag value for requesting an RGB rendering of a matrix. */
#define RSB_MARF_EPS_S	0x00000010			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (spy plot). */
#define RSB_MARF_EPS_B	0x00000020			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (blocks plot). */
#define RSB_MARF_EPS	0x00000030			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (spy plot + blocks). */
#define RSB_MARF_EPS_L	0x00000070			/*!< #rsb_marf_t Flag value for requesting an Encapsulated Postscript rendering of a matrix (spy plot + blocks + labels). */
/*!@}*/

rsb_err_t rsb_mtx_get_nrm(const struct rsb_mtx_t * mtxAp , void * Np, enum rsb_extff_t flags);
#define rsb_mtx_get_norm rsb_mtx_get_nrm /*!< \deprecated #rsb_mtx_get_norm has been deprecated: use #rsb_mtx_get_nrm . */
rsb_err_t rsb_mtx_get_vec(const struct rsb_mtx_t * mtxAp , void * Dp, enum rsb_extff_t flags);
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);
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);
#define rsb_file_mtx_render rsb_file_mtx_rndr /*!< \deprecated #rsb_file_mtx_render has been deprecated: use #rsb_file_mtx_rndr. */

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);
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);
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);
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);

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);

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);
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);
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);

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);
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);
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 );
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 );
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 );
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, rsb_coo_idx_t * IREN, rsb_coo_idx_t * JREN, rsb_nnz_idx_t *rnzp, rsb_flags_t flags );

/*! \ingroup rsb_doc_misc rsb_doc_rsb
\brief Flags for getting matrix information via #rsb_mtx_get_info()/#rsb_mtx_get_info_str().
*/
enum rsb_mif_t
{
  RSB_MIF_INDEX_STORAGE_IN_BYTES__TO__SIZE_T		=0x00000001	/*!< Index storage occupation, in bytes. (size_t) */
, RSB_MIF_INDEX_STORAGE_IN_BYTES_PER_NNZ__TO__RSB_REAL_T	=0x00000002	/*!< Index storage occupation per nnz, in bytes. (#rsb_real_t) */
, RSB_MIF_MATRIX_ROWS__TO__RSB_COO_INDEX_T		=0x00000004	/*!< Rows count(#rsb_coo_idx_t) */
, RSB_MIF_MATRIX_COLS__TO__RSB_COO_INDEX_T		=0x00000008	/*!< Columns count (#rsb_coo_idx_t) */
, RSB_MIF_MATRIX_NNZ__TO__RSB_NNZ_INDEX_T		=0x00000010	/*!< Nonzeroes count (#rsb_nnz_idx_t) */
, RSB_MIF_TOTAL_SIZE__TO__SIZE_T			=0x00000020	/*!< Total size, in bytes (size_t) */
, RSB_MIF_MATRIX_FLAGS__TO__RSB_FLAGS_T			=0x00000040	/*!< Matrix flags (#rsb_flags_t) */
, RSB_MIF_MATRIX_TYPECODE__TO__RSB_TYPE_T		=0x00000080	/*!< Matrix type code (#rsb_type_t) */
, RSB_MIF_MATRIX_INFO__TO__CHAR_P			=0x00000100	/*!< Matrix info string, only for #rsb_mtx_get_info_str() (#rsb_char_t*) */
, RSB_MIF_LEAVES_COUNT__TO__RSB_BLK_INDEX_T		=0x00000200	/*!< Leaf submatrices count (#rsb_blk_idx_t) */
};
rsb_err_t rsb_mtx_get_info(const struct rsb_mtx_t *mtxAp, enum rsb_mif_t miflags, void* minfop);
rsb_err_t rsb_mtx_get_info_str(const struct rsb_mtx_t *mtxAp, const rsb_char_t *mis, void* minfop, size_t buflen);

/*! \ingroup rsb_doc_misc rsb_doc_rsb
\brief Flags for specifying a particular elemental/row-wise operation with #rsb_mtx_upd_vals(). */
enum rsb_elopf_t
{
  RSB_ELOPF_MUL		=0x00000001		/*!< Elemental multiplication of the matrix by a specified scalar (usable with #rsb_mtx_upd_vals(), binary operation). */
, RSB_ELOPF_DIV		=0x00000002		/*!< Elemental division by a specified scalar (usable with #rsb_mtx_upd_vals(), binary operation). */
, RSB_ELOPF_POW		=0x00000004		/*!< Elemental power to a specified scalar (usable with #rsb_mtx_upd_vals(), binary operation). */
, RSB_ELOPF_NEG		=0x00000008		/*!< Elemental negation (usable with #rsb_mtx_upd_vals(), unary operation). */
, RSB_ELOPF_SCALE_ROWS	=0x00000010		/*!< Row    wise scaling by a specified scaling vector (usable with #rsb_mtx_upd_vals(), binary operation). */
, RSB_ELOPF_SCALE_COLS	=0x00000020		/*!< Column wise scaling by a specified scaling vector (usable with #rsb_mtx_upd_vals(), binary operation). */
, 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). */
, 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). */
};

rsb_err_t rsb_mtx_upd_vals(struct rsb_mtx_t * mtxAp, enum rsb_elopf_t elop_flags, const void * omegap);
#define rsb_mtx_upd_values rsb_mtx_upd_vals /*!< \deprecated #rsb_mtx_upd_values has been deprecated: use #rsb_mtx_upd_vals. */
typedef rsb_flags_t rsb_precf_t;	/*!< Basic preconditioner flags to be used with #rsb_mtx_get_prec(). */
#define RSB_PRECF_ILU0		0x00000001		/*!< ILU-0 preconditioner request to #rsb_mtx_get_prec(). */
rsb_err_t rsb_mtx_get_prec(void *opdp, const struct rsb_mtx_t * mtxAp, rsb_precf_t prec_flags, const void *ipdp);
#define rsb_mtx_get_preconditioner rsb_mtx_get_prec 	/*!< \deprecated #rsb_mtx_get_preconditioner has been deprecated: use #rsb_mtx_get_prec. */
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);
#define rsb_mtx_set_values rsb_mtx_set_vals /*!< \deprecated #rsb_mtx_set_values has been deprecated: use #rsb_mtx_set_vals. */
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);
#define rsb_mtx_get_values rsb_mtx_get_vals /*!< \deprecated #rsb_mtx_get_values has been deprecated: use #rsb_mtx_get_vals. */
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);
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);
rsb_trans_t rsb_psblas_trans_to_rsb_trans(const char psbtrans);
rsb_err_t rsb_file_mtx_save(const struct rsb_mtx_t * mtxAp, const rsb_char_t * filename);
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);
rsb_err_t rsb_file_vec_load(const rsb_char_t * filename, rsb_type_t typecode, void * Yp, rsb_coo_idx_t *yvlp);
rsb_err_t rsb_file_vec_save(const rsb_char_t * filename, rsb_type_t typecode, const void * Yp, rsb_coo_idx_t yvl);
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);
#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. */
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 );
rsb_time_t rsb_time(void);

/*! \internal
 NOTE: user programs should never include explicitly rsb_types.h.
 */
#include "rsb_types.h"

/*! \ingroup rsb_doc_misc rsb_doc_rsb
 Use #RSB_SIZEOF macro to get the size (in bytes) of a type supported by the library (e.g.: when allocating numerical vectors).
 */
#define RSB_SIZEOF(TYPE) RSB_NUMERICAL_TYPE_SIZE(TYPE)

#ifdef __cplusplus
}
#endif  /* __cplusplus */

#endif	/* RSB_RSB_H_INCLUDED */