-
Notifications
You must be signed in to change notification settings - Fork 75
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added unit test for n-arity math operators
Added tests for unary math operators with functors. Added binaryOps and reworked unaryOps. Reduced doubled code significantly, by allowing to test operators of n-arity with the same code. Integrated PR from td11235813 Removed HCC workaround and rebased NOTE: fast-math needs to be disabled for gpu-backend. Co-authored-by: Matthias Werner <Matthias.Werner1@tu-dresden.de>
- Loading branch information
Showing
7 changed files
with
968 additions
and
17 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# | ||
# Copyright 2017-2019 Benjamin Worpitz, Jakob Krude | ||
# | ||
# This file is part of Alpaka. | ||
# | ||
# This Source Code Form is subject to the terms of the Mozilla Public | ||
# License, v. 2.0. If a copy of the MPL was not distributed with this | ||
# file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
# | ||
|
||
SET(_TARGET_NAME "mathOps") | ||
|
||
|
||
append_recursive_files_add_to_src_group("src/" "src/" "cpp" _FILES_SOURCE) | ||
|
||
|
||
message(STATUS "Disabling fast math options for math operation tests only.") | ||
if(ALPAKA_ACC_GPU_CUDA_ENABLE) | ||
list(REMOVE_ITEM | ||
CUDA_NVCC_FLAGS "--ftz=true" "--prec-div=false" "--prec-sqrt=false" "--fmad=true" "--use_fast_math" "-use_fast_math") | ||
|
||
endif() | ||
if(ALPAKA_ACC_GPU_HIP_ENABLE) | ||
list(REMOVE_ITEM | ||
HIP_NVCC_FLAGS "--ftz=true" "--prec-div=false" "--prec-sqrt=false" "--fmad=true" "--use_fast_math" "-use_fast_math") | ||
endif() | ||
|
||
|
||
ALPAKA_ADD_EXECUTABLE( | ||
${_TARGET_NAME} | ||
${_FILES_SOURCE}) | ||
TARGET_INCLUDE_DIRECTORIES( | ||
${_TARGET_NAME} | ||
PRIVATE ${Boost_INCLUDE_DIRS}) | ||
TARGET_LINK_LIBRARIES( | ||
${_TARGET_NAME} | ||
PRIVATE common) | ||
SET_TARGET_PROPERTIES( | ||
${_TARGET_NAME} | ||
PROPERTIES | ||
COMPILE_OPTIONS | ||
$<$<CXX_COMPILER_ID:clang>:"-ffp-contract=off"> # ffp-contract: https://llvm.org/docs/CompileCudaWithLLVM.html#id5 | ||
) | ||
|
||
SET_TARGET_PROPERTIES(${_TARGET_NAME} PROPERTIES FOLDER "test/unit") | ||
|
||
ADD_TEST(NAME ${_TARGET_NAME} COMMAND ${_TARGET_NAME} ${_ALPAKA_TEST_OPTIONS}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
/** Copyright 2019 Jakob Krude, Benjamin Worpitz | ||
* | ||
* This file is part of Alpaka. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "Defines.hpp" | ||
#include <alpaka/test/acc/TestAccs.hpp> | ||
#include <ostream> | ||
|
||
namespace alpaka { | ||
namespace test { | ||
namespace unit { | ||
namespace math { | ||
|
||
//! Provides Alpaka-style buffer with arguments' data. | ||
//! TData can be a plain value or a complex data-structure. | ||
//! The operator() is overloaded and returns the value from the correct Buffer, | ||
//! either from the host (index) or device buffer (index, acc). | ||
//! Index out of range errors are not checked. | ||
//! @brief Encapsulates buffer initialisation and communication with Device. | ||
//! @tparam TAcc Used accelerator, not interchangeable | ||
//! @tparam TData The Data-type, only restricted by the alpaka-interface. | ||
//! @tparam Tcapacity The size of the buffer. | ||
template< | ||
typename TAcc, | ||
typename TData, | ||
size_t Tcapacity | ||
> | ||
struct Buffer | ||
{ | ||
using value_type = TData; | ||
static constexpr size_t capacity = Tcapacity; | ||
using Dim = typename alpaka::dim::traits::DimType<TAcc>::type; | ||
using Idx = typename alpaka::idx::traits::IdxType<TAcc>::type; | ||
|
||
// Defines using's for alpaka-buffer. | ||
using DevAcc = alpaka::dev::Dev< TAcc >; | ||
using DevHost = alpaka::dev::DevCpu; | ||
using PltfHost = alpaka::pltf::Pltf< DevHost >; | ||
|
||
using BufHost = alpaka::mem::buf::Buf< | ||
DevHost, | ||
TData, | ||
Dim, | ||
Idx | ||
>; | ||
using BufAcc = alpaka::mem::buf::Buf< | ||
DevAcc, | ||
TData, | ||
Dim, | ||
Idx | ||
>; | ||
|
||
DevHost devHost; | ||
|
||
BufHost hostBuffer; | ||
BufAcc devBuffer; | ||
|
||
// Native pointer to access buffer. | ||
TData * const pHostBuffer; | ||
TData * const pDevBuffer; | ||
|
||
|
||
// This constructor cant be used, | ||
// because BufHost and BufAcc need to be initialised. | ||
Buffer( ) = delete; | ||
|
||
// Constructor needs to initialize all Buffer. | ||
Buffer(const DevAcc & devAcc) | ||
: | ||
devHost{ alpaka::pltf::getDevByIdx< PltfHost >( 0u ) }, | ||
hostBuffer | ||
{ | ||
alpaka::mem::buf::alloc<TData, Idx>(devHost, Tcapacity) | ||
}, | ||
devBuffer | ||
{ | ||
alpaka::mem::buf::alloc<TData, Idx>(devAcc, Tcapacity) | ||
}, | ||
pHostBuffer{ alpaka::mem::view::getPtrNative( hostBuffer ) }, | ||
pDevBuffer{ alpaka::mem::view::getPtrNative( devBuffer ) } | ||
{} | ||
|
||
// Copy Host -> Acc. | ||
template< typename Queue > | ||
auto copyToDevice( Queue queue ) -> void | ||
{ | ||
alpaka::mem::view::copy( | ||
queue, | ||
devBuffer, | ||
hostBuffer, | ||
Tcapacity | ||
); | ||
} | ||
|
||
// Copy Acc -> Host. | ||
template< typename Queue > | ||
auto copyFromDevice( Queue queue ) -> void | ||
{ | ||
alpaka::mem::view::copy( | ||
queue, | ||
hostBuffer, | ||
devBuffer, | ||
Tcapacity | ||
); | ||
} | ||
|
||
ALPAKA_FN_ACC | ||
auto operator()( | ||
size_t idx, | ||
TAcc const & acc ) const -> TData& | ||
{ | ||
alpaka::ignore_unused(acc); | ||
return pDevBuffer[idx]; | ||
} | ||
|
||
ALPAKA_FN_HOST | ||
auto operator()( | ||
size_t idx ) const -> TData& | ||
{ | ||
return pHostBuffer[idx]; | ||
} | ||
|
||
ALPAKA_FN_HOST | ||
friend std::ostream & operator<<( | ||
std::ostream & os, | ||
const Buffer & buffer | ||
) | ||
{ | ||
os << "capacity: " << capacity | ||
<< "\n"; | ||
for( size_t i = 0; i < capacity; ++i ) | ||
{ | ||
os << i | ||
<< ": " << buffer.pHostBuffer[i] | ||
<< "\n"; | ||
} | ||
return os; | ||
} | ||
}; | ||
|
||
} // math | ||
} // unit | ||
} // test | ||
} // alpaka |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
/** Copyright 2019 Jakob Krude, Benjamin Worpitz | ||
* | ||
* This file is part of Alpaka. | ||
* | ||
* This Source Code Form is subject to the terms of the Mozilla Public | ||
* License, v. 2.0. If a copy of the MPL was not distributed with this | ||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include "Defines.hpp" | ||
#include <random> | ||
#include <limits> | ||
#include <cassert> | ||
|
||
namespace alpaka { | ||
namespace test { | ||
namespace unit { | ||
namespace math { | ||
|
||
|
||
/** | ||
* Fills buffer with random numbers (host-only). | ||
* | ||
* @tparam TData The used data-type (float || double). | ||
* @tparam TArgs The args-buffer to be filled. | ||
* @tparam TFunctor The used Functor-type. | ||
* @param args The buffer that should be filled. | ||
* @param functor The Functor, needed for ranges. | ||
* @param seed The used seed. | ||
*/ | ||
template< | ||
typename TData, | ||
typename TArgs, | ||
typename TFunctor> | ||
auto fillWithRndArgs( | ||
TArgs & args, | ||
TFunctor functor, | ||
unsigned long const & seed | ||
) -> void | ||
{ | ||
/* | ||
* Each "sub-buffer" is filled with zero and/or max and/or lowest, | ||
* depending on the specified range (at [0] - [2]). | ||
* | ||
* Every switch case needs to return! | ||
* If no switch case was matched an assert(false) will be triggered. | ||
* | ||
* This function is easily extendable. It is only necessary to add extra | ||
* definitions in the switch case, for more Range-types. | ||
*/ | ||
static_assert( TArgs::value_type::arity == TFunctor::arity, | ||
"Buffer properties must match TFunctor::arity" ); | ||
static_assert( TArgs::capacity > 2, | ||
"Set of args must provide > 2 entries." ); | ||
constexpr auto max = std::numeric_limits< TData >::max(); | ||
constexpr auto low = std::numeric_limits< TData >::lowest(); | ||
std::default_random_engine eng{ seed }; | ||
|
||
// These pseudo-random numbers are implementation/platform specific! | ||
std::uniform_real_distribution< TData > dist(0,1000); | ||
std::uniform_real_distribution< TData > distOne(-1,1); | ||
|
||
for(size_t k = 0; k < TFunctor::arity_nr; ++k) | ||
{ | ||
bool matchedSwitch = false; | ||
switch( functor.ranges[k] ) | ||
{ | ||
case Range::OneNeighbourhood: | ||
matchedSwitch = true; | ||
for( size_t i = 0; i < TArgs::capacity; ++i ) | ||
{ | ||
args( i ).arg[k] = distOne( eng ); | ||
} | ||
break; | ||
|
||
case Range::PositiveOnly: | ||
matchedSwitch = true; | ||
args( 0 ).arg[k] = max; | ||
for( size_t i = 1; i < TArgs::capacity; ++i ) | ||
{ | ||
args( i ).arg[k] = dist( eng ) + static_cast<TData>(1); | ||
} | ||
break; | ||
|
||
case Range::PositiveAndZero: | ||
matchedSwitch = true; | ||
args( 0 ).arg[k] = 0.0; | ||
args( 1 ).arg[k] = max; | ||
for( size_t i = 2; i < TArgs::capacity; ++i ) | ||
{ | ||
args( i ).arg[k] = dist( eng ); | ||
} | ||
break; | ||
|
||
case Range::NotZero: | ||
matchedSwitch = true; | ||
args( 0 ).arg[k] = max; | ||
args( 1 ).arg[k] = low; | ||
for( size_t i = 2; i < TArgs::capacity; ++i ) | ||
{ | ||
TData arg; | ||
do | ||
{ | ||
arg = dist( eng ); | ||
} | ||
while( std::equal_to<TData>()(arg,1) ); | ||
if( i % 2 == 0 ) | ||
args( i ).arg[k] = arg; | ||
else | ||
args( i ).arg[k] = -arg; | ||
} | ||
break; | ||
|
||
case Range::Unrestricted: | ||
matchedSwitch = true; | ||
args( 0 ).arg[k] = 0.0; | ||
args( 1 ).arg[k] = max; | ||
args( 2 ).arg[k] = low; | ||
for( size_t i = 3; i < TArgs::capacity; ++i ) | ||
{ | ||
if( i % 2 == 0 ) | ||
args( i ).arg[k] = dist( eng ); | ||
else | ||
args( i ).arg[k] = -dist( eng ); | ||
} | ||
break; | ||
} | ||
// disable gcc-warning "unused variable" | ||
alpaka::ignore_unused(matchedSwitch); | ||
assert(matchedSwitch); | ||
} | ||
} | ||
|
||
} // math | ||
} // unit | ||
} // test | ||
} // alpaka |
Oops, something went wrong.