Skip to content

Commit

Permalink
Merge pull request #2243 from SCIInstitute/fix_mac_action
Browse files Browse the repository at this point in the history
Fix mac GitHub Action and add Mac Arm64
  • Loading branch information
akenmorris committed May 2, 2024
2 parents ee6d2d6 + f39e63e commit bb1b785
Show file tree
Hide file tree
Showing 20 changed files with 945 additions and 792 deletions.
126 changes: 126 additions & 0 deletions .github/workflows/build-mac-arm64.yml
@@ -0,0 +1,126 @@
name: Mac Arm64 Build

on:
push:
branches:
- master
- release_v*
tags:
- '*'
pull_request:

env:
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
BUILD_TYPE: Release
SW_CLOUD_LOGIN: ${{ secrets.CLOUD_LOGIN }}
CACHE_HOST: ${{ secrets.SSH_HOST }}
GA_MEASUREMENT_ID: ${{ secrets.GA_MEASUREMENT_ID }}
GA_API_SECRET: ${{ secrets.GA_API_SECRET }}

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

jobs:
build:

runs-on: macos-latest

steps:

- name: Install SSH Key
uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_PRIVATE_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}

- name: Setup Miniconda
uses: conda-incubator/setup-miniconda@v3.0.4

- name: OS Setup
run: |
sudo chown -R $UID $CONDA
conda init zsh
source ~/.zshrc
brew install ccache pigz gnu-tar coreutils
- name: Checkout code
uses: actions/checkout@v3
with:
lfs: true

