Skip to content
Merged
9 changes: 9 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ stages:
# only:
# - master
# - develop
# - /^v.*-rc.*$/
# artifacts:
# paths:
# - build/
Expand All @@ -44,6 +45,7 @@ stages:
# only:
# - master
# - develop
# - /^v.*-rc.*$/


#test_centos_8_unit:
Expand All @@ -59,6 +61,7 @@ stages:
# only:
# - master
# - develop
# - /^v.*-rc.*$/


#test_centos_8_smoke:
Expand All @@ -74,6 +77,7 @@ stages:
# only:
# - master
# - develop
# - /^v.*-rc.*$/


#test_centos_8_performance:
Expand All @@ -89,6 +93,7 @@ stages:
# only:
# - master
# - develop
# - /^v.*-rc.*$/


#test_centos_8_installation:
Expand All @@ -103,6 +108,7 @@ stages:
# only:
# - master
# - develop
# - /^v.*-rc.*$/


# Main testing on Ubuntu, all branches
Expand Down Expand Up @@ -148,6 +154,7 @@ build_debugrelease_tests:
only:
- master
- develop
- /^v.*-rc.*$/


# linting is currently disabled since clang-format is not mature enough
Expand Down Expand Up @@ -266,6 +273,7 @@ tests_performance:
only:
- master
- develop
- /^v.*-rc.*$/


tests_unit_debug:
Expand All @@ -281,4 +289,5 @@ tests_unit_debug:
only:
- master
- develop
- /^v.*-rc.*$/

2 changes: 1 addition & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
cmake_minimum_required( VERSION 3.13 )

set( MAJORVERSION 0 )
set( MINORVERSION 5 )
set( MINORVERSION 6 )
set( BUGVERSION 0 )
set( VERSION "${MAJORVERSION}.${MINORVERSION}.${BUGVERSION}" )

Expand Down
95 changes: 95 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,98 @@

Version 0.6.0
=============

This is a summary of changes. For full details, see the publicly available Git
history prior to the v0.6 tag.

Highlights and changes to the specification:
- Deprecated `grb::init` and `grb::finalize` in favour of grb::Launcher.
Existing code should migrate to using the Launcher as any later release may
remove the now-deprecated primtives.
- If you wish to rely on ALP/GraphBLAS for more standard sparse linear
algebra but if you cannot, or do not wish to, adapt your existing sources
to the C++ ALP/GraphBLAS API, then v0.6 onwards generates libraries that
implement a subset of the standard C/C++ SparseBLAS and SpBLAS interfaces.
After installation, these libraries are found in
- `<install path>/lib/sequential/libsparseblas.a` (sequential) and
- `<install path>/lib/sequential/libsparseblas_omp.a` (shared-memory
parallel).
The headers are found in
- `<install path>/include/transition/sparseblas.h` and
- `<install path>/include/transition/spblas.h`.
- Input iterators passed to `grb::buildMatrixUnique` that happen to be random
access will now lead to shared-memory parallel ingestion when using the
reference_omp or hybrid backends.
- `grb::Phase` is now only accepted for primitives with non-scalar
ALP/GraphBLAS output containers.

Algorithms:
- Feature: the CG algorithm has been adapted to work with complex-valued
matrices making use of the standard `std::complex` type. A corresponding
smoke test is added.
- Bugfix: BiCGstab erroneously relied on `grb::utils::equals`, and could
(rarely) lead to false orthogonality detection and an unnecessary abort.

Utilities:
- The parser that reads MatrixMarket files, `grb::utils::MatrixFileReader`, now
can parse complex values and load Hermitian matrices.
- What constitutes an ALP/GraphBLAS sparse matrix iterator has been formalised
with a novel type trait, `grb::utils::is_alp_matrix_iterator`. ALP/GraphBLAS
matrix output iterators now also adhere to these requirements.
- A `grb::utils::is_complex` type trait has been added, and is used by the CG
algorithm so as to not materialise unnecessary buffers and code paths.
- Bugfixes to the `grb::utils::equals` routine, as well as better
documentation. A unit test has been added for it.

Testing, development, and documentation:
- Documentation has been adapted to include GitHub for reporting issues.
- Documentation of various ALP/GraphBLAS primitives and concepts have been
improved.
- Documentation detailing the compiler warning suppressions and their rationale
have been moved to the code repository at `docs/Suppressions.md`.
- Add basic CI tests (build, install, and smoke tests) for GitHub.
- More thorough testing of output matrix iterators, input iterators, and of
`grb::buildMatrixUnique`.
- The `dense_spmv.cpp` smoke test did not correctly verify output, and could
fail for SpMV multiplications that yield very small nonzero values.
- Improvements to various tests and scripts.

