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
7 changes: 7 additions & 0 deletions core/iwasm/libraries/wasi-nn/include/wasi_ephemeral_nn.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/*
* Copyright (C) 2025 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

#define WASM_ENABLE_WASI_EPHEMERAL_NN 1
#include "wasi_nn.h"
8 changes: 8 additions & 0 deletions wamr-wasi-extensions/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

cmake_minimum_required (VERSION 3.14)

project(wamr-wasi-extensions LANGUAGES C)

add_subdirectory(nn)
25 changes: 25 additions & 0 deletions wamr-wasi-extensions/nn/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

add_library(wamr-wasi-nn INTERFACE)

set(wasi_nn_header_dir ${CMAKE_CURRENT_SOURCE_DIR}/../../core/iwasm/libraries/wasi-nn/include)

set(headers
${wasi_nn_header_dir}/wasi_ephemeral_nn.h
${wasi_nn_header_dir}/wasi_nn.h
${wasi_nn_header_dir}/wasi_nn_types.h
)

set_property(TARGET wamr-wasi-nn PROPERTY PUBLIC_HEADER ${headers})

target_include_directories(wamr-wasi-nn
INTERFACE
$<BUILD_INTERFACE:${wasi_nn_header_dir}>
$<INSTALL_INTERFACE:include>)

install(TARGETS wamr-wasi-nn
EXPORT wamr-wasi-nn-config
PUBLIC_HEADER DESTINATION include/wamr)
install(EXPORT wamr-wasi-nn-config
DESTINATION lib/cmake/wamr-wasi-nn)
13 changes: 13 additions & 0 deletions wamr-wasi-extensions/samples/nn/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

cmake_minimum_required(VERSION 3.14)

set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED YES)
set(CMAKE_C_EXTENSIONS NO)

project(nn-classification-openvino LANGUAGES C)
add_executable(nn-classification-openvino "app.c")
find_package(wamr-wasi-nn REQUIRED)
target_link_libraries(nn-classification-openvino wamr-wasi-nn)
169 changes: 169 additions & 0 deletions wamr-wasi-extensions/samples/nn/app.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
/*
* Copyright (C) 2025 Midokura Japan KK. All rights reserved.
* SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
*/

#include <sys/stat.h>

#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include <wamr/wasi_ephemeral_nn.h>

/*
* what this application does is basically same as:
* https://github.com/bytecodealliance/wasmtime/tree/efa236e58d09570baaf27865da33fb852fcf40a5/crates/wasi-nn/examples/classification-example
*
* map_file/unmap_file are copy-and-pasted from:
* https://github.com/yamt/toywasm/blob/0eaad8cacd0cc7692946ff19b25994f106113be8/lib/fileio.c
*/

int
map_file(const char *path, void **pp, size_t *sizep)
{
void *p;
size_t size;
ssize_t ssz;
int fd;
int ret;

fd = open(path, O_RDONLY);
if (fd == -1) {
ret = errno;
assert(ret != 0);
return ret;
}
struct stat st;
ret = fstat(fd, &st);
if (ret == -1) {
ret = errno;
assert(ret != 0);
close(fd);
return ret;
}
size = st.st_size;
if (size > 0) {
p = malloc(size);
}
else {
/* Avoid a confusing error */
p = malloc(1);
}
if (p == NULL) {
close(fd);
return ENOMEM;
}
ssz = read(fd, p, size);
if (ssz != size) {
ret = errno;
assert(ret != 0);
close(fd);
return ret;
}
close(fd);
*pp = p;
*sizep = size;
return 0;
}

void
unmap_file(void *p, size_t sz)
{
free(p);
}

static void
print_result(const float *result, size_t sz)
{
/*
* just dump the raw result.
* you can postprocess the output with eg. "sort -k2nr | head"
*/
int i;
for (i = 0; i < sz / sizeof(float); i++) {
printf("%d %f\n", i, result[i]);
}
}

int
main(int argc, char **argv)
{
wasi_nn_error nnret;
int ret;
void *xml;
size_t xmlsz;
ret = map_file("fixture/model.xml", &xml, &xmlsz);
if (ret != 0) {
fprintf(stderr, "failed to load fixture/model.xml: %s\n",
strerror(ret));
exit(1);
}
void *weights;
size_t weightssz;
ret = map_file("fixture/model.bin", &weights, &weightssz);
if (ret != 0) {
fprintf(stderr, "failed to load fixture/model.bin: %s\n",
strerror(ret));
exit(1);
}
/* note: openvino takes two buffers, namely IR and weights */
graph_builder builders[2] = { {
.buf = xml,
.size = xmlsz,
},
{
.buf = weights,
.size = weightssz,
} };
graph g;
nnret = load(builders, 2, openvino, cpu, &g);
unmap_file(xml, xmlsz);
unmap_file(weights, weightssz);
if (nnret != success) {
fprintf(stderr, "load failed with %d\n", (int)nnret);
exit(1);
}
graph_execution_context ctx;
nnret = init_execution_context(g, &ctx);
if (nnret != success) {
fprintf(stderr, "init_execution_context failed with %d\n", (int)nnret);
exit(1);
}
void *tensordata;
size_t tensordatasz;
ret = map_file("fixture/tensor.bgr", &tensordata, &tensordatasz);
if (ret != 0) {
fprintf(stderr, "failed to load fixture/tensor.bgr: %s\n",
strerror(ret));
exit(1);
}
tensor tensor = {
.dimensions = { .buf = (uint32_t[]){1, 3, 224, 224,}, .size = 4, },
.type = fp32,
.data = tensordata,
};
nnret = set_input(ctx, 0, &tensor);
unmap_file(tensordata, tensordatasz);
if (nnret != success) {
fprintf(stderr, "set_input failed with %d\n", (int)nnret);
exit(1);
}
nnret = compute(ctx);
if (nnret != success) {
fprintf(stderr, "compute failed with %d\n", (int)nnret);
exit(1);
}
float result[1001];
uint32_t resultsz;
nnret = get_output(ctx, 0, (void *)result, sizeof(result), &resultsz);
if (nnret != success) {
fprintf(stderr, "get_output failed with %d\n", (int)nnret);
exit(1);
}
print_result(result, resultsz);
}
19 changes: 19 additions & 0 deletions wamr-wasi-extensions/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#! /bin/sh

# Copyright (C) 2025 Midokura Japan KK. All rights reserved.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception

PREFIX=/tmp/wamr
WASI_SDK=${WASI_SDK:-/opt/wasi-sdk}

cmake -B build-lib \
-DCMAKE_TOOLCHAIN_FILE=${WASI_SDK}/share/cmake/wasi-sdk.cmake \
-DCMAKE_INSTALL_PREFIX=${PREFIX} \
.
cmake --build build-lib -t install

cmake -B build-app-nn \
-DCMAKE_TOOLCHAIN_FILE=${WASI_SDK}/share/cmake/wasi-sdk.cmake \
-DCMAKE_PREFIX_PATH=${PREFIX} \
samples/nn
cmake --build build-app-nn
Loading