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
9 changes: 9 additions & 0 deletions DataFormats/Portable/test/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,12 @@
<use name="HeterogeneousCore/AlpakaInterface"/>
<flags ALPAKA_BACKENDS="1"/>
</bin>

<bin name="Device_test_methods" file="alpaka/device_test_methods.dev.cc">
<use name="DataFormats/Portable"/>
<use name="DataFormats/SoATemplate"/>
<use name="catch2"/>
<use name="eigen"/>
<use name="HeterogeneousCore/AlpakaInterface"/>
<flags ALPAKA_BACKENDS="1"/>
</bin>
117 changes: 94 additions & 23 deletions DataFormats/Portable/test/alpaka/device_methods.dev.cc
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,27 @@ GENERATE_SOA_LAYOUT(SoAPositionTemplate,

SOA_ELEMENT_METHODS(

SOA_HOST_DEVICE void normalise() {
SOA_HOST_DEVICE SOA_INLINE void normalise() {
float norm_position = square_norm_position();
if (norm_position > 0.0f) {
x() /= norm_position;
y() /= norm_position;
z() /= norm_position;
}};
}}

template <typename OtherView>
SOA_HOST_DEVICE SOA_INLINE void add(OtherView& otherSoA) {
x() = x() + otherSoA.x(0);
y() = y() + otherSoA.y(0);
z() = z() + otherSoA.z(0);
}

),

SOA_CONST_ELEMENT_METHODS(
SOA_HOST_DEVICE float square_norm_position() const { return sqrt(x() * x() + y() * y() + z() * z()); };

SOA_HOST_DEVICE SOA_INLINE float square_norm_position() const { return sqrt(x() * x() + y() * y() + z() * z()); };

),

