Examples of usage of librsb.
More...
Examples of usage of librsb.
The following fully working example programs illustrate correct ways of using the library.
The script displayed here should be sufficient to build them.
#!/bin/bash
# Script to build the librsb example programs.
LIBRSB_CONFIG=${LIBRSB_CONFIG:-librsb-config}
for s in *.c
do
p=${s/.c/}
rm -f $p
CFLAGS=`${LIBRSB_CONFIG} --I_opts`
LDFLAGS=`${LIBRSB_CONFIG} --static --ldflags --extra_libs`
CC=`${LIBRSB_CONFIG} --cc`
cmd="$CC $CFLAGS $s $LDFLAGS -o $p"
echo $cmd
$cmd
done
# replace false with true if you have built the Fortran modules and installed them in the include directory.
if false ; then
for s in *.F90
do
p=${s/.F90/}
rm -f $p
CFLAGS=`${LIBRSB_CONFIG} --I_opts`
LDFLAGS=`${LIBRSB_CONFIG} --static --ldflags --extra_libs`
FC=`${LIBRSB_CONFIG} --fc`
cmd="$FC $CFLAGS $s $LDFLAGS -o $p"
echo $cmd
$cmd
done
fi
#include <stdio.h>
int main(const int argc, char * const argv[])
{
struct rsb_mtx_t *mtxAp = NULL;
const int brA = bs, bcA = bs;
char ib[200];
printf("Hello, RSB!\n");
printf("Initializing the library...\n");
{
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");
{
{
char errbuf[256];
printf("Failed setting the"
" RSB_IO_WANT_EXTRA_VERBOSE_INTERFACE"
" library option (reason string:\n%s).\n",errbuf);
{
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;
&evi);
}
}
VA,IA,JA,nnzA,typecode,nrA,ncA,brA,bcA,
,&errval);
{
printf("Error while allocating the matrix!\n");
goto err;
}
printf("Correctly allocated a matrix.\n");
printf("Summary information of the matrix:\n");
ib,sizeof(ib));
printf("%s",ib);
printf("\n");
if((errval =
{
printf("Error performing a multiplication!\n");
goto err;
}
printf("Correctly performed a SPMV.\n");
printf("Correctly freed the matrix.\n");
{
printf("Error finalizing the library!\n");
goto err;
}
printf("Correctly finalized the library.\n");
printf("Program terminating with no error.\n");
return 0;
err:
printf("Program terminating with error.\n");
return -1;
}
#include <stdio.h>
int main(const int argc, char * const argv[])
{
#ifndef RSB_NUMERICAL_TYPE_DOUBLE
printf("'double' type configured out."
" Please reconfigure the library with it and recompile.\n");
return 0;
#else
const int nnz = 4;
const int nr = 3;
const int nc = 3;
int IA[] = { 0, 1, 2, 2 };
int JA[] = { 0, 1, 0, 2 };
double VA[] = { 11.0, 22.0, 13.0, 33.0 };
double X[] = { 0.0, 0.0, 0.0 };
double B[] = { -1.0, -2.0, -2.0 };
double AB[] = { 11.0+26.0, 44.0, 66.0+13.0 };
int i;
printf("Hello, RSB!\n");
{
goto err;
}
printf("Correctly initialized the library.\n");
{
goto err;
}
{
goto err;
}
{
printf("Symmetry property non set ?!\n");
goto err;
}
{
goto err;
}
{
goto err;
}
printf("Correctly allocated a matrix.\n");
VA[0] = 0.0;
{
goto err;
}
if( VA[0] != 11.0 )
{
goto err;
}
{
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");
{
goto err;
}
printf("Correctly freed the matrix.\n");
{
goto err;
}
printf("Correctly finalized the library.\n");
printf("Program terminating with no error.\n");
return 0;
err:
printf("Program terminating with error.\n");
return -1;
#endif
}
#include <stdio.h>
int main(const int argc, char * const argv[])
{
#ifndef RSB_NUMERICAL_TYPE_DOUBLE
printf("'double' type configured out."
" Please reconfigure the library with it and recompile.\n");
return 0;
#else
const int nnz = 4;
const int nr = 3;
const int nc = 3;
int IA[] = { 0, 1, 2, 2 };
int JA[] = { 0, 1, 0, 2 };
double VA[] = { 11.0, 22.0, 13.0, 33.0 };
double X[] = { 0.0, 0.0, 0.0 };
double B[] = { -1.0, -2.0, -2.0 };
double AB[] = { 11.0+26.0, 44.0, 66.0+13.0 };
int i;
printf("Hello, RSB!\n");
{
goto err;
}
printf("Correctly initialized the library.\n");
{
goto err;
}
{
goto err;
}
{
printf("Symmetry property non set ?!\n");
goto err;
}
{
goto err;
}
{
goto err;
}
printf("Correctly allocated a matrix.\n");
VA[0] = 0.0;
{
goto err;
}
if( VA[0] != 11.0 )
{
goto err;
}
{
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");
{
goto err;
}
printf("Correctly freed the matrix.\n");
{
goto err;
}
printf("Correctly finalized the library.\n");
printf("Program terminating with no error.\n");
return 0;
err:
printf("Program terminating with error.\n");
return -1;
#endif
}
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
int tune_from_file(
char *
const filename,
rsb_int_t wvat)
{
struct rsb_mtx_t *mtxMp = NULL;
char ib[200];
const char*is = "RSB_MIF_MATRIX_INFO__TO__CHAR_P";
int ione = 1;
rsb_type_t typecodea [] = RSB_MATRIX_SPBLAS_TYPE_CODES_ARRAY;
int typecodei;
goto err;
goto err;
printf("Loading matrix from file \"%s\".\n",filename);
goto err;
for( typecodei = 0 ; typecodei < RSB_IMPLEMENTED_TYPES; ++typecodei )
{
struct rsb_mtx_t *mtxAp = NULL;
struct rsb_mtx_t *mtxOp = NULL;
sf = 0.0;
tn = 0;
printf("Considering %c clone.\n",typecode);
flagsA);
goto err;
printf("Base matrix:\n");
printf("%s\n\n",ib);
&alpha, mtxAp, nrhs, order, NULL, ldB, &beta, NULL, ldC);
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");
mtxOp = mtxAp;
&alpha, NULL, nrhs, order, NULL, ldB, &beta, NULL, ldC);
goto err;
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);
printf("%s\n",ib);
}
printf("\n");
mtxAp = NULL;
}
mtxMp = NULL;
goto ret;
ret:
return 0;
err:
printf("Program terminating with error.\n");
return -1;
}
int main(const int argc, char * const argv[])
{
struct rsb_mtx_t *mtxAp = NULL;
char ib[200];
const char*is = "RSB_MIF_MATRIX_INFO__TO__CHAR_P";
if(argc > 1 && !isdigit(argv[1][0]) )
return tune_from_file(argv[1],wvat);
if(argc > 1)
{
nrA = ncA = atoi(argv[1]);
goto err;
nnzA = (nrA/rd)*(ncA/cd);
ldB = nrA;
ldC = ncA;
}
printf("Creating %d x %d matrix with %d nonzeroes.\n",nrA,ncA,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<nrhs;++nrhsi)
for(ci=0;ci<ncA/cd;++ci)
Bp[nrhsi*ldC+ci] = 1.0;
for(nrhsi=0;nrhsi<nrhs;++nrhsi)
for(ri=0;ri<nrA/rd;++ri)
Cp[nrhsi*ldC+ri] = 1.0;
ni = 0;
for(ci=0;ci<ncA/cd;++ci)
for(ri=0;ri<nrA/rd;++ri)
{
VA[ni] = nrA * ri + ci,
IA[ni] = ri;
JA[ni] = ci;
ni++;
}
VA,IA,JA,nnzA,typecode,nrA,ncA,bs,bs,
free(VA);
free(IA);
free(JA);
VA = NULL;
IA = NULL;
JA = NULL;
goto err;
printf("Allocated matrix of %zd nonzeroes:\n",(size_t)nnzA);
printf("%s\n\n",ib);
for(t=0;t<tt;++t)
rsb_spmm(transA,&alpha,mtxAp,nrhs,order,Bp,ldB,&beta,Cp,ldC);
odt = dt;
printf("Before auto-tuning, %d multiplications took %lfs.\n",tt,dt);
printf("Threads autotuning (may take more than %lfs)...\n",
oitmax*tmax);
&alpha, mtxAp, nrhs, order, Bp, ldB, &beta, Cp, ldC);
goto err;
if(tn == 0)
printf("After %lfs, autotuning routine did not find a better"
" threads count configuration.\n",dt);
else
printf("After %lfs, autotuning routine declared speedup of %lg x,"
" when using threads count of %d.\n",dt,sf,tn);
goto err;
printf("%s\n",ib);
for(t=0;t<tt;++t)
rsb_spmm(transA,&alpha,mtxAp,nrhs,order,Bp,ldB,&beta,Cp,ldC);
printf("After threads auto-tuning, %d multiplications took %lfs"
" -- effective speedup of %lg x\n",tt,dt,odt/dt);
odt = dt;
tn = 0;
goto err;
goto err;
printf("Matrix autotuning (may take more than %lfs; using %d"
" threads )...\n", oitmax*tmax, tn);
&alpha, NULL, nrhs, order, Bp, ldB, &beta, Cp, ldC);
goto err;
if(tn == 0)
printf("After %lfs, autotuning routine did not find a better"
" threads count configuration.\n",dt);
else
printf("After %lfs, autotuning routine declared speedup of %lg x,"
" when using threads count of %d.\n",dt,sf,tn);
printf("%s\n",ib);
for(t=0;t<tt;++t)
rsb_spmm(transA,&alpha,mtxAp,nrhs,order,Bp,ldB,&beta,Cp,ldC);
printf("After threads auto-tuning, %d multiplications took %lfs"
" -- further speedup of %lg x\n",tt,dt,odt/dt);
free(Cp);
free(Bp);
{
printf("librsb timer-based profiling is not supported in "
"this build. If you wish to have it, re-configure librsb "
"with its support. So you can safely ignore the error you"
" might just have seen printed out on screen.\n");
}
else
if(etime)
printf("Elapsed program time is %5.2lfs\n",etime);
goto err;
return 0;
err:
printf("Program terminating with error.\n");
return -1;
}
#include <stdio.h>
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 0;
#else
rsb_char_t * filename = argc > 1 ? argv[1] :
"../pd.mtx";
printf("Hello, RSB!\n");
{
printf("Error while initializing the library.\n");
goto err;
}
printf("Correctly initialized the library.\n");
typecode );
{
printf("Error while loading matrix %s from file.\n",
filename);
goto err;
}
printf("Correctly loaded and allocated a matrix"
" from file %s.\n",filename);
printf("Matrix is symmetric\n");
printf("Matrix is hermitian\n");
printf("Now SPMV with NULL vectors will be attempted,"
" resulting in an error (so don't worry).\n");
{
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 -1;
okerr:
printf("Program correctly recovered from intentional"
" error condition.\n");
{
printf("Error while freeing the matrix!\n");
goto err;
}
printf("Correctly freed the matrix.\n");
err:
{
printf("Failed finalizing the library.\n");
goto ferr;
}
printf("Correctly finalized the library.\n");
return 0;
ferr:
return -1;
#endif
}
#include <stdio.h>
int main(const int argc, char * const argv[])
{
struct rsb_mtx_t *mtxAp = NULL;
{
return -1;
}
VA,IA,JA,nnzA,typecode,nrA,ncA,
if(!mtxAp)
{
return -1;
}
{
goto err;
}
{
goto err;
}
{
goto err;
}
if(!mtxAp)
{
return -1;
}
{
goto err;
}
{
goto err;
}
{
goto err;
}
goto err;
if( vl != 6 )
{
goto err;
}
goto err;
{
unsigned char pixmap[3*2*2];
goto err;
}
{
goto err;
}
return 0;
err:
return -1;
}
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
int main(const int argc, char * const argv[])
{
int WANT_VERBOSE = 0;
struct rsb_mtx_t *mtxAp = NULL;
int i;
const int br = bs, bc = bs;
oldnorm = 1.0,
*b1 = NULL, *b2 = NULL,
*bnow = NULL, *bnext = NULL;
size_t ds = 0;
return -1;
if(!mtxAp)
return -1;
b1 = calloc(1,ds);
b2 = calloc(1,ds);
if(! (b1 && b2))
{
goto err;
}
for( i = 0; i < nrA; ++i )
b1[i] = 1;
bnow = b1, bnext = b2;
while( fabs(norm-oldnorm) > tol && it<maxit )
{
++ it;
oldnorm = norm;
goto err;
norm = 0;
for(i=0;i<nrA;++i)
norm += bnext[i]*bnext[i];
norm = sqrt(norm);
norm = 1.0/norm;
for(i=0;i<nrA;++i)
bnext[i] *= norm;
norm = 1.0/norm;
printf("it:%d norm:%lg norm diff:%lg\n",it,norm,norm-oldnorm);
{void *tmp=bnow;bnow=bnext;bnext=tmp;}
if(WANT_VERBOSE)
{
printf("norm:%lg\n",norm);
if(isinf(norm))
goto err;
for(i=0;i<2;++i)
printf("x[%d]=%lg\n",i,((double*)bnext)[i]);
}
}
free(b1);
free(b2);
goto err;
if( it == maxit )
{
printf("ERROR: hit iterations limit without convergence!");
}
return 0;
err:
return -1;
}
SUBROUTINE blas_sparse_mod_example(res)
IMPLICIT NONE
INTEGER :: res, istat = 0, i
TYPE(c_ptr),TARGET :: mtxap = c_null_ptr
INTEGER :: a
INTEGER,PARAMETER :: incx = 1
INTEGER,PARAMETER :: incy = 1
REAL(KIND=8),PARAMETER :: alpha = 3
INTEGER,PARAMETER :: nr = 20
INTEGER,PARAMETER :: nc = nr
INTEGER,PARAMETER :: nnz = (nr*(nr+1))/2
INTEGER :: nt = 0
INTEGER :: ic, ir
INTEGER,PARAMETER :: ia(nnz) = (/ (((ir), ic=1,ir), ir=1,nr ) /)
INTEGER,PARAMETER :: ja(nnz) = (/ (((ic), ic=1,ir), ir=1,nr ) /)
REAL(KIND=8),PARAMETER :: va(nnz) = (/ ((1, ic=1,ir), ir=1,nr ) /)
REAL(KIND=8) :: x(nc) = (/((1), ir=1,nc)/)
REAL(KIND=8),PARAMETER :: cy(nr) = (/((alpha+alpha*nr), ir=1,nr)/)
REAL(KIND=8) :: y(nr) = (/((alpha), ir=1,nr)/)
res = 0
IF (res.NE.0) goto 9999
IF (istat.NE.0) goto 9997
IF (istat.NE.0) print *,"autotuning returned nonzero:", istat &
&," ...did you enable autotuning ?"
IF (istat.NE.0) goto 9997
IF (istat.NE.0) goto 9997
IF (nt.NE.0) print*,"autotuner chose ",nt," threads"
IF (istat.NE.0) goto 9997
CALL
usmv(transn,alpha,a,x,incx,y,incy,istat)
IF (istat.NE.0) goto 9997
DO i = 1, nr
IF (y(i).NE.cy(i)) print *, "first check results are not ok"
IF (y(i).NE.cy(i)) goto 9997
END DO
y(:) = alpha
IF (istat.NE.0) goto 9997
CALL
usmv(transn,alpha,a,x,incx,y,incy,istat)
IF (istat.NE.0) goto 9997
DO i = 1, nr
IF (y(i).NE.cy(i)) print *,"second check results are not ok"
IF (y(i).NE.cy(i)) goto 9997
END DO
print *, "check results are ok"
goto 9998
9997 res = -1
9998 CONTINUE
IF (istat.NE.0) res = -1
9999 CONTINUE
end SUBROUTINE blas_sparse_mod_example
PROGRAM main
USE rsb, ONLY: rsb_lib_init, rsb_lib_exit, C_PTR, C_NULL_PTR,&
& rsb_io_want_extra_verbose_interface,rsb_io_want_verbose_tuning,&
USE iso_c_binding
IMPLICIT NONE
INTEGER :: res = 0, passed = 0, failed = 0
TYPE(c_ptr),PARAMETER :: eo = c_null_ptr
TYPE(c_ptr),PARAMETER :: io = c_null_ptr
INTEGER,TARGET::ione=1
CALL blas_sparse_mod_example(res)
IF (res.LT.0) failed = failed + 1
IF (res.EQ.0) passed = passed + 1
print *, "FAILED:", failed
print *, "PASSED:", passed
IF (failed .GT. 0) THEN
stop 1
END IF
END PROGRAM
SUBROUTINE rsb_mod_example1(res)
USE iso_c_binding
IMPLICIT NONE
INTEGER ::res
INTEGER,TARGET :: istat = 0, i
INTEGER :: transt = rsb_transposition_n
INTEGER :: incx = 1, incy = 1
REAL(KIND=8),TARGET :: alpha = 3, beta = 1
INTEGER :: nnz = 4
INTEGER :: nr = 2
INTEGER :: nc = 2
INTEGER :: nrhs = 1
INTEGER :: order = rsb_flag_want_column_major_order
INTEGER :: flags = rsb_flag_noflags
INTEGER,TARGET :: ia(4) = (/0, 1, 1,0/)
INTEGER,TARGET :: ja(4) = (/0, 0, 1,1/)
REAL(KIND=8),TARGET :: va(4) = (/1,1,1,1/)
REAL(KIND=8),TARGET :: x(2) = (/1, 1/)
REAL(KIND=8),TARGET :: cy(2) = (/9, 9/)
REAL(KIND=8),TARGET :: y(2) = (/3, 3/)
TYPE(c_ptr),TARGET :: mtxap = c_null_ptr
REAL(KIND=8) :: tmax = 2.0
INTEGER :: titmax = 2
INTEGER,TARGET :: ont = 0
res = 0
&,nnz,&
& rsb_numerical_type_double,nr,nc,1,1,flags,c_loc(istat))
IF (istat.NE.rsb_err_no_error) goto 9997
istat =
rsb_tune_spmm(c_loc(mtxap),c_null_ptr,c_null_ptr,titmax,&
& tmax,&
& transt,c_loc(alpha),c_null_ptr,nrhs,order,c_loc(x),nr,&
& c_loc(beta),c_loc(y),nc)
IF (istat.NE.rsb_err_no_error) goto 9997
& tmax,&
& transt,c_loc(alpha),mtxap,nrhs,order,c_loc(x),nr,c_loc(beta),&
& c_loc(y),nc)
print *, "Optimal number of threads:", ont
y(:) = (/3, 3/)
IF (istat.NE.rsb_err_no_error) goto 9997
IF (istat.NE.rsb_err_no_error) goto 9997
istat =
rsb_spmv(transt,c_loc(alpha),mtxap,c_loc(x),incx,&
& c_loc(beta),c_loc(y),incy)
IF (istat.NE.rsb_err_no_error) goto 9997
DO i = 1, 2
IF (y(i).NE.cy(i)) print *,
"type=d dims=2x2 sym=g diag=g & &blocks=1x1 usmv alpha= 3 beta= 1 incx=1 incy=1 trans=n is not ok"
IF (y(i).NE.cy(i)) goto 9997
END DO
print*,
"type=d dims=2x2 sym=g diag=g blocks=1x1 usmv alpha= 3& & beta= 1 incx=1 incy=1 trans=n is ok"
goto 9998
9997 res = -1
9998 CONTINUE
IF (istat.NE.rsb_err_no_error) res = -1
end SUBROUTINE rsb_mod_example1
SUBROUTINE rsb_mod_example2(res)
USE iso_c_binding
IMPLICIT NONE
INTEGER,TARGET :: errval
INTEGER :: res
INTEGER :: transt = rsb_transposition_n
INTEGER :: incx = 1, incb = 1
REAL(KIND=8),TARGET :: alpha = 3,beta = 1
INTEGER :: nnza = 4, nra = 3, nca = 3
INTEGER,TARGET :: ia(4) = (/1, 2, 3, 3/)
INTEGER,TARGET :: ja(4) = (/1, 2, 1, 3/)
INTEGER(C_SIGNED_CHAR) :: typecode = rsb_numerical_type_double
INTEGER :: flags =rsb_flag_default_matrix_flags+rsb_flag_symmetric
REAL(KIND=8),TARGET :: va(4) = (/11.0, 22.0, 13.0, 33.0/)
REAL(KIND=8),TARGET :: x(3) = (/ 0, 0, 0/)
REAL(KIND=8),TARGET :: b(3) = (/-1.0, -2.0, -2.0/)
TYPE(c_ptr),TARGET :: mtxap = c_null_ptr
TYPE(c_ptr) :: mtxapp = c_null_ptr
REAL(KIND=8),TARGET :: etime = 0.0
TYPE(c_ptr),PARAMETER :: eo = c_null_ptr
TYPE(c_ptr),PARAMETER :: io = c_null_ptr
IF (errval.NE.rsb_err_no_error) &
& stop "error calling rsb_lib_init"
#if defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 5)
#define RSB_SKIP_BECAUSE_OLD_COMPILER 1
#endif
#ifndef RSB_SKIP_BECAUSE_OLD_COMPILER
& c_loc(errval))
& c_loc(va),c_loc(ia),c_loc(ja),nnza,flags)
mtxapp = c_loc(mtxap)
IF (errval.NE.rsb_err_no_error) &
& stop "error calling rsb_mtx_set_vals"
IF (errval.NE.rsb_err_no_error) &
& stop "error calling rsb_mtx_alloc_from_coo_end"
errval =
rsb_spmv(transt,c_loc(alpha),mtxap,c_loc(x),&
& incx,c_loc(beta),c_loc(b),incb)
IF (errval.NE.rsb_err_no_error)&
& stop "error calling rsb_spmv"
IF (errval.EQ.rsb_err_no_error)&
& print*,"Time spent in librsb is:",etime
errval = rsb_err_no_error
IF (errval.NE.rsb_err_no_error) &
& stop "error calling rsb_mtx_free"
#else
print*,"You have an old Fortran compiler not supporting C_LOC."
print*,"Skipping a part of the test"
#endif
IF (errval.NE.rsb_err_no_error)&
& stop "error calling rsb_lib_exit"
print *, "rsb module fortran test is ok"
res = errval
end SUBROUTINE rsb_mod_example2
PROGRAM main
IMPLICIT NONE
INTEGER :: res = rsb_err_no_error, passed = 0, failed = 0
TYPE(c_ptr),PARAMETER :: eo = c_null_ptr
TYPE(c_ptr),PARAMETER :: io = c_null_ptr
CALL rsb_mod_example1(res)
IF (res.LT.0) failed = failed + 1
IF (res.EQ.0) passed = passed + 1
CALL rsb_mod_example2(res)
IF (res.LT.0) failed = failed + 1
IF (res.EQ.0) passed = passed + 1
print *, "FAILED:", failed
print *, "PASSED:", passed
IF (failed.GT.0) THEN
stop 1
END IF
END PROGRAM