55#include < cctype>
66#include < map>
77#include < set>
8- #include < sstream>
98
109#include < utility>
1110#include " core/providers/shared_library/provider_api.h"
2019
2120namespace onnxruntime {
2221namespace openvino_ep {
23-
2422void ParseConfigOptions (ProviderInfo& pi) {
2523 if (pi.config_options == nullptr )
2624 return ;
@@ -380,7 +378,7 @@ struct OpenVINOProviderFactory : IExecutionProviderFactory {
380378 // The implementation of the SessionOptionsAppendExecutionProvider C API function automatically adds EP options to
381379 // the session option configurations with the key prefix "ep.<lowercase_ep_name>.".
382380 // Extract those EP options into a new "provider_options" map.
383- std::string lowercase_ep_name = " OpenVINOExecutionProvider " ;
381+ std::string lowercase_ep_name = kOpenVINOExecutionProvider ;
384382 std::transform (lowercase_ep_name.begin (), lowercase_ep_name.end (), lowercase_ep_name.begin (), [](unsigned char c) {
385383 return static_cast <char >(std::tolower (c));
386384 });
@@ -436,7 +434,7 @@ struct OpenVINO_Provider : Provider {
436434 }
437435
438436 Status CreateIExecutionProvider (const OrtHardwareDevice* const * /* devices*/ ,
439- const OrtKeyValuePairs* const * /* ep_metadata*/ ,
437+ const OrtKeyValuePairs* const * ep_metadata,
440438 size_t num_devices,
441439 ProviderOptions& provider_options,
442440 const OrtSessionOptions& session_options,
@@ -445,12 +443,27 @@ struct OpenVINO_Provider : Provider {
445443 if (num_devices != 1 ) {
446444 return Status (common::ONNXRUNTIME, ORT_EP_FAIL, " OpenVINO EP only supports one device." );
447445 }
448- std::array<const void *, 2 > params{
449- &provider_options,
450- &session_options.GetConfigOptions (),
451- };
452- auto ep_factory = CreateExecutionProviderFactory (¶ms);
453- ep = ep_factory->CreateProvider (session_options, logger);
446+
447+ ProviderInfo pi;
448+ const auto & config_options = session_options.GetConfigOptions ();
449+ ParseProviderInfo (provider_options, &config_options, pi);
450+
451+ const auto & device_meta_data = ep_metadata[0 ];
452+ auto it = device_meta_data->Entries ().find (" ov_device" );
453+ if (it == device_meta_data->Entries ().end ()) {
454+ return Status (common::ONNXRUNTIME, ORT_INVALID_ARGUMENT, " OpenVINO EP device metadata not found." );
455+ }
456+ pi.device_type = it->second ;
457+
458+ /*
459+ TODO: This is where we need to perform some checking / manupulation of the session_options before
460+ they are passed into CreateProviders() below.
461+ Note: pi.device_type is getting set above, but I *think* it will just get overridden by the
462+ ParseConfigOptions() that will be done inside of CreateProvider();
463+ */
464+
465+ auto factory = std::make_unique<OpenVINOProviderFactory>(pi, SharedContext::Get ());
466+ ep = factory->CreateProvider (session_options, logger);
454467 return Status::OK ();
455468 }
456469
@@ -464,106 +477,6 @@ struct OpenVINO_Provider : Provider {
464477 ProviderInfo_OpenVINO_Impl info_;
465478}; // OpenVINO_Provider
466479
467- // OrtEpApi infrastructure to be able to use the OpenVINO EP as an OrtEpFactory for auto EP selection.
468- struct OpenVINOEpFactory : OrtEpFactory {
469- OpenVINOEpFactory (const OrtApi& ort_api_in)
470- : ort_api{ort_api_in} {
471- GetName = GetNameImpl;
472- GetVendor = GetVendorImpl;
473- GetSupportedDevices = GetSupportedDevicesImpl;
474- CreateEp = CreateEpImpl;
475- ReleaseEp = ReleaseEpImpl;
476- }
477-
478- static const char * GetNameImpl (const OrtEpFactory*) noexcept {
479- return ep_name;
480- }
481-
482- static const char * GetVendorImpl (const OrtEpFactory*) noexcept {
483- return vendor;
484- }
485-
486- static OrtStatus* GetSupportedDevicesImpl (OrtEpFactory* ep_factory,
487- const OrtHardwareDevice* const * devices,
488- size_t num_devices,
489- OrtEpDevice** ep_devices,
490- size_t max_ep_devices,
491- size_t * num_ep_devices) noexcept {
492- if (!ep_factory || !devices || !ep_devices || !num_ep_devices) {
493- return nullptr ;
494- }
495-
496- *num_ep_devices = 0 ;
497- const OpenVINOEpFactory* factory = static_cast <const OpenVINOEpFactory*>(ep_factory);
498-
499- // Simple device discovery and EP device creation
500- for (size_t i = 0 ; i < num_devices && *num_ep_devices < max_ep_devices; ++i) {
501- const std::uint32_t vendorId = factory->ort_api .HardwareDevice_VendorId (devices[i]);
502- const char * vendorName = factory->ort_api .HardwareDevice_Vendor (devices[i]);
503-
504- // Check if this is an Intel device
505- if ((vendorId == intel_vendor_id) ||
506- (vendorName && std::string (vendorName).find (" Intel" ) != std::string::npos)) {
507-
508- const auto device_type = factory->ort_api .HardwareDevice_Type (devices[i]);
509-
510- // Map device type to OpenVINO string
511- const char * device_type_str = nullptr ;
512- switch (device_type) {
513- case OrtHardwareDeviceType_CPU: device_type_str = " CPU" ; break ;
514- case OrtHardwareDeviceType_GPU: device_type_str = " GPU" ; break ;
515- case OrtHardwareDeviceType_NPU: device_type_str = " NPU" ; break ;
516- default : continue ; // Skip unknown device types
517- }
518-
519- // Create EP options
520- OrtKeyValuePairs* ep_options = nullptr ;
521- factory->ort_api .CreateKeyValuePairs (&ep_options);
522- factory->ort_api .AddKeyValuePair (ep_options, " device_type" , device_type_str);
523-
524- // Create EP device
525- OrtEpDevice* ep_device = nullptr ;
526- OrtStatus* status = factory->ort_api .GetEpApi ()->CreateEpDevice (
527- ep_factory, devices[i], nullptr , ep_options, &ep_device);
528-
529- factory->ort_api .ReleaseKeyValuePairs (ep_options);
530-
531- if (status == nullptr ) {
532- ep_devices[(*num_ep_devices)++] = ep_device;
533- } else {
534- return status;
535- }
536- }
537- }
538-
539- return nullptr ;
540- }
541-
542- static OrtStatus* CreateEpImpl (OrtEpFactory* ep_factory,
543- const OrtHardwareDevice* const * devices,
544- const OrtKeyValuePairs* const * ep_metadata_pairs,
545- size_t num_devices,
546- const OrtSessionOptions* session_options,
547- const OrtLogger* logger,
548- OrtEp** ep) noexcept {
549- if (!ep_factory || !ep) {
550- return nullptr ;
551- }
552- const OpenVINOEpFactory* factory = static_cast <const OpenVINOEpFactory*>(ep_factory);
553- return factory->ort_api .CreateStatus (ORT_INVALID_ARGUMENT, " OpenVINO EP factory does not support this method." );
554- }
555-
556- static void ReleaseEpImpl (OrtEpFactory*, OrtEp*) noexcept {
557- // no-op as we never create an EP here.
558- }
559-
560- const OrtApi& ort_api;
561- // Intel vendor ID. Refer to the ACPI ID registry (search Intel): https://uefi.org/ACPI_ID_List
562- static constexpr std::uint32_t intel_vendor_id{0x8086 };
563- static constexpr const char * const ep_name{kOpenVINOExecutionProvider };
564- static constexpr const char * const vendor{" Intel Corporation" };
565- };
566-
567480} // namespace openvino_ep
568481} // namespace onnxruntime
569482
@@ -573,37 +486,4 @@ ORT_API(onnxruntime::Provider*, GetProvider) {
573486 static onnxruntime::openvino_ep::OpenVINO_Provider g_provider;
574487 return &g_provider;
575488}
576-
577- OrtStatus* CreateEpFactories (const char * /* registration_name*/ , const OrtApiBase* ort_api_base,
578- OrtEpFactory** factories, size_t max_factories, size_t * num_factories) {
579- if (!ort_api_base || !factories || !num_factories) {
580- return nullptr ;
581- }
582-
583- const OrtApi* ort_api = ort_api_base->GetApi (ORT_API_VERSION);
584- if (!ort_api) {
585- return nullptr ;
586- }
587-
588- if (max_factories < 1 ) {
589- return ort_api->CreateStatus (ORT_INVALID_ARGUMENT,
590- " Not enough space to return EP factory. Need at least one." );
591- }
592-
593- try {
594- factories[0 ] = new onnxruntime::openvino_ep::OpenVINOEpFactory (*ort_api);
595- *num_factories = 1 ;
596- return nullptr ;
597- } catch (...) {
598- return ort_api->CreateStatus (ORT_FAIL, " Failed to create OpenVINO EP factory." );
599- }
600- }
601-
602- OrtStatus* ReleaseEpFactory (OrtEpFactory* factory) {
603- if (factory) {
604- delete static_cast <onnxruntime::openvino_ep::OpenVINOEpFactory*>(factory);
605- }
606- return nullptr ;
607- }
608-
609489}
0 commit comments