Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes builds for cpp examples. #57

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.idea
7 changes: 7 additions & 0 deletions cpp/examples/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.bazelrc
/bazel-*
/out

** Editors **
*.swp
*.idea
82 changes: 82 additions & 0 deletions cpp/examples/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
# Copyright 2022 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
SHELL := /bin/bash
MAKEFILE_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))
OS := $(shell uname -s)

# Allowed CPU values: k8, armv7a, aarch64
ifeq ($(OS),Linux)
CPU ?= k8
else
$(error $(OS) is not supported)
endif
ifeq ($(filter $(CPU),k8 armv7a aarch64),)
$(error CPU must be k8, armv7a, aarch64)
endif

# Allowed COMPILATION_MODE values: opt, dbg
COMPILATION_MODE ?= opt
ifeq ($(filter $(COMPILATION_MODE),opt dbg),)
$(error COMPILATION_MODE must be opt or dbg)
endif

BAZEL_OUT_DIR := $(MAKEFILE_DIR)/bazel-out/$(CPU)-$(COMPILATION_MODE)/bin
BAZEL_BUILD_FLAGS := --crosstool_top=@crosstool//:toolchains \
--compiler=gcc \
--compilation_mode=$(COMPILATION_MODE) \
--copt=-DNPY_NO_DEPRECATED_API=NPY_1_7_API_VERSION \
--copt=-std=c++14 \
--verbose_failures \
--cpu=$(CPU) \
--experimental_repo_remote_exec

ifeq ($(COMPILATION_MODE), opt)
BAZEL_BUILD_FLAGS += --linkopt=-Wl,--strip-all
else ifeq ($(COMPILATION_MODE), dbg)
# for now, disable arm_neon in dbg.
# see: https://github.com/tensorflow/tensorflow/issues/33360
BAZEL_BUILD_FLAGS += --cxxopt -DTF_LITE_DISABLE_X86_NEON
endif

ifeq ($(CPU),k8)
BAZEL_BUILD_FLAGS += --copt=-includeglibc_compat.h
else ifeq ($(CPU),aarch64)
BAZEL_BUILD_FLAGS += --copt=-ffp-contract=off
else ifeq ($(CPU),armv7a)
BAZEL_BUILD_FLAGS += --copt=-ffp-contract=off
endif


DEMO_OUT_DIR := $(MAKEFILE_DIR)/out/$(CPU)/

.PHONY: all lstpu classify clean


examples:
bazel build $(BAZEL_BUILD_FLAGS) //classification:classify
bazel build $(BAZEL_BUILD_FLAGS) //lstpu:lstpu
mkdir -p $(DEMO_OUT_DIR)
cp -f $(BAZEL_OUT_DIR)/classification/classify \
$(DEMO_OUT_DIR)
cp -f $(BAZEL_OUT_DIR)/lstpu/lstpu \
$(DEMO_OUT_DIR)
rm -rf $(MAKEFILE_DIR)/bazel-*

clean:
rm -rf $(MAKEFILE_DIR)/out

DOCKER_WORKSPACE=$(MAKEFILE_DIR)
DOCKER_CPUS=k8 armv7a aarch64 armv6
DOCKER_TAG_BASE=tflite-coral-examples
include $(MAKEFILE_DIR)/docker/docker.mk
14 changes: 14 additions & 0 deletions cpp/examples/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Simple C++ code example

These examples show how to build a simple C++ program that uses the EdgeTPU
runtime library. This subdirectory contains 2 different examples:

- lstpu:
- lists available Edge TPU devices (It does not perform inference).
- classification:
- classify a bmp image using a classification model.

## Compile the examples
```bash
$ make DOCKER_TARGET=examples DOCKER_CPUS=k8 docker-build
```
49 changes: 49 additions & 0 deletions cpp/examples/WORKSPACE
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Copyright 2020 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
workspace(name = "tflite_examples")

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")

TENSORFLOW_COMMIT = "48c3bae94a8b324525b45f157d638dfd4e8c3be1"
TENSORFLOW_SHA256 = "363420a67b4cfa271cd21e5c8fac0d7d91b18b02180671c3f943c887122499d8"

