Skip to content

Commit 1a8eb9a

Browse files
committed
Add LogSoftmax conversion
Fix Softmax comments [TF-TRT] Move LogSoftmax to use OpConverterBase Fix compiler errors clang-format Undo changes to convert_nodes.cc Fix comments
1 parent 85aee74 commit 1a8eb9a

File tree

3 files changed

+134
-7
lines changed

3 files changed

+134
-7
lines changed

tensorflow/compiler/tf2tensorrt/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -677,6 +677,7 @@ tf_cuda_library(
677677
"convert/ops/einsum.cc",
678678
"convert/ops/fill_ops.cc",
679679
"convert/ops/like_ops.cc",
680+
"convert/ops/log_softmax.cc",
680681
"convert/ops/quantization_ops.cc",
681682
"convert/ops/slice_ops.cc",
682683
"convert/ops/tile.cc",

tensorflow/compiler/tf2tensorrt/convert/convert_nodes_test.cc

Lines changed: 39 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4825,13 +4825,14 @@ TEST_P(OpConverter_FP32_FP16_Test, ConvertSoftmax) {
48254825
std::vector<float> expected_values;
48264826
};
48274827
std::vector<TestParams> test_params = {
4828-
TestParams{{2, 3},
4829-
{0.09003057, 0.24472848, 0.66524094, 0.09003057, 0.24472848,
4830-
0.66524094}},
4831-
TestParams{{6, 1}, {1, 1, 1, 1, 1, 1}}, // works with std input
4832-
TestParams{{1, 6}, // this works with arange(1,7) input
4833-
{0.00426978, 0.01160646, 0.03154963, 0.08576079, 0.23312202,
4834-
0.6336913}},
4828+
TestParams{/*input_dims=*/{2, 3},
4829+
/*expected_values=*/{0.09003057, 0.24472848, 0.66524094,
4830+
0.09003057, 0.24472848, 0.66524094}},
4831+
TestParams{/*input_dims=*/{6, 1},
4832+
/*expected_values=*/{1, 1, 1, 1, 1, 1}}, // works w/ std input
4833+
TestParams{/*input_dims=*/{1, 6}, // this works w/ arange(1,7) input
4834+
/*expected_values=*/{0.00426978, 0.01160646, 0.03154963,
4835+
0.08576079, 0.23312202, 0.6336913}}
48354836
};
48364837
std::vector<float> input_values{1, 2, 3, 4, 5, 6};
48374838
for (auto p : test_params) {
@@ -4842,6 +4843,37 @@ TEST_P(OpConverter_FP32_FP16_Test, ConvertSoftmax) {
48424843
}
48434844
}
48444845

4846+
TEST_P(OpConverter_FP32_FP16_Test, ConvertLogSoftmax) {
4847+
// Get the NodeDef for LogSoftMax.
4848+
Scope s = Scope::NewRootScope();
4849+
auto input = ops::Placeholder(s.WithOpName("logits"), tf_type_);
4850+
auto logsoftmax = ops::LogSoftmax(s.WithOpName("my_logsoftmax"), input);
4851+
const NodeDef& node_def = logsoftmax.operation.node()->def();
4852+
4853+
struct TestParams {
4854+
std::vector<int> input_dims;
4855+
std::vector<float> expected_values;
4856+
};
4857+
4858+
std::vector<TestParams> test_params = {
4859+
TestParams{/*input_dims=*/{2, 3},
4860+
/*expected_values=*/{-2.4076061, -1.407606, -0.40760604,
4861+
-2.4076061, -1.407606, -0.40760604}},
4862+
TestParams{/*input_dims=*/{1, 6},
4863+
/*expected_values=*/{-5.4561934, -4.4561934, -3.4561934,
4864+
-2.4561934, -1.4561933, -0.45619333}},
4865+
TestParams{/*input_dims=*/{6, 1},
4866+
/*expected_values=*/{0, 0, 0, 0, 0, 0}}
4867+
};
4868+
std::vector<float> input_values{1, 2, 3, 4, 5, 6};
4869+
for (auto p : test_params) {
4870+
Reset();
4871+
AddTestTensor("logits", p.input_dims, input_values);
4872+
TestOpConverter("my_logsoftmax", node_def, p.input_dims, Status::OK(),
4873+
Status::OK(), ArrayFloatNear(p.expected_values, 1e-3));
4874+
}
4875+
}
4876+
48454877
TEST_P(OpConverter_FP32_Test, ConvertSqueeze) {
48464878
const bool use_implicit_batch = (trt_mode_ == TrtTestMode::kImplicitBatch);
48474879
// Get the NodeDef for Squeeze.
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
#if GOOGLE_CUDA && GOOGLE_TENSORRT
2+
3+
#include "tensorflow/compiler/tf2tensorrt/convert/convert_nodes.h"
4+
#include "tensorflow/compiler/tf2tensorrt/convert/op_converter_registry.h"
5+
#include "tensorflow/compiler/tf2tensorrt/convert/ops/layer_utils.h"
6+
7+
namespace tensorflow {
8+
namespace tensorrt {
9+
namespace convert {
10+
11+
class ConvertLogSoftmax : public OpConverterBase<ConvertLogSoftmax> {
12+
public:
13+
explicit ConvertLogSoftmax(OpConverterParams *params)
14+
: OpConverterBase<ConvertLogSoftmax>(params) {}
15+
16+
static constexpr std::array<DataType, 3> AllowedDataTypes() {
17+
return {DataType::DT_FLOAT, DataType::DT_HALF};
18+
}
19+
20+
static constexpr std::array<InputArgSpec, 1> InputSpec() {
21+
return std::array<InputArgSpec, 1>{
22+
InputArgSpec::Create("logits", TrtInputArg::kTensor)};
23+
}
24+
25+
Status Validate() {
26+
const auto &params = *this->params_;
27+
const auto &inputs = params.inputs;
28+
const auto &node_def = params.node_def;
29+
30+
ITensorProxyPtr logits_tensor = inputs.at(0).tensor();
31+
32+
const int num_trt_dims = logits_tensor->getDimensions().nbDims;
33+
if (!num_trt_dims && params.use_implicit_batch) {
34+
return errors::InvalidArgument(
35+
"TensorRT LogSoftmax cannot apply on the batch dimension");
36+
}
37+
38+
return Status::OK();
39+
}
40+
41+
Status Convert() {
42+
const auto &params = *this->params_;
43+
const auto &inputs = params.inputs;
44+
const auto &node_def = params.node_def;
45+
46+
// Perform LogSoftmax operation:
47+
// `logsoftmax = logits - log(reduce_sum(exp(logits), axis))`
48+
49+
// Get the logits tensor.
50+
ITensorProxyPtr logits_tensor = inputs.at(0).tensor();
51+
const int num_trt_dims = logits_tensor->getDimensions().nbDims;
52+
53+
// Exponent of logits.
54+
nvinfer1::IUnaryLayer *exp = params.converter->network()->addUnary(
55+
*logits_tensor->trt_tensor(), nvinfer1::UnaryOperation::kEXP);
56+
TFTRT_RETURN_ERROR_IF_NULLPTR(exp, node_def.name());
57+
params.converter->SetLayerName(exp, node_def, "exp");
58+
59+
// Reduce-sum operation across the final dimension.
60+
nvinfer1::IReduceLayer *reduced_sum =
61+
params.converter->network()->addReduce(
62+
*exp->getOutput(0), nvinfer1::ReduceOperation::kSUM,
63+
(1 << (num_trt_dims - 1)), /*Reduce across final dimension*/
64+
true /*Keep reduced dims*/);
65+
params.converter->SetLayerName(reduced_sum, node_def, "reduced_sum");
66+
67+
// Logarithm of reduced_sum.
68+
nvinfer1::IUnaryLayer *log_reduced_sum =
69+
params.converter->network()->addUnary(*reduced_sum->getOutput(0),
70+
nvinfer1::UnaryOperation::kLOG);
71+
TFTRT_RETURN_ERROR_IF_NULLPTR(log_reduced_sum, node_def.name());
72+
params.converter->SetLayerName(log_reduced_sum, node_def,
73+
"log_reduced_sum");
74+
75+
// Finally, get the output by subtracting log_reduced_sum from logits.
76+
nvinfer1::IElementWiseLayer *sub =
77+
params.converter->network()->addElementWise(
78+
*logits_tensor->trt_tensor(), *log_reduced_sum->getOutput(0),
79+
nvinfer1::ElementWiseOperation::kSUB);
80+
TFTRT_RETURN_ERROR_IF_NULLPTR(sub, node_def.name());
81+
params.converter->SetLayerName(sub, node_def, "sub");
82+
83+
params.outputs->push_back(TRT_TensorOrWeights(sub->getOutput(0)));
84+
return Status::OK();
85+
}
86+
};
87+
88+
REGISTER_DEFAULT_TRT_OP_CONVERTER(MakeConverterFunction<ConvertLogSoftmax>(),
89+
"LogSoftmax");
90+
91+
} // namespace convert
92+
} // namespace tensorrt
93+
} // namespace tensorflow
94+
#endif // GOOGLE_CUDA && GOOGLE_TENSORRT

0 commit comments

Comments
 (0)