1111#include " openvino/util/shared_object.hpp"
1212
1313namespace intel_npu {
14+
15+ static inline std::string getLatestVCLLog (vcl_log_handle_t logHandle) {
16+ Logger _logger (" VCLAPI" , Logger::global ().level ());
17+ _logger.debug (" getLatestVCLLog start" );
18+
19+ vcl_version_info_t compilerVersion;
20+ vcl_version_info_t profilingVersion;
21+ vcl_result_t ret = vclGetVersion (&compilerVersion, &profilingVersion);
22+
23+ if (ret != VCL_RESULT_SUCCESS || compilerVersion.major < 3 ) {
24+ _logger.warning (" Failed to get VCL version: 0x%x" , ret);
25+ return " Can not get VCL log, VCL version is too old!" ;
26+ }
27+
28+ // Get log size
29+ size_t size = 0 ;
30+ // Null graph handle to get error log
31+ ret = vclLogHandleGetString (logHandle, &size, nullptr );
32+ if (ZE_RESULT_SUCCESS != ret) {
33+ return " Failed to get size of latest VCL log" ;
34+ }
35+
36+ if (size <= 0 ) {
37+ return " No error stored in VCL when error detected" ;
38+ }
39+
40+ // Get log content
41+ std::string logContent{};
42+ logContent.resize (size);
43+ ret = vclLogHandleGetString (logHandle, &size, const_cast <char *>(logContent.data ()));
44+ if (ZE_RESULT_SUCCESS != ret) {
45+ return " Size of latest error log > 0, failed to get content" ;
46+ }
47+ _logger.debug (" getLatestBuildError end" );
48+ return logContent;
49+ }
50+
51+ #define THROW_ON_FAIL_FOR_VCL (step, ret, logHandle ) \
52+ if (ret != VCL_RESULT_SUCCESS) { \
53+ OPENVINO_THROW (" Failed to call VCL API : " , \
54+ step, \
55+ " result: 0x" , \
56+ std::hex, \
57+ ret, \
58+ " - " , \
59+ getLatestVCLLog (logHandle)); \
60+ }
61+
1462VCLApi::VCLApi () : _logger(" VCLApi" , ov::log::Level::DEBUG) {
1563 const std::string baseName = " npu_vcl_compiler" ;
1664 try {
@@ -61,13 +109,10 @@ const std::shared_ptr<VCLApi>& VCLApi::getInstance() {
61109VCLCompilerImpl::VCLCompilerImpl () : _logHandle(nullptr ), _logger(" VCLCompilerImpl" , ov::log::Level::DEBUG) {
62110 _logger.debug (" VCLCompilerImpl constructor start" );
63111 // Initialize the VCL API
64- vcl_result_t ret = VCL_RESULT_SUCCESS;
65112 vcl_version_info_t compilerVersion;
66113 vcl_version_info_t profilingVersion;
67- ret = vclGetVersion (&compilerVersion, &profilingVersion);
68- if (ret != VCL_RESULT_SUCCESS) {
69- OPENVINO_THROW (" Failed to get VCL version: 0x" , ret);
70- }
114+ THROW_ON_FAIL_FOR_VCL (" vclGetVersion" , vclGetVersion (&compilerVersion, &profilingVersion), nullptr );
115+
71116 _logger.info (" Plugin VCL API Version: %d.%d" , VCL_COMPILER_VERSION_MAJOR, VCL_COMPILER_VERSION_MINOR);
72117 _logger.info (" Plugin VCL Profiling API Version: %d.%d" , VCL_PROFILING_VERSION_MAJOR, VCL_PROFILING_VERSION_MINOR);
73118 _logger.info (" Lib VCL Compiler Version: %d.%d" , compilerVersion.major , compilerVersion.minor );
@@ -78,20 +123,19 @@ VCLCompilerImpl::VCLCompilerImpl() : _logHandle(nullptr), _logger("VCLCompilerIm
78123 compilerDesc.version = compilerVersion;
79124 compilerDesc.debugLevel = static_cast <__vcl_log_level_t >(static_cast <int >(Logger::global ().level ()) - 1 );
80125 vcl_device_desc_t device_desc;
126+ device_desc.size = sizeof (vcl_device_desc_t );
81127 device_desc.deviceID = 0x643E ; // Value from intel_npu/src/backend/src/zero_device.cpp
82128 device_desc.revision = -1 ; // -1 to skip the config
83- device_desc.tileCount = 1 ; // 1 as init value
129+ device_desc.tileCount = 5 ; // 1 as init value
84130
85- if (compilerDesc.debugLevel > VCL_LOG_NONE) {
86- ret = vclCompilerCreate (&compilerDesc, &device_desc, &_compilerHandle, &_logHandle);
87- } else {
88- ret = vclCompilerCreate (&compilerDesc, &device_desc, &_compilerHandle, nullptr );
89- }
131+ THROW_ON_FAIL_FOR_VCL (" vclCompilerCreate" ,
132+ vclCompilerCreate (&compilerDesc, &device_desc, &_compilerHandle, &_logHandle),
133+ nullptr );
134+
135+ THROW_ON_FAIL_FOR_VCL (" vclCompilerGetProperties" ,
136+ vclCompilerGetProperties (_compilerHandle, &_compilerProperties),
137+ _logHandle);
90138
91- ret = vclCompilerGetProperties (_compilerHandle, &_compilerProperties);
92- if (ret != VCL_RESULT_SUCCESS) {
93- OPENVINO_THROW (" Failed to create VCL compiler: 0x" , ret);
94- }
95139 _logger.info (" VCL Compiler created successfully" );
96140 _logger.info (" VCL Compiler Properties: ID: %s, Version: %d.%d, Supported Opsets: %u" ,
97141 _compilerProperties.id ,
@@ -102,10 +146,7 @@ VCLCompilerImpl::VCLCompilerImpl() : _logHandle(nullptr), _logger("VCLCompilerIm
102146
103147VCLCompilerImpl::~VCLCompilerImpl () {
104148 if (_compilerHandle) {
105- vcl_result_t ret = vclCompilerDestroy (_compilerHandle);
106- if (ret != VCL_RESULT_SUCCESS) {
107- _logger.error (" Failed to destroy VCL compiler: 0x%x" , ret);
108- }
149+ THROW_ON_FAIL_FOR_VCL (" vclCompilerDestroy" , vclCompilerDestroy (_compilerHandle), _logHandle);
109150 }
110151 if (_logHandle) {
111152 _logHandle = nullptr ; // Log handle is released automatically with the compiler
@@ -115,7 +156,6 @@ VCLCompilerImpl::~VCLCompilerImpl() {
115156
116157NetworkDescription VCLCompilerImpl::compile (const std::shared_ptr<const ov::Model>& model, const Config& config) const {
117158 _logger.debug (" compile start" );
118- vcl_result_t ret = VCL_RESULT_SUCCESS;
119159
120160 const auto maxOpsetVersion = _compilerProperties.supportedOpsets ;
121161 _logger.info (" getSupportedOpsetVersion Max supported version of opset in CiD: %d" , maxOpsetVersion);
@@ -129,34 +169,31 @@ NetworkDescription VCLCompilerImpl::compile(const std::shared_ptr<const ov::Mode
129169 std::string buildFlags;
130170 const bool useIndices = !((compilerVersion.major < 5 ) || (compilerVersion.major == 5 && compilerVersion.minor < 9 ));
131171
132- _logger.debug (" build flags" );
172+ _logger.debug (" create build flags" );
133173 buildFlags += intel_npu::driver_compiler_utils::serializeIOInfo (model, useIndices);
134174 buildFlags += " " ;
135175 buildFlags += intel_npu::driver_compiler_utils::serializeConfig (config, compilerVersion);
136-
176+ _logger. debug ( " final build flags to compiler: %s " , buildFlags. c_str ());
137177 vcl_executable_desc_t exeDesc = {serializedIR.second .get (),
138178 serializedIR.first ,
139179 buildFlags.c_str (),
140180 buildFlags.size ()};
141181 vcl_executable_handle_t exeHandle = nullptr ;
142- ret = vclExecutableCreate (_compilerHandle, exeDesc, &exeHandle);
143- if (ret != VCL_RESULT_SUCCESS) {
144- OPENVINO_THROW (" Failed to create VCL executable: 0x" , ret);
145- }
182+ THROW_ON_FAIL_FOR_VCL (" vclExecutableCreate" , vclExecutableCreate (_compilerHandle, exeDesc, &exeHandle), _logHandle);
183+
146184 size_t size = 0 ;
147- ret = vclExecutableGetSerializableBlob (exeHandle, nullptr , &size);
148- if (ret != VCL_RESULT_SUCCESS) {
149- OPENVINO_THROW (" Failed to get VCL executable blob size: 0x" , ret);
185+ THROW_ON_FAIL_FOR_VCL (" vclExecutableGetSerializableBlob" ,
186+ vclExecutableGetSerializableBlob (exeHandle, nullptr , &size),
187+ _logHandle);
188+ if (size == 0 ) {
189+ OPENVINO_THROW (" Failed to get VCL executable blob size, size is zero" );
150190 }
151191 std::vector<uint8_t > compiledNetwork (size);
152- ret = vclExecutableGetSerializableBlob (exeHandle, compiledNetwork.data (), &size);
153- if (ret != VCL_RESULT_SUCCESS) {
154- OPENVINO_THROW (" Failed to get VCL executable blob: 0x" , ret);
155- }
156- ret = vclExecutableDestroy (exeHandle);
157- if (ret != VCL_RESULT_SUCCESS) {
158- OPENVINO_THROW (" Failed to destroy VCL executable: 0x" , ret);
159- }
192+ THROW_ON_FAIL_FOR_VCL (" vclExecutableGetSerializableBlob" ,
193+ vclExecutableGetSerializableBlob (exeHandle, compiledNetwork.data (), &size),
194+ _logHandle);
195+
196+ THROW_ON_FAIL_FOR_VCL (" vclExecutableDestroy" , vclExecutableDestroy (exeHandle), _logHandle);
160197
161198 // Use empty metadata as VCL does not support metadata extraction
162199 NetworkMetadata metadata;
@@ -180,16 +217,15 @@ std::vector<ov::ProfilingInfo> VCLCompilerImpl::process_profiling_output(const s
180217 vcl_profiling_handle_t profilingHandle;
181218 vcl_profiling_input_t profilingInput = {network.data (), network.size (), profData.data (), profData.size ()};
182219 vcl_log_handle_t logHandle;
183- ret = vclProfilingCreate (&profilingInput, &profilingHandle, &logHandle);
184- if (ret != VCL_RESULT_SUCCESS) {
185- OPENVINO_THROW (" Failed to create VCL profiling handler: 0x" , ret);
186- }
220+ THROW_ON_FAIL_FOR_VCL (" vclProfilingCreate" ,
221+ vclProfilingCreate (&profilingInput, &profilingHandle, &logHandle),
222+ nullptr );
187223
188224 vcl_profiling_properties_t profProperties;
189- ret = vclProfilingGetProperties (profilingHandle, &profProperties);
190- if (ret != VCL_RESULT_SUCCESS) {
191- OPENVINO_THROW ( " Failed to get VCL profiling properties: 0x " , ret );
192- }
225+ THROW_ON_FAIL_FOR_VCL ( " vclProfilingGetProperties " ,
226+ vclProfilingGetProperties (profilingHandle, &profProperties),
227+ logHandle );
228+
193229 _logger.info (" VCL Profiling Properties: Version: %d.%d" ,
194230 profProperties.version .major ,
195231 profProperties.version .minor );
@@ -199,9 +235,11 @@ std::vector<ov::ProfilingInfo> VCLCompilerImpl::process_profiling_output(const s
199235
200236 vcl_profiling_output_t profOutput;
201237 profOutput.data = NULL ;
202- ret = vclGetDecodedProfilingBuffer (profilingHandle, request, &profOutput);
203- if (ret != VCL_RESULT_SUCCESS || profOutput.data == NULL ) {
204- OPENVINO_THROW (" Failed to get VCL profiling output: 0x" , ret);
238+ THROW_ON_FAIL_FOR_VCL (" vclGetDecodedProfilingBuffer" ,
239+ vclGetDecodedProfilingBuffer (profilingHandle, request, &profOutput),
240+ logHandle);
241+ if (profOutput.data == NULL ) {
242+ OPENVINO_THROW (" Failed to get VCL profiling output" );
205243 }
206244
207245 std::vector<ze_profiling_layer_info> layerInfo (profOutput.size / sizeof (ze_profiling_layer_info));
@@ -211,21 +249,18 @@ std::vector<ov::ProfilingInfo> VCLCompilerImpl::process_profiling_output(const s
211249 }
212250
213251 // profOutput.data = NULL;
214- // ret = vclGetDecodedProfilingBuffer(profilingHandle, VCL_PROFILING_TASK_LEVEL, &profOutput);
215- // if (ret != VCL_RESULT_SUCCESS || profOutput.data == NULL) {
216- // OPENVINO_THROW("Failed to get VCL profiling task level output: 0x", ret );
252+ // THROW_ON_FAIL_FOR_VCL("vclGetDecodedProfilingBuffer", vclGetDecodedProfilingBuffer(profilingHandle,
253+ // VCL_PROFILING_TASK_LEVEL, &profOutput), logHandle); if ( profOutput.data == NULL) {
254+ // OPENVINO_THROW("Failed to get VCL profiling task level output" );
217255 // }
218256
219257 // profOutput.data = NULL;
220- // ret = vclGetDecodedProfilingBuffer(profilingHandle, VCL_PROFILING_RAW, &profOutput);
221- // if (ret != VCL_RESULT_SUCCESS || profOutput.data == NULL) {
222- // OPENVINO_THROW("Failed to get VCL profiling raw output: 0x", ret );
258+ // THROW_ON_FAIL_FOR_VCL("vclGetDecodedProfilingBuffer", vclGetDecodedProfilingBuffer(profilingHandle,
259+ // VCL_PROFILING_RAW, &profOutput),logHandle); if ( profOutput.data == NULL) {
260+ // OPENVINO_THROW("Failed to get VCL profiling raw output" );
223261 // }
224262
225- ret = vclProfilingDestroy (profilingHandle);
226- if (ret != VCL_RESULT_SUCCESS) {
227- OPENVINO_THROW (" Failed to destroy VCL profiling handler: 0x" , ret);
228- }
263+ THROW_ON_FAIL_FOR_VCL (" vclProfilingDestroy" , vclProfilingDestroy (profilingHandle), logHandle);
229264
230265 return intel_npu::profiling::convertLayersToIeProfilingInfo (layerInfo); // Return processed profiling info
231266}
@@ -236,7 +271,6 @@ uint32_t VCLCompilerImpl::get_version() const {
236271
237272ov::SupportedOpsMap VCLCompilerImpl::query (const std::shared_ptr<const ov::Model>& model, const Config& config) const {
238273 _logger.debug (" query start" );
239- vcl_result_t ret = VCL_RESULT_SUCCESS;
240274 const auto maxOpsetVersion = _compilerProperties.supportedOpsets ;
241275 _logger.info (" getSupportedOpsetVersion Max supported version of opset in CiD: %d" , maxOpsetVersion);
242276
@@ -252,27 +286,19 @@ ov::SupportedOpsMap VCLCompilerImpl::query(const std::shared_ptr<const ov::Model
252286
253287 vcl_query_handle_t queryHandle;
254288 vcl_query_desc_t queryDesc = {serializedIR.second .get (), serializedIR.first , buildFlags.c_str (), buildFlags.size ()};
255- ret = vclQueryNetworkCreate (_compilerHandle, queryDesc, &queryHandle);
256- if (ret != VCL_RESULT_SUCCESS) {
257- OPENVINO_THROW (" Failed to create VCL query network: 0x" , ret);
258- }
289+ THROW_ON_FAIL_FOR_VCL (" vclQueryNetworkCreate" ,
290+ vclQueryNetworkCreate (_compilerHandle, queryDesc, &queryHandle),
291+ _logHandle);
259292
260293 uint64_t size = 0 ;
261- ret = vclQueryNetwork (queryHandle, nullptr , &size);
262- if (ret != VCL_RESULT_SUCCESS) {
263- OPENVINO_THROW (" Failed to query network size: 0x" , ret);
264- }
294+ THROW_ON_FAIL_FOR_VCL (" vclQueryNetwork" , vclQueryNetwork (queryHandle, nullptr , &size), _logHandle);
265295
266296 std::vector<char > supportedLayers (size);
267- ret = vclQueryNetwork (queryHandle, reinterpret_cast <uint8_t *>(supportedLayers.data ()), &size);
268- if (ret != VCL_RESULT_SUCCESS) {
269- OPENVINO_THROW (" Failed to query network: 0x" , ret);
270- }
297+ THROW_ON_FAIL_FOR_VCL (" vclQueryNetwork" ,
298+ vclQueryNetwork (queryHandle, reinterpret_cast <uint8_t *>(supportedLayers.data ()), &size),
299+ _logHandle);
271300
272- ret = vclQueryNetworkDestroy (queryHandle);
273- if (ret != VCL_RESULT_SUCCESS) {
274- OPENVINO_THROW (" Failed to destroy VCL query network: 0x" , ret);
275- }
301+ THROW_ON_FAIL_FOR_VCL (" vclQueryNetworkDestroy" , vclQueryNetworkDestroy (queryHandle), _logHandle);
276302
277303 const std::string deviceName = " NPU" ;
278304 ov::SupportedOpsMap result;
@@ -287,32 +313,26 @@ ov::SupportedOpsMap VCLCompilerImpl::query(const std::shared_ptr<const ov::Model
287313
288314bool VCLCompilerImpl::get_supported_options (std::vector<char >& options) const {
289315 _logger.debug (" get_supported_options start" );
290- vcl_result_t ret = VCL_RESULT_SUCCESS;
291316 // 1. get size of compiler supported options list
292317 size_t str_size = 0 ;
293318 try {
294- ret = vclGetCompilerSupportedOptions (_compilerHandle, nullptr , &str_size);
295-
296- if (ret != VCL_RESULT_SUCCESS) {
297- _logger.debug (" Failed to get size of option list %x" , ret);
298- return false ;
299- }
319+ THROW_ON_FAIL_FOR_VCL (" vclGetCompilerSupportedOptions" ,
320+ vclGetCompilerSupportedOptions (_compilerHandle, nullptr , &str_size),
321+ _logHandle);
300322
301323 if (str_size > 0 ) {
302324 _logger.debug (" obtain list" );
303325 // 2. allocate buffer for it
304326 options.resize (str_size);
305327 // 3. populate char list
306- ret = vclGetCompilerSupportedOptions (_compilerHandle, options.data (), &str_size);
307-
308- if (ret == VCL_RESULT_SUCCESS) {
309- _logger.debug (" pfnCompilerGetSupportedOptions - list size %d, got option list" , str_size);
310- return true ;
311- } else {
312- _logger.debug (" Failed to get content of option list 0x%x" , ret);
313- }
328+ THROW_ON_FAIL_FOR_VCL (" vclGetCompilerSupportedOptions" ,
329+ vclGetCompilerSupportedOptions (_compilerHandle, options.data (), &str_size),
330+ _logHandle);
331+
332+ _logger.debug (" Option list size %d, got option list" , str_size);
333+ return true ;
314334 } else {
315- _logger.debug (" pfnCompilerGetSupportedOptions - list size 0 - skipping!" );
335+ _logger.debug (" Option list size 0 - skipping!" );
316336 }
317337 } catch (const std::exception& e) {
318338 // The API is only supported in new version, just add log here
@@ -326,10 +346,10 @@ bool VCLCompilerImpl::is_option_supported(const std::string& option) const {
326346 try {
327347 const char * optname_ch = option.c_str ();
328348 _logger.debug (" is_option_supported start for option: %s" , optname_ch);
329- auto result = vclGetCompilerIsOptionSupported (_compilerHandle, optname_ch, nullptr );
330- if (result == VCL_RESULT_SUCCESS) {
331- return true ;
332- }
349+ THROW_ON_FAIL_FOR_VCL ( " vclGetCompilerIsOptionSupported " ,
350+ vclGetCompilerIsOptionSupported (_compilerHandle, optname_ch, nullptr ),
351+ _logHandle) ;
352+ return true ;
333353 } catch (const std::exception& e) {
334354 // The API is only supported in new version, just add log here
335355 _logger.debug (" Exception in is_option_supported: %s" , e.what ());
0 commit comments