cmake_minimum_required(VERSION 3.16)

project(traceloom_native VERSION 0.1.0 LANGUAGES CXX)

include(GNUInstallDirs)
find_package(Threads REQUIRED)

option(TRACELOOM_NATIVE_BUILD_TESTS "Build TraceLoom native tests" ON)
option(
  TRACELOOM_NATIVE_ENABLE_SQLITE_ADAPTERS
  "Build optional SQLite profile adapters"
  ON
)
set(TRACELOOM_NATIVE_SQLITE_ADAPTERS_AVAILABLE OFF)

find_path(LIBYAML_INCLUDE_DIR yaml.h)
find_library(LIBYAML_LIBRARY yaml)
if(NOT LIBYAML_INCLUDE_DIR OR NOT LIBYAML_LIBRARY)
  message(FATAL_ERROR "libyaml development files required (libyaml-dev / libyaml-devel)")
endif()

add_library(traceloom_native_core
  src/analysis/clock_calibration.cpp
  src/analysis/event_cost_attribution.cpp
  src/analysis/event_reconciliation.cpp
  src/analysis/event_reconciliation_task_communication.cpp
  src/analysis/exact_periodic_suffix.cpp
  src/analysis/flat_anchor_builder.cpp
  src/analysis/host_launch_order.cpp
  src/analysis/graph_body_cost_summary.cpp
  src/analysis/signal_classification_rules.cpp
  src/analysis/signal_classification_rules_io.cpp
  src/analysis/marked_structure.cpp
  src/analysis/structural_occurrence_builder.cpp
  src/analysis/structural_occurrence_graph.cpp
  src/analysis/structural_occurrence_validation.cpp
  src/analysis/structural_position_model.cpp
  src/analysis/structural_symbol_normalization.cpp
  src/analysis/native_pipeline.cpp
  src/analysis/replay_body_pattern.cpp
  src/analysis/replay_internal_cost_map.cpp
  src/core/diagnostics.cpp
  src/core/sha256.cpp
  src/core/string_table.cpp
  src/cost/cost_summary_lite.cpp
  src/ir/anchor_table.cpp
  src/ir/capture_slot_table.cpp
  src/ir/captured_graph_instance_table.cpp
  src/ir/communication_op_table.cpp
  src/ir/graph_launch_occurrence_table.cpp
  src/ir/graph_launch_activity_table.cpp
  src/ir/graph_launch_body_table.cpp
  src/ir/graph_slot_template_table.cpp
  src/ir/graph_template_table.cpp
  src/ir/protected_interval_table.cpp
  src/ir/replay_composition_candidate_table.cpp
  src/ir/replay_unit_table.cpp
  src/ir/runtime_call_table.cpp
  src/ir/source_ref_table.cpp
  src/ir/stream_table.cpp
  src/ir/task_table.cpp
  src/ir/token_table.cpp
  src/ir/trace_event_table.cpp
  src/pattern/candidate.cpp
  src/pattern/candidate_reduce.cpp
  src/pattern/candidate_scan.cpp
  src/pattern/grammar_apply.cpp
  src/pattern/grammar_commit_plan.cpp
  src/pattern/grammar_engine.cpp
  src/pattern/grammar_modes.cpp
  src/pattern/grammar_round.cpp
  src/pattern/grammar_snapshot.cpp
  src/pattern/grammar_state.cpp
  src/config/yaml_document.cpp
  src/config/rule_manifest.cpp
  src/config/analysis_rules_config.cpp
  src/pattern/macro_match_rules.cpp
  src/pattern/pattern_candidate_table.cpp
  src/pattern/pattern_candidate_summary.cpp
  src/analysis/anchor_graph_child_cost.cpp
  src/analysis/anchor_internal_cost_breakdown.cpp
  src/analysis/structural_cost_tree.cpp
  src/analysis/structural_cost_handoff.cpp
  src/runtime/thread_pool.cpp
  src/sequence/boundary_index.cpp
  src/sequence/partition_plan.cpp
  src/sequence/protected_sequence.cpp
)

target_include_directories(traceloom_native_core
  PUBLIC
    ${CMAKE_CURRENT_SOURCE_DIR}/include
)

target_compile_features(traceloom_native_core PUBLIC cxx_std_17)

target_compile_definitions(
  traceloom_native_core
  PRIVATE
    TRACELOOM_SOURCE_DEFAULT_RULESET_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data/default_signal_classification_rules.yaml"
    TRACELOOM_INSTALL_DEFAULT_RULESET_PATH="${CMAKE_INSTALL_FULL_DATADIR}/traceloom/default_signal_classification_rules.yaml"
    TRACELOOM_SOURCE_DEFAULT_SYMBOL_RULESET_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data/default_structural_symbol_rules.yaml"
    TRACELOOM_INSTALL_DEFAULT_SYMBOL_RULESET_PATH="${CMAKE_INSTALL_FULL_DATADIR}/traceloom/default_structural_symbol_rules.yaml"
    TRACELOOM_SOURCE_DEFAULT_EVENT_RECONCILIATION_RULESET_PATH="${CMAKE_CURRENT_SOURCE_DIR}/data/default_event_reconciliation_rules.yaml"
    TRACELOOM_INSTALL_DEFAULT_EVENT_RECONCILIATION_RULESET_PATH="${CMAKE_INSTALL_FULL_DATADIR}/traceloom/default_event_reconciliation_rules.yaml"
)

install(FILES ${CMAKE_CURRENT_SOURCE_DIR}/../configs/deepseekv4.yaml
        DESTINATION ${CMAKE_INSTALL_DATADIR}/traceloom/models)

install(
  FILES data/default_signal_classification_rules.yaml
  DESTINATION ${CMAKE_INSTALL_DATADIR}/traceloom
)
install(
  FILES data/default_structural_symbol_rules.yaml
  DESTINATION ${CMAKE_INSTALL_DATADIR}/traceloom
)
install(
  FILES data/default_event_reconciliation_rules.yaml
  DESTINATION ${CMAKE_INSTALL_DATADIR}/traceloom
)

if(MSVC)
  target_compile_options(traceloom_native_core PRIVATE /W4)
else()
  target_compile_options(traceloom_native_core PRIVATE -Wall -Wextra -Wpedantic)
endif()

