Skip to content

Commit 82d7d99

Browse files
rocking5566rocking
andauthored
Hotfix binary elementwise (for broadcast on fastest axis) (#254)
* Support different length of ScalarPerVector * Add example of broadcast on fastest axis * Typo * Refine fastest example * Add dimension check * Modify fastest broadcast example to 3d * Enforce users give scalarPerVector explicitely * 1. Add CscalarPerVedctor 2. Not only broadcast on fastest need to set scalarPerVector to 1 * Rename var * Move IsScalarPerVectorValid() inside IsSupportedArgument() * Separate GridDesc_M0 into A, B and C * rename var * Rename var of length Co-authored-by: rocking <[email protected]>
1 parent e579c9e commit 82d7d99

File tree

7 files changed

+319
-125
lines changed

7 files changed

+319
-125
lines changed
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
add_example_executable(example_broadcast_add_2d broadcast_add_2d.cpp)
1+
add_example_executable(example_broadcast_add_2d_amn_bn broadcast_add_2d_amn_bn.cpp)
2+
add_example_executable(example_broadcast_add_3d_am_bmnk broadcast_add_3d_am_bmnk.cpp)
23
add_example_executable(example_elementwise_add_1d elementwise_add_1d.cpp)
34
add_example_executable(example_elementwise_add_4d elementwise_add_4d.cpp)

example/19_binary_elementwise/broadcast_add_2d.cpp renamed to example/19_binary_elementwise/broadcast_add_2d_amn_bn.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,17 @@ using EltwiseComputeDataType = F32;
1919

2020
using Add = ck::tensor_operation::binary_element_wise::Add;
2121

22-
using DeviceElementwiseAddInstance = ck::tensor_operation::device::
23-
DeviceBinaryElementwise<ABDataType, ABDataType, CDataType, EltwiseComputeDataType, Add, 2, 8>;
22+
using DeviceElementwiseAddInstance =
23+
ck::tensor_operation::device::DeviceBinaryElementwise<ABDataType,
24+
ABDataType,
25+
CDataType,
26+
EltwiseComputeDataType,
27+
Add,
28+
2,
29+
8,
30+
8,
31+
8,
32+
8>;
2433

2534
template <typename HostTensorA,
2635
typename HostTensorB,
@@ -100,7 +109,7 @@ int main()
100109
if(!broadcastAdd.IsSupportedArgument(argument.get()))
101110
{
102111
throw std::runtime_error("The runtime parameters seems not supported by the "
103-
"DeviceBinaryElementwise_2D instance, exiting!");
112+
"DeviceBinaryElementwise instance, exiting!");
104113
};
105114

106115
auto broadcastAdd_invoker_ptr = broadcastAdd.MakeInvokerPointer();
@@ -123,7 +132,7 @@ int main()
123132
0>(host_c_m_n, a_m_n, b_n, M, N, Add{});
124133

125134
pass &= ck::utils::check_err(
126-
c_m_n.mData, host_c_m_n.mData, "Error: Incorrect results d1", 1e-3, 1e-3);
135+
c_m_n.mData, host_c_m_n.mData, "Error: Incorrect results c", 1e-3, 1e-3);
127136
}
128137

