diff --git a/BUILD.bazel b/BUILD.bazel index 395ec1daa04..cc66f07b489 100644 --- a/BUILD.bazel +++ b/BUILD.bazel @@ -16,7 +16,6 @@ load( "xnnpack_if_kleidiai_enabled", "xnnpack_min_size_copts", "xnnpack_slinky_deps", - "xnnpack_slinky_srcs", "xnnpack_source_list_file", "xnnpack_transitive_source_list", "xnnpack_visibility", @@ -1019,9 +1018,17 @@ xnnpack_cc_library( ], ) +xnnpack_cc_library( + name = "subgraph_h", + hdrs = [ + "src/xnnpack/subgraph.h", + ], + compatible_with = [], +) + xnnpack_cc_library( name = "subgraph", - srcs = SUBGRAPH_SRCS + xnnpack_slinky_srcs(), + srcs = SUBGRAPH_SRCS, hdrs = [ "src/xnnpack/memory-planner.h", "src/xnnpack/reshape-helpers.h", @@ -1050,6 +1057,7 @@ xnnpack_cc_library( ":operators", ":params", ":requantization", + ":subgraph_h", ":xnnpack_h", "@pthreadpool", ] + xnnpack_slinky_deps(), diff --git a/build_defs.bzl b/build_defs.bzl index c4ad91206a7..d0e6b7bb614 100644 --- a/build_defs.bzl +++ b/build_defs.bzl @@ -62,9 +62,6 @@ def xnnpack_optional_dnnl_deps(): """Optional Intel DNNL dependencies.""" return [] -def xnnpack_slinky_srcs(): - return [] - def xnnpack_slinky_deps(): return [] diff --git a/src/runtime.c b/src/runtime.c index a36edcf708b..e0f53697bbc 100644 --- a/src/runtime.c +++ b/src/runtime.c @@ -553,8 +553,19 @@ enum xnn_status xnn_create_runtime_v4( } #ifdef XNN_SLINKY_ENABLED - runtime->slinky_pipeline = xnn_runtime_to_slinky_pipeline(runtime); + // If compiling with XNN_SLINKY_ENABLED defined, assume we always + // want Slinky enabled, regardless of the runtime flag + const bool use_slinky = true; +#else + const bool use_slinky = (flags & XNN_FLAG_SLINKY_ENABLED) != 0; #endif + if (use_slinky) { + #ifdef XNN_SLINKY_AVAILABLE + // slinky_init_pipeline(runtime); + #else + xnn_log_warning("Slinky requested but not available"); + #endif + } for (uint32_t i = 0; i < runtime->num_values; i++) { struct xnn_value* value = &runtime->values[i]; @@ -695,23 +706,9 @@ enum xnn_status xnn_setup_runtime( } } -#ifdef XNN_SLINKY_ENABLED - size_t input_id = 0, output_id = 0; - // Use the runtime values instead of the external values so the order is the - // same. - for (size_t i = 0; i < runtime->num_values; i++) { - struct xnn_value* value = &runtime->values[i]; - if (xnn_value_is_static(value)) { - // The value is constant. - } else if (value->flags & XNN_VALUE_FLAG_EXTERNAL_INPUT) { - runtime->input_values[input_id++] = value; - } else if (value->flags & XNN_VALUE_FLAG_EXTERNAL_OUTPUT) { - runtime->output_values[output_id++] = value; - } - } - runtime->num_inputs = input_id; - runtime->num_outputs = output_id; -#endif + #ifdef XNN_SLINKY_AVAILABLE + // slinky_setup_inputs_and_outputs(runtime); + #endif // Apply runtime state changes. for (size_t i = 0; i < num_external_values; i++) { @@ -794,23 +791,9 @@ enum xnn_status xnn_setup_runtime_v2( value->data = external_value->data; } -#ifdef XNN_SLINKY_ENABLED - size_t input_id = 0, output_id = 0; - // Use the runtime values instead of the external values so the order is the - // same. - for (size_t i = 0; i < runtime->num_values; i++) { - struct xnn_value* value = &runtime->values[i]; - if (xnn_value_is_static(value)) { - // The value is constant. - } else if (value->flags & XNN_VALUE_FLAG_EXTERNAL_INPUT) { - runtime->input_values[input_id++] = value; - } else if (value->flags & XNN_VALUE_FLAG_EXTERNAL_OUTPUT) { - runtime->output_values[output_id++] = value; - } - } - runtime->num_inputs = input_id; - runtime->num_outputs = output_id; -#endif + #ifdef XNN_SLINKY_AVAILABLE + // slinky_setup_inputs_and_outputs(runtime); + #endif for (uint32_t opdata_id = 0; opdata_id < runtime->num_ops; opdata_id++) { struct xnn_operator_data* opdata = &runtime->opdata[opdata_id]; @@ -981,13 +964,10 @@ enum xnn_status xnn_get_runtime_profiling_info(xnn_runtime_t runtime, enum xnn_status xnn_invoke_runtime( xnn_runtime_t runtime) { -#ifdef XNN_SLINKY_ENABLED - if (runtime->slinky_pipeline) { - return evaluate(runtime->slinky_pipeline, runtime->input_values, - runtime->num_inputs, runtime->output_values, - runtime->num_outputs); - } -#endif + #ifdef XNN_SLINKY_AVAILABLE + enum xnn_status status; + // if (slinky_evaluate(runtime, &status)) return status; + #endif if (runtime->profiling) { runtime->start_ts = xnn_read_timer(); @@ -1015,9 +995,10 @@ enum xnn_status xnn_delete_runtime( xnn_runtime_t runtime) { if (runtime != NULL) { -#ifdef XNN_SLINKY_ENABLED - destroy_slinky_pipeline(runtime->slinky_pipeline); -#endif + #ifdef XNN_SLINKY_AVAILABLE + // slinky_destroy_pipeline(runtime); + #endif + if (runtime->opdata != NULL) { for (size_t i = 0; i < runtime->num_ops; i++) { for (size_t j = 0; j < XNN_MAX_OPERATOR_OBJECTS; j++) { diff --git a/src/xnnpack/subgraph.h b/src/xnnpack/subgraph.h index 93a87a9b524..53235e488da 100644 --- a/src/xnnpack/subgraph.h +++ b/src/xnnpack/subgraph.h @@ -34,18 +34,23 @@ /// Disable fusion of nodes in subgraph. Fusion is enabled by default, set this flag to turn it off. #define XNN_FLAG_NO_OPERATOR_FUSION 0x80000000 +/// Enable Slinky (if available). +#define XNN_FLAG_SLINKY_ENABLED 0x40000000 + #ifdef __cplusplus extern "C" { #endif -#ifdef XNN_SLINKY_ENABLED -struct xnn_value; +#ifdef XNN_SLINKY_AVAILABLE +/// Slinky interface -- unused unless XNN_FLAG_SLINKY_ENABLED is set struct slinky_pipeline; typedef struct slinky_pipeline* slinky_pipeline_t; -slinky_pipeline_t xnn_runtime_to_slinky_pipeline(xnn_runtime_t runtime); -void destroy_slinky_pipeline(slinky_pipeline_t pipeline); -enum xnn_status evaluate(slinky_pipeline_t p, struct xnn_value* const* input_values, size_t num_inputs, struct xnn_value* const* output_values, size_t num_outputs); -#endif + +void slinky_init_pipeline(xnn_runtime_t runtime); +void slinky_setup_inputs_and_outputs(xnn_runtime_t runtime); +void slinky_destroy_pipeline(xnn_runtime_t runtime); +bool slinky_evaluate(xnn_runtime_t runtime, enum xnn_status* status); +#endif // XNN_SLINKY_AVAILABLE struct xnn_shape { size_t num_dims; @@ -446,13 +451,14 @@ struct xnn_runtime { bool has_been_setup; bool memory_planned; -#ifdef XNN_SLINKY_ENABLED + #ifdef XNN_SLINKY_AVAILABLE + // Fields used by Slinky -- unused unless XNN_FLAG_SLINKY_ENABLED is set slinky_pipeline_t slinky_pipeline; - size_t num_inputs; - size_t num_outputs; - struct xnn_value* input_values[XNN_MAX_SUBGRAPH_INPUT_OR_OUTPUTS]; - struct xnn_value* output_values[XNN_MAX_SUBGRAPH_INPUT_OR_OUTPUTS]; -#endif + size_t slinky_num_inputs; + size_t slinky_num_outputs; + struct xnn_value* slinky_input_values[XNN_MAX_SUBGRAPH_INPUT_OR_OUTPUTS]; + struct xnn_value* slinky_output_values[XNN_MAX_SUBGRAPH_INPUT_OR_OUTPUTS]; + #endif // XNN_SLINKY_AVAILABLE }; enum xnn_status xnn_insert_clamp_node(xnn_subgraph_t subgraph, float output_min, float output_max, struct xnn_node *node);