|
12 | 12 | #include <ShapeworksUtils.h> |
13 | 13 | #include <Utils/StringUtils.h> |
14 | 14 |
|
15 | | -#include <QApplication> |
| 15 | +#include <QCoreApplication> |
16 | 16 | #include <boost/filesystem.hpp> |
17 | 17 |
|
18 | 18 | namespace shapeworks { |
@@ -371,18 +371,23 @@ void DeepSSMCommand::buildParser() { |
371 | 371 | .set_default(0) |
372 | 372 | .help("Number of data loader workers (default: 0)"); |
373 | 373 |
|
| 374 | + parser.add_option("--aug_processes") |
| 375 | + .action("store") |
| 376 | + .type("int") |
| 377 | + .set_default(0) |
| 378 | + .help("Number of augmentation processes (default: 0 = use all cores)"); |
| 379 | + |
374 | 380 | Command::buildParser(); |
375 | 381 | } |
376 | 382 |
|
377 | 383 | bool DeepSSMCommand::execute(const optparse::Values& options, SharedCommandData& sharedData) { |
378 | | - // Create a non-gui QApplication instance |
379 | | - int argc = 3; |
380 | | - char* argv[3]; |
| 384 | + // QCoreApplication provides the event loop needed for PythonWorker's QThread, |
| 385 | + // without requiring Qt platform plugins (which may not be available on headless CI). |
| 386 | + int argc = 1; |
| 387 | + char* argv[1]; |
381 | 388 | argv[0] = const_cast<char*>("shapeworks"); |
382 | | - argv[1] = const_cast<char*>("-platform"); |
383 | | - argv[2] = const_cast<char*>("offscreen"); |
384 | 389 |
|
385 | | - QApplication app(argc, argv); |
| 390 | + QCoreApplication app(argc, argv); |
386 | 391 |
|
387 | 392 | // Handle project file: either from --name or first positional argument |
388 | 393 | std::string project_file; |
@@ -413,12 +418,14 @@ bool DeepSSMCommand::execute(const optparse::Values& options, SharedCommandData& |
413 | 418 | bool do_test = options.is_set("test") || options.is_set("all"); |
414 | 419 |
|
415 | 420 | int num_workers = static_cast<int>(options.get("num_workers")); |
| 421 | + int aug_processes = static_cast<int>(options.get("aug_processes")); |
416 | 422 |
|
417 | 423 | std::cout << "Prep step: " << (do_prep ? "on" : "off") << "\n"; |
418 | 424 | std::cout << "Augment step: " << (do_augment ? "on" : "off") << "\n"; |
419 | 425 | std::cout << "Train step: " << (do_train ? "on" : "off") << "\n"; |
420 | 426 | std::cout << "Test step: " << (do_test ? "on" : "off") << "\n"; |
421 | 427 | std::cout << "Num dataloader workers: " << num_workers << "\n"; |
| 428 | + std::cout << "Augmentation processes: " << (aug_processes == 0 ? QThread::idealThreadCount() : aug_processes) << "\n"; |
422 | 429 |
|
423 | 430 | if (!do_prep && !do_augment && !do_train && !do_test) { |
424 | 431 | do_prep = true; |
@@ -472,6 +479,7 @@ bool DeepSSMCommand::execute(const optparse::Values& options, SharedCommandData& |
472 | 479 | if (do_augment) { |
473 | 480 | std::cout << "Running DeepSSM data augmentation...\n"; |
474 | 481 | auto job = QSharedPointer<DeepSSMJob>::create(project, DeepSSMJob::JobType::DeepSSM_AugmentationType); |
| 482 | + job->set_aug_processes(aug_processes); |
475 | 483 | python_worker.run_job(job); |
476 | 484 | if (!wait_for_job(job)) { |
477 | 485 | return false; |
|
0 commit comments