Skip to content

Commit 244006d

Browse files
committed
[alpaka/cuda] tests for atomic and barriers
1 parent 7e07487 commit 244006d

6 files changed

Lines changed: 677 additions & 0 deletions

File tree

src/alpaka/test/alpaka/atomtest.cc

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
#include "AlpakaCore/alpakaConfig.h"
5+
#include "AlpakaCore/alpakaWorkDivHelper.h"
6+
7+
using namespace ALPAKA_ACCELERATOR_NAMESPACE;
8+
9+
template <typename T, typename Data>
10+
struct shared_block {
11+
template <typename T_Acc>
12+
ALPAKA_FN_ACC void operator()(const T_Acc& acc, Data *vec, T elements) const {
13+
14+
auto threadIdxLocal(alpaka::getIdx<alpaka::Block, alpaka::Threads>(acc)[0u]);
15+
auto blockIdxInGrid(alpaka::getIdx<alpaka::Grid, alpaka::Blocks>(acc)[0u]);
16+
Data b = 1.0;
17+
Data c = -1.0;
18+
19+
auto& s = alpaka::declareSharedVar<Data, __COUNTER__>(acc);
20+
21+
if (threadIdxLocal == 0) {
22+
s = 0;
23+
}
24+
25+
syncBlockThreads(acc);
26+
27+
for (T index: cms::alpakatools::elements_with_stride<T, T_Acc>(acc, elements)) {
28+
for (int i = 0; i < 200000; i++) {
29+
alpaka::atomicAdd(acc, &s, b, alpaka::hierarchy::Blocks{});
30+
alpaka::atomicAdd(acc, &s, c, alpaka::hierarchy::Blocks{});
31+
}
32+
alpaka::atomicAdd(acc, &s, b, alpaka::hierarchy::Blocks{});
33+
}
34+
35+
syncBlockThreads(acc);
36+
37+
if (threadIdxLocal == 0) {
38+
vec[blockIdxInGrid] = s;
39+
}
40+
}
41+
};
42+
43+
template <typename T, typename Data>
44+
struct global_block {
45+
template <typename T_Acc>
46+
ALPAKA_FN_ACC void operator()(const T_Acc& acc, Data *vec, T elements) const {
47+
48+
auto blockIdxInGrid(alpaka::getIdx<alpaka::Grid, alpaka::Blocks>(acc)[0u]);
49+
Data b = 1.0;
50+
Data c = -1.0;
51+
52+
for (T index: cms::alpakatools::elements_with_stride<T, T_Acc>(acc, elements)) {
53+
for (int i = 0; i < 200000; i++) {
54+
alpaka::atomicAdd(acc, &vec[blockIdxInGrid], b, alpaka::hierarchy::Grids{});
55+
alpaka::atomicAdd(acc, &vec[blockIdxInGrid], c, alpaka::hierarchy::Grids{});
56+
}
57+
alpaka::atomicAdd(acc, &vec[blockIdxInGrid], b, alpaka::hierarchy::Grids{});
58+
}
59+
}
60+
};
61+
62+
template <typename T, typename Data>
63+
struct global_grid {
64+
template <typename T_Acc>
65+
ALPAKA_FN_ACC void operator()(const T_Acc& acc, Data *vec, T elements) const {
66+
67+
Data b = 1.0;
68+
Data c = -1.0;
69+
70+
for (T index: cms::alpakatools::elements_with_stride<T, T_Acc>(acc, elements)) {
71+
for (int i = 0; i < 200000; i++) {
72+
alpaka::atomicAdd(acc, &vec[0], b, alpaka::hierarchy::Grids{}); //alpaka::hierarchy::Blocks/Threads/Grids
73+
alpaka::atomicAdd(acc, &vec[0], c, alpaka::hierarchy::Grids{});
74+
}
75+
alpaka::atomicAdd(acc, &vec[0], b, alpaka::hierarchy::Grids{});
76+
}
77+
}
78+
};
79+
80+
template <typename T, typename Data>
81+
struct shared_grid {
82+
template <typename T_Acc>
83+
ALPAKA_FN_ACC void operator()(const T_Acc& acc, Data *vec, T elements) const {
84+
85+
auto threadIdxLocal(alpaka::getIdx<alpaka::Block, alpaka::Threads>(acc)[0u]);
86+
Data b = 1.0;
87+
Data c = -1.0;
88+
89+
auto& s = alpaka::declareSharedVar<Data, __COUNTER__>(acc);
90+
91+
if (threadIdxLocal == 0) {
92+
s = 0;
93+
}
94+
95+
syncBlockThreads(acc);
96+
97+
for (T index: cms::alpakatools::elements_with_stride<T, T_Acc>(acc, elements)) {
98+
for (int i = 0; i < 200000; i++) {
99+
alpaka::atomicAdd(acc, &s, b, alpaka::hierarchy::Blocks{}); //alpaka::hierarchy::Blocks/Threads/Grids
100+
alpaka::atomicAdd(acc, &s, c, alpaka::hierarchy::Blocks{});
101+
}
102+
alpaka::atomicAdd(acc, &s, b, alpaka::hierarchy::Blocks{});
103+
}
104+
105+
syncBlockThreads(acc);
106+
107+
if (threadIdxLocal == 0) {
108+
alpaka::atomicAdd(acc, &vec[0], s, alpaka::hierarchy::Grids{});
109+
}
110+
}
111+
};
112+
113+
114+
int main(void) {
115+
116+
using Dim = alpaka::DimInt<1u>;
117+
using Data = float;
118+
const Idx num_items = 1<<15;
119+
Idx nThreadsInit = 256;
120+
Idx nBlocksInit = (num_items + nThreadsInit - 1) / nThreadsInit;
121+
122+
const DevAcc1 device_1(alpaka::getDevByIdx<PltfAcc1>(0u));
123+
alpaka::Queue<DevAcc1, alpaka::Blocking> queue_1_0(device_1);
124+
alpaka::Queue<DevAcc1, alpaka::Blocking> queue_1_1(device_1);
125+
126+
const Vec1 threadsPerBlockOrElementsPerThread1(Vec1::all(nThreadsInit));
127+
const Vec1 blocksPerGrid1(Vec1::all(nBlocksInit));
128+
auto workDivMultiBlockInit1 =
129+
cms::alpakatools::make_workdiv(blocksPerGrid1, threadsPerBlockOrElementsPerThread1);
130+
131+
132+
using DevHost = alpaka::DevCpu;
133+
auto const devHost = alpaka::getDevByIdx<DevHost>(0u);
134+
135+
using BufHost = alpaka::Buf<DevHost, Data, Dim, Idx>;
136+
BufHost bufHostA(alpaka::allocBuf<Data, Idx>(devHost, num_items));
137+
BufHost res(alpaka::allocBuf<Data, Idx>(devHost, num_items));
138+
139+
Data* const pBufHostA(alpaka::getPtrNative(bufHostA));
140+
Data* const res_ptr(alpaka::getPtrNative(res));
141+
142+
for (Idx i = 0; i < num_items; i++) {
143+
pBufHostA[i] = 0.0;
144+
}
145+
146+
using BufAcc = alpaka::Buf<DevAcc1, Data, Dim, Idx>;
147+
BufAcc order(alpaka::allocBuf<Data, Idx>(device_1, num_items));
148+
149+
150+
printf("Threads/block:%d blocks/grid:%d\n", threadsPerBlockOrElementsPerThread1[0u], blocksPerGrid1[0u]);
151+
152+
// Run on shared memory
153+
alpaka::memcpy(queue_1_0, order, bufHostA, num_items);
154+
auto beginT = std::chrono::high_resolution_clock::now();
155+
alpaka::enqueue(queue_1_0, alpaka::createTaskKernel<Acc1>(workDivMultiBlockInit1,
156+
shared_block<Idx, Data>(), alpaka::getPtrNative(order), num_items));
157+
alpaka::wait(queue_1_0);
158+
auto endT = std::chrono::high_resolution_clock::now();
159+
std::cout << "Shared Block: " << std::chrono::duration<double>(endT - beginT).count() << " s"
160+
<< std::endl;
161+
alpaka::memcpy(queue_1_0, res, order, num_items);
162+
for (Idx i = 0; i < nBlocksInit; i++)
163+
{
164+
if (res_ptr[i] != (Data) nThreadsInit) std::cout << "[" << i << "]: " << res_ptr[i] << " != " << (Data) num_items << std::endl;
165+
}
166+
167+
// Run on global memory
168+
alpaka::memcpy(queue_1_0, order, bufHostA, num_items);
169+
beginT = std::chrono::high_resolution_clock::now();
170+
alpaka::enqueue(queue_1_0, alpaka::createTaskKernel<Acc1>(workDivMultiBlockInit1,
171+
global_block<Idx, Data>(), alpaka::getPtrNative(order), num_items));
172+
alpaka::wait(queue_1_0);
173+
endT = std::chrono::high_resolution_clock::now();
174+
std::cout << "Global Block: " << std::chrono::duration<double>(endT - beginT).count() << " s"
175+
<< std::endl;
176+
alpaka::memcpy(queue_1_0, res, order, num_items);
177+
for (Idx i = 0; i < nBlocksInit; i++)
178+
{
179+
if (res_ptr[i] != (Data) nThreadsInit) std::cout << "[" << i << "]: " << res_ptr[i] << " != " << (Data) num_items << std::endl;
180+
}
181+
182+
// Run on Shared memory
183+
alpaka::memcpy(queue_1_0, order, bufHostA, num_items);
184+
beginT = std::chrono::high_resolution_clock::now();
185+
alpaka::enqueue(queue_1_0, alpaka::createTaskKernel<Acc1>(workDivMultiBlockInit1,
186+
shared_grid<Idx, Data>(), alpaka::getPtrNative(order), num_items));
187+
alpaka::wait(queue_1_0);
188+
endT = std::chrono::high_resolution_clock::now();
189+
std::cout << "Shared Grid: " << std::chrono::duration<double>(endT - beginT).count() << " s"
190+
<< std::endl;
191+
alpaka::memcpy(queue_1_0, res, order, num_items);
192+
if (res_ptr[0] != (Data) num_items) std::cout << "[0]: " << res_ptr[0] << " != " << (Data) num_items << std::endl
193+
<< std::endl;
194+
195+
// Run on Global memory
196+
alpaka::memcpy(queue_1_0, order, bufHostA, num_items);
197+
beginT = std::chrono::high_resolution_clock::now();
198+
alpaka::enqueue(queue_1_0, alpaka::createTaskKernel<Acc1>(workDivMultiBlockInit1,
199+
global_grid<Idx, Data>(), alpaka::getPtrNative(order), num_items));
200+
alpaka::wait(queue_1_0);
201+
endT = std::chrono::high_resolution_clock::now();
202+
std::cout << "Global Grid: " << std::chrono::duration<double>(endT - beginT).count() << " s"
203+
<< std::endl;
204+
alpaka::memcpy(queue_1_0, res, order, num_items);
205+
if (res_ptr[0] != (Data) num_items) std::cout << "[0]: " << res_ptr[0] << " != " << (Data) num_items << std::endl;
206+
207+
return 0;
208+
}
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
#include "AlpakaCore/alpakaConfig.h"
5+
#include "AlpakaCore/alpakaWorkDivHelper.h"
6+
#include "AlpakaCore/threadfence.h"
7+
8+
using namespace ALPAKA_ACCELERATOR_NAMESPACE;
9+
10+
template <typename T, typename Data>
11+
struct global_fence {
12+
template <typename T_Acc>
13+
ALPAKA_FN_ACC void operator()(const T_Acc& acc, Data *vec, T elements) const {
14+
15+
auto blockIdxLocal(alpaka::getIdx<alpaka::Grid, alpaka::Blocks>(acc)[0u]);
16+
int no_blocks = 128;
17+
18+
for (int i = 0; i < no_blocks*no_blocks*10; i++) {
19+
if (i%no_blocks == (int) blockIdxLocal) {
20+
if (i%no_blocks > 0) {
21+
vec[blockIdxLocal] = vec[blockIdxLocal - 1] + 1;
22+
}
23+
}
24+
cms::alpakatools::threadfence(acc);
25+
}
26+
}
27+
};
28+
29+
template <typename T, typename Data>
30+
struct shared_fence {
31+
template <typename T_Acc>
32+
ALPAKA_FN_ACC void operator()(const T_Acc& acc, Data *vec, T elements) const {
33+
34+
auto threadIdxLocal(alpaka::getIdx<alpaka::Block, alpaka::Threads>(acc)[0u]);
35+
auto blockIdxLocal(alpaka::getIdx<alpaka::Grid, alpaka::Blocks>(acc)[0u]);
36+
37+
auto& s = alpaka::declareSharedVar<Data[256], __COUNTER__>(acc);
38+
39+
for (int i = 0; i < 256*256*10; i++) {
40+
if (i%256 == (int) threadIdxLocal && threadIdxLocal > 0) {
41+
s[threadIdxLocal] = s[threadIdxLocal-1] + 1;
42+
}
43+
cms::alpakatools::threadfence(acc);
44+
}
45+
46+
if (threadIdxLocal == 0) {
47+
vec[blockIdxLocal] = s[127] + s[129];
48+
}
49+
}
50+
};
51+
52+
53+
int main(void) {
54+
55+
using Dim = alpaka::DimInt<1u>;
56+
using Data = float;
57+
const Idx num_items = 1<<15;
58+
Idx nThreadsInit = 256;
59+
Idx nBlocksInit = (num_items + nThreadsInit - 1) / nThreadsInit;
60+
61+
const DevAcc1 device_1(alpaka::getDevByIdx<PltfAcc1>(0u));
62+
alpaka::Queue<DevAcc1, alpaka::Blocking> queue_1_0(device_1);
63+
alpaka::Queue<DevAcc1, alpaka::Blocking> queue_1_1(device_1);
64+
65+
const Vec1 threadsPerBlockOrElementsPerThread1(Vec1::all(nThreadsInit));
66+
const Vec1 blocksPerGrid1(Vec1::all(nBlocksInit));
67+
auto workDivMultiBlockInit1 =
68+
cms::alpakatools::make_workdiv(blocksPerGrid1, threadsPerBlockOrElementsPerThread1);
69+
70+
71+
using DevHost = alpaka::DevCpu;
72+
auto const devHost = alpaka::getDevByIdx<DevHost>(0u);
73+
74+
using BufHost = alpaka::Buf<DevHost, Data, Dim, Idx>;
75+
BufHost bufHostA(alpaka::allocBuf<Data, Idx>(devHost, num_items));
76+
BufHost res(alpaka::allocBuf<Data, Idx>(devHost, num_items));
77+
78+
Data* const pBufHostA(alpaka::getPtrNative(bufHostA));
79+
Data* const res_ptr(alpaka::getPtrNative(res));
80+
81+
for (Idx i = 0; i < num_items; i++) {
82+
pBufHostA[i] = 0.0;
83+
}
84+
85+
using BufAcc = alpaka::Buf<DevAcc1, Data, Dim, Idx>;
86+
BufAcc order(alpaka::allocBuf<Data, Idx>(device_1, num_items));
87+
88+
printf("Threads/block:%d blocks/grid:%d\n", threadsPerBlockOrElementsPerThread1[0u], blocksPerGrid1[0u]);
89+
90+
// Run on shared memory
91+
alpaka::memcpy(queue_1_0, order, bufHostA, num_items);
92+
auto beginT = std::chrono::high_resolution_clock::now();
93+
alpaka::enqueue(queue_1_0, alpaka::createTaskKernel<Acc1>(workDivMultiBlockInit1,
94+
shared_fence<Idx, Data>(), alpaka::getPtrNative(order), num_items));
95+
alpaka::wait(queue_1_0);
96+
auto endT = std::chrono::high_resolution_clock::now();
97+
std::cout << "Shared time: " << std::chrono::duration<double>(endT - beginT).count() << " s"
98+
<< std::endl;
99+
alpaka::memcpy(queue_1_0, res, order, num_items);
100+
for (int i = 0; i < 128; i++) {
101+
if (res_ptr[i] != 256.0) printf("Error1: d[%d] != r (%f, %d)\n", i, res_ptr[i], i);
102+
}
103+
104+
// Run on global memory
105+
alpaka::memcpy(queue_1_0, order, bufHostA, num_items);
106+
beginT = std::chrono::high_resolution_clock::now();
107+
alpaka::enqueue(queue_1_0, alpaka::createTaskKernel<Acc1>(workDivMultiBlockInit1,
108+
global_fence<Idx, Data>(), alpaka::getPtrNative(order), num_items));
109+
alpaka::wait(queue_1_0);
110+
endT = std::chrono::high_resolution_clock::now();
111+
std::cout << "Global time: " << std::chrono::duration<double>(endT - beginT).count() << " s"
112+
<< std::endl;
113+
alpaka::memcpy(queue_1_0, res, order, num_items);
114+
for (int i = 0; i < 128; i++)
115+
{
116+
if (res_ptr[i] != Data (i)) printf("Error1: d[%d] != r (%f, %d)\n", i, res_ptr[i], i);
117+
}
118+
119+
120+
return 0;
121+
}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
#include <iostream>
2+
#include <string>
3+
4+
#include "AlpakaCore/alpakaConfig.h"
5+
#include "AlpakaCore/alpakaWorkDivHelper.h"
6+
7+
using namespace ALPAKA_ACCELERATOR_NAMESPACE;
8+
9+
template <typename T, typename Data>
10+
struct check_sync {
11+
template <typename T_Acc>
12+
ALPAKA_FN_ACC void operator()(const T_Acc& acc, Data *vec, T elements) const {
13+
14+
int n = (int) elements;
15+
16+
auto threadIdxLocal(alpaka::getIdx<alpaka::Block, alpaka::Threads>(acc)[0u]);
17+
for (int i = 0; i < n*n; i++) {
18+
if (i%n == (int) threadIdxLocal) {
19+
for (int j = i; j < 10000; j++) {
20+
if (j % 2 == 0) {
21+
// Do random stuff
22+
int sum = 0;
23+
for (int k = 0; k < 1000; k++)
24+
sum += k;
25+
}
26+
}
27+
}
28+
syncBlockThreads(acc);
29+
}
30+
}
31+
};
32+
33+
34+
int main(void) {
35+
36+
using Dim = alpaka::DimInt<1u>;
37+
using Data = float;
38+
const Idx num_items = 1<<10;
39+
Idx nThreadsInit = 1024;
40+
Idx nBlocksInit = (num_items + nThreadsInit - 1) / nThreadsInit;
41+
42+
const DevAcc1 device_1(alpaka::getDevByIdx<PltfAcc1>(0u));
43+
alpaka::Queue<DevAcc1, alpaka::Blocking> queue_1_0(device_1);
44+
alpaka::Queue<DevAcc1, alpaka::Blocking> queue_1_1(device_1);
45+
46+
const Vec1 threadsPerBlockOrElementsPerThread1(Vec1::all(nThreadsInit));
47+
const Vec1 blocksPerGrid1(Vec1::all(nBlocksInit));
48+
auto workDivMultiBlockInit1 =
49+
cms::alpakatools::make_workdiv(blocksPerGrid1, threadsPerBlockOrElementsPerThread1);
50+
51+
using BufAcc = alpaka::Buf<DevAcc1, Data, Dim, Idx>;
52+
BufAcc order(alpaka::allocBuf<Data, Idx>(device_1, num_items));
53+
54+
printf("Threads/block:%d blocks/grid:%d\n", threadsPerBlockOrElementsPerThread1[0u], blocksPerGrid1[0u]);
55+
56+
// Run function
57+
auto beginT = std::chrono::high_resolution_clock::now();
58+
alpaka::enqueue(queue_1_0, alpaka::createTaskKernel<Acc1>(workDivMultiBlockInit1,
59+
check_sync<Idx, Data>(), alpaka::getPtrNative(order), nThreadsInit));
60+
alpaka::wait(queue_1_0);
61+
auto endT = std::chrono::high_resolution_clock::now();
62+
std::cout << "Time: " << std::chrono::duration<double>(endT - beginT).count() << " s" << std::endl;
63+
64+
return 0;
65+
}

0 commit comments

Comments
 (0)