lardon3d/src/raw_development_task.cpp
fy59 599be97fbe feat(governor): freeze adaptive GPU-first orchestration
Freeze Compute Governor v2 and asynchronous Vulkan Matcher execution.

Governor now owns production task admission and live resource adaptation,
with GPU-first AUTO selection for validated backends, CPU12 host capacity,
desktop CPU/RAM reserves, UMA accounting, pressure throttling, hysteresis,
and recovery.

Validate and freeze the rolling Vulkan ORB Matcher path, host topology
policy, task capability envelopes, runtime telemetry, restart/durability
contracts, portable CPU fallback, and scientific equivalence.

COMPUTE_GOVERNOR_V2=PASS/FROZEN
ORB_VULKAN_ASYNC_EXECUTION=PASS/FROZEN
MATCHER_GPU=EXISTING_BACKEND_VALIDATED_AND_PREFERRED
2026-08-30 22:17:51 +02:00

210 lines
8.4 KiB
C++

extern "C" {
#include <lardon3d/project.h>
#include <lardon3d/raw_development.h>
#include <lardon3d/raw_development_task.h>
#include <lardon3d/task_queue.h>
}
#include "opencv_task_thread_guard.h"
#include <cstdio>
#include <new>
namespace {
/* One admitted RAW execution owns a conservative allowance for the bounded
* 40 MP decoder image, LibRaw storage, BGR/PNG buffers, validation decode, and
* immutable-asset publication. This is an operational hardware bound, not a
* scientific limit on the number of Captures. The Queue/Governor reservation
* exists only for this one Task callback and is released by Task runtime on
* every terminal path. */
constexpr uint64_t kRawWorkingBytes = UINT64_C(2) * 1024u * 1024u * 1024u;
struct Context {
char project_path[LARDON3D_APP_STATE_PATH_CAPACITY]{};
Lardon3DProjectDb *database{};
Lardon3DResourceGovernor *governor{};
uint64_t capture_id{};
uint64_t source_asset_id{};
};
void destroy(void *value) { delete static_cast<Context *>(value); }
void runtime(const Context *context, Lardon3DAppState *state) {
lardon3d_app_state_init(state);
state->project_loaded = true;
state->project_db = context->database;
state->resource_governor = context->governor;
std::snprintf(state->project_path, sizeof(state->project_path), "%s", context->project_path);
}
bool checkpoint(Context *context, Lardon3DTask *task,
Lardon3DProjectDbRawDevelopmentTaskPhase phase, uint64_t image_id) {
Lardon3DAppState state;
runtime(context, &state);
Lardon3DProjectDbRawDevelopmentTask parameters{
lardon3d_task_id(task), context->capture_id, context->source_asset_id, phase,
image_id != 0, image_id};
return lardon3d_project_checkpoint_raw_development_task(&state, task, &parameters) ==
LARDON3D_PROJECT_TASK_CHECKPOINT_OK;
}
bool run_impl(Lardon3DTask *task, Context *context) {
Lardon3DProjectDbRawDevelopmentTask persisted{};
if (lardon3d_project_db_load_raw_development_task(
context->database, lardon3d_task_id(task), &persisted) != LARDON3D_PROJECT_DB_OK)
return lardon3d_task_fail(task, "État durable du développement RAW invalide.");
if (!lardon3d_task_checkpoint(task)) return false;
if (persisted.phase == LARDON3D_RAW_DEVELOPMENT_TASK_PUBLISHED) {
return lardon3d_task_set_progress(task, 100, "Développement RAW déjà publié.") &&
checkpoint(context, task, LARDON3D_RAW_DEVELOPMENT_TASK_PUBLISHED,
persisted.image_id);
}
Lardon3DProjectDbCapture capture{};
if (lardon3d_project_db_load_capture(context->database, context->capture_id, &capture) !=
LARDON3D_PROJECT_DB_OK)
return lardon3d_task_fail(task, "Capture du développement RAW introuvable.");
Lardon3DAppState state;
runtime(context, &state);
Lardon3DRawDevelopmentOutput output{};
Lardon3DRawDevelopmentResult developed = lardon3d_raw_develop_asset_to_capture(
&state, context->capture_id, context->source_asset_id, lardon3d_task_id(task),
capture.created_at, &output);
if (developed != LARDON3D_RAW_DEVELOPMENT_OK)
return lardon3d_task_fail(task, "Développement RAW S3-B1 impossible.");
/* Immutable output publication may precede this checkpoint if the process
* dies. The frozen developer is content-addressed and exact retry converges;
* once this atomic typed/generic checkpoint succeeds, recovery never guesses
* which image was published. */
if (!lardon3d_task_set_progress(task, 100, "Représentation RAW publiée.") ||
!checkpoint(context, task, LARDON3D_RAW_DEVELOPMENT_TASK_PUBLISHED,
output.image.image_id))
return lardon3d_task_fail(task, "Checkpoint du développement RAW impossible.");
return true;
}
bool run(Lardon3DTask *task, void *value) noexcept {
try {
Lardon3DOpenCvTaskThreadGuard threads(task);
if (!threads.valid())
return lardon3d_task_fail(task, "Contrat CPU OpenCV RAW invalide.");
bool result = run_impl(task, static_cast<Context *>(value));
if (!threads.restore())
return lardon3d_task_fail(task, "Restauration OpenCV RAW impossible.");
return result;
} catch (const std::bad_alloc &) {
return lardon3d_task_fail(task, "Mémoire insuffisante pour le développement RAW.");
} catch (...) {
return lardon3d_task_fail(task, "Erreur interne du développement RAW.");
}
}
void finished(const Lardon3DTask *task, void *value) noexcept {
try {
Lardon3DAppState state;
runtime(static_cast<Context *>(value), &state);
(void)lardon3d_project_checkpoint_task(&state, task);
} catch (...) {
}
}
Context *make_context(const Lardon3DTaskReconstructionContext *runtime_context,
uint64_t capture_id, uint64_t source_asset_id) {
if (!runtime_context || !runtime_context->project_path ||
!runtime_context->project_path[0] || !runtime_context->project_db ||
!runtime_context->resource_governor)
return nullptr;
Context *context = new (std::nothrow) Context;
if (!context) return nullptr;
int written = std::snprintf(context->project_path, sizeof(context->project_path), "%s",
runtime_context->project_path);
if (written <= 0 || written >= static_cast<int>(sizeof(context->project_path))) {
delete context;
return nullptr;
}
context->database = runtime_context->project_db;
context->governor = runtime_context->resource_governor;
context->capture_id = capture_id;
context->source_asset_id = source_asset_id;
return context;
}
} // namespace
extern "C" bool lardon3d_raw_development_task_reconstruct(
const Lardon3DTaskDurableSnapshot *snapshot, void *value,
Lardon3DTaskKindBinding *binding) {
try {
auto *runtime_context = static_cast<Lardon3DTaskReconstructionContext *>(value);
if (!snapshot || !runtime_context || !binding) return false;
Lardon3DProjectDbRawDevelopmentTask persisted{};
if (lardon3d_project_db_load_raw_development_task(
runtime_context->project_db, snapshot->id, &persisted) != LARDON3D_PROJECT_DB_OK)
return false;
Context *context = make_context(runtime_context, persisted.capture_id,
persisted.source_asset_id);
if (!context) return false;
*binding = {};
binding->callback = run;
binding->userdata = context;
binding->userdata_destroy = destroy;
binding->finished_callback = finished;
binding->finished_userdata = context;
return true;
} catch (...) {
return false;
}
}
extern "C" Lardon3DTask *lardon3d_project_create_raw_development_task(
Lardon3DAppState *state, uint64_t capture_id, uint64_t source_asset_id,
uint64_t *task_id) {
if (task_id) *task_id = 0;
try {
if (!state || !state->project_loaded || !state->project_db ||
!state->resource_governor || !task_id || capture_id == 0 || source_asset_id == 0)
return nullptr;
Lardon3DTaskReconstructionContext runtime_context{
state->project_path, state->project_db, state->resource_governor, nullptr};
Context *context = make_context(&runtime_context, capture_id, source_asset_id);
if (!context) return nullptr;
uint64_t id = 0;
if (lardon3d_project_db_allocate_task_id(state->project_db, &id) != LARDON3D_PROJECT_DB_OK) {
delete context;
return nullptr;
}
Lardon3DResourceEstimate estimate{kRawWorkingBytes + sizeof(Context), 0, 0, 0,
1, 1, 1, 0, 1, LARDON3D_RESOURCE_TASK_MIXED};
Lardon3DTask *task = lardon3d_task_create_typed(
"Développement RAW S3-B1", &estimate, LARDON3D_RAW_DEVELOPMENT_TASK_KIND,
LARDON3D_RAW_DEVELOPMENT_TASK_KIND_VERSION, run, context, destroy);
if (!task || !lardon3d_task_assign_id(task, id) ||
!lardon3d_task_set_finished_callback(task, finished, context) ||
!checkpoint(context, task, LARDON3D_RAW_DEVELOPMENT_TASK_PENDING, 0)) {
lardon3d_task_destroy(task);
return nullptr;
}
*task_id = id;
return task;
} catch (...) {
return nullptr;
}
}
extern "C" bool lardon3d_project_enqueue_raw_development(
Lardon3DAppState *state, uint64_t capture_id, uint64_t source_asset_id,
uint64_t *task_id) {
try {
if (!state || !state->task_queue) return false;
Lardon3DTask *task = lardon3d_project_create_raw_development_task(
state, capture_id, source_asset_id, task_id);
if (!task) return false;
if (!lardon3d_task_queue_add(state->task_queue, task, nullptr)) {
lardon3d_task_destroy(task);
return false;
}
return true;
} catch (...) {
return false;
}
}