# These values come from the Tensorflow workspace. If the TF commit is updated,
# these should be updated to match.
IO_BAZEL_RULES_CLOSURE_COMMIT = "308b05b2419edb5c8ee0471b67a40403df940149"
IO_BAZEL_RULES_CLOSURE_SHA256 = "5b00383d08dd71f28503736db0500b6fb4dda47489ff5fc6bed42557c07c6ba9"

CORAL_CROSSTOOL_COMMIT = "142e930ac6bf1295ff3ba7ba2b5b6324dfb42839"
CORAL_CROSSTOOL_SHA256 = "088ef98b19a45d7224be13636487e3af57b1564880b67df7be8b3b7eee4a1bfc"

# Configure libedgetpu and downstream libraries (TF and Crosstool).
http_archive(
name = "libedgetpu",
sha256 = "d76d18c5a96758dd620057028cdd4e129bd885480087a5c7334070bba3797e58",
strip_prefix = "libedgetpu-14eee1a076aa1af7ec1ae3c752be79ae2604a708",
urls = [
"https://github.com/google-coral/libedgetpu/archive/14eee1a076aa1af7ec1ae3c752be79ae2604a708.tar.gz"
],
)

load("@libedgetpu//:workspace.bzl", "libedgetpu_dependencies")
libedgetpu_dependencies(TENSORFLOW_COMMIT, TENSORFLOW_SHA256,
IO_BAZEL_RULES_CLOSURE_COMMIT,IO_BAZEL_RULES_CLOSURE_SHA256,
CORAL_CROSSTOOL_COMMIT,CORAL_CROSSTOOL_SHA256)


load("@org_tensorflow//tensorflow:workspace.bzl", "tf_workspace")
tf_workspace(tf_repo_name = "org_tensorflow")

load("@coral_crosstool//:configure.bzl", "cc_crosstool")
cc_crosstool(name = "crosstool", additional_system_include_directories=["//docker/include"])
23 changes: 23 additions & 0 deletions cpp/examples/classification/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
cc_binary(
name = "classify",
srcs = ["classify.cc"],
deps = [
"@libedgetpu//tflite/public:oss_edgetpu_direct_all",
"@org_tensorflow//tensorflow/lite:builtin_op_data",
"@org_tensorflow//tensorflow/lite:framework",
"@org_tensorflow//tensorflow/lite/kernels:builtin_ops",
],
)
46 changes: 0 additions & 46 deletions cpp/examples/classification/Makefile

This file was deleted.

28 changes: 10 additions & 18 deletions cpp/examples/classification/classify.cc
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@
#include <utility>
#include <vector>

#include "edgetpu_c.h"
#include "tensorflow/lite/builtin_op_data.h"
#include "tensorflow/lite/interpreter.h"
#include "tensorflow/lite/kernels/register.h"
#include "tensorflow/lite/model.h"
#include "tflite/public/edgetpu.h"

