/usr/share/doc/librsb-dev/html/index.html is in librsb-doc 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 | <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<meta name="generator" content="Doxygen 1.8.13"/>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<title>librsb: Main Page</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0">
<tbody>
<tr style="height: 56px;">
<td id="projectalign" style="padding-left: 0.5em;">
<div id="projectname">librsb
 <span id="projectnumber">1.2.0-rc7</span>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<!-- end header part -->
<!-- Generated by Doxygen 1.8.13 -->
<script type="text/javascript" src="menudata.js"></script>
<script type="text/javascript" src="menu.js"></script>
<script type="text/javascript">
$(function() {
initMenu('',false,false,'search.php','Search');
});
</script>
<div id="main-nav"></div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">librsb Documentation</div> </div>
</div><!--header-->
<div class="contents">
<div class="textblock"><p>A sparse matrix library implementing the `Recursive Sparse Blocks' (<b>RSB</b>) matrix storage.</p>
<p>This is the documentation for the application programming interface (API) of the <em>`<code>librsb'</code> library</em>. <br />
In order to use <code>librsb</code>, there is no need for the user to know the RSB layout and algorithms: this documentation should be sufficient. <br />
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. <br />
Many computationally intensive operations are implemented with thread parallelism, by using OpenMP. <br />
Thread parallelism can be turned off at configure time, if desired, or limited at execution time. <br />
Many of the computational kernels source code files (mostly internals) were automatically generated. <br />
This user documentation concerns the end user API only; that is, neither the internals, nor the code generator. <br />
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.</p>
<p>This library is research software and as such, still <b>experimental</b>. For a first approach, we suggest to go through the <a class="el" href="group__rsb__doc__examples.html">Example programs and code</a> documentation section, or the <a class="el" href="index.html#examples_section">quick start examples</a> section on this page.</p>
<p><br />
Information about the supported matrix types and matrix operations resides in the <a class="el" href="rsb__types_8h.html">rsb_types.h </a> file.</p>
<p>A C/C++ user can use the native API of RSB by including the <a class="el" href="rsb_8h.html">rsb.h </a> header. The same interface is available in Fortran via the ISO C Binding interface, specified in <a class="el" href="rsb_8F90.html">rsb.F90</a>. <br />
The C header file for the <a class="el" href="group__rsb__doc__sparse__blas.html">The Sparse BLAS interface to librsb (blas_sparse.h, rsb_blas_sparse.F90)</a> is <a class="el" href="blas__sparse_8h.html">blas_sparse.h</a>.</p>
<dl class="section author"><dt>Author</dt><dd>Michele Martone < michelemartone AT users DOT sourceforge DOT net ></dd></dl>
<p>Contents of the README file : </p><pre class="fragment">
================================================================================
librsb README file
================================================================================
librsb - Recursive Sparse Blocks Matrix computations library
A library for sparse matrix computations featuring the Recursive Sparse Blocks
(RSB) matrix format. This format allows cache efficient and multi-threaded
(that is, shared memory parallel) operations on large sparse matrices.
It provides the most common operations necessary to iterative solvers, like
matrix-vector multiplication, triangular solution, rows/columns scaling,
diagonal extraction / setting, blocks extraction, norm computation, formats
conversion. The RSB format is especially well suited for symmetric and
transposed multiplication variants.
Most numerical kernels code is auto generated, and the supported numerical
types can be chosen by the user at build time.
This library is dual-interfaced: it can be used via the native (`RSB')
interface (with identifiers prefixed by `rsb_' or `RSB_'), and a Sparse BLAS
one (`BLAS_').
The `RSB' interface can be used from C (rsb.h header) or via modern Fortran
ISO-C-BINDING ("rsb" module).
The Sparse BLAS interface is usable from C via the blas_sparse.h header, and
from Fortran via the "blas_sparse" module.
================================================================================
This (README) is the first document you should read about librsb.
It contains basic instructions to generate, compile, install, and use librsb.
The reference documentation for programming with librsb is contained in the
./doc/ source package subdirectory and when installed, placed in the
appropriate system directories as both Unix man pages (./doc/man/) and HTML
(./doc/html/).
If you are a user of a previous version of librsb, see the NEWS file listing
the changes.
After having read this file you are welcome to ask questions to the author.
--------------------------------------------------------------------------------
INTRODUCTION
--------------------------------------------------------------------------------
librsb is a library for sparse matrix algebra computations.
It is stand-alone: does not require any other library to build or work.
It is shared memory parallel, using the OpenMP standard.
It focuses on high performance and provides build options.
A part of the library code is automatically generated from templates and
macros, on the basis of the numerical type a user wish to have supported.
The configure script options (self documented --- not documented here) provide
many build time options, especially with respect to debug and additional
verbosity.
INTRODUCTION
MAIN ASPECTS,FEATURES
QUICK INSTALL AND TESTING
LIBRARY CONFIGURATION, GENERATION, BUILD
INSTALLATION, USAGE
EXECUTION AND ENVIRONMENT VARIABLES
DOCUMENTATION, EXAMPLES AND PROGRAMMING GUIDELINES
CONFIGURE, BUILD AND BENCHMARK EXAMPLE
COMPATIBILITY
FAQ
POSSIBLE / POTENTIAL FUTURE FEATURES / ENHANCEMENTS
ABOUT THE INTERNALS
BUGS
CONTACTS
CREDITS
LICENSE
--------------------------------------------------------------------------------
MAIN ASPECTS,FEATURES
--------------------------------------------------------------------------------
* very efficient (see the website for benchmark performance results)
* threads/structure autotuning feature for additional performance
* support for multiple numerical data types which can be turned
on/off individually (e.g.:double, float, int, char, complex, double complex)
at configure time
* a sparse BLAS interface for matrix assembly, computation, destruction
* a code generator for its inner CSR, COO computational kernels
* based on a recursive memory layout of submatrices
* enough functionality to implement the most common iterative methods
* basic index types overflow checks and input sanitizing
* parallel matrix assembly and conversion routines
* auxiliary functions for matrix I/O (using the "Matrix Market" format:
real, integer, complex and pattern are supported)
* implemented as a building block for solvers like e.g. PSBLAS
* dual implementation of kernels: with "full word" and "half word" indices
* thread level (shared memory) parallelism by using OpenMP
* basic (unoptimized) sparse matrices multiplication and summation
* interactive usage possible by using the "sparsersb" plugin for GNU Octave
* complete with examples and a test suite
* see the NEWS text file for a list of changes from version to version
--------------------------------------------------------------------------------
QUICK INSTALL AND TESTING EXAMPLE
--------------------------------------------------------------------------------
# unpack the archives or get them from the repositories
./autogen.sh # only necessary if configure file does not exist
./configure --prefix=$HOME/local/librsb/
# see also ./configure --help for many other options
# librsb has been configured
make help # provides information
make # build the library and test programs
# librsb has been built
make qtests # perform brief sanity tests
make qqtests # the same, but with less output
make tests # perform extended sanity tests
ls examples/*.c # here are editable examples; build them with 'make'
ls examples/*.F90 # here are editable examples; build them with 'make'
make install # install to $HOME/local/librsb/
# librsb has been installed; now you can write your own programs
# for instance, try using one of the librsb examples as a model:
mkdir -p ~/rsb-test/ && cp examples/hello.c ~/rsb-test/myrsb.c
# adapt hello.c to your needs and recompile:
cd ~/rsb-test/
export PATH=$PATH:$HOME/local/librsb/bin/
gcc `librsb-config --I_opts`. -c myrsb.c
gcc -o myrsb myrsb.o `librsb-config --static --ldflags --extra_libs`
./myrsb # run your program
--------------------------------------------------------------------------------
LIBRARY CONFIGURATION, GENERATION, BUILD
--------------------------------------------------------------------------------
This library consists of C code (C 99), partially generated by M4 macros.
The user wishing to build librsb can specify different initial parameters
determining the supported matrix operations, inner explicit loop unrolling
factors, available numerical data types and code variations.
These parameters have to be specified to the ./configure script.
The M4 macros are used at build time to generate specialized C code.
If building from repository sources, an M4 preprocessor is required.
Otherwise, it is necessary only when specifying ./configure options affecting
code generation (see ./configure --help).
The M4 preprocessor executable can be specified explicitly to ./configure
with the M4 environment variable or via the --with-m4 option.
After invoking ./configure and before running 'make' it is possible to invoke
'make cleanall' to make sure that auto-generated code is deleted first.
At configure time, it is very important that the configure script is able to
detect the system cache memory hierarchy parameters.
In the case it fails, you are encouraged to specify cache parameters by
re-running ./configure and setting the --with-memhinfo option.
For instance:
--with-memhinfo=L2:4/64/512K,L1:8/64/24K
These values need not be exact: they can be approximate.
Yet they may be critical to library performance; for this reason you are
allowed to override this default in a variety of ways.
Read further to get a description of the memory hierarchy info string format.
If you want to build Fortran examples, be sure of invoking ./configure with the
--enable-fortran-examples option. You can specify the desired Fortran compiler
and compilation flags via the FC and FCFLAGS variables.
Set the CPPFLAGS variable at configure time to provide additional compilation
flags; e.g. configure to detect necessary headers in non-standard location.
Similarly, the LDFLAGS variable can be set to contain link time options; so
you can use it to specify libraries to be linked to librsb examples.
Invoke ./configure --help for details of other relevant environment variables.
After ./configure you will see information about the current build options
and if satisfied, invoke 'make' to build the library and the examples.
To check for library consistence, run:
make qtests # takes a short time
or
make tests # takes longer, more complete
If these tests terminate with an error code, it is highly likely that it has
been caused by a bug in librsb, so please tell us (see BUGS).
--------------------------------------------------------------------------------
INSTALLATION, USAGE
--------------------------------------------------------------------------------
Once built, the library can be installed with:
su -c 'make install' #'make install' installs the library system-wide
This installs header files, binary library files, and the librsb-config
program.
Then, application C programs should include the rsb.h header file with
#include <rsb.h>
and be compiled using include options as generated by the output of
`librsb-config --I_opts`.
To link to the librsb.a static library file and its dependencies one can use
the output of `librsb-config --static --ldflags --extra_libs`.
Only static libraries are built currently.
If you wish to use the library without installing it in the system directories,
make sure to include the <rsb.h> header file and link to the librsb.a library
and all the necessary additional libraries.
Users of pkg-config can manually copy the librsb.pc file to the appropriate
directory to use pkg-config in a way similar to librsb-config.
--------------------------------------------------------------------------------
EXECUTION AND ENVIRONMENT VARIABLES
--------------------------------------------------------------------------------
By default, the only environment variable read by librsb is
RSB_USER_SET_MEM_HIERARCHY_INFO, and will override configure-time and
auto-detected settings about memory hierarchy.
Its value is specified as n concatenated strings of the form:
L<l>:<a_l>/<b_l>/<c_l>
These strings are separated by a comma (","), and each of them is made
up from substrings where:
<n> is the cache memories hierarchy height, from 1 upwards.
<l> is the cache level, from 1 upwards.
<a_l> is the cache associativity
<b_l> is the cache block size (cache line length)
<c_l> is the cache capacity (size)
The <a_l>, <b_l>, <c_l> substrings consist of an integer number with an
optional multiplier character among {K,M,G} (to specify respectively 2^10,
2^20 or 2^30).
Any value is permitted, a long as it is positive. Higher level cache
capacities are required to be larger than lower level ones.
Example strings and usage in the BASH shell:
RSB_USER_SET_MEM_HIERARCHY_INFO="L2:4/64/512K,L1:8/64/32K" <your program>
RSB_USER_SET_MEM_HIERARCHY_INFO="L1:8/128/2M" <your program>
You may explicitly set this environment variable to fine-tune the library
operation.
If not doing so, runtime detection will be attempted; if this shall fail,
a configure time detected value will be used.
In some cases the configure time detection fails (e.g.: on very recent
systems); this is not a fault of librsb but rather of the underlying
environment.
A default value for this memory hierarchy info string can be set at configure
time by using the --with-memhinfo configure option.
If you don't know values for these parameters, you can run the
./scripts/linux-sys-cache.sh
script to try to get a guess on a Linux system.
On other systems, please consult the available documentation.
E.g.: On Mac OS 10.6 it is possible to get this information by invoking
"sysctl -a | grep cache".
The librsb library achieves parallelism by using OpenMP.
Even though librsb does not directly read any OpenMP environment variable,
it is still affected by them (e.g. the OMP_NUM_THREADS environment variable
specifying the number of parallel threads).
Please consult your compiler's OpenMP implementation documentation
for more information.
--------------------------------------------------------------------------------
DOCUMENTATION, EXAMPLES AND PROGRAMMING GUIDELINES
--------------------------------------------------------------------------------
The API is entirely specified in the <rsb.h> header file. This is the only
header file the application developer should ever include to use the library.
The complete API documentation is generated by the doxygen tool in the doc
directory in both HTML and man formats, and gets installed with 'make install'.
If you wish not to use doxygen (or don't have it) you can skip documentation
generation by adding the "DOXYGEN=false" argument to ./configure .
There are a number of working example programs in the "examples" directory.
The library only declares symbols prefixed by `rsb_'.
These symbols include those declared in rsb.h, as well as internal,
undocumented service functions and variables.
Therefore, to avoid name clashes, you should avoid declaring `rsb_' prefixed
identifiers in programs using librsb.
If configure has been invoked with the --enable-sparse-blas-interface, then
the corresponding `BLAS_' and `blas_' prefixed symbols will also be built.
If after building the library, you find that it exports symbols with different
prefixes (besides the system specific, compiler-generated symbols), please
report this to us -- it is a bug.
--------------------------------------------------------------------------------
CONFIGURE, BUILD AND BENCHMARK EXAMPLE
--------------------------------------------------------------------------------
First configure and build with reasonable options, such as (gcc, 64 bit):
export MKLROOT=/opt/intel/mkl
./configure --disable-debug CC=gcc FC=gfortran CFLAGS=-O3 \
--with-mkl="-static -L${MKLROOT}/lib/intel64 \
-Wl,--start-group,-lmkl_intel_lp64,-lmkl_gnu_thread,-lmkl_core,--end-group \
-fopenmp -lpthread" \
--with-memhinfo=L2:4/64/512K,L1:8/64/24K \
--with-mkl-include=/opt/intel/mkl/include/ \
--prefix=/opt/librsb-optimized/ \
--enable-matrix-types="double,double complex"
Or (icc, 64 bit):
export MKLROOT=/opt/intel/mkl
./configure --disable-debug CC=icc FC=ifort CFLAGS=-O3 \
--with-mkl="-static -L${MKLROOT}/lib/intel64 -openmp -lpthread \
-Wl,--start-group,-lmkl_intel_lp64,-lmkl_intel_thread,-lmkl_core,--end-group" \
--with-memhinfo=L2:4/64/512K,L1:8/64/24K \
--with-mkl-include=/opt/intel/mkl/include/ \
--prefix=/opt/librsb-optimized/ \
--enable-matrix-types="double,double complex"
or (32 bit):
./configure --disable-debug CC=gcc FC=gfortran CFLAGS=-O3 \
--with-memhinfo=L2:4/64/512K,L1:8/64/24K \
--with-mkl="-static -L/opt/intel/mkl/lib/ia32/ -lmkl_solver \
-Wl,--start-group,-lmkl_intel,-lmkl_gnu_thread,-lmkl_core,--end-group \
-fopenmp -lpthread" \
--with-mkl-include=/opt/intel/mkl/include/ \
--prefix=/opt/librsb-optimized/ \
--enable-matrix-types="double,double complex"
and then
make # builds library and test programs
make tests # optional
In the above example, optional use of the MKL library is configured in.
However, librsb does not use MKL in any way: it is only used by the
"rsbench" test program.
Say you want to quickly benchmark the library for a quick SPMV speed test.
You have a valid Matrix Market file containing a matrix, A.mtx,
and you want to benchmark librsb with it on 1 and 4 cores, performing
100 sparse matrix-vector multiply iterations.
Then do a serial test first:
./rsbench -oa -Ob -f A.mtx -qH -R -n1 -t100 --verbose
and then a parallel test:
OMP_NUM_THREADS=4 ./rsbench -oa -Ob -f A.mtx -qH -R -n1,4 -t100 --verbose
You can add option --compare-competitors to enable comparisons to the MKL,
provided it has been configured in.
If not specifying a type (argument to the -T option), the default will be
used.
If configured in at build time, choices may be -T D (where D is the BLAS
prefix for "double"), -T Z (Z stands for "double complex") and so on.
You can specify "-T :" to mean all of the configured types.
Output of 'rsbench' shall be easy to understand or parse.
For more options and configure information, invoke:
./rsbench --help
To get the built in defaults, invoke the following:
./rsbench -oa -Ob --help
./rsbench --help
./rsbench --version
./rsbench -I
./rsbench -C
An example Matrix Market matrix file contents:
%%MatrixMarket matrix coordinate pattern general
% This is a comment.
% See other examples in the distributed *.mtx files.
2 2 3
1 1
2 1
2 2
--------------------------------------------------------------------------------
COMPATIBILITY
--------------------------------------------------------------------------------
This library has been built and tested on Unix machines.
Microsoft Windows users might try building librsb under the Cygwin environment.
Some tricks may have to be used on IBM AIX. For instance, adding the
--without-xdr or the --without-zlib switch to ./configure.
Your mileage may vary.
AIX's "make" program may give problems; use the GNU version "gmake" instead;
the same shall be done with the M4 interpreter.
This library was developed mostly on Debian Linux and using only free software.
--------------------------------------------------------------------------------
FAQ
--------------------------------------------------------------------------------
Q: Can you provide me good configure defaults for an optimized build ?
A: Default './configure' options are appropriate for an optimized build.
You will need to choose good compilation flags.
A good starting point for gcc is ./configure CC=gcc CFLAGS='-O3'.
For more, consult your compiler documentation (e.g. man gcc, man icc),
and learn about the best flags for your specific platform.
Striping your executable (make install-strip for librsb's rsbench) may
help.
Q: I am a beginner and I wish librsb to be very verbose when I invoke
library interface functions incorrectly.
Can you provide me good configure defaults for such a "debug" build ?
A: Yes: ./scripts/configure_for_debug.sh
Q: I have machine X, compiler Y, compiling flags Z; is SpMV performance P with
matrix M good ?
A: In general, hard to tell. However you can `make hinfo.log' and send me
(see CONTACTS) the hinfo.log file and your matrix in Matrix Market format
(well, please don't send matrices by email but rather upload them
somewhere on the web and send an URL to them).
The hinfo.log file will contain useful compile and machine information.
Then I *may* get an idea about the performance you should get with that
matrix on that computer.
Q: What is the Sparse BLAS ?
A: It's a programming interface specification:
[sparseblas_2001]:
BLAS Technical Forum Standard, Chapter 3, Sparse BLAS
http://www.netlib.org/blas/blast-forum/chapter3.pdf
[dhp_2002]:
An Overview of the Sparse Basic Linear Algebra Subprograms:
The New Standard from the BLAS Technical Forum
IAIN S. DUFF, CERFACS and Rutherford Appleton Laboratory
MICHAEL A. HEROUX, Sandia National Laboratories
ROLDAN POZO, National Institute of Standards and Technology
[dv_2002]:
Algorithm 818:
A Reference Model Implementation of the Sparse BLAS in Fortran 95
IAIN S. DUFF, CERFACS, France and Atlas Centre, RAL, England
CHRISTOF VĂ–MEL, CERFACS, France
Q: Is there an easy way to profile librsb usage in my application ?
A: Yes: build with --enable-librsb-stats and extract time elapsed in librsb
via e.g.: RSB_REINIT_SINGLE_VALUE_GET(RSB_IO_WANT_LIBRSB_ETIME,&dt,errval).
Q: Why another sparse matrix library ?
A: This library is the fruit of the author's PhD work, focused on researching
improved multi threaded and cache friendly matrix storage schemes for
PSBLAS.
Q: What are the key features of this library when compared to other ones ?
A: Recursive storage, a code generator, parallel BLAS operations
(including matrix assembly, matrix-matrix multiplication, transposed
matrix-vector multiply), a battery of tests, a Sparse BLAS
interface and a free software licensing.
Q: How do I detect librsb from my package's configure script ?
A: Add to your configure.ac:
AH_TEMPLATE([HAVE_LIBRSB])
AC_CHECK_FUNC([rsb_lib_init],AC_DEFINE([HAVE_LIBRSB],[1],[librsb detected]))
then rerun autoconf and invoke configure as:
./configure CFLAGS=`librsb-config --cflags` \
LDFLAGS=`librsb-config --ldflags --extra_libs`
Q: How is correctness checked in the librsb test suite ?
A: Different linear system generators and tester programs are being used to
brute-force-test several routines and input combinations as possible.
See 'make tests'; and run/edit the following tester programs if you are
curious:
test -f sbtc && ./sbtc||true # Sparse BLAS checker (C interface based)
test -f sbtf && ./sbtf||true # Sparse BLAS checker (Fortran interface, opt.)
./rsbench -Q 10.0 # 10 seconds brute-test
Q: Why did you write the library in C and not in C++ ?
A: Mainly...
Because C can be easily interfaced with C++ and Fortran.
Because using a debugger under full fledged C++ is a headache.
Because of the C's 'restrict' keyword.
Q: Why did you use C and not Fortran ?
A: This library is slightly system-oriented, and system calls interfacing is
much easier in C. Also C's pointers arithmetic support plays a crucial role.
Q: Is there a quick and easy way to perform an artificial performance
test with huge matrices without having to program ?
A: Sure. The following lines generate matrices of a specified dimension.
You can play with them by changing the matrix size, for instance.
./rsbench -oa -Ob -qH -R --dense 1 --verbose
./rsbench -oa -Ob -qH -R --dense 1024 --verbose
./rsbench -oa -Ob -qH -R --lower 1024 --as-symmetric --verbose
./rsbench -oa -Ob -qH -R --dense 1000 --gen-lband 10 --gen-uband 3
./rsbench -oa -Ob -qH -R --generate-diagonal 1000
Q: I've found a bug! What should I do ?
A: First please make sure it is really a bug: read the documentation, check,
double check.
Then you can write a description of the problem, with a minimal program
source code and data to replicate it.
Then you can jump to the CONTACTS details section.
Q: Is it possible to build matrices of, say, long double or
long double complex or int or short int ?
A: Yes, it's not a problem. You should invoke the configure script accordingly,
e.g.: --enable-matrix-types="long double".
If this breaks code compilation, feel free to contact the author
(see the CONTACTS section).
Q: Is there a way to compare the performance of this library to some other
high performance libraries ?
A: If you build rsbench with support for the Intel MKL library, then you
can do performance comparisons with e.g.:
# ./rsbench -oa -Ob -qH -R --gen-diag 100 --compare-competitors --verbose
or use the following script:
# bench/dense.sh ' '
Or even better, check out the --write-performance-record feature ; for
details see the output of:
# rsbench -oa -Ob --help
Q: Is there a non-threaded (serial) version of librsb ?
A: Yes: you can configure the library to work serially (with no OpenMP).
See ./configure --help.
Q: Is this library thread-safe ?
A: Probably yes: no static buffers are being used, and reentrant C standard
library functions are invoked.
Q: Does the librsb library run on GPUs or Intel MIC ?
A: It has been built on Intel MIC once, but not tested.
Q: I built and compiled the code without enabling any BLAS type (S,D,C,Z),
and both `make qtests' and `make tests' ran successfully outside the
./examples directory, but `make tests' breaks within ./examples directory.
A: Well, the tests passed because the examples testing was simply skipped.
The example programs need at least one of these types to work.
Q: At build time I get many "unused variable" warnings. Why ?
A: librsb accommodates many code generation and build time configuration
options. Some combinations may turn off compilation of certain parts of the
code, leading some variables to be unused.
Q: Are there papers to read about the RSB format and algorithms ?
A: Yes, the following:
Michele Martone
Efficient Multithreaded Untransposed, Transposed or Symmetric Sparse
Matrix-Vector Multiplication with the Recursive Sparse Blocks Format
Parallel Computing 40(7): 251-270 (2014)
http://dx.doi.org/10.1016/j.parco.2014.03.008
Michele Martone
Cache and Energy Efficiency of Sparse Matrix-Vector Multiplication for
Different BLAS Numerical Types with the RSB Format
Proceedings of the ParCo 2013 conference, September 2013, Munich, Germany
PARCO 2013: 193-202
http://dx.doi.org/10.3233/978-1-61499-381-0-193
Michele Martone, Marcin Paprzycki, Salvatore Filippone: An Improved Sparse
Matrix-Vector Multiply Based on Recursive Sparse Blocks Layout.
LSSC 2011: 606-613
http://dx.doi.org/10.1007/978-3-642-29843-1_69
Michele Martone, Salvatore Filippone, Salvatore Tucci, Marcin Paprzycki,
Maria Ganzha: Utilizing Recursive Storage in Sparse Matrix-Vector
Multiplication - Preliminary Considerations. CATA 2010: 300-305
Michele Martone, Salvatore Filippone, Marcin Paprzycki, Salvatore Tucci:
Assembling Recursively Stored Sparse Matrices. IMCSIT 2010: 317-325
http://www.proceedings2010.imcsit.org/pliks/205.pdf
Michele Martone, Salvatore Filippone, Pawel Gepner, Marcin Paprzycki,
Salvatore Tucci: Use of Hybrid Recursive CSR/COO Data Structures in Sparse
Matrices-Vector Multiplication. IMCSIT 2010: 327-335
http://dx.doi.org/10.1109/SYNASC.2010.72
Michele Martone, Salvatore Filippone, Marcin Paprzycki, Salvatore Tucci:
On BLAS Operations with Recursively Stored Sparse Matrices.
SYNASC 2010: 49-56
http://dx.doi.org/10.1109/SYNASC.2010.72
Michele Martone, Salvatore Filippone, Marcin Paprzycki, Salvatore Tucci:
On the Usage of 16 Bit Indices in Recursively Stored Sparse Matrices.
SYNASC 2010: 57-64
http://dx.doi.org/10.1109/SYNASC.2010.77
Q: I have M4-related problems on IBM SP5/SP6 (my M4 preprocessor tries to
regenerate code but it fails). What should I do ?
A: A fix is to use a GNU M4 implementation
e.g.: M4=/opt/freeware/bin/m4 ./configure ...
e.g.: M4=gm4 ./configure ...
or execute:
touch *.h ; touch *.c ; make
Or "./configure; make" the library on a different machine, then build
a sources archive with `make dist', and use it on the original machine.
--------------------------------------------------------------------------------
POSSIBLE / POTENTIAL FUTURE FEATURES / ENHANCEMENTS
--------------------------------------------------------------------------------
* auxiliary functions for numerical vectors
* CSC,BCSR,BCSC and other formats
* (optional) loop unrolled kernels for BCSR/BCSC
* performance prediction/estimation facilities (experimental)
* types of the blocks, nonzeroes, and coordinates indices can be user specified
* a code generator for BCSR, BCSC, VBR, VBC kernels
* full support for BCSR, BCSC storages
* automatic matrix blocking selection (for BCSR/BCSC)
* an arbitrary subset of block size kernels can be specified to be generated
* full support for VBR,VBC storages
* recursive storage variants of blocked formats (non uniform blocking)
* more auto-tuning and prediction control
* use of assembly functions or intrinsics
* the use of context variables (scenarios with multiple libraries using
librsb completely independently at the same time are not supported)
* enhanced in-place matrix assembly functions (useful for really huge matrices)
--------------------------------------------------------------------------------
ABOUT THE INTERNALS
--------------------------------------------------------------------------------
The following good practices are being followed during development of librsb.
- only symbols beginning with `rsb_' or `blas_' are being exported.
- internal functions are usually prefixed by `rsb__'.
- no library internal function shall call any API function.
If by using/inspecting the code you notice any of the above is being violated,
please report about it.
--------------------------------------------------------------------------------
BUGS
--------------------------------------------------------------------------------
If you encounter any bug (e.g.: mismatch of library/program behaviour and
documentation, please let me know about it by sending me (see CONTACTS) all
relevant information (code snippet, originating data/matrix, config.log), in
such a way that I can replicate the bug behaviour on my machines.
If the bug occurred when using rsb interfaced to some proprietary library,
please make sure the bug is in librsb.
It may be of great help to you to build the library with the debug compile
options on (e.g.: CFLAGS='-O0 -ggdb'), and with appropriate library verbosity
levels (--enable-internals-error-verbosity, --enable-interface-error-verbosity
and --enable-io-level options to configure) to better understand the program
behaviour before sending a report.
Make sure you have the latest version of the library when reporting a bug.
--------------------------------------------------------------------------------
CONTACTS
--------------------------------------------------------------------------------
You are welcome to contact the librsb author:
Michele Martone < michelemartone AT users DOT sourceforge DOT net >
Please specify "librsb" in the "Subject:" line of your emails.
More information and downloads on http://sourceforge.net/projects/librsb
Mailing list: https://lists.sourceforge.net/lists/listinfo/librsb-users
--------------------------------------------------------------------------------
CREDITS (in alphabetical order)
--------------------------------------------------------------------------------
For librsb-1.2:
Sebastian Koenig spotted a computational bug in -rc6.
Rafael Laboissiere helped improving the documentation.
Mu-Chu Lee provided a patch to fix sorting code crashing with > 10^9 nnz.
Marco Atzeri provided testing, patches to build librsb under cygwin and
spotted a few bugs.
For librsb-1.1:
Gilles Gouaillardet provided a patch for OpenMP-encapsulated I/O.
Marco Restelli provided with testing and detailed comments and suggestions.
For librsb-1.0:
Francis Casson helped with testing and documentation reviewing during the first
release.
Nitya Hariharan helped revising early versions of the documentation.
--------------------------------------------------------------------------------
LICENSE
--------------------------------------------------------------------------------
This software is distributed under the terms of the Lesser GNU Public License
version 3 (LGPLv3) or later.
See the COPYING file for a copy of the LGPLv3.
librsb is free software.
To support it, consider writing "thank you" to the author and acknowledging use
of librsb in your publications. That would be very appreciated.
--------------------------------------------------------------------------------
</pre><p><a class="anchor" id="examples_section"></a></p>
<p>For a quick startup, consider the following two programs.</p>
<p>The first, using the internal RSB interface: </p><div class="fragment"><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">Copyright (C) 2008-2015 Michele Martone</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">This file is part of librsb.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">librsb is free software; you can redistribute it and/or modify it</span></div><div class="line"><span class="comment">under the terms of the GNU Lesser General Public License as published</span></div><div class="line"><span class="comment">by the Free Software Foundation; either version 3 of the License, or</span></div><div class="line"><span class="comment">(at your option) any later version.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">librsb is distributed in the hope that it will be useful, but WITHOUT</span></div><div class="line"><span class="comment">ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or</span></div><div class="line"><span class="comment">FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public</span></div><div class="line"><span class="comment">License for more details.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">You should have received a copy of the GNU Lesser General Public</span></div><div class="line"><span class="comment">License along with librsb; see the file COPYING.</span></div><div class="line"><span class="comment">If not, see <http://www.gnu.org/licenses/>.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">*/</span><span class="comment"></span></div><div class="line"><span class="comment">/*!</span></div><div class="line"><span class="comment"> \ingroup rsb_doc_examples</span></div><div class="line"><span class="comment"> @file</span></div><div class="line"><span class="comment"> @author Michele Martone</span></div><div class="line"><span class="comment"> @brief This is a first "hello RSB" example program.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment"> \include hello.c</span></div><div class="line"><span class="comment">*/</span></div><div class="line"><span class="preprocessor">#include <<a class="code" href="rsb_8h.html">rsb.h</a>></span> <span class="comment">/* librsb header to include */</span></div><div class="line"><span class="preprocessor">#include <stdio.h></span> <span class="comment">/* printf() */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keyword">const</span> <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * <span class="keyword">const</span> argv[])</div><div class="line">{<span class="comment"></span></div><div class="line"><span class="comment"> /*!</span></div><div class="line"><span class="comment"> A Hello-RSB program.</span></div><div class="line"><span class="comment"> </span></div><div class="line"><span class="comment"> This program shows how to use the rsb.h interface correctly to:</span></div><div class="line"><span class="comment"> </span></div><div class="line"><span class="comment"> - initialize the library using #rsb_lib_init()</span></div><div class="line"><span class="comment"> - set library options using #rsb_lib_set_opt()</span></div><div class="line"><span class="comment"> - revert such changes </span></div><div class="line"><span class="comment"> - allocate (build) a single sparse matrix in the RSB format</span></div><div class="line"><span class="comment"> using #rsb_mtx_alloc_from_coo_const()</span></div><div class="line"><span class="comment"> - prints information obtained via #rsb_mtx_get_info_str()</span></div><div class="line"><span class="comment"> - multiply the matrix times a vector using #rsb_spmv()</span></div><div class="line"><span class="comment"> - deallocate the matrix using #rsb_mtx_free() </span></div><div class="line"><span class="comment"> - finalize the library using #rsb_lib_exit(RSB_NULL_EXIT_OPTIONS) </span></div><div class="line"><span class="comment"> </span></div><div class="line"><span class="comment"> In this example, we use #RSB_DEFAULT_TYPE as matrix type.</span></div><div class="line"><span class="comment"> This type depends on what was configured at library build time.</span></div><div class="line"><span class="comment"> * */</span></div><div class="line"> <span class="keyword">struct </span>rsb_mtx_t *mtxAp = NULL; <span class="comment">/* matrix structure pointer */</span></div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">int</span> bs = <a class="code" href="rsb_8h.html#a3579d00f3b97cd569707f7c62e462322">RSB_DEFAULT_BLOCKING</a>;</div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">int</span> brA = bs, bcA = bs;</div><div class="line"> <span class="keyword">const</span> <a class="code" href="rsb__types_8h.html#aa5e96f00841ec8f4f3ca1ff0bf1b5bbd">RSB_DEFAULT_TYPE</a> one = 1;</div><div class="line"> <a class="code" href="rsb_8h.html#ac0f6a03345c8874f6e50f0ed033d984b">rsb_type_t</a> typecode = <a class="code" href="rsb__types_8h.html#a56fc5ef14266266227797621e0a1e217">RSB_NUMERICAL_TYPE_DEFAULT</a>;</div><div class="line"> <a class="code" href="rsb_8h.html#a640e84bcc5268cd92d5d31fd6ac321b8">rsb_err_t</a> errval = <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>;</div><div class="line"> <span class="keyword">const</span> <a class="code" href="rsb_8h.html#a46b3366e54a5b4dda754a6ace22264df">rsb_nnz_idx_t</a> nnzA = 4; <span class="comment">/* matrix nonzeroes count */</span></div><div class="line"> <span class="keyword">const</span> <a class="code" href="rsb_8h.html#a4874ba61df0ff15b4395278496f83a5d">rsb_coo_idx_t</a> nrA = 3; <span class="comment">/* matrix rows count */</span></div><div class="line"> <span class="keyword">const</span> <a class="code" href="rsb_8h.html#a4874ba61df0ff15b4395278496f83a5d">rsb_coo_idx_t</a> ncA = 3; <span class="comment">/* matrix columns count */</span></div><div class="line"> <span class="comment">/* nonzero row indices coordinates: */</span></div><div class="line"> <a class="code" href="rsb_8h.html#a4874ba61df0ff15b4395278496f83a5d">rsb_coo_idx_t</a> IA[] = {0,1,2,2};</div><div class="line"> <span class="comment">/* nonzero column indices coordinates: */</span></div><div class="line"> <a class="code" href="rsb_8h.html#a4874ba61df0ff15b4395278496f83a5d">rsb_coo_idx_t</a> JA[] = {0,1,2,2};</div><div class="line"> <a class="code" href="rsb__types_8h.html#aa5e96f00841ec8f4f3ca1ff0bf1b5bbd">RSB_DEFAULT_TYPE</a> VA[] = {11,22,32,1};<span class="comment">/* values of nonzeroes */</span></div><div class="line"> <a class="code" href="rsb__types_8h.html#aa5e96f00841ec8f4f3ca1ff0bf1b5bbd">RSB_DEFAULT_TYPE</a> X[] = { 0, 0, 0 }; <span class="comment">/* X vector's array */</span></div><div class="line"> <span class="keyword">const</span> <a class="code" href="rsb__types_8h.html#aa5e96f00841ec8f4f3ca1ff0bf1b5bbd">RSB_DEFAULT_TYPE</a> B[] = { -1, -2, -5 }; <span class="comment">/* B vector's array */</span></div><div class="line"> <span class="keywordtype">char</span> ib[200];</div><div class="line"></div><div class="line"> printf(<span class="stringliteral">"Hello, RSB!\n"</span>);</div><div class="line"> printf(<span class="stringliteral">"Initializing the library...\n"</span>);</div><div class="line"> <span class="keywordflow">if</span>((errval = <a class="code" href="group__rsb__doc__rsb.html#gaf2b874d9f117ee6a6899634472b17946">rsb_lib_init</a>(<a class="code" href="rsb_8h.html#add105c42e570c5c269680d437f8c51e2">RSB_NULL_INIT_OPTIONS</a>)) != </div><div class="line"> <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>)</div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Error initializing the library!\n"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly initialized the library.\n"</span>);</div><div class="line"></div><div class="line"> printf(<span class="stringliteral">"Attempting to set the"</span></div><div class="line"> <span class="stringliteral">" RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE library option.\n"</span>);</div><div class="line"> {</div><div class="line"> <a class="code" href="rsb_8h.html#aefcdc7de885ab34a89a0d36470e11deb">rsb_int_t</a> evi=1; </div><div class="line"> <span class="comment">/* Setting a single optional library parameter. */</span></div><div class="line"> errval = <a class="code" href="rsb_8h.html#a2a08c5a23f3999fe8cf36440680e4a05">rsb_lib_set_opt</a>(</div><div class="line"> <a class="code" href="group__rsb__doc__rsb.html#ggae0bada88731b01751401847d60110fb6a56c0c6849135ce5fa9edd7907ab3e0cb">RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE</a>, &evi);</div><div class="line"> <span class="keywordflow">if</span>(errval != <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>)</div><div class="line"> {</div><div class="line"> <span class="keywordtype">char</span> errbuf[256];</div><div class="line"> <a class="code" href="group__rsb__doc__rsb.html#ga28710b8dade48738ea8e075aa1a3d262">rsb_strerror_r</a>(errval,&errbuf[0],<span class="keyword">sizeof</span>(errbuf));</div><div class="line"> printf(<span class="stringliteral">"Failed setting the"</span></div><div class="line"> <span class="stringliteral">" RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE"</span></div><div class="line"> <span class="stringliteral">" library option (reason string:\n%s).\n"</span>,errbuf);</div><div class="line"> <span class="keywordflow">if</span>(errval&<a class="code" href="rsb_8h.html#a4d8eb05488b681b75449f64c418b8893">RSB_ERRS_UNSUPPORTED_FEATURES</a>)</div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"This error may be safely ignored.\n"</span>);</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Some unexpected error occurred!\n"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> }</div><div class="line"> <span class="keywordflow">else</span></div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Setting back the "</span></div><div class="line"> <span class="stringliteral">"RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE"</span></div><div class="line"> <span class="stringliteral">" library option.\n"</span>);</div><div class="line"> evi = 0;</div><div class="line"> errval = <a class="code" href="rsb_8h.html#a2a08c5a23f3999fe8cf36440680e4a05">rsb_lib_set_opt</a>(<a class="code" href="group__rsb__doc__rsb.html#ggae0bada88731b01751401847d60110fb6a56c0c6849135ce5fa9edd7907ab3e0cb">RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE</a>,</div><div class="line"> &evi);</div><div class="line"> errval = <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>;</div><div class="line"> }</div><div class="line"> }</div><div class="line"></div><div class="line"> mtxAp = <a class="code" href="group__rsb__doc__rsb.html#ga86c1b0d0586f817ee31ca1caa3fee9be">rsb_mtx_alloc_from_coo_const</a>(</div><div class="line"> VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,</div><div class="line"> <a class="code" href="rsb_8h.html#a0ea7640214ee34c87e483c475b15827d">RSB_FLAG_NOFLAGS</a> <span class="comment">/* default format will be chosen */</span></div><div class="line"> |<a class="code" href="rsb_8h.html#afd1b39c625f4249cd32fccea38957f97">RSB_FLAG_DUPLICATES_SUM</a><span class="comment">/* duplicates will be summed */</span></div><div class="line"> ,&errval);</div><div class="line"> <span class="keywordflow">if</span>((!mtxAp) || (errval != <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>))</div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Error while allocating the matrix!\n"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly allocated a matrix.\n"</span>);</div><div class="line"> printf(<span class="stringliteral">"Summary information of the matrix:\n"</span>);</div><div class="line"> <span class="comment">/* print out the matrix summary information */</span></div><div class="line"> <a class="code" href="group__rsb__doc__rsb.html#ga2b7d51b9822f73d2fe7fcf5b9d0be1e9">rsb_mtx_get_info_str</a>(mtxAp,<span class="stringliteral">"RSB_MIF_MATRIX_INFO__TO__CHAR_P"</span>,</div><div class="line"> ib,<span class="keyword">sizeof</span>(ib));</div><div class="line"> printf(<span class="stringliteral">"%s"</span>,ib);</div><div class="line"> printf(<span class="stringliteral">"\n"</span>);</div><div class="line"></div><div class="line"> <span class="keywordflow">if</span>((errval = </div><div class="line"> <a class="code" href="group__rsb__doc__rsb.html#ga4a16a82d289c76a437915db449553d4d">rsb_spmv</a>(<a class="code" href="rsb__types_8h.html#a9673f34330af77b1c0fd4a585e0c62cc">RSB_TRANSPOSITION_N</a>,&one,mtxAp,B,1,&one,X,1))</div><div class="line"> != <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a> )</div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Error performing a multiplication!\n"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly performed a SPMV.\n"</span>);</div><div class="line"> <a class="code" href="group__rsb__doc__rsb.html#gab64a020286a8b58d23d84d4512bd9132">rsb_mtx_free</a>(mtxAp);</div><div class="line"> printf(<span class="stringliteral">"Correctly freed the matrix.\n"</span>);</div><div class="line"> <span class="keywordflow">if</span>((errval = <a class="code" href="group__rsb__doc__rsb.html#ga86db30487afe975ed18a7aa6ee0db81d">rsb_lib_exit</a>(<a class="code" href="rsb_8h.html#a2234a5e51156de6c95c3f8c2951ae09f">RSB_NULL_EXIT_OPTIONS</a>))</div><div class="line"> != <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>)</div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Error finalizing the library!\n"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly finalized the library.\n"</span>);</div><div class="line"> printf(<span class="stringliteral">"Program terminating with no error.\n"</span>);</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">err:</div><div class="line"> <a class="code" href="group__rsb__doc__rsb.html#gab660cf8aff876ae88b59c7a22ddfc912">rsb_perror</a>(NULL,errval);</div><div class="line"> printf(<span class="stringliteral">"Program terminating with error.\n"</span>);</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line">}</div><div class="line"></div></div><!-- fragment --><p>And the second, using the Sparse BLAS interface: </p><div class="fragment"><div class="line"><span class="comment">/*</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">Copyright (C) 2008-2015 Michele Martone</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">This file is part of librsb.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">librsb is free software; you can redistribute it and/or modify it</span></div><div class="line"><span class="comment">under the terms of the GNU Lesser General Public License as published</span></div><div class="line"><span class="comment">by the Free Software Foundation; either version 3 of the License, or</span></div><div class="line"><span class="comment">(at your option) any later version.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">librsb is distributed in the hope that it will be useful, but WITHOUT</span></div><div class="line"><span class="comment">ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or</span></div><div class="line"><span class="comment">FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public</span></div><div class="line"><span class="comment">License for more details.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">You should have received a copy of the GNU Lesser General Public</span></div><div class="line"><span class="comment">License along with librsb; see the file COPYING.</span></div><div class="line"><span class="comment">If not, see <http://www.gnu.org/licenses/>.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment">*/</span><span class="comment"></span></div><div class="line"><span class="comment">/*!</span></div><div class="line"><span class="comment"> \ingroup rsb_doc_examples</span></div><div class="line"><span class="comment"> @file</span></div><div class="line"><span class="comment"> @author Michele Martone</span></div><div class="line"><span class="comment"> @brief This is a first "hello RSB" example program using </span></div><div class="line"><span class="comment"> a Sparse BLAS interface.</span></div><div class="line"><span class="comment"></span></div><div class="line"><span class="comment"> \include hello-spblas.c</span></div><div class="line"><span class="comment">*/</span></div><div class="line"><span class="preprocessor">#include <<a class="code" href="rsb_8h.html">rsb.h</a>></span> <span class="comment">/* for rsb_lib_init */</span></div><div class="line"><span class="preprocessor">#include <<a class="code" href="blas__sparse_8h.html">blas_sparse.h</a>></span> <span class="comment">/* Sparse BLAS on the top of librsb */</span></div><div class="line"><span class="preprocessor">#include <stdio.h></span> <span class="comment">/* printf */</span></div><div class="line"></div><div class="line"><span class="keywordtype">int</span> main(<span class="keyword">const</span> <span class="keywordtype">int</span> argc, <span class="keywordtype">char</span> * <span class="keyword">const</span> argv[])</div><div class="line">{<span class="comment"></span></div><div class="line"><span class="comment"> /*!</span></div><div class="line"><span class="comment"> * A Hello/Sparse BLAS program.</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * This program shows how to use the blas_sparse.h</span></div><div class="line"><span class="comment"> * interface correctly to:</span></div><div class="line"><span class="comment"> *</span></div><div class="line"><span class="comment"> * - initialize the library using #rsb_lib_init()</span></div><div class="line"><span class="comment"> * - allocate (build) a single sparse matrix in the RSB</span></div><div class="line"><span class="comment"> * format using #BLAS_duscr_begin()/#BLAS_duscr_insert_entries()</span></div><div class="line"><span class="comment"> * /#BLAS_duscr_end()</span></div><div class="line"><span class="comment"> * - extract one matrix element with #BLAS_dusget_element()</span></div><div class="line"><span class="comment"> * - multiply the matrix times a vector using #BLAS_dusmv()</span></div><div class="line"><span class="comment"> * - deallocate the matrix using #BLAS_usds() </span></div><div class="line"><span class="comment"> * - finalize the library using</span></div><div class="line"><span class="comment"> * #rsb_lib_exit(#RSB_NULL_EXIT_OPTIONS) </span></div><div class="line"><span class="comment"> */</span></div><div class="line"><span class="preprocessor">#ifndef RSB_NUMERICAL_TYPE_DOUBLE </span></div><div class="line"> printf(<span class="stringliteral">"'double' type configured out."</span></div><div class="line"> <span class="stringliteral">" Please reconfigure the library with it and recompile.\n"</span>);</div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line"><span class="preprocessor">#else </span><span class="comment">/* RSB_NUMERICAL_TYPE_DOUBLE */</span><span class="preprocessor"></span></div><div class="line"> <a class="code" href="blas__sparse_8h.html#a6f56456b01e0cc6b25b81201aa67c163">blas_sparse_matrix</a> A = <a class="code" href="blas__sparse_8h.html#a7cb10fb1b47b79ef278d6f09d571bd06a51022d3d696b9aee38d51040a5b01da7">blas_invalid_handle</a>; <span class="comment">/* handle for A */</span></div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">int</span> nnz = 4; <span class="comment">/* number of nonzeroes of matrix A */</span></div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">int</span> nr = 3; <span class="comment">/* number of A's rows */</span></div><div class="line"> <span class="keyword">const</span> <span class="keywordtype">int</span> nc = 3; <span class="comment">/* number of A's columns */</span></div><div class="line"> <span class="comment">/* A's nonzero elements row indices (coordinates): */</span></div><div class="line"> <span class="keywordtype">int</span> IA[] = { 0, 1, 2, 2 };</div><div class="line"> <span class="comment">/* A's nonzero elements column indices (coordinates): */</span></div><div class="line"> <span class="keywordtype">int</span> JA[] = { 0, 1, 0, 2 };</div><div class="line"> <span class="comment">/* A's nonzero values (matrix coefficients): */</span></div><div class="line"> <span class="keywordtype">double</span> VA[] = { 11.0, 22.0, 13.0, 33.0 };</div><div class="line"> <span class="comment">/* the X vector's array: */</span></div><div class="line"> <span class="keywordtype">double</span> X[] = { 0.0, 0.0, 0.0 };</div><div class="line"> <span class="comment">/* the B vector's array: */</span></div><div class="line"> <span class="keywordtype">double</span> B[] = { -1.0, -2.0, -2.0 };</div><div class="line"> <span class="comment">/* the (known) result array: */</span></div><div class="line"> <span class="keywordtype">double</span> AB[] = { 11.0+26.0, 44.0, 66.0+13.0 };</div><div class="line"> <span class="comment">/* rsb error variable: */</span></div><div class="line"> <a class="code" href="rsb_8h.html#a640e84bcc5268cd92d5d31fd6ac321b8">rsb_err_t</a> errval = <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>;</div><div class="line"> <span class="keywordtype">int</span> i;</div><div class="line"></div><div class="line"> printf(<span class="stringliteral">"Hello, RSB!\n"</span>);</div><div class="line"> <span class="comment">/* initialize the library */</span></div><div class="line"> <span class="keywordflow">if</span>((errval = <a class="code" href="group__rsb__doc__rsb.html#gaf2b874d9f117ee6a6899634472b17946">rsb_lib_init</a>(<a class="code" href="rsb_8h.html#add105c42e570c5c269680d437f8c51e2">RSB_NULL_INIT_OPTIONS</a>)) </div><div class="line"> != <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly initialized the library.\n"</span>);</div><div class="line"></div><div class="line"> <span class="comment">/* initialize a matrix descriptor */</span></div><div class="line"> A = <a class="code" href="group__rsb__doc__sparse__blas.html#gac931dcb1129ee3016ab82602c3d14fee">BLAS_duscr_begin</a>(nr,nc);</div><div class="line"> <span class="keywordflow">if</span>( A == <a class="code" href="blas__sparse_8h.html#a7cb10fb1b47b79ef278d6f09d571bd06a51022d3d696b9aee38d51040a5b01da7">blas_invalid_handle</a> )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> </div><div class="line"> <span class="comment">/* specify properties (e.g.: symmetry)*/</span></div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="blas__sparse_8h.html#a6719ae77dfef6d6dd0790e34a65c1924">BLAS_ussp</a>(A,<a class="code" href="blas__sparse_8h.html#a7da08ccc1c4c7f5ff40768d502a6e63baba96b7c19a0ccfe3be9d78cb27690487">blas_lower_symmetric</a>) != 0 )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/* get properties (e.g.: symmetry) */</span></div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="blas__sparse_8h.html#a5eec91b6d95962811bd9cb4e37266214">BLAS_usgp</a>(A,<a class="code" href="blas__sparse_8h.html#a7da08ccc1c4c7f5ff40768d502a6e63baba96b7c19a0ccfe3be9d78cb27690487">blas_lower_symmetric</a>) != 1 )</div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Symmetry property non set ?!\n"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/* insert the nonzeroes (here, all at once) */</span></div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__rsb__doc__sparse__blas.html#gae0683bc8f0af5dd3e53b964190f9e1b4">BLAS_duscr_insert_entries</a>(A, nnz, VA, IA, JA)</div><div class="line"> == <a class="code" href="blas__sparse_8h.html#a7cb10fb1b47b79ef278d6f09d571bd06a51022d3d696b9aee38d51040a5b01da7">blas_invalid_handle</a>)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/* finalize (allocate) the matrix build */</span></div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__rsb__doc__sparse__blas.html#ga5d9ce97bf054b1e3750eaae5d4e6c335">BLAS_duscr_end</a>(A) == <a class="code" href="blas__sparse_8h.html#a7cb10fb1b47b79ef278d6f09d571bd06a51022d3d696b9aee38d51040a5b01da7">blas_invalid_handle</a> )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly allocated a matrix.\n"</span>);</div><div class="line"></div><div class="line"> VA[0] = 0.0;</div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__rsb__doc__sparse__blas.html#gacf35fa073f6cc991efe75f6a012a9a04">BLAS_dusget_element</a>(A, IA[0], JA[0], &VA[0]) )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/* a check */</span></div><div class="line"> <span class="keywordflow">if</span>( VA[0] != 11.0 )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">/* compute X = X + (-1) * A * B */</span></div><div class="line"> <span class="keywordflow">if</span>(<a class="code" href="group__rsb__doc__sparse__blas.html#ga9a8f45ddd3c890a296239b212f0c033b">BLAS_dusmv</a>(<a class="code" href="blas__sparse_8h.html#a23e5e138364c80074ac014a3dfd346b7a60c827bef60beeea296c26486e28d85f">blas_no_trans</a>,-1,A,B,1,X,1))</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keywordflow">for</span>( i = 0 ; i < nc; ++i )</div><div class="line"> <span class="keywordflow">if</span>( X[i] != AB[i] )</div><div class="line"> {</div><div class="line"> printf(<span class="stringliteral">"Computed SPMV result seems wrong. Terminating.\n"</span>);</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly performed a SPMV.\n"</span>);</div><div class="line"></div><div class="line"> <span class="comment">/* deallocate matrix A */</span></div><div class="line"> <span class="keywordflow">if</span>( <a class="code" href="group__rsb__doc__sparse__blas.html#ga8b0cca8196f40f7b55084a978b40717f">BLAS_usds</a>(A) )</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly freed the matrix.\n"</span>);</div><div class="line"></div><div class="line"> <span class="comment">/* finalize the library */</span></div><div class="line"> <span class="keywordflow">if</span>((errval = <a class="code" href="group__rsb__doc__rsb.html#ga86db30487afe975ed18a7aa6ee0db81d">rsb_lib_exit</a>(<a class="code" href="rsb_8h.html#a2234a5e51156de6c95c3f8c2951ae09f">RSB_NULL_EXIT_OPTIONS</a>))</div><div class="line"> != <a class="code" href="rsb_8h.html#a1ad3f986b2e84249785751bf42ff3f8a">RSB_ERR_NO_ERROR</a>)</div><div class="line"> {</div><div class="line"> <span class="keywordflow">goto</span> err;</div><div class="line"> }</div><div class="line"> printf(<span class="stringliteral">"Correctly finalized the library.\n"</span>);</div><div class="line"> printf(<span class="stringliteral">"Program terminating with no error.\n"</span>);</div><div class="line"></div><div class="line"> <span class="keywordflow">return</span> 0;</div><div class="line">err:</div><div class="line"> <a class="code" href="group__rsb__doc__rsb.html#gab660cf8aff876ae88b59c7a22ddfc912">rsb_perror</a>(NULL,errval);</div><div class="line"> printf(<span class="stringliteral">"Program terminating with error.\n"</span>);</div><div class="line"> <span class="keywordflow">return</span> -1;</div><div class="line"><span class="preprocessor">#endif </span><span class="comment">/* RSB_NUMERICAL_TYPE_DOUBLE */</span><span class="preprocessor"></span></div><div class="line">}</div><div class="line"></div></div><!-- fragment --><p>For more, see the <a class="el" href="group__rsb__doc__examples.html">Example programs and code</a> section. </p>
</div></div><!-- contents -->
<!-- start footer part -->
<hr class="footer"/><address class="footer"><small>
Generated by  <a href="http://www.doxygen.org/index.html">
<img class="footer" src="doxygen.png" alt="doxygen"/>
</a> 1.8.13
</small></address>
</body>
</html>
|