这个函数执行图切分与调度,你的计算图将被切分成一系列子图,并被调度到不同设备上。 调度的逻辑分为自动控制的部分以及手动覆盖的部分,你可以使用 QuantizationSetting 来向这个函数传递手动调度表 从而覆盖 PPQ 的调度逻辑。 注意:这个函数依据调度器和 TargetPlatform 平台的不同而产生行为差异,生成不同的调度计划。 This function will cut your graph into a series of subgraph and send them to different device. PPQ provides
(
graph: BaseGraph, platform: TargetPlatform,
dispatcher: Union[str, GraphDispatcher] = 'conservative',
dispatching_table: DispatchingTable = None)
| 642 | |
| 643 | |
| 644 | def dispatch_graph( |
| 645 | graph: BaseGraph, platform: TargetPlatform, |
| 646 | dispatcher: Union[str, GraphDispatcher] = 'conservative', |
| 647 | dispatching_table: DispatchingTable = None) -> BaseGraph: |
| 648 | """这个函数执行图切分与调度,你的计算图将被切分成一系列子图,并被调度到不同设备上。 |
| 649 | 调度的逻辑分为自动控制的部分以及手动覆盖的部分,你可以使用 QuantizationSetting 来向这个函数传递手动调度表 从而覆盖 PPQ 的调度逻辑。 |
| 650 | |
| 651 | 注意:这个函数依据调度器和 TargetPlatform 平台的不同而产生行为差异,生成不同的调度计划。 |
| 652 | |
| 653 | This function will cut your graph into a series of subgraph and send them to different device. |
| 654 | PPQ provides an automatic dispatcher which, will generate different dispatching scheme on your TargetPlatform. |
| 655 | A dispatching table can be passed via QuantizationSetting to override |
| 656 | the default dispatching logic of ppq dispatcher manually. |
| 657 | """ |
| 658 | dispatching_override = dispatching_table |
| 659 | quantizer = PFL.Quantizer(platform=platform, graph=graph) # 初始化一个 quantizer 没有很大代价... |
| 660 | |
| 661 | if isinstance(dispatcher, str): |
| 662 | dispatcher = dispatcher.lower() |
| 663 | if dispatcher not in DISPATCHER_TABLE: |
| 664 | raise ValueError(f'Can not found dispatcher type "{dispatcher}", check your input again.') |
| 665 | dispatcher = DISPATCHER_TABLE[dispatcher](graph) |
| 666 | else: |
| 667 | if not isinstance(dispatcher, GraphDispatcher): |
| 668 | raise TypeError('Parameter "dispachter" of function ppq.api.dispatch_graph must be String or GraphDispatcher, ' |
| 669 | f'however {type(dispatcher)} was given.') |
| 670 | dispatcher = dispatcher |
| 671 | |
| 672 | assert isinstance(dispatcher, GraphDispatcher) |
| 673 | assert isinstance(quantizer, BaseQuantizer) |
| 674 | quant_types = quantizer.quant_operation_types |
| 675 | dispatching_table = dispatcher.dispatch( |
| 676 | graph=graph, quant_types=quant_types, |
| 677 | quant_platform=TargetPlatform.UNSPECIFIED, # MUST BE UNSPECIFIED, 这里的意思是交由 Quantizer 决定是否量化这个算子 |
| 678 | fp32_platform=TargetPlatform.FP32, |
| 679 | SOI_platform=TargetPlatform.SOI) |
| 680 | |
| 681 | # override dispatching result |
| 682 | if dispatching_override is not None: |
| 683 | if not isinstance(dispatching_override, DispatchingTable): |
| 684 | raise TypeError('Parameter "dispatching_table" of function ppq.api.dispatch_graph must be DispatchingTable, ' |
| 685 | f'however {type(dispatching_override)} was given.') |
| 686 | |
| 687 | for opname, platform in dispatching_override.dispatchings.items(): |
| 688 | if opname not in graph.operations: continue |
| 689 | assert isinstance(platform, int), ( |
| 690 | f'Your dispatching table contains a invalid setting of operation {opname}, ' |
| 691 | 'All platform setting given in dispatching table is expected given as int, ' |
| 692 | f'however {type(platform)} was given.') |
| 693 | dispatching_table[opname] = TargetPlatform(platform) |
| 694 | |
| 695 | for operation in graph.operations.values(): |
| 696 | assert operation.name in dispatching_table, ( |
| 697 | f'Internal Error, Can not find operation {operation.name} in dispatching table.') |
| 698 | operation.platform = dispatching_table[operation.name] |
| 699 | return graph |
| 700 | |
| 701 |
no test coverage detected