Skip to content

Commit 487bde9

Browse files
tongqiuWovchena
andauthored
[C] Add ov::Property as arguments to the ov_genai_llm_pipeline_create function (openvinotoolkit#2071)
In order to enhance the functionality of the `ov_genai_llm_pipeline_create` function, I've included `ov::Property` as arguments. This will allow user to pass additional properties when compiling the model. --------- Co-authored-by: Vladimir Zlobin <vladimir.zlobin@intel.com>
1 parent fd78169 commit 487bde9

File tree

6 files changed

+75
-9
lines changed

6 files changed

+75
-9
lines changed

samples/c/text_generation/benchmark_genai_c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ int main(int argc, char* argv[]) {
125125
ov_genai_perf_metrics* metrics = NULL;
126126
ov_genai_perf_metrics* cumulative_metrics = NULL;
127127

128-
CHECK_STATUS(ov_genai_llm_pipeline_create(options.model, options.device, &pipe));
128+
CHECK_STATUS(ov_genai_llm_pipeline_create(options.model, options.device, 0, &pipe));
129129

130130
CHECK_STATUS(ov_genai_generation_config_create(&config));
131131
CHECK_STATUS(ov_genai_generation_config_set_max_new_tokens(config, options.max_new_tokens));

samples/c/text_generation/chat_sample_c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ int main(int argc, char* argv[]) {
4040
streamer.callback_func = print_callback;
4141
char prompt[MAX_PROMPT_LENGTH];
4242

43-
CHECK_STATUS(ov_genai_llm_pipeline_create(models_path, device, &pipeline));
43+
CHECK_STATUS(ov_genai_llm_pipeline_create(models_path, device, 0, &pipeline));
4444
CHECK_STATUS(ov_genai_generation_config_create(&config));
4545
CHECK_STATUS(ov_genai_generation_config_set_max_new_tokens(config, 100));
4646

samples/c/text_generation/greedy_causal_lm_c.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ int main(int argc, char* argv[]) {
2727
// the memory.
2828
size_t output_size = 0; // Used to store the required size of the output buffer.
2929

30-
CHECK_STATUS(ov_genai_llm_pipeline_create(model_dir, device, &pipeline));
30+
CHECK_STATUS(ov_genai_llm_pipeline_create(model_dir, device, 0, &pipeline));
3131
CHECK_STATUS(ov_genai_generation_config_create(&config));
3232
CHECK_STATUS(ov_genai_generation_config_set_max_new_tokens(config, 100));
3333
CHECK_STATUS(ov_genai_llm_pipeline_generate(pipeline, prompt, config, NULL, &results));

src/c/include/openvino/genai/c/llm_pipeline.h

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,16 +70,30 @@ typedef struct ov_genai_llm_pipeline_opaque ov_genai_llm_pipeline;
7070

7171
/**
7272
* @brief Construct ov_genai_llm_pipeline.
73+
*
74+
* Initializes a ov_genai_llm_pipeline instance from the specified model directory and device. Optional property
75+
* parameters can be passed as key-value pairs.
76+
*
7377
* @param models_path Path to the directory containing the model files.
7478
* @param device Name of a device to load a model to.
79+
* @param property_args_size How many properties args will be passed, each property contains 2 args: key and value.
7580
* @param ov_genai_llm_pipeline A pointer to the newly created ov_genai_llm_pipeline.
81+
* @param ... property paramater: Optional pack of pairs: <char* property_key, char* property_value> relevant only
7682
* @return ov_status_e A status code, return OK(0) if successful.
83+
*
84+
* @example
85+
* Example with no properties:
86+
* ov_genai_llm_pipeline_create(model_path, "CPU", 0, &pipe);
87+
*
88+
* Example with properties:
89+
* ov_genai_llm_pipeline_create(model_path, "GPU", 2, &pipe,
90+
* "CACHE_DIR", "cache_dir");
7791
*/
7892
OPENVINO_GENAI_C_EXPORTS ov_status_e ov_genai_llm_pipeline_create(const char* models_path,
7993
const char* device,
80-
ov_genai_llm_pipeline** pipe);
81-
82-
// TODO: Add 'const ov::AnyMap& properties' as an input argument when creating ov_genai_llm_pipeline.
94+
const size_t property_args_size,
95+
ov_genai_llm_pipeline** pipe,
96+
...);
8397

8498
/**
8599
* @brief Release the memory allocated by ov_genai_llm_pipeline.

src/c/src/llm_pipeline.cpp

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
#include "openvino/genai/generation_config.hpp"
77
#include "openvino/genai/llm_pipeline.hpp"
88
#include "types_c.h"
9+
#include <stdarg.h>
910

1011
ov_status_e ov_genai_decoded_results_create(ov_genai_decoded_results** results) {
1112
if (!results) {
@@ -67,14 +68,23 @@ ov_status_e ov_genai_decoded_results_get_string(const ov_genai_decoded_results*
6768
}
6869
return ov_status_e::OK;
6970
}
70-
ov_status_e ov_genai_llm_pipeline_create(const char* models_path, const char* device, ov_genai_llm_pipeline** pipe) {
71-
if (!models_path || !device || !pipe) {
71+
ov_status_e ov_genai_llm_pipeline_create(const char* models_path, const char* device, const size_t property_args_size, ov_genai_llm_pipeline** pipe, ...) {
72+
if (!models_path || !device || !pipe || property_args_size % 2 != 0) {
7273
return ov_status_e::INVALID_C_PARAM;
7374
}
7475
try {
76+
ov::AnyMap property = {};
77+
va_list args_ptr;
78+
va_start(args_ptr, pipe);
79+
size_t property_size = property_args_size / 2;
80+
for (size_t i = 0; i < property_size; i++) {
81+
GET_PROPERTY_FROM_ARGS_LIST;
82+
}
83+
va_end(args_ptr);
84+
7585
std::unique_ptr<ov_genai_llm_pipeline> _pipe = std::make_unique<ov_genai_llm_pipeline>();
7686
_pipe->object =
77-
std::make_shared<ov::genai::LLMPipeline>(std::filesystem::path(models_path), std::string(device));
87+
std::make_shared<ov::genai::LLMPipeline>(std::filesystem::path(models_path), std::string(device), property);
7888
*pipe = _pipe.release();
7989
} catch (...) {
8090
return ov_status_e::UNKNOW_EXCEPTION;

src/c/src/types_c.h

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,48 @@
66
#include "openvino/genai/llm_pipeline.hpp"
77
#include "openvino/genai/visibility.hpp"
88

9+
#define GET_PROPERTY_FROM_ARGS_LIST \
10+
std::string property_key = va_arg(args_ptr, char*); \
11+
if (property_key == ov::cache_encryption_callbacks.name()) { \
12+
ov_encryption_callbacks* _value = va_arg(args_ptr, ov_encryption_callbacks*); \
13+
auto encrypt_func = _value->encrypt_func; \
14+
auto decrypt_func = _value->decrypt_func; \
15+
std::function<std::string(const std::string&)> encrypt_value = [encrypt_func](const std::string& in) { \
16+
size_t out_size = 0; \
17+
std::string out_str; \
18+
encrypt_func(in.c_str(), in.length(), nullptr, &out_size); \
19+
if (out_size > 0) { \
20+
std::unique_ptr<char[]> output_ptr = std::make_unique<char[]>(out_size); \
21+
if (output_ptr) { \
22+
char* output = output_ptr.get(); \
23+
encrypt_func(in.c_str(), in.length(), output, &out_size); \
24+
out_str.assign(output, out_size); \
25+
} \
26+
} \
27+
return out_str; \
28+
}; \
29+
std::function<std::string(const std::string&)> decrypt_value = [decrypt_func](const std::string& in) { \
30+
size_t out_size = 0; \
31+
std::string out_str; \
32+
decrypt_func(in.c_str(), in.length(), nullptr, &out_size); \
33+
if (out_size > 0) { \
34+
std::unique_ptr<char[]> output_ptr = std::make_unique<char[]>(out_size); \
35+
if (output_ptr) { \
36+
char* output = output_ptr.get(); \
37+
decrypt_func(in.c_str(), in.length(), output, &out_size); \
38+
out_str.assign(output, out_size); \
39+
} \
40+
} \
41+
return out_str; \
42+
}; \
43+
ov::EncryptionCallbacks encryption_callbacks{std::move(encrypt_value), std::move(decrypt_value)}; \
44+
property[property_key] = encryption_callbacks; \
45+
} else { \
46+
std::string _value = va_arg(args_ptr, char*); \
47+
ov::Any value = _value; \
48+
property[property_key] = value; \
49+
}
50+
951
/**
1052
* @struct ov_genai_generation_config_opaque
1153
* @brief This is an interface of ov::genai::GenerationConfig

0 commit comments

Comments
 (0)