namespace {
constexpr size_t kBmpFileHeaderSize = 14;
Expand Down Expand Up @@ -130,17 +131,6 @@ int main(int argc, char* argv[]) {
const std::string image_file = argv[3];
const float threshold = std::stof(argv[4]);

// Find TPU device.
size_t num_devices;
std::unique_ptr<edgetpu_device, decltype(&edgetpu_free_devices)> devices(
edgetpu_list_devices(&num_devices), &edgetpu_free_devices);

if (num_devices == 0) {
std::cerr << "No connected TPU found" << std::endl;
return 1;
}
const auto& device = devices.get()[0];

// Load labels.
auto labels = ReadLabels(label_file);
if (labels.empty()) {
Expand All @@ -164,17 +154,19 @@ int main(int argc, char* argv[]) {
return 1;
}

// Create interpreter.
// Get edgetpu context.
auto edgetpu_context = edgetpu::EdgeTpuManager::GetSingleton()->OpenDevice();
tflite::ops::builtin::BuiltinOpResolver resolver;
resolver.AddCustom(edgetpu::kCustomOp, edgetpu::RegisterCustomOp());

// Create interpreter.
std::unique_ptr<tflite::Interpreter> interpreter;
if (tflite::InterpreterBuilder(*model, resolver)(&interpreter) != kTfLiteOk) {
std::cerr << "Cannot create interpreter" << std::endl;
return 1;
exit(EXIT_FAILURE);
}

auto* delegate =
edgetpu_create_delegate(device.type, device.path, nullptr, 0);
interpreter->ModifyGraphWithDelegate({delegate, edgetpu_free_delegate});
interpreter->SetExternalContext(kTfLiteEdgeTpuContext, edgetpu_context.get());
interpreter->SetNumThreads(1);

// Allocate tensors.
if (interpreter->AllocateTensors() != kTfLiteOk) {
Expand Down
54 changes: 54 additions & 0 deletions cpp/examples/docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Copyright 2021 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

ARG IMAGE
FROM ${IMAGE}

COPY update_sources.sh /
RUN /update_sources.sh

RUN dpkg --add-architecture armhf
RUN dpkg --add-architecture arm64
RUN apt-get update && apt-get install -y \
sudo \
debhelper \
build-essential \
crossbuild-essential-armhf \
crossbuild-essential-arm64 \
libusb-1.0-0-dev \
libusb-1.0-0-dev:arm64 \
libusb-1.0-0-dev:armhf \
python \
python3-all \
python3-six \
zlib1g-dev \
zlib1g-dev:armhf \
zlib1g-dev:arm64 \
pkg-config \
zip \
unzip \
curl \
wget \
git \
subversion \
vim \
python3-numpy

ARG BAZEL_VERSION=2.1.0
RUN wget -O /bazel https://github.com/bazelbuild/bazel/releases/download/${BAZEL_VERSION}/bazel-${BAZEL_VERSION}-installer-linux-x86_64.sh && \
bash /bazel && \
rm -f /bazel

RUN svn export https://github.com/google-coral/edgetpu/trunk/libedgetpu /libedgetpu

39 changes: 39 additions & 0 deletions cpp/examples/docker/docker.mk
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
DOCKER_MK_DIR := $(realpath $(dir $(lastword $(MAKEFILE_LIST))))

# Docker
DOCKER_CPUS ?= k8 armv7a armv6 aarch64
DOCKER_TARGETS ?=
DOCKER_IMAGE ?= debian:buster
DOCKER_TAG_BASE ?= "bazel-cross"
DOCKER_TAG := "$(DOCKER_TAG_BASE)-$(subst :,-,$(DOCKER_IMAGE))"
DOCKER_SHELL_COMMAND ?=

ifndef DOCKER_WORKSPACE
$(error DOCKER_WORKSPACE is not defined)
endif

WORKSPACE := /workspace
MAKE_COMMAND := \
for cpu in $(DOCKER_CPUS); do \
make CPU=\$${cpu} COMPILATION_MODE=$(COMPILATION_MODE) -C /workspace $(DOCKER_TARGETS) || exit 1; \
done

define run_command
chmod a+w /; \
groupadd --gid $(shell id -g) $(shell id -g -n); \
useradd -m -e '' -s /bin/bash --gid $(shell id -g) --uid $(shell id -u) $(shell id -u -n); \
echo '$(shell id -u -n) ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers; \
su $(shell id -u -n) $(if $(1),-c '$(1)',)
endef

docker-image:
docker build $(DOCKER_IMAGE_OPTIONS) -t $(DOCKER_TAG) \
--build-arg IMAGE=$(DOCKER_IMAGE) $(DOCKER_MK_DIR)

docker-shell: docker-image
docker run --rm -i --tty -v $(DOCKER_WORKSPACE):$(WORKSPACE) --workdir $(WORKSPACE) \
$(DOCKER_TAG) /bin/bash -c "$(call run_command,$(DOCKER_SHELL_COMMAND))"

docker-build: docker-image
docker run --rm -i $(shell tty -s && echo --tty) -v $(DOCKER_WORKSPACE):$(WORKSPACE) \
$(DOCKER_TAG) /bin/bash -c "$(call run_command,$(MAKE_COMMAND))"
Empty file.
Loading