.TH "rsb-examples" 3 "Sun Jan 1 2023" "Version 1.3.0.2" "librsb" \" -*- nroff -*-
.ad l
.nh
.SH NAME
librsb -
rsb-examples \- Example programs and code
.SH DESCRIPTION
.PP
\- Examples of usage of \fClibrsb\fP in C (<\fBrsb\&.h\fP> and <\fBblas_sparse\&.h\fP>), C++ (optional <\fBrsb\&.hpp\fP>), Fortran (<\fBrsb\&.F90\fP> and <\fBrsb_blas_sparse\&.F90\fP>)\&.
.SH SYNOPSIS
.br
.PP
.SS "Files"
.in +1c
.ti -1c
.RI "file \fBassemble\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> assembling \fBRsbMatrix\fP by pieces\&. "
.ti -1c
.RI "file \fBautotune\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> for performance-benchmarking a matrix from file using \fBRsbMatrix\&.tune_spmm()\fP, for various right-hand side counts\&. "
.ti -1c
.RI "file \fBbench\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> for performance-benchmarking a matrix from file using \fBRsbMatrix\&.spmm()\fP, for various right-hand side counts\&. "
.ti -1c
.RI "file \fBbuild\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> using timings for common matrix operations on \fBRsbMatrix\fP: \fBRsbMatrix\&.get_coo()\fP, \fBrsb_coo_sort()\fP, \fBrsb_time()\fP\&. "
.ti -1c
.RI "file \fBexample\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> using \fBRsbMatrix\&.spmm()\fP\&. "
.ti -1c
.RI "file \fBmisc\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> showing various \fBRsbMatrix\fP operations\&. "
.ti -1c
.RI "file \fBmtx2bin\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> converting a Matrix Market file into a custom format using \fBRsbMatrix\&.get_coo()\fP\&. "
.ti -1c
.RI "file \fBrender\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> of invoking the autotuner on an \fBRsbMatrix\fP matrix with \fBRsbMatrix\&.tune_spmm()\fP and rendering it with \fBRsbMatrix\&.rndr()\fP\&. "
.ti -1c
.RI "file \fBspan\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> illustrating use of \fBRsbMatrix\&.file_save()\fP, and std::span-based versions of \fBRsbMatrix\&.tune_spmm()\fP, \fBRsbMatrix\&.spmv()\fP\&. "
.ti -1c
.RI "file \fBtwonnz\&.cpp\fP"
.br
.RI "C++ example based on <\fBrsb\&.hpp\fP> measuring \fBRsbMatrix\&.spmm()\fP performance of a matrix with only two elements; this is is effectively measuring performance of result vector scaling\&. "
.ti -1c
.RI "file \fBautotune\&.c\fP"
.br
.RI "C 'RSB autotune' example program based on <\fBrsb\&.h\fP>\&. uses \fBrsb_file_mtx_load()\fP, \fBrsb_spmm()\fP, \fBrsb_tune_spmm()\fP\&. "
.ti -1c
.RI "file \fBbacksolve\&.c\fP"
.br
.RI "C triangular solve example program\&. Uses \fBrsb_spsv()\fP,\fBrsb_tune_spsm()\fP\&. Based on <\fBrsb\&.h\fP>\&. "
.ti -1c
.RI "file \fBcplusplus\&.cpp\fP"
.br
.RI "C++ program using the C <\fBrsb\&.h\fP> interface\&. Uses \fBrsb_tune_spmm()\fP, \fBrsb_spmv()\fP\&. "
.ti -1c
.RI "file \fBhello\-spblas\&.c\fP"
.br
.RI "A first C 'hello RSB' example program using a Sparse BLAS interface and <\fBrsb\&.h\fP>\&. Uses \fBBLAS_duscr_begin()\fP, \fBBLAS_ussp()\fP, \fBBLAS_usgp()\fP, \fBBLAS_duscr_insert_entries()\fP, \fBBLAS_duscr_end()\fP, \fBBLAS_dusget_element()\fP,\fBBLAS_dusmv()\fP,\fBBLAS_usds()\fP\&. "
.ti -1c
.RI "file \fBhello\&.c\fP"
.br
.RI "A first 'hello RSB' example C program based on <\fBrsb\&.h\fP>\&. Uses \fBrsb_lib_set_opt()\fP, \fBrsb_mtx_get_info_str()\fP\&. "
.ti -1c
.RI "file \fBio\-spblas\&.c\fP"
.br
.RI "Example C program using the Sparse BLAS interface and reading from file using \fBrsb_blas_file_mtx_load()\fP, \fBBLAS_usgp()\fP, \fBBLAS_dusmv()\fP, \fBBLAS_usds()\fP\&. "
.ti -1c
.RI "file \fBpower\&.c\fP"
.br
.RI "A toy <\fBrsb\&.h\fP>-based C program implementing the power method for computing matrix eigenvalues\&. Uses \fBrsb_spmv()\fP\&. "
.ti -1c
.RI "file \fBsnippets\&.c\fP"
.br
.RI "Collection of C snippets of other examples\&. Used piecewise the documentation\&. Not intended to be read as example\&. "
.ti -1c
.RI "file \fBtranspose\&.c\fP"
.br
.RI "A toy <\fBrsb\&.h\fP>-based C program showing instantiation, transposition and other operations on a single matrix\&. Uses \fBrsb_mtx_clone()\fP, \fBrsb_file_mtx_save()\fP, \fBrsb_file_mtx_get_dims()\fP, \fBrsb_file_mtx_load()\fP\&. "
.in -1c
.SH "Detailed Description"
.PP
Examples of usage of \fClibrsb\fP in C (<\fBrsb\&.h\fP> and <\fBblas_sparse\&.h\fP>), C++ (optional <\fBrsb\&.hpp\fP>), Fortran (<\fBrsb\&.F90\fP> and <\fBrsb_blas_sparse\&.F90\fP>)\&.
.PP
.nf
The following fully working example programs illustrate correct ways of using the library\&.
.fi
.PP
.IP "\(bu" 2
First example in C, using <\fBrsb\&.h\fP>: \fBexamples_hello_c\fP\&.
.IP "\(bu" 2
First example in C, using <\fBblas_sparse\&.h\fP>: \fBexamples_hello_spblas_c\fP\&.
.IP "\(bu" 2
Autotuning example in C, using <\fBrsb\&.h\fP>: \fBexamples_autotune_c\fP\&.
.IP "\(bu" 2
I/O example in C, using <\fBblas_sparse\&.h\fP>: \fBexamples_io_spblas_c\fP\&.
.IP "\(bu" 2
Example transposing a matrix in C, using <\fBrsb\&.h\fP> in C: \fBexamples_transpose_c\fP\&.
.IP "\(bu" 2
Example showing the power method in C, using <\fBrsb\&.h\fP> in C: \fBexamples_power_c\fP\&.
.IP "\(bu" 2
Example in Fortran, using <\fBrsb_blas_sparse\&.F90\fP>: \fBexamples_fortran_F90\fP\&.
.IP "\(bu" 2
Example in Fortran, using <\fBrsb\&.F90\fP>: \fBexamples_fortran_rsb_fi_F90\fP\&.
.IP "\(bu" 2
Example in C, using <\fBrsb\&.h\fP>: \fBexamples_backsolve_c\fP\&.
.IP "\(bu" 2
Misc example snippets in C, using <\fBrsb\&.h\fP>: \fBexamples_snippets_c\fP\&.
.IP "\(bu" 2
Benchmark invocation from shell script: \fBexamples_bench_sh\fP\&.
.PP
.PP
Once installed \fClibrsb\fP, the script displayed here (\fBexamples/make\&.sh\fP) should be sufficient to build these examples:
.PP
.nf
#!/bin/bash
# Example script to build the librsb example programs\&.
# Uses librsb-config in the $PATH for build flags\&.
# Environment-provided $LIBRSB_CONFIG override that\&.
set -e
set -x
srcdir=${srcdir:-`pwd`}
builddir=${builddir:-`pwd`}
prefix="/usr"
exec_prefix="${prefix}"
bindir="${exec_prefix}/bin"
if test -z "${LIBRSB_CONFIG}"; then
export PATH="${bindir}:$PATH"
fi
LIBRSB_CONFIG=${LIBRSB_CONFIG:-librsb-config}
PKG_CONFIG=pkg-config
WANT_PKGCONFIG="yes"
WANT_CLEANUP=${WANT_CLEANUP:-false}
if test x"yes" == x"yes" ; then
CXX="`${LIBRSB_CONFIG} --cxx`"
if test x"rsblib" != x"" -a x"${CXX}" != x"" ; then
for s in ${srcdir}/*\&.cpp
do
p=${builddir}/`basename ${s/\&.cpp/}`
rm -f $p
CXXFLAGS=`${LIBRSB_CONFIG} --cxxflags --I_opts`
LDFLAGS=`${LIBRSB_CONFIG} --ldflags --extra_libs`
LINK=`${LIBRSB_CONFIG} --link`
o="${p}\&.o"
ccmd="$CXX $CXXFLAGS -c $s -o $o"
lcmd="$LINK $o $LDFLAGS -o $p"
echo "$ccmd && $lcmd"
( $ccmd && $lcmd )
${WANT_CLEANUP} && rm -f "$p"
# one may use a single command, but that's error-prone (may miss libraries):
#cmd="$CXX $CXXFLAGS $s $LDFLAGS -o $p"
#echo $cmd
#$cmd
done
fi
fi
if test x"yes" == x"yes" ; then
for s in ${srcdir}/*\&.c
do
p=`basename ${s/\&.c/}`
if test $p == hello-spblas -a x"yes" != x"yes" ; then continue; fi
if test $p == io-spblas -a x"yes" != x"yes" ; then continue; fi
rm -f $p
CFLAGS=`${LIBRSB_CONFIG} --I_opts --cppflags`
LDFLAGS=`${LIBRSB_CONFIG} --ldflags --extra_libs`
CC=`${LIBRSB_CONFIG} --cc`
LINK=`${LIBRSB_CONFIG} --link`
o="${p}\&.o"
ccmd="$CC $CFLAGS -c $s -o $o"
lcmd="$LINK $o $LDFLAGS -o $p"
echo "$ccmd && $lcmd"
( $ccmd && $lcmd )
${WANT_CLEANUP} && rm -f "$p"
# one may use a single command, but that's error-prone (may miss libraries):
#cmd="$CC $CFLAGS $s $LDFLAGS -o $p"
#echo $cmd
#$cmd
if test x"${WANT_PKGCONFIG}" != x"no" ; then
CFLAGS=`${PKG_CONFIG} --cflags librsb`
LIBS=`${PKG_CONFIG} --libs --static librsb`
ccmd="$CC $CFLAGS -c $s -o $o"
lcmd="$LINK $o $LIBS -o $p"
${WANT_CLEANUP} && rm -f "$p"
echo "$ccmd && $lcmd"
( $ccmd && $lcmd )
fi
done
fi
if test x"yes" == x"yes" ; then
if test x"yes" = x"yes" ; then
FP=${srcdir}/fortran_rsb_fi\&.F90
if test x"yes" = x"yes" ; then
FP+=\ ${srcdir}/fortran\&.F90
fi
# activated if you have built the Fortran modules and installed them in the right path\&.
for s in $FP
do
p=`basename ${s/\&.F90/}`
rm -f $p
FCFLAGS=`${LIBRSB_CONFIG} --I_opts --fcflags`
LDFLAGS=`${LIBRSB_CONFIG} --ldflags --extra_libs`
FC=`${LIBRSB_CONFIG} --fc`
LINK=`${LIBRSB_CONFIG} --link`
o="${p}\&.o"
FCLIBS=`${LIBRSB_CONFIG} --fclibs`
ccmd="$FC $FCFLAGS -c $s -o $o"
lcmd="$LINK $o $LDFLAGS $FCLIBS -o $p"
echo "$ccmd && $lcmd"
( $ccmd && $lcmd )
${WANT_CLEANUP} && rm -f "$p"
done
fi
fi
echo " [*] done building examples!"
.fi
.PP
.PP
\fBexamples/hello\&.c\fP:
.PP
.nf
/*
Copyright (C) 2008-2021 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 \&.
*/
/*!
\ingroup rsb-examples
@file
@author Michele Martone
@brief A first "hello RSB" example C program based on \&.
Uses #rsb_lib_set_opt(), #rsb_mtx_get_info_str()\&.
\include hello\&.c
*/
#include /* librsb header to include */
#include /* printf() */
int main(const int argc, char * const argv[])
{
/*!
A Hello-RSB program\&.
This program shows how to use the rsb\&.h interface correctly to:
- initialize the library using #rsb_lib_init()
- set library options using #rsb_lib_set_opt()
- revert such changes
- allocate (build) a single sparse matrix in the RSB format
using #rsb_mtx_alloc_from_coo_const()
- prints information obtained via #rsb_mtx_get_info_str()
- multiply the matrix times a vector using #rsb_spmv()
- deallocate the matrix using #rsb_mtx_free()
- finalize the library using #rsb_lib_exit()
In this example, we use #RSB_DEFAULT_TYPE as matrix type\&.
This type depends on what was configured at library build time\&.
* */
const rsb_blk_idx_t bs = RSB_DEFAULT_BLOCKING;
const rsb_blk_idx_t brA = bs, bcA = bs;
const RSB_DEFAULT_TYPE one = 1;
const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
const rsb_nnz_idx_t nnzA = 4; /* matrix nonzeroes count */
const rsb_coo_idx_t nrA = 3; /* matrix rows count */
const rsb_coo_idx_t ncA = 3; /* matrix columns count */
/* nonzero row indices coordinates: */
const rsb_coo_idx_t IA[] = {0,1,2,2};
/* nonzero column indices coordinates: */
const rsb_coo_idx_t JA[] = {0,1,2,2};
const RSB_DEFAULT_TYPE VA[] = {11,22,32,1};/* values of nonzeroes */
RSB_DEFAULT_TYPE X[] = { 0, 0, 0 }; /* X vector's array */
const RSB_DEFAULT_TYPE B[] = { -1, -2, -5 }; /* B vector's array */
char ib[200];
struct rsb_mtx_t *mtxAp = NULL; /* matrix structure pointer */
rsb_err_t errval = RSB_ERR_NO_ERROR;
printf("Hello, RSB!\n");
printf("Initializing the library\&.\&.\&.\n");
if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS)) !=
RSB_ERR_NO_ERROR)
{
printf("Error initializing the library!\n");
goto err;
}
printf("Correctly initialized the library\&.\n");
printf("Attempting to set the"
" RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE library option\&.\n");
{
rsb_int_t evi=1;
/* Setting a single optional library parameter\&. */
errval = rsb_lib_set_opt(
RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE, &evi);
if(errval != RSB_ERR_NO_ERROR)
{
char errbuf[256];
rsb_strerror_r(errval,&errbuf[0],sizeof(errbuf));
printf("Failed setting the"
" RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE"
" library option (reason string:\n%s)\&.\n",errbuf);
if(errval&RSB_ERRS_UNSUPPORTED_FEATURES)
{
printf("This error may be safely ignored\&.\n");
}
else
{
printf("Some unexpected error occurred!\n");
goto err;
}
}
else
{
printf("Setting back the "
"RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE"
" library option\&.\n");
evi = 0;
errval = rsb_lib_set_opt(RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE,
&evi);
errval = RSB_ERR_NO_ERROR;
}
}
mtxAp = rsb_mtx_alloc_from_coo_const(
VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
RSB_FLAG_NOFLAGS /* default format will be chosen */
|RSB_FLAG_DUPLICATES_SUM/* duplicates will be summed */
,&errval);
if((!mtxAp) || (errval != RSB_ERR_NO_ERROR))
{
printf("Error while allocating the matrix!\n");
goto err;
}
printf("Correctly allocated a matrix\&.\n");
printf("Summary information of the matrix:\n");
/* print out the matrix summary information */
rsb_mtx_get_info_str(mtxAp,"RSB_MIF_MATRIX_INFO__TO__CHAR_P",
ib,sizeof(ib));
printf("%s",ib);
printf("\n");
if((errval =
rsb_spmv(RSB_TRANSPOSITION_N,&one,mtxAp,B,1,&one,X,1))
!= RSB_ERR_NO_ERROR )
{
printf("Error performing a multiplication!\n");
goto err;
}
printf("Correctly performed a SPMV\&.\n");
rsb_mtx_free(mtxAp);
printf("Correctly freed the matrix\&.\n");
if((errval = rsb_lib_exit(RSB_NULL_EXIT_OPTIONS))
!= RSB_ERR_NO_ERROR)
{
printf("Error finalizing the library!\n");
goto err;
}
printf("Correctly finalized the library\&.\n");
printf("Program terminating with no error\&.\n");
return EXIT_SUCCESS;
err:
rsb_perror(NULL,errval);
printf("Program terminating with error\&.\n");
return EXIT_FAILURE;
}
.fi
.PP
.PP
\fBexamples/hello-spblas\&.c\fP:
.PP
.nf
/*
Copyright (C) 2008-2021 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 \&.
*/
/*!
\ingroup rsb-examples
@file
@author Michele Martone
@brief A first C "hello RSB" example program using
a Sparse BLAS interface and \&.
Uses #BLAS_duscr_begin(), #BLAS_ussp(), #BLAS_usgp(),
#BLAS_duscr_insert_entries(), #BLAS_duscr_end(),
#BLAS_dusget_element(),#BLAS_dusmv(),#BLAS_usds()\&.
\include hello-spblas\&.c
*/
#include /* for rsb_lib_init */
#include /* Sparse BLAS on the top of librsb */
#include /* printf */
int main(const int argc, char * const argv[])
{
/*!
* A Hello/Sparse BLAS program\&.
*
* This program shows how to use the blas_sparse\&.h
* interface correctly to:
*
* - initialize the library using #rsb_lib_init()
* - allocate (build) a single sparse matrix in the RSB
* format using #BLAS_duscr_begin()/#BLAS_duscr_insert_entries()
* /#BLAS_duscr_end()
* - extract one matrix element with #BLAS_dusget_element()
* - multiply the matrix times a vector using #BLAS_dusmv()
* - deallocate the matrix using #BLAS_usds()
* - finalize the library using
* #rsb_lib_exit(#RSB_NULL_EXIT_OPTIONS)
*/
#ifndef RSB_NUMERICAL_TYPE_DOUBLE
printf("'double' type configured out\&."
" Please reconfigure the library with it and recompile\&.\n");
return EXIT_SUCCESS;
#else /* RSB_NUMERICAL_TYPE_DOUBLE */
blas_sparse_matrix A = blas_invalid_handle; /* handle for A */
const int nnz = 4; /* number of nonzeroes of matrix A */
const int nr = 3; /* number of A's rows */
const int nc = 3; /* number of A's columns */
/* A's nonzero elements row indices (coordinates): */
#ifdef RSB_WANT_LONG_IDX_TYPE
const int64_t IA[] = { 0, 1, 2, 2 };
#else /* RSB_WANT_LONG_IDX_TYPE */
const int IA[] = { 0, 1, 2, 2 };
#endif /* RSB_WANT_LONG_IDX_TYPE */
/* A's nonzero elements column indices (coordinates): */
#ifdef RSB_WANT_LONG_IDX_TYPE
const int64_t JA[] = { 0, 1, 0, 2 };
#else /* RSB_WANT_LONG_IDX_TYPE */
const int JA[] = { 0, 1, 0, 2 };
#endif /* RSB_WANT_LONG_IDX_TYPE */
/* A's nonzero values (matrix coefficients): */
double VA[] = { 11\&.0, 22\&.0, 13\&.0, 33\&.0 };
/* the X vector's array: */
double X[] = { 0\&.0, 0\&.0, 0\&.0 };
/* the B vector's array: */
const double B[] = { -1\&.0, -2\&.0, -2\&.0 };
/* the (known) result array: */
const double AB[] = { 11\&.0+26\&.0, 44\&.0, 66\&.0+13\&.0 };
/* rsb error variable: */
rsb_err_t errval = RSB_ERR_NO_ERROR;
int i;
printf("Hello, RSB!\n");
/* initialize the library */
if((errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS))
!= RSB_ERR_NO_ERROR)
{
goto err;
}
printf("Correctly initialized the library\&.\n");
/* initialize a matrix descriptor */
A = BLAS_duscr_begin(nr,nc);
if( A == blas_invalid_handle )
{
goto err;
}
/* specify properties (e\&.g\&.: symmetry)*/
if( BLAS_ussp(A,blas_lower_symmetric) != 0 )
{
goto err;
}
/* get properties (e\&.g\&.: symmetry) */
if( BLAS_usgp(A,blas_lower_symmetric) != 1 )
{
printf("Symmetry property non set ?!\n");
goto err;
}
/* insert the nonzeroes (here, all at once) */
if( BLAS_duscr_insert_entries(A, nnz, VA, IA, JA)
== blas_invalid_handle)
{
goto err;
}
/* finalize (allocate) the matrix build */
if( BLAS_duscr_end(A) == blas_invalid_handle )
{
goto err;
}
printf("Correctly allocated a matrix\&.\n");
VA[0] = 0\&.0;
if( BLAS_dusget_element(A, IA[0], JA[0], &VA[0]) )
{
goto err;
}
/* a check */
if( VA[0] != 11\&.0 )
{
goto err;
}
/* compute X = X + (-1) * A * B */
if(BLAS_dusmv(blas_no_trans,-1,A,B,1,X,1))
{
goto err;
}
for( i = 0 ; i < nc; ++i )
if( X[i] != AB[i] )
{
printf("Computed SPMV result seems wrong\&. Terminating\&.\n");
goto err;
}
printf("Correctly performed a SPMV\&.\n");
/* deallocate matrix A */
if( BLAS_usds(A) )
{
goto err;
}
printf("Correctly freed the matrix\&.\n");
/* finalize the library */
if((errval = rsb_lib_exit(RSB_NULL_EXIT_OPTIONS))
!= RSB_ERR_NO_ERROR)
{
goto err;
}
printf("Correctly finalized the library\&.\n");
printf("Program terminating with no error\&.\n");
return EXIT_SUCCESS;
err:
rsb_perror(NULL,errval);
printf("Program terminating with error\&.\n");
return EXIT_FAILURE;
#endif /* RSB_NUMERICAL_TYPE_DOUBLE */
}
.fi
.PP
.PP
\fBexamples/autotune\&.c\fP:
.PP
.nf
/*
Copyright (C) 2008-2021 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 \&.
*/
/*!
\ingroup rsb-examples
@file
@author Michele Martone
@brief C "RSB autotune" example program based on \&.
uses #rsb_file_mtx_load(), rsb_spmm(), rsb_tune_spmm()\&.
\include autotune\&.c
*/
#include /* librsb header to include */
#include /* printf() */
#include /* isdigit() */
#include /* atoi() */
/* #include "rsb_internals\&.h" */
static int tune_from_file(char * const filename, rsb_int_t wvat)
{
struct rsb_mtx_t *mtxMp = NULL;
/* spmv specific variables */
const void * alphap = NULL; // equivalent to 1
const void * betap = NULL; // equivalent to 1
rsb_flags_t order = RSB_FLAG_WANT_COLUMN_MAJOR_ORDER;
const rsb_coo_idx_t nrhs = 2; /* number of right hand sides */
rsb_trans_t transA = RSB_TRANSPOSITION_N; /* transposition */
rsb_nnz_idx_t ldB = 0;
rsb_nnz_idx_t ldC = 0;
/* misc variables */
rsb_err_t errval = RSB_ERR_NO_ERROR;
rsb_time_t dt;
char ib[200];
const char*is = "RSB_MIF_MATRIX_INFO__TO__CHAR_P";
/* misc variables */
/* input autotuning variables */
rsb_int_t oitmax = 1 /*15*/; /* auto-tune iterations */
rsb_time_t tmax = 0\&.1; /* time per autotune operation */
/* output autotuning variables */
rsb_flags_t flagsA = RSB_FLAG_NOFLAGS;
/* int ione = 1; */
rsb_type_t typecodea [] = RSB_MATRIX_TYPE_CODES_ARRAY;
int typecodei;
errval = rsb_lib_init(RSB_NULL_INIT_OPTIONS);
if( (errval) != RSB_ERR_NO_ERROR )
goto err;
errval = rsb_lib_set_opt(RSB_IO_WANT_VERBOSE_TUNING, &wvat );
/*
errval = rsb_lib_set_opt(RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE, &ione);
*/
if( (errval) != RSB_ERR_NO_ERROR )
goto err;
printf("Loading matrix from file \"%s\"\&.\n",filename);
mtxMp = rsb_file_mtx_load(filename, flagsA, typecodea[0], &errval);
if( (errval) != RSB_ERR_NO_ERROR )
goto err;
for( typecodei = 0 ; typecodei < RSB_IMPLEMENTED_TYPES; ++typecodei )
{
rsb_type_t typecode = typecodea[typecodei];
struct rsb_mtx_t *mtxAp = NULL;
struct rsb_mtx_t *mtxOp = NULL;
rsb_real_t sf = 0\&.0;
rsb_int_t tn = 0;
sf = 0\&.0;
tn = 0;
printf("Considering %c clone\&.\n",typecode);
errval = rsb_mtx_clone(&mtxAp, typecode, transA, NULL, mtxMp,
flagsA);
if( (errval) != RSB_ERR_NO_ERROR )
goto err;
printf("Base matrix:\n");
rsb_mtx_get_info_str(mtxAp,is,ib,sizeof(ib));
printf("%s\n\n",ib);
dt = -rsb_time();
errval = rsb_tune_spmm(NULL, &sf, &tn, oitmax, tmax, transA,
alphap, mtxAp, nrhs, order, NULL, ldB, betap, NULL, ldC);
dt += rsb_time();
if(tn == 0)
printf("After %lfs, autotuning routine did not find a better"
" threads count configuration\&.\n",dt);
else
printf("After %lfs, thread autotuning declared speedup of %lg x,"
" when using threads count of %d\&.\n",dt,sf,tn);
printf("\n");
dt = -rsb_time();
mtxOp = mtxAp;
errval = rsb_tune_spmm(&mtxAp, &sf, &tn, oitmax, tmax, transA,
alphap, NULL, nrhs, order, NULL, ldB, betap, NULL, ldC);
if( (errval) != RSB_ERR_NO_ERROR )
goto err;
dt += rsb_time();
if( mtxOp == mtxAp )
{
printf("After %lfs, global autotuning found old matrix optimal,"
" with declared speedup %lg x when using %d threads\n",dt,sf,tn);
}
else
{
printf("After %lfs, global autotuning declared speedup of %lg x,"
" when using threads count of %d and a new matrix:\n",dt,sf,tn);
rsb_mtx_get_info_str(mtxAp,is,ib,sizeof(ib));
printf("%s\n",ib);
}
printf("\n");
/* user is expected to:
errval = rsb_lib_set_opt(RSB_IO_WANT_EXECUTING_THREADS,&tn);
and use mtxAp in SpMV\&.
*/
rsb_mtx_free(mtxAp);
mtxAp = NULL;
}
rsb_mtx_free(mtxMp);
mtxMp = NULL;
err:
rsb_perror(NULL,errval);
if ( errval != RSB_ERR_NO_ERROR )
printf("Program terminating with error\&.\n");
return errval;
}
int main(const int argc, char * const argv[])
{
/*!
Autotuning example\&.
*/
/* matrix variables */
struct rsb_mtx_t *mtxAp = NULL; /* matrix structure pointer */
const int bs = RSB_DEFAULT_BLOCKING;
rsb_coo_idx_t nrA = 500; /* number of rows */
rsb_coo_idx_t ncA = 500; /* number of cols */
const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
const rsb_coo_idx_t rd = 1;/* every rd rows one is non empty */
const rsb_coo_idx_t cd = 4;/* every cd cols one is non empty */
rsb_nnz_idx_t nnzA = (nrA/rd)*(ncA/cd); /* nonzeroes */
rsb_coo_idx_t*IA = NULL;
rsb_coo_idx_t*JA = NULL;
RSB_DEFAULT_TYPE*VA = NULL;
/* spmv specific variables */
const RSB_DEFAULT_TYPE alpha = 1;
const RSB_DEFAULT_TYPE beta = 1;
RSB_DEFAULT_TYPE*Cp = NULL;
RSB_DEFAULT_TYPE*Bp = NULL;
rsb_flags_t order = RSB_FLAG_WANT_COLUMN_MAJOR_ORDER;
const rsb_coo_idx_t nrhs = 2; /* number of right hand sides */
const rsb_trans_t transA = RSB_TRANSPOSITION_N;
rsb_nnz_idx_t ldB = nrA;
rsb_nnz_idx_t ldC = ncA;
/* misc variables */
rsb_err_t errval = RSB_ERR_NO_ERROR;
const size_t so = sizeof(RSB_DEFAULT_TYPE);
const size_t si = sizeof(rsb_coo_idx_t);
rsb_time_t dt,odt;
rsb_int_t t;
const rsb_int_t tt = 100; /* will repeat spmv tt times */
char ib[200];
const char*is = "RSB_MIF_MATRIX_INFO__TO__CHAR_P";
/* misc counters */
rsb_coo_idx_t ci;
rsb_coo_idx_t ri;
rsb_coo_idx_t ni;
rsb_int_t nrhsi;
/* misc variables */
rsb_time_t etime = 0\&.0;
/* input autotuning variables */
const rsb_int_t oitmax = 15; /* auto-tune iterations */
const rsb_time_t tmax = 0\&.1; /* time per autotune operation */
/* input/output autotuning variables */
rsb_int_t tn = 0; /* threads number */
/* output autotuning variables */
rsb_real_t sf = 0\&.0; /* speedup factor obtained from auto tuning */
const rsb_int_t wvat = 1; /* want verbose autotuning; see
documentation of RSB_IO_WANT_VERBOSE_TUNING */
if(argc > 1 && !isdigit(argv[1][0]) )
{
errval = tune_from_file(argv[1],wvat);
goto ret;
}
if(argc > 1)
{
nrA = ncA = atoi(argv[1]);
if ( nrA < RSB_MIN_MATRIX_DIM || (nrA > (RSB_MAX_MATRIX_DIM) ))
goto err;
nnzA = (nrA/rd)*(ncA/cd);
ldB = nrA;
ldC = ncA;
}
printf("Creating %d x %d matrix with %d nonzeroes\&.\n",(int)nrA,
(int)ncA, (int)nnzA);
IA = calloc(nnzA, si);
JA = calloc(nnzA, si);
VA = calloc(nnzA, so);
Bp = calloc(nrhs*ncA ,so);
Cp = calloc(nrhs*nrA ,so);
if( ! ( VA && IA && JA && Bp && Cp ) )
goto err;
for(nrhsi=0;nrhsi\&.
*/
/*!
\ingroup rsb-examples
@file
@author Michele Martone
@brief Example C program using the Sparse BLAS interface
and reading from file using \ref rsb_blas_file_mtx_load(),
\ref BLAS_usgp(), \ref BLAS_dusmv(), \ref BLAS_usds()\&.
\include io-spblas\&.c
*/
#include /* for rsb_lib_init */
#include
#include
int main(const int argc, char * const argv[])
{
#ifndef RSB_NUMERICAL_TYPE_DOUBLE
printf("Skipping a test because of 'double' type opted out\&.\n");
return EXIT_SUCCESS;
#else /* RSB_NUMERICAL_TYPE_DOUBLE */
blas_sparse_matrix A = blas_invalid_handle;
const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DOUBLE;
const rsb_char_t * filename = argc > 1 ? argv[1] : "pd\&.mtx";
printf("Hello, RSB!\n");
if((rsb_perror(NULL,
rsb_lib_init(RSB_NULL_INIT_OPTIONS)))!=RSB_ERR_NO_ERROR)
{
printf("Error while initializing the library\&.\n");
goto err;
}
printf("Correctly initialized the library\&.\n");
A = rsb_blas_file_mtx_load(filename, typecode );
if( A == blas_invalid_handle )
{
printf("Error while loading matrix %s from file\&.\n",
filename);
goto err;
}
printf("Correctly loaded and allocated a matrix"
" from file %s\&.\n",filename);
if( BLAS_usgp(A,blas_symmetric) == 1 )
printf("Matrix is symmetric\n");
if( BLAS_usgp(A,blas_hermitian) == 1 )
printf("Matrix is hermitian\n");
printf("Now SPMV with NULL vectors will be attempted,"
" resulting in an error (so don't worry)\&.\n");
if(BLAS_dusmv(blas_no_trans,-1,A,NULL,1,NULL,1))
{
printf("Correctly detected an error condition\&.\n");
goto okerr;
}
printf("No error detected ?\nIf you see this line printed out,"
" please report as a bug, because the above NULL pointers"
" should have been detected\n");
return EXIT_FAILURE;
okerr:
printf("Program correctly recovered from intentional"
" error condition\&.\n");
if(BLAS_usds(A))
{
printf("Error while freeing the matrix!\n");
goto err;
}
printf("Correctly freed the matrix\&.\n");
err:
if(rsb_perror(NULL,
rsb_lib_exit(RSB_NULL_EXIT_OPTIONS))!=RSB_ERR_NO_ERROR)
{
printf("Failed finalizing the library\&.\n");
goto ferr;
}
printf("Correctly finalized the library\&.\n");
return EXIT_SUCCESS;
ferr:
return EXIT_FAILURE;
#endif /* RSB_NUMERICAL_TYPE_DOUBLE */
}
.fi
.PP
.PP
\fBexamples/transpose\&.c\fP:
.PP
.nf
/*
Copyright (C) 2008-2021 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 \&.
*/
/*!
@file
@author Michele Martone
@brief A toy -based C program showing instantiation,
transposition and other operations on a single matrix\&.
Uses \ref rsb_mtx_clone(), \ref rsb_file_mtx_save(),
\ref rsb_file_mtx_get_dims(), \ref rsb_file_mtx_load()\&.
\ingroup rsb-examples
\include transpose\&.c
*/
#include
#include /* printf */
int main(const int argc, char * const argv[])
{
struct rsb_mtx_t *mtxAp = NULL;
const rsb_blk_idx_t brA = RSB_DEFAULT_BLOCKING,
bcA = RSB_DEFAULT_BLOCKING;
rsb_nnz_idx_t nnzA = 4;
rsb_coo_idx_t nrA = 3;
rsb_coo_idx_t ncA = 3;
const rsb_coo_idx_t IA[] = { 0, 1, 2, 0 };
const rsb_coo_idx_t JA[] = { 0, 1, 2, 2 };
const RSB_DEFAULT_TYPE VA[] = { 11, 22, 33, 13 };
RSB_DEFAULT_TYPE XV[] = { 0,0,0,0,0,0 };
rsb_coo_idx_t vl = 0;
const rsb_type_t typecode = RSB_NUMERICAL_TYPE_DEFAULT;
rsb_err_t errval = RSB_ERR_NO_ERROR;
/* library initialization */
if(rsb_lib_init(RSB_NULL_INIT_OPTIONS)!=RSB_ERR_NO_ERROR)
{
return EXIT_FAILURE;
}
/* allocation */
mtxAp = rsb_mtx_alloc_from_coo_const(
VA,IA,JA,nnzA,typecode,nrA,ncA,
brA,bcA,RSB_FLAG_NOFLAGS,NULL);
if(!mtxAp)
{
return EXIT_FAILURE;
}
/* printout */
if(RSB_ERR_NO_ERROR!=(errval = rsb_file_mtx_save(mtxAp,NULL)))
{
if(errval != RSB_ERR_UNSUPPORTED_FEATURE)
goto err;
}
/* matrix transposition */
if( RSB_ERR_NO_ERROR != (errval =
rsb_mtx_clone(&mtxAp,RSB_NUMERICAL_TYPE_SAME_TYPE,
RSB_TRANSPOSITION_T,NULL,mtxAp,RSB_FLAG_IDENTICAL_FLAGS)))
{
goto err;
}
/* printout */
if(RSB_ERR_NO_ERROR!=(errval = rsb_file_mtx_save(mtxAp,NULL)))
{
if(errval != RSB_ERR_UNSUPPORTED_FEATURE)
goto err;
}
rsb_mtx_free(mtxAp);
/* doing the same after load from file */
mtxAp = rsb_file_mtx_load("pd\&.mtx",
RSB_FLAG_NOFLAGS,typecode,NULL);
if(!mtxAp)
{
return EXIT_FAILURE;
}
/* printout */
if(RSB_ERR_NO_ERROR!=(errval = rsb_file_mtx_save(mtxAp,NULL)))
{
if(errval != RSB_ERR_UNSUPPORTED_FEATURE)
goto err;
}
/* one can see dimensions in advance, also */
if(RSB_ERR_NO_ERROR!=(errval =
rsb_file_mtx_get_dims("pd\&.mtx",&nrA,&ncA,&nnzA,NULL)))
{
if(errval != RSB_ERR_UNSUPPORTED_FEATURE)
goto err;
}
/* A matrix can be rendered to Postscript\&. */
{
if(RSB_ERR_NO_ERROR!=(errval =
rsb_mtx_rndr("pd\&.eps",mtxAp,512,512,RSB_MARF_EPS_B)))
goto err;
}
rsb_mtx_free(mtxAp);
/* also vectors can be loaded */
if(RSB_ERR_NO_ERROR!=(errval =
rsb_file_vec_load("vf\&.mtx",typecode,NULL,&vl )))
goto err;
/* we expect vf\&.mtx to be 6 rows long */
if( vl != 6 )
{
goto err;
}
if(RSB_ERR_NO_ERROR!=(errval =
rsb_file_vec_load("vf\&.mtx",typecode,XV, NULL )))
goto err;
/* matrices can be rendered from file to a pixelmap as well */
{
unsigned char pixmap[3*2*2];
if(RSB_ERR_NO_ERROR!=(errval =
rsb_file_mtx_rndr(pixmap,"pd\&.mtx",2,2,2,RSB_MARF_RGB)))
goto err;
}
if(RSB_ERR_NO_ERROR != rsb_lib_exit(RSB_NULL_EXIT_OPTIONS))
{
goto err;
}
return EXIT_SUCCESS;
err:
rsb_perror(NULL,errval);
return EXIT_FAILURE;
}
.fi
.PP
.PP
\fBexamples/power\&.c\fP:
.PP
.nf
/*
Copyright (C) 2008-2021 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 \&.
*/
/*!
@file
@author Michele Martone
@brief A toy -based C program implementing the power
method for computing matrix eigenvalues\&. Uses #rsb_spmv()\&.
\ingroup rsb-examples
\include power\&.c
*/
#include // printf
#include