@@ -106,15 +106,50 @@ inline void print_statistic(std::vector<ov::genai::ImageGenerationPerfMetrics>&
106
106
<< " ms, vae decoder infer avg time:" << vae_decoder_mean << " ms" << std::endl;
107
107
}
108
108
109
+ inline std::vector<std::string> device_string_to_triplet (const std::string& device_input) {
110
+ std::vector<std::string> devices;
111
+ std::istringstream stream (device_input);
112
+ std::string device;
113
+
114
+ // Split the device input string by commas
115
+ while (std::getline (stream, device, ' ,' )) {
116
+ devices.push_back (device);
117
+ }
118
+
119
+ // Trim whitespace from each device name
120
+ for (auto & dev : devices) {
121
+ dev.erase (0 , dev.find_first_not_of (" \t " ));
122
+ dev.erase (dev.find_last_not_of (" \t " ) + 1 );
123
+ }
124
+
125
+ // Ensure exactly three devices
126
+ if (devices.size () == 1 ) {
127
+ return {devices[0 ], devices[0 ], devices[0 ]};
128
+ } else if (devices.size () == 3 ) {
129
+ return devices;
130
+ } else {
131
+ throw std::invalid_argument (" The device specified by -d/--device must be a single device (e.g. -d \" GPU\" ), "
132
+ " or exactly 3 comma separated device names (e.g. -d \" CPU,NPU,GPU\" )" );
133
+ }
134
+ }
135
+
109
136
void text2image (cxxopts::ParseResult& result) {
110
137
std::string prompt = result[" prompt" ].as <std::string>();
111
138
const std::string models_path = result[" model" ].as <std::string>();
112
- std::string device = result[" device" ].as <std::string>();
139
+ auto devices = device_string_to_triplet ( result[" device" ].as <std::string>() );
113
140
size_t num_warmup = result[" num_warmup" ].as <size_t >();
114
141
size_t num_iter = result[" num_iter" ].as <size_t >();
115
142
const std::string output_dir = result[" output_dir" ].as <std::string>();
116
143
117
- ov::genai::Text2ImagePipeline pipe (models_path, device);
144
+ ov::genai::Text2ImagePipeline pipe (models_path);
145
+ if (result[" reshape" ].as <bool >()) {
146
+ pipe .reshape (result[" num_images_per_prompt" ].as <size_t >(),
147
+ result[" height" ].as <size_t >(),
148
+ result[" width" ].as <size_t >(),
149
+ pipe .get_generation_config ().guidance_scale );
150
+ }
151
+ pipe .compile (devices[0 ], devices[1 ], devices[2 ]);
152
+
118
153
ov::genai::ImageGenerationConfig config = pipe .get_generation_config ();
119
154
config.width = result[" width" ].as <size_t >();
120
155
config.height = result[" height" ].as <size_t >();
@@ -148,15 +183,21 @@ void image2image(cxxopts::ParseResult& result) {
148
183
std::string prompt = result[" prompt" ].as <std::string>();
149
184
const std::string models_path = result[" model" ].as <std::string>();
150
185
std::string image_path = result[" image" ].as <std::string>();
151
- std::string device = result[" device" ].as <std::string>();
186
+ auto devices = device_string_to_triplet ( result[" device" ].as <std::string>() );
152
187
size_t num_warmup = result[" num_warmup" ].as <size_t >();
153
188
size_t num_iter = result[" num_iter" ].as <size_t >();
154
189
const std::string output_dir = result[" output_dir" ].as <std::string>();
155
190
float strength = result[" strength" ].as <float >();
156
191
157
192
ov::Tensor image_input = utils::load_image (image_path);
158
193
159
- ov::genai::Image2ImagePipeline pipe (models_path, device);
194
+ ov::genai::Image2ImagePipeline pipe (models_path);
195
+ if (result[" reshape" ].as <bool >()) {
196
+ auto height = image_input.get_shape ()[1 ];
197
+ auto width = image_input.get_shape ()[2 ];
198
+ pipe .reshape (1 , height, width, pipe .get_generation_config ().guidance_scale );
199
+ }
200
+ pipe .compile (devices[0 ], devices[1 ], devices[2 ]);
160
201
161
202
std::vector<ov::genai::ImageGenerationPerfMetrics> warmup_metrics;
162
203
std::cout << std::fixed << std::setprecision (2 );
@@ -185,15 +226,21 @@ void inpainting(cxxopts::ParseResult& result) {
185
226
const std::string models_path = result[" model" ].as <std::string>();
186
227
std::string image_path = result[" image" ].as <std::string>();
187
228
std::string mask_image_path = result[" mask_image" ].as <std::string>();
188
- std::string device = result[" device" ].as <std::string>();
229
+ auto devices = device_string_to_triplet ( result[" device" ].as <std::string>() );
189
230
size_t num_warmup = result[" num_warmup" ].as <size_t >();
190
231
size_t num_iter = result[" num_iter" ].as <size_t >();
191
232
const std::string output_dir = result[" output_dir" ].as <std::string>();
192
233
193
234
ov::Tensor image_input = utils::load_image (image_path);
194
235
ov::Tensor mask_image = utils::load_image (mask_image_path);
195
236
196
- ov::genai::InpaintingPipeline pipe (models_path, device);
237
+ ov::genai::InpaintingPipeline pipe (models_path);
238
+ if (result[" reshape" ].as <bool >()) {
239
+ auto height = image_input.get_shape ()[1 ];
240
+ auto width = image_input.get_shape ()[2 ];
241
+ pipe .reshape (1 , height, width, pipe .get_generation_config ().guidance_scale );
242
+ }
243
+ pipe .compile (devices[0 ], devices[1 ], devices[2 ]);
197
244
198
245
std::cout << std::fixed << std::setprecision (2 );
199
246
std::vector<ov::genai::ImageGenerationPerfMetrics> warmup_metrics;
@@ -239,6 +286,7 @@ int main(int argc, char* argv[]) try {
239
286
(" s,strength" , " Indicates extent to transform the reference `image`. Must be between 0 and 1" , cxxopts::value<float >()->default_value (std::to_string (0.8 )))
240
287
// special parameters of inpainting pipeline
241
288
(" mi,mask_image" , " Mask image path" , cxxopts::value<std::string>())
289
+ (" r,reshape" , " Reshape pipeline before compilation" , cxxopts::value<bool >()->default_value (" false" ))
242
290
(" h,help" , " Print usage" );
243
291
244
292
cxxopts::ParseResult result;
0 commit comments