Repository: microsoft/onnxruntime
File: onnxruntime/core/session/plugin_ep/ep_plugin_provider_interfaces.cc (C++)

Code before:
                                 const OrtMemoryInfo* mem_b = ep_device->device_memory_info;

                                 if (mem_a == mem_b) {
                                   return true;  // Point to the same OrtMemoryInfo instance.
                                 }

                                 if (mem_a == nullptr || mem_b == nullptr) {
                                   return false;  // One is nullptr and the other is not.
                                 }

                                 // Both non-null but point to different instances. Use operator==.
                                 return *mem_a == *mem_b;
                               });
  if (!all_match) {
    ORT_THROW("Error creating execution provider '", ep_devices[0]->ep_name,
              "': expected all OrtEpDevice instances to use the same device_memory_info.");
  }

  return device_memory_info != nullptr ? device_memory_info->device : OrtDevice();
}

static const Node* FindFirstNodeAssignedToOtherEP(const std::string& ep_type,
                                                  gsl::span<const EpNode* const> ep_nodes) {
  auto node_iter = std::find_if(ep_nodes.begin(), ep_nodes.end(),
                                [&ep_type](const EpNode* node) -> bool {
                                  return node->GetInternalNode().GetExecutionProviderType() != ep_type;
                                });

  return node_iter != ep_nodes.end() ? &(*node_iter)->GetInternalNode() : nullptr;
}

PluginExecutionProvider::PluginExecutionProvider(UniqueOrtEp ep, const OrtSessionOptions& session_options,
                                                 OrtEpFactory& ep_factory,
                                                 gsl::span<const OrtEpDevice* const> ep_devices,
                                                 const logging::Logger& logger)
    : IExecutionProvider(ep->GetName(ep.get()), GetOrtDeviceForPluginEp(ep_devices), logger),
      ort_ep_(std::move(ep)),
      ep_factory_(ep_factory),
      ep_devices_(ep_devices.begin(), ep_devices.end()) {
  generate_ep_ctx_model_ = session_options.value.GetEpContextGenerationOptions().enable;

  for (const auto* ep_device : ep_devices_) {
    if (ep_device->device_memory_info != nullptr) {
      allocator_mem_infos_.push_back(ep_device->device_memory_info);
    }

    if (ep_device->host_accessible_memory_info != nullptr) {
      allocator_mem_infos_.push_back(ep_device->host_accessible_memory_info);
    }

    if (ep_device->read_only_device_memory_info != nullptr) {

Review comment (suggestion):
should it also check that `node->GetInternalNode().GetExecutionProviderType()` is non-empty (`node` is assigned to an EP)?

```suggestion
                                  const auto& node_ep_type = node->GetInternalNode().GetExecutionProviderType();
                                  return !node_ep_type.empty() && node_ep_type != ep_type;
```

Code after:
                                 if (mem_a == mem_b) {
                                   return true;  // Point to the same OrtMemoryInfo instance.
                                 }

                                 if (mem_a == nullptr || mem_b == nullptr) {
                                   return false;  // One is nullptr and the other is not.
                                 }

                                 // Both non-null but point to different instances. Use operator==.
                                 return *mem_a == *mem_b;
                               });
  if (!all_match) {
    ORT_THROW("Error creating execution provider '", ep_devices[0]->ep_name,
              "': expected all OrtEpDevice instances to use the same device_memory_info.");
  }

  return device_memory_info != nullptr ? device_memory_info->device : OrtDevice();
}

static const Node* FindFirstNodeAssignedToOtherEP(const std::string& ep_type,
                                                  gsl::span<const EpNode* const> ep_nodes) {
  auto node_iter = std::find_if(ep_nodes.begin(), ep_nodes.end(),
                                [&ep_type](const EpNode* node) -> bool {
                                  const auto& node_ep_type = node->GetInternalNode().GetExecutionProviderType();
                                  return !node_ep_type.empty() && node_ep_type != ep_type;
                                });

  return node_iter != ep_nodes.end() ? &(*node_iter)->GetInternalNode() : nullptr;
}

PluginExecutionProvider::PluginExecutionProvider(UniqueOrtEp ep, const OrtSessionOptions& session_options,
                                                 OrtEpFactory& ep_factory,
                                                 gsl::span<const OrtEpDevice* const> ep_devices,
                                                 const logging::Logger& logger)
    : IExecutionProvider(ep->GetName(ep.get()), GetOrtDeviceForPluginEp(ep_devices), logger),
      ort_ep_(std::move(ep)),
      ep_factory_(ep_factory),
      ep_devices_(ep_devices.begin(), ep_devices.end()) {
  generate_ep_ctx_model_ = session_options.value.GetEpContextGenerationOptions().enable;

  for (const auto* ep_device : ep_devices_) {
    if (ep_device->device_memory_info != nullptr) {
      allocator_mem_infos_.push_back(ep_device->device_memory_info);
    }

    if (ep_device->host_accessible_memory_info != nullptr) {
      allocator_mem_infos_.push_back(ep_device->host_accessible_memory_info);
    }

    if (ep_device->read_only_device_memory_info != nullptr) {
      allocator_mem_infos_.push_back(ep_device->read_only_device_memory_info);