@@ -106,15 +106,50 @@ inline void print_statistic(std::vector<ov::genai::ImageGenerationPerfMetrics>&
106106 << " ms, vae decoder infer avg time:" << vae_decoder_mean << " ms" << std::endl;
107107}
108108
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+
109136void text2image (cxxopts::ParseResult& result) {
110137 std::string prompt = result[" prompt" ].as <std::string>();
111138 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>() );
113140 size_t num_warmup = result[" num_warmup" ].as <size_t >();
114141 size_t num_iter = result[" num_iter" ].as <size_t >();
115142 const std::string output_dir = result[" output_dir" ].as <std::string>();
116143
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+
118153 ov::genai::ImageGenerationConfig config = pipe.get_generation_config ();
119154 config.width = result[" width" ].as <size_t >();
120155 config.height = result[" height" ].as <size_t >();
@@ -148,15 +183,21 @@ void image2image(cxxopts::ParseResult& result) {
148183 std::string prompt = result[" prompt" ].as <std::string>();
149184 const std::string models_path = result[" model" ].as <std::string>();
150185 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>() );
152187 size_t num_warmup = result[" num_warmup" ].as <size_t >();
153188 size_t num_iter = result[" num_iter" ].as <size_t >();
154189 const std::string output_dir = result[" output_dir" ].as <std::string>();
155190 float strength = result[" strength" ].as <float >();
156191
157192 ov::Tensor image_input = utils::load_image (image_path);
158193
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 ]);
160201
161202 std::vector<ov::genai::ImageGenerationPerfMetrics> warmup_metrics;
162203 std::cout << std::fixed << std::setprecision (2 );
@@ -185,15 +226,21 @@ void inpainting(cxxopts::ParseResult& result) {
185226 const std::string models_path = result[" model" ].as <std::string>();
186227 std::string image_path = result[" image" ].as <std::string>();
187228 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>() );
189230 size_t num_warmup = result[" num_warmup" ].as <size_t >();
190231 size_t num_iter = result[" num_iter" ].as <size_t >();
191232 const std::string output_dir = result[" output_dir" ].as <std::string>();
192233
193234 ov::Tensor image_input = utils::load_image (image_path);
194235 ov::Tensor mask_image = utils::load_image (mask_image_path);
195236
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 ]);
197244
198245 std::cout << std::fixed << std::setprecision (2 );
199246 std::vector<ov::genai::ImageGenerationPerfMetrics> warmup_metrics;
@@ -239,6 +286,7 @@ int main(int argc, char* argv[]) try {
239286 (" 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 )))
240287 // special parameters of inpainting pipeline
241288 (" mi,mask_image" , " Mask image path" , cxxopts::value<std::string>())
289+ (" r,reshape" , " Reshape pipeline before compilation" , cxxopts::value<bool >()->default_value (" false" ))
242290 (" h,help" , " Print usage" );
243291
244292 cxxopts::ParseResult result;
0 commit comments