@@ -444,10 +444,53 @@ def build_portable_header_lib(name, oplist_header_name, feature = None):
444
444
feature = feature ,
445
445
)
446
446
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" ]):
450
455
"""
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 )
451
494
452
495
# Copy portable cpp files.
453
496
portable_source_files = []
@@ -546,6 +589,72 @@ def build_optimized_lib(name, oplist_header_name, portable_header_lib, feature =
546
589
feature = feature ,
547
590
)
548
591
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
+
549
658
def executorch_generated_lib (
550
659
name ,
551
660
functions_yaml_target = None ,
@@ -721,32 +830,11 @@ def executorch_generated_lib(
721
830
722
831
# genrule for selective build from static operator list
723
832
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 )
735
834
736
835
# genrule to generate selected_op_variants.h from selected_operators.yaml above
737
836
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 )
750
838
751
839
# codegen genrule(s). For ATen mode we expect two genrules, one for ATen ops one for custom ops.
752
840
for genrule_name in genrules :
@@ -777,7 +865,7 @@ def executorch_generated_lib(
777
865
778
866
# Build portable lib.
779
867
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 )
781
869
kernel_deps .append (":{}" .format (portable_lib_name ))
782
870
783
871
if "//executorch/kernels/optimized:optimized_operators" in kernel_deps :
0 commit comments