@@ -57,9 +57,6 @@ std::unique_ptr<IExecutionProvider> VitisAIProviderFactory::CreateProvider(const
57
57
}
58
58
}
59
59
60
- // Store pointer to session options as done in SessionOptionsAppendExecutionProvider_VitisAI
61
- provider_options[" session_options" ] = std::to_string ((uintptr_t )(void *)&session_options);
62
-
63
60
auto ep_instance = std::make_unique<VitisAIExecutionProvider>(provider_options);
64
61
ep_instance->SetLogger (reinterpret_cast <const logging::Logger*>(&session_logger));
65
62
return ep_instance;
@@ -89,13 +86,123 @@ struct VitisAI_Provider : Provider {
89
86
void Initialize () override { initialize_vitisai_ep (); }
90
87
// Called right before unloading the shared library
91
88
void Shutdown () override { deinitialize_vitisai_ep (); }
89
+
90
+ Status CreateIExecutionProvider (const OrtHardwareDevice* const * /* devices*/ ,
91
+ const OrtKeyValuePairs* const * /* ep_metadata*/ ,
92
+ size_t /* num_devices*/ ,
93
+ ProviderOptions& provider_options,
94
+ const OrtSessionOptions& session_options,
95
+ const OrtLogger& logger,
96
+ std::unique_ptr<IExecutionProvider>& ep) override {
97
+ auto ep_factory = CreateExecutionProviderFactory (&provider_options);
98
+ ep = ep_factory->CreateProvider (session_options, logger);
99
+ return Status::OK ();
100
+ }
92
101
} g_provider;
93
102
103
+ struct VitisAIEpFactory : OrtEpFactory {
104
+ VitisAIEpFactory (const OrtApi& ort_api_in)
105
+ : ort_api{ort_api_in} {
106
+ ort_version_supported = ORT_API_VERSION;
107
+ GetName = GetNameImpl;
108
+ GetVendor = GetVendorImpl;
109
+ GetVendorId = GetVendorIdImpl;
110
+ GetVersion = GetVersionImpl;
111
+ GetSupportedDevices = GetSupportedDevicesImpl;
112
+ CreateEp = CreateEpImpl;
113
+ ReleaseEp = ReleaseEpImpl;
114
+ }
115
+
116
+ static const char * GetNameImpl (const OrtEpFactory* /* this_ptr*/ ) noexcept {
117
+ return ep_name;
118
+ }
119
+
120
+ static const char * GetVendorImpl (const OrtEpFactory* /* this_ptr*/ ) noexcept {
121
+ return vendor;
122
+ }
123
+
124
+ static uint32_t GetVendorIdImpl (const OrtEpFactory* /* this_ptr*/ ) noexcept {
125
+ return hardware_vendor_id;
126
+ }
127
+
128
+ static const char * ORT_API_CALL GetVersionImpl (const OrtEpFactory* /* this_ptr*/ ) noexcept {
129
+ return ORT_VERSION;
130
+ }
131
+
132
+ static OrtStatus* GetSupportedDevicesImpl (OrtEpFactory* ep_factory,
133
+ const OrtHardwareDevice* const * devices,
134
+ size_t num_devices,
135
+ OrtEpDevice** ep_devices,
136
+ size_t max_ep_devices,
137
+ size_t * p_num_ep_devices) noexcept {
138
+ size_t & num_ep_devices = *p_num_ep_devices;
139
+ VitisAIEpFactory* factory = static_cast <VitisAIEpFactory*>(ep_factory);
140
+
141
+ for (size_t i = 0 ; i < num_devices; ++i) {
142
+ const OrtHardwareDevice* hardware_device = devices[i];
143
+ const std::uint32_t vendor_id = factory->ort_api .HardwareDevice_VendorId (hardware_device);
144
+ const OrtHardwareDeviceType device_type = factory->ort_api .HardwareDevice_Type (hardware_device);
145
+
146
+ if ((vendor_id != VitisAIEpFactory::hardware_vendor_id) ||
147
+ (device_type != OrtHardwareDeviceType_NPU)) {
148
+ continue ;
149
+ }
150
+
151
+ if (num_ep_devices == max_ep_devices) {
152
+ return factory->ort_api .CreateStatus (ORT_INVALID_ARGUMENT, " Not enough space to return EP devices." );
153
+ }
154
+
155
+ auto status = factory->ort_api .GetEpApi ()->CreateEpDevice (factory, hardware_device, nullptr , nullptr ,
156
+ &ep_devices[num_ep_devices++]);
157
+ if (status != nullptr ) {
158
+ return status;
159
+ }
160
+ }
161
+ return nullptr ;
162
+ }
163
+
164
+ static OrtStatus* CreateEpImpl (OrtEpFactory* /* this_ptr*/ ,
165
+ _In_reads_ (num_devices) const OrtHardwareDevice* const * /* devices*/ ,
166
+ _In_reads_(num_devices) const OrtKeyValuePairs* const * /* ep_metadata*/ ,
167
+ _In_ size_t /* num_devices*/ ,
168
+ _In_ const OrtSessionOptions* /* session_options*/ ,
169
+ _In_ const OrtLogger* /* logger*/ ,
170
+ _Out_ OrtEp** /* ep*/ ) noexcept {
171
+ return CreateStatus (ORT_INVALID_ARGUMENT, " VitisAI EP factory does not support this method." );
172
+ }
173
+
174
+ static void ReleaseEpImpl (OrtEpFactory*, OrtEp*) noexcept {
175
+ // no-op as we never create an EP here.
176
+ }
177
+
178
+ const OrtApi& ort_api;
179
+ static constexpr const char * const ep_name{kVitisAIExecutionProvider };
180
+ static constexpr std::uint32_t hardware_vendor_id{0x1022 };
181
+ static constexpr const char * const vendor{" AMD" };
182
+ };
183
+
94
184
} // namespace onnxruntime
95
185
96
186
extern " C" {
97
187
98
188
ORT_API (onnxruntime::Provider*, GetProvider) {
99
189
return &onnxruntime::g_provider;
100
190
}
191
+
192
+ OrtStatus* CreateEpFactories (const char * /* registration_name*/ , const OrtApiBase* ort_api_base,
193
+ OrtEpFactory** factories, size_t max_factories, size_t * num_factories) {
194
+ const OrtApi* ort_api = ort_api_base->GetApi (ORT_API_VERSION);
195
+ if (max_factories < 1 ) {
196
+ return ort_api->CreateStatus (ORT_INVALID_ARGUMENT,
197
+ " Not enough space to return EP factory. Need at least one." );
198
+ }
199
+ factories[0 ] = std::make_unique<onnxruntime::VitisAIEpFactory>(*ort_api).release ();
200
+ *num_factories = 1 ;
201
+ return nullptr ;
202
+ }
203
+
204
+ OrtStatus* ReleaseEpFactory (OrtEpFactory* factory) {
205
+ delete static_cast <onnxruntime::VitisAIEpFactory*>(factory);
206
+ return nullptr ;
207
+ }
101
208
}
0 commit comments