|
| 1 | +// Copyright 2025 Google LLC. |
| 2 | +// |
| 3 | +// Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +// you may not use this file except in compliance with the License. |
| 5 | +// You may obtain a copy of the License at |
| 6 | +// |
| 7 | +// http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +// |
| 9 | +// Unless required by applicable law or agreed to in writing, software |
| 10 | +// distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +// See the License for the specific language governing permissions and |
| 13 | +// limitations under the License. |
| 14 | +// |
| 15 | +// Copyright (c) Qualcomm Innovation Center, Inc. All Rights Reserved. |
| 16 | +// SPDX-License-Identifier: Apache-2.0 |
| 17 | + |
| 18 | +#include "litert/c/options/litert_intel_openvino_options.h" |
| 19 | + |
| 20 | +#include <cstdint> |
| 21 | +#include <memory> |
| 22 | +#include <string> |
| 23 | +#include <utility> |
| 24 | +#include <vector> |
| 25 | + |
| 26 | +#include "absl/strings/string_view.h" // from @com_google_absl |
| 27 | +#include "litert/c/litert_common.h" |
| 28 | +#include "litert/c/litert_opaque_options.h" |
| 29 | +#include "litert/cc/litert_macros.h" |
| 30 | +#include "litert/core/cache/hash_util.h" |
| 31 | + |
| 32 | +struct LiteRtIntelOpenVinoOptionsT { |
| 33 | + LiteRtIntelOpenVinoDeviceType device_type = kLiteRtIntelOpenVinoDeviceTypeNPU; |
| 34 | + LiteRtIntelOpenVinoPerformanceMode performance_mode = |
| 35 | + kLiteRtIntelOpenVinoPerformanceModeLatency; |
| 36 | + // Store custom configuration options as key-value pairs |
| 37 | + std::vector<std::pair<std::string, std::string>> configs_map_options; |
| 38 | +}; |
| 39 | + |
| 40 | +LiteRtStatus LiteRtIntelOpenVinoOptionsCreate(LiteRtOpaqueOptions* options) { |
| 41 | + if (options == nullptr) { |
| 42 | + return kLiteRtStatusErrorInvalidArgument; |
| 43 | + } |
| 44 | + |
| 45 | + auto options_data = std::make_unique<LiteRtIntelOpenVinoOptionsT>(); |
| 46 | + |
| 47 | + LITERT_RETURN_IF_ERROR(LiteRtCreateOpaqueOptions( |
| 48 | + LiteRtIntelOpenVinoOptionsGetIdentifier(), options_data.get(), |
| 49 | + [](void* payload) { |
| 50 | + delete reinterpret_cast<LiteRtIntelOpenVinoOptions>(payload); |
| 51 | + }, |
| 52 | + options)); |
| 53 | + |
| 54 | + auto intel_openvino_hash = [](const void* payload) -> uint64_t { |
| 55 | + const LiteRtIntelOpenVinoOptionsT* opts = |
| 56 | + reinterpret_cast<const LiteRtIntelOpenVinoOptionsT*>(payload); |
| 57 | + uint64_t ans = 0; |
| 58 | + litert::HashCombine(ans, opts->device_type, opts->performance_mode); |
| 59 | + // Hash the configs_map_options |
| 60 | + for (const auto& pair : opts->configs_map_options) { |
| 61 | + litert::HashCombine(ans, pair.first, pair.second); |
| 62 | + } |
| 63 | + return ans; |
| 64 | + }; |
| 65 | + LITERT_RETURN_IF_ERROR( |
| 66 | + LiteRtSetOpaqueOptionsHash(*options, intel_openvino_hash)); |
| 67 | + |
| 68 | + options_data.release(); |
| 69 | + return kLiteRtStatusOk; |
| 70 | +} |
| 71 | + |
| 72 | +const char* LiteRtIntelOpenVinoOptionsGetIdentifier() { |
| 73 | + return "intel_openvino"; |
| 74 | +} |
| 75 | + |
| 76 | +LiteRtStatus LiteRtIntelOpenVinoOptionsGet( |
| 77 | + LiteRtOpaqueOptions options, LiteRtIntelOpenVinoOptions* options_data) { |
| 78 | + if (options_data == nullptr || options == nullptr) { |
| 79 | + return kLiteRtStatusErrorInvalidArgument; |
| 80 | + } |
| 81 | + const char* identifier; |
| 82 | + LITERT_RETURN_IF_ERROR( |
| 83 | + LiteRtGetOpaqueOptionsIdentifier(options, &identifier)); |
| 84 | + if (absl::NullSafeStringView(identifier) != |
| 85 | + LiteRtIntelOpenVinoOptionsGetIdentifier()) { |
| 86 | + return kLiteRtStatusErrorInvalidArgument; |
| 87 | + } |
| 88 | + void* payload; |
| 89 | + LITERT_RETURN_IF_ERROR(LiteRtGetOpaqueOptionsData(options, &payload)); |
| 90 | + *options_data = reinterpret_cast<LiteRtIntelOpenVinoOptionsT*>(payload); |
| 91 | + return kLiteRtStatusOk; |
| 92 | +} |
| 93 | + |
| 94 | +// COMPILATION OPTIONS ///////////////////////////////////////////////////////// |
| 95 | + |
| 96 | +// device_type ---------------------------------------------------------------- |
| 97 | +LiteRtStatus LiteRtIntelOpenVinoOptionsSetDeviceType( |
| 98 | + LiteRtIntelOpenVinoOptions options, |
| 99 | + LiteRtIntelOpenVinoDeviceType device_type) { |
| 100 | + if (options == nullptr) { |
| 101 | + return kLiteRtStatusErrorInvalidArgument; |
| 102 | + } |
| 103 | + options->device_type = device_type; |
| 104 | + return kLiteRtStatusOk; |
| 105 | +} |
| 106 | + |
| 107 | +LiteRtStatus LiteRtIntelOpenVinoOptionsGetDeviceType( |
| 108 | + LiteRtIntelOpenVinoOptions options, |
| 109 | + LiteRtIntelOpenVinoDeviceType* device_type) { |
| 110 | + if (options == nullptr || device_type == nullptr) { |
| 111 | + return kLiteRtStatusErrorInvalidArgument; |
| 112 | + } |
| 113 | + *device_type = options->device_type; |
| 114 | + return kLiteRtStatusOk; |
| 115 | +} |
| 116 | + |
| 117 | +// performance_mode ----------------------------------------------------------- |
| 118 | +LiteRtStatus LiteRtIntelOpenVinoOptionsSetPerformanceMode( |
| 119 | + LiteRtIntelOpenVinoOptions options, |
| 120 | + LiteRtIntelOpenVinoPerformanceMode performance_mode) { |
| 121 | + if (options == nullptr) { |
| 122 | + return kLiteRtStatusErrorInvalidArgument; |
| 123 | + } |
| 124 | + options->performance_mode = performance_mode; |
| 125 | + return kLiteRtStatusOk; |
| 126 | +} |
| 127 | + |
| 128 | +LiteRtStatus LiteRtIntelOpenVinoOptionsGetPerformanceMode( |
| 129 | + LiteRtIntelOpenVinoOptions options, |
| 130 | + LiteRtIntelOpenVinoPerformanceMode* performance_mode) { |
| 131 | + if (options == nullptr || performance_mode == nullptr) { |
| 132 | + return kLiteRtStatusErrorInvalidArgument; |
| 133 | + } |
| 134 | + *performance_mode = options->performance_mode; |
| 135 | + return kLiteRtStatusOk; |
| 136 | +} |
| 137 | + |
| 138 | +// configs_map_options -------------------------------------------------------- |
| 139 | +LiteRtStatus LiteRtIntelOpenVinoOptionsSetConfigsMapOption( |
| 140 | + LiteRtIntelOpenVinoOptions options, const char* key, const char* value) { |
| 141 | + if (options == nullptr || key == nullptr || value == nullptr) { |
| 142 | + return kLiteRtStatusErrorInvalidArgument; |
| 143 | + } |
| 144 | + // Check if the key already exists and update it, otherwise add new |
| 145 | + for (auto& pair : options->configs_map_options) { |
| 146 | + if (pair.first == key) { |
| 147 | + pair.second = value; |
| 148 | + return kLiteRtStatusOk; |
| 149 | + } |
| 150 | + } |
| 151 | + options->configs_map_options.emplace_back(key, value); |
| 152 | + return kLiteRtStatusOk; |
| 153 | +} |
| 154 | + |
| 155 | +LiteRtStatus LiteRtIntelOpenVinoOptionsGetNumConfigsMapOptions( |
| 156 | + LiteRtIntelOpenVinoOptions options, int* num_options) { |
| 157 | + if (options == nullptr || num_options == nullptr) { |
| 158 | + return kLiteRtStatusErrorInvalidArgument; |
| 159 | + } |
| 160 | + *num_options = static_cast<int>(options->configs_map_options.size()); |
| 161 | + return kLiteRtStatusOk; |
| 162 | +} |
| 163 | + |
| 164 | +LiteRtStatus LiteRtIntelOpenVinoOptionsGetConfigsMapOption( |
| 165 | + LiteRtIntelOpenVinoOptions options, int index, const char** key, |
| 166 | + const char** value) { |
| 167 | + if (options == nullptr || key == nullptr || value == nullptr) { |
| 168 | + return kLiteRtStatusErrorInvalidArgument; |
| 169 | + } |
| 170 | + if (index < 0 || |
| 171 | + index >= static_cast<int>(options->configs_map_options.size())) { |
| 172 | + return kLiteRtStatusErrorIndexOOB; |
| 173 | + } |
| 174 | + const auto& pair = options->configs_map_options[index]; |
| 175 | + *key = pair.first.c_str(); |
| 176 | + *value = pair.second.c_str(); |
| 177 | + return kLiteRtStatusOk; |
| 178 | +} |
0 commit comments