perf(shell): skip proven zero derivative Hessian work
This commit is contained in:
@@ -204,3 +204,19 @@ Actual source/lib/exe hash 및 native argv는 parent dger-contract-native.json/d
|
||||
Root는 실제 production local thread1 scope에서 개선 근거가 없으므로 DGER를 채택하지 않기로 결정했다. 위110 PASS 및14 Jet 행동/단일 kernel 자료는 실험 source11af92809a674567262c51c0c0f2e7e130241ca7의 기록이며 현재 복원 source의 새 실행 결과가 아니다. 기본 thread 설정에서의27.9% 감소를 실제 production scope1의2.5% 증가와 바꾸어 주장하지 않는다.
|
||||
|
||||
Working/index에 다른 변경이 없음을 확인하고 T4가 소유한 dense_blas_internal.cpp와 dense_blas_internal_test.cpp만 c58d499727e2370cb405c96decea0efcb2645bea의 checked GEMM 상태로 복원했다. 새 GEMM 대 GEMM 비교로만 남는 DGER 실험 검사도 제거했으며 기존 c58 검사/MKL 적용/TLS 정책은 유지한다. 검증된 DGER 원문은 parent dger-verified-dense_blas_internal.cpp/dger-verified-dense_blas_internal_test.cpp, 실험 commit/manifest/micro/review/native8 실패·진단·native0 행동 자료와 함께 보존한다. 복원 후 전체검사/micro를 반복하지 않았다. 실제 복원 file hash는 parent dger-gemm-restored-source.json에 기록한다. 다음 변경은 프로파일 근거의 Constant provenance 및 정확한 true-trial 재사용이며100초 목표는 계속 미달이다.
|
||||
|
||||
## Constant provenance 및 immutable zero Hessian 후보
|
||||
|
||||
DGER 미채택/GEMM 복원8bfe97dbf82b37a264109fe03028300600b63d1b 이후 nonlinear_mitc4_shell.cpp만 수정했다. 고정 production SHA DABB5423A43A8AA439C50272C4CED40607FC189C67E03A9BC498559BA94F64DC, parent constant-source.json SHA0FDFE9A18ED5BECF3E1DA7A4F1420BADD9B22340EAC9A159550ABC96D5778E37. Direct derivative 쓰기와 수명 근거는 constant-write-audit.md, 조건부 이론 검토는 constant-specialization-proof.md, 현재 source-only/current Jet caller 독립 PASS는 source-numerical-review-constant.md에 보존한다. 결과를 전체 모델/성능 PASS로 확대하지 않는다.
|
||||
|
||||
Anonymous Jet의 derivative-zero provenance는 기본false이며 Constant만true로 시작하고 Variable은 seed 쓰기 전에false로 만든다. 연산 결과에서는 원래 식과 실제 finite 계수로 증명될 때만 전파한다. Null Hessian은 Variable도 가지므로 상수 판정으로 사용하지 않는다. 별도 IsImplicitZero는 immutable zero storage의 사실만 나타낸다. +/−의 양 implicit H 및 finite scalar×implicit H에는 독립 H=0 lemma를 사용하며 first/directional/mixed 식은 그대로 계산한다. ScalarInf/NaN은 원래 H576 경로로 보내0 곱의 기존 실패를 유지한다.
|
||||
|
||||
Jet 곱의 known-zero outer는 finite lhs/rhs/result value와 상대 gradient 전체 finite를 확인한 proven Constant 경로에서만 생략한다. 일반 비영24outer는 기존 checked MKL GEMM이다. 필요한 H 항은 원래 left association을 유지하며 양쪽 implicit H일 때만 H576 전체를 생략한다. Compose는 실제 first/second/third 및 input/result value finite를 모두 요구한다. Atan2는 actual Cartesian 계수와 양 provenance로 H영을 증명하지만 std::atan2 value/first/bounded ratio/Reciprocal/Compose/directional/mixed 원래 식과 실패 경로는 계속 계산한다. radius_fourthInf 자체를 새 gate로 사용하지 않는다.
|
||||
|
||||
입력 또는 기존 allocated alias를 결과로 반환하지 않고 fresh Jet를 만든다. Allocated H의 기존 shared copy/첫 mutable write alias는 유지한다. 알려진 영 결과는 immutable zero를 읽는 readonly copy로 사용할 수 있으며 현재 생산 consumer는 그 결과에 raw derivative를 나중에 쓰는 경로가 없다. 모든 직접 Jet derivative 생산자는 기본false fresh 결과 또는 Variable seed에서 시작하며 true 전파는 쓰기 완료 후 증명한다. 값·분기·finite/진단·공개 결과에 영향이 없는 현재 raw H의 numeric zero 범위만 다루고 pair/canonical-zero 기준과 전역 flags/thread policy는 변경하지 않는다.
|
||||
|
||||
실제 corrected-prefix Debug 정식5edges build0, Ninja dependency 양수/private math header 확인, /Od /Ob0 /RTC1 /MDd /W4 /WX production TU oracle compile0, frozen33-case oracle native0를 확인했다. Value/first/directional/mixed 영 부호와 비영 bits는 strict, H의 양쪽 numeric zero만 부호 차이를 기록하며 NaN은 같은 failure 분류와 owner IsFinite 거부를 검증했다. Constant/seed/default-false unknown, finite·Inf·NaN scalar, Compose first/second/third 각각Inf/NaN, Sqrt0, Atan2 branch/singular/extreme scale, mixed-third, nonfinite gradient/H, allocated alias와 readonly zero-result copy chain을 반증했다. 33사례의 기록된 H zero-sign 차이는 모두0이며 provenance/alias 조건도 통과했다.
|
||||
|
||||
관련 shell residual/tangent/objectivity/patch, hidden graph/finite/initial Newton/기존serial-TBB-repeat 결정론 필터는 **actual53/53 PASS(native0/71.98초)**이다. 기존 serial/TBB fixture57.46초도 별도 기록했지만 이는 전체 모델 성능 기준이 아니다. 실행 source/컴파일 환경/argv/thread/native 및 모든 hash는 parent constant-debug-native.json/constant-debug-built-hashes.json/constant-debug-delivery.json에 보존한다. Debug library SHA25632077F5A27A0216E4EB8E9F785F88D70B5FF37FAE02127430DE3D40C18814, probe exeBA299678CF250BBEEF78A7E095C503315277A354938B67B0BAA80BA455D0EC0E, unit exe23DAFC468C20211D9B1CDD60365F448B76E33BDC5EE3478A80CF4DCEE27D090D.
|
||||
|
||||
현재 후보의 Release 비용·전체 shell 실행·현재 mixed-time·최종 전체Debug/C08/reference는 미실행이다. 과거 packed-mixed의 actual CTest61.25초/native61.4626626초 자료는 별도로 보존하며 이전60.69 표기를 이 source의 실행 시간으로 재사용하지 않는다. 시간 수치를 맞추기 위한 반복도 하지 않았다. 다음 단계의 원본 shell150초 안전 제한 개발 실행도 partial 진행을 시간 개선 비율이나100초 합격으로 바꾸지 않는다.
|
||||
|
||||
@@ -417,6 +417,9 @@ class Hessian {
|
||||
|
||||
const double* ReadData() const { return Storage().data(); }
|
||||
|
||||
/// @brief Identifies only the immutable zero Hessian, independently of seeds.
|
||||
bool IsImplicitZero() const { return !values_; }
|
||||
|
||||
/// @brief Gets fresh output storage without redundant zero initialization.
|
||||
/// @note Only fresh operator results use this pointer; all 576 entries must
|
||||
/// be written before any read or copy of the result.
|
||||
@@ -461,6 +464,9 @@ struct Jet {
|
||||
double directional_second{};
|
||||
std::array<double, kGlobalDofCount> mixed_first{};
|
||||
std::array<double, kGlobalDofCount> mixed_second{};
|
||||
// Provenance for numerically zero derivatives; a null Hessian alone is not
|
||||
// constant provenance because Variable retains a nonzero gradient seed.
|
||||
bool constant_derivatives{false};
|
||||
};
|
||||
|
||||
using JetVector3 = std::array<Jet, 3>;
|
||||
@@ -471,6 +477,7 @@ using JetTensor = std::array<std::array<Jet, 3>, 3>;
|
||||
Jet Constant(const double value) {
|
||||
Jet result{};
|
||||
result.value = value;
|
||||
result.constant_derivatives = true;
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -478,6 +485,7 @@ Jet Constant(const double value) {
|
||||
Jet Variable(const double value, const std::size_t index,
|
||||
const double direction = 0.0) {
|
||||
Jet result = Constant(value);
|
||||
result.constant_derivatives = false;
|
||||
result.first[index] = 1.0;
|
||||
result.directional_first = direction;
|
||||
return result;
|
||||
@@ -497,6 +505,11 @@ Jet operator+(const Jet& left, const Jet& right) {
|
||||
result.mixed_second[index] =
|
||||
left.mixed_second[index] + right.mixed_second[index];
|
||||
}
|
||||
result.constant_derivatives = left.constant_derivatives &&
|
||||
right.constant_derivatives &&
|
||||
std::isfinite(result.value);
|
||||
if (left.second.IsImplicitZero() && right.second.IsImplicitZero())
|
||||
return result;
|
||||
const double* left_second = left.second.ReadData();
|
||||
const double* right_second = right.second.ReadData();
|
||||
double* result_second = result.second.OverwriteData();
|
||||
@@ -520,6 +533,11 @@ Jet operator-(const Jet& left, const Jet& right) {
|
||||
result.mixed_second[index] =
|
||||
left.mixed_second[index] - right.mixed_second[index];
|
||||
}
|
||||
result.constant_derivatives = left.constant_derivatives &&
|
||||
right.constant_derivatives &&
|
||||
std::isfinite(result.value);
|
||||
if (left.second.IsImplicitZero() && right.second.IsImplicitZero())
|
||||
return result;
|
||||
const double* left_second = left.second.ReadData();
|
||||
const double* right_second = right.second.ReadData();
|
||||
double* result_second = result.second.OverwriteData();
|
||||
@@ -554,9 +572,29 @@ Jet operator*(const Jet& left, const Jet& right) {
|
||||
2.0 * left.directional_first * right.mixed_first[index] +
|
||||
left.value * right.mixed_second[index];
|
||||
}
|
||||
const bool finite_values = std::isfinite(left.value) &&
|
||||
std::isfinite(right.value) &&
|
||||
std::isfinite(result.value);
|
||||
const auto finite_gradient = [](const auto& gradient) {
|
||||
return std::all_of(gradient.begin(), gradient.end(),
|
||||
[](const double value) { return std::isfinite(value); });
|
||||
};
|
||||
const bool zero_outer = finite_values &&
|
||||
((left.constant_derivatives && finite_gradient(right.first)) ||
|
||||
(right.constant_derivatives && finite_gradient(left.first)));
|
||||
result.constant_derivatives = finite_values && left.constant_derivatives &&
|
||||
right.constant_derivatives;
|
||||
if (zero_outer && left.second.IsImplicitZero() &&
|
||||
right.second.IsImplicitZero()) return result;
|
||||
const double* left_second = left.second.ReadData();
|
||||
const double* right_second = right.second.ReadData();
|
||||
double* result_second = result.second.OverwriteData();
|
||||
if (zero_outer) {
|
||||
for (std::size_t index = 0U; index < kHessianSize; ++index)
|
||||
result_second[index] = left_second[index] * right.value + 0.0 + 0.0 +
|
||||
left.value * right_second[index];
|
||||
return result;
|
||||
}
|
||||
Outer(left.first, right.first, result_second);
|
||||
std::array<double, kHessianSize> reverse;
|
||||
Outer(right.first, left.first, reverse.data());
|
||||
@@ -582,6 +620,10 @@ Jet operator*(const double scalar, const Jet& value) {
|
||||
result.mixed_first[index] = scalar * value.mixed_first[index];
|
||||
result.mixed_second[index] = scalar * value.mixed_second[index];
|
||||
}
|
||||
result.constant_derivatives = value.constant_derivatives &&
|
||||
std::isfinite(scalar) &&
|
||||
std::isfinite(result.value);
|
||||
if (std::isfinite(scalar) && value.second.IsImplicitZero()) return result;
|
||||
const double* value_second = value.second.ReadData();
|
||||
double* result_second = result.second.OverwriteData();
|
||||
for (std::size_t index = 0U; index < kHessianSize; ++index) {
|
||||
@@ -614,6 +656,10 @@ Jet Compose(const Jet& input, const double value, const double first,
|
||||
input.first[index] * input.directional_second) +
|
||||
first * input.mixed_second[index];
|
||||
}
|
||||
result.constant_derivatives = input.constant_derivatives &&
|
||||
std::isfinite(input.value) && std::isfinite(value) &&
|
||||
std::isfinite(first) && std::isfinite(second) && std::isfinite(third);
|
||||
if (result.constant_derivatives) return result;
|
||||
std::array<double, kGlobalDofCount> scaled_first{};
|
||||
for (std::size_t row = 0U; row < kGlobalDofCount; ++row)
|
||||
scaled_first[row] = second * input.first[row];
|
||||
@@ -673,32 +719,38 @@ Jet Atan2(const Jet& y, const Jet& x) {
|
||||
const double derivative_yx =
|
||||
(y.value * y.value - x.value * x.value) / radius_fourth;
|
||||
const double derivative_xx = 2.0 * x.value * y.value / radius_fourth;
|
||||
std::array<double, kGlobalDofCount> scaled_y{};
|
||||
std::array<double, kGlobalDofCount> scaled_x{};
|
||||
for (std::size_t i = 0U; i < kGlobalDofCount; ++i) {
|
||||
scaled_y[i] = derivative_yy * y.first[i];
|
||||
scaled_x[i] = derivative_xx * x.first[i];
|
||||
}
|
||||
std::array<std::array<double, kHessianSize>, 4U> products;
|
||||
Outer(scaled_y, y.first, products[0U].data());
|
||||
Outer(y.first, x.first, products[1U].data());
|
||||
Outer(x.first, y.first, products[2U].data());
|
||||
Outer(scaled_x, x.first, products[3U].data());
|
||||
const bool zero_hessian = x.constant_derivatives && y.constant_derivatives &&
|
||||
std::isfinite(result.value) && std::isfinite(derivative_y) &&
|
||||
std::isfinite(derivative_x) && std::isfinite(derivative_yy) &&
|
||||
std::isfinite(derivative_yx) && std::isfinite(derivative_xx);
|
||||
for (std::size_t index = 0U; index < kGlobalDofCount; ++index) {
|
||||
result.first[index] =
|
||||
derivative_y * y.first[index] + derivative_x * x.first[index];
|
||||
}
|
||||
const double* y_second = y.second.ReadData();
|
||||
const double* x_second = x.second.ReadData();
|
||||
double* result_second = result.second.OverwriteData();
|
||||
for (std::size_t row = 0U; row < kGlobalDofCount; ++row) {
|
||||
for (std::size_t column = 0U; column < kGlobalDofCount; ++column) {
|
||||
const std::size_t index = row * kGlobalDofCount + column;
|
||||
result_second[index] =
|
||||
derivative_y * y_second[index] + derivative_x * x_second[index] +
|
||||
products[0U][index] +
|
||||
derivative_yx * (products[1U][index] + products[2U][index]) +
|
||||
products[3U][index];
|
||||
if (!zero_hessian) {
|
||||
std::array<double, kGlobalDofCount> scaled_y{};
|
||||
std::array<double, kGlobalDofCount> scaled_x{};
|
||||
for (std::size_t i = 0U; i < kGlobalDofCount; ++i) {
|
||||
scaled_y[i] = derivative_yy * y.first[i];
|
||||
scaled_x[i] = derivative_xx * x.first[i];
|
||||
}
|
||||
std::array<std::array<double, kHessianSize>, 4U> products;
|
||||
Outer(scaled_y, y.first, products[0U].data());
|
||||
Outer(y.first, x.first, products[1U].data());
|
||||
Outer(x.first, y.first, products[2U].data());
|
||||
Outer(scaled_x, x.first, products[3U].data());
|
||||
const double* y_second = y.second.ReadData();
|
||||
const double* x_second = x.second.ReadData();
|
||||
double* result_second = result.second.OverwriteData();
|
||||
for (std::size_t row = 0U; row < kGlobalDofCount; ++row) {
|
||||
for (std::size_t column = 0U; column < kGlobalDofCount; ++column) {
|
||||
const std::size_t index = row * kGlobalDofCount + column;
|
||||
result_second[index] =
|
||||
derivative_y * y_second[index] + derivative_x * x_second[index] +
|
||||
products[0U][index] +
|
||||
derivative_yx * (products[1U][index] + products[2U][index]) +
|
||||
products[3U][index];
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use a bounded ratio for the directional third derivative only. Retain
|
||||
@@ -717,6 +769,7 @@ Jet Atan2(const Jet& y, const Jet& x) {
|
||||
result.mixed_first[i] = sign * angle.mixed_first[i];
|
||||
result.mixed_second[i] = sign * angle.mixed_second[i];
|
||||
}
|
||||
result.constant_derivatives = zero_hessian && angle.constant_derivatives;
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user