Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions apps/starry/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,25 @@ cargo xtask starry qemu \
See `picoclaw-cli/README.md` for the online agent, gateway, and interactive
flows.

## K230 KPU NNCase

The `k230-kpu-nncase` case is the operator-facing K230 KPU/NPU demo. It installs
the StarryOS guest NNCase runtime demo binaries, `yolov8n_320.kmodel`, and
`bus.jpg` into the K230 rootfs overlay, then runs:

```text
.kmodel -> NNCase runtime -> KPU command stream -> /dev/kpu -> IRQ/done -> output hashes
```

```bash
bash apps/starry/k230-kpu-nncase/c/tools/build-nncase-runtime-binaries.sh
PATH="$PWD/target/qemu-k230-docker-build:$PATH" \
cargo xtask starry app qemu -t k230-kpu-nncase --arch riscv64
```

See `k230-kpu-nncase/README.md` and `docs/k230-kpu-nncase-runtime.md` for the
asset preparation flow.

## Redis

The `redis` case is a QEMU app workflow that installs Redis into a temporary
Expand Down
79 changes: 79 additions & 0 deletions apps/starry/k230-kpu-nncase/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# Starry K230 KPU NNCase App

This Starry app is the operator-facing K230 KPU/NPU demo. It runs the same
runtime path as the `kpu-nncase-runtime` test case:

```text
yolov8n_320.kmodel
-> K230 SDK NNCase runtime in StarryOS userspace
-> KPU command stream
-> /dev/kpu ioctl/mmap
-> QEMU K230 KPU model
-> done/IRQ and output tensor hashes
```

The lower-level device regression remains under `test-suit/starryos`; the demo
application, build helper, and teacher script live here under `apps/starry`.

## Local Assets

This app does not commit the real model, image, K230 SDK static libraries, or
prebuilt guest binaries. Prepare the official SDK assets under:

```text
target/official-k230/k230-sdk-src/
```

See `docs/k230-kpu-nncase-runtime.md` for the full SDK preparation flow.

Build the ignored StarryOS guest binaries with:

```sh
bash apps/starry/k230-kpu-nncase/c/tools/build-nncase-runtime-binaries.sh
```

The script writes:

```text
apps/starry/k230-kpu-nncase/c/assets/bin/
kpu-nncase-minimal
k230-yolov8n-demo
```

## Run As A Starry App

Prepare the K230 QEMU fork first:

```sh
bash test-suit/starryos/k230-qemu/prepare-k230-qemu.sh
```

Then run:

```sh
PATH="$PWD/target/qemu-k230-docker-build:$PATH" \
cargo xtask starry app qemu -t k230-kpu-nncase --arch riscv64
```

Expected success markers:

```text
NNCASE_MINIMAL_PASS
YOLOV8N_DEMO_PASS
K230_NNCASE_RUNTIME_PASS
```

## Teacher Demo

For a terminal-friendly demonstration with streamed logs and a short evidence
summary, run:

```sh
bash apps/starry/k230-kpu-nncase/demo-teacher.sh
```

The legacy test-suite wrapper remains available:

