def test_single_insertions(self, setup, insertion_point): if insertion_point.insertion_type in [ InsertionType.OPERATOR_PRE_HOOK, InsertionType.OPERATOR_POST_HOOK ]: hook = lambda x: x else: hook = BaseOp(lambda x: x) command = InsertionCommand(insertion_point, hook) self.compressed_model.register_insertion_command(command) self.compressed_model.commit_compression_changes() #pylint:disable=protected-access if insertion_point.insertion_type == InsertionType.OPERATOR_PRE_HOOK: ctx = self.compressed_model.get_tracing_context() assert ctx._pre_hooks[ command.insertion_point.ia_op_exec_context][0] is hook if insertion_point.insertion_type == InsertionType.OPERATOR_POST_HOOK: ctx = self.compressed_model.get_tracing_context() assert ctx._post_hooks[ command.insertion_point.ia_op_exec_context][0] is hook if insertion_point.insertion_type == InsertionType.NNCF_MODULE_PRE_OP: module = self.compressed_model.get_module_by_scope( command.insertion_point.ia_op_exec_context.scope_in_model) assert module.pre_ops["0"] is hook if insertion_point.insertion_type == InsertionType.NNCF_MODULE_POST_OP: module = self.compressed_model.get_module_by_scope( command.insertion_point.ia_op_exec_context.scope_in_model) assert module.post_ops["0"] is hook
class TestInsertionCommands: @pytest.fixture() def setup(self): self.compressed_model = NNCFNetwork( InsertionPointTestModel(), [ModelInputInfo([1, 1, 10, 10])]) # type: NNCFNetwork conv1_module_scope = Scope.from_str( 'InsertionPointTestModel/NNCFConv2d[conv1]') conv1_module_context = InputAgnosticOperationExecutionContext( '', conv1_module_scope, 0) point_for_conv1_weights = InsertionPoint( ia_op_exec_context=conv1_module_context, insertion_type=InsertionType.NNCF_MODULE_PRE_OP) point_for_conv1_inputs = InsertionPoint( ia_op_exec_context=conv1_module_context, insertion_type=InsertionType.NNCF_MODULE_PRE_OP) point_for_conv1_activations = InsertionPoint( ia_op_exec_context=conv1_module_context, insertion_type=InsertionType.NNCF_MODULE_POST_OP) conv2_module_scope = Scope.from_str( 'InsertionPointTestModel/NNCFConv2d[conv2]') conv2_module_context = InputAgnosticOperationExecutionContext( '', conv2_module_scope, 0) point_for_conv2_weights = InsertionPoint( ia_op_exec_context=conv2_module_context, insertion_type=InsertionType.NNCF_MODULE_PRE_OP) point_for_conv2_inputs = InsertionPoint( ia_op_exec_context=conv2_module_context, insertion_type=InsertionType.NNCF_MODULE_PRE_OP) point_for_conv2_activations = InsertionPoint( ia_op_exec_context=conv2_module_context, insertion_type=InsertionType.NNCF_MODULE_POST_OP) linear_op_scope = Scope.from_str('InsertionPointTestModel/linear_0') linear_op_context = InputAgnosticOperationExecutionContext( 'linear', linear_op_scope, 0) point_for_linear_weight_input = InsertionPoint( ia_op_exec_context=linear_op_context, insertion_type=InsertionType.OPERATOR_PRE_HOOK) point_for_linear_activation = InsertionPoint( ia_op_exec_context=linear_op_context, insertion_type=InsertionType.OPERATOR_POST_HOOK) relu_op_scope = Scope.from_str('InsertionPointTestModel/ReLU[relu]/relu') relu_op_context = InputAgnosticOperationExecutionContext( 'relu', relu_op_scope, 0) point_for_relu_inputs = InsertionPoint( ia_op_exec_context=relu_op_context, insertion_type=InsertionType.OPERATOR_PRE_HOOK) point_for_relu_activations = InsertionPoint( ia_op_exec_context=relu_op_context, insertion_type=InsertionType.OPERATOR_POST_HOOK) available_points = [ point_for_conv1_weights, point_for_conv2_weights, point_for_conv1_inputs, point_for_conv2_inputs, point_for_conv1_activations, point_for_conv2_activations, point_for_linear_activation, point_for_linear_weight_input, point_for_relu_activations, point_for_relu_inputs ] @pytest.mark.parametrize("insertion_point", available_points) def test_single_insertions(self, setup, insertion_point): if insertion_point.insertion_type in [ InsertionType.OPERATOR_PRE_HOOK, InsertionType.OPERATOR_POST_HOOK ]: hook = lambda x: x else: hook = BaseOp(lambda x: x) command = InsertionCommand(insertion_point, hook) self.compressed_model.register_insertion_command(command) self.compressed_model.commit_compression_changes() #pylint:disable=protected-access if insertion_point.insertion_type == InsertionType.OPERATOR_PRE_HOOK: ctx = self.compressed_model.get_tracing_context() assert ctx._pre_hooks[ command.insertion_point.ia_op_exec_context][0] is hook if insertion_point.insertion_type == InsertionType.OPERATOR_POST_HOOK: ctx = self.compressed_model.get_tracing_context() assert ctx._post_hooks[ command.insertion_point.ia_op_exec_context][0] is hook if insertion_point.insertion_type == InsertionType.NNCF_MODULE_PRE_OP: module = self.compressed_model.get_module_by_scope( command.insertion_point.ia_op_exec_context.scope_in_model) assert module.pre_ops["0"] is hook if insertion_point.insertion_type == InsertionType.NNCF_MODULE_POST_OP: module = self.compressed_model.get_module_by_scope( command.insertion_point.ia_op_exec_context.scope_in_model) assert module.post_ops["0"] is hook priority_types = ["same", "different"] insertion_types = InsertionType priority_test_cases = list( itertools.product(priority_types, insertion_types)) @staticmethod def check_order(iterable1: List, iterable2: List, ordering: List): for idx, order in enumerate(ordering): assert iterable1[idx] is iterable2[order] # pylint:disable=undefined-variable @pytest.mark.parametrize( "case", priority_test_cases, ids=[x[1].name + '-' + x[0] for x in priority_test_cases]) def test_priority(self, case, setup): #pylint:disable=too-many-branches priority_type = case[0] insertion_type = case[1] if insertion_type in [ InsertionType.NNCF_MODULE_PRE_OP, InsertionType.NNCF_MODULE_POST_OP ]: hook1 = BaseOp(lambda x: x) hook2 = BaseOp(lambda x: 2 * x) hook3 = BaseOp(lambda x: 3 * x) else: hook1 = lambda x: x hook2 = lambda x: 2 * x hook3 = lambda x: 3 * x if insertion_type == InsertionType.NNCF_MODULE_PRE_OP: point = self.point_for_conv2_weights elif insertion_type == InsertionType.NNCF_MODULE_POST_OP: point = self.point_for_conv1_activations elif insertion_type == InsertionType.OPERATOR_PRE_HOOK: point = self.point_for_linear_weight_input elif insertion_type == InsertionType.OPERATOR_POST_HOOK: point = self.point_for_relu_activations if priority_type == "same": # Same-priority commands will be executed in registration order command1 = InsertionCommand(point, hook1, OperationPriority.DEFAULT_PRIORITY) command2 = InsertionCommand(point, hook2, OperationPriority.DEFAULT_PRIORITY) command3 = InsertionCommand(point, hook3, OperationPriority.DEFAULT_PRIORITY) else: # Prioritized commands will be executed in ascending priority order command1 = InsertionCommand( point, hook1, OperationPriority.SPARSIFICATION_PRIORITY) command2 = InsertionCommand( point, hook2, OperationPriority.QUANTIZATION_PRIORITY) command3 = InsertionCommand(point, hook3, OperationPriority.DEFAULT_PRIORITY) self.compressed_model.register_insertion_command(command1) self.compressed_model.register_insertion_command(command2) self.compressed_model.register_insertion_command(command3) self.compressed_model.commit_compression_changes() hook_list = [hook1, hook2, hook3] if priority_type == "same": order = [0, 1, 2] elif priority_type == "different": order = [2, 0, 1] #pylint:disable=protected-access if insertion_type == InsertionType.OPERATOR_PRE_HOOK: ctx = self.compressed_model.get_tracing_context() self.check_order(ctx._pre_hooks[point.ia_op_exec_context], hook_list, order) if insertion_type == InsertionType.OPERATOR_POST_HOOK: ctx = self.compressed_model.get_tracing_context() self.check_order(ctx._post_hooks[point.ia_op_exec_context], hook_list, order) if insertion_type == InsertionType.NNCF_MODULE_PRE_OP: module = self.compressed_model.get_module_by_scope( point.ia_op_exec_context.scope_in_model) # Works because Pytorch ModuleDict is ordered self.check_order(list(module.pre_ops.values()), hook_list, order) if insertion_type == InsertionType.NNCF_MODULE_POST_OP: module = self.compressed_model.get_module_by_scope( point.ia_op_exec_context.scope_in_model) # Works because Pytorch ModuleDict is ordered self.check_order(list(module.post_ops.values()), hook_list, order)