Reference and reference_omp backends:
- Bugfix: matrix output iterators failed if all nonzeroes were on the last row
and no nonzeroes existed anywhere else.
- Bugfix: copying and immediately dereferencing a matrix output iterator led to
use of uninitialised values.
- Bugfix: `grb::foldl` with a dense descriptor would accept sparse inputs while
it should return `ILLEGAL`. This behaviour, as well as for other error codes,
are now also (unit) tested for, including with masks and inverted masks.
- Bugfix: `grb::set` was moved from `reference/blas1.hpp` to
`reference/io.hpp`, but the macros that guard parallelisation were not
properly updated.
- Bugfix: the OpenMP `schedule( static, chunk_size )` has a dynamic (run-time)
component that was not intended.
- Bugifx: some OpenMP `schedule( dynamic, chunk_size )` operate on regular
loops and should employ a static schedule instead.

BSP1D backend:
- Bugfix: too thorough sanity checking disallowed building dense matrices.
- Bugfix: `grb::set` on vectors with non-fundamental value types would not
compile (due to code handling the use_index descriptor).
- Bugfix: `grb::clear` could leave the vector in an undefined state if it
immediately followed an operation that left said vector dense.
- Code improvement: PinnedVector constructors now throws exceptions on errors.

All backends:
- Bugfix: an input-masked variant of `grb::foldr` was missing. These are now
also added to the unit test suite.
- Bugfix: matrix constructors that throw an exception could segfault on
destruction.
- Bugfix: use of PinnedVectors that pin sparse or empty vectors could segfault.
- Code improvements: noexcept additions, const-correctness, code style fixes,
removal of compiler warnings (on some compiler versions), dead code removal,
improved `_DEBUG` tracing, additional debug-mode sanity checks, and reduced
code duplication.


Version 0.5.0
=============

Expand Down Expand Up @@ -123,6 +217,7 @@ Various other bugfixes, performance bug fixes, documentation improvements,
default configuration updates, and code structure improvements -- see Gitee MRs
!21, !22, !38, !39, !40, and !42 for details.


Version 0.4.1
=============

Expand Down
93 changes: 93 additions & 0 deletions docs/Suppressions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@

This file keeps track of all active compiler warning suppressions and updates
with every release. Listed are the code, which suppression is used, and the
rationale for why the suppression is OK to use and the compiler warning is safe
to ignore.

1. `include/graphblas/reference/compressed_storage.hpp`, copyFrom:
```
GRB_UTIL_IGNORE_CLASS_MEMACCESS // by the ALP spec, D can only be POD types.
// In this case raw memory copies are OK.
(void) std::memcpy( values + k,
other.values + k,
(loop_end - k) * sizeof( D )
);
GRB_UTIL_RESTORE_WARNINGS
```

2. `include/graphblas/reference/blas1.hpp`, dot_generic:
```
for( size_t k = 0; k < AnyOp::blocksize; ++k ) {
zz[ k ] = addMonoid.template getIdentity< typename AnyOp::D3 >();
}
for( size_t k = 0; k < AnyOp::blocksize; ++k ) {
if( mask[ k ] ) {
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // yy and xx cannot be used
// uninitialised or mask
apply( zz[ k ], xx[ k ], yy[ k ], anyOp ); // would be false while zz
GRB_UTIL_RESTORE_WARNINGS // init is just above
}
}
```

3. `include/graphblas/reference/blas1.hpp`, sparse_apply_generic:
```
if( masked ) {
if( mask[ i ] ) {
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // if masked && mask[ i ], then
z_p[ offsets[ i ] ] = z_b[ i ]; // z_b[ i ] was set from x or y in
GRB_UTIL_RESTORE_WARNINGS // the above
}
} else {
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // the only way the below could write
// an uninitialised value is if the
// static_assert at the top of this
z_p[ offsets[ i ] ] = z_b[ i ]; // function had triggered. See also
GRB_UTIL_RESTORE_WARNINGS // internal issue #321.
}
```

4. `include/graphblas/base/internalops.hpp`, multiple sources:
- mul::apply, add::apply, add::foldl, equal::apply, not_equal::apply.

These are indirectly caused by the following calls:
- `include/graphblas/blas0.hpp`, apply;
- `include/graphblas/reference/blas1.hpp`, dot_generic, masked_apply_generic,
and sparse_apply_generic.

These are all OK to suppress since the reads are masked.

