Skip to content

Commit 18b9b5b

Browse files
authored
feat: add webassembly compilation" (#12)
* feat: working wasm emission * feat: output companion .js file * wip: better interfacing * feat: working listing of devices for a driver * feat: add bytecode loader class * wip: call bytecode * wip * merge * feat: first working draft of wasm execution * wip * fix: return typed arrays * fix: double-free on context * chore: cleanup comments * refactor: modularize cmakelists * feat: compile fewer things for wasm host tools
1 parent a30e664 commit 18b9b5b

23 files changed

+930
-221
lines changed

.github/workflows/embedded_devices.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,9 @@ jobs:
7070
if: steps.cache-iree-dir.outputs.cache-hit != 'true'
7171
run: make clone_iree
7272
- name: Compile Host
73-
run: BUILD_IREE_RUNTIME=true ./scripts/build_and_package.sh --target=host
73+
run: ./scripts/build_and_package.sh --target=host
7474
- name: Compile
75-
run: BUILD_IREE_RUNTIME=false ./scripts/build_and_package.sh --target=${{ matrix.build_target }}
75+
run: ./scripts/build_and_package.sh --target=${{ matrix.build_target }}
7676
- name: Release Artifacts
7777
uses: softprops/action-gh-release@v2
7878
if: startsWith(github.ref, 'refs/tags/')

Makefile

+54-25
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,54 @@ PRIV_DIR = $(MIX_APP_PATH)/priv
1717
ifeq ($(NX_IREE_PREFER_PRECOMPILED), true)
1818
all: nx_iree
1919
else
20-
all: install_runtime nx_iree
20+
all: clone_iree install_runtime nx_iree
2121
endif
2222

2323
.PHONY: clone_iree
2424
clone_iree: $(NX_IREE_SOURCE_DIR)
25+
@echo "Cloned IREE into $(NX_IREE_SOURCE_DIR)"
2526

26-
.PHONY: iree_source_dir
27-
iree_source_dir:
27+
$(NX_IREE_SOURCE_DIR):
2828
./scripts/clone_iree.sh $(IREE_GIT_REV) $(NX_IREE_SOURCE_DIR)
2929

3030
IREE_CMAKE_BUILD_DIR ?= $(abspath iree-runtime/iree-build)
3131
IREE_RUNTIME_INCLUDE_PATH := $(abspath $(NX_IREE_SOURCE_DIR)/runtime/src/iree)
3232
IREE_RUNTIME_BUILD_DIR ?= $(abspath iree-runtime/build)
3333
IREE_INSTALL_DIR ?= $(abspath iree-runtime/host/install)
3434

35-
IREE_CMAKE_CONFIG ?= Release
36-
3735
IREE_BUILD_TARGET ?= host
3836

3937
BUILD_TARGET_FLAGS = -S $(abspath cmake)
4038

4139
CUDA_PRESENT := $(shell command -v nvcc >/dev/null 2>&1 && echo true || echo false)
4240

4341
ifeq ($(CUDA_PRESENT), true)
44-
CFLAGS += -DCUDA_ENABLED
45-
CMAKE_CXX_FLAGS += -DCUDA_ENABLED
42+
ifeq ($(IREE_BUILD_TARGET), host)
43+
CFLAGS += -DCUDA_ENABLED
44+
CMAKE_CXX_FLAGS += -DCUDA_ENABLED
45+
endif
4646
endif
4747

