Skip to content

Commit ac9897a

Browse files
committed
Fix CI tests
1 parent 53205b7 commit ac9897a

11 files changed

Lines changed: 54 additions & 19 deletions

File tree

Applications/shapeworks/Commands.cpp

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
#include <ShapeworksUtils.h>
1313
#include <Utils/StringUtils.h>
1414

15-
#include <QApplication>
15+
#include <QCoreApplication>
1616
#include <boost/filesystem.hpp>
1717

1818
namespace shapeworks {
@@ -371,18 +371,23 @@ void DeepSSMCommand::buildParser() {
371371
.set_default(0)
372372
.help("Number of data loader workers (default: 0)");
373373

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+
374380
Command::buildParser();
375381
}
376382

377383
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];
381388
argv[0] = const_cast<char*>("shapeworks");
382-
argv[1] = const_cast<char*>("-platform");
383-
argv[2] = const_cast<char*>("offscreen");
384389

385-
QApplication app(argc, argv);
390+
QCoreApplication app(argc, argv);
386391

387392
// Handle project file: either from --name or first positional argument
388393
std::string project_file;
@@ -413,12 +418,14 @@ bool DeepSSMCommand::execute(const optparse::Values& options, SharedCommandData&
413418
bool do_test = options.is_set("test") || options.is_set("all");
414419

415420
int num_workers = static_cast<int>(options.get("num_workers"));
421+
int aug_processes = static_cast<int>(options.get("aug_processes"));
416422

417423
std::cout << "Prep step: " << (do_prep ? "on" : "off") << "\n";
418424
std::cout << "Augment step: " << (do_augment ? "on" : "off") << "\n";
419425
std::cout << "Train step: " << (do_train ? "on" : "off") << "\n";
420426
std::cout << "Test step: " << (do_test ? "on" : "off") << "\n";
421427
std::cout << "Num dataloader workers: " << num_workers << "\n";
428+
std::cout << "Augmentation processes: " << (aug_processes == 0 ? QThread::idealThreadCount() : aug_processes) << "\n";
422429

423430
if (!do_prep && !do_augment && !do_train && !do_test) {
424431
do_prep = true;
@@ -472,6 +479,7 @@ bool DeepSSMCommand::execute(const optparse::Values& options, SharedCommandData&
472479
if (do_augment) {
473480
std::cout << "Running DeepSSM data augmentation...\n";
474481
auto job = QSharedPointer<DeepSSMJob>::create(project, DeepSSMJob::JobType::DeepSSM_AugmentationType);
482+
job->set_aug_processes(aug_processes);
475483
python_worker.run_job(job);
476484
if (!wait_for_job(job)) {
477485
return false;

Examples/Python/deep_ssm.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,8 @@ def Run_Pipeline(args):
6464
This data is comprised of femur meshes and corresponding hip CT scans.
6565
"""
6666

67-
if platform.system() == "Darwin":
68-
# On MacOS, CPU PyTorch is hanging with parallel
67+
if platform.system() != "Linux":
68+
# CPU PyTorch hangs with OpenMP parallelism on macOS and Windows
6969
os.environ['OMP_NUM_THREADS'] = "1"
7070
# If running a tiny_test, then download subset of the data
7171
if args.tiny_test:

Libs/Application/DeepSSM/DeepSSMJob.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,12 @@ void DeepSSMJob::run_augmentation() {
241241
py::module py_deep_ssm_utils = py::module::import("DeepSSMUtils");
242242
py::object run_data_aug = py_deep_ssm_utils.attr("run_data_augmentation");
243243

244+
int processes = aug_processes_ > 0 ? aug_processes_ : QThread::idealThreadCount();
245+
244246
int aug_dims = run_data_aug(project_, params.get_aug_num_samples(),
245247
0 /* num dims, set to zero to allow percent variability to be used */,
246248
params.get_aug_percent_variability(), sampler_type.toStdString(), 0 /* mixture_num */,
247-
QThread::idealThreadCount() /* processes */
248-
)
249+
processes)
249250
.cast<int>();
250251

251252
params.set_training_num_dims(aug_dims);
@@ -394,6 +395,12 @@ void DeepSSMJob::set_num_dataloader_workers(int num_workers) { num_dataloader_wo
394395
//---------------------------------------------------------------------------
395396
int DeepSSMJob::get_num_dataloader_workers() { return num_dataloader_workers_; }
396397

398+
//---------------------------------------------------------------------------
399+
void DeepSSMJob::set_aug_processes(int processes) { aug_processes_ = processes; }
400+
401+
//---------------------------------------------------------------------------
402+
int DeepSSMJob::get_aug_processes() { return aug_processes_; }
403+
397404
//---------------------------------------------------------------------------
398405
void DeepSSMJob::update_prep_stage(PrepStep step) {
399406
/*

Libs/Application/DeepSSM/DeepSSMJob.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ class DeepSSMJob : public Job {
5555
void set_num_dataloader_workers(int num_workers);
5656
int get_num_dataloader_workers();
5757

58+
void set_aug_processes(int processes);
59+
int get_aug_processes();
60+
5861
void set_prep_step(DeepSSMJob::PrepStep step) {
5962
std::lock_guard<std::mutex> lock(mutex_);
6063
prep_step_ = step;
@@ -72,6 +75,7 @@ class DeepSSMJob : public Job {
7275
DeepSSMJob::PrepStep prep_step_{DeepSSMJob::NOT_STARTED};
7376

7477
int num_dataloader_workers_{0};
78+
int aug_processes_{0};
7579

7680
// mutex
7781
std::mutex mutex_;

Libs/Application/Job/PythonWorker.cpp

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -207,11 +207,10 @@ bool PythonWorker::init() {
207207
path = QString::fromStdString(line);
208208
}
209209
file.close();
210+
qputenv("PATH", path.toUtf8());
211+
SW_LOG("Setting PATH for Python to: " + path.toStdString());
210212
}
211213

212-
qputenv("PATH", path.toUtf8());
213-
SW_LOG("Setting PATH for Python to: " + path.toStdString());
214-
215214
// Python 3.8+ requires explicit DLL directory registration
216215
// PATH environment variable is no longer used for DLL search
217216
SetDefaultDllDirectories(LOAD_LIBRARY_SEARCH_DEFAULT_DIRS | LOAD_LIBRARY_SEARCH_USER_DIRS);

Testing/DeepSSMTests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ target_link_libraries(DeepSSMTests
1111
)
1212

1313
add_test(NAME DeepSSMTests COMMAND DeepSSMTests)
14+
set_tests_properties(DeepSSMTests PROPERTIES TIMEOUT 1800)

Testing/DeepSSMTests/deepssm_default.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# Test DeepSSM with default settings (no tl_net, no fine_tune)
33
set -e
44

5+
# Prevent PyTorch/OpenMP deadlock on macOS and Windows
6+
export OMP_NUM_THREADS=1
7+
58
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
69

710
# Unzip test data if not already extracted
@@ -11,7 +14,7 @@ fi
1114

1215
cd "${DATA}/deepssm/projects"
1316
rm -rf deepssm groomed *_particles
14-
shapeworks deepssm --name default.swproj --all
17+
shapeworks deepssm --name default.swproj --all --aug_processes 1
1518

1619
# Verify results
1720
python3 "${SCRIPT_DIR}/verify_deepssm_results.py" "${DATA}/deepssm/projects"

Testing/DeepSSMTests/deepssm_fine_tune.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# Test DeepSSM with fine tuning enabled
33
set -e
44

5+
# Prevent PyTorch/OpenMP deadlock on macOS and Windows
6+
export OMP_NUM_THREADS=1
7+
58
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
69

710
# Unzip test data if not already extracted
@@ -11,7 +14,7 @@ fi
1114

1215
cd "${DATA}/deepssm/projects"
1316
rm -rf deepssm groomed *_particles
14-
shapeworks deepssm --name fine_tune.swproj --all
17+
shapeworks deepssm --name fine_tune.swproj --all --aug_processes 1
1518

1619
# Verify results
1720
python3 "${SCRIPT_DIR}/verify_deepssm_results.py" "${DATA}/deepssm/projects"

Testing/DeepSSMTests/deepssm_tl_net.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# Test DeepSSM with TL-DeepSSM network enabled
33
set -e
44

5+
# Prevent PyTorch/OpenMP deadlock on macOS and Windows
6+
export OMP_NUM_THREADS=1
7+
58
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
69

710
# Unzip test data if not already extracted
@@ -11,7 +14,7 @@ fi
1114

1215
cd "${DATA}/deepssm/projects"
1316
rm -rf deepssm groomed *_particles
14-
shapeworks deepssm --name tl_net.swproj --all
17+
shapeworks deepssm --name tl_net.swproj --all --aug_processes 1
1518

1619
# Verify results
1720
python3 "${SCRIPT_DIR}/verify_deepssm_results.py" "${DATA}/deepssm/projects"

Testing/DeepSSMTests/deepssm_tl_net_fine_tune.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
# Test DeepSSM with both TL-DeepSSM and fine tuning enabled
33
set -e
44

5+
# Prevent PyTorch/OpenMP deadlock on macOS and Windows
6+
export OMP_NUM_THREADS=1
7+
58
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
69

710
# Unzip test data if not already extracted
@@ -11,7 +14,7 @@ fi
1114

1215
cd "${DATA}/deepssm/projects"
1316
rm -rf deepssm groomed *_particles
14-
shapeworks deepssm --name tl_net_fine_tune.swproj --all
17+
shapeworks deepssm --name tl_net_fine_tune.swproj --all --aug_processes 1
1518

1619
# Verify results
1720
python3 "${SCRIPT_DIR}/verify_deepssm_results.py" "${DATA}/deepssm/projects"

0 commit comments

Comments
 (0)