SOA_SCALAR(int, detectorType))
Expand All @@ -69,16 +79,34 @@ struct FillSoA {
// Kernel for normalising the positions
struct NormalisePositions {
template <typename TAcc, typename PositionView>
ALPAKA_FN_ACC void operator()(TAcc const& acc, PositionView positionView) const {
ALPAKA_FN_ACC void operator()(TAcc const& acc, PositionView& positionView) const {
for (auto local_idx : cms::alpakatools::uniform_elements(acc, positionView.metadata().size())) {
positionView[local_idx].normalise();
}
}
};


// Kernel for finding the sum of first element and the current element
struct Addition {
template <typename TAcc, typename PositionView>
ALPAKA_FN_ACC void operator()(TAcc const& acc, PositionView& positionView) const {
for (auto local_idx : cms::alpakatools::uniform_elements(acc, positionView.metadata().size())) {
if (local_idx != 0) {
positionView[local_idx].add(positionView);
}
}
}
};


int main(int argc, char** argv) {

int i=0;
std::chrono::time_point<std::chrono::high_resolution_clock> start, end;
std::vector<double> inner_repetitions(100);
double sum, average;

auto const& devices = cms::alpakatools::devices<Platform>();
if (devices.empty()) {
std::cout << "No devices available for the " << EDM_STRINGIZE(ALPAKA_ACCELERATOR_NAMESPACE) << " backend, "
Expand All @@ -87,27 +115,28 @@ int main(int argc, char** argv) {

auto devHost = alpaka::getDevByIdx(alpaka::PlatformCpu{}, 0u);

for (auto const& device : cms::alpakatools::devices<Platform>()) {
for (auto const& device : cms::alpakatools::devices<Platform>()) {
std::cout << "Running on " << alpaka::getName(device) << std::endl;

Queue queue(device);

// common number of elements for the SoAs
const std::size_t elems = 50000000;
const std::size_t elems = parse_or_default(argc > 1 ? argv[1] : nullptr, 0);

// Portable Collections
PortableCollection<SoAPosition, Device> positionCollection(elems, queue);
SoAPositionView& positionCollectionView = positionCollection.view();
SoAPositionView positionCollectionView = positionCollection.view();
// SoAPositionConstView positionCollectionConstView = positionCollection.const_view();

// fill up
// 1) Block size: argv[1] if valid, else 64
const std::size_t blockSize = parse_or_default(argc > 1 ? argv[1] : nullptr, 64);
const std::size_t blockSize = parse_or_default(argc > 2 ? argv[2] : nullptr, 512);

// 2) Default blocks: cover all elements for the chosen block size
const std::size_t defaultBlocks = cms::alpakatools::divide_up_by(elems, blockSize);

// 3) Number of blocks: argv[2] if valid (>0), else defaultBlocks
std::size_t numberOfBlocks = parse_or_default(argc > 2 ? argv[2] : nullptr, defaultBlocks);
std::size_t numberOfBlocks = parse_or_default(argc > 3 ? argv[3] : nullptr, defaultBlocks);

// (Optional) guard: never let it be 0
if (numberOfBlocks == 0) numberOfBlocks = defaultBlocks;
Expand All @@ -117,28 +146,70 @@ int main(int argc, char** argv) {
alpaka::exec<Acc1D>(queue, workDiv, FillSoA{}, positionCollectionView);
alpaka::wait(queue);

auto start = std::chrono::high_resolution_clock::now();
start = std::chrono::high_resolution_clock::now();

// normalise
alpaka::exec<Acc1D>(queue, workDiv, NormalisePositions{}, positionCollectionView);
alpaka::wait(queue);
for (int j = 0 ; j < 20 ; j++) {
// normalise
alpaka::exec<Acc1D>(queue, workDiv, NormalisePositions{}, positionCollectionView);
alpaka::wait(queue);

auto end = std::chrono::high_resolution_clock::now();
std::chrono::duration<double> elapsed = end - start;
std::cout << "Total execution time: " << elapsed.count() << " seconds\n";
// element addition
alpaka::exec<Acc1D>(queue, workDiv, Addition{}, positionCollectionView);
alpaka::wait(queue);

// fill
alpaka::exec<Acc1D>(queue, workDiv, FillSoA{}, positionCollectionView);
alpaka::wait(queue);
}

end = std::chrono::high_resolution_clock::now();

for(i=0; i<101; i++) {

start = std::chrono::high_resolution_clock::now();

for (int j = 0 ; j < 10 ; j++) {
// normalise
alpaka::exec<Acc1D>(queue, workDiv, NormalisePositions{}, positionCollectionView);
alpaka::wait(queue);

// element addition
alpaka::exec<Acc1D>(queue, workDiv, Addition{}, positionCollectionView);
alpaka::wait(queue);

// fill
alpaka::exec<Acc1D>(queue, workDiv, FillSoA{}, positionCollectionView);
alpaka::wait(queue);
}

end = std::chrono::high_resolution_clock::now();

std::chrono::duration<double> elapsed = (end - start) * 1000;

if (i > 0)
inner_repetitions[i-1] = elapsed.count();
}

// Calculate the sum of all elements
sum = std::accumulate(inner_repetitions.begin(), inner_repetitions.end(), 0.0);

// Calculate the average
average = sum / inner_repetitions.size();

std::cout << "Average execution time: " << average << " ms\n";

PortableHostCollection<SoAPosition> positionHostCollection(elems, queue);
alpaka::memcpy(queue, positionHostCollection.buffer(), positionCollection.buffer());
alpaka::wait(queue);

// check norm == 1
const SoAPositionConstView& positionViewHostCollection = positionHostCollection.const_view();
for (size_t i = 0; i < elems; i++) {
float norm = positionViewHostCollection[i].square_norm_position();
if (std::abs(norm - 1.0f) > 1.e-5f) {
std::cout << "Error in normalisation at element " << i << " : " << norm << std::endl;
}
}
// const SoAPositionConstView& positionViewHostCollection = positionHostCollection.const_view();
// for (size_t i = 0; i < elems; i++) {
// float norm = positionViewHostCollection[i].square_norm_position();
// if (std::abs(norm - 1.0f) > 1.e-5f) {
// std::cout << "Error in normalisation at element " << i << " : " << norm << std::endl;
// }
// }

std::cout << "Normalisation check completed" << std::endl;

Expand Down
Loading