Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions include/graphblas/base/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -236,6 +236,28 @@ namespace grb {
(void) n;
}

/**
* Creates a dense ALP/GraphBLAS vector.
*
* This constructor takes an initialiser list of values that will be copied
* into this vector. The size of the vector will be equal to the number of
* elements in the initialiser list.
*
* For backends with more than one user process, the size of \a vals is the
* global vector size, and the contents of \a vals are processed using
* sequential I/O semantics.
*
* @see #grb::IOMode For the difference between sequential and parallel I/O
* modes.
*
* \note There is only a difference if there are more than one user process.
*
* @param[in] vals The values to be copied into this vector.
*/
Vector( const std::initializer_list< D > &vals ) {
(void) vals;
}

/**
* Move constructor.
*
Expand Down
61 changes: 61 additions & 0 deletions include/graphblas/bsp1d/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2377,6 +2377,67 @@ namespace grb {
#endif
}

/**
* Constructs a BSP1D vector.
*
* @see Full description in base backend.
*
* \internal
* This constructor initialises the local vector and synchronises the global
* vector once.
*
* TODO rewrite below logic using an iterator filter (GitHub PR 233, issue
* 228)
* \endinternal
*/
Vector( const std::initializer_list< D > &vals )
: Vector( vals.size(), vals.size() )
{
#ifdef _DEBUG
std::cerr << "In Vector< BSP1D >::Vector( initializer_list ) constructor\n";
#endif
RC ret = SUCCESS;
const size_t n = vals.size();
const internal::BSP1D_Data &data = internal::grb_BSP1D.cload();

// Set all the local values
for( size_t i = 0; i < vals.size(); i++ ) {
const D val = *( vals.begin() + i );

// check if local
// if( (i / x._b) % data.P != data.s ) {
if( data.s !=
internal::Distribution< BSP1D >::global_index_to_process_id(
i, n, data.P
)
) {
continue;
}

// local, so translate index and perform requested operation
const size_t local_index =
internal::Distribution< BSP1D >::global_index_to_local( i, n, data.P );
#ifdef _DEBUG
std::cout << data.s << ", grb::setElement translates global index "
<< i << " to " << local_index << "\n";
#endif
ret = ret
? ret
: setElement( _local, val, local_index, EXECUTE );
}

// Synchronise once between all processes
if( SUCCESS !=
collectives< BSP1D >::allreduce( ret, operators::any_or< RC >() )
) {
throw std::runtime_error( "grb::Vector< BSP1D >::Vector( initializer_list ): "
"collective::allreduce failed." );
}

// on successful execute, sync new nnz count
updateNnz();
}

/**
* Copy constructor.
*
Expand Down
3 changes: 2 additions & 1 deletion include/graphblas/hyperdags/io.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,8 @@ namespace grb {
typename T
>
RC set(
Vector< DataType, hyperdags, Coords > &x, const T val,
Vector< DataType, hyperdags, Coords > &x,
const T val,
const Phase &phase = EXECUTE,
const typename std::enable_if<
!grb::is_object< DataType >::value &&
Expand Down
9 changes: 9 additions & 0 deletions include/graphblas/hyperdags/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,15 @@ namespace grb {
register_vector();
}

Vector( const std::initializer_list< T > vals ) : vector( vals )
{
#ifdef _DEBUG
std::cout << "In Vector< hyperdags >::Vector( initializer_list )"
<< " constructor\n";
#endif
register_vector();
}

~Vector() {
#ifdef _DEBUG
std::cout << "Vector (hyperdags) destructor\n";
Expand Down
18 changes: 15 additions & 3 deletions include/graphblas/nonblocking/coordinates.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,7 @@ namespace grb {
}

template< bool maybe_invalid = false >
inline void local_assignAll( ) noexcept {
inline void local_assignAll() noexcept {
if( maybe_invalid || _n != _cap ) {
if( _assigned != nullptr ) {
assert( _stack != nullptr );
Expand Down Expand Up @@ -318,16 +318,28 @@ namespace grb {
}
}

inline void clear() noexcept {
inline void assignAll() noexcept {
// this operates on the global coordinates, not on a local view of it
#pragma omp parallel
{
size_t start, end;
config::OMP::localRange( start, end, 0, _cap );
for( size_t i = start; i < end; ++i ) {
_assigned[ i ] = true;
_stack[ i ] = i;
}
}
_n = _cap;
}

inline void clear() noexcept {
if( _n == _cap ) {
#ifndef NDEBUG
if( _assigned == nullptr && _cap > 0 ) {
const bool dense_coordinates_may_not_call_clear = false;
assert( dense_coordinates_may_not_call_clear );
}
#endif

#pragma omp parallel for schedule( dynamic, config::CACHE_LINE_SIZE::value() )
for( size_t i = 0; i < _cap; ++i ) {
_assigned[ i ] = false;
Expand Down
18 changes: 17 additions & 1 deletion include/graphblas/nonblocking/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,14 @@ namespace grb {
typedef typename Vector< D, reference, MyCoordinates >::const_iterator
const_iterator;

Vector( const size_t n, const size_t nz ) : ref( n, nz ) {}
Vector( const size_t n, const size_t nz ) : ref( n, nz ) {
// pipeline execution is not required here as this is a grb::Vector
// declaration
#ifdef _DEBUG
std::cerr << "In Vector< nonblocking >::Vector( size_t, size_t )"
<< " constructor\n";
#endif
}

Vector( const size_t n ) : Vector( n, n ) {

Expand All @@ -266,6 +273,15 @@ namespace grb {
#endif
}

Vector( const std::initializer_list< D > vals ) : ref( vals ) {
// pipeline execution is not required here as this is a grb::Vector
// declaration
#ifdef _DEBUG
std::cerr << "In Vector< nonblocking >::Vector( initializer_list )"
<< " constructor\n";
#endif
}

Vector() : Vector( 0 ) {}

Vector( const Vector< D, nonblocking, MyCoordinates > &x ) :
Expand Down
22 changes: 22 additions & 0 deletions include/graphblas/reference/vector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,28 @@ namespace grb {
#endif
}

/**
* Constructs a reference vector.
*
* @see Full description in base backend.
*/
Vector( const std::initializer_list< D > &vals )
: Vector( vals.size(), vals.size() )
{
#ifdef _DEBUG
std::cerr << "In Vector< reference >::Vector( initializer_list )"
<< " constructor\n";
#endif

#ifdef _H_GRB_REFERENCE_OMP_VECTOR
#pragma omp parallel for simd
#endif
for( size_t i = 0; i < vals.size(); ++i ) {
_raw[ i ] = *( vals.begin() + i );
}
_coordinates.assignAll();
}

