mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-07-29 20:14:01 +00:00
Fix a issue for cuda reduce Max Min (#474)
* Fix a issue for Reduce Max, Min. Per cudnn document, only Max/Min ops requires the indices output, it will report error if requesting indices for the other reduction ops.
This commit is contained in:
parent
9bc6503463
commit
4408342f0b
2 changed files with 25 additions and 14 deletions
|
|
@ -123,7 +123,11 @@ Status ReduceKernel<allow_multi_axes>::ComputeImpl(OpKernelContext* ctx, cudnnRe
|
|||
ORT_RETURN_IF_ERROR(output_tensor.Set(output_dims_cudnn, cudnn_type_X));
|
||||
size_t workspace_bytes = 0;
|
||||
CUDNN_RETURN_IF_ERROR(cudnnGetReductionWorkspaceSize(CudnnHandle(), reduce_desc, input_tensor, output_tensor, &workspace_bytes));
|
||||
auto workspace_cuda = GetScratchBuffer<void>(workspace_bytes);
|
||||
auto workspace_cuda = GetScratchBuffer<CudaT>(workspace_bytes);
|
||||
|
||||
size_t indices_bytes = 0;
|
||||
CUDNN_RETURN_IF_ERROR(cudnnGetReductionIndicesSize(CudnnHandle(), reduce_desc, input_tensor, output_tensor, &indices_bytes));
|
||||
auto indices_cuda = GetScratchBuffer<uint32_t>(indices_bytes);
|
||||
|
||||
// need to allocate a separate buffer for ArgMin/ArgMax comparsion output
|
||||
auto output_count = Y->Shape().Size();
|
||||
|
|
@ -139,11 +143,14 @@ Status ReduceKernel<allow_multi_axes>::ComputeImpl(OpKernelContext* ctx, cudnnRe
|
|||
tmp_div, tmp_div,
|
||||
input_data, input_count);
|
||||
} else if (log_sum_exp_) {
|
||||
// Reduce max
|
||||
// Reduce max -- Max/Min will output indices data
|
||||
CudnnReduceDescriptor reduce_max_desc;
|
||||
ORT_RETURN_IF_ERROR(reduce_max_desc.Set(CUDNN_REDUCE_TENSOR_MAX, cudnn_type_X, CUDNN_REDUCE_TENSOR_NO_INDICES));
|
||||
size_t indices_bytes_max = 0;
|
||||
CUDNN_RETURN_IF_ERROR(cudnnGetReductionIndicesSize(CudnnHandle(), reduce_max_desc, input_tensor, output_tensor, &indices_bytes_max));
|
||||
auto indices_cuda_max = GetScratchBuffer<uint32_t>(indices_bytes);
|
||||
CUDNN_RETURN_IF_ERROR(cudnnReduceTensor(
|
||||
CudnnHandle(), reduce_max_desc, nullptr, 0, workspace_cuda.get(), workspace_bytes,
|
||||
CudnnHandle(), reduce_max_desc, indices_cuda_max.get(), indices_bytes_max, workspace_cuda.get(), workspace_bytes,
|
||||
&one, input_tensor, reinterpret_cast<const CudaT*>(X->template Data<T>()),
|
||||
&zero, output_tensor, reinterpret_cast<CudaT*>(Y->template MutableData<T>())));
|
||||
|
||||
|
|
@ -169,7 +176,7 @@ Status ReduceKernel<allow_multi_axes>::ComputeImpl(OpKernelContext* ctx, cudnnRe
|
|||
|
||||
// ReduceSum
|
||||
CUDNN_RETURN_IF_ERROR(cudnnReduceTensor(
|
||||
CudnnHandle(), reduce_desc, nullptr, 0, workspace_cuda.get(), workspace_bytes,
|
||||
CudnnHandle(), reduce_desc, indices_cuda.get(), indices_bytes, workspace_cuda.get(), workspace_bytes,
|
||||
&one, input_tensor, exp_result,
|
||||
&zero, output_tensor, reinterpret_cast<CudaT*>(log_sum_result)));
|
||||
|
||||
|
|
@ -188,16 +195,18 @@ Status ReduceKernel<allow_multi_axes>::ComputeImpl(OpKernelContext* ctx, cudnnRe
|
|||
|
||||
return Status::OK();
|
||||
}
|
||||
|
||||
CUDNN_RETURN_IF_ERROR(cudnnReduceTensor(
|
||||
CudnnHandle(), reduce_desc, nullptr, 0, workspace_cuda.get(), workspace_bytes,
|
||||
&one, input_tensor, calculate_sqt_ ? input_data : reinterpret_cast<const CudaT*>(X->template Data<T>()),
|
||||
&zero, output_tensor, reinterpret_cast<CudaT*>(Y->template MutableData<T>())));
|
||||
} else {
|
||||
size_t indices_bytes = 0;
|
||||
CUDNN_RETURN_IF_ERROR(cudnnGetReductionIndicesSize(CudnnHandle(), reduce_desc, input_tensor, output_tensor, &indices_bytes));
|
||||
auto indices_cuda = GetScratchBuffer<void>(indices_bytes);
|
||||
|
||||
if (calculate_sqt_) {
|
||||
CUDNN_RETURN_IF_ERROR(cudnnReduceTensor(
|
||||
CudnnHandle(), reduce_desc, indices_cuda.get(), indices_bytes, workspace_cuda.get(), workspace_bytes,
|
||||
&one, input_tensor, input_data,
|
||||
&zero, output_tensor, reinterpret_cast<CudaT*>(Y->template MutableData<T>())));
|
||||
} else {
|
||||
CUDNN_RETURN_IF_ERROR(cudnnReduceTensor(
|
||||
CudnnHandle(), reduce_desc, indices_cuda.get(), indices_bytes, workspace_cuda.get(), workspace_bytes,
|
||||
&one, input_tensor, reinterpret_cast<const CudaT*>(X->template Data<T>()),
|
||||
&zero, output_tensor, reinterpret_cast<CudaT*>(Y->template MutableData<T>())));
|
||||
}
|
||||
} else { // For ArgMax & ArgMin ops, use the indicies as the output with int64 type
|
||||
if (temp_X) {
|
||||
auto temp_output = GetScratchBuffer<float>(output_count);
|
||||
CUDNN_RETURN_IF_ERROR(cudnnReduceTensor(
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ class ReduceKernel : public CudaKernel, public ReduceKernelBase<allow_multi_axes
|
|||
calculate_sqt_(false),
|
||||
log_sum_exp_(false) {}
|
||||
|
||||
// Only Max Min need to set ReduceTensorIndices CUDNN_REDUCE_TENSOR_FLATTENED_INDICES as per cudnn library manual
|
||||
// Only Max Min will have indices output, need to set the indices to nullptr for other ops
|
||||
template <typename T, cudnnReduceTensorIndices_t ReduceTensorIndices = CUDNN_REDUCE_TENSOR_NO_INDICES>
|
||||
Status ComputeImpl(OpKernelContext* ctx, cudnnReduceTensorOp_t cudnnReduceOp) const;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue