Skip to content

Commit f4679ae

Browse files
lucylqfacebook-github-bot
authored andcommitted
Dependency refactor, add tests (pytorch#1165)
Summary: Pull Request resolved: pytorch#1165 Refactor dependency chain following: https://docs.google.com/document/d/1vuU9UdQA5bq3WU7YnEgJowq9ey6vkF3KUKA0rpIxxIY/edit#heading=h.8raqyft9y50 **New dep chain:** op_<op>.cpp -> selected_op_variants.h selected_op_variants.h -> scalar_type_util **Old dep chain:** op_<op>.cpp -> scalar_type_util scalar_type_util -> selected_op_variants.h **Testing** Add e2e test with addmul model Update unit test to use addmul model Gated to only run with fbcode, as there is dependency on exir which is only in fbcode. Reviewed By: larryliu0820 Differential Revision: D51036567 fbshipit-source-id: ba76b3c61fc9c044232b0ae66f4dba788254bfab
1 parent d664d76 commit f4679ae

File tree

18 files changed

+175
-111
lines changed

18 files changed

+175
-111
lines changed

codegen/targets.bzl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ def define_common_targets():
2929
visibility = [
3030
"//executorch/runtime/kernel/...",
3131
"//executorch/kernels/...",
32-
"//executorch/runtime/core/exec_aten/...",
3332
"@EXECUTORCH_CLIENTS",
3433
],
3534
)

examples/portable/scripts/export.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ def main() -> None:
2626
required=True,
2727
help=f"provide a model name. Valid ones: {list(MODEL_NAME_TO_MODEL.keys())}",
2828
)
29+
parser.add_argument("-o", "--output_dir", default=".", help="output directory")
2930

3031
args = parser.parse_args()
3132

@@ -40,7 +41,7 @@ def main() -> None:
4041
)
4142

4243
prog = export_to_exec_prog(model, example_inputs)
43-
save_pte_program(prog.buffer, args.model_name)
44+
save_pte_program(prog.buffer, args.model_name, args.output_dir)
4445

4546

4647
if __name__ == "__main__":

examples/portable/utils.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
# LICENSE file in the root directory of this source tree.
66

77
import logging
8+
import os
89

910
from typing import Tuple, Union
1011

@@ -78,8 +79,8 @@ def export_to_exec_prog(
7879
return exec_prog
7980

8081

81-
def save_pte_program(buffer: bytes, model_name: str) -> None:
82-
filename = f"{model_name}.pte"
82+
def save_pte_program(buffer: bytes, model_name: str, output_dir: str = "") -> None:
83+
filename = os.path.join(output_dir, f"{model_name}.pte")
8384
try:
8485
with open(filename, "wb") as file:
8586
file.write(buffer)

examples/selective_build/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ Check out `targets.bzl` for demo of 3 selective build APIs:
2121

2222
Other configs:
2323
- `--config executorch.max_kernel_num=N`: Only allocate memory for the required number of operators. Take this result from `selected_operators.yaml`.
24-
- `--config executorch.dtype_selective_build_lib=<executorch_generated_lib_name>`: Use dtype selective build. For each op, we register the dtypes that are used. Eg. if the model only uses the float implementation of add, then only the float add will be registered. Pass in the executorch_generated_lib name (see buck2 list example).
24+
- `--config executorch.dtype_selective_build_lib=<executorch_generated_lib_name>`: Use dtype selective build. For each op, we register the dtypes that are used. Eg. if the model only uses the float implementation of add, then only the float add will be registered. Pass in the executorch_generated_lib name (see buck2 model example in targets.bzl).
2525

2626
## CMake examples
2727

examples/selective_build/targets.bzl

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ def define_common_targets():
4343
deps = [
4444
":select_ops_in_list",
4545
],
46-
visibility = ["//executorch/runtime/core/..."],
4746
)
4847

4948
# Select all ops from a yaml file
@@ -67,6 +66,28 @@ def define_common_targets():
6766
# Select all ops from a given model
6867
# TODO(larryliu0820): Add this
6968

