Skip to content

Commit 07956a8

Browse files
authored
[Graph Optimization] Fix IR graph dependency error exposed after enabling SOT by updating the return value of TextImageGatherScatter (#4610)
* fix TextImageGatherScatter in sot * fix codestyle
1 parent 4d2f478 commit 07956a8

3 files changed

Lines changed: 171 additions & 167 deletions

File tree

custom_ops/gpu_ops/cpp_extensions.cc

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -485,13 +485,14 @@ void TextImageIndexOut(const paddle::Tensor& token_type_ids,
485485
paddle::Tensor& text_input,
486486
paddle::Tensor& image_input);
487487

488-
void TextImageGatherScatter(paddle::Tensor& input,
489-
paddle::Tensor& text_input,
490-
paddle::Tensor& image_input,
491-
paddle::Tensor& token_type_ids,
492-
paddle::Tensor& text_index,
493-
paddle::Tensor& image_index,
494-
const bool is_scatter);
488+
std::vector<paddle::Tensor> TextImageGatherScatter(
489+
paddle::Tensor& input,
490+
paddle::Tensor& text_input,
491+
paddle::Tensor& image_input,
492+
paddle::Tensor& token_type_ids,
493+
paddle::Tensor& text_index,
494+
paddle::Tensor& image_index,
495+
const bool is_scatter);
495496

496497
paddle::Tensor count_tokens_per_expert_func(const paddle::Tensor& topk_ids,
497498
int64_t num_experts);

custom_ops/gpu_ops/text_image_gather_scatter.cu

Lines changed: 161 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@
1414

1515
#include "helper.h"
1616

17-
inline cudaError_t GetGridSize(int64_t n, int block_size, int num_waves, int* num_blocks) {
17+
inline cudaError_t GetGridSize(int64_t n,
18+
int block_size,
19+
int num_waves,
20+
int* num_blocks) {
1821
int dev;
1922
{
2023
cudaError_t err = cudaGetDevice(&dev);
@@ -45,195 +48,195 @@ inline cudaError_t GetGridSize(int64_t n, int block_size, int num_waves, int* nu
4548
return cudaSuccess;
4649
}
4750

48-
template<typename T, int VecSize>
49-
__global__ void text_image_scatter_kernel(
50-
T* input_ptr,
51-
T* text_gather_ptr,
52-
T* image_gather_ptr,
53-
int32_t* token_type_ids,
54-
int32_t* text_index,
55-
int32_t* image_index,
56-
const int64_t hidden_size,
57-
const int64_t total_element_num
58-
){
59-
constexpr int HalfVecSize = VecSize / 2;
60-
using T_Vec = AlignedVector<T, VecSize>;
61-
T_Vec input_ptr_vec;
62-
T_Vec text_images_vec;
63-
64-
int64_t global_thread_id = blockIdx.x * blockDim.x + threadIdx.x;
65-
const int64_t step = blockDim.x * gridDim.x * VecSize;
66-
67-
for(int64_t element_idx = global_thread_id * VecSize;
68-
element_idx < total_element_num;
69-
element_idx += step){
70-
int64_t token_idx = element_idx / hidden_size;
71-
int64_t hidden_offset = element_idx % hidden_size;
72-
int32_t token_type_ids_num = token_type_ids[token_idx];
73-
74-
int64_t input_load_offset = token_idx * hidden_size + hidden_offset;
75-
76-
Load<T, VecSize>(input_ptr + input_load_offset, &input_ptr_vec);
77-
#pragma unroll
78-
for(int vi = 0; vi < VecSize; ++vi) {
79-
text_images_vec[vi] = input_ptr_vec[vi];
80-
}
81-
82-
if (token_type_ids_num == 0) {
83-
int64_t text_load_offset = text_index[token_idx] * hidden_size + hidden_offset;
84-
Store<T,VecSize>(text_images_vec, text_gather_ptr + text_load_offset);
85-
86-
} else if(token_type_ids_num == 1){
87-
int64_t image_load_offset = image_index[token_idx] * hidden_size + hidden_offset;
88-
Store<T,VecSize>(text_images_vec, image_gather_ptr + image_load_offset);
89-
90-
} else {
91-
// skip cuda graph padding value
92-
continue;
93-
}
51+
template <typename T, int VecSize>
52+
__global__ void text_image_scatter_kernel(T* input_ptr,
53+
T* text_gather_ptr,
54+
T* image_gather_ptr,
55+
int32_t* token_type_ids,
56+
int32_t* text_index,
57+
int32_t* image_index,
58+
const int64_t hidden_size,
59+
const int64_t total_element_num) {
60+
constexpr int HalfVecSize = VecSize / 2;
61+
using T_Vec = AlignedVector<T, VecSize>;
62+
T_Vec input_ptr_vec;
63+
T_Vec text_images_vec;
64+
65+
int64_t global_thread_id = blockIdx.x * blockDim.x + threadIdx.x;
66+
const int64_t step = blockDim.x * gridDim.x * VecSize;
67+
68+
for (int64_t element_idx = global_thread_id * VecSize;
69+
element_idx < total_element_num;
70+
element_idx += step) {
71+
int64_t token_idx = element_idx / hidden_size;
72+
int64_t hidden_offset = element_idx % hidden_size;
73+
int32_t token_type_ids_num = token_type_ids[token_idx];
74+
75+
int64_t input_load_offset = token_idx * hidden_size + hidden_offset;
76+
77+
Load<T, VecSize>(input_ptr + input_load_offset, &input_ptr_vec);
78+
#pragma unroll
79+
for (int vi = 0; vi < VecSize; ++vi) {
80+
text_images_vec[vi] = input_ptr_vec[vi];
9481
}
82+
83+
if (token_type_ids_num == 0) {
84+
int64_t text_load_offset =
85+
text_index[token_idx] * hidden_size + hidden_offset;
86+
Store<T, VecSize>(text_images_vec, text_gather_ptr + text_load_offset);
87+
88+
} else if (token_type_ids_num == 1) {
89+
int64_t image_load_offset =
90+
image_index[token_idx] * hidden_size + hidden_offset;
91+
Store<T, VecSize>(text_images_vec, image_gather_ptr + image_load_offset);
92+
93+
} else {
94+
// skip cuda graph padding value
95+
continue;
96+
}
97+
}
9598
}
9699

97-
template<typename T, int VecSize>
98-
__global__ void text_image_gather_kernel(
99-
T* output_ptr,
100-
T* text_gather_ptr,
101-
T* image_gather_ptr,
102-
int32_t* token_type_ids,
103-
int32_t* text_index,
104-
int32_t* image_index,
105-
const int64_t hidden_size,
106-
const int64_t total_element_num
107-
){
108-
constexpr int HalfVecSize = VecSize / 2;
109-
using T_Vec = AlignedVector<T, VecSize>;
110-
T_Vec output_ptr_vec;
111-
T_Vec text_imgaes_vec;
112-
113-
int64_t global_thread_id = blockIdx.x * blockDim.x + threadIdx.x;
114-
const int64_t step = blockDim.x * gridDim.x * VecSize;
115-
116-
for(int64_t element_idx = global_thread_id * VecSize;
117-
element_idx < total_element_num;
118-
element_idx += step){
119-
int64_t token_idx = element_idx / hidden_size;
120-
int64_t hidden_offset = element_idx % hidden_size;
121-
int32_t token_type_ids_num = token_type_ids[token_idx];
122-
123-
if (token_type_ids_num == 0) {
124-
int64_t text_load_offset = text_index[token_idx] * hidden_size + hidden_offset;
125-
Load<T,VecSize>(text_gather_ptr + text_load_offset, &text_imgaes_vec);
126-
127-
} else if (token_type_ids_num == 1){
128-
int64_t image_load_offset = image_index[token_idx] * hidden_size + hidden_offset;
129-
Load<T,VecSize>(image_gather_ptr + image_load_offset, &text_imgaes_vec);
130-
} else {
131-
// skip cuda graph padding value
132-
continue;
133-
}
134-
135-
#pragma unroll
136-
for(int vi = 0; vi < VecSize; ++vi) {
137-
output_ptr_vec[vi] = text_imgaes_vec[vi];
138-
}
139-
140-
int64_t input_load_offset = token_idx * hidden_size + hidden_offset;
141-
142-
Store<T, VecSize>(output_ptr_vec, output_ptr + input_load_offset);
100+
template <typename T, int VecSize>
101+
__global__ void text_image_gather_kernel(T* output_ptr,
102+
T* text_gather_ptr,
103+
T* image_gather_ptr,
104+
int32_t* token_type_ids,
105+
int32_t* text_index,
106+
int32_t* image_index,
107+
const int64_t hidden_size,
108+
const int64_t total_element_num) {
109+
constexpr int HalfVecSize = VecSize / 2;
110+
using T_Vec = AlignedVector<T, VecSize>;
111+
T_Vec output_ptr_vec;
112+
T_Vec text_imgaes_vec;
113+
114+
int64_t global_thread_id = blockIdx.x * blockDim.x + threadIdx.x;
115+
const int64_t step = blockDim.x * gridDim.x * VecSize;
116+
117+
for (int64_t element_idx = global_thread_id * VecSize;
118+
element_idx < total_element_num;
119+
element_idx += step) {
120+
int64_t token_idx = element_idx / hidden_size;
121+
int64_t hidden_offset = element_idx % hidden_size;
122+
int32_t token_type_ids_num = token_type_ids[token_idx];
123+
124+
if (token_type_ids_num == 0) {
125+
int64_t text_load_offset =
126+
text_index[token_idx] * hidden_size + hidden_offset;
127+
Load<T, VecSize>(text_gather_ptr + text_load_offset, &text_imgaes_vec);
128+
129+
} else if (token_type_ids_num == 1) {
130+
int64_t image_load_offset =
131+
image_index[token_idx] * hidden_size + hidden_offset;
132+
Load<T, VecSize>(image_gather_ptr + image_load_offset, &text_imgaes_vec);
133+
} else {
134+
// skip cuda graph padding value
135+
continue;
136+
}
137+
138+
#pragma unroll
139+
for (int vi = 0; vi < VecSize; ++vi) {
140+
output_ptr_vec[vi] = text_imgaes_vec[vi];
143141
}
142+
143+
int64_t input_load_offset = token_idx * hidden_size + hidden_offset;
144+
145+
Store<T, VecSize>(output_ptr_vec, output_ptr + input_load_offset);
146+
}
144147
}
145148

146149
template <paddle::DataType D>
147-
void LaunchTextImageGatherScatter(
148-
paddle::Tensor& input,
149-
paddle::Tensor& text_input,
150-
paddle::Tensor& image_input,
151-
paddle::Tensor& token_type_ids,
152-
paddle::Tensor& text_index,
153-
paddle::Tensor& image_index,
154-
const bool is_scatter) {
155-
156-
typedef PDTraits<D> traits_;
157-
typedef typename traits_::DataType DataType_;
158-
typedef typename traits_::data_t data_t;
159-
auto stream = input.stream();
160-
const auto& in_dims = input.dims();
161-
const int64_t token_num = in_dims[0];
162-
const int64_t hidden_size = in_dims[1];
163-
164-
const int VecSize = 16 / sizeof(data_t);
165-
const int64_t tot_element_num = token_num * hidden_size;
166-
167-
int64_t tot_pack_num = (tot_element_num + VecSize - 1) / VecSize;
168-
169-
const int block_size = 128;
170-
int grid_index = (token_num + block_size - 1) / block_size;
171-
constexpr int32_t kNumWaves = 16;
172-
int grid_size_x = -1;
173-
174-
PADDLE_ENFORCE_GPU_SUCCESS(GetGridSize(tot_pack_num, block_size, kNumWaves, &grid_size_x));
175-
dim3 grid_dim = dim3(grid_size_x, 1, 1);
176-
if (is_scatter) {
177-
text_image_scatter_kernel<DataType_, VecSize><<<grid_dim, block_size, 0, stream>>>(
150+
void LaunchTextImageGatherScatter(paddle::Tensor& input,
151+
paddle::Tensor& text_input,
152+
paddle::Tensor& image_input,
153+
paddle::Tensor& token_type_ids,
154+
paddle::Tensor& text_index,
155+
paddle::Tensor& image_index,
156+
const bool is_scatter) {
157+
typedef PDTraits<D> traits_;
158+
typedef typename traits_::DataType DataType_;
159+
typedef typename traits_::data_t data_t;
160+
auto stream = input.stream();
161+
const auto& in_dims = input.dims();
162+
const int64_t token_num = in_dims[0];
163+
const int64_t hidden_size = in_dims[1];
164+
165+
const int VecSize = 16 / sizeof(data_t);
166+
const int64_t tot_element_num = token_num * hidden_size;
167+
168+
int64_t tot_pack_num = (tot_element_num + VecSize - 1) / VecSize;
169+
170+
const int block_size = 128;
171+
int grid_index = (token_num + block_size - 1) / block_size;
172+
constexpr int32_t kNumWaves = 16;
173+
int grid_size_x = -1;
174+
175+
PADDLE_ENFORCE_GPU_SUCCESS(
176+
GetGridSize(tot_pack_num, block_size, kNumWaves, &grid_size_x));
177+
dim3 grid_dim = dim3(grid_size_x, 1, 1);
178+
if (is_scatter) {
179+
text_image_scatter_kernel<DataType_, VecSize>
180+
<<<grid_dim, block_size, 0, stream>>>(
178181
reinterpret_cast<DataType_*>(input.data<data_t>()),
179182
reinterpret_cast<DataType_*>(text_input.data<data_t>()),
180183
reinterpret_cast<DataType_*>(image_input.data<data_t>()),
181184
reinterpret_cast<int32_t*>(token_type_ids.data<int32_t>()),
182185
reinterpret_cast<int32_t*>(text_index.data<int32_t>()),
183186
reinterpret_cast<int32_t*>(image_index.data<int32_t>()),
184187
hidden_size,
185-
tot_element_num
186-
);
187-
} else {
188-
text_image_gather_kernel<DataType_, VecSize><<<grid_dim, block_size, 0, stream>>>(
188+
tot_element_num);
189+
} else {
190+
text_image_gather_kernel<DataType_, VecSize>
191+
<<<grid_dim, block_size, 0, stream>>>(
189192
reinterpret_cast<DataType_*>(input.data<data_t>()),
190193
reinterpret_cast<DataType_*>(text_input.data<data_t>()),
191194
reinterpret_cast<DataType_*>(image_input.data<data_t>()),
192195
reinterpret_cast<int32_t*>(token_type_ids.data<int32_t>()),
193196
reinterpret_cast<int32_t*>(text_index.data<int32_t>()),
194197
reinterpret_cast<int32_t*>(image_index.data<int32_t>()),
195198
hidden_size,
196-
tot_element_num
197-
);
198-
}
199+
tot_element_num);
200+
}
199201
}
200202

201-
void TextImageGatherScatter(
202-
paddle::Tensor& input,
203-
paddle::Tensor& text_input,
204-
paddle::Tensor& image_input,
205-
paddle::Tensor& token_type_ids,
206-
paddle::Tensor& text_index,
207-
paddle::Tensor& image_index,
208-
const bool is_scatter) {
209-
210-
switch (input.type()) {
211-
case paddle::DataType::BFLOAT16: {
212-
return LaunchTextImageGatherScatter<paddle::DataType::BFLOAT16>(input, text_input, image_input, token_type_ids, text_index, image_index, is_scatter);
213-
}
214-
default: {
215-
PD_THROW(
216-
"NOT supported data type. Only support BFLOAT16. ");
217-
break;
218-
}
203+
std::vector<paddle::Tensor> TextImageGatherScatter(
204+
paddle::Tensor& input,
205+
paddle::Tensor& text_input,
206+
paddle::Tensor& image_input,
207+
paddle::Tensor& token_type_ids,
208+
paddle::Tensor& text_index,
209+
paddle::Tensor& image_index,
210+
const bool is_scatter) {
211+
switch (input.dtype()) {
212+
case paddle::DataType::BFLOAT16: {
213+
LaunchTextImageGatherScatter<paddle::DataType::BFLOAT16>(input,
214+
text_input,
215+
image_input,
216+
token_type_ids,
217+
text_index,
218+
image_index,
219+
is_scatter);
220+
break;
221+
}
222+
default: {
223+
PD_THROW("NOT supported data type. Only support BFLOAT16, but got",
224+
input.dtype());
219225
}
226+
}
227+
return {input, text_input, image_input};
220228
}
221229

222-
223230
PD_BUILD_STATIC_OP(text_image_gather_scatter)
224231
.Inputs({"input",
225232
"text_input",
226233
"image_input",
227234
"token_type_ids",
228235
"text_index",
229236
"image_index"})
230-
.Outputs({"text_input_out",
231-
"image_input_out",
232-
"text_index_out",
233-
"image_index_out"})
237+
.Outputs({"output", "text_input_out", "image_input_out"})
234238
.Attrs({"is_scatter:bool"})
235-
.SetInplaceMap({{"text_input", "text_input_out"},
236-
{"image_input", "image_input_out"},
237-
{"text_index", "text_index_out"},
238-
{"image_index", "image_index_out"}})
239+
.SetInplaceMap({{"input", "output"},
240+
{"text_input", "text_input_out"},
241+
{"image_input", "image_input_out"}})
239242
.SetKernelFn(PD_KERNEL(TextImageGatherScatter));

0 commit comments

Comments
 (0)