Mousius commented on code in PR #71: URL: https://github.com/apache/tvm-rfcs/pull/71#discussion_r876066248
########## rfcs/0070-target-preprocessing.md: ########## @@ -0,0 +1,217 @@ +- Feature Name: target-architecture-preprocessor +- Start Date: 2022-04-04 +- RFC PR: [apache/tvm-rfcs#0070](https://github.com/apache/tvm-rfcs/pull/0000) +- GitHub Issue: [apache/tvm#0000](https://github.com/apache/tvm/issues/0000) + +# Summary +[summary]: #summary +Provide a standard and easily testable way to inspect architecture extensions and provide them to the various parts of TVM which utilise that information. + +# Motivation +[motivation]: #motivation +TVM has multiple ways to define a `Target`s architectural features for use in deciding on schedules or other calculations, here's a few different ways we do this: + +* CPU to Feature Mapping: https://github.com/apache/tvm/blob/d2db9cb0d839e32778f461b77e59f6418282a511/python/tvm/target/arm_isa.py#L22-L39 +* Inspecting `Target` in utility functions: https://github.com/apache/tvm/blob/d2db9cb0d839e32778f461b77e59f6418282a511/python/tvm/topi/arm_cpu/arm_utils.py#L24-L70 +* Inspecting `Target` in utility functions inside legalization code: https://github.com/apache/tvm/blob/02fbaf0ed9120a8f95155e63de42459f230584aa/python/tvm/relay/qnn/op/legalizations.py#L350-L359 +* Inspecting `Target` inside the definition a strategy: https://github.com/apache/tvm/blob/b542724873140bb051492530d97a78b9b7b7983d/python/tvm/relay/op/strategy/arm_cpu.py#L232 +* Processing bespoke Compiler arguments: https://github.com/apache/tvm/blob/d2db9cb0d839e32778f461b77e59f6418282a511/src/relay/backend/contrib/cmsisnn/compiler_attrs.cc#L47-L70 +* Registered as a `PackedFunc` (https://github.com/apache/tvm/blob/24e5498021cecca2fe7d44149ce90efe28b6d930/python/tvm/topi/x86/utils.py#L21-L34) and then used as part of `Op` processing: https://github.com/apache/tvm/blob/24e5498021cecca2fe7d44149ce90efe28b6d930/src/relay/qnn/op/requantize_config.h#L58-L73 + +This RFC aims to standardise the way in which we convert `Target` attributes into architectural features by processing them ahead of time. + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +Two additional pre-processors can be added to the `Target`, for users to preprocess architectural information when the `Target` is created: +* Architecture Pre-processing - maps `Target` `attrs` to a new `arch` object +* Keys Pre-processing - maps `Target` `attrs` and `keys` to a new set of `keys` + +These new preprocessors will be illustrated using examples targeting TVM for Arm(R) Cortex(R)-M4. + +## Architecture Pre-processing +```c++ +TVM_REGISTER_TARGET_KIND("c", kDLCPU) + .set_arch_preprocessor(MyArchPreprocessor) +``` + +This takes the `attrs` from `Target` and converts them into an object representing the architectural features of the `Target`, which can then be accessed using the `GetArch` method similar to `GetAttr`: + +```c++ +Target my_target("c -mcpu=cortex-m4"); +my_target->GetArch<Bool>("is_aarch64", false); // false +my_target->GetArch<Bool>("has_dsp", false); // true +``` + +```python +my_target = Target("c -mcpu=cortex-m4") +my_target.arch.is_aarch64 // false +my_target.arch.has_dsp // true +``` + +## Keys Pre-processing + +```c++ +TVM_REGISTER_TARGET_KIND("c", kDLCPU) + .set_keys_preprocessor(MyKeysPreprocessor) +``` + +This takes the `attrs` from `Target` and maps them to relevant `keys` for use when selecting schedules: + +```c++ +Target my_target("c -mcpu=cortex-m4"); +my_target->keys; // ["arm_cpu", "cpu"] <-- "cpu" is taken from default keys and merged by the pre-preprocessor +``` + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +Currently, there is a single `preprocessor` which takes an input of `attrs` and expects the same `attrs` returned with pre-processing applied: + +https://github.com/apache/tvm/blob/d2db9cb0d839e32778f461b77e59f6418282a511/src/target/target.cc#L810-L814 + +In extension to this, a series of new pre-processors will be defined: + +```c++ +using TargetAttrs = Map<String, ObjectRef>; +using TargetArch = Map<String, ObjectRef>; +using TargetKeys = Array<String>; + +using FTVMAttrPreprocessor = runtime::TypedPackedFunc<TargetAttrs(TargetAttrs)>; +using FTVMArchPreprocessor = runtime::TypedPackedFunc<TargetArch(TargetAttrs)>; +using FTVMKeysPreprocessor = runtime::TypedPackedFunc<TargetKeys(TargetAttrs, TargetKeys)>; Review Comment: Hmm, I don't see the overlap, taking the example of: ``` TVM_REGISTER_TARGET_TAG("raspberry-pi/4b-aarch64") .set_config({{"kind", String("llvm")}, {"mtriple", String("aarch64-linux-gnu")}, {"mcpu", String("cortex-a72")}, {"mattr", Array<String>{"+neon"}}, {"num-cores", Integer(4)}, {"host", Map<String, ObjectRef>{{"kind", String("llvm")}, {"mtriple", String("aarch64-linux-gnu")}, {"mcpu", String("cortex-a72")}, {"mattr", Array<String>{"+neon"}}, {"num-cores", Integer(4)}}}}); ``` These are pre-configured `Target`s with various `mtriple`, `mcpu` and `mattr` attributes already set - once pre-processed these can produce a set of architecture features for subsequent steps, such as replacing this check in the operator strategy: https://github.com/apache/tvm/blob/f88a10fb00419c51a116a63f931a98d8286b23de/python/tvm/relay/op/strategy/arm_cpu.py#L232-L245 Other tagged `Target`s will likely have the same `mattr` and `mcpu`, thus rather than trying to hand craft the permutations each time, the pre-processor will 😸 -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