/**
* The default constructor creates an empty vector and should never be
* used explicitly.
Expand Down
4 changes: 4 additions & 0 deletions tests/unit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -300,6 +300,10 @@ add_grb_executables( adapterIterator adapterIterator.cpp
BACKENDS reference reference_omp hyperdags nonblocking bsp1d hybrid
)

add_grb_executables( vectorFromListConstructor vectorFromListConstructor.cpp
BACKENDS reference reference_omp bsp1d hybrid hyperdags nonblocking
)

# the below targets test successfully when they compile -- they do not need to
# be executed successfully as part of the unit test suite.

Expand Down
9 changes: 6 additions & 3 deletions tests/unit/eWiseLambda.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,16 +49,19 @@ void grbProgram( const void *, const size_t in_size, int &error ) {
}

if( !error ) {
rc = grb::eWiseLambda( [&M]( const size_t i, const size_t j, int& nz ) { nz = j; }, M );
rc = grb::eWiseLambda( [&M]( const size_t i, const size_t j, int& nz ) {
(void) i;
nz = j;
}, M );
}
if( rc != SUCCESS ) {
std::cerr << "\t eWiseLambda call failed\n";
error = 10;
}

if( !error ) {
for(auto it: M) {
if( it.second != it.first.second ) {
for( const auto &it : M ) {
if( static_cast< size_t >(it.second) != it.first.second ) {
std::cerr << "\t eWiseLambda returned incorrect result\n";
error = 15;
break;
Expand Down
6 changes: 6 additions & 0 deletions tests/unit/unittests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,12 @@ for MODE in ${MODES}; do
grep 'Test OK' ${TEST_OUT_DIR}/buildVector_${MODE}_${BACKEND}_${P}_${T}.log || echo "Test FAILED"
echo " "

echo ">>> [x] [ ] Testing grb::Vector( initializer_list ) constructor"
$runner ${TEST_BIN_DIR}/vectorFromListConstructor_${MODE}_${BACKEND} &> ${TEST_OUT_DIR}/vectorFromListConstructor_${MODE}_${BACKEND}_${P}_${T}.log
head -1 ${TEST_OUT_DIR}/vectorFromListConstructor_${MODE}_${BACKEND}_${P}_${T}.log
grep 'Test OK' ${TEST_OUT_DIR}/vectorFromListConstructor_${MODE}_${BACKEND}_${P}_${T}.log || echo "Test FAILED"
echo " "

echo ">>> [x] [ ] Testing grb::vectorToMatrixConverter"
$runner ${TEST_BIN_DIR}/vectorToMatrix_${MODE}_${BACKEND} &> ${TEST_OUT_DIR}/vectorToMatrix_${MODE}_${BACKEND}_${P}_${T}.log
head -1 ${TEST_OUT_DIR}/vectorToMatrix_${MODE}_${BACKEND}_${P}_${T}.log
Expand Down
80 changes: 80 additions & 0 deletions tests/unit/vectorFromListConstructor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@

/*
* Copyright 2021 Huawei Technologies Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <iostream>
#include <vector>

#include "graphblas.hpp"


using namespace grb;

void grbProgram( const void *, const size_t in_size, int &error ) {
if( in_size != 0 ) {
std::cerr << "Unit tests called with unexpected input" << std::endl;
error = 1;
return;
}
std::vector< int > values = { 4, 7, 4, 6, 4, 7, 1, 7, 3, 6, 7, 5, 1, 8, 7 };
grb::Vector< int > x( { 4, 7, 4, 6, 4, 7, 1, 7, 3, 6, 7, 5, 1, 8, 7 } );
bool equals = true;
auto vector_it = x.begin();
for( size_t i = 0; i < values.size(); i++ ) {
if( vector_it == x.end() ) {
std::cerr << "Vector iterator prematurely in end position!" << std::endl;
error = 10;
return;
}
auto position = vector_it->first;
auto value = vector_it->second;
if( i != position || values[ i ] != value ) {
std::cerr << "Expected position " << i << " value " << values[ i ]
<< " but got position " << position << " value " << value
<< std::endl;
equals = false;
break;
}
(void) vector_it.operator++();
}
if( !equals ) {
std::cerr << "Vector values are not correct" << std::endl;
error = 20;
return;
}
}

int main( int argc, char ** argv ) {
(void) argc;
std::cout << "Functional test executable: " << argv[ 0 ] << std::endl;

int error = 0;
grb::Launcher< AUTOMATIC > launcher;
if( launcher.exec( &grbProgram, NULL, 0, error ) != SUCCESS ) {
std::cout << "Test FAILED (test failed to launch)" << std::endl;
error = 255;
}
std::cerr << std::flush;
if( error == 0 ) {
std::cout << std::flush << "Test OK" << std::endl;
} else {
std::cout << std::flush << "Test FAILED" << std::endl;
}

// done
return error;
}