Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion codegen/targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,6 @@ def define_common_targets():
visibility = [
"//executorch/runtime/kernel/...",
"//executorch/kernels/...",
"//executorch/runtime/core/exec_aten/...",
"@EXECUTORCH_CLIENTS",
],
)
3 changes: 2 additions & 1 deletion examples/portable/scripts/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ def main() -> None:
required=True,
help=f"provide a model name. Valid ones: {list(MODEL_NAME_TO_MODEL.keys())}",
)
parser.add_argument("-o", "--output_dir", default=".", help="output directory")

args = parser.parse_args()

Expand All @@ -40,7 +41,7 @@ def main() -> None:
)

prog = export_to_exec_prog(model, example_inputs)
save_pte_program(prog.buffer, args.model_name)
save_pte_program(prog.buffer, args.model_name, args.output_dir)


if __name__ == "__main__":
Expand Down
5 changes: 3 additions & 2 deletions examples/portable/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
# LICENSE file in the root directory of this source tree.

import logging
import os

from typing import Tuple, Union

Expand Down Expand Up @@ -78,8 +79,8 @@ def export_to_exec_prog(
return exec_prog


def save_pte_program(buffer: bytes, model_name: str) -> None:
filename = f"{model_name}.pte"
def save_pte_program(buffer: bytes, model_name: str, output_dir: str = "") -> None:
filename = os.path.join(output_dir, f"{model_name}.pte")
try:
with open(filename, "wb") as file:
file.write(buffer)
Expand Down
2 changes: 1 addition & 1 deletion examples/selective_build/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ Check out `targets.bzl` for demo of 3 selective build APIs:

Other configs:
- `--config executorch.max_kernel_num=N`: Only allocate memory for the required number of operators. Take this result from `selected_operators.yaml`.
- `--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).
- `--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).

## CMake examples

Expand Down
25 changes: 24 additions & 1 deletion examples/selective_build/targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ def define_common_targets():
deps = [
":select_ops_in_list",
],
visibility = ["//executorch/runtime/core/..."],
)

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

if not runtime.is_oss:
runtime.genrule(
name = "add_mul_model",
outs = {"add_mul": ["add_mul.pte"]},
cmd = "$(exe fbcode//executorch/examples/portable/scripts:export) --model_name add_mul --output_dir $OUT",
macros_only = False,
visibility = ["//executorch/..."],
)

et_operator_library(
name = "select_ops_from_model",
model = ":add_mul_model[add_mul]",
)

executorch_generated_lib(
name = "select_ops_from_model_lib",
functions_yaml_target = "//executorch/kernels/portable:functions.yaml",
kernel_deps = ["//executorch/kernels/portable:operators"],
deps = [":select_ops_from_model"],
visibility = ["//executorch/kernels/..."],
)

