def handle_mark(self, time, mark):
    ' Handle a single trace item (scoped entry and exit).\n        Translates:\n          - Automatically generated HIDL traces into NNTRACE layers and phases\n          - SPEC:Switch phase during function into dummy items\n          - SPEC:Subtracting time when nesting is violated into "subtract"\n            markers\n          - CPU/Driver layer distinction based on whether the process is the\n            driver or an application\n        This function is called multiple times for a single application run,\n        afterwards the statistics can be calculated.\n    '
    if (mark[0] == 'B'):
        switch = False
        subtract = False
        if (('ANeuralNetworksEvent_free' in mark) or ('ANeuralNetworksExecution_free' in mark)):
            mark = mark.replace('_PT', '_PE')
        if ('getSupportedExtensions' in mark):
            mark = mark.replace('_PC', '_PI')
        elif ('[SW][NN_LA_PR]executeWithCompilation' in mark):
            mark = mark.replace('[SW]', '')
        if (MARKER_SWITCH in mark):
            switch = True
        if (MARKER_SUBTRACT in mark):
            subtract = True
        if switch:
            self.handle_mark(time, 'E')
            self.mytree.push_dummy(time)
        m = self.matcher.search(mark)
        if (m is None):
            tag = translate_hidl_mark_to_nn_and_tag(mark)
            if (tag is None):
                raise Exception(("Couldn't parse mark " + mark))
        else:
            tag = m.group(1)
        [_, layer, phase] = tag.split('_')
        if ((layer == LAYER_APPLICATION) and (phase in [PHASE_WARMUP, PHASE_BENCHMARK])):
            self.app_phase.push(phase)
        if (not self.is_driver):
            layer = layer.replace(LAYER_DRIVER, LAYER_CPU)
        else:
            layer = layer.replace(LAYER_CPU, LAYER_DRIVER)
        if ((layer == LAYER_APPLICATION) and (phase == PHASE_EXECUTION)):
            self.la_pe_counts[self.app_phase.current()] = (self.la_pe_counts.get(self.app_phase.current(), 0) + 1)
        self.mytree.push(time, mark, layer, phase, self.app_phase.current(), subtract)
    elif (mark[0] == 'E'):
        try:
            node = self.mytree.pop(time)
            if node.is_dummy():
                pass
            else:
                if ((node.layer == LAYER_APPLICATION) and (node.phase in [PHASE_WARMUP, PHASE_BENCHMARK])):
                    self.app_phase.pop()
                function = ((node.app_phase + '::') + get_function_name_from_mark(node.mark))
                self.begins_and_ends_ms[function] = (self.begins_and_ends_ms.get(function, []) + [[(float(node.start_time_s) * 1000.0), (float(node.end_time_s) * 1000.0)]])
        except IndexError as e:
            raise Exception('Unable to process a trace termination mark, please check that the collected trace are including full application lifecycles.\n') from e
Handle a single trace item (scoped entry and exit).
Translates:
  - Automatically generated HIDL traces into NNTRACE layers and phases
  - SPEC:Switch phase during function into dummy items
  - SPEC:Subtracting time when nesting is violated into "subtract"
    markers
  - CPU/Driver layer distinction based on whether the process is the
    driver or an application
This function is called multiple times for a single application run,
afterwards the statistics can be calculated.
def handle_mark(self, time, mark):
    ' Handle a single trace item (scoped entry and exit).\n        Translates:\n          - Automatically generated HIDL traces into NNTRACE layers and phases\n          - SPEC:Switch phase during function into dummy items\n          - SPEC:Subtracting time when nesting is violated into "subtract"\n            markers\n          - CPU/Driver layer distinction based on whether the process is the\n            driver or an application\n        This function is called multiple times for a single application run,\n        afterwards the statistics can be calculated.\n    '
    if (mark[0] == 'B'):
        switch = False
        subtract = False
        if (('ANeuralNetworksEvent_free' in mark) or ('ANeuralNetworksExecution_free' in mark)):
            mark = mark.replace('_PT', '_PE')
        if ('getSupportedExtensions' in mark):
            mark = mark.replace('_PC', '_PI')
        elif ('[SW][NN_LA_PR]executeWithCompilation' in mark):
            mark = mark.replace('[SW]', )
        if (MARKER_SWITCH in mark):
            switch = True
        if (MARKER_SUBTRACT in mark):
            subtract = True
        if switch:
            self.handle_mark(time, 'E')
            self.mytree.push_dummy(time)
        m = self.matcher.search(mark)
        if (m is None):
            tag = translate_hidl_mark_to_nn_and_tag(mark)
            if (tag is None):
                raise Exception(("Couldn't parse mark " + mark))
        else:
            tag = m.group(1)
        [_, layer, phase] = tag.split('_')
        if ((layer == LAYER_APPLICATION) and (phase in [PHASE_WARMUP, PHASE_BENCHMARK])):
            self.app_phase.push(phase)
        if (not self.is_driver):
            layer = layer.replace(LAYER_DRIVER, LAYER_CPU)
        else:
            layer = layer.replace(LAYER_CPU, LAYER_DRIVER)
        if ((layer == LAYER_APPLICATION) and (phase == PHASE_EXECUTION)):
            self.la_pe_counts[self.app_phase.current()] = (self.la_pe_counts.get(self.app_phase.current(), 0) + 1)
        self.mytree.push(time, mark, layer, phase, self.app_phase.current(), subtract)
    elif (mark[0] == 'E'):
        try:
            node = self.mytree.pop(time)
            if node.is_dummy():
                pass
            else:
                if ((node.layer == LAYER_APPLICATION) and (node.phase in [PHASE_WARMUP, PHASE_BENCHMARK])):
                    self.app_phase.pop()
                function = ((node.app_phase + '::') + get_function_name_from_mark(node.mark))
                self.begins_and_ends_ms[function] = (self.begins_and_ends_ms.get(function, []) + [[(float(node.start_time_s) * 1000.0), (float(node.end_time_s) * 1000.0)]])
        except IndexError as e:
            raise Exception('Unable to process a trace termination mark, please check that the collected trace are including full application lifecycles.\n') from e