/* * Copyright 2010-2019 NVIDIA Corporation. All rights reserved * * Sample CUPTI app to query domains and events supported by device * */ #include #include #include #include #if defined(WIN32) || defined(_WIN32) #define stricmp _stricmp #else #define stricmp strcasecmp #endif #ifndef EXIT_WAIVED #define EXIT_WAIVED 2 #endif #define NAME_SHORT 64 #define NAME_LONG 128 #define DESC_SHORT 512 #define DESC_LONG 2048 #define CATEGORY_LENGTH sizeof(CUpti_EventCategory) static unsigned int optionsFlag = 0; #define setOptionsFlag(bit) (optionsFlag |= (1< -getdomains : displays supported domains for specified device\n"); printf(" -device -getmetrics : displays supported metrics for specified device\n"); printf(" -device -domain -getevents : displays supported events for specified domain and device\n"); printf("Note: default device is 0 and default domain is first domain for device\n"); } // add a null terminator to the end of a string if the string // length equals the maximum length (as in that case there was no // room to write the null terminator) static void checkNullTerminator(char *str, size_t len, size_t max_len) { if (len >= max_len) { str[max_len - 1] = '\0'; } } int enumEventDomains(CUdevice dev) { CUptiResult ptiStatus = CUPTI_SUCCESS; CUpti_EventDomainID *domainId = NULL; ptiDomainData domainData; uint32_t maxDomains = 0, i = 0; size_t size = 0; ptiStatus = cuptiDeviceGetNumEventDomains(dev, &maxDomains); CHECK_CUPTI_ERROR(ptiStatus, "cuptiDeviceGetNumEventDomains"); if (maxDomains == 0) { printf("No domain is exposed by dev = %d\n", dev); ptiStatus = CUPTI_ERROR_UNKNOWN; goto Exit; } size = sizeof(CUpti_EventDomainID) * maxDomains; domainId = (CUpti_EventDomainID*)malloc(size); if (domainId == NULL) { printf("Failed to allocate memory to domain ID\n"); ptiStatus = CUPTI_ERROR_OUT_OF_MEMORY; goto Exit; } memset(domainId, 0, size); ptiStatus = cuptiDeviceEnumEventDomains(dev, &size, domainId); CHECK_CUPTI_ERROR(ptiStatus, "cuptiDeviceEnumEventDomains"); // enum domains for (i = 0; i < maxDomains; i++) { domainData.domainId = domainId[i]; // query domain name size = NAME_SHORT; ptiStatus = cuptiEventDomainGetAttribute(domainData.domainId, CUPTI_EVENT_DOMAIN_ATTR_NAME, &size, (void*)domainData.domainName); checkNullTerminator(domainData.domainName, size, NAME_SHORT); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventDomainGetAttribute"); // query num of profiled instances in the domain size = sizeof(domainData.profiledInstanceCnt); ptiStatus = cuptiDeviceGetEventDomainAttribute(dev, domainData.domainId, CUPTI_EVENT_DOMAIN_ATTR_INSTANCE_COUNT, &size, (void*)&domainData.profiledInstanceCnt); CHECK_CUPTI_ERROR(ptiStatus, "cuptiDeviceEventDomainGetAttribute"); // query total instances in the domain size = sizeof(domainData.totalInstanceCnt); ptiStatus = cuptiDeviceGetEventDomainAttribute(dev, domainData.domainId, CUPTI_EVENT_DOMAIN_ATTR_TOTAL_INSTANCE_COUNT, &size, (void*)&domainData.totalInstanceCnt); CHECK_CUPTI_ERROR(ptiStatus, "cuptiDeviceEventDomainGetAttribute"); size = sizeof(CUpti_EventCollectionMethod); ptiStatus = cuptiEventDomainGetAttribute(domainData.domainId, CUPTI_EVENT_DOMAIN_ATTR_COLLECTION_METHOD, &size, (void*)&domainData.eventCollectionMethod); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventDomainGetAttribute"); printf ("Domain# %u\n", i+1); printf ("Id = %d\n", domainData.domainId); printf ("Name = %s\n", domainData.domainName); printf ("Profiled instance count = %u\n", domainData.profiledInstanceCnt); printf ("Total instance count = %u\n", domainData.totalInstanceCnt); printf ("Event collection method = "); switch(domainData.eventCollectionMethod) { case CUPTI_EVENT_COLLECTION_METHOD_PM: printf("CUPTI_EVENT_COLLECTION_METHOD_PM\n"); break; case CUPTI_EVENT_COLLECTION_METHOD_SM: printf("CUPTI_EVENT_COLLECTION_METHOD_SM\n"); break; case CUPTI_EVENT_COLLECTION_METHOD_INSTRUMENTED: printf("CUPTI_EVENT_COLLECTION_METHOD_INSTRUMENTED\n"); break; case CUPTI_EVENT_COLLECTION_METHOD_NVLINK_TC: printf("CUPTI_EVENT_COLLECTION_METHOD_NVLINK_TC\n"); break; default: printf("\nError: Invalid event collection method!\n"); return -1; } } Exit: if (domainId) { free (domainId); } if (ptiStatus == CUPTI_SUCCESS) { return 0; } else { return -1; } } int enumEvents(CUpti_EventDomainID domainId) { ptiData eventData; CUptiResult ptiStatus = CUPTI_SUCCESS; CUpti_EventID *eventId = NULL; uint32_t maxEvents = 0; uint32_t i = 0; size_t size = 0; // query num of events available in the domain ptiStatus = cuptiEventDomainGetNumEvents(domainId, &maxEvents); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventDomainGetNumEvents"); size = sizeof(CUpti_EventID) * maxEvents; eventId = (CUpti_EventID*)malloc(size); if (eventId == NULL) { printf("Failed to allocate memory to event ID\n"); ptiStatus = CUPTI_ERROR_OUT_OF_MEMORY; goto Exit; } memset(eventId, 0, size); ptiStatus = cuptiEventDomainEnumEvents(domainId, &size, eventId); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventDomainEnumEvents"); // query event info for (i = 0; i < maxEvents; i++) { eventData.Id.eventId = eventId[i]; size = NAME_SHORT; ptiStatus = cuptiEventGetAttribute(eventData.Id.eventId, CUPTI_EVENT_ATTR_NAME, &size, (uint8_t*)eventData.eventName); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventGetAttribute"); checkNullTerminator(eventData.eventName, size, NAME_SHORT); size = DESC_SHORT; ptiStatus = cuptiEventGetAttribute(eventData.Id.eventId, CUPTI_EVENT_ATTR_SHORT_DESCRIPTION, &size, (uint8_t*)eventData.shortDesc); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventGetAttribute"); checkNullTerminator(eventData.shortDesc, size, DESC_SHORT); size = DESC_LONG; ptiStatus = cuptiEventGetAttribute(eventData.Id.eventId, CUPTI_EVENT_ATTR_LONG_DESCRIPTION, &size, (uint8_t*)eventData.longDesc); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventGetAttribute"); checkNullTerminator(eventData.longDesc, size, DESC_LONG); size = CATEGORY_LENGTH; ptiStatus = cuptiEventGetAttribute(eventData.Id.eventId, CUPTI_EVENT_ATTR_CATEGORY, &size, (&eventData.category)); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventGetAttribute"); printf("Event# %u\n", i+1); printf("Id = %d\n", eventData.Id.eventId); printf("Name = %s\n", eventData.eventName); printf("Shortdesc = %s\n", eventData.shortDesc); printf("Longdesc = %s\n", eventData.longDesc); switch(eventData.category) { case CUPTI_EVENT_CATEGORY_INSTRUCTION: printf("Category = CUPTI_EVENT_CATEGORY_INSTRUCTION\n\n"); break; case CUPTI_EVENT_CATEGORY_MEMORY: printf("Category = CUPTI_EVENT_CATEGORY_MEMORY\n\n"); break; case CUPTI_EVENT_CATEGORY_CACHE: printf("Category = CUPTI_EVENT_CATEGORY_CACHE\n\n"); break; case CUPTI_EVENT_CATEGORY_PROFILE_TRIGGER: printf("Category = CUPTI_EVENT_CATEGORY_PROFILE_TRIGGER\n\n"); break; case CUPTI_EVENT_CATEGORY_SYSTEM: printf("Category = CUPTI_EVENT_CATEGORY_SYSTEM\n\n"); break; default: printf("\n Invalid category!\n"); } } Exit: if (eventId) { free (eventId); } if (ptiStatus == CUPTI_SUCCESS) { return 0; } else { return -1; } } int enumMetrics(CUdevice dev) { ptiData metricData; CUptiResult ptiStatus = CUPTI_SUCCESS; CUpti_MetricID *metricId = NULL; uint32_t maxMetrics = 0; uint32_t i = 0; size_t size = 0; ptiStatus = cuptiDeviceGetNumMetrics(dev, &maxMetrics); CHECK_CUPTI_ERROR(ptiStatus, "cuptiDeviceGetNumMetrics"); size = sizeof(CUpti_EventID) * maxMetrics; metricId = (CUpti_MetricID*)malloc(size); if (metricId == NULL) { printf("Failed to allocate memory to metric ID\n"); ptiStatus = CUPTI_ERROR_OUT_OF_MEMORY; goto Exit; } memset(metricId, 0, size); ptiStatus = cuptiDeviceEnumMetrics(dev, &size, metricId); CHECK_CUPTI_ERROR(ptiStatus, "cuptiDeviceEnumMetrics"); // query metric info for (i = 0; i < maxMetrics; i++) { metricData.Id.metricId = metricId[i]; size = NAME_SHORT; ptiStatus = cuptiMetricGetAttribute(metricData.Id.metricId, CUPTI_METRIC_ATTR_NAME, &size, (uint8_t*)metricData.eventName); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventGetAttribute"); checkNullTerminator(metricData.eventName, size, NAME_SHORT); size = DESC_SHORT; ptiStatus = cuptiMetricGetAttribute(metricData.Id.metricId, CUPTI_METRIC_ATTR_SHORT_DESCRIPTION, &size, (uint8_t*)metricData.shortDesc); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventGetAttribute"); checkNullTerminator(metricData.shortDesc, size, DESC_SHORT); size = DESC_LONG; ptiStatus = cuptiMetricGetAttribute(metricData.Id.metricId, CUPTI_METRIC_ATTR_LONG_DESCRIPTION, &size, (uint8_t*)metricData.longDesc); CHECK_CUPTI_ERROR(ptiStatus, "cuptiEventGetAttribute"); checkNullTerminator(metricData.longDesc, size, DESC_LONG); printf("Metric# %u\n", i+1); printf("Id = %d\n", metricData.Id.metricId); printf("Name = %s\n", metricData.eventName); printf("Shortdesc = %s\n", metricData.shortDesc); printf("Longdesc = %s\n\n", metricData.longDesc); } Exit: if (metricId) { free (metricId); } if (ptiStatus == CUPTI_SUCCESS) { return 0; } else { return -1; } } void parseCommandLineArgs(int argc, char *argv[], int &deviceId, CUpti_EventDomainID &domainId) { for(int k=1; k