xref: /aosp_15_r20/external/executorch/kernels/optimized/op_registration_util.bzl (revision 523fa7a60841cd1ecfb9cc4201f1ca8b03ed023a)
1load("@fbsource//xplat/executorch/build:runtime_wrapper.bzl", "runtime")
2load("@fbsource//xplat/executorch/build:selects.bzl", "selects")
3load(
4    "@fbsource//xplat/executorch/kernels/optimized:lib_defs.bzl",
5    "get_vec_preprocessor_flags",
6    "get_vec_deps",
7)
8load(
9    "@fbsource//xplat/executorch/kernels/portable:op_registration_util.bzl",
10    "get_compiler_optimization_flags",
11)
12
13def op_target(name, deps = []):
14    """Registers an optimized implementation for an operator overload group.
15
16    An operator overload group is a set of operator overloads with a common
17    operator name. That common operator name should be the base name of this
18    target.
19
20    E.g., the "add" operator overload group, named "op_add" in this target,
21    might implement:
22    - add.Tensor
23    - add_.Tensor
24    - add.out
25    - add.Scalar
26
27    If an op target would like to share a header/sources with a different op
28    target (e.g., helpers/utilities), it should declare a separate cxx_library
29    and add it as a dep.
30
31    Args:
32        name: The name of the operator overload group; e.g.,
33            "op_add". This directory must contain a source file named
34            "<name>.cpp"; e.g., "op_add.cpp".
35        deps: Optional extra deps to add to the cxx_library(). Note:
36            - op targets may not depend on other op targets, to keep the
37              dependencies manageable. If two op targets would like to share
38              code, define a separate runtime.cxx_library that they both depend
39              on.
40    """
41
42    # Note that this doesn't actually define the target, but helps register
43    # it in a table that's used to define the target.
44    return {
45        "deps": deps,
46        "name": name,
47    }
48
49def _enforce_deps(deps, name):
50    """Fails if any of the deps are not allowed.
51
52    Args:
53        deps: A list of build target strings.
54        name: The name of the target; e.g., "op_add"
55    """
56    for dep in deps:
57        if dep.startswith(":op_"):
58            # op targets may not depend on other op targets, to keep the
59            # dependencies manageable. If two op targets would like to share
60            # code, define a separate runtime.cxx_library that they both depend
61            # on.
62            fail("op_target {} may not depend on other op_target {}".format(
63                name,
64                dep,
65            ))
66
67def define_op_library(name, deps):
68    """Defines a cxx_library target for the named operator overload group.
69
70    Args:
71        name: The name of the target; e.g., "op_add"
72        deps: List of deps for the target.
73    """
74    selects.apply(obj = deps, function = native.partial(_enforce_deps, name = name))
75
76    augmented_deps = deps + [
77        "//executorch/kernels/optimized:libvec",
78        "//executorch/kernels/optimized:libutils",
79    ]
80
81    runtime.cxx_library(
82        name = "{}".format(name),
83        srcs = [
84            "{}.cpp".format(name),
85        ],
86        visibility = [
87            "//executorch/kernels/portable/test/...",
88            "//executorch/kernels/quantized/test/...",
89            "//executorch/kernels/optimized/test/...",
90            "//executorch/kernels/test/...",
91            "@EXECUTORCH_CLIENTS",
92        ],
93        # kernels often have helpers with no prototypes just disabling the warning here as the headers
94        # are codegend and linked in later
95        compiler_flags = ["-Wno-missing-prototypes"] + get_compiler_optimization_flags(),
96        deps = [
97            "//executorch/runtime/kernel:kernel_includes",
98        ] + augmented_deps + get_vec_deps(),
99        preprocessor_flags = get_vec_preprocessor_flags(),
100        # sleef needs to be added as a direct dependency of the operator target when building for Android,
101        # or a linker error may occur. Not sure why this happens; it seems that fbandroid_platform_deps of
102        # dependencies are not transitive
103        fbandroid_platform_deps = [
104            (
105                "^android-arm64.*$",
106                [
107                    "fbsource//third-party/sleef:sleef_arm",
108                ],
109            ),
110        ],
111        # link_whole is necessary because the operators register themselves
112        # via static initializers that run at program startup.
113        # @lint-ignore BUCKLINT link_whole
114        link_whole = True,
115    )
116
117def define_op_target(name, deps):
118    """Possibly defines cxx_library targets for the named operator group.
119
120    Args:
121        name: The base name of the target; e.g., "op_add"
122        deps: List of deps for the targets.
123    """
124
125    # When building in ATen mode, ATen-compatible (non-custom) operators will
126    # use the implementations provided by ATen, so we should not build the
127    # versions defined here.
128    define_op_library(
129        name = name,
130        deps = deps,
131    )
132
133def is_op_disabled(name):
134    # All ops are enabled for internal builds.
135    return False
136