129138
return pass ? 0 : 1;
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#include <iostream>
2+
#include <cstdlib>
3+
#include "check_err.hpp"
4+
#include "config.hpp"
5+
#include "device.hpp"
6+
#include "host_tensor.hpp"
7+
#include "host_tensor_generator.hpp"
8+
9+
#include "device_tensor.hpp"
10+
#include "binary_element_wise_operation.hpp"
11+
#include "device_binary_elementwise.hpp"
12+
13+
using F16 = ck::half_t;
14+
using F32 = float;
15+
16+
using ABDataType = F16;
17+
using CDataType = F16;
18+
using EltwiseComputeDataType = F32;
19+
20+
using Add = ck::tensor_operation::binary_element_wise::Add;
21+
22+
using DeviceElementwiseAddInstance =
23+
ck::tensor_operation::device::DeviceBinaryElementwise<ABDataType,
24+
ABDataType,
25+
CDataType,
26+
EltwiseComputeDataType,
27+
Add,
28+
3,
29+
8,
30+
1,
31+
8,
32+
8>;
33+
34+
template <typename HostTensorA,
35+
typename HostTensorB,
36+
typename HostTensorC,
37+
typename ComputeDataType,
38+
typename Functor>
39+
void host_broadcast3D_am_bmnk(HostTensorC& C,
40+
const HostTensorA& A,
41+
const HostTensorB& B,
42+
const std::vector<std::size_t>& shape,
43+
Functor functor)
44+
{
45+
using ctype = ck::remove_reference_t<decltype(C(0, 0))>;
46+
47+
for(std::size_t m = 0; m < shape[0]; ++m)
48+
for(std::size_t n = 0; n < shape[1]; ++n)
49+
for(std::size_t k = 0; k < shape[2]; ++k)
50+
{
51+
ComputeDataType a_val = static_cast<ComputeDataType>(A(m));
52+
ComputeDataType b_val = static_cast<ComputeDataType>(B(m, n, k));
53+
ComputeDataType c_val = 0;
54+
functor(c_val, a_val, b_val);
55+
C(m, n, k) = static_cast<ctype>(c_val);
56+
}
57+
}
58+
59+
int main()
60+
{
61+
bool do_verification = true;
62+
bool time_kernel = false;
63+
64+
std::vector<std::size_t> mnk = {4, 16, 32};
65+
ck::index_t M = mnk[0];
66+
67+
Tensor<ABDataType> a_m({M});
68+
Tensor<ABDataType> b_m_n_k(mnk);
69+
Tensor<CDataType> c_m_n_k(mnk);
70+
71+
a_m.GenerateTensorValue(GeneratorTensor_3<ABDataType>{0.0, 1.0});
72+
b_m_n_k.GenerateTensorValue(GeneratorTensor_3<ABDataType>{0.0, 1.0});
73+
74+
DeviceMem a_m_device_buf(sizeof(ABDataType) * a_m.mDesc.GetElementSpace());
75+
DeviceMem b_m_n_k_device_buf(sizeof(ABDataType) * b_m_n_k.mDesc.GetElementSpace());
76+
DeviceMem c_m_n_k_device_buf(sizeof(CDataType) * c_m_n_k.mDesc.GetElementSpace());
77+
78+
a_m_device_buf.ToDevice(a_m.mData.data());
79+
b_m_n_k_device_buf.ToDevice(b_m_n_k.mData.data());
80+
81+
auto broadcastAdd = DeviceElementwiseAddInstance{};
82+
auto argument = broadcastAdd.MakeArgumentPointer(
83+
a_m_device_buf.GetDeviceBuffer(),
84+
b_m_n_k_device_buf.GetDeviceBuffer(),
85+
c_m_n_k_device_buf.GetDeviceBuffer(),
86+
std::vector<ck::index_t>{mnk.begin(), mnk.end()},
87+
{1, 0, 0}, // broadcast A on second and third dimension
88+
std::vector<ck::index_t>{b_m_n_k.mDesc.GetStrides().begin(),
89+
b_m_n_k.mDesc.GetStrides().end()},
90+
std::vector<ck::index_t>{c_m_n_k.mDesc.GetStrides().begin(),
91+
c_m_n_k.mDesc.GetStrides().end()},
92+
Add{});
93+
94+
if(!broadcastAdd.IsSupportedArgument(argument.get()))
95+
{
96+
throw std::runtime_error("The runtime parameters seems not supported by the "
97+
"DeviceBinaryElementwise instance, exiting!");
98+
};
99+
100+
auto broadcastAdd_invoker_ptr = broadcastAdd.MakeInvokerPointer();
101+
float ave_time =
102+
broadcastAdd_invoker_ptr->Run(argument.get(), StreamConfig{nullptr, time_kernel});
103+
104+
std::cout << "Perf: " << ave_time << " ms" << std::endl;
105+
106+
bool pass = true;
107+
if(do_verification)
108+
{
109+
c_m_n_k_device_buf.FromDevice(c_m_n_k.mData.data());
110+
Tensor<CDataType> host_c_m_n_k(mnk);
111+
112+
host_broadcast3D_am_bmnk<Tensor<ABDataType>,
113+
Tensor<ABDataType>,
114+
Tensor<CDataType>,
115+
EltwiseComputeDataType,
116+
Add>(host_c_m_n_k, a_m, b_m_n_k, mnk, Add{});
117+
118+
pass &= ck::utils::check_err(
119+
c_m_n_k.mData, host_c_m_n_k.mData, "Error: Incorrect results c", 1e-3, 1e-3);
120+
}
121+
122+
return pass ? 0 : 1;
123+
}

