Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions .github/workflows/perf-deep.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ jobs:
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=x64-linux
cmake --build build-release --parallel --target bench_geometry bench_dod bench_pipelines
cmake --build build-release --parallel --target bench_geometry bench_dod bench_pipelines bench_diffgeo

- name: Run head deep benchmarks
shell: bash
Expand All @@ -78,6 +78,13 @@ jobs:
--benchmark_out=artifacts/perf/head/bench_pipelines_head.json \
--benchmark_out_format=json > artifacts/perf/head/bench_pipelines_head.txt

./build-release/bench_diffgeo \
--benchmark_min_time=0.2s \
--benchmark_repetitions=10 \
--benchmark_report_aggregates_only=true \
--benchmark_out=artifacts/perf/head/bench_diffgeo_head.json \
--benchmark_out_format=json > artifacts/perf/head/bench_diffgeo_head.txt

- name: Build and run baseline deep benchmarks
shell: bash
run: |
Expand Down Expand Up @@ -114,6 +121,17 @@ jobs:
echo "bench_pipelines target not available on baseline $BASELINE_SHA" > artifacts/perf/base/bench_pipelines_base.txt
fi

if cmake --build baseline/build-release --parallel --target bench_diffgeo; then
./baseline/build-release/bench_diffgeo \
--benchmark_min_time=0.2s \
--benchmark_repetitions=10 \
--benchmark_report_aggregates_only=true \
--benchmark_out=artifacts/perf/base/bench_diffgeo_base.json \
--benchmark_out_format=json > artifacts/perf/base/bench_diffgeo_base.txt
else
echo "bench_diffgeo target not available on baseline $BASELINE_SHA" > artifacts/perf/base/bench_diffgeo_base.txt
fi

- name: Compare benchmark deltas
shell: bash
run: |
Expand Down Expand Up @@ -141,6 +159,24 @@ jobs:
--output-markdown artifacts/perf/reports/bench_pipelines_deep.md \
--output-json artifacts/perf/reports/bench_pipelines_deep.json

if [[ -s artifacts/perf/base/bench_diffgeo_base.json ]]; then
python3 scripts/perf/compare_against_main.py \
--baseline artifacts/perf/base/bench_diffgeo_base.json \
--current artifacts/perf/head/bench_diffgeo_head.json \
--baseline-commit "$BASELINE_SHA" \
--label "Deep run: bench_diffgeo (baseline $BASELINE_SHA)" \
--output-markdown artifacts/perf/reports/bench_diffgeo_deep.md \
--output-json artifacts/perf/reports/bench_diffgeo_deep.json
else
python3 scripts/perf/compare_against_main.py \
--baseline artifacts/perf/base/bench_diffgeo_base.txt \
--current artifacts/perf/head/bench_diffgeo_head.json \
--baseline-commit "$BASELINE_SHA" \
--label "Deep run: bench_diffgeo (baseline $BASELINE_SHA)" \
--output-markdown artifacts/perf/reports/bench_diffgeo_deep.md \
--output-json artifacts/perf/reports/bench_diffgeo_deep.json
fi

{
echo "# Perf Deep Report"
echo
Expand All @@ -151,6 +187,8 @@ jobs:
cat artifacts/perf/reports/bench_dod_deep.md
echo
cat artifacts/perf/reports/bench_pipelines_deep.md
echo
cat artifacts/perf/reports/bench_diffgeo_deep.md
} > artifacts/perf/reports/deep-summary.md

- name: Build compact CSV summary
Expand All @@ -162,7 +200,7 @@ jobs:

out = Path("artifacts/perf/reports/deep-summary.csv")
rows = ["suite,benchmark,baseline_ns,current_ns,delta_pct,status"]
for suite in ("bench_geometry_deep", "bench_dod_deep", "bench_pipelines_deep"):
for suite in ("bench_geometry_deep", "bench_dod_deep", "bench_pipelines_deep", "bench_diffgeo_deep"):
path = Path(f"artifacts/perf/reports/{suite}.json")
if not path.exists():
continue
Expand Down
42 changes: 41 additions & 1 deletion .github/workflows/perf-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ jobs:
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_TOOLCHAIN_FILE=${{ github.workspace }}/vcpkg/scripts/buildsystems/vcpkg.cmake \
-DVCPKG_TARGET_TRIPLET=x64-linux
cmake --build build-release --parallel --target bench_geometry bench_dod bench_pipelines
cmake --build build-release --parallel --target bench_geometry bench_dod bench_pipelines bench_diffgeo

