Skip to content

Commit 3fe86c2

Browse files
mkupersttensorflower-gardener
authored andcommitted
[XLA] Add should_inline callback to CallInliner
Add a callback to CallInliner to allow finer-grained control over which callsites to inline. PiperOrigin-RevId: 779849022
1 parent 37d758b commit 3fe86c2

4 files changed

Lines changed: 75 additions & 6 deletions

File tree

third_party/xla/xla/service/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -981,6 +981,7 @@ xla_cc_test(
981981
size = "small",
982982
srcs = ["call_inliner_test.cc"],
983983
deps = [
984+
":call_graph",
984985
":call_inliner",
985986
"//xla:literal_util",
986987
"//xla:shape_util",

third_party/xla/xla/service/call_inliner.cc

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,27 @@ bool CallInliner::IsInlineableCallOp(HloInstruction* instruction) const {
298298
InlineComposites(instruction, composites_to_preserve_);
299299
}
300300

301+
bool CallInliner::ShouldInline(const CallGraph& call_graph,
302+
HloInstruction* instruction) const {
303+
if (!IsInlineableCallOp(instruction)) {
304+
return false;
305+
}
306+
307+
if (should_inline_.has_value()) {
308+
if (!(*should_inline_)(call_graph, instruction)) {
309+
return false;
310+
}
311+
}
312+
313+
if (single_call_site_) {
314+
return call_graph.GetNode(instruction->to_apply())
315+
.caller_callsites()
316+
.size() == 1;
317+
}
318+
319+
return true;
320+
}
321+
301322
absl::StatusOr<bool> CallInliner::InlineAndLegalize(
302323
const CallGraph& call_graph, HloComputation* computation,
303324
absl::Span<HloInstruction* const> instruction_sequence) const {
@@ -309,10 +330,7 @@ absl::StatusOr<bool> CallInliner::InlineAndLegalize(
309330
// used for parallel device computation.
310331
// TODO(b/229887502): update the inliner to ignore only parallel
311332
// device type async call instead of all.
312-
if (IsInlineableCallOp(instruction) &&
313-
(!single_call_site_ || call_graph.GetNode(instruction->to_apply())
314-
.caller_callsites()
315-
.size() == 1)) {
333+
if (ShouldInline(call_graph, instruction)) {
316334
// The caller instruction will get removed after inlining. Record the
317335
// callee computation beforehand, so we can find its schedule.
318336
HloComputation* callee = instruction->to_apply();

third_party/xla/xla/service/call_inliner.h

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ limitations under the License.
1616
#ifndef XLA_SERVICE_CALL_INLINER_H_
1717
#define XLA_SERVICE_CALL_INLINER_H_
1818

19+
#include <functional>
20+
#include <optional>
1921
#include <string>
2022
#include <utility>
2123

@@ -48,14 +50,19 @@ class CallInliner : public HloModulePass {
4850
// are being inlined if necessary.
4951
// If `uniquify_channel_ids` is true, the channel ids of the resulting
5052
// computation will be uniquified.
53+
// If the callback `should_inline` is provided, only functions callsite for
54+
// which it retuns true will be inlined.
5155
explicit CallInliner(
5256
bool single_call_site = false, bool update_domain = false,
5357
absl::flat_hash_set<std::string> composites_to_preserve = {},
54-
bool uniquify_channel_ids = false)
58+
bool uniquify_channel_ids = false,
59+
std::optional<std::function<bool(const CallGraph&, HloInstruction*)>>
60+
should_inline = std::nullopt)
5561
: single_call_site_(single_call_site),
5662
update_domain_(update_domain),
5763
uniquify_channel_ids_(uniquify_channel_ids),
58-
composites_to_preserve_(std::move(composites_to_preserve)) {}
64+
composites_to_preserve_(std::move(composites_to_preserve)),
65+
should_inline_(std::move(should_inline)) {}
5966
~CallInliner() override = default;
6067
absl::string_view name() const override { return "call-inliner"; }
6168

@@ -73,10 +80,16 @@ class CallInliner : public HloModulePass {
7380
const CallGraph& call_graph, HloComputation* computation,
7481
absl::Span<HloInstruction* const> instruction_sequence) const;
7582

83+
bool ShouldInline(const CallGraph& call_graph,
84+
HloInstruction* instruction) const;
85+
7686
bool single_call_site_;
7787
bool update_domain_;
7888
bool uniquify_channel_ids_;
7989
absl::flat_hash_set<std::string> composites_to_preserve_;
90+
std::optional<
91+
std::function<bool(const CallGraph& call_graph, HloInstruction*)>>
92+
should_inline_;
8093
};
8194

8295
} // namespace xla

third_party/xla/xla/service/call_inliner_test.cc

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ limitations under the License.
3333
#include "xla/hlo/transforms/simplifiers/hlo_dce.h"
3434
#include "xla/hlo/utils/hlo_matchers.h"
3535
#include "xla/literal_util.h"
36+
#include "xla/service/call_graph.h"
3637
#include "xla/shape.h"
3738
#include "xla/shape_util.h"
3839
#include "xla/tsl/lib/core/status_test_util.h"
@@ -813,5 +814,41 @@ ENTRY main {
813814
EXPECT_EQ(root->metadata().op_name(), "x/y");
814815
}
815816

817+
TEST_F(CallInlinerTest, InliningCallBack) {
818+
const char* hlo = R"(
819+
callee_negate {
820+
input = f32[128,32] parameter(0)
821+
ROOT y = f32[128,32] negate(input)
822+
}
823+
824+
callee_trivial {
825+
ROOT input = f32[128,32] parameter(0)
826+
}
827+
828+
ENTRY main {
829+
input = f32[128,32] parameter(0)
830+
call.negate = f32[128,32] call(input), to_apply=callee_negate
831+
call.trivial = f32[128,32] call(input), to_apply=callee_trivial
832+
ROOT result = subtract(call.negate, call.trivial)
833+
})";
834+
835+
TF_ASSERT_OK_AND_ASSIGN(std::unique_ptr<HloModule> m,
836+
ParseAndReturnVerifiedModule(hlo));
837+
838+
auto inline_trivial_only = [](const CallGraph& call_graph,
839+
HloInstruction* instruction) {
840+
HloComputation* callee = instruction->to_apply();
841+
return (callee->root_instruction()->opcode() == HloOpcode::kParameter);
842+
};
843+
CallInliner call_inliner(/*single_call_site=*/false, /*update_domain=*/false,
844+
/*composites_to_preserve=*/{},
845+
/*uniquify_channel_ids=*/false,
846+
/*should_inline=*/inline_trivial_only);
847+
848+
EXPECT_THAT(call_inliner.Run(m.get()), ::tsl::testing::IsOkAndHolds(true));
849+
EXPECT_THAT(m->entry_computation()->root_instruction(),
850+
op::Subtract(op::Call(op::Parameter(0)), op::Parameter(0)));
851+
}
852+
816853
} // namespace
817854
} // namespace xla

0 commit comments

Comments
 (0)