# ~~~ Test binary for selective build ~~~
select_ops = native.read_config("executorch", "select_ops", None)
lib = []
Expand All @@ -76,6 +97,8 @@ def define_common_targets():
lib.append(":select_ops_in_list_lib")
elif select_ops == "yaml":
lib.append(":select_ops_from_yaml_lib")
elif select_ops == "model":
lib.append(":select_ops_from_model_lib")
runtime.cxx_binary(
name = "selective_build_test",
srcs = [],
Expand Down
1 change: 0 additions & 1 deletion examples/selective_build/test_selective_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ test_buck2_select_ops_in_list() {
$BUCK run //examples/selective_build:selective_build_test \
--config=executorch.max_kernel_num=17 \
--config=executorch.select_ops=list \
--config=executorch.dtype_selective_build_lib="//examples/selective_build:select_ops_in_list_lib" \
-- --model_path=./add_mul.pte

echo "Removing add_mul.pte"
Expand Down
2 changes: 1 addition & 1 deletion kernels/portable/cpu/TARGETS
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

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

define_common_targets()
define_common_targets(is_fbcode = True)
1 change: 1 addition & 0 deletions kernels/portable/cpu/scalar_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include <cmath>
#include <limits>

#include <executorch/kernels/portable/cpu/selective_build.h>
#include <executorch/runtime/core/exec_aten/exec_aten.h>
#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
#include <executorch/runtime/core/portable_type/scalar.h>
Expand Down
44 changes: 44 additions & 0 deletions kernels/portable/cpu/selective_build.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree.
*/

#pragma once

#include <executorch/runtime/core/exec_aten/exec_aten.h>

#ifdef EXECUTORCH_SELECTIVE_BUILD_DTYPE
// include header generated by
// executorch/codegen/tools/gen_selected_op_variants.py
#include <executorch/kernels/portable/cpu/selected_op_variants.h>
#else
// dummy implementation
inline constexpr bool should_include_kernel_dtype(
const char* /*operator_name*/,
exec_aten::ScalarType /*scalar_type*/
) {
return true;
}
#endif

namespace torch {
namespace executor {
#define ET_INTERNAL_CHECK_SELECTIVE_BUILD(enum_type) \
do { \
if (!should_include_kernel_dtype(et_switch_name, enum_type)) { \
ET_LOG( \
Error, \
"dtype '%" PRId8 "' not selected for operator %s", \
static_cast<int8_t>(enum_type), \
et_switch_name); \
torch::executor::runtime_abort(); \
} \
} while (0)

} // namespace executor
} // namespace torch

#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
66 changes: 64 additions & 2 deletions kernels/portable/cpu/targets.bzl
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
load("@fbsource//xplat/executorch/codegen:codegen.bzl", "et_operator_library", "executorch_generated_lib")
load("@fbsource//xplat/executorch/kernels/portable:op_registration_util.bzl", "define_op_target", "op_target")

# Operators that are listed in `functions.yaml`, and are thus compatible with
Expand Down Expand Up @@ -821,7 +822,7 @@ _CUSTOM_OPS = (
),
)

def define_common_targets():
def define_common_targets(is_fbcode = False):
"""Defines targets that should be shared between fbcode and xplat.

The directory containing this targets.bzl file should also contain both
Expand Down Expand Up @@ -878,11 +879,30 @@ def define_common_targets():
],
)

dtype_selective_build_lib = native.read_config("executorch", "dtype_selective_build_lib", None)
if dtype_selective_build_lib != None:
# retrieve selected_op_variants.h from codegen
genrule_name = dtype_selective_build_lib + "_et_op_dtype_gen[selected_op_variants]"
runtime.cxx_library(
name = "dtype_headers",
srcs = [],
exported_headers = {
"selected_op_variants.h": genrule_name,
},
visibility = [
"//executorch/...",
"@EXECUTORCH_CLIENTS",
],
)

# Only for use by targets in this directory.
runtime.cxx_library(
name = "scalar_utils",
srcs = [],
exported_headers = ["scalar_utils.h"],
# include dtype selective build flag and header
exported_preprocessor_flags = ["-DEXECUTORCH_SELECTIVE_BUILD_DTYPE"] if dtype_selective_build_lib != None else [],
exported_headers = ["scalar_utils.h", "selective_build.h"],
exported_deps = [":dtype_headers"] if dtype_selective_build_lib != None else [],
visibility = [
"//executorch/kernels/portable/cpu/...",
"//executorch/kernels/optimized/cpu/...",
Expand All @@ -893,3 +913,45 @@ def define_common_targets():
"//executorch/runtime/core/exec_aten/util:scalar_type_util",
],
)

# dtype selective build test artifacts
if is_fbcode:
et_operator_library(
name = "add_model",
model = "fbcode//executorch/test/models:exported_programs[ModuleAdd.pte]",
)

executorch_generated_lib(
name = "add_model_lib",
functions_yaml_target = "//executorch/kernels/portable:functions.yaml",
kernel_deps = ["//executorch/kernels/portable:operators"],
deps = [":add_model"],
visibility = ["//executorch/kernels/..."],
)

runtime.cxx_library(
name = "dtype_headers_TEST_ONLY",
srcs = [],
exported_headers = {
"selected_op_variants.h": ":add_model_lib_et_op_dtype_gen[selected_op_variants]",
},
visibility = [
"//executorch/...",
"@EXECUTORCH_CLIENTS",
],
)

runtime.cxx_library(
name = "scalar_utils_TEST_ONLY",
srcs = [],
exported_preprocessor_flags = ["-DEXECUTORCH_SELECTIVE_BUILD_DTYPE"],
exported_headers = ["scalar_utils.h", "selective_build.h"],
exported_deps = [":dtype_headers_TEST_ONLY"],
visibility = [
"//executorch/kernels/...",
"@EXECUTORCH_CLIENTS",
],
deps = [
"//executorch/runtime/core/exec_aten/util:scalar_type_util",
],
)
2 changes: 1 addition & 1 deletion kernels/portable/targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,8 @@ def define_common_targets():
deps = [
":executorch_aten_ops",
":executorch_custom_ops",
"//executorch/kernels/portable:operators",
],
kernel_deps = ["//executorch/kernels/portable:operators"],
**generated_lib_common_args
)

Expand Down
2 changes: 1 addition & 1 deletion kernels/test/TARGETS
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ load(":targets.bzl", "define_common_targets")

oncall("executorch")

define_common_targets()
define_common_targets(is_fbcode = True)

python_unittest(
name = "gen_supported_features_test",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,47 +6,48 @@
* LICENSE file in the root directory of this source tree.
*/

#include <executorch/runtime/core/exec_aten/util/scalar_type_util.h>
#include <executorch/kernels/portable/cpu/scalar_utils.h>
#include <executorch/test/utils/DeathTest.h>
#include <gtest/gtest.h>

using namespace ::testing;
using exec_aten::ScalarType;
using torch::executor::ScalarTypeToCppType;

// Add test for specific dtypes when we can run on model file.

TEST(SelectedMobileOpsHeaderTest, UnknownOp) {
TEST(DtypeSelectiveBuildTest, UnknownOp) {
ET_EXPECT_DEATH(
ET_SWITCH_TWO_TYPES(
Float,
Int,
exec_aten::ScalarType::Float,
ctx,
"addmm.out",
"unknown.out",
CTYPE_OUT,
[&] { return true; }),
"");
}

TEST(SelectedMobileOpsHeaderTest, OpWithDtype) {
ASSERT_EQ(
TEST(DtypeSelectiveBuildTest, OpWithoutDtype) {
ET_EXPECT_DEATH(
ET_SWITCH_TWO_TYPES(
Float,
Int,
exec_aten::ScalarType::Float,
exec_aten::ScalarType::Int,
ctx,
"add.out",
CTYPE_OUT,
[&] { return true; }),
true);
"");
}

TEST(DtypeSelectiveBuildTest, OpWithDtype) {
ASSERT_EQ(
ET_SWITCH_TWO_TYPES(
Float,
Int,
exec_aten::ScalarType::Int,
exec_aten::ScalarType::Float,
ctx,
"mm.out",
"add.out",
CTYPE_OUT,
[&] { return true; }),
true);
Expand Down
14 changes: 13 additions & 1 deletion kernels/test/targets.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ def make_example_generated_op_test_target():
"//executorch/kernels/test:function_header_wrapper_portable",
)

def define_common_targets():
def define_common_targets(is_fbcode = False):
"""Defines targets that should be shared between fbcode and xplat.

The directory containing this targets.bzl file should also contain both
Expand Down Expand Up @@ -280,3 +280,15 @@ def define_common_targets():
_common_op_test("op_zeros_test", ["aten", "portable"])

make_example_generated_op_test_target()

# dtype selective build test
if is_fbcode:
runtime.cxx_test(
name = "dtype_selective_build_test",
srcs = ["dtype_selective_build_test.cpp"],
deps = [
"//executorch/kernels/portable/cpu:scalar_utils_TEST_ONLY",
"//executorch/runtime/core/exec_aten:lib",
],
preprocessor_flags = ["-DEXECUTORCH_SELECTIVE_BUILD_DTYPE"],
)
Loading