- name: Run head smoke benchmarks
shell: bash
Expand All @@ -117,6 +117,14 @@ jobs:
--benchmark_out=artifacts/perf/head/bench_pipelines_head.json \
--benchmark_out_format=json > artifacts/perf/head/bench_pipelines_head.txt

./build-release/bench_diffgeo \
--benchmark_filter='bench_diffgeo_pipeline/1000/50/32/32|bench_diffgeo_pipeline/4000/64/32/32|bench_diffgeo_phase_structure_build/1000/50/32/32|bench_diffgeo_phase_structure_build/4000/64/32/32|bench_diffgeo_phase_eigenbasis/1000/50/32/32|bench_diffgeo_phase_eigenbasis/4000/64/32/32|bench_diffgeo_phase_circular/1000/50/32/32|bench_diffgeo_phase_circular/4000/64/32/32|bench_diffgeo_phase_k1_up/4000/64/32/32|bench_diffgeo_phase_k2_up/4000/64/32/32' \
--benchmark_min_time=0.05s \
--benchmark_repetitions=5 \
--benchmark_report_aggregates_only=true \
--benchmark_out=artifacts/perf/head/bench_diffgeo_head.json \
--benchmark_out_format=json > artifacts/perf/head/bench_diffgeo_head.txt

- name: Build and run baseline smoke benchmarks
shell: bash
run: |
Expand Down Expand Up @@ -155,6 +163,18 @@ jobs:
echo "bench_pipelines target not available on baseline ${{ steps.baseline.outputs.base_sha }}" > artifacts/perf/base/bench_pipelines_base.txt
fi

if cmake --build baseline/build-release --parallel --target bench_diffgeo; then
./baseline/build-release/bench_diffgeo \
--benchmark_filter='bench_diffgeo_pipeline/1000/50/32/32|bench_diffgeo_pipeline/4000/64/32/32|bench_diffgeo_phase_structure_build/1000/50/32/32|bench_diffgeo_phase_structure_build/4000/64/32/32|bench_diffgeo_phase_eigenbasis/1000/50/32/32|bench_diffgeo_phase_eigenbasis/4000/64/32/32|bench_diffgeo_phase_circular/1000/50/32/32|bench_diffgeo_phase_circular/4000/64/32/32|bench_diffgeo_phase_k1_up/4000/64/32/32|bench_diffgeo_phase_k2_up/4000/64/32/32' \
--benchmark_min_time=0.05s \
--benchmark_repetitions=5 \
--benchmark_report_aggregates_only=true \
--benchmark_out=artifacts/perf/base/bench_diffgeo_base.json \
--benchmark_out_format=json > artifacts/perf/base/bench_diffgeo_base.txt
else
echo "bench_diffgeo target not available on baseline ${{ steps.baseline.outputs.base_sha }}" > artifacts/perf/base/bench_diffgeo_base.txt
fi

- name: Compare benchmark deltas
shell: bash
run: |
Expand Down Expand Up @@ -216,6 +236,24 @@ jobs:
> artifacts/perf/reports/bench_pipelines_smoke.json
fi

if [[ -s artifacts/perf/base/bench_diffgeo_base.json ]]; then
python3 scripts/perf/compare_against_main.py \
--baseline artifacts/perf/base/bench_diffgeo_base.json \
--current artifacts/perf/head/bench_diffgeo_head.json \
--baseline-commit "${{ steps.baseline.outputs.base_sha }}" \
--label "PR smoke: bench_diffgeo (baseline ${{ steps.baseline.outputs.base_sha }})" \
--output-markdown artifacts/perf/reports/bench_diffgeo_smoke.md \
--output-json artifacts/perf/reports/bench_diffgeo_smoke.json
else
python3 scripts/perf/compare_against_main.py \
--baseline artifacts/perf/base/bench_diffgeo_base.txt \
--current artifacts/perf/head/bench_diffgeo_head.json \
--baseline-commit "${{ steps.baseline.outputs.base_sha }}" \
--label "PR smoke: bench_diffgeo (baseline ${{ steps.baseline.outputs.base_sha }})" \
--output-markdown artifacts/perf/reports/bench_diffgeo_smoke.md \
--output-json artifacts/perf/reports/bench_diffgeo_smoke.json
fi

{
echo "# Perf Smoke Report"
echo
Expand All @@ -229,6 +267,8 @@ jobs:
cat artifacts/perf/reports/bench_dod_smoke.md
echo
cat artifacts/perf/reports/bench_pipelines_smoke.md
echo
cat artifacts/perf/reports/bench_diffgeo_smoke.md
} > artifacts/perf/reports/smoke-summary.md

