Skip to content

Commit 72dc467

Browse files
committed
Recover GPU
1 parent f9c515d commit 72dc467

File tree

13 files changed

+2596
-0
lines changed

13 files changed

+2596
-0
lines changed
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file testGPUsortHIP.hip
13+
/// \author Michael Lettrich
14+
15+
#define GPUCA_GPUTYPE_VEGA
16+
17+
#define BOOST_TEST_MODULE Test GPUCommonAlgorithm Sorting HIP
18+
#define BOOST_TEST_MAIN
19+
#define BOOST_TEST_DYN_LINK
20+
21+
#include <iostream>
22+
#include <cstring>
23+
#include <hip/hip_runtime.h>
24+
#include <boost/test/unit_test.hpp>
25+
#include "GPUCommonAlgorithm.h"
26+
27+
///////////////////////////////////////////////////////////////
28+
// Test setup and tear down
29+
///////////////////////////////////////////////////////////////
30+
31+
static constexpr float TOLERANCE = 10 * std::numeric_limits<float>::epsilon();
32+
33+
hipError_t hipCheckError(hipError_t hipErrorCode)
34+
{
35+
if (hipErrorCode != hipSuccess) {
36+
std::cerr << "ErrorCode " << hipErrorCode << " " << hipGetErrorName(hipErrorCode) << ": " << hipGetErrorString(hipErrorCode) << std::endl;
37+
}
38+
return hipErrorCode;
39+
}
40+
41+
void hipCheckErrorFatal(hipError_t hipErrorCode)
42+
{
43+
if (hipCheckError(hipErrorCode) != hipSuccess) {
44+
exit(-1);
45+
}
46+
}
47+
48+
struct TestEnvironment {
49+
TestEnvironment() : size(101), data(nullptr), sorted(size)
50+
{
51+
hipCheckErrorFatal(hipHostMalloc(&data, size * sizeof(float), hipHostRegisterDefault));
52+
53+
// create an array of unordered floats with negative and positive values
54+
for (size_t i = 0; i < size; i++) {
55+
data[i] = size / 2.0f - i;
56+
}
57+
// create copy
58+
std::memcpy(sorted.data(), data, size * sizeof(float));
59+
// sort
60+
std::sort(sorted.begin(), sorted.end());
61+
}
62+
63+
~TestEnvironment() // NOLINT: clang-tidy doesn't understand hip macro magic, and thinks this is trivial
64+
{
65+
hipCheckErrorFatal(hipFree(data));
66+
};
67+
68+
const size_t size;
69+
float* data;
70+
std::vector<float> sorted;
71+
};
72+
73+
template <typename T>
74+
void testAlmostEqualArray(T* correct, T* testing, size_t size)
75+
{
76+
for (size_t i = 0; i < size; i++) {
77+
if (std::fabs(correct[i]) < TOLERANCE) {
78+
BOOST_CHECK_SMALL(testing[i], TOLERANCE);
79+
} else {
80+
BOOST_CHECK_CLOSE(correct[i], testing[i], TOLERANCE);
81+
}
82+
}
83+
}
84+
85+
///////////////////////////////////////////////////////////////
86+
87+
__global__ void sortInThread(float* data, size_t dataLength)
88+
{
89+
// make sure only one thread is working on this.
90+
if (hipBlockIdx_x == 0 && hipBlockIdx_y == 0 && hipBlockIdx_z == 0 && hipThreadIdx_x == 0 && hipThreadIdx_y == 0 && hipThreadIdx_z == 0) {
91+
o2::gpu::CAAlgo::sort(data, data + dataLength);
92+
}
93+
}
94+
95+
__global__ void sortInThreadWithOperator(float* data, size_t dataLength)
96+
{
97+
// make sure only one thread is working on this.
98+
if (hipBlockIdx_x == 0 && hipBlockIdx_y == 0 && hipBlockIdx_z == 0 && hipThreadIdx_x == 0 && hipThreadIdx_y == 0 && hipThreadIdx_z == 0) {
99+
o2::gpu::CAAlgo::sort(data, data + dataLength, [](float a, float b) { return a < b; });
100+
}
101+
}
102+
103+
///////////////////////////////////////////////////////////////
104+
105+
__global__ void sortInBlock(float* data, size_t dataLength)
106+
{
107+
o2::gpu::CAAlgo::sortInBlock<float>(data, data + dataLength);
108+
}
109+
110+
__global__ void sortInBlockWithOperator(float* data, size_t dataLength)
111+
{
112+
o2::gpu::CAAlgo::sortInBlock(data, data + dataLength, [](float a, float b) { return a < b; });
113+
}
114+
///////////////////////////////////////////////////////////////
115+
116+
BOOST_AUTO_TEST_SUITE(TestsortInThread)
117+
118+
BOOST_FIXTURE_TEST_CASE(GPUsortThreadHIP, TestEnvironment)
119+
{
120+
hipLaunchKernelGGL(sortInThread, dim3(1), dim3(1), 0, 0, data, size);
121+
// sortInThread<<<dim3(1), dim3(1), 0, 0>>>(data, size);
122+
BOOST_CHECK_EQUAL(hipCheckError(hipDeviceSynchronize()), hipSuccess);
123+
testAlmostEqualArray(sorted.data(), data, size);
124+
}
125+
126+
BOOST_FIXTURE_TEST_CASE(GPUsortThreadOperatorHIP, TestEnvironment)
127+
{
128+
hipLaunchKernelGGL(sortInThreadWithOperator, dim3(1), dim3(1), 0, 0, data, size);
129+
// sortInThreadWithOperator<<<dim3(1), dim3(1), 0, 0>>>(data, size);
130+
BOOST_CHECK_EQUAL(hipCheckError(hipDeviceSynchronize()), hipSuccess);
131+
testAlmostEqualArray(sorted.data(), data, size);
132+
}
133+
134+
BOOST_AUTO_TEST_SUITE_END()
135+
136+
BOOST_AUTO_TEST_SUITE(TestsortInBlock)
137+
138+
BOOST_FIXTURE_TEST_CASE(GPUsortBlockHIP, TestEnvironment)
139+
{
140+
hipLaunchKernelGGL(sortInBlock, dim3(1), dim3(128), 0, 0, data, size);
141+
// sortInBlock<<<dim3(1), dim3(128), 0, 0>>>(data, size);
142+
BOOST_CHECK_EQUAL(hipCheckError(hipDeviceSynchronize()), hipSuccess);
143+
testAlmostEqualArray(sorted.data(), data, size);
144+
}
145+
146+
BOOST_FIXTURE_TEST_CASE(GPUsortBlockOperatorHIP, TestEnvironment)
147+
{
148+
hipLaunchKernelGGL(sortInBlockWithOperator, dim3(1), dim3(128), 0, 0, data, size);
149+
// sortInBlockWithOperator<<<dim3(1), dim3(128), 0, 0>>>(data, size);
150+
BOOST_CHECK_EQUAL(hipCheckError(hipDeviceSynchronize()), hipSuccess);
151+
testAlmostEqualArray(sorted.data(), data, size);
152+
}
153+
154+
BOOST_AUTO_TEST_SUITE_END()

0 commit comments

Comments
 (0)