Add deterministic diagnostics and OOM handling

This commit is contained in:
Carl Niklas Rydberg 2025-12-22 06:55:29 +01:00
parent b891b588ee
commit e838e2c977
6 changed files with 623 additions and 20 deletions

View file

@ -49,6 +49,8 @@ typedef struct {
size_t diagnostics_len; size_t diagnostics_len;
} amduat_pel_execution_result_value_t; } amduat_pel_execution_result_value_t;
void amduat_pel_execution_result_free(amduat_pel_execution_result_value_t *result);
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" */ } /* extern "C" */
#endif #endif

View file

@ -4,9 +4,11 @@
#include "amduat/pel/opreg_kernel_params.h" #include "amduat/pel/opreg_kernel_params.h"
#include "amduat/pel/program_dag_desc.h" #include "amduat/pel/program_dag_desc.h"
#include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -42,13 +44,153 @@ static void amduat_set_result(amduat_pel_execution_result_value_t *result,
if (result == NULL) { if (result == NULL) {
return; return;
} }
amduat_pel_execution_result_free(result);
result->pel1_version = 1; result->pel1_version = 1;
result->status = status; result->status = status;
result->scheme_ref = amduat_pel_program_dag_scheme_ref(); result->scheme_ref = amduat_pel_program_dag_scheme_ref();
result->summary.kind = kind; result->summary.kind = kind;
result->summary.status_code = status_code; result->summary.status_code = status_code;
result->diagnostics = NULL; }
result->diagnostics_len = 0;
static bool amduat_diag_set(
amduat_pel_execution_result_value_t *result,
uint32_t code,
const uint8_t *message,
size_t message_len) {
amduat_pel_diagnostic_entry_t *entries;
uint8_t *message_copy = NULL;
if (result == NULL) {
return false;
}
amduat_pel_execution_result_free(result);
if (message_len != 0) {
message_copy = (uint8_t *)malloc(message_len);
if (message_copy == NULL) {
return false;
}
if (message != NULL) {
memcpy(message_copy, message, message_len);
}
}
entries = (amduat_pel_diagnostic_entry_t *)calloc(1, sizeof(*entries));
if (entries == NULL) {
free(message_copy);
return false;
}
entries[0].code = code;
entries[0].message = amduat_octets(message_copy, message_len);
result->diagnostics = entries;
result->diagnostics_len = 1;
return true;
}
static bool amduat_diag_setf(
amduat_pel_execution_result_value_t *result,
uint32_t code,
const char *fmt,
...) {
va_list ap;
va_list ap_copy;
int needed;
size_t message_len;
uint8_t *buffer;
if (result == NULL || fmt == NULL) {
return false;
}
va_start(ap, fmt);
va_copy(ap_copy, ap);
needed = vsnprintf(NULL, 0, fmt, ap_copy);
va_end(ap_copy);
if (needed < 0) {
va_end(ap);
return false;
}
message_len = (size_t)needed;
buffer = NULL;
if (message_len != 0) {
buffer = (uint8_t *)malloc(message_len + 1);
if (buffer == NULL) {
va_end(ap);
return false;
}
if (vsnprintf((char *)buffer, message_len + 1, fmt, ap) < 0) {
free(buffer);
va_end(ap);
return false;
}
}
va_end(ap);
if (!amduat_diag_set(result, code, buffer, message_len)) {
free(buffer);
return false;
}
free(buffer);
return true;
}
enum {
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID = 0x00010001u,
AMDUAT_PEL_DAG_DIAG_UNKNOWN_OP = 0x00010002u,
AMDUAT_PEL_DAG_DIAG_PARAM_DECODE_FAILED = 0x00010003u,
AMDUAT_PEL_DAG_DIAG_INPUT_ARITY = 0x00010004u,
AMDUAT_PEL_DAG_DIAG_INVALID_INPUT_KIND = 0x00010005u,
AMDUAT_PEL_DAG_DIAG_MISSING_NODE = 0x00010006u,
AMDUAT_PEL_DAG_DIAG_DUPLICATE_NODE = 0x00010007u,
AMDUAT_PEL_DAG_DIAG_CYCLE = 0x00010008u,
AMDUAT_PEL_DAG_DIAG_ROOT_OUTPUT_INDEX = 0x00010009u,
AMDUAT_PEL_DAG_DIAG_INVALID_INPUT_INDEX = 0x00020001u,
AMDUAT_PEL_DAG_DIAG_OUTPUT_INDEX = 0x0001000au,
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED = 0x00030001u
};
typedef enum {
AMDUAT_PEL_PREP_ERROR_NONE = 0,
AMDUAT_PEL_PREP_ERROR_NULL_NODES,
AMDUAT_PEL_PREP_ERROR_NULL_ROOTS,
AMDUAT_PEL_PREP_ERROR_ROOTS_WITHOUT_NODES,
AMDUAT_PEL_PREP_ERROR_DUPLICATE_NODE,
AMDUAT_PEL_PREP_ERROR_MISSING_NODE,
AMDUAT_PEL_PREP_ERROR_INVALID_INPUT_KIND,
AMDUAT_PEL_PREP_ERROR_INVALID_OP_NAME,
AMDUAT_PEL_PREP_ERROR_INVALID_OP_UTF8,
AMDUAT_PEL_PREP_ERROR_NULL_INPUTS,
AMDUAT_PEL_PREP_ERROR_NULL_PARAMS,
AMDUAT_PEL_PREP_ERROR_UNKNOWN_OP,
AMDUAT_PEL_PREP_ERROR_INPUT_ARITY,
AMDUAT_PEL_PREP_ERROR_PARAM_DECODE,
AMDUAT_PEL_PREP_ERROR_CYCLE,
AMDUAT_PEL_PREP_ERROR_ROOT_MISSING,
AMDUAT_PEL_PREP_ERROR_ROOT_OUTPUT_INDEX
} amduat_pel_program_prep_error_t;
typedef struct {
amduat_pel_program_prep_error_t kind;
amduat_pel_node_id_t node_id;
uint32_t index;
uint32_t min;
uint32_t max;
} amduat_pel_program_prep_error_info_t;
static void amduat_pel_prep_error_reset(
amduat_pel_program_prep_error_info_t *error) {
if (error == NULL) {
return;
}
error->kind = AMDUAT_PEL_PREP_ERROR_NONE;
error->node_id = 0;
error->index = 0;
error->min = 0;
error->max = 0;
} }
static bool amduat_utf8_is_valid(amduat_octets_t value) { static bool amduat_utf8_is_valid(amduat_octets_t value) {
@ -130,9 +272,11 @@ static int amduat_find_node_index(const amduat_pel_program_t *program,
return -1; return -1;
} }
static bool amduat_build_node_order(const amduat_pel_program_t *program, static bool amduat_build_node_order(
size_t *out_order, const amduat_pel_program_t *program,
bool *out_oom) { size_t *out_order,
bool *out_oom,
amduat_pel_program_prep_error_info_t *out_error) {
size_t n; size_t n;
size_t *deps; size_t *deps;
bool *placed; bool *placed;
@ -141,6 +285,7 @@ static bool amduat_build_node_order(const amduat_pel_program_t *program,
if (out_oom != NULL) { if (out_oom != NULL) {
*out_oom = false; *out_oom = false;
} }
amduat_pel_prep_error_reset(out_error);
n = program->nodes_len; n = program->nodes_len;
deps = NULL; deps = NULL;
placed = NULL; placed = NULL;
@ -164,6 +309,10 @@ static bool amduat_build_node_order(const amduat_pel_program_t *program,
size_t j; size_t j;
for (j = i + 1; j < n; ++j) { for (j = i + 1; j < n; ++j) {
if (program->nodes[i].id == program->nodes[j].id) { if (program->nodes[i].id == program->nodes[j].id) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_DUPLICATE_NODE;
out_error->node_id = program->nodes[i].id;
}
free(deps); free(deps);
free(placed); free(placed);
return false; return false;
@ -180,12 +329,20 @@ static bool amduat_build_node_order(const amduat_pel_program_t *program,
const amduat_pel_dag_input_t *input = &node->inputs[j]; const amduat_pel_dag_input_t *input = &node->inputs[j];
if (input->kind == AMDUAT_PEL_DAG_INPUT_NODE) { if (input->kind == AMDUAT_PEL_DAG_INPUT_NODE) {
if (amduat_find_node_index(program, input->value.node.node_id) < 0) { if (amduat_find_node_index(program, input->value.node.node_id) < 0) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_MISSING_NODE;
out_error->node_id = input->value.node.node_id;
}
free(deps); free(deps);
free(placed); free(placed);
return false; return false;
} }
deps[i] += 1; deps[i] += 1;
} else if (input->kind != AMDUAT_PEL_DAG_INPUT_EXTERNAL) { } else if (input->kind != AMDUAT_PEL_DAG_INPUT_EXTERNAL) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_INVALID_INPUT_KIND;
out_error->node_id = node->id;
}
free(deps); free(deps);
free(placed); free(placed);
return false; return false;
@ -209,6 +366,9 @@ static bool amduat_build_node_order(const amduat_pel_program_t *program,
} }
if (best == SIZE_MAX) { if (best == SIZE_MAX) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_CYCLE;
}
free(deps); free(deps);
free(placed); free(placed);
return false; return false;
@ -232,6 +392,9 @@ static bool amduat_build_node_order(const amduat_pel_program_t *program,
if (input->kind == AMDUAT_PEL_DAG_INPUT_NODE && if (input->kind == AMDUAT_PEL_DAG_INPUT_NODE &&
input->value.node.node_id == program->nodes[best].id) { input->value.node.node_id == program->nodes[best].id) {
if (deps[j] == 0) { if (deps[j] == 0) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_CYCLE;
}
free(deps); free(deps);
free(placed); free(placed);
return false; return false;
@ -322,25 +485,37 @@ typedef enum {
static amduat_pel_program_prepare_result_t amduat_program_prepare( static amduat_pel_program_prepare_result_t amduat_program_prepare(
const amduat_pel_program_t *program, const amduat_pel_program_t *program,
amduat_pel_program_dag_prepared_t *prepared) { amduat_pel_program_dag_prepared_t *prepared,
amduat_pel_program_prep_error_info_t *out_error) {
size_t i; size_t i;
bool oom; bool oom;
if (program == NULL || prepared == NULL) { if (program == NULL || prepared == NULL) {
amduat_pel_prep_error_reset(out_error);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
amduat_prepared_reset(prepared); amduat_prepared_reset(prepared);
amduat_pel_prep_error_reset(out_error);
if (program->nodes_len > 0 && program->nodes == NULL) { if (program->nodes_len > 0 && program->nodes == NULL) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_NULL_NODES;
}
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (program->roots_len > 0 && program->roots == NULL) { if (program->roots_len > 0 && program->roots == NULL) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_NULL_ROOTS;
}
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (program->nodes_len == 0) { if (program->nodes_len == 0) {
if (program->roots_len != 0) { if (program->roots_len != 0) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_ROOTS_WITHOUT_NODES;
}
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
return AMDUAT_PEL_PROGRAM_PREP_OK; return AMDUAT_PEL_PROGRAM_PREP_OK;
@ -364,34 +539,65 @@ static amduat_pel_program_prepare_result_t amduat_program_prepare(
const amduat_pel_kernel_op_desc_t *desc; const amduat_pel_kernel_op_desc_t *desc;
if (node->op.name.len > 0 && node->op.name.data == NULL) { if (node->op.name.len > 0 && node->op.name.data == NULL) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_INVALID_OP_NAME;
out_error->node_id = node->id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (!amduat_utf8_is_valid(node->op.name)) { if (!amduat_utf8_is_valid(node->op.name)) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_INVALID_OP_UTF8;
out_error->node_id = node->id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (node->inputs_len > 0 && node->inputs == NULL) { if (node->inputs_len > 0 && node->inputs == NULL) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_NULL_INPUTS;
out_error->node_id = node->id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (node->params.len > 0 && node->params.data == NULL) { if (node->params.len > 0 && node->params.data == NULL) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_NULL_PARAMS;
out_error->node_id = node->id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
desc = amduat_pel_kernel_op_lookup(node->op.name, node->op.version); desc = amduat_pel_kernel_op_lookup(node->op.name, node->op.version);
if (desc == NULL) { if (desc == NULL) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_UNKNOWN_OP;
out_error->node_id = node->id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (node->inputs_len < desc->min_inputs || if (node->inputs_len < desc->min_inputs ||
node->inputs_len > desc->max_inputs) { node->inputs_len > desc->max_inputs) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_INPUT_ARITY;
out_error->node_id = node->id;
out_error->index = (uint32_t)node->inputs_len;
out_error->min = (uint32_t)desc->min_inputs;
out_error->max = (uint32_t)desc->max_inputs;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (!amduat_pel_kernel_params_decode(desc, node->params, if (!amduat_pel_kernel_params_decode(desc, node->params,
&prepared->params[i])) { &prepared->params[i])) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_PARAM_DECODE;
out_error->node_id = node->id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
@ -400,7 +606,7 @@ static amduat_pel_program_prepare_result_t amduat_program_prepare(
} }
oom = false; oom = false;
if (!amduat_build_node_order(program, prepared->order, &oom)) { if (!amduat_build_node_order(program, prepared->order, &oom, out_error)) {
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return oom ? AMDUAT_PEL_PROGRAM_PREP_OOM return oom ? AMDUAT_PEL_PROGRAM_PREP_OOM
: AMDUAT_PEL_PROGRAM_PREP_INVALID; : AMDUAT_PEL_PROGRAM_PREP_INVALID;
@ -415,6 +621,10 @@ static amduat_pel_program_prepare_result_t amduat_program_prepare(
int dep_index = amduat_find_node_index(program, int dep_index = amduat_find_node_index(program,
input->value.node.node_id); input->value.node.node_id);
if (dep_index < 0) { if (dep_index < 0) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_MISSING_NODE;
out_error->node_id = input->value.node.node_id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
@ -433,11 +643,20 @@ static amduat_pel_program_prepare_result_t amduat_program_prepare(
for (i = 0; i < program->roots_len; ++i) { for (i = 0; i < program->roots_len; ++i) {
int root_index = amduat_find_node_index(program, program->roots[i].node_id); int root_index = amduat_find_node_index(program, program->roots[i].node_id);
if (root_index < 0) { if (root_index < 0) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_ROOT_MISSING;
out_error->node_id = program->roots[i].node_id;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
if (program->roots[i].output_index >= if (program->roots[i].output_index >=
prepared->ops[root_index]->outputs_len) { prepared->ops[root_index]->outputs_len) {
if (out_error != NULL) {
out_error->kind = AMDUAT_PEL_PREP_ERROR_ROOT_OUTPUT_INDEX;
out_error->node_id = program->roots[i].node_id;
out_error->index = program->roots[i].output_index;
}
amduat_prepared_free(prepared); amduat_prepared_free(prepared);
return AMDUAT_PEL_PROGRAM_PREP_INVALID; return AMDUAT_PEL_PROGRAM_PREP_INVALID;
} }
@ -451,7 +670,7 @@ bool amduat_pel_program_dag_validate(const amduat_pel_program_t *program) {
amduat_pel_program_prepare_result_t prep_result; amduat_pel_program_prepare_result_t prep_result;
amduat_prepared_reset(&prepared); amduat_prepared_reset(&prepared);
prep_result = amduat_program_prepare(program, &prepared); prep_result = amduat_program_prepare(program, &prepared, NULL);
amduat_prepared_free(&prepared); amduat_prepared_free(&prepared);
return prep_result == AMDUAT_PEL_PROGRAM_PREP_OK; return prep_result == AMDUAT_PEL_PROGRAM_PREP_OK;
} }
@ -467,6 +686,7 @@ static bool amduat_pel_program_dag_exec_internal(
amduat_pel_program_dag_trace_t *out_trace) { amduat_pel_program_dag_trace_t *out_trace) {
amduat_pel_program_dag_prepared_t prepared; amduat_pel_program_dag_prepared_t prepared;
amduat_pel_program_prepare_result_t prep_result; amduat_pel_program_prepare_result_t prep_result;
amduat_pel_program_prep_error_info_t prep_error;
amduat_pel_program_dag_node_result_t *node_results; amduat_pel_program_dag_node_result_t *node_results;
amduat_artifact_t *resolved_inputs; amduat_artifact_t *resolved_inputs;
size_t max_inputs; size_t max_inputs;
@ -477,6 +697,7 @@ static bool amduat_pel_program_dag_exec_internal(
if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) { if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) {
return false; return false;
} }
memset(out_result, 0, sizeof(*out_result));
(void)params; (void)params;
*out_outputs = NULL; *out_outputs = NULL;
@ -487,13 +708,125 @@ static bool amduat_pel_program_dag_exec_internal(
} }
amduat_prepared_reset(&prepared); amduat_prepared_reset(&prepared);
prep_result = amduat_program_prepare(program, &prepared); prep_result = amduat_program_prepare(program, &prepared, &prep_error);
if (prep_result == AMDUAT_PEL_PROGRAM_PREP_OOM) { if (prep_result == AMDUAT_PEL_PROGRAM_PREP_OOM) {
return false; amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
AMDUAT_PEL_KERNEL_STATUS_OOM);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
"runtime failed: out of memory");
return true;
} }
if (prep_result != AMDUAT_PEL_PROGRAM_PREP_OK) { if (prep_result != AMDUAT_PEL_PROGRAM_PREP_OK) {
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM, amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
switch (prep_error.kind) {
case AMDUAT_PEL_PREP_ERROR_NULL_NODES:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: nodes missing");
break;
case AMDUAT_PEL_PREP_ERROR_NULL_ROOTS:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: roots missing");
break;
case AMDUAT_PEL_PREP_ERROR_ROOTS_WITHOUT_NODES:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: roots without nodes");
break;
case AMDUAT_PEL_PREP_ERROR_DUPLICATE_NODE:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_DUPLICATE_NODE,
"invalid program: duplicate node id %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_MISSING_NODE:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_MISSING_NODE,
"invalid program: missing node id %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_INVALID_INPUT_KIND:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_INVALID_INPUT_KIND,
"invalid program: invalid input kind in node %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_INVALID_OP_NAME:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: op name missing in node %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_INVALID_OP_UTF8:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: op name utf8 invalid in node %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_NULL_INPUTS:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: inputs missing in node %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_NULL_PARAMS:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: params missing in node %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_UNKNOWN_OP:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_UNKNOWN_OP,
"invalid program: unknown op in node %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_INPUT_ARITY:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_INPUT_ARITY,
"invalid program: input arity in node %u "
"(inputs=%u min=%u max=%u)",
(unsigned int)prep_error.node_id,
(unsigned int)prep_error.index,
(unsigned int)prep_error.min,
(unsigned int)prep_error.max);
break;
case AMDUAT_PEL_PREP_ERROR_PARAM_DECODE:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_PARAM_DECODE_FAILED,
"invalid program: param decode failed in node %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_CYCLE:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_CYCLE,
"invalid program: dependency cycle");
break;
case AMDUAT_PEL_PREP_ERROR_ROOT_MISSING:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_MISSING_NODE,
"invalid program: root node missing id %u",
(unsigned int)prep_error.node_id);
break;
case AMDUAT_PEL_PREP_ERROR_ROOT_OUTPUT_INDEX:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_ROOT_OUTPUT_INDEX,
"invalid program: root output index out of range "
"for node %u (index=%u)",
(unsigned int)prep_error.node_id,
(unsigned int)prep_error.index);
break;
case AMDUAT_PEL_PREP_ERROR_NONE:
default:
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_STRUCTURAL_INVALID,
"invalid program: structural validation failed");
break;
}
amduat_prepared_free(&prepared); amduat_prepared_free(&prepared);
return true; return true;
} }
@ -516,6 +849,9 @@ static bool amduat_pel_program_dag_exec_internal(
if (needs_inputs) { if (needs_inputs) {
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS, amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS,
AMDUAT_PEL_EXEC_ERROR_INPUTS, 3); AMDUAT_PEL_EXEC_ERROR_INPUTS, 3);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_INVALID_INPUT_INDEX,
"invalid inputs: missing external inputs");
amduat_prepared_free(&prepared); amduat_prepared_free(&prepared);
return true; return true;
} }
@ -532,7 +868,13 @@ static bool amduat_pel_program_dag_exec_internal(
program->nodes_len, sizeof(*node_results)); program->nodes_len, sizeof(*node_results));
if (node_results == NULL) { if (node_results == NULL) {
amduat_prepared_free(&prepared); amduat_prepared_free(&prepared);
return false; amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
AMDUAT_PEL_KERNEL_STATUS_OOM);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
"runtime failed: out of memory");
return true;
} }
for (i = 0; i < program->nodes_len; ++i) { for (i = 0; i < program->nodes_len; ++i) {
node_results[i].status = AMDUAT_PEL_NODE_TRACE_SKIPPED; node_results[i].status = AMDUAT_PEL_NODE_TRACE_SKIPPED;
@ -553,7 +895,13 @@ static bool amduat_pel_program_dag_exec_internal(
if (resolved_inputs == NULL) { if (resolved_inputs == NULL) {
amduat_node_results_free(node_results, program->nodes_len); amduat_node_results_free(node_results, program->nodes_len);
amduat_prepared_free(&prepared); amduat_prepared_free(&prepared);
return false; amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
AMDUAT_PEL_KERNEL_STATUS_OOM);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
"runtime failed: out of memory");
return true;
} }
} }
@ -569,6 +917,10 @@ static bool amduat_pel_program_dag_exec_internal(
if (input->value.external.input_index >= inputs_len) { if (input->value.external.input_index >= inputs_len) {
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS, amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS,
AMDUAT_PEL_EXEC_ERROR_INPUTS, 3); AMDUAT_PEL_EXEC_ERROR_INPUTS, 3);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_INVALID_INPUT_INDEX,
"invalid inputs: missing input index %u",
(unsigned int)input->value.external.input_index);
free(resolved_inputs); free(resolved_inputs);
goto finish; goto finish;
} }
@ -581,6 +933,11 @@ static bool amduat_pel_program_dag_exec_internal(
node_results[dep_index].outputs_len) { node_results[dep_index].outputs_len) {
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM, amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_OUTPUT_INDEX,
"invalid program: node %u output index %u out of range",
(unsigned int)input->value.node.node_id,
(unsigned int)input->value.node.output_index);
free(resolved_inputs); free(resolved_inputs);
goto finish; goto finish;
} }
@ -589,6 +946,10 @@ static bool amduat_pel_program_dag_exec_internal(
} else { } else {
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM, amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_INVALID_INPUT_KIND,
"invalid program: invalid input kind in node %u",
(unsigned int)node->id);
free(resolved_inputs); free(resolved_inputs);
goto finish; goto finish;
} }
@ -601,6 +962,7 @@ static bool amduat_pel_program_dag_exec_internal(
&node_results[node_index].outputs_len, &status_code)) { &node_results[node_index].outputs_len, &status_code)) {
if (status_code == AMDUAT_PEL_KERNEL_STATUS_OOM) { if (status_code == AMDUAT_PEL_KERNEL_STATUS_OOM) {
free(resolved_inputs); free(resolved_inputs);
resolved_inputs = NULL;
goto oom_finish; goto oom_finish;
} }
if (status_code == 2 || status_code == 3 || status_code == 0) { if (status_code == 2 || status_code == 3 || status_code == 0) {
@ -611,6 +973,11 @@ static bool amduat_pel_program_dag_exec_internal(
any_node_executed = true; any_node_executed = true;
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED, amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
AMDUAT_PEL_EXEC_ERROR_RUNTIME, status_code); AMDUAT_PEL_EXEC_ERROR_RUNTIME, status_code);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
"runtime failed: node %u status_code %u",
(unsigned int)node->id,
(unsigned int)status_code);
free(resolved_inputs); free(resolved_inputs);
goto finish; goto finish;
} }
@ -624,6 +991,7 @@ static bool amduat_pel_program_dag_exec_internal(
program->roots_len, sizeof(**out_outputs)); program->roots_len, sizeof(**out_outputs));
if (*out_outputs == NULL) { if (*out_outputs == NULL) {
free(resolved_inputs); free(resolved_inputs);
resolved_inputs = NULL;
goto oom_finish; goto oom_finish;
} }
} }
@ -635,6 +1003,12 @@ static bool amduat_pel_program_dag_exec_internal(
node_results[root_index].outputs_len) { node_results[root_index].outputs_len) {
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM, amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_ROOT_OUTPUT_INDEX,
"invalid program: root output index out of range "
"for node %u (index=%u)",
(unsigned int)program->roots[i].node_id,
(unsigned int)program->roots[i].output_index);
amduat_pel_program_dag_free_outputs(*out_outputs, amduat_pel_program_dag_free_outputs(*out_outputs,
program->roots_len); program->roots_len);
*out_outputs = NULL; *out_outputs = NULL;
@ -651,6 +1025,7 @@ static bool amduat_pel_program_dag_exec_internal(
*out_outputs = NULL; *out_outputs = NULL;
*out_outputs_len = 0; *out_outputs_len = 0;
free(resolved_inputs); free(resolved_inputs);
resolved_inputs = NULL;
goto oom_finish; goto oom_finish;
} }
} }
@ -681,6 +1056,19 @@ finish:
return true; return true;
oom_finish: oom_finish:
amduat_set_result(out_result, AMDUAT_PEL_EXEC_STATUS_RUNTIME_FAILED,
AMDUAT_PEL_EXEC_ERROR_RUNTIME,
AMDUAT_PEL_KERNEL_STATUS_OOM);
amduat_diag_setf(out_result,
AMDUAT_PEL_DAG_DIAG_RUNTIME_FAILED,
"runtime failed: out of memory");
if (out_outputs != NULL && *out_outputs != NULL) {
amduat_pel_program_dag_free_outputs(*out_outputs, *out_outputs_len);
*out_outputs = NULL;
*out_outputs_len = 0;
}
free(resolved_inputs);
resolved_inputs = NULL;
if (wants_trace) { if (wants_trace) {
out_trace->any_node_executed = any_node_executed; out_trace->any_node_executed = any_node_executed;
if (any_node_executed) { if (any_node_executed) {
@ -695,7 +1083,7 @@ oom_finish:
node_results = NULL; node_results = NULL;
} }
amduat_prepared_free(&prepared); amduat_prepared_free(&prepared);
return false; return true;
} }
bool amduat_pel_program_dag_exec( bool amduat_pel_program_dag_exec(

View file

@ -6,8 +6,126 @@
#include "amduat/pel/program_dag.h" #include "amduat/pel/program_dag.h"
#include "amduat/pel/program_dag_desc.h" #include "amduat/pel/program_dag_desc.h"
#include <stdarg.h>
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
void amduat_pel_execution_result_free(
amduat_pel_execution_result_value_t *result) {
size_t i;
if (result == NULL) {
return;
}
if (result->diagnostics != NULL) {
for (i = 0; i < result->diagnostics_len; ++i) {
free((void *)result->diagnostics[i].message.data);
result->diagnostics[i].message.data = NULL;
result->diagnostics[i].message.len = 0;
}
}
free(result->diagnostics);
result->diagnostics = NULL;
result->diagnostics_len = 0;
}
static bool amduat_diag_set(
amduat_pel_execution_result_value_t *result,
uint32_t code,
const uint8_t *message,
size_t message_len) {
amduat_pel_diagnostic_entry_t *entries;
uint8_t *message_copy = NULL;
if (result == NULL) {
return false;
}
amduat_pel_execution_result_free(result);
if (message_len != 0) {
message_copy = (uint8_t *)malloc(message_len);
if (message_copy == NULL) {
return false;
}
if (message != NULL) {
memcpy(message_copy, message, message_len);
}
}
entries = (amduat_pel_diagnostic_entry_t *)calloc(1, sizeof(*entries));
if (entries == NULL) {
free(message_copy);
return false;
}
entries[0].code = code;
entries[0].message = amduat_octets(message_copy, message_len);
result->diagnostics = entries;
result->diagnostics_len = 1;
return true;
}
static bool amduat_diag_setf(
amduat_pel_execution_result_value_t *result,
uint32_t code,
const char *fmt,
...) {
va_list ap;
va_list ap_copy;
int needed;
size_t message_len;
uint8_t *buffer;
if (result == NULL || fmt == NULL) {
return false;
}
va_start(ap, fmt);
va_copy(ap_copy, ap);
needed = vsnprintf(NULL, 0, fmt, ap_copy);
va_end(ap_copy);
if (needed < 0) {
va_end(ap);
return false;
}
message_len = (size_t)needed;
buffer = NULL;
if (message_len != 0) {
buffer = (uint8_t *)malloc(message_len + 1);
if (buffer == NULL) {
va_end(ap);
return false;
}
if (vsnprintf((char *)buffer, message_len + 1, fmt, ap) < 0) {
free(buffer);
va_end(ap);
return false;
}
}
va_end(ap);
if (!amduat_diag_set(result, code, buffer, message_len)) {
free(buffer);
return false;
}
free(buffer);
return true;
}
enum {
AMDUAT_PEL_DAG_DIAG_DECODE_FAILED = 0x00010001u,
AMDUAT_PEL_DAG_DIAG_WRONG_TYPE_TAG = 0x00010002u,
AMDUAT_PEL_DAG_DIAG_INPUTS_MISSING = 0x00020001u
};
bool amduat_pel_surf_run_with_result(amduat_asl_store_t *store, bool amduat_pel_surf_run_with_result(amduat_asl_store_t *store,
amduat_reference_t scheme_ref, amduat_reference_t scheme_ref,
amduat_reference_t program_ref, amduat_reference_t program_ref,
@ -63,20 +181,21 @@ static bool amduat_pel_exec_program_bytes_unchecked(
if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) { if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) {
return false; return false;
} }
memset(out_result, 0, sizeof(*out_result));
if (inputs_len != 0 && inputs == NULL) { if (inputs_len != 0 && inputs == NULL) {
out_result->pel1_version = 1; out_result->pel1_version = 1;
out_result->status = AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS; out_result->status = AMDUAT_PEL_EXEC_STATUS_INVALID_INPUTS;
out_result->scheme_ref = amduat_pel_program_dag_scheme_ref(); out_result->scheme_ref = amduat_pel_program_dag_scheme_ref();
out_result->summary.kind = AMDUAT_PEL_EXEC_ERROR_INPUTS; out_result->summary.kind = AMDUAT_PEL_EXEC_ERROR_INPUTS;
out_result->summary.status_code = 3; out_result->summary.status_code = 3;
out_result->diagnostics = NULL; amduat_diag_setf(out_result,
out_result->diagnostics_len = 0; AMDUAT_PEL_DAG_DIAG_INPUTS_MISSING,
"invalid inputs: missing external inputs");
return true; return true;
} }
*out_outputs = NULL; *out_outputs = NULL;
*out_outputs_len = 0; *out_outputs_len = 0;
memset(out_result, 0, sizeof(*out_result));
memset(&program, 0, sizeof(program)); memset(&program, 0, sizeof(program));
decode_status = amduat_enc_pel_program_dag_decode_v1_ex(program_bytes, decode_status = amduat_enc_pel_program_dag_decode_v1_ex(program_bytes,
@ -90,8 +209,9 @@ static bool amduat_pel_exec_program_bytes_unchecked(
out_result->scheme_ref = amduat_pel_program_dag_scheme_ref(); out_result->scheme_ref = amduat_pel_program_dag_scheme_ref();
out_result->summary.kind = AMDUAT_PEL_EXEC_ERROR_PROGRAM; out_result->summary.kind = AMDUAT_PEL_EXEC_ERROR_PROGRAM;
out_result->summary.status_code = 2; out_result->summary.status_code = 2;
out_result->diagnostics = NULL; amduat_diag_setf(out_result,
out_result->diagnostics_len = 0; AMDUAT_PEL_DAG_DIAG_DECODE_FAILED,
"invalid program: decode failed");
return true; return true;
} }
@ -116,6 +236,7 @@ bool amduat_pel_exec_program_artifact(amduat_artifact_t program_artifact,
if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) { if (out_outputs == NULL || out_outputs_len == NULL || out_result == NULL) {
return false; return false;
} }
memset(out_result, 0, sizeof(*out_result));
if (!program_artifact.has_type_tag || if (!program_artifact.has_type_tag ||
program_artifact.type_tag.tag_id != AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1) { program_artifact.type_tag.tag_id != AMDUAT_PEL_TYPE_TAG_PROGRAM_DAG_1) {
@ -124,8 +245,9 @@ bool amduat_pel_exec_program_artifact(amduat_artifact_t program_artifact,
out_result->scheme_ref = amduat_pel_program_dag_scheme_ref(); out_result->scheme_ref = amduat_pel_program_dag_scheme_ref();
out_result->summary.kind = AMDUAT_PEL_EXEC_ERROR_PROGRAM; out_result->summary.kind = AMDUAT_PEL_EXEC_ERROR_PROGRAM;
out_result->summary.status_code = 2; out_result->summary.status_code = 2;
out_result->diagnostics = NULL; amduat_diag_setf(out_result,
out_result->diagnostics_len = 0; AMDUAT_PEL_DAG_DIAG_WRONG_TYPE_TAG,
"invalid program: wrong type tag");
*out_outputs = NULL; *out_outputs = NULL;
*out_outputs_len = 0; *out_outputs_len = 0;
return true; return true;

View file

@ -6,9 +6,11 @@
#include "amduat/pel/program_dag.h" #include "amduat/pel/program_dag.h"
#include "amduat/pel/program_dag_desc.h" #include "amduat/pel/program_dag_desc.h"
#include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
@ -45,6 +47,66 @@ static void amduat_init_core_result(amduat_pel_execution_result_value_t *result,
result->diagnostics_len = 0; result->diagnostics_len = 0;
} }
static bool amduat_surf_diag_setf(
amduat_pel_execution_result_value_t *result,
uint32_t code,
const char *fmt,
...) {
va_list ap;
va_list ap_copy;
int needed;
size_t message_len;
uint8_t *buffer;
amduat_pel_diagnostic_entry_t *entries;
if (result == NULL || fmt == NULL) {
return false;
}
amduat_pel_execution_result_free(result);
va_start(ap, fmt);
va_copy(ap_copy, ap);
needed = vsnprintf(NULL, 0, fmt, ap_copy);
va_end(ap_copy);
if (needed < 0) {
va_end(ap);
return false;
}
message_len = (size_t)needed;
buffer = NULL;
if (message_len != 0) {
buffer = (uint8_t *)malloc(message_len + 1);
if (buffer == NULL) {
va_end(ap);
return false;
}
if (vsnprintf((char *)buffer, message_len + 1, fmt, ap) < 0) {
free(buffer);
va_end(ap);
return false;
}
}
va_end(ap);
entries = (amduat_pel_diagnostic_entry_t *)calloc(1, sizeof(*entries));
if (entries == NULL) {
free(buffer);
return false;
}
entries[0].code = code;
entries[0].message = amduat_octets(buffer, message_len);
result->diagnostics = entries;
result->diagnostics_len = 1;
return true;
}
enum {
AMDUAT_PEL_DAG_DIAG_DECODE_FAILED = 0x00010001u,
AMDUAT_PEL_DAG_DIAG_WRONG_TYPE_TAG = 0x00010002u
};
static bool amduat_store_error_map(amduat_asl_store_error_t err, static bool amduat_store_error_map(amduat_asl_store_error_t err,
amduat_pel_store_error_code_t *out_code) { amduat_pel_store_error_code_t *out_code) {
if (out_code == NULL) { if (out_code == NULL) {
@ -401,6 +463,9 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
amduat_init_core_result(&core_result, scheme_ref, amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
amduat_surf_diag_setf(&core_result,
AMDUAT_PEL_DAG_DIAG_WRONG_TYPE_TAG,
"invalid program: wrong type tag");
} else { } else {
amduat_pel_program_dag_decode_status_t decode_status = amduat_pel_program_dag_decode_status_t decode_status =
amduat_enc_pel_program_dag_decode_v1_ex(program_artifact.bytes, amduat_enc_pel_program_dag_decode_v1_ex(program_artifact.bytes,
@ -420,6 +485,9 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
amduat_init_core_result(&core_result, scheme_ref, amduat_init_core_result(&core_result, scheme_ref,
AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM, AMDUAT_PEL_EXEC_STATUS_INVALID_PROGRAM,
AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2); AMDUAT_PEL_EXEC_ERROR_PROGRAM, 2);
amduat_surf_diag_setf(&core_result,
AMDUAT_PEL_DAG_DIAG_DECODE_FAILED,
"invalid program: decode failed");
} else { } else {
program_decoded = true; program_decoded = true;
const amduat_artifact_t *params_arg = const amduat_artifact_t *params_arg =
@ -495,6 +563,7 @@ bool amduat_pel_surf_run(amduat_asl_store_t *store,
amduat_artifact_free(&params_artifact); amduat_artifact_free(&params_artifact);
} }
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&core_result);
return true; return true;
cleanup: cleanup:
@ -511,5 +580,6 @@ cleanup:
amduat_artifact_free(&params_artifact); amduat_artifact_free(&params_artifact);
} }
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&core_result);
return false; return false;
} }

View file

@ -672,6 +672,8 @@ static int amduat_pel_cli_cmd_exec(int argc,
FILE *out_stream = NULL; FILE *out_stream = NULL;
int i; int i;
memset(&result, 0, sizeof(result));
if (global == NULL) { if (global == NULL) {
return AMDUAT_PEL_CLI_EXIT_USAGE; return AMDUAT_PEL_CLI_EXIT_USAGE;
} }
@ -924,6 +926,7 @@ exec_cleanup:
if (outputs != NULL) { if (outputs != NULL) {
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
} }
amduat_pel_execution_result_free(&result);
if (inputs != NULL) { if (inputs != NULL) {
for (i = 0; i < (int)input_paths_len; ++i) { for (i = 0; i < (int)input_paths_len; ++i) {
amduat_asl_artifact_free(&inputs[i]); amduat_asl_artifact_free(&inputs[i]);

View file

@ -58,6 +58,8 @@ static int test_valid_program(void) {
amduat_octets_t const_params; amduat_octets_t const_params;
int exit_code = 1; int exit_code = 1;
memset(&result, 0, sizeof(result));
const_params = make_const_params(const_bytes, sizeof(const_bytes)); const_params = make_const_params(const_bytes, sizeof(const_bytes));
if (const_params.data == NULL) { if (const_params.data == NULL) {
fprintf(stderr, "const params alloc failed\n"); fprintf(stderr, "const params alloc failed\n");
@ -117,6 +119,7 @@ static int test_valid_program(void) {
cleanup: cleanup:
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&result);
free((void *)const_params.data); free((void *)const_params.data);
return exit_code; return exit_code;
} }
@ -132,6 +135,10 @@ static int test_invalid_program_cycle(void) {
amduat_pel_execution_result_value_t result; amduat_pel_execution_result_value_t result;
const char op_concat[] = "pel.bytes.concat"; const char op_concat[] = "pel.bytes.concat";
memset(&result, 0, sizeof(result));
memset(&result, 0, sizeof(result));
node1_inputs[0].kind = AMDUAT_PEL_DAG_INPUT_NODE; node1_inputs[0].kind = AMDUAT_PEL_DAG_INPUT_NODE;
node1_inputs[0].value.node.node_id = 2; node1_inputs[0].value.node.node_id = 2;
node1_inputs[0].value.node.output_index = 0; node1_inputs[0].value.node.output_index = 0;
@ -165,6 +172,7 @@ static int test_invalid_program_cycle(void) {
if (!amduat_pel_program_dag_exec(&program, NULL, 0, NULL, &outputs, if (!amduat_pel_program_dag_exec(&program, NULL, 0, NULL, &outputs,
&outputs_len, &result)) { &outputs_len, &result)) {
fprintf(stderr, "exec failed\n"); fprintf(stderr, "exec failed\n");
amduat_pel_execution_result_free(&result);
return 1; return 1;
} }
@ -173,10 +181,12 @@ static int test_invalid_program_cycle(void) {
result.summary.status_code != 2) { result.summary.status_code != 2) {
fprintf(stderr, "unexpected invalid program status\n"); fprintf(stderr, "unexpected invalid program status\n");
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&result);
return 1; return 1;
} }
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&result);
return 0; return 0;
} }
@ -192,6 +202,8 @@ static int test_invalid_params(void) {
const char op_concat[] = "pel.bytes.concat"; const char op_concat[] = "pel.bytes.concat";
uint8_t bad_params[] = {0x01u}; uint8_t bad_params[] = {0x01u};
memset(&result, 0, sizeof(result));
node_inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL; node_inputs[0].kind = AMDUAT_PEL_DAG_INPUT_EXTERNAL;
node_inputs[0].value.external.input_index = 0; node_inputs[0].value.external.input_index = 0;
@ -215,6 +227,7 @@ static int test_invalid_params(void) {
if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs, if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs,
&outputs_len, &result)) { &outputs_len, &result)) {
fprintf(stderr, "exec failed\n"); fprintf(stderr, "exec failed\n");
amduat_pel_execution_result_free(&result);
return 1; return 1;
} }
@ -223,10 +236,12 @@ static int test_invalid_params(void) {
result.summary.status_code != 2) { result.summary.status_code != 2) {
fprintf(stderr, "unexpected invalid params status\n"); fprintf(stderr, "unexpected invalid params status\n");
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&result);
return 1; return 1;
} }
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&result);
return 0; return 0;
} }
@ -264,6 +279,7 @@ static int test_invalid_input_index(void) {
if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs, if (!amduat_pel_program_dag_exec(&program, inputs, 1, NULL, &outputs,
&outputs_len, &result)) { &outputs_len, &result)) {
fprintf(stderr, "exec failed\n"); fprintf(stderr, "exec failed\n");
amduat_pel_execution_result_free(&result);
return 1; return 1;
} }
@ -272,10 +288,12 @@ static int test_invalid_input_index(void) {
result.summary.status_code != 3) { result.summary.status_code != 3) {
fprintf(stderr, "unexpected invalid inputs status\n"); fprintf(stderr, "unexpected invalid inputs status\n");
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&result);
return 1; return 1;
} }
amduat_pel_program_dag_free_outputs(outputs, outputs_len); amduat_pel_program_dag_free_outputs(outputs, outputs_len);
amduat_pel_execution_result_free(&result);
return 0; return 0;
} }