69+
if not runtime.is_oss:
70+
runtime.genrule(
71+
name = "add_mul_model",
72+
outs = {"add_mul": ["add_mul.pte"]},
73+
cmd = "$(exe fbcode//executorch/examples/portable/scripts:export) --model_name add_mul --output_dir $OUT",
74+
macros_only = False,
75+
visibility = ["//executorch/..."],
76+
)
77+
78+
et_operator_library(
79+
name = "select_ops_from_model",
80+
model = ":add_mul_model[add_mul]",
81+
)
82+
83+
executorch_generated_lib(
84+
name = "select_ops_from_model_lib",
85+
functions_yaml_target = "//executorch/kernels/portable:functions.yaml",
86+
kernel_deps = ["//executorch/kernels/portable:operators"],
87+
deps = [":select_ops_from_model"],
88+
visibility = ["//executorch/kernels/..."],
89+
)
90+
7091
# ~~~ Test binary for selective build ~~~
7192
select_ops = native.read_config("executorch", "select_ops", None)
7293
lib = []
@@ -76,6 +97,8 @@ def define_common_targets():
7697
lib.append(":select_ops_in_list_lib")
7798
elif select_ops == "yaml":
7899
lib.append(":select_ops_from_yaml_lib")
100+
elif select_ops == "model":
101+
lib.append(":select_ops_from_model_lib")
79102
runtime.cxx_binary(
80103
name = "selective_build_test",
81104
srcs = [],

examples/selective_build/test_selective_build.sh

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ test_buck2_select_ops_in_list() {
4747
$BUCK run //examples/selective_build:selective_build_test \
4848
--config=executorch.max_kernel_num=17 \
4949
--config=executorch.select_ops=list \
50-
--config=executorch.dtype_selective_build_lib="//examples/selective_build:select_ops_in_list_lib" \
5150
-- --model_path=./add_mul.pte
5251

5352
echo "Removing add_mul.pte"

kernels/portable/cpu/TARGETS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,4 @@
33

44
load(":targets.bzl", "define_common_targets")
55

6-
define_common_targets()
6+
define_common_targets(is_fbcode = True)

kernels/portable/cpu/scalar_utils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <cmath>
1313
#include <limits>
1414

15+
#include <executorch/kernels/portable/cpu/selective_build.h>
1516
#include <executorch/runtime/core/exec_aten/exec_aten.h>
1617
#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
1718
#include <executorch/runtime/core/portable_type/scalar.h>
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
* Copyright (c) Meta Platforms, Inc. and affiliates.
3+
* All rights reserved.
4+
*
5+
* This source code is licensed under the BSD-style license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
9+
#pragma once
10+
11+
#include <executorch/runtime/core/exec_aten/exec_aten.h>
12+
13+
#ifdef EXECUTORCH_SELECTIVE_BUILD_DTYPE
14+
// include header generated by
15+
// executorch/codegen/tools/gen_selected_op_variants.py
16+
#include <executorch/kernels/portable/cpu/selected_op_variants.h>
17+
#else
18+
// dummy implementation
19+
inline constexpr bool should_include_kernel_dtype(
20+
const char* /*operator_name*/,
21+
exec_aten::ScalarType /*scalar_type*/
22+
) {
23+
return true;
24+
}
25+
#endif
26+
27+
namespace torch {
28+
namespace executor {
29+
#define ET_INTERNAL_CHECK_SELECTIVE_BUILD(enum_type) \
30+
do { \
31+
if (!should_include_kernel_dtype(et_switch_name, enum_type)) { \
32+
ET_LOG( \
33+
Error, \
34+
"dtype '%" PRId8 "' not selected for operator %s", \
35+
static_cast<int8_t>(enum_type), \
36+
et_switch_name); \
37+
torch::executor::runtime_abort(); \
38+
} \
39+
} while (0)
40+
41+
} // namespace executor
42+
} // namespace torch
43+
44+
#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>

kernels/portable/cpu/targets.bzl

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
2+
load("@fbsource//xplat/executorch/codegen:codegen.bzl", "et_operator_library", "executorch_generated_lib")
23
load("@fbsource//xplat/executorch/kernels/portable:op_registration_util.bzl", "define_op_target", "op_target")
34

45
# Operators that are listed in `functions.yaml`, and are thus compatible with
@@ -821,7 +822,7 @@ _CUSTOM_OPS = (
821822
),
822823
)
823824

824-
def define_common_targets():
825+
def define_common_targets(is_fbcode = False):
825826
"""Defines targets that should be shared between fbcode and xplat.
826827
827828
The directory containing this targets.bzl file should also contain both
@@ -878,11 +879,30 @@ def define_common_targets():
878879
],
879880
)
880881

882+
dtype_selective_build_lib = native.read_config("executorch", "dtype_selective_build_lib", None)
883+
if dtype_selective_build_lib != None:
884+
# retrieve selected_op_variants.h from codegen
885+
genrule_name = dtype_selective_build_lib + "_et_op_dtype_gen[selected_op_variants]"
886+
runtime.cxx_library(
887+
name = "dtype_headers",
888+
srcs = [],
889+
exported_headers = {
890+
"selected_op_variants.h": genrule_name,
891+
},
892+
visibility = [
893+
"//executorch/...",
894+
"@EXECUTORCH_CLIENTS",
895+
],
896+
)
897+
881898
# Only for use by targets in this directory.
882899
runtime.cxx_library(
883900
name = "scalar_utils",
884901
srcs = [],
885-
exported_headers = ["scalar_utils.h"],
902+
# include dtype selective build flag and header
903+
exported_preprocessor_flags = ["-DEXECUTORCH_SELECTIVE_BUILD_DTYPE"] if dtype_selective_build_lib != None else [],
904+
exported_headers = ["scalar_utils.h", "selective_build.h"],
905+
exported_deps = [":dtype_headers"] if dtype_selective_build_lib != None else [],
886906
visibility = [
887907
"//executorch/kernels/portable/cpu/...",
888908
"//executorch/kernels/optimized/cpu/...",
@@ -893,3 +913,45 @@ def define_common_targets():
893913
"//executorch/runtime/core/exec_aten/util:scalar_type_util",
894914
],
895915
)
916+
917+
# dtype selective build test artifacts
918+
if is_fbcode:
919+
et_operator_library(
920+
name = "add_model",
921+
model = "fbcode//executorch/test/models:exported_programs[ModuleAdd.pte]",
922+
)
923+
924+
executorch_generated_lib(
925+
name = "add_model_lib",
926+
functions_yaml_target = "//executorch/kernels/portable:functions.yaml",
927+
kernel_deps = ["//executorch/kernels/portable:operators"],
928+
deps = [":add_model"],
929+
visibility = ["//executorch/kernels/..."],
930+
)
931+
932+
runtime.cxx_library(
933+
name = "dtype_headers_TEST_ONLY",
934+
srcs = [],
935+
exported_headers = {
936+
"selected_op_variants.h": ":add_model_lib_et_op_dtype_gen[selected_op_variants]",
937+
},
938+
visibility = [
939+
"//executorch/...",
940+
"@EXECUTORCH_CLIENTS",
941+
],
942+
)
943+
944+
runtime.cxx_library(
945+
name = "scalar_utils_TEST_ONLY",
946+
srcs = [],
947+
exported_preprocessor_flags = ["-DEXECUTORCH_SELECTIVE_BUILD_DTYPE"],
948+
exported_headers = ["scalar_utils.h", "selective_build.h"],
949+
exported_deps = [":dtype_headers_TEST_ONLY"],
950+
visibility = [
951+
"//executorch/kernels/...",
952+
"@EXECUTORCH_CLIENTS",
953+
],
954+
deps = [
955+
"//executorch/runtime/core/exec_aten/util:scalar_type_util",
956+
],
957+
)

kernels/portable/targets.bzl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,8 @@ def define_common_targets():
9797
deps = [
9898
":executorch_aten_ops",
9999
":executorch_custom_ops",
100-
"//executorch/kernels/portable:operators",
101100
],
101+
kernel_deps = ["//executorch/kernels/portable:operators"],
102102
**generated_lib_common_args
103103
)
104104

kernels/test/TARGETS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ load(":targets.bzl", "define_common_targets")
77

88
oncall("executorch")
99

10-
define_common_targets()
10+
define_common_targets(is_fbcode = True)
1111

1212
python_unittest(
1313
name = "gen_supported_features_test",

runtime/core/exec_aten/util/test/selected_op_variants_test.cpp renamed to kernels/test/dtype_selective_build_test.cpp

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,48 @@
66
* LICENSE file in the root directory of this source tree.
77
*/
88

9-
#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
9+
#include <executorch/kernels/portable/cpu/scalar_utils.h>
1010
#include <executorch/test/utils/DeathTest.h>
1111
#include <gtest/gtest.h>
1212

1313
using namespace ::testing;
1414
using exec_aten::ScalarType;
1515
using torch::executor::ScalarTypeToCppType;
1616

17-
// Add test for specific dtypes when we can run on model file.
18-
19-
TEST(SelectedMobileOpsHeaderTest, UnknownOp) {
17+
TEST(DtypeSelectiveBuildTest, UnknownOp) {
2018
ET_EXPECT_DEATH(
2119
ET_SWITCH_TWO_TYPES(
2220
Float,
2321
Int,
2422
exec_aten::ScalarType::Float,
2523
ctx,
26-
"addmm.out",
24+
"unknown.out",
2725
CTYPE_OUT,
2826
[&] { return true; }),
2927
"");
3028
}
3129

32-
TEST(SelectedMobileOpsHeaderTest, OpWithDtype) {
33-
ASSERT_EQ(
30+
TEST(DtypeSelectiveBuildTest, OpWithoutDtype) {
31+
ET_EXPECT_DEATH(
3432
ET_SWITCH_TWO_TYPES(
3533
Float,
3634
Int,
37-
exec_aten::ScalarType::Float,
35+
exec_aten::ScalarType::Int,
3836
ctx,
3937
"add.out",
4038
CTYPE_OUT,
4139
[&] { return true; }),
42-
true);
40+
"");
41+
}
42+
43+
TEST(DtypeSelectiveBuildTest, OpWithDtype) {
4344
ASSERT_EQ(
4445
ET_SWITCH_TWO_TYPES(
4546
Float,
4647
Int,
47-
exec_aten::ScalarType::Int,
48+
exec_aten::ScalarType::Float,
4849
ctx,
49-
"mm.out",
50+
"add.out",
5051
CTYPE_OUT,
5152
[&] { return true; }),
5253
true);

kernels/test/targets.bzl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ def make_example_generated_op_test_target():
2828
"//executorch/kernels/test:function_header_wrapper_portable",
2929
)
3030

31-
def define_common_targets():
31+
def define_common_targets(is_fbcode = False):
3232
"""Defines targets that should be shared between fbcode and xplat.
3333
3434
The directory containing this targets.bzl file should also contain both
@@ -280,3 +280,15 @@ def define_common_targets():
280280
_common_op_test("op_zeros_test", ["aten", "portable"])
281281

282282
make_example_generated_op_test_target()
283+
284+
# dtype selective build test
285+
if is_fbcode:
286+
runtime.cxx_test(
287+
name = "dtype_selective_build_test",
288+
srcs = ["dtype_selective_build_test.cpp"],
289+
deps = [
290+
"//executorch/kernels/portable/cpu:scalar_utils_TEST_ONLY",
291+
"//executorch/runtime/core/exec_aten:lib",
292+
],
293+
preprocessor_flags = ["-DEXECUTORCH_SELECTIVE_BUILD_DTYPE"],
294+
)

0 commit comments

Comments
 (0)