mirror of
https://github.com/saymrwulf/onnxruntime.git
synced 2026-06-08 00:23:03 +00:00
1. Fix static analysis warnings found by VC++ 2. Add a new pipeline for static analysis 3. Merge all the windows CI build into one single yaml file.(Easier to queue them all). 4. Make DNNL build faster by disabling building the tests and examples. 5. Enable custom op unitest.
355 lines
14 KiB
C++
355 lines
14 KiB
C++
// Copyright (c) Microsoft Corporation. All rights reserved.
|
|
// Licensed under the MIT License.
|
|
|
|
#include "eparser.h"
|
|
|
|
// Get the metadata for the event.
|
|
|
|
// Get the length of the property data. For MOF-based events, the size is inferred from the data type
|
|
// of the property. For manifest-based events, the property can specify the size of the property value
|
|
// using the length attribute. The length attribue can specify the size directly or specify the name
|
|
// of another property in the event data that contains the size. If the property does not include the
|
|
// length attribute, the size is inferred from the data type. The length will be zero for variable
|
|
// length, null-terminated strings and structures.
|
|
|
|
DWORD GetPropertyLength(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, USHORT i, PUSHORT PropertyLength);
|
|
|
|
// Get the size of the array. For MOF-based events, the size is specified in the declaration or using
|
|
// the MAX qualifier. For manifest-based events, the property can specify the size of the array
|
|
// using the count attribute. The count attribue can specify the size directly or specify the name
|
|
// of another property in the event data that contains the size.
|
|
|
|
DWORD GetArraySize(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, USHORT i, PUSHORT ArraySize);
|
|
|
|
// Both MOF-based events and manifest-based events can specify name/value maps. The
|
|
// map values can be integer values or bit values. If the property specifies a value
|
|
// map, get the map.
|
|
|
|
DWORD GetMapInfo(PEVENT_RECORD pEvent, LPWSTR pMapName, DWORD DecodingSource, PEVENT_MAP_INFO& pMapInfo);
|
|
|
|
// Print the property.
|
|
template <typename T>
|
|
PBYTE PrintProperties(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, DWORD PointerSize, USHORT i, PBYTE pUserData,
|
|
PBYTE pEndOfUserData, const T& t) {
|
|
TDHSTATUS status = ERROR_SUCCESS;
|
|
USHORT PropertyLength = 0;
|
|
DWORD FormattedDataSize = 0;
|
|
USHORT UserDataConsumed = 0;
|
|
LPWSTR pFormattedData = NULL;
|
|
DWORD LastMember = 0; // Last member of a structure
|
|
USHORT ArraySize = 0;
|
|
PEVENT_MAP_INFO pMapInfo = NULL;
|
|
|
|
// Get the length of the property.
|
|
|
|
status = GetPropertyLength(pEvent, pInfo, i, &PropertyLength);
|
|
if (ERROR_SUCCESS != status) {
|
|
wprintf(L"GetPropertyLength failed.\n");
|
|
pUserData = NULL;
|
|
goto cleanup;
|
|
}
|
|
|
|
// Get the size of the array if the property is an array.
|
|
|
|
status = GetArraySize(pEvent, pInfo, i, &ArraySize);
|
|
|
|
for (USHORT k = 0; k < ArraySize; k++) {
|
|
// If the property is a structure, print the members of the structure.
|
|
|
|
if ((pInfo->EventPropertyInfoArray[i].Flags & PropertyStruct) == PropertyStruct) {
|
|
LastMember = pInfo->EventPropertyInfoArray[i].structType.StructStartIndex +
|
|
pInfo->EventPropertyInfoArray[i].structType.NumOfStructMembers;
|
|
|
|
for (USHORT j = pInfo->EventPropertyInfoArray[i].structType.StructStartIndex; j < LastMember; j++) {
|
|
pUserData = PrintProperties(pEvent, pInfo, PointerSize, j, pUserData, pEndOfUserData, t);
|
|
if (NULL == pUserData) {
|
|
wprintf(L"Printing the members of the structure failed.\n");
|
|
pUserData = NULL;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
} else {
|
|
// Get the name/value mapping if the property specifies a value map.
|
|
|
|
status =
|
|
GetMapInfo(pEvent, (PWCHAR)((PBYTE)(pInfo) + pInfo->EventPropertyInfoArray[i].nonStructType.MapNameOffset),
|
|
pInfo->DecodingSource, pMapInfo);
|
|
|
|
if (ERROR_SUCCESS != status) {
|
|
wprintf(L"GetMapInfo failed\n");
|
|
pUserData = NULL;
|
|
goto cleanup;
|
|
}
|
|
|
|
// Get the size of the buffer required for the formatted data.
|
|
|
|
status = TdhFormatProperty(pInfo, pMapInfo, PointerSize, pInfo->EventPropertyInfoArray[i].nonStructType.InType,
|
|
pInfo->EventPropertyInfoArray[i].nonStructType.OutType, PropertyLength,
|
|
(USHORT)(pEndOfUserData - pUserData), pUserData, &FormattedDataSize, pFormattedData,
|
|
&UserDataConsumed);
|
|
|
|
if (ERROR_INSUFFICIENT_BUFFER == status) {
|
|
if (pFormattedData) {
|
|
free(pFormattedData);
|
|
pFormattedData = NULL;
|
|
}
|
|
|
|
pFormattedData = (LPWSTR)malloc(FormattedDataSize);
|
|
if (pFormattedData == NULL) {
|
|
wprintf(L"Failed to allocate memory for formatted data (size=%lu).\n", FormattedDataSize);
|
|
status = ERROR_OUTOFMEMORY;
|
|
pUserData = NULL;
|
|
goto cleanup;
|
|
}
|
|
|
|
// Retrieve the formatted data.
|
|
|
|
status = TdhFormatProperty(pInfo, pMapInfo, PointerSize, pInfo->EventPropertyInfoArray[i].nonStructType.InType,
|
|
pInfo->EventPropertyInfoArray[i].nonStructType.OutType, PropertyLength,
|
|
(USHORT)(pEndOfUserData - pUserData), pUserData, &FormattedDataSize, pFormattedData,
|
|
&UserDataConsumed);
|
|
}
|
|
|
|
if (ERROR_SUCCESS == status) {
|
|
t((PWCHAR)((PBYTE)(pInfo) + pInfo->EventPropertyInfoArray[i].NameOffset), pFormattedData);
|
|
pUserData += UserDataConsumed;
|
|
} else {
|
|
wprintf(L"TdhFormatProperty failed with %lu.\n", status);
|
|
pUserData = NULL;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
|
|
if (pFormattedData) {
|
|
free(pFormattedData);
|
|
pFormattedData = NULL;
|
|
}
|
|
|
|
if (pMapInfo) {
|
|
free(pMapInfo);
|
|
pMapInfo = NULL;
|
|
}
|
|
|
|
return pUserData;
|
|
}
|
|
|
|
DWORD GetPropertyLength(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, USHORT i, PUSHORT PropertyLength) {
|
|
DWORD status = ERROR_SUCCESS;
|
|
PROPERTY_DATA_DESCRIPTOR DataDescriptor;
|
|
DWORD PropertySize = 0;
|
|
|
|
// If the property is a binary blob and is defined in a manifest, the property can
|
|
// specify the blob's size or it can point to another property that defines the
|
|
// blob's size. The PropertyParamLength flag tells you where the blob's size is defined.
|
|
|
|
if ((pInfo->EventPropertyInfoArray[i].Flags & PropertyParamLength) == PropertyParamLength) {
|
|
DWORD Length = 0; // Expects the length to be defined by a UINT16 or UINT32
|
|
DWORD j = pInfo->EventPropertyInfoArray[i].lengthPropertyIndex;
|
|
ZeroMemory(&DataDescriptor, sizeof(PROPERTY_DATA_DESCRIPTOR));
|
|
DataDescriptor.PropertyName = (ULONGLONG)((PBYTE)(pInfo) + pInfo->EventPropertyInfoArray[j].NameOffset);
|
|
DataDescriptor.ArrayIndex = ULONG_MAX;
|
|
status = TdhGetPropertySize(pEvent, 0, NULL, 1, &DataDescriptor, &PropertySize);
|
|
status = TdhGetProperty(pEvent, 0, NULL, 1, &DataDescriptor, PropertySize, (PBYTE)&Length);
|
|
*PropertyLength = (USHORT)Length;
|
|
} else {
|
|
if (pInfo->EventPropertyInfoArray[i].length > 0) {
|
|
*PropertyLength = pInfo->EventPropertyInfoArray[i].length;
|
|
} else {
|
|
// If the property is a binary blob and is defined in a MOF class, the extension
|
|
// qualifier is used to determine the size of the blob. However, if the extension
|
|
// is IPAddrV6, you must set the PropertyLength variable yourself because the
|
|
// EVENT_PROPERTY_INFO.length field will be zero.
|
|
|
|
if (TDH_INTYPE_BINARY == pInfo->EventPropertyInfoArray[i].nonStructType.InType &&
|
|
TDH_OUTTYPE_IPV6 == pInfo->EventPropertyInfoArray[i].nonStructType.OutType) {
|
|
*PropertyLength = (USHORT)sizeof(IN6_ADDR);
|
|
} else if (TDH_INTYPE_UNICODESTRING == pInfo->EventPropertyInfoArray[i].nonStructType.InType ||
|
|
TDH_INTYPE_ANSISTRING == pInfo->EventPropertyInfoArray[i].nonStructType.InType ||
|
|
(pInfo->EventPropertyInfoArray[i].Flags & PropertyStruct) == PropertyStruct) {
|
|
*PropertyLength = pInfo->EventPropertyInfoArray[i].length;
|
|
} else {
|
|
wprintf(L"Unexpected length of 0 for intype %ud and outtype %ud\n",
|
|
pInfo->EventPropertyInfoArray[i].nonStructType.InType,
|
|
pInfo->EventPropertyInfoArray[i].nonStructType.OutType);
|
|
|
|
status = ERROR_EVT_INVALID_EVENT_DATA;
|
|
goto cleanup;
|
|
}
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
|
|
return status;
|
|
}
|
|
|
|
DWORD GetArraySize(PEVENT_RECORD pEvent, PTRACE_EVENT_INFO pInfo, USHORT i, PUSHORT ArraySize) {
|
|
DWORD status = ERROR_SUCCESS;
|
|
PROPERTY_DATA_DESCRIPTOR DataDescriptor;
|
|
DWORD PropertySize = 0;
|
|
|
|
if ((pInfo->EventPropertyInfoArray[i].Flags & PropertyParamCount) == PropertyParamCount) {
|
|
DWORD Count = 0; // Expects the count to be defined by a UINT16 or UINT32
|
|
DWORD j = pInfo->EventPropertyInfoArray[i].countPropertyIndex;
|
|
ZeroMemory(&DataDescriptor, sizeof(PROPERTY_DATA_DESCRIPTOR));
|
|
DataDescriptor.PropertyName = (ULONGLONG)((PBYTE)(pInfo) + pInfo->EventPropertyInfoArray[j].NameOffset);
|
|
DataDescriptor.ArrayIndex = ULONG_MAX;
|
|
status = TdhGetPropertySize(pEvent, 0, NULL, 1, &DataDescriptor, &PropertySize);
|
|
status = TdhGetProperty(pEvent, 0, NULL, 1, &DataDescriptor, PropertySize, (PBYTE)&Count);
|
|
*ArraySize = (USHORT)Count;
|
|
} else {
|
|
*ArraySize = pInfo->EventPropertyInfoArray[i].count;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
DWORD GetMapInfo(PEVENT_RECORD pEvent, LPWSTR pMapName, DWORD DecodingSource, PEVENT_MAP_INFO& pMapInfo) {
|
|
DWORD status = ERROR_SUCCESS;
|
|
DWORD MapSize = 0;
|
|
|
|
// Retrieve the required buffer size for the map info.
|
|
|
|
status = TdhGetEventMapInformation(pEvent, pMapName, pMapInfo, &MapSize);
|
|
|
|
if (ERROR_INSUFFICIENT_BUFFER == status) {
|
|
pMapInfo = (PEVENT_MAP_INFO)malloc(MapSize);
|
|
if (pMapInfo == NULL) {
|
|
wprintf(L"Failed to allocate memory for map info (size=%lu).\n", MapSize);
|
|
status = ERROR_OUTOFMEMORY;
|
|
goto cleanup;
|
|
}
|
|
|
|
// Retrieve the map info.
|
|
|
|
status = TdhGetEventMapInformation(pEvent, pMapName, pMapInfo, &MapSize);
|
|
}
|
|
|
|
if (ERROR_SUCCESS == status) {
|
|
if (DecodingSourceXMLFile == DecodingSource) {
|
|
abort();
|
|
}
|
|
} else {
|
|
if (ERROR_NOT_FOUND == status) {
|
|
status = ERROR_SUCCESS; // This case is okay.
|
|
} else {
|
|
wprintf(L"TdhGetEventMapInformation failed with 0x%x.\n", status);
|
|
}
|
|
}
|
|
|
|
cleanup:
|
|
|
|
return status;
|
|
}
|
|
|
|
LoggingEventRecord LoggingEventRecord::CreateLoggingEventRecord(EVENT_RECORD* pEvent, DWORD& status) {
|
|
LoggingEventRecord ret;
|
|
ret.event_record_ = pEvent;
|
|
status = ERROR_SUCCESS;
|
|
DWORD BufferSize = 0;
|
|
|
|
// Retrieve the required buffer size for the event metadata.
|
|
|
|
status = TdhGetEventInformation(pEvent, 0, NULL, nullptr, &BufferSize);
|
|
|
|
if (ERROR_INSUFFICIENT_BUFFER != status) return ret;
|
|
ret.buffer_.resize(BufferSize);
|
|
// Retrieve the event metadata.
|
|
status = TdhGetEventInformation(pEvent, 0, NULL, ret.GetEventInfo(), &BufferSize);
|
|
return ret;
|
|
}
|
|
|
|
void OrtEventHandler(EVENT_RECORD* pEvent, void* pContext) {
|
|
ProfilingInfo& info = *(ProfilingInfo*)pContext;
|
|
DWORD status = ERROR_SUCCESS;
|
|
|
|
LoggingEventRecord record = LoggingEventRecord::CreateLoggingEventRecord(pEvent, status);
|
|
if (ERROR_SUCCESS != status) {
|
|
if (status == ERROR_NOT_FOUND) return;
|
|
wprintf(L"GetEventInformation failed with %lu\n", status);
|
|
abort();
|
|
}
|
|
DWORD PointerSize = 0;
|
|
if (EVENT_HEADER_FLAG_32_BIT_HEADER == (pEvent->EventHeader.Flags & EVENT_HEADER_FLAG_32_BIT_HEADER)) {
|
|
PointerSize = 4;
|
|
} else {
|
|
PointerSize = 8;
|
|
}
|
|
|
|
PTRACE_EVENT_INFO pInfo = record.GetEventInfo();
|
|
const wchar_t* name = record.GetTaskName();
|
|
if (wcscmp(name, L"OpEnd") == 0) {
|
|
if (!info.session_started || info.session_ended) return;
|
|
PBYTE pUserData = (PBYTE)pEvent->UserData;
|
|
PBYTE pEndOfUserData = (PBYTE)pEvent->UserData + pEvent->UserDataLength;
|
|
|
|
// Print the event data for all the top-level properties. Metadata for all the
|
|
// top-level properties come before structure member properties in the
|
|
// property information array.
|
|
std::wstring opname;
|
|
long time_spent_in_this_op = 0;
|
|
for (USHORT i = 0; i < pInfo->TopLevelPropertyCount; i++) {
|
|
pUserData = PrintProperties(pEvent, pInfo, PointerSize, i, pUserData, pEndOfUserData,
|
|
[&opname, &time_spent_in_this_op](const wchar_t* key, wchar_t* value) {
|
|
if (wcscmp(key, L"op_name") == 0) {
|
|
opname = value;
|
|
} else if (wcscmp(key, L"time") == 0) {
|
|
time_spent_in_this_op = wcstol(value, nullptr, 10);
|
|
} else {
|
|
wprintf(key);
|
|
abort();
|
|
}
|
|
});
|
|
if (NULL == pUserData) {
|
|
wprintf(L"Printing top level properties failed.\n");
|
|
abort();
|
|
}
|
|
}
|
|
auto iter = info.op_stat.find(opname);
|
|
if (iter == info.op_stat.end()) {
|
|
OpStat s;
|
|
s.name = opname;
|
|
s.count = 1;
|
|
s.total_time = time_spent_in_this_op;
|
|
info.op_stat[opname] = s;
|
|
} else {
|
|
OpStat& s = iter->second;
|
|
++s.count;
|
|
s.total_time += time_spent_in_this_op;
|
|
}
|
|
} else if (wcscmp(name, L"OrtRun") == 0) {
|
|
if (!info.session_started || info.session_ended) return;
|
|
if (pInfo->EventDescriptor.Opcode == EVENT_TRACE_TYPE_START) {
|
|
info.op_start_time = pEvent->EventHeader.TimeStamp;
|
|
++info.ortrun_count;
|
|
} else if (pInfo->EventDescriptor.Opcode == EVENT_TRACE_TYPE_END) {
|
|
if (pEvent->EventHeader.TimeStamp.QuadPart < info.op_start_time.QuadPart) {
|
|
throw std::runtime_error("time error");
|
|
}
|
|
info.time_per_run.push_back(pEvent->EventHeader.TimeStamp.QuadPart - info.op_start_time.QuadPart);
|
|
++info.ortrun_end_count;
|
|
} else {
|
|
abort();
|
|
}
|
|
}
|
|
|
|
else if (wcscmp(name, L"OrtInferenceSessionActivity") == 0) {
|
|
if (pInfo->EventDescriptor.Opcode == EVENT_TRACE_TYPE_START) {
|
|
info.session_started = true;
|
|
} else if (pInfo->EventDescriptor.Opcode == EVENT_TRACE_TYPE_END) {
|
|
info.session_ended = true;
|
|
} else {
|
|
abort();
|
|
}
|
|
|
|
printf("OrtInferenceSessionActivity\n");
|
|
} else if (wcscmp(name, L"NodeNameMapping") == 0) {
|
|
// ignore
|
|
} else {
|
|
wprintf(L"unknown event:%s\n", name);
|
|
abort();
|
|
}
|
|
}
|