1
1
/* Copyright (c) 2016 PaddlePaddle Authors. All Rights Reserved.
2
+
2
3
Licensed under the Apache License, Version 2.0 (the "License");
3
4
you may not use this file except in compliance with the License.
4
5
You may obtain a copy of the License at
6
+
5
7
http://www.apache.org/licenses/LICENSE-2.0
8
+
6
9
Unless required by applicable law or agreed to in writing, software
7
10
distributed under the License is distributed on an "AS IS" BASIS,
8
11
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -12,9 +15,9 @@ limitations under the License. */
12
15
#pragma once
13
16
14
17
#include < glog/logging.h>
18
+ #include " paddle/fluid/platform/enforce.h"
15
19
#include " paddle/fluid/platform/float16.h"
16
20
#include " paddle/fluid/platform/hostdevice.h"
17
-
18
21
#define PADDLE_CUDA_THREAD_SIZE 512
19
22
20
23
#ifdef PADDLE_WITH_CUDA
@@ -29,11 +32,14 @@ limitations under the License. */
29
32
#define __h2div h2div
30
33
#endif
31
34
35
+ #define DIV_ERROR_INFO \
36
+ " InvalidArgumentError: Integer division by zero encountered in " \
37
+ " divide.Please check.\n "
32
38
namespace paddle {
33
39
namespace operators {
34
40
35
41
#define DEFINE_SIMPLE_BINARY_FUNCTOR (Func, expr ) \
36
- template <typename T> \
42
+ template <typename T, class Enable = void > \
37
43
struct Func ##Functor { \
38
44
inline HOSTDEVICE T operator ()(const T& a, const T& b) const { \
39
45
return a expr b; \
@@ -46,8 +52,18 @@ DEFINE_SIMPLE_BINARY_FUNCTOR(Mul, *)
46
52
DEFINE_SIMPLE_BINARY_FUNCTOR (Div, /)
47
53
#undef DEFINE_SIMPLE_BINARY_FUNCTOR
48
54
55
+ // special div functor for int32/int64. check divison has a zero
56
+ template <typename T>
57
+ struct DivFunctor <T,
58
+ typename std::enable_if<std::is_integral<T>::value>::type> {
59
+ inline HOSTDEVICE T operator ()(const T& a, const T& b) const {
60
+ PADDLE_ENFORCE (b != 0 , DIV_ERROR_INFO);
61
+ return a / b;
62
+ }
63
+ };
64
+
49
65
#define DEFINE_SIMPLE_CUDA_BINARY_FUNCTOR (Func, expr ) \
50
- template <typename T> \
66
+ template <typename T, class Enable = void > \
51
67
struct Func ##RangeFunctor { \
52
68
Func##RangeFunctor(const T* x, const T* y, T* z) : x_(x), y_(y), z_(z) {} \
53
69
inline HOSTDEVICE void operator ()(size_t id) const { \
@@ -63,6 +79,20 @@ DEFINE_SIMPLE_CUDA_BINARY_FUNCTOR(Mul, *)
63
79
DEFINE_SIMPLE_CUDA_BINARY_FUNCTOR (Div, /)
64
80
#undef DEFINE_SIMPLE_CUDA_BINARY_FUNCTOR
65
81
82
+ // special div functor for int32/int64. check divison has a zero
83
+ template <typename T>
84
+ struct DivRangeFunctor <
85
+ T, typename std::enable_if<std::is_integral<T>::value>::type> {
86
+ DivRangeFunctor (const T* x, const T* y, T* z) : x_(x), y_(y), z_(z) {}
87
+ inline HOSTDEVICE void operator ()(size_t id) const {
88
+ PADDLE_ENFORCE (y_[id] != 0 , DIV_ERROR_INFO);
89
+ z_[id] = x_[id] / y_[id];
90
+ }
91
+ const T* x_;
92
+ const T* y_;
93
+ T* z_;
94
+ };
95
+
66
96
#ifdef PADDLE_CUDA_FP16
67
97
inline DEVICE half2 half2_add (const half2& a, const half2& b) {
68
98
#if defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 530
0 commit comments