From 9716bc37df435170ad3f4b2954373387d978d67f Mon Sep 17 00:00:00 2001 From: pca006132 Date: Sun, 29 Dec 2024 22:31:34 +0800 Subject: [PATCH] update optimizing_tape --- src/sdf/affine_value.h | 42 +++++++++++++++++++++++++++++++++++++++ src/sdf/context.cpp | 25 +---------------------- src/sdf/context.h | 1 - src/sdf/optimizing_tape.h | 14 ++++++------- 4 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 src/sdf/affine_value.h diff --git a/src/sdf/affine_value.h b/src/sdf/affine_value.h new file mode 100644 index 000000000..766279f90 --- /dev/null +++ b/src/sdf/affine_value.h @@ -0,0 +1,42 @@ +// Copyright 2024 The Manifold Authors. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +#pragma once + +#include "context.h" + +namespace manifold::sdf { +struct AffineValue { + // value = var * a + b + Operand var; + double a; + double b; + + AffineValue(Operand var, double a, double b) : var(var), a(a), b(b) {} + AffineValue(double constant) : var(Operand::none()), a(0.0), b(constant) {} + bool operator==(const AffineValue &other) const { + return var == other.var && a == other.a && b == other.b; + } + AffineValue operator+(double d) { return AffineValue(var, a, b + d); } + AffineValue operator*(double d) { return AffineValue(var, a * d, b * d); } +}; +} // namespace manifold::sdf + +template <> +struct std::hash { + size_t operator()(const AffineValue &value) const { + size_t h = std::hash()(value.var.id); + hash_combine(h, value.a, value.b); + return h; + } +}; diff --git a/src/sdf/context.cpp b/src/sdf/context.cpp index a3b7d8e17..1aa95f6ae 100644 --- a/src/sdf/context.cpp +++ b/src/sdf/context.cpp @@ -20,32 +20,9 @@ #include #endif +#include "affine_value.h" #include "manifold/optional_assert.h" -struct AffineValue { - // value = var * a + b - Operand var; - double a; - double b; - - AffineValue(Operand var, double a, double b) : var(var), a(a), b(b) {} - AffineValue(double constant) : var(Operand::none()), a(0.0), b(constant) {} - bool operator==(const AffineValue &other) const { - return var == other.var && a == other.a && b == other.b; - } - AffineValue operator+(double d) { return AffineValue(var, a, b + d); } - AffineValue operator*(double d) { return AffineValue(var, a * d, b * d); } -}; - -template <> -struct std::hash { - size_t operator()(const AffineValue &value) const { - size_t h = std::hash()(value.var.id); - hash_combine(h, value.a, value.b); - return h; - } -}; - namespace manifold::sdf { void Context::dump() const { #ifdef MANIFOLD_DEBUG diff --git a/src/sdf/context.h b/src/sdf/context.h index 772366dc2..e0dc20f84 100644 --- a/src/sdf/context.h +++ b/src/sdf/context.h @@ -57,7 +57,6 @@ using namespace manifold::sdf; inline void hash_combine(std::size_t& seed) {} -// note: ankerl hash combine function is too costly template inline void hash_combine(std::size_t& seed, const T& v, Rest... rest) { std::hash hasher; diff --git a/src/sdf/optimizing_tape.h b/src/sdf/optimizing_tape.h index d7e0a4ca1..90d80cab7 100644 --- a/src/sdf/optimizing_tape.h +++ b/src/sdf/optimizing_tape.h @@ -15,6 +15,7 @@ #include +#include "affine_value.h" #include "interval.h" #include "manifold/vec_view.h" @@ -58,7 +59,7 @@ class OptimizerContext { * For dependencies, we use relative index to track them. * ID = current ID - value * - If value is 0, this means the operand is not being used, i.e. the - * instruction does not have 3 operands. + * instruction does not have that operand. * - If value is 255, this means the dependency is too far away, and we * should look it up in far dependencies. * Ideally, we should not have too many far dependencies. @@ -80,10 +81,9 @@ class OptimizerContext { * memory operations, we reuse them. * * - `buffer` is the regular register buffer for tape evaluation. - * - `constantOffset` is a constant that adds to a corresponding register. - * This can be constant folded. - * - `results` contains instruction id + register id, indicating the - * predetermined branch result for choice/min/max function. + * - `affineValue` is the affine value associated with a register. + * - `results` contains instruction id + affine value, indicating the + * optimized result for some instruction. * Note that this must be sorted according to instruction id. * - `uses` is the temporary use count vector that is mutable in each * evaluation. It is reset before each evaluation. @@ -91,8 +91,8 @@ class OptimizerContext { * elimination. */ VecView> buffer; - VecView constantOffset; - std::vector> results; + VecView affineValues; + std::vector> results; std::vector uses; std::vector dead; };