target_include_directories(traceloom_native_core PUBLIC ${LIBYAML_INCLUDE_DIR})
target_link_libraries(traceloom_native_core PUBLIC ${LIBYAML_LIBRARY} Threads::Threads)

add_library(traceloom_native_adapters
  src/adapters/aclgraph_fixture_adapter.cpp
  src/adapters/aclgraph_fixture_reader.cpp
  src/adapters/fixture_adapter.cpp
  src/adapters/protected_sequence_fixture_reader.cpp
)

target_link_libraries(traceloom_native_adapters PUBLIC traceloom_native_core)

add_library(traceloom_native_materialize
  src/compat/anchor_sequence_rows.cpp
  src/compat/anchor_cost_breakdown_rows.cpp
  src/compat/augmented_catalog_materializer.cpp
  src/compat/augmented_projection_catalog.cpp
  src/compat/augmented_position_projection_catalog.cpp
  src/compat/augmented_replay_projection_catalog.cpp
  src/compat/augmented_replay_body_projection_catalog.cpp
  src/compat/aux_attribution_rows.cpp
  src/compat/collective_tag_rows.cpp
  src/compat/compact_grammar_projection.cpp
  src/compat/exact_graph_sql_rows.cpp
  src/compat/native_graph_replay_rows.cpp
  src/compat/scheduler_context.cpp
  src/compat/scheduler_replay_context.cpp
  src/compat/native_sidecar_materializer.cpp
  src/compat/native_sidecar_packaging.cpp
  src/compat/structural_projection_rows.cpp
  src/compat/structural_projection_tokens.cpp
  src/compat/structural_position_rows.cpp
  src/compat/replay_body_pattern_rows.cpp
  src/compat/replay_cost_sql_rows.cpp
  src/compat/replay_position_views.cpp
  src/compat/evidence_role_decision_rows.cpp
  src/compat/evidence_role_sql_rows.cpp
  src/compat/evidence_role_sql_writer.cpp
  src/compat/event_reconciliation_rows.cpp
  src/compat/runtime_device_rows.cpp
  src/compat/source_locator_json.cpp
  src/compat/schema.cpp
  src/compat/schema_structural_tables.cpp
  src/compat/schema_structural_position_tables.cpp
  src/compat/schema_replay_tables.cpp
  src/compat/schema_replay_body_pattern_tables.cpp
  src/compat/sidecar_sqlite_utils.cpp
  src/compat/sidecar_collective_bindings.cpp
  src/compat/sidecar_collective_writer.cpp
  src/compat/sidecar_core_bindings.cpp
  src/compat/sidecar_core_writer.cpp
  src/compat/sidecar_graph_bindings.cpp
  src/compat/sidecar_graph_views.cpp
  src/compat/sidecar_graph_writer.cpp
  src/compat/sidecar_indexes.cpp
  src/compat/sidecar_runtime_views.cpp
  src/compat/sidecar_structure_bubble_views.cpp
  src/compat/sidecar_semantic_bindings.cpp
  src/compat/sidecar_semantic_views.cpp
  src/compat/sidecar_semantic_writer.cpp
  src/compat/sidecar_structure_bindings.cpp
  src/compat/sidecar_structure_writer.cpp
  src/compat/sidecar_symbol_normalization_views.cpp
  src/compat/sidecar_symbol_normalization_writer.cpp
  src/compat/sidecar_tree_views.cpp
  src/compat/sidecar_views.cpp
  src/compat/sidecar_writer.cpp
  src/compat/timeline_rows.cpp
  src/compat/symbol_normalization_rows.cpp
  src/materialize/grammar_debug_json.cpp
  src/materialize/loop_tree_markdown.cpp
)

target_link_libraries(traceloom_native_materialize PUBLIC traceloom_native_core)

if(MSVC)
  target_compile_options(traceloom_native_materialize PRIVATE /W4)
else()
  target_compile_options(
    traceloom_native_materialize PRIVATE -Wall -Wextra -Wpedantic
  )
endif()

