oneapi-src / level-zero-spec

MIT License
17 stars 25 forks source link

Support decoding L0 Tracer Metrics #287

Open matcabral opened 3 months ago

matcabral commented 3 months ago

Summary

Extend the support of tracer metrics (https://github.com/oneapi-src/level-zero-spec/issues/285) to allow decoding raw events.

Details

Motivation

Extend users visibility of the raw data collected to allow retrieving in a format that allows parsing.

Interoperability with Other APIs

Raw data retrieved by zetMetricTracerReadDataExp() can be used as input to an API that decodes it to a format that allows parsing.

Proposed APIs

New Enumerations

Extend the metrics types https://spec.oneapi.io/level-zero/latest/tools/api.html#_CPPv417zet_metric_type_t

zet_metric_type_t {
...
 ZET_METRIC_TYPE_EXP_EVENT_NO_VALUE   
Metric type:  have only timestamp and value has no meaning.
ZET_METRIC_TYPE_EXP_EVENT_START
Metric type: the first event of a start/stop event pair.
ZET_METRIC_TYPE_EXP_EVENT_END
Metric type: the second event of a start/stop event pair.
ZET_METRIC_TYPE_EXP_EVENT_INSTANT
Metric type: instance event (non-paired).
ZET_METRIC_TYPE_EXP_EVENT_ MONOTHONIC_WRAPS_VALUE
Metric type: value of the event is a monotonic increasing value that can wrap around.
}

New Handles

zet_metric_decoder_exp_handle_t

Metric tracer decoder handle

New Structures

zet_metric_entry_exp_t

   typedef struct _zet_metric_entry_exp_t {
    zet_value_t value;
    uint64_t timeStamp;
    uint32_t metricIndex;
} zet_metric_entry_exp_t;
Attribute Description
value [out] value of the decodable metric entry or event. Number is meaningful based on the metric type
timeStamp [out] timestamp at which the event happened in the trace
metricIndex [out] index to the decodable metric handle in the input array (phMetric) in zetMetricTracerDecode()

New Functions

zetMetricDecoderCreateExp

ze_result_t  zetMetricDecoderCreateExp(zet_metric_tracer_exp_handle_t hMetricTracer,  zet_metric_decoder_exp_handle_t *phMetricDecoder);

Create a metric decoder for a given metric tracer.

Parameter Description
hMetricTracer [in] handle of the metric tracer object
phMetricDecoder [in] handle of the metric decoder object

zetMetricDecoderDestroyExp

ze_result_t  zetMetricDecoderDestroyExp(zet_metric_decoder_exp_handle_t hMetricDecoder);

Destroy the metric decoder.

Parameter Description
hMetricDecoder [in] handle of the metric decoder object

zetMetricDecoderGetDecodableMetricsExp

ze_result_t zetMetricDecoderGetDecodableMetricsExp(zet_metric_decoder_exp_handle_t    hMetricDecoder, uint32_t *pCount, zet_metric_handle_t *phMetrics);

Return the list of the decodable metrics that can be collected in the tracer for the which the metric decoder handle was provided. The decodable metrics handles returned by this API are only valid to decode metrics raw data with zetMetricTracerDecodeExp(). Decodable metric handles are not valid to compare with metrics handles included in metric groups.

Parameter Description
hMetricDecoder [in] handle of the metrics decoder object
pCount [in,out] pointer to number of decodable metric in the hMetricDecoder handle. If count is zero, then the driver shall update the value with the total number of decodable metrics available in the decoder. if count is greater than zero but less than the total number of decodable metrics available in the decoder, then only that number will be returned. if count is greater than the number of decodable metrics available in the decoder, then the driver shall update the value with the actual number of decodable metrics available.
phMetrics [in,out] [range(0, pCount)] array of handles of decodable metrics in the hMetricDecoder handle provided

zetMetricTracerDecodeExp

ze_result_t zetMetricTracerDecodeExp(zet_metric_decoder_exp_handle_t    hMetricDecoder,  size_t *prawDataSize, const uint8_t *pRawData, uint32_t metricCount, zet_metric_handle_t *phMetric, uint32_t *pMetricEntriesCount, ze_metric_entry_exp_t   * pMetricEntries);

Decode raw events collected from a tracer into list of ze_metric_entry_exp_t

Parameter Description
hMetricDecoder [in] handle of the metrics decoder object
prawDataSize [in,out] size in bytes of raw data buffer. If pMetricEntriesCount is greater than zero but less than total number of decodable metrics available in the raw data buffer, then driver shall update this value with actual number of raw data bytes processed.
pRawData [in][range(0, rawDataSize)] buffer of raw data to decode
metricCount [in] number of decodable metrics in the tracer for which the hMetricDecoder handle was provided. See zetMetricDecoderGetDecodableMetricsExp(). If metricCount is greater than zero but less than the number decodable metrics available in the raw data buffer, then driver shall only decode those
phMetric [in] [range(0, metricCount)] array of handles of decodable metrics in the decoder for which the hMetricDecoder handle was provided. Metrics handles are expected to be for decodable metrics, see zetMetricDecoderGetDecodableMetrics ()
pMetricEntriesCount [in,out] pointer to number of decodable metric entries to be decoded. If count is zero, then the driver shall update the value with the total number of decodable metric entries to be decoded. If count is greater than zero but less than the total number available in the raw data, then only that number of results will be decoded. if count is greater than the number available in the raw data buffer, then the driver shall update the value with the actual number of decodable metric entries to be decoded
pMetricEntries [in,out] [in,out][optional][range(0, * pMetricEntriesCount)] buffer of decoded metric entries

Usage Example

Extend example provided in https://github.com/oneapi-src/level-zero-spec/issues/285 with decoder APIs

    ... 
    zetMetricTracerCreateExp(hContext, hDevice, 1, hMetricGroup , &tracerDescriptor, hNotificationEvent, &hMetricTracer);
    // create decoder 

    zet_metric_decoder_exp_handle_t hMetricDecoder;
    zetMetricDecoderCreateExp( hMetricTracer,  &hMetricDecoder);

   //get decodable metrics

   uint32_t numDecodableMetrics=0;
   ze_result_t zetMetricDecoderGetDecodableMetricsExp(hMetricDecoder, &numDecodableMetrics, nullptr);
   std::vector<zet_metric_handle_t>decodableMetrics(numDecodableMetrics);
   ze_result_t zetMetricDecoderGetDecodableMetricsExp(hMetricDecoder, &numDecodableMetrics, decodableMetrics);

    zetMetricTracerEnableExp(hMetricTracer, true);
    workload(hDevice);
    size_t rawDataSize = 0;
    zetMetricTracerReadDataExp(hMetricTracer, &rawDataSize, nullptr);
    uint8_t* rawData = malloc(rawDataSize);
    zetMetricTracerReadDataExp(hMetricTracer, &rawDataSize, rawData);

   // decode
   uint32_t numEntries =0;
   zetMetricTracerDecodeExp(hMetricDecoder,  &prawDataSize, pRawData, numDecodableMetrics, decodableMetrics, 
   &numEntries, nullptr);
   std::vector<ze_metric_entry_exp_t > decodedEntries(numEntries)
    zetMetricTracerDecodeExp(hMetricDecoder,  &prawDataSize, pRawData, numDecodableMetrics, decodableMetrics, 
   &numEntries, decodedEntries);

    for (uint32_t index = 0; index < numEntries; index++) {
        ze_metric_entry_exp_t metricEntry = decodedEntries[index];
        zet_metric_properties_t metricProperties = {};
       zetMetricGetProperties(decodableMetrics[metricEntry.metricIndex], &metricProperties);
        printf ("Component: %s .Decodable metric name: %s ", metricProperties.component,  metricProperties.name);
        switch (metricProperties.resultType) {
        case ZET_VALUE_TYPE_UINT32:
        case ZET_VALUE_TYPE_UINT8:
        case ZET_VALUE_TYPE_UINT16:
            printf "\t value: %lu \n" << metricEntry.value.ui32;
          break;
        case ZET_VALUE_TYPE_UINT64:
            printf "\t value: %llu \n" << metricEntry.value.ui64;
          break;
        case ZET_VALUE_TYPE_FLOAT32:
            printf "\t value: %f \n" << metricEntry.value.fp32;
          break;
        case ZET_VALUE_TYPE_FLOAT64:
            printf "\t value: %f \n" << metricEntry.value.fp64;
          break;
        case ZET_VALUE_TYPE_BOOL8:
     if( metricEntry.value.b8 )
                    printf(" Value: true\n" );
                else
                    printf(" Value: false\n" );
                break;
          break;
        default:
         break;
        }
       }

    // Close and cleanup

    zetMetricTracerDisableExp(hMetricTracer, true);
    zetMetricDecoderDestroyExp(hMetricDecoder);
    zetMetricTracerDestroyExp(hMetricTracer);
    free(rawData);
matcabral commented 3 months ago

@wdamon-intel