5. `include/graphblas/reference/blas1.hpp`, fold_from_vector_to_scalar_generic:
```
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // the below code ensures to set local
IOType local; // whenever our local block is
GRB_UTIL_RESTORE_WARNINGS // non-empty
if( end > 0 ) {
if( i < end ) {
local = static_cast< IOType >( internal::getRaw( to_fold )[ i ] );
} else {
local = static_cast< IOType >( internal::getRaw( to_fold )[ 0 ] );
}
}
```
and
```
if( root == s ) {
// then I should be non-empty
assert( !empty );
// set global value to locally computed value
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // one is only root if the local
global = local; // chunk is non-empty, in which case
GRB_UTIL_RESTORE_WARNINGS // local will be initialised (above)
}
```

6. `include/graphblas/reference/blas1.hpp`, masked_apply_generic:
```
if( mask_b[ t ] ) {
// ...
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // z_b is computed from x_b and
*( z_p + indices[ t ] ) = z_b[ t ]; // y_b, which are both initialised
GRB_UTIL_RESTORE_WARNINGS // if mask_b is true
```

2 changes: 1 addition & 1 deletion docs/doxy.conf
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ PROJECT_NAME = "ALP/GraphBLAS"
# could be handy for archiving the generated documentation or if some version
# control system is used.

PROJECT_NUMBER = 0.5.0
PROJECT_NUMBER = 0.6.0

# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
Expand Down
3 changes: 2 additions & 1 deletion include/graphblas/internalops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
#include "base/internalops.hpp"

#ifdef _GRB_WITH_BANSHEE
#include <graphblas/banshee/internalops.hpp>
#include <graphblas/banshee/internalops.hpp>
#endif

#endif

22 changes: 13 additions & 9 deletions include/graphblas/reference/blas1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -244,9 +244,9 @@ namespace grb {
}
#endif

GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED
IOType local;
GRB_UTIL_RESTORE_WARNINGS
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // the below code ensures to set local
IOType local; // whenever our local block is
GRB_UTIL_RESTORE_WARNINGS // non-empty
if( end > 0 ) {
if( i < end ) {
local = static_cast< IOType >( internal::getRaw( to_fold )[ i ] );
Expand Down Expand Up @@ -316,9 +316,9 @@ namespace grb {
// then I should be non-empty
assert( !empty );
// set global value to locally computed value
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED
global = local;
GRB_UTIL_RESTORE_WARNINGS
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // one is only root if the local
global = local; // chunk is non-empty, in which case
GRB_UTIL_RESTORE_WARNINGS // local will be initialised (above)
}
}
#pragma omp barrier
Expand Down Expand Up @@ -3017,7 +3017,9 @@ namespace grb {
for( size_t i = 0; i < block_size; i++ ) {
if( masked ) {
if( mask[ i ] ) {
z_p[ offsets[ i ] ] = z_b[ i ];
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // if masked && mask[ i ], then
z_p[ offsets[ i ] ] = z_b[ i ]; // z_b[ i ] was set from x or y in
GRB_UTIL_RESTORE_WARNINGS // the above
}
} else {
if( x_m[ i ] ) {
Expand Down Expand Up @@ -3431,7 +3433,9 @@ namespace grb {
}
#endif
}
*( z_p + indices[ t ] ) = z_b[ t ];
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // z_b is computed from x_b and
*( z_p + indices[ t ] ) = z_b[ t ]; // y_b, which are both initialised
GRB_UTIL_RESTORE_WARNINGS // if mask_b is true
}
}
#ifndef _H_GRB_REFERENCE_OMP_BLAS1
Expand Down Expand Up @@ -8176,7 +8180,7 @@ namespace grb {
if( mask[ k ] ) {
GRB_UTIL_IGNORE_MAYBE_UNINITIALIZED // yy and xx cannot be used
// uninitialised or mask
apply( zz[ k ], xx[ k ], yy[ k ], anyOp ); // would be false. also, zz
apply( zz[ k ], xx[ k ], yy[ k ], anyOp ); // would be false while zz
GRB_UTIL_RESTORE_WARNINGS // init is just above
}
}
Expand Down
1 change: 1 addition & 0 deletions include/graphblas/reference/compressed_storage.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@

#include <cstring> //std::memcpy


namespace grb {

namespace internal {
Expand Down
2 changes: 1 addition & 1 deletion include/graphblas/utils/suppressions.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@
#define GRB_UTIL_RESTORE_WARNINGS
#endif

#endif // end ``_H_GRB_REFERENCE_BLAS2''
#endif // end ``_H_GRB_UTILS_SUPRESSIONS''