From afe6a6a32fb8b67c93b8d4846ae2520c27343539 Mon Sep 17 00:00:00 2001 From: lucylq Date: Tue, 20 May 2025 09:25:08 -0700 Subject: [PATCH] Dtype selective build: check if portable/optimized in deps When dtype selective build is enabled: Show a warning if kernel_deps does not contain portable/optimized Error out if deps contains portable/optimized, and it is also in kernel_deps. Differential Revision: [D74922471](https://our.internmc.facebook.com/intern/diff/D74922471/) [ghstack-poisoned] --- examples/portable/executor_runner/targets.bzl | 2 +- shim_et/xplat/executorch/codegen/codegen.bzl | 47 ++++++++++++++++++- 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/examples/portable/executor_runner/targets.bzl b/examples/portable/executor_runner/targets.bzl index 30653404eb0..0af45d85075 100644 --- a/examples/portable/executor_runner/targets.bzl +++ b/examples/portable/executor_runner/targets.bzl @@ -84,8 +84,8 @@ def define_common_targets(): "//executorch/kernels/optimized:optimized_oplist", "//executorch/kernels/portable:executorch_aten_ops", "//executorch/kernels/portable:executorch_custom_ops", - "//executorch/kernels/portable:operators", ], + kernel_deps = ["//executorch/kernels/portable:operators",], custom_ops_aten_kernel_deps = [ "//executorch/kernels/portable:operators_aten", ], diff --git a/shim_et/xplat/executorch/codegen/codegen.bzl b/shim_et/xplat/executorch/codegen/codegen.bzl index ceb987a1a78..ffca7850f72 100644 --- a/shim_et/xplat/executorch/codegen/codegen.bzl +++ b/shim_et/xplat/executorch/codegen/codegen.bzl @@ -647,7 +647,7 @@ def executorch_generated_lib( !!WARNING!! Dtype_selective_build is only available in xplat. Proceeding without dtype selective build for lib: {}.""".format(name)) - # Dtype selective build is enabled on portable and optimized kernel libraries. + # Dtype selective build is enabled on portable and optimized kernel libraries. if (not "//executorch/kernels/portable:operators" in kernel_deps) and (not "//executorch/kernels/optimized:optimized_operators" in kernel_deps): warning(""" !!WARNING!! Dtype_selective_build is enabled but kernel_deps does not contain portable or optimized dependencies. @@ -660,6 +660,23 @@ def executorch_generated_lib( Proceeding without dtype selective build. """.format(kernel_deps)) + + # Dtype selective build requires that the portable/optimized kernel libraries are not passed into `deps`. + if ("//executorch/kernels/portable:operators" in kernel_deps): + index = 0 + for dep in deps: + index = index + 1 + portable = name + "_check_portable_" + dep.split(":")[1] + str(index) + message = "Dtype selective build requires that the portable library is not passed into `deps`. Please remove it from `deps` and place it into `kernel_deps`" + check_recursive_dependencies(portable, dep, "//executorch/kernels/portable:operators", message) + if ("//executorch/kernels/optimized:optimized_operators" in kernel_deps): + index = 0 + for dep in deps: + index = index + 1 + optimized = name + "_check_optimized_" + dep.split(":")[1] + str(index) + message = "Dtype selective build requires that the optimized library is not passed into `deps`. Please remove it from `deps` and place it into `kernel_deps`" + check_recursive_dependencies(optimized, dep, "//executorch/kernels/optimized:optimized_operators", message) + aten_suffix = "_aten" if aten_mode else "" @@ -875,3 +892,31 @@ def executorch_ops_check( default_outs = ["."], **kwargs, ) + +def check_recursive_dependencies( + name, + parent, + child, + message = "", + **kwargs, +): + """ + Checks if child is a transitive dependency of parent and fails if it is. + The query runs the equivalent of `buck2 uquery "allpaths(parent, child)". + The path from parent->child is available in the out file and error message. + """ + message = "Dependency violation: '{}' should not depend on '{}'. {}".format(parent, child, message) + + if parent == child: + fail(message) + + runtime.genrule( + name = name, + macros_only = False, + cmd = 'mkdir -p $OUT;paths="$(query_targets allpaths({}, {}))"; echo "$paths" > $OUT/dep.txt; if [ -z "$paths" ]; then echo "Dependencies look good"; else echo {}. This will cause duplicate symbol errors when building with dtype selective build. The dependency path is: "$paths"; fail; fi'.format(parent, child, message), + define_static_target = False, + # The path is saved to $OUT/dep.txt and can be accessed via genrule_name[result]. + outs = {"result": ["dep.txt"]}, + default_outs = ["."], + platforms = kwargs.pop("platforms", get_default_executorch_platforms()), + )