提交 0ee967b5 编写于 作者: H hedaoyuan 提交者: GitHub

Merge pull request #4288 from hedaoyuan/fix_bug

Bug fix for get device_context in conv2d op.
...@@ -75,9 +75,6 @@ class GemmConv2DKernel : public framework::OpKernel { ...@@ -75,9 +75,6 @@ class GemmConv2DKernel : public framework::OpKernel {
framework::DDim output_matrix_shape = {output_channels, framework::DDim output_matrix_shape = {output_channels,
output_height * output_width}; output_height * output_width};
auto* device_context =
const_cast<platform::DeviceContext*>(context.device_context_);
// convolution operator: im2col + gemm // convolution operator: im2col + gemm
int in_step = input_channels / groups; int in_step = input_channels / groups;
int out_step = output_channels / groups; int out_step = output_channels / groups;
...@@ -87,14 +84,14 @@ class GemmConv2DKernel : public framework::OpKernel { ...@@ -87,14 +84,14 @@ class GemmConv2DKernel : public framework::OpKernel {
for (int g = 0; g < groups; g++) { for (int g = 0; g < groups; g++) {
// im2col // im2col
Tensor in_slice = in_batch.Slice<T>(g * in_step, (g + 1) * in_step); Tensor in_slice = in_batch.Slice<T>(g * in_step, (g + 1) * in_step);
im2col(in_slice, col, strides[0], strides[1], paddings[0], paddings[1], im2col(context.device_context(), in_slice, col, strides[0], strides[1],
device_context); paddings[0], paddings[1]);
// gemm // gemm
Tensor out_slice = out_batch.Slice<T>(g * out_step, (g + 1) * out_step); Tensor out_slice = out_batch.Slice<T>(g * out_step, (g + 1) * out_step);
Tensor filter_slice = filter.Slice<T>(g * out_step, (g + 1) * out_step); Tensor filter_slice = filter.Slice<T>(g * out_step, (g + 1) * out_step);
math::matmul<Place, T>(filter_slice, false, col_matrix, false, T(1.0), math::matmul<Place, T>(context.device_context(), filter_slice, false,
&out_slice, T(0.0), device_context); col_matrix, false, T(1.0), &out_slice, T(0.0));
} }
} }
} }
...@@ -160,9 +157,6 @@ class GemmConvGrad2DKernel : public framework::OpKernel { ...@@ -160,9 +157,6 @@ class GemmConvGrad2DKernel : public framework::OpKernel {
filter.numel() / filter.dims()[0]}; filter.numel() / filter.dims()[0]};
filter.Resize(filter_matrix_shape); filter.Resize(filter_matrix_shape);
auto* device_context =
const_cast<platform::DeviceContext*>(context.device_context_);
// convolution backward input operator: gemm + col2im // convolution backward input operator: gemm + col2im
// convolution backward weight operator: im2col + gemm // convolution backward weight operator: im2col + gemm
int in_step = input_channels / groups; int in_step = input_channels / groups;
...@@ -184,14 +178,15 @@ class GemmConvGrad2DKernel : public framework::OpKernel { ...@@ -184,14 +178,15 @@ class GemmConvGrad2DKernel : public framework::OpKernel {
out_grad_batch.Slice<T>(g * out_step, (g + 1) * out_step); out_grad_batch.Slice<T>(g * out_step, (g + 1) * out_step);
Tensor filter_slice = Tensor filter_slice =
filter.Slice<T>(g * out_step, (g + 1) * out_step); filter.Slice<T>(g * out_step, (g + 1) * out_step);
math::matmul<Place, T>(filter_slice, true, out_grad_slice, false, math::matmul<Place, T>(context.device_context(), filter_slice, true,
T(1.0), &col_matrix, T(0.0), device_context); out_grad_slice, false, T(1.0), &col_matrix,
T(0.0));
// col2im // col2im
Tensor in_grad_slice = Tensor in_grad_slice =
in_grad_batch.Slice<T>(g * in_step, (g + 1) * in_step); in_grad_batch.Slice<T>(g * in_step, (g + 1) * in_step);
col2im(in_grad_slice, col, strides[0], strides[1], paddings[0], col2im(context.device_context(), in_grad_slice, col, strides[0],
paddings[1], device_context); strides[1], paddings[0], paddings[1]);
} }
} }
} }
...@@ -212,15 +207,15 @@ class GemmConvGrad2DKernel : public framework::OpKernel { ...@@ -212,15 +207,15 @@ class GemmConvGrad2DKernel : public framework::OpKernel {
Tensor out_grad_slice = Tensor out_grad_slice =
out_grad_batch.Slice<T>(g * out_step, (g + 1) * out_step); out_grad_batch.Slice<T>(g * out_step, (g + 1) * out_step);
Tensor in_slice = in_batch.Slice<T>(g * in_step, (g + 1) * in_step); Tensor in_slice = in_batch.Slice<T>(g * in_step, (g + 1) * in_step);
im2col(in_slice, col, strides[0], strides[1], paddings[0], im2col(context.device_context(), in_slice, col, strides[0],
paddings[1], device_context); strides[1], paddings[0], paddings[1]);
// gemm // gemm
Tensor filter_grad_slice = Tensor filter_grad_slice =
filter_grad_.Slice<T>(g * out_step, (g + 1) * out_step); filter_grad_.Slice<T>(g * out_step, (g + 1) * out_step);
math::matmul<Place, T>(out_grad_slice, false, col_matrix, true, math::matmul<Place, T>(context.device_context(), out_grad_slice,
T(1.0), &filter_grad_slice, T(1.0), false, col_matrix, true, T(1.0),
device_context); &filter_grad_slice, T(1.0));
} }
} }
} }
......
...@@ -27,9 +27,10 @@ template <class T> ...@@ -27,9 +27,10 @@ template <class T>
class Im2ColFunctor<paddle::operators::math::ColFormat::kCFO, class Im2ColFunctor<paddle::operators::math::ColFormat::kCFO,
platform::CPUPlace, T> { platform::CPUPlace, T> {
public: public:
void operator()(const framework::Tensor& im, framework::Tensor& col, void operator()(const platform::DeviceContext& context,
const framework::Tensor& im, framework::Tensor& col,
int stride_height, int stride_width, int padding_height, int stride_height, int stride_width, int padding_height,
int padding_width, platform::DeviceContext* context) { int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
...@@ -79,9 +80,9 @@ template <class T> ...@@ -79,9 +80,9 @@ template <class T>
class Col2ImFunctor<paddle::operators::math::ColFormat::kCFO, class Col2ImFunctor<paddle::operators::math::ColFormat::kCFO,
platform::CPUPlace, T> { platform::CPUPlace, T> {
public: public:
void operator()(framework::Tensor& im, const framework::Tensor& col, void operator()(const platform::DeviceContext& context, framework::Tensor& im,
int stride_height, int stride_width, int padding_height, const framework::Tensor& col, int stride_height,
int padding_width, platform::DeviceContext* context) { int stride_width, int padding_height, int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
int input_channels = im.dims()[0]; int input_channels = im.dims()[0];
...@@ -137,9 +138,10 @@ template <class T> ...@@ -137,9 +138,10 @@ template <class T>
class Im2ColFunctor<paddle::operators::math::ColFormat::kOCF, class Im2ColFunctor<paddle::operators::math::ColFormat::kOCF,
platform::CPUPlace, T> { platform::CPUPlace, T> {
public: public:
void operator()(const framework::Tensor& im, framework::Tensor& col, void operator()(const platform::DeviceContext& context,
const framework::Tensor& im, framework::Tensor& col,
int stride_height, int stride_width, int padding_height, int stride_height, int stride_width, int padding_height,
int padding_width, platform::DeviceContext* context) { int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
int input_channels = im.dims()[0]; int input_channels = im.dims()[0];
...@@ -197,9 +199,9 @@ template <class T> ...@@ -197,9 +199,9 @@ template <class T>
class Col2ImFunctor<paddle::operators::math::ColFormat::kOCF, class Col2ImFunctor<paddle::operators::math::ColFormat::kOCF,
platform::CPUPlace, T> { platform::CPUPlace, T> {
public: public:
void operator()(framework::Tensor& im, const framework::Tensor& col, void operator()(const platform::DeviceContext& context, framework::Tensor& im,
int stride_height, int stride_width, int padding_height, const framework::Tensor& col, int stride_height,
int padding_width, platform::DeviceContext* context) { int stride_width, int padding_height, int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
int input_channels = im.dims()[0]; int input_channels = im.dims()[0];
......
...@@ -64,9 +64,10 @@ template <class T> ...@@ -64,9 +64,10 @@ template <class T>
class Im2ColFunctor<paddle::operators::math::ColFormat::kCFO, class Im2ColFunctor<paddle::operators::math::ColFormat::kCFO,
platform::GPUPlace, T> { platform::GPUPlace, T> {
public: public:
void operator()(const framework::Tensor& im, framework::Tensor& col, void operator()(const platform::DeviceContext& context,
const framework::Tensor& im, framework::Tensor& col,
int stride_height, int stride_width, int padding_height, int stride_height, int stride_width, int padding_height,
int padding_width, platform::DeviceContext* context) { int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
...@@ -84,9 +85,9 @@ class Im2ColFunctor<paddle::operators::math::ColFormat::kCFO, ...@@ -84,9 +85,9 @@ class Im2ColFunctor<paddle::operators::math::ColFormat::kCFO,
int block_y = (blocks + 512 - 1) / 512; int block_y = (blocks + 512 - 1) / 512;
dim3 threads(1024, 1); dim3 threads(1024, 1);
dim3 grid(block_x, block_y); dim3 grid(block_x, block_y);
im2col<T><<< im2col<T><<<grid, threads, 0,
grid, threads, 0, reinterpret_cast<const platform::CUDADeviceContext&>(context)
reinterpret_cast<platform::CUDADeviceContext*>(context)->stream()>>>( .stream()>>>(
im.data<T>(), num_outputs, input_height, input_width, filter_height, im.data<T>(), num_outputs, input_height, input_width, filter_height,
filter_width, stride_height, stride_width, padding_height, filter_width, stride_height, stride_width, padding_height,
padding_width, output_height, output_width, col.data<T>()); padding_width, output_height, output_width, col.data<T>());
...@@ -149,9 +150,9 @@ template <class T> ...@@ -149,9 +150,9 @@ template <class T>
class Col2ImFunctor<paddle::operators::math::ColFormat::kCFO, class Col2ImFunctor<paddle::operators::math::ColFormat::kCFO,
platform::GPUPlace, T> { platform::GPUPlace, T> {
public: public:
void operator()(framework::Tensor& im, const framework::Tensor& col, void operator()(const platform::DeviceContext& context, framework::Tensor& im,
int stride_height, int stride_width, int padding_height, const framework::Tensor& col, int stride_height,
int padding_width, platform::DeviceContext* context) { int stride_width, int padding_height, int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
...@@ -174,9 +175,9 @@ class Col2ImFunctor<paddle::operators::math::ColFormat::kCFO, ...@@ -174,9 +175,9 @@ class Col2ImFunctor<paddle::operators::math::ColFormat::kCFO,
// To avoid involving atomic operations, we will launch one kernel per // To avoid involving atomic operations, we will launch one kernel per
// bottom dimension, and then in the kernel add up the top dimensions. // bottom dimension, and then in the kernel add up the top dimensions.
col2im<T><<< col2im<T><<<grid, threads, 0,
grid, threads, 0, reinterpret_cast<const platform::CUDADeviceContext&>(context)
reinterpret_cast<platform::CUDADeviceContext*>(context)->stream()>>>( .stream()>>>(
num_kernels, col.data<T>(), input_height + 2 * padding_height, num_kernels, col.data<T>(), input_height + 2 * padding_height,
input_width + 2 * padding_width, input_channels, filter_height, input_width + 2 * padding_width, input_channels, filter_height,
filter_width, stride_height, stride_width, padding_height, filter_width, stride_height, stride_width, padding_height,
...@@ -235,9 +236,10 @@ template <class T> ...@@ -235,9 +236,10 @@ template <class T>
class Im2ColFunctor<paddle::operators::math::ColFormat::kOCF, class Im2ColFunctor<paddle::operators::math::ColFormat::kOCF,
platform::GPUPlace, T> { platform::GPUPlace, T> {
public: public:
void operator()(const framework::Tensor& im, framework::Tensor& col, void operator()(const platform::DeviceContext& context,
const framework::Tensor& im, framework::Tensor& col,
int stride_height, int stride_width, int padding_height, int stride_height, int stride_width, int padding_height,
int padding_width, platform::DeviceContext* context) { int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
int input_channels = im.dims()[0]; int input_channels = im.dims()[0];
...@@ -268,9 +270,9 @@ class Im2ColFunctor<paddle::operators::math::ColFormat::kOCF, ...@@ -268,9 +270,9 @@ class Im2ColFunctor<paddle::operators::math::ColFormat::kOCF,
dim3 threads(block_dim_x, block_dim_y, dim3 threads(block_dim_x, block_dim_y,
std::min(block_dim_z, input_channels)); std::min(block_dim_z, input_channels));
dim3 grid(output_width, output_height); dim3 grid(output_width, output_height);
im2colOCF<T><<< im2colOCF<T><<<grid, threads, 0,
grid, threads, 0, reinterpret_cast<const platform::CUDADeviceContext&>(context)
reinterpret_cast<platform::CUDADeviceContext*>(context)->stream()>>>( .stream()>>>(
im.data<T>(), col.data<T>(), input_channels, input_height, input_width, im.data<T>(), col.data<T>(), input_channels, input_height, input_width,
filter_height, filter_width, stride_height, stride_width, filter_height, filter_width, stride_height, stride_width,
padding_height, padding_width, output_height, output_width); padding_height, padding_width, output_height, output_width);
...@@ -318,9 +320,9 @@ template <class T> ...@@ -318,9 +320,9 @@ template <class T>
class Col2ImFunctor<paddle::operators::math::ColFormat::kOCF, class Col2ImFunctor<paddle::operators::math::ColFormat::kOCF,
platform::GPUPlace, T> { platform::GPUPlace, T> {
public: public:
void operator()(framework::Tensor& im, const framework::Tensor& col, void operator()(const platform::DeviceContext& context, framework::Tensor& im,
int stride_height, int stride_width, int padding_height, const framework::Tensor& col, int stride_height,
int padding_width, platform::DeviceContext* context) { int stride_width, int padding_height, int padding_width) {
PADDLE_ENFORCE(im.dims().size() == 3); PADDLE_ENFORCE(im.dims().size() == 3);
PADDLE_ENFORCE(col.dims().size() == 5); PADDLE_ENFORCE(col.dims().size() == 5);
int input_channels = im.dims()[0]; int input_channels = im.dims()[0];
...@@ -351,9 +353,9 @@ class Col2ImFunctor<paddle::operators::math::ColFormat::kOCF, ...@@ -351,9 +353,9 @@ class Col2ImFunctor<paddle::operators::math::ColFormat::kOCF,
dim3 threads(block_dim_x, block_dim_y, dim3 threads(block_dim_x, block_dim_y,
std::min(block_dim_z, input_channels)); std::min(block_dim_z, input_channels));
dim3 grid(output_width, output_height); dim3 grid(output_width, output_height);
col2imOCF<T><<< col2imOCF<T><<<grid, threads, 0,
grid, threads, 0, reinterpret_cast<const platform::CUDADeviceContext&>(context)
reinterpret_cast<platform::CUDADeviceContext*>(context)->stream()>>>( .stream()>>>(
im.data<T>(), col.data<T>(), input_channels, input_height, input_width, im.data<T>(), col.data<T>(), input_channels, input_height, input_width,
filter_height, filter_width, stride_height, stride_width, filter_height, filter_width, stride_height, stride_width,
padding_height, padding_width, output_height, output_width); padding_height, padding_width, output_height, output_width);
......
...@@ -72,17 +72,18 @@ enum class ColFormat { kCFO = 0, kOCF = 1 }; ...@@ -72,17 +72,18 @@ enum class ColFormat { kCFO = 0, kOCF = 1 };
template <ColFormat Format, typename Place, typename T> template <ColFormat Format, typename Place, typename T>
class Im2ColFunctor { class Im2ColFunctor {
public: public:
void operator()(const framework::Tensor& im, framework::Tensor& col, void operator()(const platform::DeviceContext& context,
const framework::Tensor& im, framework::Tensor& col,
int stride_height, int stride_width, int padding_height, int stride_height, int stride_width, int padding_height,
int padding_width, platform::DeviceContext* context); int padding_width);
}; };
template <ColFormat Format, typename Place, typename T> template <ColFormat Format, typename Place, typename T>
class Col2ImFunctor { class Col2ImFunctor {
public: public:
void operator()(framework::Tensor& im, const framework::Tensor& col, void operator()(const platform::DeviceContext& context, framework::Tensor& im,
int stride_height, int stride_width, int padding_height, const framework::Tensor& col, int stride_height,
int padding_width, platform::DeviceContext* context); int stride_width, int padding_height, int padding_width);
}; };
} // namespace math } // namespace math
......
...@@ -78,8 +78,8 @@ void testIm2col() { ...@@ -78,8 +78,8 @@ void testIm2col() {
PADDLE_THROW("no GPU support"); PADDLE_THROW("no GPU support");
#endif // PADDLE_ONLY_CPU #endif // PADDLE_ONLY_CPU
} }
im2col(input, output_cfo, stride, stride, padding, padding, context); im2col(*context, input, output_cfo, stride, stride, padding, padding);
im2col_ocf(input, output_ocf, stride, stride, padding, padding, context); im2col_ocf(*context, input, output_ocf, stride, stride, padding, padding);
float* out_cfo_ptr; float* out_cfo_ptr;
if (paddle::platform::is_cpu_place(*place)) { if (paddle::platform::is_cpu_place(*place)) {
......
...@@ -73,13 +73,22 @@ class TestConv2dOp(OpTest): ...@@ -73,13 +73,22 @@ class TestConv2dOp(OpTest):
self.check_output() self.check_output()
def test_check_grad(self): def test_check_grad(self):
self.check_grad(set(['Input', 'Filter']), 'Output') self.check_grad(
set(['Input', 'Filter']), 'Output', max_relative_error=0.05)
def test_check_grad_no_filter(self): def test_check_grad_no_filter(self):
self.check_grad(['Input'], 'Output', no_grad_set=set(['Filter'])) self.check_grad(
['Input'],
'Output',
max_relative_error=0.05,
no_grad_set=set(['Filter']))
def test_check_grad_no_input(self): def test_check_grad_no_input(self):
self.check_grad(['Filter'], 'Output', no_grad_set=set(['Input'])) self.check_grad(
['Filter'],
'Output',
max_relative_error=0.05,
no_grad_set=set(['Input']))
def init_groups(self): def init_groups(self):
self.groups = 1 self.groups = 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册