example/19_binary_elementwise/elementwise_add_1d.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,17 @@ using EltwiseComputeDataType = F32;
1919

2020
using Add = ck::tensor_operation::binary_element_wise::Add;
2121

22-
using DeviceElementwiseAddInstance = ck::tensor_operation::device::
23-
DeviceBinaryElementwise<ABDataType, ABDataType, CDataType, EltwiseComputeDataType, Add, 1, 8>;
22+
using DeviceElementwiseAddInstance =
23+
ck::tensor_operation::device::DeviceBinaryElementwise<ABDataType,
24+
ABDataType,
25+
CDataType,
26+
EltwiseComputeDataType,
27+
Add,
28+
1,
29+
8,
30+
8,
31+
8,
32+
8>;
2433

2534
template <typename HostTensorA,
2635
typename HostTensorB,
@@ -81,7 +90,7 @@ int main()
8190
if(!broadcastAdd.IsSupportedArgument(argument.get()))
8291
{
8392
throw std::runtime_error("The runtime parameters seems not supported by the "
84-
"DeviceBinaryElementwise_2D instance, exiting!");
93+
"DeviceBinaryElementwise instance, exiting!");
8594
};
8695

8796
auto broadcastAdd_invoker_ptr = broadcastAdd.MakeInvokerPointer();
@@ -103,7 +112,7 @@ int main()
103112
Add>(host_c_m, a_m, b_m, M, Add{});
104113

105114
pass &= ck::utils::check_err(
106-
c_m.mData, host_c_m.mData, "Error: Incorrect results d1", 1e-3, 1e-3);
115+
c_m.mData, host_c_m.mData, "Error: Incorrect results c", 1e-3, 1e-3);
107116
}
108117

109118
return pass ? 0 : 1;

example/19_binary_elementwise/elementwise_add_4d.cpp

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,17 @@ using EltwiseComputeDataType = F32;
1919

2020
using Add = ck::tensor_operation::binary_element_wise::Add;
2121

22-
using DeviceElementwiseAddInstance = ck::tensor_operation::device::
23-
DeviceBinaryElementwise<ABDataType, ABDataType, CDataType, EltwiseComputeDataType, Add, 4, 8>;
22+
using DeviceElementwiseAddInstance =
23+
ck::tensor_operation::device::DeviceBinaryElementwise<ABDataType,
24+
ABDataType,
25+
CDataType,
26+
EltwiseComputeDataType,
27+
Add,
28+
4,
29+
8,
30+
8,
31+
8,
32+
8>;
2433

2534
template <typename HostTensorA,
2635
typename HostTensorB,
@@ -83,7 +92,7 @@ int main()
8392
if(!broadcastAdd.IsSupportedArgument(argument.get()))
8493
{
8594
throw std::runtime_error("The runtime parameters seems not supported by the "
86-
"DeviceBinaryElementwise_2D instance, exiting!");
95+
"DeviceBinaryElementwise instance, exiting!");
8796
};
8897

8998
auto broadcastAdd_invoker_ptr = broadcastAdd.MakeInvokerPointer();
@@ -105,7 +114,7 @@ int main()
105114
Add>(host_c, a, b, nchw, Add{});
106115

107116
pass &=
108-
ck::utils::check_err(c.mData, host_c.mData, "Error: Incorrect results d1", 1e-3, 1e-3);
117+
ck::utils::check_err(c.mData, host_c.mData, "Error: Incorrect results c", 1e-3, 1e-3);
109118
}
110119

111120
return pass ? 0 : 1;

0 commit comments

Comments
 (0)