if(TRACELOOM_NATIVE_ENABLE_SQLITE_ADAPTERS)
  find_package(SQLite3 QUIET)
  if(SQLite3_FOUND)
    target_sources(traceloom_native_adapters
      PRIVATE
        src/adapters/ascend_sqlite_adapter.cpp
        src/adapters/ascend_sqlite_evidence.cpp
        src/adapters/ascend_sqlite_foundation.cpp
        src/adapters/ascend_sqlite_graph.cpp
        src/adapters/ascend_sqlite_replay.cpp
        src/adapters/ascend_sqlite_split.cpp
        src/adapters/ascend_sqlite_tasks.cpp
        src/adapters/cuda_nsys_sqlite_adapter.cpp
        src/adapters/cuda_nsys_sqlite_foundation.cpp
        src/adapters/cuda_nsys_sqlite_graph.cpp
        src/adapters/hygon_sqlite_adapter.cpp
        src/adapters/sqlite_profile_reader.cpp
    )
    target_sources(traceloom_native_materialize
      PRIVATE
        src/compat/perfetto_exporter.cpp
        src/compat/perfetto_distributed_clock_model.cpp
        src/compat/perfetto_distributed_export.cpp
        src/compat/perfetto_raw_export.cpp
        src/compat/perfetto_context_export.cpp
        src/compat/perfetto_replay_export.cpp
        src/compat/perfetto_timeline_render.cpp
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(traceloom_native_adapters PRIVATE SQLite::SQLite3)
      target_link_libraries(traceloom_native_materialize PRIVATE SQLite::SQLite3)
    else()
      target_include_directories(
        traceloom_native_adapters PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_include_directories(
        traceloom_native_materialize PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        traceloom_native_adapters PRIVATE ${SQLite3_LIBRARIES}
      )
      target_link_libraries(
        traceloom_native_materialize PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    target_compile_definitions(
      traceloom_native_adapters
      PUBLIC TRACELOOM_NATIVE_HAS_SQLITE_ADAPTERS=1
    )
    target_compile_definitions(
      traceloom_native_materialize
      PRIVATE TRACELOOM_NATIVE_HAS_SQLITE_COMPAT=1
    )
    set(TRACELOOM_NATIVE_SQLITE_ADAPTERS_AVAILABLE ON)
  else()
    message(STATUS "SQLite3 not found; SQLite source adapters are disabled")
  endif()
endif()

if(MSVC)
  target_compile_options(traceloom_native_adapters PRIVATE /W4)
else()
  target_compile_options(traceloom_native_adapters PRIVATE -Wall -Wextra -Wpedantic)
endif()

if(TRACELOOM_NATIVE_SQLITE_ADAPTERS_AVAILABLE)
  add_executable(traceloom-native-ascend-sqlite-inventory
    src/tools/ascend_sqlite_inventory_main.cpp
  )
  target_link_libraries(
    traceloom-native-ascend-sqlite-inventory PRIVATE traceloom_native_adapters
  )

  add_executable(traceloom
    src/tools/analyze_db_main.cpp
    src/tools/analyze_db_rules.cpp
    src/tools/analyze_db_usage.cpp
    src/tools/perfetto_cli_args.cpp
    src/tools/profile_input_discovery.cpp
  )
  target_link_libraries(
    traceloom PRIVATE
    traceloom_native_adapters
    traceloom_native_materialize
  )

  target_compile_definitions(
    traceloom PRIVATE TRACELOOM_NATIVE_VERSION="${PROJECT_VERSION}"
  )

  install(
    TARGETS traceloom
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
  )

  set(CPACK_GENERATOR "DEB")
  set(CPACK_PACKAGE_NAME "traceloom-native")
  set(CPACK_PACKAGE_VENDOR "vLLM-HUST")
  set(CPACK_PACKAGE_CONTACT "vLLM-HUST")
  set(CPACK_PACKAGE_DESCRIPTION_SUMMARY
      "Native TraceLoom analyzer for profiler SQLite databases")
  set(CPACK_PACKAGE_VERSION "${PROJECT_VERSION}")
  set(CPACK_DEBIAN_PACKAGE_MAINTAINER "vLLM-HUST")
  set(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6, libstdc++6, libsqlite3-0, libyaml-0-2, gzip")
  set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
  set(CPACK_PACKAGING_INSTALL_PREFIX "/usr")
  include(CPack)
endif()

add_executable(traceloom-native-analyze-fixture
  src/tools/analyze_fixture_main.cpp
)
target_link_libraries(
  traceloom-native-analyze-fixture PRIVATE
  traceloom_native_adapters
  traceloom_native_materialize
)

if(TRACELOOM_NATIVE_BUILD_TESTS)
  enable_testing()
  if(SQLite3_FOUND)
    include(${CMAKE_CURRENT_SOURCE_DIR}/../integrations/vllm/tests/register.cmake)
  endif()

  set(
    TRACELOOM_NATIVE_FIXTURE_ROOT
    "${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures"
  )

  add_executable(marked_structure_tests tests/analysis/marked_structure_tests.cpp)
  target_link_libraries(marked_structure_tests PRIVATE traceloom_native_core)
  add_test(NAME marked_structure_tests COMMAND marked_structure_tests)

  add_executable(analysis_rules_config_tests tests/analysis/analysis_rules_config_tests.cpp)
  target_link_libraries(analysis_rules_config_tests PRIVATE traceloom_native_core)
  add_test(NAME analysis_rules_config_tests COMMAND analysis_rules_config_tests)

  add_executable(macro_match_rules_tests tests/pattern/macro_match_rules_tests.cpp)
  target_link_libraries(macro_match_rules_tests PRIVATE traceloom_native_core)
  add_test(NAME macro_match_rules_tests COMMAND macro_match_rules_tests)

  add_executable(host_launch_order_tests tests/analysis/host_launch_order_tests.cpp)
  target_link_libraries(host_launch_order_tests PRIVATE traceloom_native_materialize)
  add_test(NAME host_launch_order_tests COMMAND host_launch_order_tests)

  add_executable(id_tests
    tests/core/id_tests.cpp
  )
  target_link_libraries(id_tests PRIVATE traceloom_native_core)
  add_test(NAME id_tests COMMAND id_tests)

  add_executable(cost_summary_tests
    tests/cost/cost_summary_lite_tests.cpp
  )
  target_link_libraries(
    cost_summary_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME cost_summary_tests
    COMMAND cost_summary_tests
  )

  add_executable(ir_contract_tests
    tests/ir/native_ir_contract_tests.cpp
  )
  target_link_libraries(ir_contract_tests PRIVATE traceloom_native_core)
  add_test(
    NAME ir_contract_tests
    COMMAND ir_contract_tests
  )

  add_executable(sequence_contract_tests
    tests/sequence/sequence_contract_tests.cpp
  )
  target_link_libraries(
    sequence_contract_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME sequence_contract_tests
    COMMAND sequence_contract_tests
  )

  add_executable(thread_pool_tests
    tests/runtime/thread_pool_tests.cpp
  )
  target_link_libraries(
    thread_pool_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME thread_pool_tests
    COMMAND thread_pool_tests
  )

  add_executable(candidate_scan_tests
    tests/pattern/candidate_scan_tests.cpp
  )
  target_link_libraries(
    candidate_scan_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME candidate_scan_tests
    COMMAND candidate_scan_tests
  )

  add_executable(grammar_state_tests
    tests/pattern/grammar_state_tests.cpp
  )
  target_link_libraries(
    grammar_state_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME grammar_state_tests
    COMMAND grammar_state_tests
  )

  add_executable(grammar_snapshot_tests
    tests/pattern/grammar_snapshot_tests.cpp
  )
  target_link_libraries(
    grammar_snapshot_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME grammar_snapshot_tests
    COMMAND grammar_snapshot_tests
  )

  add_executable(grammar_round_tests
    tests/pattern/grammar_round_tests.cpp
  )
  target_link_libraries(
    grammar_round_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME grammar_round_tests
    COMMAND grammar_round_tests
  )

  add_executable(grammar_commit_plan_tests
    tests/pattern/grammar_commit_plan_tests.cpp
  )
  target_link_libraries(
    grammar_commit_plan_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME grammar_commit_plan_tests
    COMMAND grammar_commit_plan_tests
  )

  add_executable(grammar_apply_tests
    tests/pattern/grammar_apply_tests.cpp
  )
  target_link_libraries(
    grammar_apply_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME grammar_apply_tests
    COMMAND grammar_apply_tests
  )

  add_executable(grammar_engine_tests
    tests/pattern/grammar_engine_tests.cpp
  )
  target_link_libraries(
    grammar_engine_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME grammar_engine_tests
    COMMAND grammar_engine_tests
  )

  add_executable(flat_anchor_builder_tests
    tests/analysis/flat_anchor_builder_tests.cpp
  )
  target_link_libraries(
    flat_anchor_builder_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME flat_anchor_builder_tests
    COMMAND flat_anchor_builder_tests
  )

  add_executable(clock_calibration_tests
    tests/analysis/clock_calibration_tests.cpp
  )
  target_link_libraries(
    clock_calibration_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME clock_calibration_tests
    COMMAND clock_calibration_tests
  )

  add_executable(event_reconciliation_tests
    tests/analysis/event_reconciliation_tests.cpp
  )
  target_link_libraries(
    event_reconciliation_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME event_reconciliation_tests
    COMMAND event_reconciliation_tests
  )

  add_executable(structural_symbol_normalization_tests
    tests/analysis/structural_symbol_normalization_tests.cpp
  )
  target_link_libraries(
    structural_symbol_normalization_tests PRIVATE
    traceloom_native_core
  )
  add_test(
    NAME structural_symbol_normalization_tests
    COMMAND structural_symbol_normalization_tests
  )

  add_executable(signal_classification_rules_tests
    tests/analysis/signal_classification_rules_tests.cpp
  )
  target_link_libraries(
    signal_classification_rules_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME signal_classification_rules_tests
    COMMAND signal_classification_rules_tests
  )

  add_executable(graph_body_cost_summary_tests
    tests/analysis/graph_body_cost_summary_tests.cpp
  )
  target_link_libraries(
    graph_body_cost_summary_tests PRIVATE
    traceloom_native_core
  )
  add_test(
    NAME graph_body_cost_summary_tests
    COMMAND graph_body_cost_summary_tests
  )

  add_executable(replay_internal_cost_map_tests
    tests/analysis/replay_internal_cost_map_contract_tests.cpp
    tests/analysis/replay_internal_cost_map_happy_path_tests.cpp
    tests/analysis/replay_internal_cost_map_tests.cpp
  )
  target_link_libraries(
    replay_internal_cost_map_tests PRIVATE
    traceloom_native_core
  )
  add_test(
    NAME replay_internal_cost_map_tests
    COMMAND replay_internal_cost_map_tests
  )

  add_executable(replay_body_pattern_tests
    tests/analysis/replay_body_pattern_tests.cpp
  )
  target_link_libraries(
    replay_body_pattern_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME replay_body_pattern_tests
    COMMAND replay_body_pattern_tests
  )

  add_executable(sha256_tests
    tests/core/sha256_tests.cpp
  )
  target_link_libraries(
    sha256_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME sha256_tests
    COMMAND sha256_tests
  )
  add_executable(pipeline_tests
    tests/analysis/native_pipeline_tests.cpp
  )
  target_link_libraries(
    pipeline_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME pipeline_tests
    COMMAND pipeline_tests
  )

  add_executable(structural_occurrence_builder_tests
    tests/analysis/structural_occurrence_builder_tests.cpp
  )
  target_link_libraries(
    structural_occurrence_builder_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME structural_occurrence_builder_tests
    COMMAND structural_occurrence_builder_tests
  )

  add_executable(structural_position_model_tests
    tests/analysis/structural_position_model_tests.cpp
  )
  target_link_libraries(
    structural_position_model_tests PRIVATE
    traceloom_native_core
  )
  add_test(
    NAME structural_position_model_tests
    COMMAND structural_position_model_tests
  )

  add_executable(structural_occurrence_visibility_tests
    tests/analysis/structural_occurrence_visibility_tests.cpp
  )
  target_link_libraries(
    structural_occurrence_visibility_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME structural_occurrence_visibility_tests
    COMMAND structural_occurrence_visibility_tests
  )

  add_executable(structural_occurrence_graph_boundary_tests
    tests/analysis/structural_occurrence_graph_boundary_tests.cpp
  )
  target_link_libraries(
    structural_occurrence_graph_boundary_tests PRIVATE
    traceloom_native_core
  )
  add_test(
    NAME structural_occurrence_graph_boundary_tests
    COMMAND structural_occurrence_graph_boundary_tests
  )

  add_executable(structural_cost_handoff_tests
    tests/analysis/structural_cost_handoff_tests.cpp
  )
  target_link_libraries(
    structural_cost_handoff_tests PRIVATE
    traceloom_native_core
  )
  add_test(
    NAME structural_cost_handoff_tests
    COMMAND structural_cost_handoff_tests
  )

  add_executable(structural_cost_tree_tests
    tests/analysis/structural_cost_tree_tests.cpp
  )
  target_link_libraries(
    structural_cost_tree_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME structural_cost_tree_tests
    COMMAND structural_cost_tree_tests
  )

  add_executable(anchor_internal_cost_breakdown_tests
    tests/analysis/anchor_internal_cost_breakdown_tests.cpp
  )
  target_link_libraries(
    anchor_internal_cost_breakdown_tests PRIVATE
    traceloom_native_core
  )
  add_test(
    NAME anchor_internal_cost_breakdown_tests
    COMMAND anchor_internal_cost_breakdown_tests
  )

  add_executable(anchor_graph_child_cost_tests
    tests/analysis/anchor_graph_child_cost_tests.cpp
  )
  target_link_libraries(
    anchor_graph_child_cost_tests PRIVATE traceloom_native_core
  )
  add_test(
    NAME anchor_graph_child_cost_tests
    COMMAND anchor_graph_child_cost_tests
  )

  add_executable(loop_tree_markdown_tests
    tests/materialize/loop_tree_markdown_tests.cpp
  )
  target_link_libraries(
    loop_tree_markdown_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME loop_tree_markdown_tests
    COMMAND loop_tree_markdown_tests
  )

  add_executable(anchor_cost_breakdown_rows_tests
    tests/compat/anchor_cost_breakdown_rows_tests.cpp
  )
  target_link_libraries(
    anchor_cost_breakdown_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME anchor_cost_breakdown_rows_tests
    COMMAND anchor_cost_breakdown_rows_tests
  )

  add_executable(anchor_sequence_rows_tests
    tests/compat/anchor_sequence_rows_tests.cpp
  )
  target_link_libraries(
    anchor_sequence_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME anchor_sequence_rows_tests
    COMMAND anchor_sequence_rows_tests
  )

  add_executable(symbol_normalization_rows_tests
    tests/compat/symbol_normalization_rows_tests.cpp
  )
  target_link_libraries(
    symbol_normalization_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME symbol_normalization_rows_tests
    COMMAND symbol_normalization_rows_tests
  )

  add_executable(aux_attribution_rows_tests
    tests/compat/aux_attribution_rows_tests.cpp
  )
  target_link_libraries(
    aux_attribution_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME aux_attribution_rows_tests
    COMMAND aux_attribution_rows_tests
  )

  if(TRACELOOM_NATIVE_SQLITE_ADAPTERS_AVAILABLE)
    add_executable(runtime_device_rows_tests
      tests/compat/runtime_device_rows_tests.cpp
    )
    target_link_libraries(
      runtime_device_rows_tests PRIVATE
      traceloom_native_materialize
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        runtime_device_rows_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        runtime_device_rows_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        runtime_device_rows_tests PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME runtime_device_rows_tests
      COMMAND runtime_device_rows_tests
    )
  endif()

  add_executable(collective_tag_rows_tests
    tests/compat/collective_tag_rows_tests.cpp
  )
  target_link_libraries(
    collective_tag_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME collective_tag_rows_tests
    COMMAND collective_tag_rows_tests
  )

  add_executable(structural_projection_rows_tests
    tests/compat/structural_projection_rows_tests.cpp
  )
  target_link_libraries(
    structural_projection_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME structural_projection_rows_tests
    COMMAND structural_projection_rows_tests
  )

  add_executable(timeline_rows_tests
    tests/compat/timeline_rows_tests.cpp
  )
  target_link_libraries(
    timeline_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME timeline_rows_tests
    COMMAND timeline_rows_tests
  )

  add_executable(exact_graph_sql_rows_tests
    tests/compat/exact_graph_sql_rows_tests.cpp
  )
  target_link_libraries(
    exact_graph_sql_rows_tests PRIVATE
    traceloom_native_materialize
  )
  add_test(
    NAME exact_graph_sql_rows_tests
    COMMAND exact_graph_sql_rows_tests
  )

  add_executable(grammar_debug_json_tests
    tests/materialize/grammar_debug_json_tests.cpp
  )
  target_link_libraries(
    grammar_debug_json_tests PRIVATE
    traceloom_native_adapters
    traceloom_native_materialize
  )
  add_test(
    NAME grammar_debug_json_tests
    COMMAND grammar_debug_json_tests
  )

  add_test(
    NAME analyze_fixture_grammar_debug_cli
    COMMAND traceloom-native-analyze-fixture
      --fixture
      ${TRACELOOM_NATIVE_FIXTURE_ROOT}/protected_sequence/f1_tiny_repeated_pair.json
      --threads 2
      --grammar-debug-out -
  )
  set_tests_properties(
    analyze_fixture_grammar_debug_cli
    PROPERTIES PASS_REGULAR_EXPRESSION "native_grammar_debug_v1"
  )

  add_executable(fixture_adapter_tests
    tests/adapters/fixture_adapter_tests.cpp
  )
  target_link_libraries(
    fixture_adapter_tests PRIVATE traceloom_native_adapters
  )
  add_test(
    NAME fixture_adapter_tests
    COMMAND fixture_adapter_tests
  )

  add_executable(aclgraph_fixture_reader_tests
    tests/adapters/aclgraph_fixture_reader_tests.cpp
  )
  target_compile_definitions(
    aclgraph_fixture_reader_tests PRIVATE
    TRACELOOM_NATIVE_FIXTURE_ROOT="${TRACELOOM_NATIVE_FIXTURE_ROOT}"
  )
  target_link_libraries(
    aclgraph_fixture_reader_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME aclgraph_fixture_reader_tests
    COMMAND aclgraph_fixture_reader_tests
  )

  add_executable(aclgraph_fixture_adapter_tests
    tests/adapters/aclgraph_fixture_adapter_tests.cpp
  )
  target_compile_definitions(
    aclgraph_fixture_adapter_tests PRIVATE
    TRACELOOM_NATIVE_FIXTURE_ROOT="${TRACELOOM_NATIVE_FIXTURE_ROOT}"
  )
  target_link_libraries(
    aclgraph_fixture_adapter_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME aclgraph_fixture_adapter_tests
    COMMAND aclgraph_fixture_adapter_tests
  )

  add_executable(protected_sequence_fixture_reader_tests
    tests/adapters/protected_sequence_fixture_reader_tests.cpp
  )
  target_compile_definitions(
    protected_sequence_fixture_reader_tests PRIVATE
    TRACELOOM_NATIVE_FIXTURE_ROOT="${TRACELOOM_NATIVE_FIXTURE_ROOT}"
  )
  target_link_libraries(
    protected_sequence_fixture_reader_tests PRIVATE
    traceloom_native_adapters
  )
  add_test(
    NAME protected_sequence_fixture_reader_tests
    COMMAND protected_sequence_fixture_reader_tests
  )

  if(TRACELOOM_NATIVE_SQLITE_ADAPTERS_AVAILABLE)
    add_test(
      NAME rejects_removed_json_option
      COMMAND ${CMAKE_COMMAND}
        -DTRACELOOM_ANALYZER=$<TARGET_FILE:traceloom>
        -DTRACELOOM_REMOVED_JSON_PATH=${CMAKE_CURRENT_BINARY_DIR}/removed_native_result.json
        -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/boundary/reject_removed_native_json_option.cmake
    )

  function(traceloom_add_ascend_sqlite_test target source)
      add_executable(${target}
        ${source}
        tests/support/ascend_sqlite_fixture.cpp
        tests/support/sqlite_fixture.cpp
      )
      target_compile_definitions(
        ${target} PRIVATE
        TRACELOOM_NATIVE_FIXTURE_ROOT="${TRACELOOM_NATIVE_FIXTURE_ROOT}"
      )
      target_include_directories(
        ${target} PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/tests
      )
      target_link_libraries(
        ${target} PRIVATE traceloom_native_adapters
      )
      if(TARGET SQLite::SQLite3)
        target_link_libraries(${target} PRIVATE SQLite::SQLite3)
      else()
        target_include_directories(${target} PRIVATE ${SQLite3_INCLUDE_DIRS})
        target_link_libraries(${target} PRIVATE ${SQLite3_LIBRARIES})
      endif()
      add_test(NAME ${target} COMMAND ${target})
  endfunction()

    traceloom_add_ascend_sqlite_test(
      ascend_sqlite_adapter_tests
      tests/adapters/ascend_sqlite_adapter_tests.cpp
    )
    traceloom_add_ascend_sqlite_test(
      ascend_sqlite_graph_tests
      tests/adapters/ascend_sqlite_graph_tests.cpp
    )
    traceloom_add_ascend_sqlite_test(
      ascend_sqlite_replay_composition_tests
      tests/adapters/ascend_sqlite_replay_composition_tests.cpp
    )

    add_executable(perfetto_exporter_tests
      tests/compat/perfetto_exporter_tests.cpp
    )
    add_dependencies(perfetto_exporter_tests traceloom)
    target_compile_definitions(
      perfetto_exporter_tests PRIVATE
      TRACELOOM_ANALYZER="$<TARGET_FILE:traceloom>"
    )
    target_link_libraries(
      perfetto_exporter_tests PRIVATE
      traceloom_native_materialize
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        perfetto_exporter_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        perfetto_exporter_tests PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        perfetto_exporter_tests PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME perfetto_exporter_tests
      COMMAND perfetto_exporter_tests
    )

    add_executable(ascend_sqlite_determinism_tests
      tests/adapters/ascend_sqlite_determinism_tests.cpp
    )
    target_link_libraries(
      ascend_sqlite_determinism_tests PRIVATE
      traceloom_native_adapters
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        ascend_sqlite_determinism_tests PRIVATE
        SQLite::SQLite3
      )
    else()
      target_include_directories(
        ascend_sqlite_determinism_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        ascend_sqlite_determinism_tests PRIVATE
        ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME ascend_sqlite_determinism_tests
      COMMAND ascend_sqlite_determinism_tests
    )

    add_executable(hygon_sqlite_adapter_tests
      tests/adapters/hygon_sqlite_adapter_tests.cpp
    )
    target_link_libraries(
      hygon_sqlite_adapter_tests PRIVATE
      traceloom_native_adapters
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        hygon_sqlite_adapter_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        hygon_sqlite_adapter_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        hygon_sqlite_adapter_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME hygon_sqlite_adapter_tests
      COMMAND hygon_sqlite_adapter_tests
    )

    add_executable(cuda_nsys_sqlite_adapter_tests
      tests/adapters/cuda_nsys_sqlite_adapter_tests.cpp
    )
    target_link_libraries(
      cuda_nsys_sqlite_adapter_tests PRIVATE
      traceloom_native_adapters
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        cuda_nsys_sqlite_adapter_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        cuda_nsys_sqlite_adapter_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        cuda_nsys_sqlite_adapter_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME cuda_nsys_sqlite_adapter_tests
      COMMAND cuda_nsys_sqlite_adapter_tests
        ${CMAKE_CURRENT_BINARY_DIR}/cuda_nsys_minimal_fixture.sqlite
    )

    add_executable(sqlite_profile_reader_tests
      tests/adapters/sqlite_profile_reader_tests.cpp
    )
    target_include_directories(
      sqlite_profile_reader_tests PRIVATE
      ${CMAKE_CURRENT_SOURCE_DIR}/src/adapters
    )
    target_link_libraries(
      sqlite_profile_reader_tests PRIVATE
      traceloom_native_adapters
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        sqlite_profile_reader_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        sqlite_profile_reader_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        sqlite_profile_reader_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME sqlite_profile_reader_tests
      COMMAND sqlite_profile_reader_tests
    )

    add_executable(sidecar_writer_tests
      tests/compat/sidecar_writer_tests.cpp
      tests/compat/sidecar_writer_graph_projection_tests.cpp
      tests/compat/sidecar_writer_test_support.cpp
    )
    target_compile_definitions(
      sidecar_writer_tests PRIVATE
      TRACELOOM_REPO_ROOT="${CMAKE_CURRENT_SOURCE_DIR}/.."
    )
    target_link_libraries(
      sidecar_writer_tests PRIVATE
      traceloom_native_materialize
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        sidecar_writer_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        sidecar_writer_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        sidecar_writer_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME sidecar_writer_tests
      COMMAND sidecar_writer_tests
    )

    add_executable(sidecar_materializer_tests
      tests/compat/native_sidecar_materializer_tests.cpp
      tests/compat/native_sidecar_materializer_graph_tests.cpp
      tests/compat/native_sidecar_materializer_host_window_tests.cpp
      tests/compat/native_sidecar_materializer_packaging_tests.cpp
      tests/compat/native_sidecar_materializer_position_catalog_tests.cpp
      tests/compat/native_sidecar_materializer_test_support.cpp
    )
    target_link_libraries(
      sidecar_materializer_tests PRIVATE
      traceloom_native_materialize
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        sidecar_materializer_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        sidecar_materializer_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        sidecar_materializer_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME sidecar_materializer_tests
      COMMAND sidecar_materializer_tests
    )

    add_executable(event_reconciliation_rows_tests
      tests/compat/event_reconciliation_rows_tests.cpp
    )
    target_link_libraries(
      event_reconciliation_rows_tests PRIVATE
      traceloom_native_materialize
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        event_reconciliation_rows_tests PRIVATE
        SQLite::SQLite3
      )
    else()
      target_include_directories(
        event_reconciliation_rows_tests PRIVATE
        ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        event_reconciliation_rows_tests PRIVATE
        ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME event_reconciliation_rows_tests
      COMMAND event_reconciliation_rows_tests
    )

    add_executable(report_sql_compat_tests
      tests/compat/report_sql_compat_tests.cpp
    )
    target_compile_definitions(
      report_sql_compat_tests PRIVATE
      TRACELOOM_REPO_ROOT="${CMAKE_CURRENT_SOURCE_DIR}/.."
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        report_sql_compat_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        report_sql_compat_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        report_sql_compat_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME report_sql_compat_tests
      COMMAND report_sql_compat_tests
    )

    add_executable(evidence_role_materialization_tests
      tests/compat/evidence_role_materialization_tests.cpp
    )
    target_link_libraries(
      evidence_role_materialization_tests PRIVATE
      traceloom_native_materialize
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        evidence_role_materialization_tests
        PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        evidence_role_materialization_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        evidence_role_materialization_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME evidence_role_materialization_tests
      COMMAND evidence_role_materialization_tests
    )

    add_executable(generated_sidecar_projection_tests
      tests/compat/generated_sidecar_projection_tests.cpp
    )
    target_compile_definitions(
      generated_sidecar_projection_tests PRIVATE
      TRACELOOM_NATIVE_SOURCE_ROOT="${CMAKE_CURRENT_SOURCE_DIR}"
    )
    target_link_libraries(
      generated_sidecar_projection_tests PRIVATE
      traceloom_native_adapters
      traceloom_native_materialize
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        generated_sidecar_projection_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        generated_sidecar_projection_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        generated_sidecar_projection_tests
        PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()
    add_test(
      NAME generated_sidecar_projection_tests
      COMMAND generated_sidecar_projection_tests
    )

    add_executable(cli_sidecar_smoke_tests
      tests/compat/cli_sidecar_smoke_tests.cpp
    )
    target_link_libraries(
      cli_sidecar_smoke_tests PRIVATE traceloom_native_core
    )
    if(TARGET SQLite::SQLite3)
      target_link_libraries(
        cli_sidecar_smoke_tests PRIVATE SQLite::SQLite3
      )
    else()
      target_include_directories(
        cli_sidecar_smoke_tests
        PRIVATE ${SQLite3_INCLUDE_DIRS}
      )
      target_link_libraries(
        cli_sidecar_smoke_tests PRIVATE ${SQLite3_LIBRARIES}
      )
    endif()

    set(
      TRACELOOM_OFFICIAL_ASCEND_CLI_INPUT
      ${CMAKE_CURRENT_BINARY_DIR}/official_ascend_cli_input/ascend_pytorch_profiler_0.db
    )
    add_test(
      NAME prepare_official_ascend_cli_input
      COMMAND ascend_sqlite_adapter_tests
        --materialize ${TRACELOOM_OFFICIAL_ASCEND_CLI_INPUT}
    )
    add_test(
      NAME analyze_official_ascend_cli_input
      COMMAND traceloom
        ${TRACELOOM_OFFICIAL_ASCEND_CLI_INPUT}
        --source-kind ascend_sqlite_hot_path
        --threads 2
        --timings
        --sidecar-only
        --no-aug-db
        --compat-sidecar-out
        ${CMAKE_CURRENT_BINARY_DIR}/official_ascend_cli_compat.db
        --loop-tree-out
        ${CMAKE_CURRENT_BINARY_DIR}/official_ascend_cli_compact.md
    )
    set_tests_properties(
      analyze_official_ascend_cli_input
      PROPERTIES
        DEPENDS prepare_official_ascend_cli_input
        PASS_REGULAR_EXPRESSION "timing source_kind=ascend_sqlite_hot_path"
    )
    add_test(
      NAME analyze_official_ascend_cli_sidecar
      COMMAND cli_sidecar_smoke_tests
        ${CMAKE_CURRENT_BINARY_DIR}/official_ascend_cli_compat.db ascend
        ${CMAKE_CURRENT_BINARY_DIR}/official_ascend_cli_compact.md
    )
    set_tests_properties(
      analyze_official_ascend_cli_sidecar
      PROPERTIES DEPENDS analyze_official_ascend_cli_input
    )

    add_test(NAME analysis_rules_config_cli
      COMMAND ${CMAKE_COMMAND}
        -DANALYZER=$<TARGET_FILE:traceloom>
        -DCHECKER=$<TARGET_FILE:cli_sidecar_smoke_tests>
        -DPROFILE=${TRACELOOM_OFFICIAL_ASCEND_CLI_INPUT}
        -DCONFIG=${CMAKE_CURRENT_SOURCE_DIR}/../configs/deepseekv4.yaml
        -DEMPTY_CONFIG=${CMAKE_CURRENT_SOURCE_DIR}/tests/fixtures/analysis_rules/empty-classification.yaml
        -DOUTPUT=${CMAKE_CURRENT_BINARY_DIR}/rules_config_cli.db
        -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/boundary/analysis_rules_config_cli.cmake)
    set_tests_properties(analysis_rules_config_cli PROPERTIES DEPENDS prepare_official_ascend_cli_input)

    set(
      TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT
      ${CMAKE_CURRENT_BINARY_DIR}/official_ascend_cli_multi_input
    )
    set(
      TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_0
      ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT}/rank0_ascend_pt/ASCEND_PROFILER_OUTPUT/ascend_pytorch_profiler_0.db
    )
    set(
      TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_1
      ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT}/rank1_ascend_pt/ASCEND_PROFILER_OUTPUT/ascend_pytorch_profiler_1.db
    )
    add_test(
      NAME prepare_official_ascend_multi_input_dirs
      COMMAND ${CMAKE_COMMAND} -E make_directory
        ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT}/rank0_ascend_pt/ASCEND_PROFILER_OUTPUT
        ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT}/rank1_ascend_pt/ASCEND_PROFILER_OUTPUT
    )
    add_test(
      NAME prepare_official_ascend_multi_input_0
      COMMAND ascend_sqlite_adapter_tests
        --materialize ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_0}
    )
    add_test(
      NAME prepare_official_ascend_multi_input_1
      COMMAND ascend_sqlite_adapter_tests
        --materialize ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_1}
    )
    set_tests_properties(
      prepare_official_ascend_multi_input_0
      prepare_official_ascend_multi_input_1
      PROPERTIES DEPENDS prepare_official_ascend_multi_input_dirs
    )
    add_test(
      NAME analyze_official_ascend_multi_input
      COMMAND traceloom
        ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT}
        --threads 2
        --timings
    )
    set_tests_properties(
      analyze_official_ascend_multi_input
      PROPERTIES
        DEPENDS
          "prepare_official_ascend_multi_input_0;prepare_official_ascend_multi_input_1"
        PASS_REGULAR_EXPRESSION
          "wrote queryable database timeline: .*official_ascend_cli_multi_input/traceloom/analysis_db0[12].db"
    )
    add_test(
      NAME analyze_official_ascend_multi_input_0
      COMMAND cli_sidecar_smoke_tests
        ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT}/traceloom/analysis_db01.db
        ascend-augmented
    )
    add_test(
      NAME analyze_official_ascend_multi_input_1
      COMMAND cli_sidecar_smoke_tests
        ${TRACELOOM_OFFICIAL_ASCEND_MULTI_INPUT_ROOT}/traceloom/analysis_db02.db
        ascend-augmented
    )
    set_tests_properties(
      analyze_official_ascend_multi_input_0
      analyze_official_ascend_multi_input_1
      PROPERTIES DEPENDS analyze_official_ascend_multi_input
    )

    add_test(
      NAME prepare_unrelated_sqlite_input
      COMMAND ascend_sqlite_adapter_tests
        --materialize-unrelated
        ${CMAKE_CURRENT_BINARY_DIR}/unrelated_profile.db
    )
    add_test(
      NAME rejects_unrelated_sqlite_input
      COMMAND ${CMAKE_COMMAND}
        -DTRACELOOM_ANALYZER=$<TARGET_FILE:traceloom>
        -DTRACELOOM_UNRELATED_DB=${CMAKE_CURRENT_BINARY_DIR}/unrelated_profile.db
        -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/boundary/reject_unrelated_sqlite_input.cmake
    )
    set_tests_properties(
      rejects_unrelated_sqlite_input
      PROPERTIES DEPENDS prepare_unrelated_sqlite_input
    )

    add_test(
      NAME analyze_cuda_nsys_compat_sidecar_cli
      COMMAND traceloom
        --source-kind cuda_nsys_sqlite
        --source-db ${CMAKE_CURRENT_BINARY_DIR}/cuda_nsys_minimal_fixture.sqlite
        --threads 2
        --timings
        --sidecar-only
        --no-aug-db
        --compat-sidecar-out ${CMAKE_CURRENT_BINARY_DIR}/cuda_nsys_cli_compat.db
        --loop-tree-out ${CMAKE_CURRENT_BINARY_DIR}/cuda_nsys_loop_tree_v2.md
        --loop-tree-device-id 0
    )
    set_tests_properties(
      analyze_cuda_nsys_compat_sidecar_cli
      PROPERTIES
        DEPENDS cuda_nsys_sqlite_adapter_tests
        PASS_REGULAR_EXPRESSION "timing source_kind=cuda_nsys_sqlite"
    )
    add_test(
      NAME analyze_cuda_nsys_compat_sidecar_db
      COMMAND cli_sidecar_smoke_tests
        ${CMAKE_CURRENT_BINARY_DIR}/cuda_nsys_cli_compat.db cuda
        ${CMAKE_CURRENT_BINARY_DIR}/cuda_nsys_loop_tree_v2.md
    )
    set_tests_properties(
      analyze_cuda_nsys_compat_sidecar_db
      PROPERTIES
        DEPENDS analyze_cuda_nsys_compat_sidecar_cli
    )

    add_test(
      NAME prepare_cuda_nsys_default_input_dir
      COMMAND ${CMAKE_COMMAND} -E make_directory
        ${CMAKE_CURRENT_BINARY_DIR}/default_cli_input
    )
    add_test(
      NAME prepare_cuda_nsys_default_input
      COMMAND ${CMAKE_COMMAND} -E copy
        ${CMAKE_CURRENT_BINARY_DIR}/cuda_nsys_minimal_fixture.sqlite
        ${CMAKE_CURRENT_BINARY_DIR}/default_cli_input/profile.sqlite
    )
    set_tests_properties(
      prepare_cuda_nsys_default_input
      PROPERTIES
        DEPENDS
          "cuda_nsys_sqlite_adapter_tests;prepare_cuda_nsys_default_input_dir"
    )
    add_test(
      NAME analyze_cuda_nsys_default_augmented_db_cli
      COMMAND traceloom
        ${CMAKE_CURRENT_BINARY_DIR}/default_cli_input/profile.sqlite
        --threads 2
        --classification-rule-override
        cuda.anchor.task.type.cuda.kernel.51cc7472.priority=96
    )
    set_tests_properties(
      analyze_cuda_nsys_default_augmented_db_cli
      PROPERTIES
        DEPENDS prepare_cuda_nsys_default_input
        PASS_REGULAR_EXPRESSION
          "wrote queryable database timeline: .*default_cli_input/traceloom/analysis.db"
    )
    add_test(
      NAME analyze_cuda_nsys_default_augmented_db
      COMMAND cli_sidecar_smoke_tests
        ${CMAKE_CURRENT_BINARY_DIR}/default_cli_input/traceloom/analysis.db
        augmented
    )
    set_tests_properties(
      analyze_cuda_nsys_default_augmented_db
      PROPERTIES
        DEPENDS analyze_cuda_nsys_default_augmented_db_cli
    )

    add_test(
      NAME analyze_fixture_compat_sidecar_cli
      COMMAND traceloom-native-analyze-fixture
        --fixture
        ${TRACELOOM_NATIVE_FIXTURE_ROOT}/protected_sequence/f1_tiny_repeated_pair.json
        --threads 2
        --compat-sidecar-out ${CMAKE_CURRENT_BINARY_DIR}/fixture_cli_compat.db
    )
    add_test(
      NAME analyze_fixture_compat_sidecar_db
      COMMAND cli_sidecar_smoke_tests
        ${CMAKE_CURRENT_BINARY_DIR}/fixture_cli_compat.db fixture
    )
    set_tests_properties(
      analyze_fixture_compat_sidecar_db
      PROPERTIES DEPENDS analyze_fixture_compat_sidecar_cli
    )

  endif()

  add_test(
    NAME include_boundary_tests
    COMMAND ${CMAKE_COMMAND}
      -DTRACELOOM_NATIVE_ROOT=${CMAKE_CURRENT_SOURCE_DIR}
      -P ${CMAKE_CURRENT_SOURCE_DIR}/tests/boundary/include_boundary_tests.cmake
  )
endif()