```sh
bash test-suit/starryos/k230-qemu/qemu-k230/demo-teacher.sh
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
env = {}
features = [
"k230",
]
log = "Info"
plat_dyn = true
target = "riscv64gc-unknown-none-elf"
209 changes: 209 additions & 0 deletions apps/starry/k230-kpu-nncase/c/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
cmake_minimum_required(VERSION 3.20)
project(k230-nncase-runtime C)

set(K230_SDK_ROOT "" CACHE PATH "Path to the checked out K230 SDK")
set(K230_KMODEL "" CACHE FILEPATH "Path to yolov8n_320.kmodel")
set(K230_BUS_JPG "" CACHE FILEPATH "Path to bus.jpg")
set(K230_LINUX_MUSL_PREFIX "" CACHE PATH "Linux-runnable riscv64-linux-musl cross sysroot prefix")
set(K230_PREBUILT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/assets/bin")

if(NOT K230_SDK_ROOT)
set(_probe "${CMAKE_CURRENT_SOURCE_DIR}")
while(NOT _probe STREQUAL "/")
if(EXISTS "${_probe}/target/official-k230/k230-sdk-src")
set(K230_SDK_ROOT "${_probe}/target/official-k230/k230-sdk-src")
break()
endif()
get_filename_component(_probe "${_probe}" DIRECTORY)
endwhile()
endif()

set(K230_BUILD_FROM_SOURCE OFF)
if(K230_CXX)
set(K230_BUILD_FROM_SOURCE ON)
elseif(K230_SDK_ROOT AND CMAKE_HOST_SYSTEM_PROCESSOR MATCHES "^(x86_64|amd64|AMD64)$")
set(K230_CXX "${K230_SDK_ROOT}/toolchain/riscv64-linux-musleabi_for_x86_64-pc-linux-gnu/bin/riscv64-unknown-linux-musl-g++")
if(EXISTS "${K230_CXX}")
set(K230_BUILD_FROM_SOURCE ON)
endif()
endif()

if(NOT K230_KMODEL AND K230_SDK_ROOT)
set(K230_KMODEL "${K230_SDK_ROOT}/src/big/kmodel/ai_poc/kmodel/yolov8n_320.kmodel")
endif()
if(NOT EXISTS "${K230_KMODEL}")
message(FATAL_ERROR "yolov8n_320.kmodel was not found; set -DK230_KMODEL=/path/to/yolov8n_320.kmodel")
endif()
if(NOT K230_BUS_JPG AND K230_SDK_ROOT)
set(K230_BUS_JPG "${K230_SDK_ROOT}/src/big/kmodel/ai_poc/images/bus.jpg")
endif()
if(NOT EXISTS "${K230_BUS_JPG}")
message(FATAL_ERROR "bus.jpg was not found; set -DK230_BUS_JPG=/path/to/bus.jpg")
endif()

if(K230_BUILD_FROM_SOURCE)
if(NOT K230_SDK_ROOT)
message(FATAL_ERROR "K230 SDK root was not found; set -DK230_SDK_ROOT=/path/to/k230-sdk-src")
endif()

set(K230_NNCASE_ROOT "${K230_SDK_ROOT}/src/big/nncase/riscv64")
set(K230_NNCASE_LIB "${K230_NNCASE_ROOT}/nncase/lib")
set(K230_RVV_LIB "${K230_NNCASE_ROOT}/rvvlib")
set(K230_JPEG_ROOT "${K230_SDK_ROOT}/src/big/utils/lib/hhb-prebuilt-decode")

if(NOT EXISTS "${K230_NNCASE_LIB}/libNncase.Runtime.Native.a")
message(FATAL_ERROR "K230 SDK NNCase runtime was not found; set -DK230_SDK_ROOT=/path/to/k230-sdk-src")
endif()
if(NOT EXISTS "${K230_RVV_LIB}")
message(FATAL_ERROR "K230 SDK RVV library directory was not found under ${K230_RVV_LIB}")
endif()
if(NOT EXISTS "${K230_JPEG_ROOT}/lib")
message(FATAL_ERROR "K230 SDK JPEG decode library directory was not found under ${K230_JPEG_ROOT}")
endif()
if(NOT EXISTS "${K230_CXX}")
message(FATAL_ERROR "K230 SDK C++ compiler was not found; set -DK230_CXX=/path/to/riscv64-unknown-linux-musl-g++")
endif()

message(STATUS "Building K230 NNCase runtime demo binaries from source")
message(STATUS "Using K230 NNCase C++ compiler: ${K230_CXX}")

if(NOT K230_LINUX_MUSL_PREFIX)
if(EXISTS "/linux-musl-cross/riscv64-linux-musl/lib/crt1.o")
set(K230_LINUX_MUSL_PREFIX "/linux-musl-cross")
elseif(EXISTS "/opt/riscv64-linux-musl-cross/riscv64-linux-musl/lib/crt1.o")
set(K230_LINUX_MUSL_PREFIX "/opt/riscv64-linux-musl-cross")
endif()
endif()

set(K230_LINUX_MUSL_SYSROOT "${K230_LINUX_MUSL_PREFIX}/riscv64-linux-musl")
if(NOT EXISTS "${K230_LINUX_MUSL_SYSROOT}/lib/crt1.o"
OR NOT EXISTS "${K230_LINUX_MUSL_SYSROOT}/lib/libc.a")
message(FATAL_ERROR "Linux riscv64-musl sysroot was not found; set -DK230_LINUX_MUSL_PREFIX=/path/to/riscv64-linux-musl-cross")
endif()

file(GLOB K230_LINUX_MUSL_GCC_LIB_CANDIDATES LIST_DIRECTORIES true
"${K230_LINUX_MUSL_PREFIX}/lib/gcc/riscv64-linux-musl/*")
list(SORT K230_LINUX_MUSL_GCC_LIB_CANDIDATES)
list(REVERSE K230_LINUX_MUSL_GCC_LIB_CANDIDATES)
list(GET K230_LINUX_MUSL_GCC_LIB_CANDIDATES 0 K230_LINUX_MUSL_GCC_LIB)
if(NOT EXISTS "${K230_LINUX_MUSL_GCC_LIB}/libgcc.a")
message(FATAL_ERROR "Linux riscv64-musl libgcc was not found under ${K230_LINUX_MUSL_PREFIX}")
endif()

get_filename_component(K230_SDK_TOOLCHAIN_ROOT "${K230_CXX}" DIRECTORY)
get_filename_component(K230_SDK_TOOLCHAIN_ROOT "${K230_SDK_TOOLCHAIN_ROOT}" DIRECTORY)
set(K230_SDK_GCC_LIB "${K230_SDK_TOOLCHAIN_ROOT}/lib/gcc/riscv64-unknown-linux-musl/12.0.1")
set(K230_SDK_TARGET_LIB "${K230_SDK_TOOLCHAIN_ROOT}/riscv64-unknown-linux-musl/lib")
if(NOT EXISTS "${K230_SDK_GCC_LIB}/crtbeginT.o"
OR NOT EXISTS "${K230_SDK_TARGET_LIB}/libstdc++.a")
message(FATAL_ERROR "K230 SDK target C++ runtime libraries were not found under ${K230_SDK_TOOLCHAIN_ROOT}")
endif()

set(K230_COMMON_SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/src/k230_sdk_compat.cc"
)
set(K230_COMMON_INCLUDES
"-I${CMAKE_CURRENT_SOURCE_DIR}/src"
"-I${K230_NNCASE_ROOT}"
"-I${K230_NNCASE_ROOT}/nncase/include"
"-I${K230_NNCASE_ROOT}/rvvlib/include"
"-I${K230_SDK_ROOT}/src/big/mpp/userapps/api"
"-I${K230_SDK_ROOT}/src/big/mpp/include"
"-I${K230_SDK_ROOT}/src/big/mpp/include/comm"
"-I${K230_JPEG_ROOT}/include"
)
set(K230_COMMON_FLAGS
"-std=gnu++17"
"--sysroot=${K230_LINUX_MUSL_SYSROOT}"
"-O2"
"-g0"
"-Wall"
"-Wextra"
"-Wno-unused-parameter"
"-Wno-missing-field-initializers"
"-fdiagnostics-color=never"
)
set(K230_LINK_START_FILES
"-nostdlib"
"-static"
"-Wl,-e,_start"
"${K230_LINUX_MUSL_SYSROOT}/lib/crt1.o"
"${K230_LINUX_MUSL_SYSROOT}/lib/crti.o"
"${K230_SDK_GCC_LIB}/crtbeginT.o"
)
set(K230_LINK_ARGS
"-Wl,--wrap=gnne_enable"
"-Wl,--wrap=open"
"-Wl,--wrap=openat"
"-Wl,--wrap=close"
"-Wl,--wrap=mmap"
"-Wl,--wrap=munmap"
"-Wl,--wrap=ioctl"
"-L${K230_NNCASE_LIB}"
"-L${K230_RVV_LIB}"
"-L${K230_JPEG_ROOT}/lib"
"-L${K230_LINUX_MUSL_SYSROOT}/lib"
"-L${K230_LINUX_MUSL_GCC_LIB}"
"-L${K230_SDK_GCC_LIB}"
"-L${K230_SDK_TARGET_LIB}"
"-Wl,--start-group"
"-lrvv"
"-lNncase.Runtime.Native"
"-lnncase.rt_modules.k230"
"-lfunctional_k230"
"-ljpeg"
"-lz"
"-lstdc++"
"-lsupc++"
"-lm"
"-lc"
"-lgcc"
"-lgcc_eh"
"-latomic"
"-Wl,--end-group"
"${K230_SDK_GCC_LIB}/crtend.o"
"${K230_LINUX_MUSL_SYSROOT}/lib/crtn.o"
)

function(add_k230_sdk_binary name)
set(output "${CMAKE_CURRENT_BINARY_DIR}/${name}")
add_custom_command(
OUTPUT "${output}"
COMMAND "${K230_CXX}"
${K230_COMMON_FLAGS}
${K230_COMMON_INCLUDES}
${K230_LINK_START_FILES}
${ARGN}
${K230_COMMON_SOURCES}
"-o" "${output}"
${K230_LINK_ARGS}
DEPENDS ${ARGN} ${K230_COMMON_SOURCES}
VERBATIM
COMMAND_EXPAND_LISTS
)
add_custom_target("${name}-target" ALL DEPENDS "${output}")
install(PROGRAMS "${output}" DESTINATION usr/bin)
endfunction()

add_k230_sdk_binary(kpu-nncase-minimal
"${CMAKE_CURRENT_SOURCE_DIR}/src/kpu_nncase_minimal.cc"
)
add_k230_sdk_binary(k230-yolov8n-demo
"${CMAKE_CURRENT_SOURCE_DIR}/src/k230_yolov8n_demo.cc"
)
else()
if(EXISTS "${K230_PREBUILT_DIR}/kpu-nncase-minimal" AND EXISTS "${K230_PREBUILT_DIR}/k230-yolov8n-demo")
message(STATUS "Using prebuilt K230 NNCase runtime demo binaries from ${K230_PREBUILT_DIR}")
install(PROGRAMS
"${K230_PREBUILT_DIR}/kpu-nncase-minimal"
"${K230_PREBUILT_DIR}/k230-yolov8n-demo"
DESTINATION usr/bin
)
else()
message(FATAL_ERROR "K230 NNCase runtime prebuilt binaries are missing. Run c/tools/build-nncase-runtime-binaries.sh from this case directory, or pass -DK230_CXX=/path/to/riscv64-unknown-linux-musl-g++ on an amd64 K230 SDK environment.")
endif()
endif()

install(PROGRAMS src/run-nncase-runtime-demo.sh DESTINATION usr/bin RENAME k230-nncase-runtime-demo)
install(FILES "${K230_KMODEL}" DESTINATION usr/share/k230-nncase-runtime/models)
install(FILES "${K230_BUS_JPG}" DESTINATION usr/share/k230-nncase-runtime/images)
2 changes: 2 additions & 0 deletions apps/starry/k230-kpu-nncase/c/assets/bin/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*
!.gitignore
Loading