Add positive test cases for Conv2D. Reuse build_graph in conv2d_test.
This commit is contained in:
parent
560e4dd67f
commit
cf471f0c15
@ -62,14 +62,14 @@ limitations under the License.
|
|||||||
|
|
||||||
#define TFTRT_RETURN_ERROR_IF_FALSE(status, node) \
|
#define TFTRT_RETURN_ERROR_IF_FALSE(status, node) \
|
||||||
do { \
|
do { \
|
||||||
if ((status) == false) { \
|
if (status == false) { \
|
||||||
TFTRT_INTERNAL_ERROR_AT_NODE(node); \
|
TFTRT_INTERNAL_ERROR_AT_NODE(node); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TFTRT_RETURN_ERROR_IF_NULLPTR(ptr, node) \
|
#define TFTRT_RETURN_ERROR_IF_NULLPTR(ptr, node) \
|
||||||
do { \
|
do { \
|
||||||
if ((ptr) == nullptr) { \
|
if (ptr == nullptr) { \
|
||||||
TFTRT_INTERNAL_ERROR_AT_NODE(node); \
|
TFTRT_INTERNAL_ERROR_AT_NODE(node); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
@ -1593,6 +1593,7 @@ tensorflow::Status ConvertConv2DHelper(OpConverterParams* params, int group) {
|
|||||||
node_def.name());
|
node_def.name());
|
||||||
}
|
}
|
||||||
const nvinfer1::DimsHW dilation(tf_dilations[h_index], tf_dilations[w_index]);
|
const nvinfer1::DimsHW dilation(tf_dilations[h_index], tf_dilations[w_index]);
|
||||||
|
|
||||||
const auto tf_stride = attrs.get<std::vector<int>>("strides");
|
const auto tf_stride = attrs.get<std::vector<int>>("strides");
|
||||||
if (tf_stride.size() != 4) {
|
if (tf_stride.size() != 4) {
|
||||||
return tensorflow::errors::InvalidArgument(
|
return tensorflow::errors::InvalidArgument(
|
||||||
|
@ -2697,6 +2697,17 @@ TEST_F(OpConverterTest, ConvertConv2D) {
|
|||||||
"Dilation rate must be 1 for batch and channel "
|
"Dilation rate must be 1 for batch and channel "
|
||||||
"dimensions, at my_conv2d");
|
"dimensions, at my_conv2d");
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
// Dilation value is not 1 for channel (NHWC), should fail.
|
||||||
|
Reset();
|
||||||
|
NodeDef node_def =
|
||||||
|
get_conv2d_nodedef({1, 1, 1, 1}, "SAME", "NHWC", {1, 1, 1, 2});
|
||||||
|
AddTestTensor("input", {2, 3, 1});
|
||||||
|
AddTestWeights<float>("weights", {3, 3, 1, 1}, {1, 2, 3, 4, 5, 6, 7, 8, 9});
|
||||||
|
RunValidationAndConversion(node_def, error::UNIMPLEMENTED,
|
||||||
|
"Dilation rate must be 1 for batch and channel "
|
||||||
|
"dimensions, at my_conv2d");
|
||||||
|
}
|
||||||
{
|
{
|
||||||
// Strides is not 4D, should fail.
|
// Strides is not 4D, should fail.
|
||||||
Reset();
|
Reset();
|
||||||
@ -2719,6 +2730,129 @@ TEST_F(OpConverterTest, ConvertConv2D) {
|
|||||||
node_def, error::UNIMPLEMENTED,
|
node_def, error::UNIMPLEMENTED,
|
||||||
"Stride must be 1 for batch and channel dimensions, at my_conv2d");
|
"Stride must be 1 for batch and channel dimensions, at my_conv2d");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TestParams {
|
||||||
|
TestParams(const std::vector<int>& input_dims,
|
||||||
|
const std::vector<float>& input,
|
||||||
|
const std::vector<int>& filter_dims,
|
||||||
|
const std::vector<float>& filter,
|
||||||
|
const std::vector<int>& strides, const string& padding,
|
||||||
|
const string& data_format, const std::vector<int>& dilations,
|
||||||
|
const std::vector<int>& expected_output_dims,
|
||||||
|
const std::vector<float>& expected_output)
|
||||||
|
: input_dims(input_dims),
|
||||||
|
input(input),
|
||||||
|
filter_dims(filter_dims),
|
||||||
|
filter(filter),
|
||||||
|
strides(strides),
|
||||||
|
padding(padding),
|
||||||
|
data_format(data_format),
|
||||||
|
dilations(dilations),
|
||||||
|
expected_output_dims(expected_output_dims),
|
||||||
|
expected_output(expected_output) {}
|
||||||
|
|
||||||
|
std::vector<int> input_dims;
|
||||||
|
std::vector<float> input;
|
||||||
|
std::vector<int> filter_dims;
|
||||||
|
std::vector<float> filter;
|
||||||
|
std::vector<int> strides;
|
||||||
|
string padding;
|
||||||
|
string data_format;
|
||||||
|
std::vector<int> dilations;
|
||||||
|
std::vector<int> expected_output_dims;
|
||||||
|
std::vector<float> expected_output;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Ok.
|
||||||
|
const int kConv2DOKCases = 6;
|
||||||
|
TestParams ok_params[kConv2DOKCases] = {
|
||||||
|
// Basic
|
||||||
|
TestParams{/*input_dims=*/{1, 2, 3},
|
||||||
|
/*input=*/{0, 1, 2, 3, 3, 4},
|
||||||
|
/*filter_dims=*/{1, 2, 1, 1},
|
||||||
|
/*filter=*/{-1, 1},
|
||||||
|
/*strides=*/{1, 1, 1, 1},
|
||||||
|
/*padding=*/"VALID",
|
||||||
|
/*data_format=*/"NCHW",
|
||||||
|
/*dilations=*/{1, 1, 1, 1},
|
||||||
|
/*expected_output_dims=*/{1, 2, 2},
|
||||||
|
/*expected_output=*/{1, 1, 0, 1}},
|
||||||
|
// SAME padding (Asymmetric)
|
||||||
|
TestParams{/*input_dims=*/{1, 2, 3},
|
||||||
|
/*input=*/{0, 1, 2, 3, 3, 4},
|
||||||
|
/*filter_dims=*/{1, 2, 1, 1},
|
||||||
|
/*filter=*/{-1, 1},
|
||||||
|
/*strides=*/{1, 1, 1, 1},
|
||||||
|
/*padding=*/"SAME",
|
||||||
|
/*data_format=*/"NCHW",
|
||||||
|
/*dilations=*/{1, 1, 1, 1},
|
||||||
|
/*expected_output_dims=*/{1, 2, 3},
|
||||||
|
/*expected_output=*/{1, 1, -2, 0, 1, -4}},
|
||||||
|
// SAME padding (Symmetric)
|
||||||
|
TestParams{/*input_dims=*/{1, 2, 3},
|
||||||
|
/*input=*/{0, 1, 2, 3, 3, 4},
|
||||||
|
/*filter_dims=*/{1, 3, 1, 1},
|
||||||
|
/*filter=*/{-1, 0, 1},
|
||||||
|
/*strides=*/{1, 1, 1, 1},
|
||||||
|
/*padding=*/"SAME",
|
||||||
|
/*data_format=*/"NCHW",
|
||||||
|
/*dilations=*/{1, 1, 1, 1},
|
||||||
|
/*expected_output_dims=*/{1, 2, 3},
|
||||||
|
/*expected_output=*/{1, 2, -1, 3, 1, -3}},
|
||||||
|
// NHWC
|
||||||
|
TestParams{/*input_dims=*/{2, 3, 1},
|
||||||
|
/*input=*/{0, 1, 2, 3, 3, 4},
|
||||||
|
/*filter_dims=*/{1, 2, 1, 1},
|
||||||
|
/*filter=*/{-1, 1},
|
||||||
|
/*strides=*/{1, 1, 1, 1},
|
||||||
|
/*padding=*/"VALID",
|
||||||
|
/*data_format=*/"NHWC",
|
||||||
|
/*dilations=*/{1, 1, 1, 1},
|
||||||
|
/*expected_output_dims=*/{2, 2, 1},
|
||||||
|
/*expected_output=*/{1, 1, 0, 1}},
|
||||||
|
// Dilated
|
||||||
|
TestParams{/*input_dims=*/{1, 2, 3},
|
||||||
|
/*input=*/{0, 1, 2, 3, 3, 4},
|
||||||
|
/*filter_dims=*/{1, 2, 1, 1},
|
||||||
|
/*filter=*/{-1, 1},
|
||||||
|
/*strides=*/{1, 1, 1, 1},
|
||||||
|
/*padding=*/"VALID",
|
||||||
|
/*data_format=*/"NCHW",
|
||||||
|
/*dilations=*/{1, 1, 1, 2},
|
||||||
|
/*expected_output_dims=*/{1, 2, 1},
|
||||||
|
/*expected_output=*/{2, 1}},
|
||||||
|
// Strided
|
||||||
|
TestParams{/*input_dims=*/{1, 2, 4},
|
||||||
|
/*input=*/{0, 1, 2, 2, 3, 4, 4, 7},
|
||||||
|
/*filter_dims=*/{1, 2, 1, 1},
|
||||||
|
/*filter=*/{-1, 1},
|
||||||
|
/*strides=*/{1, 1, 1, 2},
|
||||||
|
/*padding=*/"VALID",
|
||||||
|
/*data_format=*/"NCHW",
|
||||||
|
/*dilations=*/{1, 1, 1, 1},
|
||||||
|
/*expected_output_dims=*/{1, 2, 2},
|
||||||
|
/*expected_output=*/{1, 0, 1, 3}},
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < kConv2DOKCases; i++) {
|
||||||
|
Reset();
|
||||||
|
NodeDef node_def =
|
||||||
|
get_conv2d_nodedef(ok_params[i].strides, ok_params[i].padding,
|
||||||
|
ok_params[i].data_format, ok_params[i].dilations);
|
||||||
|
AddTestTensor("input", ok_params[i].input_dims);
|
||||||
|
AddTestWeights<float>("weights", ok_params[i].filter_dims,
|
||||||
|
ok_params[i].filter);
|
||||||
|
RunValidationAndConversion(node_def);
|
||||||
|
TRT_TensorOrWeights output;
|
||||||
|
TF_EXPECT_OK(GetTensorOrWeights("my_conv2d", &output));
|
||||||
|
EXPECT_TRUE(output.is_tensor());
|
||||||
|
ExpectTrtDimsEqualsArray(ok_params[i].expected_output_dims,
|
||||||
|
output.tensor()->getDimensions());
|
||||||
|
std::vector<float> output_data(ok_params[i].expected_output.size());
|
||||||
|
BuildAndRun<float>({{"input", ok_params[i].input}}, "my_conv2d",
|
||||||
|
&output_data);
|
||||||
|
EXPECT_THAT(output_data, ElementsAreArray(ok_params[i].expected_output));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace convert
|
} // namespace convert
|
||||||
|
@ -51,37 +51,60 @@ def conv2d_layer(inputs, filters, kernel_size, strides=(1, 1), padding='valid',
|
|||||||
def div_round_up(n, d):
|
def div_round_up(n, d):
|
||||||
return (n - 1) // d + 1
|
return (n - 1) // d + 1
|
||||||
|
|
||||||
|
def build_graph(input_dims, dtype, num_filters, data_format, kernel_sizes,
|
||||||
|
dilation_rates, padding='same'):
|
||||||
|
g = ops.Graph()
|
||||||
|
with g.as_default():
|
||||||
|
inp = array_ops.placeholder(
|
||||||
|
dtype=dtype, shape=[None] + input_dims[1:], name="input")
|
||||||
|
with g.device("/GPU:0"):
|
||||||
|
results = []
|
||||||
|
for kernel_size in kernel_sizes:
|
||||||
|
for dilation_rate in dilation_rates:
|
||||||
|
result = conv2d_layer(inp, num_filters, kernel_size, (1, 1),
|
||||||
|
padding, data_format, dilation_rate)
|
||||||
|
results.append(result)
|
||||||
|
output = sum(results)
|
||||||
|
output = array_ops.identity(output, name="output")
|
||||||
|
return g
|
||||||
|
|
||||||
|
|
||||||
class Conv2DNCHWTest(trt_test.TfTrtIntegrationTestBase):
|
class Conv2DNCHWTest(trt_test.TfTrtIntegrationTestBase):
|
||||||
|
|
||||||
def GetParams(self):
|
def GetParams(self):
|
||||||
"""Testing conversion of Conv2D (data_format=NCHW) in TF-TRT conversion."""
|
"""Testing conversion of Conv2D (data_format=NCHW) in TF-TRT conversion."""
|
||||||
np.random.seed(1234)
|
np.random.seed(1234)
|
||||||
dtype = dtypes.float32
|
input_dims = [13, 3, 7, 11]
|
||||||
input_name = "input"
|
g = build_graph(input_dims=input_dims, dtype=dtypes.float32, num_filters=5,
|
||||||
n, c, h, w = 13, 3, 7, 11
|
data_format="channels_first", kernel_sizes=[(3, 3), (3, 2)],
|
||||||
num_filters = 5
|
dilation_rates=[(1, 1), (2, 3)])
|
||||||
input_dims = [n, c, h, w]
|
|
||||||
output_name = "output"
|
|
||||||
g = ops.Graph()
|
|
||||||
with g.as_default():
|
|
||||||
inp = array_ops.placeholder(
|
|
||||||
dtype=dtype, shape=[None] + input_dims[1:], name=input_name)
|
|
||||||
with g.device("/GPU:0"):
|
|
||||||
results = []
|
|
||||||
for kernel_size in [(3, 3), (3, 2)]:
|
|
||||||
for dilation_rate in [(1, 1), (2, 3)]:
|
|
||||||
result = conv2d_layer(inp, num_filters, kernel_size,
|
|
||||||
dilation_rate=dilation_rate, padding='same',
|
|
||||||
data_format='channels_first')
|
|
||||||
results.append(result)
|
|
||||||
output = sum(results)
|
|
||||||
output = array_ops.identity(output, name=output_name)
|
|
||||||
return trt_test.TfTrtIntegrationTestParams(
|
return trt_test.TfTrtIntegrationTestParams(
|
||||||
gdef=g.as_graph_def(),
|
gdef=g.as_graph_def(),
|
||||||
input_names=[input_name],
|
input_names=["input"],
|
||||||
input_dims=[input_dims],
|
input_dims=[input_dims],
|
||||||
output_names=[output_name],
|
output_names=["output"],
|
||||||
expected_output_dims=[(n, num_filters, h, w)])
|
expected_output_dims=[(13, 5, 7, 11)])
|
||||||
|
|
||||||
|
def ExpectedEnginesToBuild(self, run_params):
|
||||||
|
"""Return the expected engines to build."""
|
||||||
|
return ["TRTEngineOp_0"]
|
||||||
|
|
||||||
|
|
||||||
|
class Conv2DNHWCTest(trt_test.TfTrtIntegrationTestBase):
|
||||||
|
|
||||||
|
def GetParams(self):
|
||||||
|
"""Testing conversion of Conv2D (data_format=NCHW) in TF-TRT conversion."""
|
||||||
|
np.random.seed(1234)
|
||||||
|
input_dims = [13, 7, 11, 3]
|
||||||
|
g = build_graph(input_dims=input_dims, dtype=dtypes.float32, num_filters=5,
|
||||||
|
data_format="channels_last", kernel_sizes=[(3, 3), (3, 2)],
|
||||||
|
dilation_rates=[(1, 1), (2, 3)])
|
||||||
|
return trt_test.TfTrtIntegrationTestParams(
|
||||||
|
gdef=g.as_graph_def(),
|
||||||
|
input_names=["input"],
|
||||||
|
input_dims=[input_dims],
|
||||||
|
output_names=["output"],
|
||||||
|
expected_output_dims=[(13, 7, 11, 5)])
|
||||||
|
|
||||||
def ExpectedEnginesToBuild(self, run_params):
|
def ExpectedEnginesToBuild(self, run_params):
|
||||||
"""Return the expected engines to build."""
|
"""Return the expected engines to build."""
|
||||||
@ -128,42 +151,5 @@ class Conv2DStridedNCHWTest(trt_test.TfTrtIntegrationTestBase):
|
|||||||
return ["TRTEngineOp_0"]
|
return ["TRTEngineOp_0"]
|
||||||
|
|
||||||
|
|
||||||
class Conv2DNHWCTest(trt_test.TfTrtIntegrationTestBase):
|
|
||||||
|
|
||||||
def GetParams(self):
|
|
||||||
"""Testing conversion of Conv2D (data_format=NHWC) in TF-TRT conversion."""
|
|
||||||
np.random.seed(1234)
|
|
||||||
dtype = dtypes.float32
|
|
||||||
input_name = "input"
|
|
||||||
n, h, w, c = 13, 7, 11, 3
|
|
||||||
num_filters = 5
|
|
||||||
input_dims = [n, h, w, c]
|
|
||||||
output_name = "output"
|
|
||||||
g = ops.Graph()
|
|
||||||
with g.as_default():
|
|
||||||
inp = array_ops.placeholder(
|
|
||||||
dtype=dtype, shape=[None] + input_dims[1:], name=input_name)
|
|
||||||
with g.device("/GPU:0"):
|
|
||||||
results = []
|
|
||||||
for kernel_size in [(3, 3), (3, 2)]:
|
|
||||||
for dilation_rate in [(1, 1), (2, 3)]:
|
|
||||||
result = conv2d_layer(inp, num_filters, kernel_size,
|
|
||||||
dilation_rate=dilation_rate, padding='same',
|
|
||||||
data_format='channels_last')
|
|
||||||
results.append(result)
|
|
||||||
output = sum(results)
|
|
||||||
output = array_ops.identity(output, name=output_name)
|
|
||||||
return trt_test.TfTrtIntegrationTestParams(
|
|
||||||
gdef=g.as_graph_def(),
|
|
||||||
input_names=[input_name],
|
|
||||||
input_dims=[input_dims],
|
|
||||||
output_names=[output_name],
|
|
||||||
expected_output_dims=[(n, h, w, num_filters)])
|
|
||||||
|
|
||||||
def ExpectedEnginesToBuild(self, run_params):
|
|
||||||
"""Return the expected engines to build."""
|
|
||||||
return ["TRTEngineOp_0"]
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
test.main()
|
test.main()
|
||||||
|
Loading…
Reference in New Issue
Block a user