- name: Publish job summary
Expand Down
124 changes: 124 additions & 0 deletions include/igneous/ops/dec/curvature.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,130 @@ void compute_curvature_measures(const data::Space<StructureT>& space, std::vecto

workspace.face_normals.resize(num_faces);

if constexpr (std::is_same_v<StructureT, data::DiscreteExteriorCalculus>) {
const auto& x = space.x;
const auto& y = space.y;
const auto& z = space.z;
const auto& face_v0 = structure.face_v0;
const auto& face_v1 = structure.face_v1;
const auto& face_v2 = structure.face_v2;
const auto& vertex_face_offsets = structure.vertex_face_offsets;
const auto& vertex_face_data = structure.vertex_face_data;

core::parallel_for_index(
0, static_cast<int>(num_faces),
[&](int face_idx) {
const size_t f = static_cast<size_t>(face_idx);
const uint32_t i0 = face_v0[f];
const uint32_t i1 = face_v1[f];
const uint32_t i2 = face_v2[f];

const float e10x = x[i1] - x[i0];
const float e10y = y[i1] - y[i0];
const float e10z = z[i1] - z[i0];
const float e20x = x[i2] - x[i0];
const float e20y = y[i2] - y[i0];
const float e20z = z[i2] - z[i0];

workspace.face_normals[f] = {
e10x * e20y - e10y * e20x,
e10y * e20z - e10z * e20y,
e10z * e20x - e10x * e20z,
};
},
256);

core::parallel_for_index(
0, static_cast<int>(num_verts),
[&](int vertex_idx) {
const size_t i = static_cast<size_t>(vertex_idx);
const uint32_t begin = vertex_face_offsets[i];
const uint32_t end = vertex_face_offsets[i + 1];
if (begin == end) {
return;
}

float angle_sum = 0.0f;
float area_sum = 0.0f;

float n_xy = 0.0f;
float n_yz = 0.0f;
float n_zx = 0.0f;

float sum_x = 0.0f;
float sum_y = 0.0f;
float sum_z = 0.0f;

const float px = x[i];
const float py = y[i];
const float pz = z[i];

for (uint32_t idx = begin; idx < end; ++idx) {
const uint32_t f_idx = vertex_face_data[idx];
const core::Bivec3 fn = workspace.face_normals[f_idx];
n_xy += fn.xy;
n_yz += fn.yz;
n_zx += fn.zx;

const uint32_t i0 = face_v0[f_idx];
const uint32_t i1 = face_v1[f_idx];
const uint32_t i2 = face_v2[f_idx];

uint32_t a = i0;
uint32_t b = i1;
if (i0 == i) {
a = i1;
b = i2;
} else if (i1 == i) {
a = i2;
b = i0;
}

const float ux = x[a] - px;
const float uy = y[a] - py;
const float uz = z[a] - pz;
const float vx = x[b] - px;
const float vy = y[b] - py;
const float vz = z[b] - pz;

const float dot = ux * vx + uy * vy + uz * vz;
const float wedge_xy = ux * vy - uy * vx;
const float wedge_yz = uy * vz - uz * vy;
const float wedge_zx = uz * vx - ux * vz;
const float wedge_mag =
std::sqrt(wedge_xy * wedge_xy + wedge_yz * wedge_yz + wedge_zx * wedge_zx);

angle_sum += std::atan2(wedge_mag, dot);
area_sum += 0.5f * wedge_mag;

sum_x += x[a] + x[b];
sum_y += y[a] + y[b];
sum_z += z[a] + z[b];
}

if (area_sum > 1e-12f) {
K[i] = static_cast<float>((2.0 * std::numbers::pi_v<double> - angle_sum) /
(static_cast<double>(area_sum) / 3.0));
}

const float n_mag_sq = n_xy * n_xy + n_yz * n_yz + n_zx * n_zx;
const float n_inv = (n_mag_sq > 1e-12f) ? 1.0f / std::sqrt(n_mag_sq) : 0.0f;

const float normal_x = n_yz * n_inv;
const float normal_y = n_zx * n_inv;
const float normal_z = n_xy * n_inv;

const float inv_c = 0.5f / static_cast<float>(end - begin);
const float laplacian_x = sum_x * inv_c - px;
const float laplacian_y = sum_y * inv_c - py;
const float laplacian_z = sum_z * inv_c - pz;

H[i] = laplacian_x * normal_x + laplacian_y * normal_y + laplacian_z * normal_z;
},
128);
return;
}

const auto get_face_vertex = [&](size_t face_idx, int corner) -> uint32_t {
if constexpr (std::is_same_v<StructureT, data::DiscreteExteriorCalculus>) {
if (corner == 0)
Expand Down
Loading