48-
# flags for xcode 15.4
48+
BUILD_HOST_COMPILER ?= OFF
49+
BUILD_HOST_COMPILER_FLAGS := ""
50+
51+
ifeq ($(BUILD_HOST_COMPILER), ON)
52+
BUILD_HOST_COMPILER_FLAGS += \
53+
-DIREE_BUILD_COMPILER=ON \
54+
-DIREE_INPUT_TORCH=OFF \
55+
-DIREE_INPUT_TOSA=OFF \
56+
-DIREE_BUILD_SAMPLES=OFF \
57+
-DIREE_BUILD_TESTS=OFF \
58+
-DIREE_HAL_DRIVER_DEFAULTS=OFF \
59+
-DIREE_BUILD_PYTHON_BINDINGS=OFF \
60+
-DIREE_BUILD_BINDINGS_TFLITE=OFF
61+
endif
62+
63+
# apple target flags specified for xcode 15.4
4964
ifeq ($(IREE_BUILD_TARGET), host)
65+
else ifeq ($(IREE_BUILD_TARGET), webassembly)
66+
BUILD_TARGET_FLAGS += \
67+
-DIREE_HOST_BIN_DIR=$(abspath $(IREE_HOST_BIN_DIR))
5068
else ifeq ($(IREE_BUILD_TARGET), ios)
5169
BUILD_TARGET_FLAGS += \
5270
-DCMAKE_SYSTEM_NAME=iOS\
@@ -102,39 +120,43 @@ else
102120
endif
103121

104122
.PHONY: install_runtime
105-
install_runtime: iree_host $(IREE_INSTALL_DIR)
106-
123+
ifneq ($(strip $(IREE_HOST_BUILD_DIR)),)
124+
install_runtime: $(IREE_HOST_INSTALL_DIR)/bin/iree-flatcc-cli $(IREE_INSTALL_DIR)
125+
else
126+
install_runtime: $(IREE_INSTALL_DIR)
127+
endif
107128