- name: Get tags
run: git fetch --unshallow origin +refs/tags/*:refs/tags/*

- name: Restore Caches
shell: bash -l {0}
run: .github/workflows/restore_caches.sh

- name: Conda Installs
shell: bash -l {0}
run: .github/workflows/gha_conda.sh

- name: Build Dependencies
shell: bash -l {0}
run: .github/workflows/gha_deps.sh

- name: cmake
shell: bash -l {0}
run: conda activate shapeworks && mkdir build && cd build && cmake -DCMAKE_LIBTOOL=/usr/bin/libtool -DCMAKE_CXX_FLAGS=-g -DCMAKE_PREFIX_PATH=$HOME/install -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DPython3_ROOT_DIR:FILEPATH=${CONDA_PREFIX} -DUSE_OPENMP=OFF -DBuild_Studio=ON -DCMAKE_INSTALL_PREFIX=${GITHUB_WORKSPACE}/shapeworks-install -DBUILD_DOCUMENTATION=ON -DGA_MEASUREMENT_ID=$GA_MEASUREMENT_ID -DGA_API_SECRET=$GA_API_SECRET ..

- name: make
shell: bash -l {0}
run: conda activate shapeworks && cd build && make -j4

- name: make install
shell: bash -l {0}
run: conda activate shapeworks && cd build && make install

- name: Build Binary Package
shell: bash -l {0}
env:
PR_NUMBER: ${{ github.event.number }}
run: conda activate shapeworks && source ./devenv.sh ./build/bin && ./Support/package.sh tag ${GITHUB_WORKSPACE}/shapeworks-install $HOME/install

- name: Download test data
shell: bash -l {0}
run: .github/workflows/download_test_data.sh

- name: make test
shell: bash -l {0}
run: conda activate shapeworks && source ./devenv.sh ./build/bin && cd build && ctest -VV

- uses: actions/upload-artifact@v2
with:
name: artifact-${{github.sha}}-mac-arm64
path: ${{runner.workspace}}/ShapeWorks/artifacts

- name: Deploy
id: deploy
if: github.ref == 'refs/heads/master'
uses: marvinpinto/action-automatic-releases@latest
with:
repo_token: "${{ secrets.GITHUB_TOKEN }}"
automatic_release_tag: "dev-mac-arm64"
prerelease: true
title: "Development Build for Mac Arm64"
files: |
${{runner.workspace}}/ShapeWorks/artifacts/*.zip
${{runner.workspace}}/ShapeWorks/artifacts/*.pkg
- name: Deploy Docs
if: github.ref == 'refs/heads/master'
shell: bash -l {0}
run: conda activate shapeworks && source ./devenv.sh ./build/bin && ./Support/deploy_docs.sh ${GITHUB_WORKSPACE}/build
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

- name: Store ccache
shell: bash -l {0}
run: .github/workflows/store_ccache.sh

- name: Copy artifact
shell: bash -l {0}
run: cd ${{runner.workspace}}/ShapeWorks && ${GITHUB_WORKSPACE}/.github/workflows/copy_artifact.sh artifact-${{github.sha}}-mac-arm64 artifacts

5 changes: 4 additions & 1 deletion .github/workflows/build-mac.yml
Expand Up @@ -24,7 +24,7 @@ concurrency:
jobs:
build:

runs-on: macos-latest
runs-on: macos-12

steps:

Expand All @@ -36,6 +36,9 @@ jobs:

- name: OS Setup
run: |
ls /usr/local
uname -m
echo $CONDA
sudo chown -R $UID $CONDA
conda init zsh
source ~/.zshrc
Expand Down
10 changes: 8 additions & 2 deletions .github/workflows/common.sh
Expand Up @@ -11,8 +11,14 @@ SCRIPT_PATH=`dirname $SCRIPT`

if [[ "$OSTYPE" == "darwin"* ]]; then
source ~/.zshrc
PLATFORM="mac"
CONDA_PATH="/usr/local/miniconda/envs/shapeworks"
# check arch
if [[ "$(uname -m)" == "arm64" ]]; then
PLATFORM="mac-arm64"
CONDA_PATH="/Users/runner/miniconda3/envs/shapeworks"
else
PLATFORM="mac-intel"
CONDA_PATH="/usr/local/miniconda/envs/shapeworks"
fi
DEP_PATH="$HOME/install"
CCACHE_DIR="/Users/runner/Library/Caches/ccache"
USE_CCACHE="ON"
Expand Down
17 changes: 12 additions & 5 deletions .github/workflows/gha_deps.sh
Expand Up @@ -18,17 +18,24 @@ else
export BUILD_DIR=$HOME/build
export FILE="/tmp/${DEP_FILE}"
if [[ "$PLATFORM" == "windows" ]]; then
export INSTALL_DIR="C:\deps"
export BUILD_DIR="/c/bdeps"
export FILE="${DEP_FILE}"
export INSTALL_DIR="C:\deps"
export BUILD_DIR="/c/bdeps"
export FILE="${DEP_FILE}"
fi

NPROCS=4
export SDKROOT=$HOME/MacOSX10.15.sdk # only needed for MacOS obviously

# if intel mac and not arm64, using uname -m to detect arm64
if [[ "$PLATFORM" == "mac-intel" ]]; then
export SDKROOT=$HOME/MacOSX10.15.sdk # only needed for MacOS obviously
export MACOSX_DEPLOYMENT_TARGET=10.15
fi

if [[ "$PLATFORM" == "linux" ]]; then
# GHA runner is running out of resources with 4 now on linux
# GHA runner is running out of resources with 4 now on linux
NPROCS=2
fi

./build_dependencies.sh --build-type=$BUILD_TYPE --num-procs=$NPROCS --clean-after
rm -rf $BUILD_DIR

Expand Down
2 changes: 1 addition & 1 deletion Applications/shapeworks/ImageCommands.cpp
Expand Up @@ -1127,7 +1127,7 @@ void CompareImage::buildParser()
parser.add_option("--name").action("store").type("string").set_default("").help("Compare this image with another.");
parser.add_option("--verifyall").action("store").type("bool").set_default(true).help("Also verify origin, spacing, and direction matches [default: true].");
parser.add_option("--tolerance").action("store").type("double").set_default(0.0).help("Allowed percentage of pixel differences [default: %default].");
parser.add_option("--precision").action("store").type("double").set_default(1e-12).help("Allowed difference between two pixels for them to still be considered equal [default: 1e-12].");
parser.add_option("--precision").action("store").type("double").set_default(1e-5).help("Allowed difference between two pixels for them to still be considered equal [default: 1e-5].");

Command::buildParser();
}
Expand Down
39 changes: 25 additions & 14 deletions Libs/Analyze/Analyze.cpp
Expand Up @@ -12,15 +12,21 @@ using json = nlohmann::ordered_json;

namespace shapeworks {

//---------------------------------------------------------------------------
static double round(double value, int digits = 6) {
double multiplier = pow(10.0, digits);
return std::round(value * multiplier) / multiplier;
}

//---------------------------------------------------------------------------
static json get_eigen_vectors(ParticleShapeStatistics* stats) {
auto values = stats->get_eigen_vectors();
auto values = stats->get_eigen_vectors();

std::vector<double> vals;
for (size_t i = values.cols() - 1, ii = 0; i > 0; i--, ii++) {
auto col = values.col(i);
for (int j = 0; j < col.size(); j++) {
vals.push_back(col[j]);
vals.push_back(round(col[j]));
}
}

Expand Down Expand Up @@ -217,7 +223,7 @@ void Analyze::run_offline_analysis(std::string outfile, float range, float steps
json jmode;
jmode["mode"] = mode + 1;
double eigen_value = eigen_vals[mode];
jmode["eigen_value"] = eigen_value;
jmode["eigen_value"] = round(eigen_value);
SW_LOG("eigen value [{}]: {}", mode, eigen_value);

double cumulation = 0;
Expand All @@ -227,11 +233,11 @@ void Analyze::run_offline_analysis(std::string outfile, float range, float steps

double explained_variance = eigen_vals[mode] / sum * 100;
double cumulative_explained_variance = cumulation / sum * 100;
jmode["explained_variance"] = explained_variance;
jmode["cumulative_explained_variance"] = cumulative_explained_variance;
jmode["explained_variance"] = round(explained_variance);
jmode["cumulative_explained_variance"] = round(cumulative_explained_variance);
SW_LOG("explained_variance [{}]: {:.2f}", mode, explained_variance);
SW_LOG("cumulative_explained_variance [{}]: {:.2f}", mode, cumulative_explained_variance);

double lambda = sqrt(stats_.get_eigen_values()[m]);

std::vector<json> jmodes;
Expand All @@ -244,8 +250,8 @@ void Analyze::run_offline_analysis(std::string outfile, float range, float steps
auto mode_meshes = shape->get_reconstructed_meshes(true);

json item;
item["pca_value"] = pca_value_param;
item["lambda"] = lambda * pca_value_param;
item["pca_value"] = round(pca_value_param);
item["lambda"] = round(lambda * pca_value_param);

std::vector<std::string> items;
std::vector<std::string> worlds;
Expand Down Expand Up @@ -278,7 +284,12 @@ void Analyze::run_offline_analysis(std::string outfile, float range, float steps
}

j["eigen_vectors"] = get_eigen_vectors(&stats_);
j["eigen_values"] = stats_.get_eigen_values();
auto eigen_values = stats_.get_eigen_values();
// round them
for (auto& value : eigen_values) {
value = round(value);
}
j["eigen_values"] = eigen_values;
j["modes"] = modes;
j["charts"] = create_charts(&stats_);

Expand Down Expand Up @@ -342,11 +353,11 @@ Particles Analyze::get_shape_points(int mode, double value) {
if (mode + 2 > stats_.get_eigen_values().size()) {
mode = stats_.get_eigen_values().size() - 2;
}

unsigned int m = stats_.get_eigen_vectors().cols() - (mode + 1);

Eigen::VectorXd e = stats_.get_eigen_vectors().col(m);

double lambda = sqrt(stats_.get_eigen_values()[m]);

std::vector<double> vals;
Expand Down Expand Up @@ -489,7 +500,7 @@ bool Analyze::compute_stats() {
return false;
}
}

stats_.import_points(points, group_ids);
stats_.compute_modes();

Expand Down Expand Up @@ -617,7 +628,7 @@ Particles Analyze::get_group_shape_particles(double ratio) {
if (!compute_stats()) {
return Particles();
}

auto particles = stats_.get_group1_mean() + (stats_.get_group_difference() * ratio);

return convert_from_combined(particles);
Expand Down
2 changes: 1 addition & 1 deletion Libs/Image/Image.h
Expand Up @@ -271,7 +271,7 @@ class Image {
ImageIterator iterator();

/// compares this with another image using the region of interest filter
bool compare(const Image& other, bool verifyall = true, double tolerance = 0.0, double precision = 1e-12) const;
bool compare(const Image& other, bool verifyall = true, double tolerance = 0.0, double precision = 1e-6) const;

/// compares this with another image using the region of interest filter
bool operator==(const Image& other) const { return compare(other); }
Expand Down
41 changes: 26 additions & 15 deletions Libs/Mesh/Mesh.cpp
Expand Up @@ -814,7 +814,9 @@ Field Mesh::geodesicDistance(const std::vector<Point3> curve) const {
for (int i = 0; i < curve.size(); i++) {
Field distance = geodesicDistance(curve[i]);
for (int j = 0; j < numPoints(); j++) {
if (distance->GetTuple1(j) < minDistance->GetTuple1(j)) minDistance->SetValue(j, distance->GetTuple1(j));
if (distance->GetTuple1(j) < minDistance->GetTuple1(j)) {
minDistance->SetValue(j, distance->GetTuple1(j));
}
}
}

Expand Down Expand Up @@ -1429,35 +1431,44 @@ bool Mesh::compareAllFaces(const Mesh& other_mesh) const {

// helper function to print out the cell indices
auto printCells = [](vtkCell* cell1, vtkCell* cell2) {
printf("[ ");
std::cout << "[ ";
for (int i = 0; i < cell1->GetNumberOfPoints(); i++) {
printf("%lld ", cell1->GetPointId(i));
std::cout << cell1->GetPointId(i) << " ";
}
printf("], [ ");
std::cout << "], [ ";
for (int i = 0; i < cell2->GetNumberOfPoints(); i++) {
printf("%lld ", cell2->GetPointId(i));
std::cout << cell2->GetPointId(i) << " ";
}
printf("]");
std::cout << "]";
};

for (int i = 0; i < this->poly_data_->GetNumberOfCells(); i++) {
vtkCell* cell1 = this->poly_data_->GetCell(i);
vtkCell* cell2 = other_mesh.poly_data_->GetCell(i);

if (cell1->GetNumberOfPoints() != cell2->GetNumberOfPoints()) {
printf("%ith face not equal (", i);
std::cout << i << "th face not equal (";
printCells(cell1, cell2);
printf(")\n");
std::cout << ")\n";
return false;
}

std::vector<vtkIdType> cell1Points(cell1->GetNumberOfPoints());
std::vector<vtkIdType> cell2Points(cell2->GetNumberOfPoints());

for (int pi = 0; pi < cell1->GetNumberOfPoints(); pi++) {
if (cell1->GetPointId(pi) != cell2->GetPointId(pi)) {
printf("%ith face not equal (", i);
printCells(cell1, cell2);
printf(")\n");
return false;
}
cell1Points[pi] = cell1->GetPointId(pi);
cell2Points[pi] = cell2->GetPointId(pi);
}

std::sort(cell1Points.begin(), cell1Points.end());
std::sort(cell2Points.begin(), cell2Points.end());

if (cell1Points != cell2Points) {
std::cout << i << "th face not equal (";
printCells(cell1, cell2);
std::cout << ")\n";
return false;
}
}

Expand Down Expand Up @@ -1521,7 +1532,7 @@ bool Mesh::compareField(const Mesh& other_mesh, const std::string& name1, const
return false;
}
} else {
if (!epsEqual(v1, v2, 1e-5)) {
if (!epsEqual(v1, v2, 1e-3)) {
printf("%ith values not equal (%0.8f != %0.8f)\n", i, v1, v2);
return false;
}
Expand Down

0 comments on commit bb1b785

Please sign in to comment.