Skip to content
Open
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
2 changes: 1 addition & 1 deletion include/graphblas/banshee/blas1.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3491,7 +3491,7 @@ namespace grb {
for( size_t b = 0; b < Ring::blocksize; ++b, ++i ) {
// if we end up with a zero value
if( sparse && yy[ b ] == ring.template getZero< typename Ring::D4 >() ) {
// then substract it from the set of nonzeroes stored
// then subtract it from the set of nonzeroes stored
if( internal::getCoordinates( _z ).assigned( i ) ) {
internal::getRaw( _z )[ i ] = ring.template getZero< typename Ring::D4 >();
}
Expand Down
2 changes: 1 addition & 1 deletion include/graphblas/banshee/internalops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ namespace grb {

/** \todo add documentation */
template< typename IN1, typename IN2, typename OUT >
class substract< IN1, IN2, OUT, banshee_ssr > {
class subtract< IN1, IN2, OUT, banshee_ssr > {
public:
/** Alias to the left-hand input data type. */
typedef IN1 left_type;
Expand Down
237 changes: 222 additions & 15 deletions include/graphblas/base/internalops.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,117 @@ namespace grb {
/** Core implementations of the standard operators in #grb::operators. */
namespace internal {

/**
* Standard negation operator.
*
* Assumes native availability of ! on the given data types or assumes that
* the relevant operators are properly overloaded.
*
* @tparam Op The Operator class to negate.
* Requires the following typedefs:
* - \b D1: The left-hand input domain.
* - \b D2: The right-hand input domain.
* - \b D3: The output domain, must be convertible to bool.
* - \b OperatorType: The internal::operator type to negate.
*/
template<
typename Op,
enum Backend implementation = config::default_backend
>
class logical_not {

public:

/** Alias to the left-hand input data type. */
typedef typename Op::D1 left_type;

/** Alias to the right-hand input data type. */
typedef typename Op::D2 right_type;

/** Alias to the output data type. */
typedef typename Op::D3 result_type;

/** Whether this operator has an inplace foldl. */
static constexpr bool has_foldl = Op::OperatorType::has_foldl;

/** Whether this operator has an inplace foldr. */
static constexpr bool has_foldr = Op::OperatorType::has_foldr;

/**
* Whether this operator is \em mathematically associative; that is,
* associative when assuming equivalent data types for \a IN1, \a IN2,
* and \a OUT, as well as assuming exact arithmetic, no overflows, etc.
*/
static constexpr bool is_associative = Op::OperatorType::is_associative;

/**
* Whether this operator is \em mathematically commutative; that is,
* commutative when assuming equivalent data types for \a IN1, \a IN2,
* and \a OUT, as well as assuming exact arithmetic, no overflows, etc.
*/
static constexpr bool is_commutative = Op::OperatorType::is_commutative;

/**
* Out-of-place application of the operator.
*
* @param[in] a The left-hand side input. Must be pre-allocated and
* initialised.
* @param[in] b The right-hand side input. Must be pre-allocated and
* initialised.
* @param[out] c The output. Must be pre-allocated.
*/
static void apply(
const left_type * __restrict__ const a,
const right_type * __restrict__ const b,
result_type * __restrict__ const c,
const typename std::enable_if<
std::is_convertible< result_type, bool >::value,
void
>::type * = nullptr
) {
Op::OperatorType::apply( a, b, c );
*c = !*c;
}

/**
* In-place left-to-right folding.
*
* @param[in] a Pointer to the left-hand side input data.
* @param[in,out] c Pointer to the right-hand side input data. This also
* dubs as the output memory area.
*/
static void foldr(
const left_type * __restrict__ const a,
result_type * __restrict__ const c,
const typename std::enable_if<
std::is_convertible< result_type, bool >::value,
void
>::type * = nullptr
) {
Op::OperatorType::foldr( a, c );
*c = !*c;
}

/**
* In-place right-to-left folding.
*
* @param[in,out] c Pointer to the left-hand side input data. This also
* dubs as the output memory area.
* @param[in] b Pointer to the right-hand side input data.
*/
static void foldl(
result_type * __restrict__ const c,
const right_type * __restrict__ const b,
const typename std::enable_if<
std::is_convertible< result_type, bool >::value,
void
>::type * = nullptr
) {
Op::OperatorType::foldl( c, b );
*c = !*c;
}
};

/**
* Standard argmin operator.
*
Expand Down Expand Up @@ -1128,7 +1239,7 @@ namespace grb {
typename IN1, typename IN2, typename OUT,
enum Backend implementation = config::default_backend
>
class substract {
class subtract {

public:

Expand Down Expand Up @@ -1676,7 +1787,7 @@ namespace grb {
* @param[in] b The right-hand side input. Must be pre-allocated and initialised.
* @param[out] c The output. Must be pre-allocated.
*
* At the end of the operation, \f$ c = \min\{a,b\} \f$.
* At the end of the operation, \f$ c = \any_or\{a,b\} \f$.
*/
static void apply(
const left_type * __restrict__ const a,
Expand Down Expand Up @@ -1728,7 +1839,7 @@ namespace grb {
};

/**
* The logical or operator, \f$ x \lor y \f$.
* The logical-or operator, \f$ x \lor y \f$.
*
* Assumes that the || operator is defined on the given input types.
*/
Expand Down Expand Up @@ -1778,7 +1889,7 @@ namespace grb {
* initialised.
* @param[out] c The output. Must be pre-allocated.
*
* At the end of the operation, \f$ c = \min\{a,b\} \f$.
* At the end of the operation, \f$ c = \or\{a,b\} \f$.
*/
static void apply(
const left_type * __restrict__ const a,
Expand Down Expand Up @@ -1830,6 +1941,109 @@ namespace grb {

};

/**
* The logical-xor operator, \f$ x \lxor y \f$.
*
* Assumes that the xor operator is defined on the given input types.
*/
template<
typename IN1, typename IN2, typename OUT,
enum Backend implementation = config::default_backend
>
class logical_xor {

public:

/** Alias to the left-hand input data type. */
typedef IN1 left_type;

/** Alias to the right-hand input data type. */
typedef IN2 right_type;

/** Alias to the output data type. */
typedef OUT result_type;

/** Whether this operator has an in-place foldl. */
static constexpr bool has_foldl = true;

/** Whether this operator has an in-place foldr. */
static constexpr bool has_foldr = true;

/**
* Whether this operator is \em mathematically associative; that is,
* associative when assuming equivalent data types for \a IN1, \a IN2,
* and \a OUT, as well as assuming exact arithmetic, no overflows, etc.
*/
static constexpr bool is_associative = true;

/**
* Whether this operator is \em mathematically commutative; that is,
* commutative when assuming equivalent data types for \a IN1, \a IN2,
* and \a OUT, as well as assuming exact arithmetic, no overflows, etc.
*/
static constexpr bool is_commutative = true;

/**
* Out-of-place application of this operator.
*
* @param[in] a The left-hand side input. Must be pre-allocated and
* initialised.
* @param[in] b The right-hand side input. Must be pre-allocated and
* initialised.
* @param[out] c The output. Must be pre-allocated.
*
* At the end of the operation, \f$ c = \xor\{a,b\} \f$.
*/
static void apply(
const left_type * __restrict__ const a,
const right_type * __restrict__ const b,
result_type * __restrict__ const c
) {
if( *a xor *b ) {
*c = static_cast< OUT >( true );
} else {
*c = static_cast< OUT >( false );
}
}

/**
* In-place left-to-right folding.
*
* @param[in] a Pointer to the left-hand side input data.
* @param[in,out] c Pointer to the right-hand side input data. This also
* dubs as the output memory area.
*/
static void foldr(
const left_type * __restrict__ const a,
result_type * __restrict__ const c
) {
if( *a xor *c ) {
*c = static_cast< result_type >( true );
} else {
*c = static_cast< result_type >( false );
}
}

/**
* In-place right-to-left folding.
*
* @param[in,out] c Pointer to the left-hand side input data. This also
* dubs as the output memory area.
* @param[in] b Pointer to the right-hand side input data.
*/
static void foldl(
result_type * __restrict__ const c,
const right_type * __restrict__ const b
) {
if( *b xor *c ) {
*c = static_cast< result_type >( true );
} else {
*c = static_cast< result_type >( false );
}
}

};

/**
* The logical-and operator, \f$ x \land y \f$.
*
Expand Down Expand Up @@ -1881,7 +2095,7 @@ namespace grb {
* initialised.
* @param[out] c The output. Must be pre-allocated.
*
* At the end of the operation, \f$ c = \min\{a,b\} \f$.
* At the end of the operation, \f$ c = \and\{a,b\} \f$.
*/
static void apply(
const left_type * __restrict__ const a,
Expand Down Expand Up @@ -2838,16 +3052,6 @@ namespace grb {

public:

/** @return Whether this operator is mathematically associative. */
static constexpr bool is_associative() {
return OP::is_associative;
}

/** @return Whether this operator is mathematically commutative. */
static constexpr bool is_commutative() {
return OP::is_commutative;
}

/**
* Straightforward application of this operator. Computes \f$ x \odot y \f$
* and stores the result in \a z.
Expand Down Expand Up @@ -4179,6 +4383,9 @@ namespace grb {
/** The output domain of this operator. */
typedef typename OperatorBase< OP >::D3 D3;

/** The type of the internal::operator OP. */
typedef OP OperatorType;

/**
* Reduces a vector of type \a InputType into a value in \a IOType
* by repeated application of this operator. The \a IOType is cast
Expand Down
2 changes: 1 addition & 1 deletion include/graphblas/bsp1d/init.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ namespace grb {
* Decrements \a regs_taken.
*
* @param[in] count (Optional) The number of memslots that should be
* substracted from \a regs_taken. Default is 1. Passing
* subtracted from \a regs_taken. Default is 1. Passing
* zero will turn a call to this function into a no-op.
*/
void signalMemslotReleased( const unsigned int count = 1 );
Expand Down
Loading