Skip to content

Commit

Permalink
Libbackscrub - separation into library and wrapper application (#86)
Browse files Browse the repository at this point in the history
* Initial separation of Tensorflow code into reusable static library
* position independent code required to allow use in shared libraries
* libdeepseg -> libbackscrub
* Debug callback, library cleanup function
* CMake build of separate library
* Export dependencies from backscrub library for use in other projects
* regression fix: use normalization values for model
* Re-structure into more modular build
* Install headers to sub-folder
* TFBASE->TENSORFLOW in Makefile
* Remove using namespace tflite
* Dependency fix for parallel builds
* remove TFLITE_MINIMAL_CHECK macro from API
* Remove hack to include libtensorflow-lite.a in libbackscrub.a
* Removed shared state between app and lib, now all hidden in lib. Prefixed lib function names
* Avoid full data clone for mask output
* Remove stdarg from debug callback, cleanup pointer checks
  • Loading branch information
phlash authored Jun 5, 2021
1 parent 81e8b21 commit 71747d9
Show file tree
Hide file tree
Showing 10 changed files with 526 additions and 274 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Output folder
# Output folders
bin/
build/

# dotfiles and folders
.*/
Expand Down
92 changes: 78 additions & 14 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
cmake_minimum_required(VERSION 3.16)
project(backscrub CXX)

if(NOT DEFINED TENSORFLOW)
set(TENSORFLOW tensorflow)
endif()

find_package(Git)
if(GIT_FOUND)
execute_process(
Expand All @@ -12,6 +16,9 @@ else()
endif()
message("Version: ${DEEPSEG_VERSION}")

# always build PIC everywhere
set(CMAKE_POSITION_INDEPENDENT_CODE TRUE)

find_package(OpenCV REQUIRED COMPONENTS core imgproc imgcodecs video videoio highgui)

# force compilation of XNNPACK delegate (without this the too clever-by-half use
Expand All @@ -20,29 +27,86 @@ add_compile_definitions(TFLITE_BUILD_WITH_XNNPACK_DELEGATE)

# This assumes that tensorflow got checked out as submodule.
# True, if `git clone` had the additional option `--recursive`.
add_subdirectory(tensorflow/tensorflow/lite
add_subdirectory(${TENSORFLOW}/tensorflow/lite
"${CMAKE_CURRENT_BINARY_DIR}/tensorflow-lite" EXCLUDE_FROM_ALL)

add_compile_definitions(DEEPSEG_VERSION=${DEEPSEG_VERSION})
include_directories(BEFORE .)

add_library(backscrub
lib/libbackscrub.cc
lib/transpose_conv_bias.cc)

target_link_libraries(backscrub
tensorflow-lite ${CMAKE_DL_LIBS}
opencv_core
opencv_imgproc
)

add_library(videoio
videoio/loopback.cc)

target_link_libraries(videoio)

add_executable(deepseg
deepseg.cc
loopback.cc
transpose_conv_bias.cc
app/deepseg.cc
)

target_link_libraries(deepseg
tensorflow-lite ${CMAKE_DL_LIBS}
opencv_core
opencv_video
opencv_videoio
opencv_imgproc
opencv_imgcodecs
opencv_highgui
target_link_libraries(deepseg
backscrub
videoio
opencv_core
opencv_video
opencv_videoio
opencv_imgproc
opencv_imgcodecs
opencv_highgui
)

# Export our library, and all transitive dependencies - sadly Tensorflow Lite's
# CMakeLists.txt does not export these for us
function(get_link_libraries target outlist)
message(STATUS "get_link_libraries(${target} ${outlist})")
# recursive dependency munger, feed with a name and a list to extend
get_target_property(target_type ${target} TYPE)
if(${target_type} STREQUAL "INTERFACE_LIBRARY")
get_target_property(libs ${target} INTERFACE_LINK_LIBRARIES)
else()
get_target_property(libs ${target} LINK_LIBRARIES)
endif()
foreach(lib IN LISTS libs)
if(NOT TARGET ${lib})
continue()
endif()
get_target_property(unalias ${lib} ALIASED_TARGET)
if("${unalias}" STREQUAL "unalias-NOTFOUND")
set(unalias ${lib})
endif()
get_target_property(imp ${unalias} IMPORTED)
if(${imp})
continue()
endif()
list(FIND ${outlist} ${unalias} exists)
if(NOT exists EQUAL -1)
continue()
endif()
list(APPEND ${outlist} ${unalias})
get_link_libraries(${unalias} ${outlist})
set(${outlist} ${${outlist}} PARENT_SCOPE)
endforeach()
endfunction()

set(BACKSCRUB_DEPS "")
get_link_libraries(backscrub BACKSCRUB_DEPS)

export(TARGETS
backscrub
${BACKSCRUB_DEPS}
FILE BackscrubTargets.cmake)

install(TARGETS deepseg)
install(DIRECTORY models
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/deepbacksub
install(TARGETS backscrub)
install(FILES libbackscrub.h DESTINATION include/backscrub)
install(DIRECTORY models
DESTINATION ${CMAKE_INSTALL_PREFIX}/share/backscrub
FILES_MATCHING PATTERN "*.tflite" PATTERN "*.md")
43 changes: 34 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# this is licensed software, @see LICENSE file.

# OpenCV & Tensorflow recommended flags for performance..
CFLAGS = -Ofast -march=native -fno-trapping-math -fassociative-math -funsafe-math-optimizations -Wall -pthread
CFLAGS = -fPIC -Ofast -march=native -fno-trapping-math -fassociative-math -funsafe-math-optimizations -Wall -pthread
LDFLAGS = -lrt -ldl

# Version
Expand All @@ -11,13 +11,14 @@ ifeq ($(VERSION),)
VERSION=v0.2.0-no-git
endif

CFLAGS += -D DEEPSEG_VERSION=$(VERSION)
CFLAGS += -D DEEPSEG_VERSION=$(VERSION) -I.

# TensorFlow
TFBASE=tensorflow
TFLITE=$(TFBASE)/tensorflow/lite/tools/make
TENSORFLOW=tensorflow
TFLITE=$(TENSORFLOW)/tensorflow/lite/tools/make
TFDOWN=$(TFLITE)/downloads/cpuinfo
TFLIBS=$(TFLITE)/gen/linux_x86_64/lib
TFCFLAGS += -I $(TFBASE) -I $(TFLITE)/downloads/absl -I $(TFLITE)/downloads/flatbuffers/include -ggdb
TFCFLAGS += -I $(TENSORFLOW) -I $(TFLITE)/downloads/absl -I $(TFLITE)/downloads/flatbuffers/include -ggdb
TFLDFLAGS += -L $(TFLIBS) -ltensorflow-lite -ldl

# OpenCV
Expand All @@ -43,12 +44,36 @@ clean:
$(BIN):
-mkdir -p $(BIN)

# Primary binary - special deps
$(BIN)/deepseg: $(TFLIBS)/libtensorflow-lite.a deepseg.cc loopback.cc transpose_conv_bias.cc
# Primary binaries - special deps
$(BIN)/deepseg: app/deepseg.cc $(BIN)/libbackscrub.a $(BIN)/libvideoio.a $(TFLIBS)/libtensorflow-lite.a
g++ $^ ${CFLAGS} ${TFCFLAGS} ${LDFLAGS} ${TFLDFLAGS} -o $@

$(TFLIBS)/libtensorflow-lite.a: $(TFLITE)
cd $(TFLITE) && ./download_dependencies.sh && ./build_lib.sh
# Backscrub library, must be linked with libtensorflow-lite.a
$(BIN)/libbackscrub.a: $(BIN)/libbackscrub.o $(BIN)/transpose_conv_bias.o
ar rv $@ $^

# Video I/O library - this is a Linux/v4l2loopback only target for now but replaceable later..
$(BIN)/libvideoio.a: $(BIN)/loopback.o
ar rv $@ $^

# Compile rules for various source directories
$(BIN)/%.o: lib/%.cc $(TFDOWN)
g++ $< ${CFLAGS} ${TFCFLAGS} -c -o $@

$(BIN)/%.o: videoio/%.cc $(TFDOWN)
g++ $< ${CFLAGS} ${TFCFLAGS} -c -o $@

$(BIN)/%.o: app/%.cc $(TFDOWN)
g++ $< ${CFLAGS} ${TFCFLAGS} -c -o $@

# As cloned, TFLite needs building into a static library, as per:
# https://github.com/tensorflow/tensorflow/tree/master/tensorflow/lite/tools/make
# we split this into download (pre-compile) and build (pre-link)
$(TFDOWN): $(TFLITE)
cd $(TFLITE) && ./download_dependencies.sh

$(TFLIBS)/libtensorflow-lite.a: $(TFDOWN)
cd $(TFLITE) && ./build_lib.sh

$(TFLITE):
git submodule update --init --recursive
Expand Down
Loading

0 comments on commit 71747d9

Please sign in to comment.