108-
CMAKE_SOURCES = $(abspath cmake/src/runtime.cc) $(abspath cmake/src/runtime.h)
129+
CMAKE_SOURCES = $(wildcard cmake/src/*.cc cmake/src/*.h)
109130

110-
$(IREE_INSTALL_DIR): iree_source_dir $(CMAKE_SOURCES)
111-
cmake -G Ninja -B $(IREE_CMAKE_BUILD_DIR) \
131+
$(IREE_INSTALL_DIR): $(NX_IREE_SOURCE_DIR) $(CMAKE_SOURCES)
132+
$(EMCMAKE) cmake -G Ninja -B $(IREE_CMAKE_BUILD_DIR) \
112133
-DCMAKE_BUILD_TYPE=$(IREE_CMAKE_CONFIG)\
113134
-DIREE_BUILD_COMPILER=OFF\
114135
-DIREE_RUNTIME_BUILD_DIR=$(IREE_RUNTIME_BUILD_DIR)\
115136
-DIREE_RUNTIME_INCLUDE_PATH=$(IREE_RUNTIME_INCLUDE_PATH)\
116137
-DNX_IREE_SOURCE_DIR=$(NX_IREE_SOURCE_DIR) \
117138
-DCMAKE_CXX_FLAGS=$(CMAKE_CXX_FLAGS) \
118139
$(BUILD_TARGET_FLAGS)
119-
120140
cmake --build $(IREE_CMAKE_BUILD_DIR) --config $(IREE_CMAKE_CONFIG)
121141
cmake --install $(IREE_CMAKE_BUILD_DIR) --config $(IREE_CMAKE_CONFIG) --prefix $(IREE_INSTALL_DIR)
122142

123143
.PHONY: iree_host
124-
ifeq ($(BUILD_IREE_RUNTIME), true)
144+
ifneq ($(strip $(IREE_HOST_BUILD_DIR)),)
145+
iree_host: $(IREE_HOST_BUILD_DIR)/bin/iree-flatcc-cli
146+
else
125147
iree_host:
126-
@echo "Building IREE runtime host binaries at $(IREE_HOST_BUILD_DIR)."
148+
@echo "IREE_HOST_BUILD_DIR not set. Skipping host binaries build."
149+
endif
150+
151+
$(IREE_HOST_INSTALL_DIR)/bin/iree-flatcc-cli: $(NX_IREE_SOURCE_DIR) $(CMAKE_SOURCES)
152+
@echo "Building IREE runtime host binaries at `$(IREE_HOST_BUILD_DIR)`."
127153
cmake -G Ninja -B $(IREE_HOST_BUILD_DIR) \
128154
-DCMAKE_INSTALL_PREFIX=$(IREE_HOST_INSTALL_DIR) \
129-
-DIREE_BUILD_COMPILER=OFF\
155+
-DIREE_BUILD_COMPILER=$(BUILD_HOST_COMPILER) $(BUILD_HOST_COMPILER_FLAGS) \
130156
-DCMAKE_BUILD_TYPE=$(IREE_CMAKE_CONFIG) \
131157
-DCMAKE_CXX_FLAGS=$(CMAKE_CXX_FLAGS) \
132158
-S $(NX_IREE_SOURCE_DIR)
133159
cmake --build $(IREE_HOST_BUILD_DIR) --target install
134-
else
135-
iree_host:
136-
@echo "Not building IREE runtime host binaries. Skipping."
137-
endif
138160

139161
### NxIREE Runtime NIF library
140162

@@ -146,11 +168,12 @@ NX_IREE_RUNTIME_LIB = cache/iree-runtime
146168
NX_IREE__IREE_RUNTIME_INCLUDE_PATH = $(NX_IREE_RUNTIME_LIB)/include
147169
NX_IREE_RUNTIME_SO ?= $(MIX_APP_PATH)/priv/libnx_iree_runtime.so
148170

149-
CFLAGS = -fPIC -I$(ERTS_INCLUDE_DIR) -I$(NX_IREE__IREE_RUNTIME_INCLUDE_PATH) -Wall -Wno-sign-compare \
150-
-Wno-unused-parameter -Wno-missing-field-initializers -Wno-comment \
151-
-std=c++17 -w
171+
CFLAGS = -fPIC -I$(ERTS_INCLUDE_DIR) -I$(NX_IREE__IREE_RUNTIME_INCLUDE_PATH) -Wall -std=c++17 -w
172+
173+
IREE_CMAKE_CONFIG ?= Release
152174

153175
ifdef DEBUG
176+
IREE_CMAKE_CONFIG = RelWithDebInfo
154177
CFLAGS += -g
155178
else
156179
CFLAGS += -O3
@@ -215,14 +238,20 @@ $(NX_IREE_SO): $(NX_IREE_CACHE_SO)
215238
$(NX_IREE__IREE_RUNTIME_INCLUDE_PATH):
216239
cp -r iree-runtime/host/install $(dir $@)
217240

218-
cache/objs/%.o: c_src/%.cc
241+
cache/objs/%.o: c_src/%.cc $(CMAKE_SOURCES)
219242
@ mkdir -p $(dir $@)
220243
$(CXX) $(CFLAGS) -o $@ -c $<
221244

222245
# Print IREE Dir
246+
.PHONY: PTD
223247
PTD:
224248
@ echo $(NX_IREE_SOURCE_DIR)
225249

250+
.PHONY: wasm_build
251+
webassembly:
252+
./scripts/build_and_package.sh --target=host --build-compiler
253+
./scripts/build_and_package.sh --target=webassembly
254+
226255
clean:
227256
rm -rf cache/objs
228257
rm -rf $(TARGET_DIR)

c_src/nx_iree.cc

-36
Original file line numberDiff line numberDiff line change
@@ -309,42 +309,6 @@ std::string iree_type_to_nx_type(iree_hal_element_type_t type) {
309309
return "invalid_type";
310310
}
311311

312-
iree_hal_element_type_t nx_type_to_iree_type(std::string type) {
313-
using type_enum = iree_hal_element_types_t;
314-
315-
if (type == "i8") {
316-
return type_enum::IREE_HAL_ELEMENT_TYPE_INT_8;
317-
} else if (type == "i16") {
318-
return type_enum::IREE_HAL_ELEMENT_TYPE_INT_16;
319-
} else if (type == "i32") {
320-
return type_enum::IREE_HAL_ELEMENT_TYPE_INT_32;
321-
} else if (type == "i64") {
322-
return type_enum::IREE_HAL_ELEMENT_TYPE_INT_64;
323-
} else if (type == "ui8") {
324-
return type_enum::IREE_HAL_ELEMENT_TYPE_UINT_8;
325-
} else if (type == "ui16") {
326-
return type_enum::IREE_HAL_ELEMENT_TYPE_UINT_16;
327-
} else if (type == "ui32") {
328-
return type_enum::IREE_HAL_ELEMENT_TYPE_UINT_32;
329-
} else if (type == "ui64") {
330-
return type_enum::IREE_HAL_ELEMENT_TYPE_UINT_64;
331-
} else if (type == "bf16") {
332-
return type_enum::IREE_HAL_ELEMENT_TYPE_BFLOAT_16;
333-
} else if (type == "f16") {
334-
return type_enum::IREE_HAL_ELEMENT_TYPE_FLOAT_16;
335-
} else if (type == "f32") {
336-
return type_enum::IREE_HAL_ELEMENT_TYPE_FLOAT_32;
337-
} else if (type == "f64") {
338-
return type_enum::IREE_HAL_ELEMENT_TYPE_FLOAT_64;
339-
} else if (type == "c64") {
340-
return type_enum::IREE_HAL_ELEMENT_TYPE_COMPLEX_FLOAT_64;
341-
} else if (type == "c128") {
342-
return type_enum::IREE_HAL_ELEMENT_TYPE_COMPLEX_FLOAT_128;
343-
}
344-
345-
return type_enum::IREE_HAL_ELEMENT_TYPE_NONE;
346-
}
347-
348312
DECLARE_NIF(read_buffer_nif) {
349313
iree_hal_device_t** device;
350314
iree::runtime::IREETensor** input;

cmake/CMakeLists.txt

+8-49
Original file line numberDiff line numberDiff line change
@@ -14,72 +14,31 @@ set(IREE_INPUT_STABLEHLO ON)
1414
set(IREE_BUILD_TESTS OFF)
1515
set(IREE_BUILD_SAMPLES OFF)
1616

17-
set(IREE_HAL_DRIVER_DEFAULTS ON)
18-
set(IREE_HAL_DRIVER_LOCAL_SYNC ON)
19-
set(IREE_HAL_EXECUTABLE_LOADER_DEFAULTS OFF)
20-
set(IREE_HAL_EXECUTABLE_LOADER_EMBEDDED_ELF ON)
21-
2217
if(CMAKE_BUILD_TYPE MATCHES MinSizeRel)
2318
set(IREE_SIZE_OPTIMIZED ON)
2419
endif()
2520

2621
file(GLOB iree_runtime_sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cc" "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
27-
add_library(${_NAME} SHARED ${iree_runtime_sources})
28-
29-
set(__BUILD_DIR "${IREE_RUNTIME_BUILD_DIR}")
30-
31-
add_subdirectory("${NX_IREE_SOURCE_DIR}" ${__BUILD_DIR} EXCLUDE_FROM_ALL)
3222

33-
install(
34-
TARGETS ${_NAME}
35-
DESTINATION "."
36-
)
37-
38-
set_target_properties(${_NAME} PROPERTIES SUFFIX ".so")
23+
if("$ENV{IREE_BUILD_TARGET}" STREQUAL "webassembly")
24+
add_subdirectory(modules/emscripten)
25+
else()
26+
add_subdirectory(modules/default)
27+
endif()
3928

4029
set_target_properties(${_NAME} PROPERTIES
4130
INSTALL_RPATH_USE_LINK_PATH TRUE
4231
BUILD_WITH_INSTALL_RPATH TRUE
4332
)
4433

45-
if($ENV{DEBUG})
46-
set(CMAKE_BUILD_TYPE Debug)
47-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g")
48-
endif()
34+
set(__BUILD_DIR "${IREE_RUNTIME_BUILD_DIR}")
4935

50-
if(NOT APPLE)
51-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -shared -fvisibility=default")
52-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--export-dynamic")
53-
else()
54-
# Although the compiler complains about not using these,
55-
# things only work with them set
56-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -undefined dynamic_lookup -fvisibility=default")
57-
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-export_dynamic")
58-
check_c_compiler_flag("-arch arm64" ARM64_SUPPORTED)
59-
if(ARM64_SUPPORTED)
60-
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAC_ARM64")
61-
endif()
62-
endif()
36+
add_subdirectory("${NX_IREE_SOURCE_DIR}" ${__BUILD_DIR} EXCLUDE_FROM_ALL)
6337

6438
# Ensure visibility of all symbols
6539
set(CMAKE_CXX_VISIBILITY_PRESET default)
6640
set(CMAKE_VISIBILITY_INLINES_HIDDEN OFF)
6741

6842
target_compile_options(${_NAME} PUBLIC ${IREE_DEFAULT_COPTS})
6943

70-
add_definitions(-DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1)
71-
72-
target_link_libraries(${_NAME} iree_runtime_runtime)
73-
target_link_libraries(${_NAME} iree_tooling_context_util)
74-
75-
# Install the header files - this will make it easier to copy them over
76-
# to the final bundle.
77-
78-
install(DIRECTORY "${IREE_RUNTIME_INCLUDE_PATH}"
79-
DESTINATION "include"
80-
FILES_MATCHING PATTERN "*.h")
81-
82-
file(GLOB HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/src/*.h")
83-
84-
install(FILES ${HEADER_FILES}
85-
DESTINATION "include/nx_iree")
44+
add_definitions(-DLLVM_DISABLE_ABI_BREAKING_CHECKS_ENFORCING=1)

cmake/modules/default/CMakeLists.txt

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
set(IREE_HAL_DRIVER_DEFAULTS ON)
2+
set(IREE_HAL_DRIVER_LOCAL_SYNC ON)
3+
set(IREE_HAL_EXECUTABLE_LOADER_DEFAULTS OFF)
4+
set(IREE_HAL_EXECUTABLE_LOADER_EMBEDDED_ELF ON)
5+
6+
list(REMOVE_ITEM iree_runtime_sources
7+
"${CMAKE_SOURCE_DIR}/src/emscripten_api.cc"
8+
"${CMAKE_SOURCE_DIR}/src/emscripten_api.h"
9+
)
10+
11+
add_library(${_NAME} SHARED ${iree_runtime_sources})
12+
13+
set_target_properties(${_NAME} PROPERTIES
14+
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
15+
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}"
16+
SUFFIX ".so"
17+
)
18+
19+
install(
20+
TARGETS ${_NAME}
21+
DESTINATION "."
22+
)
23+
24+
target_link_libraries(${_NAME} iree_runtime_runtime)
25+
target_link_libraries(${_NAME} iree_tooling_context_util)
26+
27+
# Install the header files - this will make it easier to copy them over
28+
# to the final bundle.
29+
install(DIRECTORY "${IREE_RUNTIME_INCLUDE_PATH}"
30+
DESTINATION "include"
31+
FILES_MATCHING PATTERN "*.h")
32+
33+
file(GLOB HEADER_FILES "${CMAKE_SOURCE_DIR}/src/*.h")
34+
35+
install(FILES ${HEADER_FILES}
36+
DESTINATION "include/nx_iree")
37+
38+
if(APPLE)
39+
# Although the compiler complains about not using these,
40+
# things only work with them set
41+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -undefined dynamic_lookup -fvisibility=default")
42+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-export_dynamic")
43+
check_c_compiler_flag("-arch arm64" ARM64_SUPPORTED)
44+
if(ARM64_SUPPORTED)
45+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DMAC_ARM64")
46+
endif()
47+
else()
48+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -shared -fvisibility=default")
49+
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--export-dynamic")
50+
endif()

0 commit comments

Comments
 (0)