Skip to content

Commit

Permalink
fix typo and docs, add topi test
Browse files Browse the repository at this point in the history
  • Loading branch information
optima2005 committed Nov 23, 2019
1 parent 536137a commit 83e05ac
Show file tree
Hide file tree
Showing 4 changed files with 126 additions and 8 deletions.
4 changes: 3 additions & 1 deletion python/tvm/contrib/cudnn.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,14 +391,16 @@ def conv3d_w_shape(in_channel,
filter_d,
filter_h,
filter_w):
"""Get weight shape for a 2D convolution
"""Get weight shape for a 3D convolution
Parameters
----------
in_channel: int
input channel
out_channel: int
output channel
filter_d: int
filter depth
filter_h: int
filter height
filter_w: int
Expand Down
13 changes: 7 additions & 6 deletions src/relay/op/nn/convolution.cc
Original file line number Diff line number Diff line change
Expand Up @@ -145,16 +145,17 @@ TVM_REGISTER_API("relay.op.nn._make.conv3d")


RELAY_REGISTER_OP("nn.conv3d")
.describe(R"code(3D convolution layer (e.g. spatial convolution over images).
.describe(R"code(3D convolution layer (e.g. convolution over 3D image data,
like Magnetic Resonance Imaging (MRI) data in medicine).
This layer creates a convolution kernel that is convolved
with the layer input to produce a tensor of outputs.
- **data**: This depends on the `layout` parameter. Input is 4D array of shape
(batch_size, in_channels, height, width) if `layout` is `NCHW`.
- **weight**: (channels, in_channels, kernel_size[0], kernel_size[1])
- **out**: This depends on the `layout` parameter. Output is 4D array of shape
(batch_size, channels, out_height, out_width) if `layout` is `NCHW`.
- **data**: This depends on the `layout` parameter. Input is 5D array of shape
(batch_size, in_channels, depth, height, width) if `layout` is `NCDHW`.
- **weight**: (channels, in_channels, kernel_size[0], kernel_size[1], kernel_size[2])
- **out**: This depends on the `layout` parameter. Output is 5D array of shape
(batch_size, channels, out_depth, out_height, out_width) if `layout` is `NCDHW`.
)code" TVM_ADD_FILELINE)
.set_attrs_type<Conv3DAttrs>()
Expand Down
2 changes: 1 addition & 1 deletion topi/python/topi/testing/conv3d_ncdhw_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def _conv3d_ncdhw_python(a_np, w_np, stride, padding):
else:
stride_d, stride_h, stride_w = stride
if isinstance(padding, int):
pad_d, pad_h = pad_w = padding * 2
pad_d = pad_h = pad_w = padding * 2
elif isinstance(padding, (list, tuple)):
pad_d, pad_h, pad_w = padding[0] * 2, padding[1] * 2, padding[2] * 2
else:
Expand Down
115 changes: 115 additions & 0 deletions topi/tests/python/test_topi_conv3d_ncdhw.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
"""Example code to do convolution."""

import numpy as np
import tvm
from tvm import autotvm
import topi
import topi.testing
from tvm.contrib.pickle_memoize import memoize
from topi.util import get_const_tuple

from common import get_all_backend

def verify_conv3d_ncdhw(batch, in_channel, in_size, num_filter, kernel, stride, padding, dilation=1, add_bias=False, add_relu=False):
print("Workload: (%d, %d, %d, %d, %d, %d, %d, %d)" % (batch, in_channel, in_size, num_filter, kernel, stride, padding, dilation))

in_depth = in_height = in_width = in_size

A = tvm.placeholder((batch, in_channel, in_depth, in_height, in_width), name='A')
W = tvm.placeholder((num_filter, in_channel, kernel, kernel, kernel), name='W')
bias = tvm.placeholder((num_filter, 1, 1, 1), name='bias')

a_shape = get_const_tuple(A.shape)
w_shape = get_const_tuple(W.shape)
bias_shape = get_const_tuple(bias.shape)
dtype = A.dtype

@memoize("topi.tests.test_topi_conv3d_ncdhw.verify_conv3d_ncdhw")
def get_ref_data():
a_np = np.random.uniform(size=a_shape).astype(dtype)
w_np = np.random.uniform(size=w_shape).astype(dtype)
b_np = np.random.uniform(size=bias_shape).astype(dtype)
dw_np = topi.testing.dilate_python(w_np, (1, 1, dilation, dilation, dilation))
c_np = topi.testing.conv3d_ncdhw_python(a_np, dw_np, stride, padding)
if add_bias:
c_np += b_np
if add_relu:
c_np = np.maximum(c_np, 0)
return a_np, w_np, b_np, c_np

a_np, w_np, b_np, c_np = get_ref_data()

def check_device(device):
ctx = tvm.context(device, 0)
if not ctx.exist:
print("Skip because %s is not enabled" % device)
return
print("Running on target: %s" % device)
with tvm.target.create(device):
C = topi.nn.conv3d(A, W, (stride, stride, stride), (padding, padding, padding),
(dilation, dilation, dilation), layout='NCDHW', out_dtype=dtype)
if add_bias:
C = topi.add(C, bias)
if add_relu:
C = topi.nn.relu(C)
s = topi.generic.schedule_conv3d_ncdhw([C])

a = tvm.nd.array(a_np, ctx)
w = tvm.nd.array(w_np, ctx)
b = tvm.nd.array(b_np, ctx)
c = tvm.nd.array(np.zeros(get_const_tuple(C.shape), dtype=C.dtype), ctx)
if add_bias:
func = tvm.build(s, [A, W, bias, C], device, name="relu_%d_%d_%d_%d_%d_%d_%d_%d" % (batch, in_channel, in_size, num_filter, kernel, stride, padding, dilation))
func(a, w, b, c)
else:
func = tvm.build(s, [A, W, C], device, name="relu_%d_%d_%d_%d_%d_%d_%d_%d" % (batch, in_channel, in_size, num_filter, kernel, stride, padding, dilation))
func(a, w, c)
tvm.testing.assert_allclose(c.asnumpy(), c_np, rtol=1e-4)

for device in get_all_backend():
with autotvm.tophub.context(device): # load tophub pre-tuned parameters
check_device(device)


def test_conv3d_ncdhw():
#3DCNN workloads
verify_conv3d_ncdhw(1, 32, 32, 5, 1, 1, 0)
verify_conv3d_ncdhw(1, 32, 32, 1, 1, 1, 0)
verify_conv3d_ncdhw(1, 32, 32, 5, 1, 1, 1)
verify_conv3d_ncdhw(1, 32, 32, 1, 1, 1, 1)

# bias, relu
verify_conv3d_ncdhw(1, 64, 56, 3, 1, 1, 1, add_relu=True)
verify_conv3d_ncdhw(1, 64, 56, 3, 1, 1, 1, add_bias=True)
verify_conv3d_ncdhw(1, 64, 56, 3, 1, 1, 1, add_bias=True, add_relu=True)

# dilation = 2
verify_conv3d_ncdhw(1, 64, 56, 3, 3, 1, 1, dilation=2)

# batch size
verify_conv3d_ncdhw(4, 64, 56, 5, 3, 1, 1)

# weird workloads
verify_conv3d_ncdhw(2, 2, 2, 2, 2, 2, 2)
verify_conv3d_ncdhw(3, 3, 3, 3, 3, 3, 3)



if __name__ == "__main__":
test_conv3d_ncdhw()

0 comments on commit 83e05ac

Please sign in to comment.