1 /**
2 * Copyright 2020 Huawei Technologies Co., Ltd
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <cupti.h>
17 #include <dlfcn.h>
18 #include "utils/log_adapter.h"
19 #include "profiler/device/gpu/cupti_interface.h"
20
21 namespace mindspore {
22 namespace profiler {
23 namespace gpu {
LoadLibrary(const char * name)24 inline void *LoadLibrary(const char *name) {
25 auto handle = dlopen(name, RTLD_LAZY | RTLD_LOCAL);
26 if (handle == nullptr) {
27 MS_LOG(EXCEPTION) << "Load lib " << name << " Please check whether configured the path of CUPTI to LD_LIBRARY_PATH";
28 }
29 return handle;
30 }
31
GetCUPTIHandle()32 inline void *GetCUPTIHandle() {
33 static void *handle = LoadLibrary("libcupti.so");
34 return handle;
35 }
36
GetCUPTIFunc(const char * name)37 inline void *GetCUPTIFunc(const char *name) {
38 static void *handle = GetCUPTIHandle();
39 void *func = dlsym(handle, name);
40 if (func == nullptr) {
41 MS_LOG(EXCEPTION) << "Load func " << name << " failed, make sure you have implied it!";
42 }
43 return func;
44 }
45
46 using CuptiSubscribeFunc = CUptiResult (*)(CUpti_SubscriberHandle *subscriber, CUpti_CallbackFunc callback,
47 void *userdata);
48 using CuptiEnableDomainFunc = CUptiResult (*)(uint32_t enable, CUpti_SubscriberHandle subscriber,
49 CUpti_CallbackDomain domain);
50 using CuptiActivityEnableFunc = CUptiResult (*)(CUpti_ActivityKind kind);
51 using CuptiActivityRegisterCallbacksFunc = CUptiResult (*)(CUpti_BuffersCallbackRequestFunc funcBufferRequested,
52 CUpti_BuffersCallbackCompleteFunc funcBufferCompleted);
53 using CuptiUnsubscribeFunc = CUptiResult (*)(CUpti_SubscriberHandle subscriber);
54 using CuptiActivityFlushAllFunc = CUptiResult (*)(uint32_t flag);
55 using CuptiActivityDisableFunc = CUptiResult (*)(CUpti_ActivityKind kind);
56 using CuptiActivityGetNextRecordFunc = CUptiResult (*)(uint8_t *buffer, size_t validBufferSizeBytes,
57 CUpti_Activity **record);
58 using CuptiActivityGetNumDroppedRecordsFunc = CUptiResult (*)(CUcontext context, uint32_t streamId, size_t *dropped);
59 using CuptiGetTimestampFunc = CUptiResult (*)(uint64_t *timestamp);
60 using CuptiGetResultStringFunc = CUptiResult (*)(CUptiResult result, const char **str);
61 using CuptiGetStreamIdFunc = CUptiResult (*)(CUcontext context, CUstream stream, uint32_t *streamId);
62 using CuptiGetDeviceIdFunc = CUptiResult (*)(CUcontext context, uint32_t *deviceId);
63
CuptiSubscribe(CUpti_SubscriberHandle * subscriber,CUpti_CallbackFunc callback,void * userdata)64 CUptiResult CuptiSubscribe(CUpti_SubscriberHandle *subscriber, CUpti_CallbackFunc callback, void *userdata) {
65 static auto func_ptr = reinterpret_cast<CuptiSubscribeFunc>(GetCUPTIFunc("cuptiSubscribe"));
66 return func_ptr(subscriber, callback, userdata);
67 }
68
CuptiEnableDomain(uint32_t enable,CUpti_SubscriberHandle subscriber,CUpti_CallbackDomain domain)69 CUptiResult CuptiEnableDomain(uint32_t enable, CUpti_SubscriberHandle subscriber, CUpti_CallbackDomain domain) {
70 static auto func_ptr = reinterpret_cast<CuptiEnableDomainFunc>(GetCUPTIFunc("cuptiEnableDomain"));
71 return func_ptr(enable, subscriber, domain);
72 }
73
CuptiActivityEnable(CUpti_ActivityKind kind)74 CUptiResult CuptiActivityEnable(CUpti_ActivityKind kind) {
75 static auto func_ptr = reinterpret_cast<CuptiActivityEnableFunc>(GetCUPTIFunc("cuptiActivityEnable"));
76 return func_ptr(kind);
77 }
78
CuptiActivityRegisterCallbacks(CUpti_BuffersCallbackRequestFunc funcBufferRequested,CUpti_BuffersCallbackCompleteFunc funcBufferCompleted)79 CUptiResult CuptiActivityRegisterCallbacks(CUpti_BuffersCallbackRequestFunc funcBufferRequested,
80 CUpti_BuffersCallbackCompleteFunc funcBufferCompleted) {
81 static auto func_ptr =
82 reinterpret_cast<CuptiActivityRegisterCallbacksFunc>(GetCUPTIFunc("cuptiActivityRegisterCallbacks"));
83 return func_ptr(funcBufferRequested, funcBufferCompleted);
84 }
85
CuptiUnsubscribe(CUpti_SubscriberHandle subscriber)86 CUptiResult CuptiUnsubscribe(CUpti_SubscriberHandle subscriber) {
87 static auto func_ptr = reinterpret_cast<CuptiUnsubscribeFunc>(GetCUPTIFunc("cuptiUnsubscribe"));
88 return func_ptr(subscriber);
89 }
90
CuptiActivityFlushAll(uint32_t flag)91 CUptiResult CuptiActivityFlushAll(uint32_t flag) {
92 static auto func_ptr = reinterpret_cast<CuptiActivityFlushAllFunc>(GetCUPTIFunc("cuptiActivityFlushAll"));
93 return func_ptr(flag);
94 }
95
CuptiActivityDisable(CUpti_ActivityKind kind)96 CUptiResult CuptiActivityDisable(CUpti_ActivityKind kind) {
97 static auto func_ptr = reinterpret_cast<CuptiActivityDisableFunc>(GetCUPTIFunc("cuptiActivityDisable"));
98 return func_ptr(kind);
99 }
100
CuptiActivityGetNextRecord(uint8_t * buffer,size_t validBufferSizeBytes,CUpti_Activity ** record)101 CUptiResult CuptiActivityGetNextRecord(uint8_t *buffer, size_t validBufferSizeBytes, CUpti_Activity **record) {
102 static auto func_ptr = reinterpret_cast<CuptiActivityGetNextRecordFunc>(GetCUPTIFunc("cuptiActivityGetNextRecord"));
103 return func_ptr(buffer, validBufferSizeBytes, record);
104 }
105
CuptiActivityGetNumDroppedRecords(CUcontext context,uint32_t streamId,size_t * dropped)106 CUptiResult CuptiActivityGetNumDroppedRecords(CUcontext context, uint32_t streamId, size_t *dropped) {
107 static auto func_ptr =
108 reinterpret_cast<CuptiActivityGetNumDroppedRecordsFunc>(GetCUPTIFunc("cuptiActivityGetNumDroppedRecords"));
109 return func_ptr(context, streamId, dropped);
110 }
111
CuptiGetTimestamp(uint64_t * timestamp)112 CUptiResult CuptiGetTimestamp(uint64_t *timestamp) {
113 static auto func_ptr = reinterpret_cast<CuptiGetTimestampFunc>(GetCUPTIFunc("cuptiGetTimestamp"));
114 return func_ptr(timestamp);
115 }
116
CuptiGetResultString(CUptiResult result,const char ** str)117 CUptiResult CuptiGetResultString(CUptiResult result, const char **str) {
118 static auto func_ptr = reinterpret_cast<CuptiGetResultStringFunc>(GetCUPTIFunc("cuptiGetResultString"));
119 return func_ptr(result, str);
120 }
121
CuptiGetStreamId(CUcontext context,CUstream stream,uint32_t * streamId)122 CUptiResult CuptiGetStreamId(CUcontext context, CUstream stream, uint32_t *streamId) {
123 static auto func_ptr = reinterpret_cast<CuptiGetStreamIdFunc>(GetCUPTIFunc("cuptiGetStreamId"));
124 return func_ptr(context, stream, streamId);
125 }
126
CuptiGetDeviceId(CUcontext context,uint32_t * deviceId)127 CUptiResult CuptiGetDeviceId(CUcontext context, uint32_t *deviceId) {
128 static auto func_ptr = reinterpret_cast<CuptiGetDeviceIdFunc>(GetCUPTIFunc("cuptiGetDeviceId"));
129 return func_ptr(context, deviceId);
130 }
131 } // namespace gpu
132 } // namespace profiler
133 } // namespace mindspore
134