@@ -444,10 +444,53 @@ def build_portable_header_lib(name, oplist_header_name, feature = None):
444444 feature = feature ,
445445 )
446446
447- def build_portable_lib (name , oplist_header_name , portable_header_lib , feature = None , expose_operator_symbols = False ):
448- """Build portable lib from source. We build from source so that the generated header file,
449- selected_op_variants.h, can be used to selectively build the lib for different dtypes.
447+ def build_portable_lib (
448+ name ,
449+ et_operator_lib_deps = [],
450+ oplist_header_name = None ,
451+ portable_header_lib = None ,
452+ feature = None ,
453+ expose_operator_symbols = False ,
454+ visibility = ["@EXECUTORCH_CLIENTS" ]):
450455 """
456+ WARNING: Before using this, please consider using executorch_generated_lib instead. This
457+ function is only for special cases where you need to build a portable kernel library with
458+ dtype selective build enabled and also wants to share it across more than one executorch_generated_lib.
459+ Any other use case is likely wrong and you should use executorch_generated_lib instead.
460+
461+ Create a new portable kernel library based on `portable_header_lib`. `portable_header_lib`
462+ should contain the header `selected_op_variants.h` generated by `dtype_header_genrule`.
463+
464+ Notice that this is giving a library that is different than //executorch/kernels/portable/cpu:cpu,
465+ because of the generated header `selected_op_variants.h`. The original portable kernel library
466+ doesn't have that header and thus include all the dtypes possible.
467+
468+ If no `portable_header_lib` is provided, try to create one based on the deps. In this case
469+ we require `deps` to be present. Notice that this way we are always enabling dtype selective
470+ build.
471+
472+ Args:
473+ name: name of the new portable kernel library.
474+ et_operator_lib_deps: list of deps to use to create the portable header library.
475+ oplist_header_name: the name of the header genrule (dtype_header_genrule)
476+ portable_header_lib: the name of the header library (build_portable_header_lib)
477+ feature: feature to use for the new portable kernel library.
478+ expose_operator_symbols: expose operator symbols to library users. This only works in xplat.
479+ visibility: visibility of the new portable kernel library.
480+ """
481+
482+ if not portable_header_lib :
483+ if not oplist_header_name :
484+ if not et_operator_lib_deps :
485+ fail ("Either et_operator_lib_deps or oplist_header_name must be provided." )
486+ oplist_header_name = name + "_header"
487+ dtype_header_genrule (
488+ name = oplist_header_name ,
489+ deps = et_operator_lib_deps ,
490+ visibility = visibility ,
491+ )
492+ portable_header_lib = name + "_portable_header_lib"
493+ build_portable_header_lib (portable_header_lib , oplist_header_name , feature )
451494
452495 # Copy portable cpp files.
453496 portable_source_files = []
@@ -546,6 +589,72 @@ def build_optimized_lib(name, oplist_header_name, portable_header_lib, feature =
546589 feature = feature ,
547590 )
548591
592+ def selected_operators_genrule (
593+ name ,
594+ deps ,
595+ platforms = get_default_executorch_platforms (),
596+ ):
597+ """Generates selected_operators.yaml from the list of deps. We look into the trasitive closure of all the deps,
598+ and look for macros `et_operator_library`.
599+
600+ `gen_all_oplist` is the python binary we use to aggregate all the `et_operator_library`s into single
601+ `selected_operators.yaml` file.
602+
603+ This file can be furthur used to generate `selected_op_variants.h` (see dtype_header_genrule) for dtype
604+ selective build work.
605+ """
606+ runtime .genrule (
607+ name = name ,
608+ macros_only = False ,
609+ cmd = ("$(exe fbsource//xplat/executorch/codegen/tools:gen_all_oplist) " +
610+ "--model_file_list_path $(@query_outputs \' attrfilter(labels, et_operator_library, deps(set({deps})))\' ) " +
611+ "--allow_include_all_overloads " +
612+ "--output_dir $OUT " ).format (deps = " " .join (["\" {}\" " .format (d ) for d in deps ])),
613+ outs = {"selected_operators.yaml" : ["selected_operators.yaml" ]},
614+ default_outs = ["." ],
615+ platforms = platforms ,
616+ )
617+
618+ def dtype_header_genrule (
619+ name ,
620+ visibility ,
621+ deps = [],
622+ selected_operators_genrule_name = None ,
623+ platforms = get_default_executorch_platforms (),
624+ ):
625+ """Generate selected_op_variants.h from selected_operators.yaml.
626+
627+ Given a `selected_operators.yaml` (passed in as selected_operators_genrule_name), we should be able to determine
628+ what dtypes to be enabled for kernels in the kernel library. For example, `add.out` kernel needs to support
629+ both float16 and float32 etc.
630+
631+ This information is recorded in `selected_op_variants.h` and it should be used to compile a new kernel library.
632+
633+ Notice that until this stage we are kernel library agnostic, meaning the header should be applicable to any
634+ kernel library that includes it.
635+ """
636+ if not selected_operators_genrule_name :
637+ if not deps :
638+ fail ("Either deps or selected_operators_genrule_name must be provided." )
639+ selected_operators_genrule_name = name + "_selected_operators"
640+ selected_operators_genrule (
641+ name = selected_operators_genrule_name ,
642+ deps = deps ,
643+ )
644+
645+ runtime .genrule (
646+ name = name ,
647+ macros_only = False ,
648+ cmd = ("$(exe //executorch/codegen/tools:gen_selected_op_variants) " +
649+ "--yaml_file_path $(location :{}[selected_operators.yaml]) " +
650+ "--output_dir $OUT" ).format (selected_operators_genrule_name ),
651+ outs = {"selected_op_variants" : ["selected_op_variants.h" ]},
652+ default_outs = ["." ],
653+ platforms = platforms ,
654+ visibility = visibility ,
655+ _is_external_target = True ,
656+ )
657+
549658def executorch_generated_lib (
550659 name ,
551660 functions_yaml_target = None ,
@@ -721,32 +830,11 @@ def executorch_generated_lib(
721830
722831 # genrule for selective build from static operator list
723832 oplist_dir_name = name + "_et_oplist"
724- runtime .genrule (
725- name = oplist_dir_name ,
726- macros_only = False ,
727- cmd = ("$(exe fbsource//xplat/executorch/codegen/tools:gen_all_oplist) " +
728- "--model_file_list_path $(@query_outputs \' attrfilter(labels, et_operator_library, deps(set({deps})))\' ) " +
729- "--allow_include_all_overloads " +
730- "--output_dir $OUT " ).format (deps = " " .join (["\" {}\" " .format (d ) for d in deps ])),
731- outs = {"selected_operators.yaml" : ["selected_operators.yaml" ]},
732- default_outs = ["." ],
733- platforms = platforms ,
734- )
833+ selected_operators_genrule (name = oplist_dir_name , deps = deps , platforms = platforms )
735834
736835 # genrule to generate selected_op_variants.h from selected_operators.yaml above
737836 oplist_header_name = name + "_et_op_dtype_gen"
738- runtime .genrule (
739- name = oplist_header_name ,
740- macros_only = False ,
741- cmd = ("$(exe //executorch/codegen/tools:gen_selected_op_variants) " +
742- "--yaml_file_path $(location :{}[selected_operators.yaml]) " +
743- "--output_dir $OUT" ).format (oplist_dir_name ),
744- outs = {"selected_op_variants" : ["selected_op_variants.h" ]},
745- default_outs = ["." ],
746- platforms = platforms ,
747- visibility = visibility ,
748- _is_external_target = True ,
749- )
837+ dtype_header_genrule (name = oplist_header_name , selected_operators_genrule_name = oplist_dir_name , platforms = platforms , visibility = visibility )
750838
751839 # codegen genrule(s). For ATen mode we expect two genrules, one for ATen ops one for custom ops.
752840 for genrule_name in genrules :
@@ -777,7 +865,7 @@ def executorch_generated_lib(
777865
778866 # Build portable lib.
779867 portable_lib_name = name + "_portable_lib"
780- build_portable_lib (portable_lib_name , oplist_header_name , portable_header_lib , feature , expose_operator_symbols )
868+ build_portable_lib (name = portable_lib_name , portable_header_lib = portable_header_lib , feature = feature , expose_operator_symbols = expose_operator_symbols )
781869 kernel_deps .append (":{}" .format (portable_lib_name ))
782870
783871 if "//executorch/kernels/optimized:optimized_operators" in kernel_deps :
0 commit comments