├── .gitignore ├── LICENSE.txt ├── README.rst ├── common_tools ├── download └── wait_for_server ├── curl ├── .gitignore ├── Makefile ├── README.md ├── curl.manifest.template └── test-docroot │ └── index.html ├── gcc ├── Makefile ├── README.md ├── gcc.manifest.template └── test_files │ ├── .gitignore │ ├── gzip.patch │ └── helloworld.c ├── iperf ├── .gitignore ├── Makefile ├── README.md └── iperf3.manifest.template ├── mongodb ├── .gitignore ├── Makefile ├── README.md ├── data │ └── db │ │ └── .gitkeep ├── mongod.manifest.template └── scripts │ ├── fetch.js │ └── insert.js ├── nodejs ├── .gitignore ├── Makefile ├── README.md ├── helloworld.js └── nodejs.manifest.template ├── openjdk ├── .gitignore ├── Makefile ├── MultiThreadMain.java ├── README.md └── java.manifest.template ├── openvino ├── .gitignore ├── Makefile ├── README.md └── benchmark_app.manifest.template ├── pytorch ├── .gitignore ├── Makefile ├── README.md ├── classes.txt ├── download-pretrained-model.py ├── input.jpg ├── pytorch.manifest.template └── pytorchexample.py ├── r ├── Makefile ├── R.manifest.template ├── README.md └── scripts │ ├── R-benchmark-25.R │ └── sample.r ├── scikit-learn-intelex ├── .gitignore ├── Makefile ├── README.md ├── run_tests.sh ├── scripts │ ├── download_dataset.py │ ├── kmeans_example.py │ └── kmeans_perf_eval.py └── sklearnex.manifest.template └── tensorflow-lite ├── .gitignore ├── Makefile ├── README.md └── label_image.manifest.template /.gitignore: -------------------------------------------------------------------------------- 1 | # sgx 2 | *.manifest 3 | *.manifest.sgx 4 | *.sig 5 | *.token 6 | 7 | # No editor backup files. 8 | *.sw* 9 | *.backup 10 | *.orig 11 | \#*# 12 | *~ 13 | 14 | # object file/libraries 15 | *.a 16 | *.o 17 | *.so 18 | *.so.* 19 | 20 | # Virtual environment 21 | my_venv 22 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2024 Gramine contributors 2 | 3 | Redistribution and use in source and binary forms, with or without modification, 4 | are permitted provided that the following conditions are met: 5 | 6 | 1. Redistributions of source code must retain the above copyright notice, this 7 | list of conditions and the following disclaimer. 8 | 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation and/or 11 | other materials provided with the distribution. 12 | 13 | 3. Neither the name of the copyright holder nor the names of its contributors 14 | may be used to endorse or promote products derived from this software without 15 | specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND 18 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 19 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 20 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 21 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 23 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 24 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 26 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | ******************************** 2 | Example applications for Gramine 3 | ******************************** 4 | 5 | .. This is not |~|, because that is in rst_prolog in conf.py, which GitHub cannot parse. 6 | GitHub doesn't appear to use it correctly anyway... 7 | .. |nbsp| unicode:: 0xa0 8 | :trim: 9 | 10 | This repository contains a curated set of Gramine examples. These examples are 11 | tested only against the most recent Gramine release (i.e., these examples are 12 | not guaranteed to work with older releases and unreleased versions of Gramine, 13 | including the latest master branch commits of Gramine). The examples were 14 | tested on Ubuntu 18.04 and 20.04. 15 | 16 | For instructions how to build and run each application under Gramine, please 17 | see the README in each subdirectory. 18 | 19 | Please note that most of the examples use oversimplified configurations which 20 | are *not secure*. E.g., we frequently specify security-critical files as 21 | ``sgx.allowed_files``. If you take these examples as templates for your own 22 | production workloads, please inspect and harden the configurations. 23 | 24 | We recommend to look at the (extensively commented) `Redis example 25 | `__ 26 | to get an idea how to write the README, Makefile and manifest files. If you want 27 | to contribute a new example to Gramine and you take the Redis example as a 28 | template, we recommend to remove the comments from your copies as they only add 29 | noise (see e.g. Memcached for a "stripped-down" example). 30 | 31 | Known unsupported applications 32 | ============================== 33 | 34 | Some applications are known to *not* run in Gramine. Typically this is because 35 | these applications depend on features currently not implemented in Gramine. 36 | 37 | We are aware of the following unsupported applications: 38 | 39 | - Apache web server: depends on Sys-V semaphores, unimplemented in Gramine. 40 | 41 | 42 | Building examples 43 | ================= 44 | 45 | All our examples use simple Makefiles to build the original application (if 46 | needed) and configure it to run in Gramine. Use one of these commands: 47 | 48 | - ``make``: create non-SGX no-debug-log manifest 49 | - ``make DEBUG=1``: create non-SGX debug-log manifest 50 | - ``make SGX=1``: create SGX no-debug-log manifest 51 | - ``make SGX=1 DEBUG=1``: create SGX debug-log manifest 52 | 53 | Use ``make clean`` to remove Gramine-generated artifacts and ``make distclean`` 54 | to remove all build artifacts (if applicable). 55 | 56 | How to Contribute? 57 | ================== 58 | 59 | Please put your application sample in a subdirectory with a comprehensible name. 60 | Ideally, the subdirectory name should be the same as your application. In 61 | addition, your application sample should have the following elements: 62 | 63 | - ``README.md``: 64 | Please document the tested environment and instructions for building and 65 | running the application. If your application sample has any known issues or 66 | requirements, please also specify them in the documentation. 67 | 68 | - ``Makefile``: 69 | Users should be able to build your application sample by running the ``make`` 70 | command. If your application needs extra building steps, please document them 71 | in the ``README.md``. If your application also runs on Intel SGX, please 72 | include the commands for signing and retrieving the SGX token in the 73 | ``Makefile``. 74 | 75 | - Manifest: 76 | Please provide the manifest needed for running your application sample. Do not 77 | hard-code any user-specific path or personal info in the manifest. The ideal 78 | way is to create a manifest template that contains variables to be replaced by 79 | runtime options in ``Makefile``. See other subdirectories for examples of the 80 | manifest templates. 81 | 82 | - Sample inputs and test suites: 83 | If you have any inputs and test suites for testing the application, 84 | please provide them in the same subdirectory, too. 85 | 86 | Please do not include any tarball of source code or binaries in the application 87 | samples. If an application requires downloading the source code or binaries, 88 | please provide instructions in the ``README.md``, or download them automatically 89 | and verify the checksums as part of the build process. 90 | -------------------------------------------------------------------------------- /common_tools/download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright (C) 2024 Gramine contributors 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | 6 | set -eu -o pipefail 7 | 8 | declare -a urls 9 | 10 | usage() { 11 | echo "Usage: download --url https://example.org/test --url https://mirror.example/blah --output test.tar --sha256 1234..abc" 12 | exit "${1:-0}" 13 | } 14 | 15 | while [ $# -gt 0 ]; do 16 | case "$1" in 17 | --url) 18 | urls+=("$2") 19 | shift 20 | ;; 21 | --output) 22 | output="$2" 23 | shift 24 | ;; 25 | --sha256) 26 | sha256="$2" 27 | shift 28 | ;; 29 | --help|-h) 30 | usage 31 | ;; 32 | *) 33 | usage 1 34 | ;; 35 | esac 36 | shift 37 | done 38 | 39 | if [ -z "${output:-}" ] || [ -z "${sha256:-}" ] || [ -z "${urls[*]}" ]; then 40 | usage 1 41 | fi 42 | 43 | if [ -n "${DL_CACHE:-}" ]; then 44 | if [ -f "$DL_CACHE/$sha256" ]; then 45 | echo "download: Found '$output' (${sha256:0:8}...) in cache." 46 | cp "$DL_CACHE/$sha256" "$output" 47 | exit 0 48 | fi 49 | fi 50 | 51 | if [ "${DL_OFFLINE:-}" == "true" ]; then 52 | echo "download: ERROR: File '$output' (${sha256:0:8}...) not found in cache and offline mode is active!" 53 | exit 1 54 | fi 55 | 56 | tmpd="$(mktemp -d -p "${DL_CACHE:-.}")" 57 | cleanup() { 58 | rm -rf "$tmpd" 59 | } 60 | trap cleanup EXIT 61 | 62 | for url in "${urls[@]}"; do 63 | echo "download: Trying to fetch $url" 64 | wget --timeout=10 -O "$tmpd/unverified" "$url" || true 65 | sha256_received="$(sha256sum "$tmpd/unverified" | cut -d ' ' -f 1)" 66 | if [ "$sha256" != "$sha256_received" ]; then 67 | echo "download: WARNING: Hash mismatch: Expected $sha256 but received $sha256_received" 68 | continue 69 | fi 70 | echo "download: Fetched '$output' (${sha256:0:8}...) successfully." 71 | if [ -n "${DL_CACHE:-}" ]; then 72 | mv "$tmpd/unverified" "$DL_CACHE/$sha256" 73 | cp "$DL_CACHE/$sha256" "$output" 74 | exit 0 75 | fi 76 | mv "$tmpd/unverified" "$output" 77 | exit 0 78 | done 79 | 80 | echo "download: ERROR: Failed to download '$output' (${sha256:0:8}...)! No URLs left to try." 81 | exit 1 82 | -------------------------------------------------------------------------------- /common_tools/wait_for_server: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright (C) 2024 Gramine contributors 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | 6 | set -eu 7 | 8 | usage() { 9 | echo "Usage: wait_for_server TIMEOUT IP PORT" 10 | exit 1 11 | } 12 | 13 | if [ $# -ne 3 ]; then 14 | usage 15 | fi 16 | 17 | exec timeout $1 bash -c "while ! nc -z -w1 $2 $3; do sleep 1; done" 18 | -------------------------------------------------------------------------------- /curl/.gitignore: -------------------------------------------------------------------------------- 1 | /OUTPUT 2 | -------------------------------------------------------------------------------- /curl/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 5 | CURL_DIR ?= /usr/bin 6 | 7 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 8 | 9 | ifeq ($(DEBUG),1) 10 | GRAMINE_LOG_LEVEL = debug 11 | else 12 | GRAMINE_LOG_LEVEL = error 13 | endif 14 | 15 | .PHONY: all 16 | all: curl.manifest 17 | ifeq ($(SGX),1) 18 | all: curl.manifest.sgx curl.sig 19 | endif 20 | 21 | curl.manifest: curl.manifest.template 22 | gramine-manifest \ 23 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 24 | -Dhome=$(HOME) \ 25 | -Darch_libdir=$(ARCH_LIBDIR) \ 26 | -Dcurl_dir=$(CURL_DIR) \ 27 | $< >$@ 28 | 29 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 30 | # for details on this workaround see 31 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 32 | curl.manifest.sgx curl.sig: sgx_sign 33 | @: 34 | 35 | .INTERMEDIATE: sgx_sign 36 | sgx_sign: curl.manifest 37 | gramine-sgx-sign \ 38 | --manifest $< \ 39 | --output $<.sgx 40 | 41 | ifeq ($(SGX),) 42 | GRAMINE = gramine-direct 43 | else 44 | GRAMINE = gramine-sgx 45 | endif 46 | 47 | .PHONY: check 48 | check: all 49 | (cd test-docroot; exec python3 -m http.server -b 127.0.0.1 19111) & httpd_pid=$$!; \ 50 | ../common_tools/wait_for_server 5 127.0.0.1 19111; \ 51 | $(GRAMINE) ./curl http://127.0.0.1:19111/ > OUTPUT; rc=$$?; \ 52 | kill $$httpd_pid; exit $$rc 53 | 54 | @grep -q "Hello World" OUTPUT && echo "[ Success 1/1 ]" 55 | @rm OUTPUT 56 | 57 | .PHONY: clean 58 | clean: 59 | $(RM) *.manifest *.manifest.sgx *.token *.sig OUTPUT 60 | 61 | .PHONY: distclean 62 | distclean: clean 63 | -------------------------------------------------------------------------------- /curl/README.md: -------------------------------------------------------------------------------- 1 | # Curl 2 | 3 | This directory contains a Makefile and template manifest to run curl on 4 | Gramine. This example uses curl installed on the system instead of compiling 5 | from source as some of the other examples do. 6 | 7 | # Quick Start 8 | 9 | To run the regression test execute ```make check```. To do the same for SGX, 10 | execute ```make SGX=1 check```. The regression test downloads the index page of 11 | `example.com`, thus it requires Internet connection. 12 | -------------------------------------------------------------------------------- /curl/curl.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # Curl manifest file example 5 | 6 | libos.entrypoint = "{{ curl_dir }}/curl" 7 | 8 | loader.log_level = "{{ log_level }}" 9 | 10 | loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" 11 | loader.env.HOME = "{{ home }}" 12 | 13 | loader.insecure__use_cmdline_argv = true 14 | 15 | fs.mounts = [ 16 | { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, 17 | { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, 18 | { uri = "file:/usr/{{ arch_libdir }}", path = "/usr{{ arch_libdir }}" }, 19 | { uri = "file:/etc", path = "/etc" }, 20 | { uri = "file:{{ curl_dir }}", path = "{{ curl_dir }}" }, 21 | ] 22 | 23 | sgx.enclave_size = "512M" 24 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '4' }} 25 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 26 | 27 | # `use_exinfo = true` is needed because the application may trigger lazy allocation of pages 28 | # (through exception handling) when EDMM is enabled 29 | sgx.use_exinfo = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 30 | 31 | sgx.trusted_files = [ 32 | "file:{{ curl_dir }}/curl", 33 | "file:{{ gramine.runtimedir() }}/", 34 | "file:{{ arch_libdir }}/", 35 | "file:/usr/{{ arch_libdir }}/", 36 | ] 37 | 38 | sgx.allowed_files = [ 39 | "file:/etc/nsswitch.conf", 40 | "file:/etc/host.conf", 41 | "file:/etc/resolv.conf", 42 | "file:/etc/ethers", 43 | "file:/etc/hosts", 44 | "file:/etc/group", 45 | "file:/etc/passwd", 46 | "file:/etc/gai.conf", 47 | ] 48 | -------------------------------------------------------------------------------- /curl/test-docroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | Hello World! 3 | -------------------------------------------------------------------------------- /gcc/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | THIS_DIR := $(abspath $(dir $(lastword $(MAKEFILE_LIST)))) 5 | 6 | ARCH_LONG ?= $(shell $(CC) -dumpmachine) 7 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 8 | 9 | BZIP2_MIRRORS ?= \ 10 | https://people.csail.mit.edu/smcc/projects/single-file-programs/bzip2.c \ 11 | https://packages.gramineproject.io/distfiles/single-file-programs/bzip2.c 12 | BZIP2_HASH ?= 89f331ce93cbf0ee7318802f440f1d7594bb78cf1a82069f2288e0459ec8d729 13 | GZIP_MIRRORS ?= \ 14 | https://people.csail.mit.edu/smcc/projects/single-file-programs/gzip.c \ 15 | https://packages.gramineproject.io/distfiles/single-file-programs/gzip.c 16 | GZIP_HASH ?= 7ec7d87822e6497648580064756f64e47dbd085727910ebbc52a7c240a88dc27 17 | 18 | ifeq ($(DEBUG),1) 19 | GRAMINE_LOG_LEVEL = debug 20 | else 21 | GRAMINE_LOG_LEVEL = error 22 | endif 23 | 24 | # awk '{print $NF}' ... print last field. 25 | BINUTILS_VERSION ?= $(shell ld -v | awk '{print $$NF}') 26 | GCC_MAJOR_VERSION ?= $(shell gcc -v 2>&1 | tail -n1 | awk '{print $$3}' | awk 'BEGIN {FS="."}{print $$1}') 27 | GCC_LIB_PATH ?= /usr/lib/gcc/$(ARCH_LONG) 28 | 29 | .PHONY: all 30 | all: gcc.manifest test_files/bzip2.c test_files/gzip.c 31 | ifeq ($(SGX),1) 32 | all: gcc.manifest.sgx gcc.sig 33 | endif 34 | 35 | gcc.manifest: gcc.manifest.template 36 | gramine-manifest \ 37 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 38 | -Darch_libdir=$(ARCH_LIBDIR) \ 39 | -Dgcc_lib_path=$(GCC_LIB_PATH) \ 40 | -Dgcc_major_version=$(GCC_MAJOR_VERSION) \ 41 | $< >$@ 42 | 43 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 44 | # for details on this workaround see 45 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 46 | gcc.manifest.sgx gcc.sig: sgx_sign 47 | @: 48 | 49 | .INTERMEDIATE: sgx_sign 50 | sgx_sign: gcc.manifest 51 | gramine-sgx-sign \ 52 | --manifest $< \ 53 | --output $<.sgx 54 | 55 | test_files/bzip2.c: 56 | ../common_tools/download --output $@ --sha256 $(BZIP2_HASH) $(foreach mirror,$(BZIP2_MIRRORS),--url $(mirror)) 57 | 58 | # the file hosted by the authors doesn't compile... 59 | test_files/gzip_broken.c: 60 | ../common_tools/download --output $@ --sha256 $(GZIP_HASH) $(foreach mirror,$(GZIP_MIRRORS),--url $(mirror)) 61 | 62 | test_files/gzip.c: test_files/gzip_broken.c test_files/gzip.patch 63 | patch test_files/gzip_broken.c -i test_files/gzip.patch -o $@ 64 | 65 | ifeq ($(SGX),) 66 | GRAMINE = gramine-direct 67 | else 68 | GRAMINE = gramine-sgx 69 | endif 70 | 71 | .PHONY: check 72 | check: all 73 | @echo "\n\nCompiling hello.c..." 74 | $(GRAMINE) gcc test_files/helloworld.c -o test_files/hello 75 | @chmod 755 test_files/hello 76 | -./test_files/hello 77 | $(RM) test_files/hello 78 | 79 | @echo "\n\nCompiling bzip2.c..." 80 | $(GRAMINE) gcc test_files/bzip2.c -o test_files/bzip2 81 | @chmod 755 test_files/bzip2 82 | $(RM) bzip2.tmp 83 | @cp -f test_files/bzip2 test_files/bzip2.copy 84 | ./test_files/bzip2 -z test_files/bzip2.copy 85 | ./test_files/bzip2 -d test_files/bzip2.copy.bz2 86 | diff -q test_files/bzip2 test_files/bzip2.copy 87 | $(RM) test_files/bzip2 test_file/bzip2.copy 88 | 89 | @echo "\n\nCompiling gzip.c..." 90 | $(GRAMINE) gcc test_files/gzip.c -o test_files/gzip 91 | @chmod 755 test_files/gzip 92 | @cp -f test_files/gzip test_files/gzip.copy 93 | ./test_files/gzip test_files/gzip.copy 94 | ./test_files/gzip -d test_files/gzip.copy.gz 95 | diff -q test_files/gzip test_files/gzip.copy 96 | $(RM) test_files/gzip test_files/gzip.copy 97 | 98 | .PHONY: clean 99 | clean: 100 | $(RM) *.manifest *.manifest.sgx *.sig *.token 101 | $(RM) test_files/gzip.copy test_files/bzip2.copy 102 | 103 | .PHONY: distclean 104 | distclean: clean 105 | $(RM) test_files/gzip_broken.c test_files/bzip2.c test_files/gzip.c 106 | -------------------------------------------------------------------------------- /gcc/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | ***TODO: this example should be reworked to use a standalone gcc version, not 4 | the one from the system*** 5 | 6 | This directory contains a Makefile and template manifests to run gcc and its 7 | related tools on Gramine. This example uses the package version of gcc and 8 | related tools (as, cc1, collect2, ld) installed on the system instead of 9 | compiling them from source as some of the other examples do. 10 | 11 | # Quick Start 12 | 13 | To run the regression tests execute ```make check```. To do the same for SGX, 14 | execute ```SGX=1 make check```. The regression tests build three sample programs 15 | - helloworld.c, bzip2.c and gzip.c - and test their functionality. 16 | 17 | # Note on OS distributions 18 | 19 | It is known that GCC relies on specific Glibc version/build. Because Gramine 20 | uses its own patched Glibc, this may lead to seemlingly inexplicable failures. 21 | In particular, this GCC example is known to work on Ubuntu 18.04/20.04 but fail 22 | on RHEL 8/CentOS 8. There is currently no fix for RHEL/CentOS. 23 | 24 | For details, see https://github.com/gramineproject/graphene/issues/2489. 25 | -------------------------------------------------------------------------------- /gcc/gcc.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # This is a general manifest template for running GCC and its utility programs, 5 | # including as, cc1, collect2, ld. 6 | 7 | libos.entrypoint = "/usr/bin/gcc" 8 | 9 | loader.log_level = "{{ log_level }}" 10 | 11 | loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" 12 | loader.env.PATH = "/bin:/usr/bin" 13 | 14 | loader.insecure__use_cmdline_argv = true 15 | 16 | fs.mounts = [ 17 | { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, 18 | { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, 19 | { uri = "file:/usr", path = "/usr" }, 20 | { uri = "file:/lib64", path = "/lib64" }, 21 | 22 | # cannot replace /tmp with "tmpfs" mount because Gramine currently doesn't support multi-process 23 | # "tmpfs" files (e.g., "tmpfs" files created in a child process are not visible in the parent) 24 | { uri = "file:/tmp", path = "/tmp" }, 25 | ] 26 | 27 | sgx.enclave_size = "1G" 28 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 29 | 30 | # `use_exinfo = true` is needed because the application may trigger lazy allocation of pages 31 | # (through exception handling) when EDMM is enabled 32 | sgx.use_exinfo = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 33 | 34 | sgx.trusted_files = [ 35 | "file:/usr/bin/gcc", 36 | "file:/usr/bin/as", 37 | "file:/usr/bin/ld", 38 | "file:{{ gramine.runtimedir() }}/", 39 | "file:{{ arch_libdir }}/", 40 | "file:/usr/{{ arch_libdir }}/", 41 | "file:{{ gcc_lib_path }}/{{ gcc_major_version }}/", 42 | "file:/lib64/", 43 | "file:/usr/include/", 44 | ] 45 | 46 | sgx.allowed_files = [ 47 | "file:/tmp", 48 | "file:test_files", 49 | ] 50 | -------------------------------------------------------------------------------- /gcc/test_files/.gitignore: -------------------------------------------------------------------------------- 1 | /bzip2 2 | /bzip2.c 3 | /bzip2.copy 4 | /gzip 5 | /gzip.c 6 | /gzip_broken.c 7 | /hello 8 | -------------------------------------------------------------------------------- /gcc/test_files/gzip.patch: -------------------------------------------------------------------------------- 1 | 2020c2020 2 | < static char * 3 | --- 4 | > char * 5 | -------------------------------------------------------------------------------- /gcc/test_files/helloworld.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | int main(int argc, char* argv[]) { 4 | printf("Hello world (%s)!\n", argv[0]); 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /iperf/.gitignore: -------------------------------------------------------------------------------- 1 | /install/ 2 | /iperf/ 3 | /*.tar.gz 4 | -------------------------------------------------------------------------------- /iperf/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 5 | 6 | IPERF_DIR = iperf 7 | IPERF_SHA256 ?= cc740c6bbea104398cc3e466befc515a25896ec85e44a662d5f4a767b9cf713e 8 | IPERF_SRC ?= iperf-3.16.tar.gz 9 | IPERF_MIRRORS ?= https://github.com/esnet/iperf/releases/download/3.16 10 | 11 | ifeq ($(DEBUG),1) 12 | GRAMINE_LOG_LEVEL = debug 13 | else 14 | GRAMINE_LOG_LEVEL = error 15 | endif 16 | 17 | .PHONY: all 18 | all: install/iperf3 install/libiperf.so.0 iperf3.manifest 19 | ifeq ($(SGX),1) 20 | all: iperf3.manifest.sgx iperf3.sig 21 | endif 22 | 23 | $(IPERF_DIR)/configure: 24 | ../common_tools/download --output $(IPERF_SRC) --sha256 $(IPERF_SHA256) \ 25 | $(foreach mirror,$(IPERF_MIRRORS),--url $(mirror)/$(IPERF_SRC)) 26 | mkdir $(IPERF_DIR) 27 | tar -C $(IPERF_DIR) --strip-components=1 -xf $(IPERF_SRC) 28 | 29 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 30 | # for details on this workaround see 31 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 32 | $(IPERF_DIR)/src/.libs/iperf3 $(IPERF_DIR)/src/.libs/libiperf.so.0: iperf_build 33 | @: 34 | 35 | .INTERMEDIATE: iperf_build 36 | iperf_build: $(IPERF_DIR)/configure 37 | cd $(IPERF_DIR) && ./configure 38 | $(MAKE) -C $(IPERF_DIR) 39 | 40 | iperf3.manifest: iperf3.manifest.template install/iperf3 install/libiperf.so.0 41 | gramine-manifest \ 42 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 43 | -Darch_libdir=$(ARCH_LIBDIR) \ 44 | $< > $@ 45 | 46 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 47 | # for details on this workaround see 48 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 49 | iperf3.sig iperf3.manifest.sgx: sgx_sign 50 | @: 51 | 52 | .INTERMEDIATE: sgx_sign 53 | sgx_sign: iperf3.manifest 54 | gramine-sgx-sign \ 55 | --manifest $< \ 56 | --output $<.sgx 57 | 58 | # for simplicity, copy iperf3 executable into our install directory 59 | install/iperf3: $(IPERF_DIR)/src/.libs/iperf3 60 | mkdir -p install 61 | cp $< $@ 62 | 63 | # for simplicity, copy libiperf library into our install directory 64 | install/libiperf.so.0: $(IPERF_DIR)/src/.libs/libiperf.so.0 65 | mkdir -p install 66 | cp $< $@ 67 | 68 | ################################## CLEANUP #################################### 69 | 70 | .PHONY: clean 71 | clean: 72 | $(RM) -r *.token *.sig *.manifest.sgx *.manifest install 73 | 74 | .PHONY: distclean 75 | distclean: clean 76 | $(RM) -r $(IPERF_DIR) *.tar.gz 77 | -------------------------------------------------------------------------------- /iperf/README.md: -------------------------------------------------------------------------------- 1 | # iperf 2 | 3 | This directory contains the Makefile and the template manifest for the most 4 | recent version of `iperf` as of this writing (3.16). 5 | 6 | # Prerequisites 7 | 8 | `iperf` has no prerequisites 9 | ([source](https://github.com/esnet/iperf/tree/3.16?tab=readme-ov-file#prerequisites)). 10 | 11 | # Building instructions 12 | 13 | We build `iperf` from source because Ubuntu 22.04 has `iperf3` v3.9 in its 14 | package repositories which is built with `TCP_CONGESTION` requirement (i.e., 15 | with `iperf3_cv_header_tcp_congestion="yes"` config option). Using the Ubuntu 16 | package would fail with the following error: 17 | ``` 18 | iperf3: error - unable to set TCP_CONGESTION: ... 19 | ``` 20 | 21 | Thus we build `iperf` manually. In this case, it is built without 22 | `TCP_CONGESTION`, and can successfully execute under Gramine[^1]. 23 | 24 | [^1]: Starting from version 3.10, `iperf` supports environments that do not 25 | implement congestion control algorithm. Thus, iperf 3.10+ prebuilt packages 26 | should work under Gramine without problems. See [release 27 | notes](https://github.com/esnet/iperf/blob/3.16/RELNOTES.md#iperf-310-2021-05-26) 28 | for details. 29 | 30 | 31 | ## Building for Linux 32 | 33 | Run `make` in the current directory. 34 | 35 | ## Building for SGX 36 | 37 | Run `make SGX=1` (non-debug) or `make SGX=1 DEBUG=1` (debug) in the current 38 | directory. 39 | 40 | # Execution instructions 41 | 42 | Run `iperf` server natively: 43 | ``` 44 | LD_LIBRARY_PATH=./install ./install/iperf3 -s 45 | ``` 46 | 47 | Run `iperf` server in Gramine without SGX: 48 | ``` 49 | gramine-direct iperf3 50 | ``` 51 | 52 | Run `iperf` server in Gramine with SGX: 53 | ``` 54 | gramine-sgx iperf3 55 | ``` 56 | 57 | To get measurements with the `iperf` client, run in another terminal: 58 | ``` 59 | LD_LIBRARY_PATH=./install ./install/iperf3 -c localhost -p 5201 60 | ``` 61 | 62 | # Useful iperf options 63 | 64 | (The options may be version-dependent. Below are the options for v3.16.) 65 | 66 | ## Generic options (both for server and client): 67 | - `-p, --port`: server port to listen on/connect to 68 | - `--forceflush`: force flushing output at every interval 69 | - `-d, --debug[=#]`: emit debugging output (optional "=" and debug level: 1-4) 70 | 71 | ## Server-specific options: 72 | - `-s, --server`: run in server mode 73 | - `-1, --one-off`: handle one client connection then exit 74 | - `--idle-timeout #`: restart idle server after # seconds in case it got stuck 75 | 76 | ## Client-specific options: 77 | - `-c, --client `: run in client mode, connecting to `` 78 | - `-t, --time #`: time in seconds to transmit for (default 10 secs) 79 | - `-n, --bytes #[KMG]`: number of bytes to transmit (instead of -t) 80 | - `-P, --parallel #`: number of parallel client streams to run 81 | - `-N, --no-delay`: set TCP/SCTP no delay, disabling Nagle's Algorithm 82 | 83 | # Notes 84 | - Tested on Ubuntu 22.04. 85 | - In the execution instructions, we use port `5201` for the client. 86 | This is the default port used by `iperf`. 87 | -------------------------------------------------------------------------------- /iperf/iperf3.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # iperf3 manifest file example 5 | 6 | libos.entrypoint = "/install/iperf3" 7 | 8 | loader.log_level = "{{ log_level }}" 9 | 10 | # Hardcode the argument to run the iperf3 server inside Gramine 11 | loader.argv = ["/install/iperf3", "-s"] 12 | 13 | loader.env.LD_LIBRARY_PATH = "/install:/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" 14 | 15 | sys.enable_sigterm_injection = true 16 | 17 | fs.mounts = [ 18 | { path = "/lib", uri = "file:{{ gramine.runtimedir() }}" }, 19 | { path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" }, 20 | { path = "/usr/{{ arch_libdir }}", uri = "file:/usr/{{ arch_libdir }}" }, 21 | { type = "tmpfs", path = "/tmp"}, 22 | 23 | # Mount iperf3 executable and libiperf (located in the install directory) 24 | # in Gramine under the /install directory. 25 | { path = "/install/iperf3", uri = "file:install/iperf3" }, 26 | { path = "/install/libiperf.so.0", uri = "file:install/libiperf.so.0" }, 27 | ] 28 | 29 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 30 | # iperf3 is single threaded; we choose 4 to accommodate Gramine additional 31 | # threads for IPC and asynchronous events/alarms. 32 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '4' }} 33 | sgx.enclave_size = "1024M" 34 | 35 | # `use_exinfo = true` is needed because the application may trigger lazy allocation of pages 36 | # (through exception handling) when EDMM is enabled 37 | sgx.use_exinfo = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 38 | 39 | sgx.trusted_files = [ 40 | "file:install/iperf3", 41 | "file:install/libiperf.so.0", 42 | "file:{{ gramine.runtimedir() }}/", 43 | "file:{{ arch_libdir }}/", 44 | "file:/usr/{{ arch_libdir }}/", 45 | ] 46 | -------------------------------------------------------------------------------- /mongodb/.gitignore: -------------------------------------------------------------------------------- 1 | /data/db/* 2 | !/data/db/.gitkeep 3 | -------------------------------------------------------------------------------- /mongodb/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 5 | 6 | ifeq ($(DEBUG),1) 7 | GRAMINE_LOG_LEVEL = debug 8 | else 9 | GRAMINE_LOG_LEVEL = error 10 | endif 11 | 12 | .PHONY: all 13 | all: mongod.manifest 14 | ifeq ($(SGX),1) 15 | all: mongod.manifest.sgx mongod.sig 16 | endif 17 | 18 | mongod.manifest: mongod.manifest.template 19 | gramine-manifest \ 20 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 21 | -Darch_libdir=$(ARCH_LIBDIR) \ 22 | -Dexecdir=$(shell dirname $(shell which mongod)) \ 23 | $< $@ 24 | 25 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 26 | # for details on this workaround see 27 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 28 | mongod.sig mongod.manifest.sgx: sgx_sign 29 | @: 30 | 31 | .INTERMEDIATE: sgx_sign 32 | sgx_sign: mongod.manifest 33 | gramine-sgx-sign \ 34 | --manifest $< \ 35 | --output $<.sgx 36 | 37 | .PHONY: clean 38 | clean: 39 | $(RM) -rf *.token *.sig *.manifest *.manifest.sgx data/db/* 40 | 41 | .PHONY: distclean 42 | distclean: clean 43 | -------------------------------------------------------------------------------- /mongodb/README.md: -------------------------------------------------------------------------------- 1 | # MongoDB example 2 | 3 | This directory contains an example for running MongoDB in Gramine, including the 4 | Makefile and a template for generating the manifest. 5 | 6 | # Generating the manifest 7 | 8 | ## Installing prerequisites 9 | 10 | Please run the following commands to install MongoDB 7.0 Community Edition on Ubuntu 22.04: 11 | 12 | 1. Import the public key used by the package management system: 13 | 14 | 1. From a terminal, install `gnupg` and `curl` if they are not already available: 15 | ``` 16 | sudo apt-get install gnupg curl 17 | ``` 18 | 19 | 2. Issue the following command to import the MongoDB public GPG Key from 20 | https://pgp.mongodb.com/server-7.0.asc: 21 | ``` 22 | curl -fsSL https://pgp.mongodb.com/server-7.0.asc | \ 23 | sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor 24 | ``` 25 | 26 | 2. Create a list file for MongoDB: 27 | ``` 28 | echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \ 29 | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list 30 | ``` 31 | 32 | 3. Reload local package database: 33 | ``` 34 | sudo apt-get update 35 | ``` 36 | 37 | 4. Install the MongoDB packages: 38 | ``` 39 | sudo apt-get install -y mongodb-org 40 | ``` 41 | 42 | ## Building for Linux 43 | 44 | Run `make` (non-debug) or `make DEBUG=1` (debug) in the directory. 45 | 46 | ## Building for SGX 47 | 48 | Run `make SGX=1` (non-debug) or `make SGX=1 DEBUG=1` (debug) in the directory. 49 | 50 | # Running MongoDB with Gramine 51 | 52 | Here's an example of running MongoDB under Gramine (note that command-line options are hardcoded in 53 | the manifest file): 54 | 55 | Without SGX: 56 | ``` 57 | gramine-direct mongod 58 | ``` 59 | 60 | With SGX: 61 | ``` 62 | gramine-sgx mongod 63 | ``` 64 | 65 | # Testing client connection 66 | 67 | Run the below commands from a new terminal: 68 | 69 | - `mongosh scripts/insert.js` - inserts new documents into a collection 70 | - `mongosh scripts/fetch.js` - fetches all documents, and prints their content 71 | -------------------------------------------------------------------------------- /mongodb/data/db/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gramineproject/examples/35a6928d8da8fd04ba9e00cc4c3c9dc7013fcda5/mongodb/data/db/.gitkeep -------------------------------------------------------------------------------- /mongodb/mongod.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | libos.entrypoint = "{{ execdir }}/mongod" 5 | 6 | loader.log_level = "{{ log_level }}" 7 | 8 | loader.argv = ["mongod", "--nounixsocket"] 9 | 10 | loader.env.LD_LIBRARY_PATH = "/lib:/usr/{{ arch_libdir }}" 11 | loader.env.PATH = "{{ execdir }}" 12 | 13 | fs.mounts = [ 14 | { path = "/lib", uri = "file:{{ gramine.runtimedir() }}" }, 15 | { path = "{{ execdir }}/mongod", uri = "file:{{ execdir }}/mongod" }, 16 | { path = "/usr/{{ arch_libdir }}", uri = "file:/usr/{{ arch_libdir }}" }, 17 | { path = "/data/db", uri = "file:data/db" }, 18 | ] 19 | 20 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 21 | sgx.enclave_size = "8G" 22 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '64' }} 23 | 24 | sgx.trusted_files = [ 25 | "file:{{ execdir }}/mongod", 26 | "file:{{ gramine.runtimedir() }}/", 27 | "file:/usr/{{ arch_libdir }}/", 28 | ] 29 | 30 | sgx.allowed_files = [ 31 | "file:data/db/", # MongoDB data will be stored in plaintext; this is insecure! 32 | ] 33 | 34 | # BSD (flock) locks are currently experimental 35 | sys.experimental__enable_flock = true 36 | -------------------------------------------------------------------------------- /mongodb/scripts/fetch.js: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Gramine contributors 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | const db = connect("mongodb://localhost:27017/mydatabase"); 5 | 6 | const products = db.products; 7 | 8 | const cursor = products.find(); 9 | while (cursor.hasNext()) { 10 | const doc = cursor.next(); 11 | printjson(doc); 12 | } 13 | -------------------------------------------------------------------------------- /mongodb/scripts/insert.js: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Gramine contributors 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | const db = connect("mongodb://localhost:27017/mydatabase"); 5 | 6 | const products = db.products; 7 | 8 | products.drop() 9 | 10 | products.insertMany([ 11 | { item: "card", quantity: 25 }, 12 | { item: "pen", quantity: 30 }, 13 | { item: "lamp", quantity: 20 }, 14 | ]); 15 | -------------------------------------------------------------------------------- /nodejs/.gitignore: -------------------------------------------------------------------------------- 1 | /OUTPUT 2 | -------------------------------------------------------------------------------- /nodejs/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 5 | NODEJS_DIR ?= /usr/bin 6 | 7 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 8 | 9 | ifeq ($(DEBUG),1) 10 | GRAMINE_LOG_LEVEL = debug 11 | else 12 | GRAMINE_LOG_LEVEL = error 13 | endif 14 | 15 | .PHONY: all 16 | all: nodejs.manifest 17 | ifeq ($(SGX),1) 18 | all: nodejs.manifest.sgx nodejs.sig 19 | endif 20 | 21 | nodejs.manifest: nodejs.manifest.template helloworld.js 22 | gramine-manifest \ 23 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 24 | -Darch_libdir=$(ARCH_LIBDIR) \ 25 | -Dnodejs_dir=$(NODEJS_DIR) \ 26 | -Dnodejs_usr_share_dir=$(wildcard /usr/share/nodejs) \ 27 | $< >$@ 28 | 29 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 30 | # for details on this workaround see 31 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 32 | nodejs.manifest.sgx nodejs.sig: sgx_sign 33 | @: 34 | 35 | .INTERMEDIATE: sgx_sign 36 | sgx_sign: nodejs.manifest 37 | gramine-sgx-sign \ 38 | --manifest $< \ 39 | --output $<.sgx 40 | 41 | ifeq ($(SGX),) 42 | GRAMINE = gramine-direct 43 | else 44 | GRAMINE = gramine-sgx 45 | endif 46 | 47 | .PHONY: check 48 | check: all 49 | $(GRAMINE) ./nodejs helloworld.js > OUTPUT 50 | @grep -q "Hello World" OUTPUT && echo "[ Success 1/1 ]" 51 | @rm OUTPUT 52 | 53 | .PHONY: clean 54 | clean: 55 | $(RM) *.manifest *.manifest.sgx *.token *.sig OUTPUT 56 | 57 | .PHONY: distclean 58 | distclean: clean 59 | -------------------------------------------------------------------------------- /nodejs/README.md: -------------------------------------------------------------------------------- 1 | # Node.js 2 | 3 | This directory contains a Makefile and template manifest to run Node.js on 4 | Gramine. This example uses Node.js installed on the system instead of compiling 5 | from source as some of the other examples do. 6 | 7 | # Quick Start 8 | 9 | To run the regression test execute ```make check```. To do the same for SGX, 10 | execute ```make SGX=1 check```. 11 | -------------------------------------------------------------------------------- /nodejs/helloworld.js: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2024 Gramine contributors 2 | // SPDX-License-Identifier: BSD-3-Clause 3 | 4 | console.log("Hello World"); 5 | -------------------------------------------------------------------------------- /nodejs/nodejs.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # Node.js manifest file example 5 | 6 | libos.entrypoint = "{{ nodejs_dir }}/nodejs" 7 | 8 | loader.log_level = "{{ log_level }}" 9 | 10 | loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" 11 | 12 | loader.insecure__use_cmdline_argv = true 13 | loader.insecure__use_host_env = true 14 | 15 | fs.mounts = [ 16 | { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, 17 | { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, 18 | { uri = "file:/usr/{{ arch_libdir }}", path = "/usr/{{ arch_libdir }}" }, 19 | { uri = "file:{{ nodejs_dir }}/nodejs", path = "{{ nodejs_dir }}/nodejs" }, 20 | {%- if nodejs_usr_share_dir %} 21 | { uri = "file:{{ nodejs_usr_share_dir }}", path = "{{ nodejs_usr_share_dir }}" }, 22 | {%- endif %} 23 | ] 24 | 25 | # Node.js expects around 1.7GB of heap on startup, see https://github.com/nodejs/node/issues/13018 26 | sgx.enclave_size = "2G" 27 | 28 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '32' }} 29 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 30 | 31 | # `use_exinfo = true` is needed because Node.js uses memory mappings with `MAP_NORESERVE`, which 32 | # will defer page accepts to page-fault events when EDMM is enabled 33 | sgx.use_exinfo = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 34 | 35 | sgx.trusted_files = [ 36 | "file:{{ nodejs_dir }}/nodejs", 37 | {%- if nodejs_usr_share_dir %} 38 | "file:{{ nodejs_usr_share_dir }}/", 39 | {%- endif %} 40 | "file:{{ gramine.runtimedir() }}/", 41 | "file:{{ arch_libdir }}/", 42 | "file:/usr/{{ arch_libdir }}/", 43 | "file:helloworld.js", 44 | ] 45 | -------------------------------------------------------------------------------- /openjdk/.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | -------------------------------------------------------------------------------- /openjdk/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 5 | 6 | ifeq ($(DEBUG),1) 7 | GRAMINE_LOG_LEVEL = debug 8 | else 9 | GRAMINE_LOG_LEVEL = error 10 | endif 11 | 12 | SOURCE_FILES = \ 13 | MultiThreadMain.java 14 | 15 | CLASS_FILES = $(SOURCE_FILES:.java=.class) 16 | 17 | %.class: %.java 18 | javac -d . $< 19 | 20 | .PHONY: all 21 | all: $(CLASS_FILES) java.manifest 22 | ifeq ($(SGX),1) 23 | all: java.manifest.sgx java.sig 24 | endif 25 | 26 | java.manifest: java.manifest.template 27 | gramine-manifest \ 28 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 29 | -Darch_libdir=$(ARCH_LIBDIR) \ 30 | -Dentrypoint=$(realpath $(shell sh -c "command -v java")) \ 31 | $< >$@ 32 | 33 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 34 | # for details on this workaround see 35 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 36 | java.manifest.sgx java.sig: sgx_sign 37 | @: 38 | 39 | .INTERMEDIATE: sgx_sign 40 | sgx_sign: java.manifest 41 | gramine-sgx-sign \ 42 | --manifest $< \ 43 | --output $<.sgx 44 | 45 | .PHONY: clean 46 | clean: 47 | $(RM) *.token *.sig *.manifest.sgx *.manifest *.class 48 | 49 | .PHONY: distclean 50 | distclean: clean 51 | -------------------------------------------------------------------------------- /openjdk/MultiThreadMain.java: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: LGPL-3.0-or-later 2 | 3 | import java.util.concurrent.ExecutorService; 4 | import java.util.concurrent.Executors; 5 | import java.util.concurrent.TimeUnit; 6 | 7 | class SyncedCounter { 8 | private int counter = 0; 9 | 10 | public int getCounter() { 11 | return counter; 12 | } 13 | 14 | public synchronized void increment() { 15 | counter = counter + 1; 16 | } 17 | 18 | } 19 | 20 | public class MultiThreadMain { 21 | public static void main(String[] args) throws InterruptedException { 22 | ExecutorService executorService = Executors.newFixedThreadPool(8); 23 | 24 | SyncedCounter syncedCounter = new SyncedCounter(); 25 | 26 | for(int i = 0; i < 10000; i++) { 27 | executorService.submit(() -> syncedCounter.increment()); 28 | } 29 | 30 | executorService.shutdown(); 31 | executorService.awaitTermination(30, TimeUnit.SECONDS); 32 | 33 | System.out.println("Final Count is: " + syncedCounter.getCounter()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /openjdk/README.md: -------------------------------------------------------------------------------- 1 | # Java example 2 | 3 | This directory contains an example for running a OpenJDK example in Gramine, 4 | including the Makefile and a template for generating the manifest. 5 | 6 | ## Installing prerequisites 7 | 8 | For generating the manifest and running the OpenJDK example, run the 9 | following command to install the required packages (Ubuntu-specific): 10 | 11 | sudo apt-get install openjdk-11-jdk 12 | 13 | ## Building for gramine-direct 14 | 15 | Run `make` (non-debug) or `make DEBUG=1` (debug) in the directory. 16 | 17 | ## Building for gramine-sgx 18 | 19 | Run `make SGX=1` (non-debug) or `make SGX=1 DEBUG=1` (debug) in the directory. 20 | 21 | ## Run OpenJDK example with Gramine 22 | 23 | Without SGX: 24 | 25 | gramine-direct java MultiThreadMain 26 | 27 | With SGX: 28 | 29 | gramine-sgx java -Xmx8G MultiThreadMain 30 | 31 | Note: If using 64G or greater enclave sizes, the JVM flag `-Xmx8G` can be omitted in gramine-sgx. 32 | -------------------------------------------------------------------------------- /openjdk/java.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | libos.entrypoint = "{{ entrypoint }}" 5 | 6 | loader.log_level = "{{ log_level }}" 7 | 8 | loader.insecure__use_cmdline_argv = true 9 | 10 | loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" 11 | 12 | fs.mounts = [ 13 | { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, 14 | { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, 15 | { uri = "file:/usr", path = "/usr" }, 16 | ] 17 | 18 | # If using 64G or greater enclave sizes, the JVM flag `-Xmx8G` can be omitted in gramine-sgx. 19 | sgx.enclave_size = "16G" 20 | 21 | # SGX needs minimum 64 threads for loading OpenJDK runtime. 22 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '64' }} 23 | 24 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 25 | 26 | # `use_exinfo = true` is needed because OpenJDK queries fault info on page faults 27 | sgx.use_exinfo = true 28 | 29 | sgx.trusted_files = [ 30 | "file:{{ entrypoint }}", 31 | "file:{{ gramine.runtimedir() }}/", 32 | "file:{{ arch_libdir }}/", 33 | "file:/usr/{{ arch_libdir }}/", 34 | "file:/usr/lib/jvm/java-11-openjdk-amd64/lib/", 35 | "file:/usr/lib/jvm/java-11-openjdk-amd64/conf/security/java.security", 36 | "file:MultiThreadMain.class", 37 | "file:SyncedCounter.class", 38 | ] 39 | -------------------------------------------------------------------------------- /openvino/.gitignore: -------------------------------------------------------------------------------- 1 | /benchmark_app 2 | /inference_engine_cpp_samples_build/ 3 | /model/ 4 | /openvino/ 5 | /output.txt 6 | -------------------------------------------------------------------------------- /openvino/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | SHELL := /bin/bash # use bash syntax to activate virtual environment and to download models 5 | 6 | OPENVINO_DIR ?= $(INTEL_OPENVINO_DIR) 7 | 8 | THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 9 | 10 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 11 | 12 | INFERENCE_ENGINE_CPP_SAMPLES_BUILD ?= $(THIS_DIR)inference_engine_cpp_samples_build 13 | 14 | MODEL_DIR ?= $(THIS_DIR)/model 15 | 16 | INTEL_MODELS = \ 17 | bert-large-uncased-whole-word-masking-squad-0001 \ 18 | bert-large-uncased-whole-word-masking-squad-int8-0001 19 | 20 | PUBLIC_MODELS = \ 21 | resnet-50-tf \ 22 | brain-tumor-segmentation-0001 \ 23 | brain-tumor-segmentation-0002 \ 24 | ssd_mobilenet_v1_coco 25 | 26 | VENV_DIR ?= $(THIS_DIR)/openvino 27 | 28 | ifeq ($(DEBUG),1) 29 | GRAMINE_LOG_LEVEL = debug 30 | else 31 | GRAMINE_LOG_LEVEL = error 32 | endif 33 | 34 | .PHONY: all 35 | all: benchmark_app benchmark_app.manifest $(VENV_DIR)/.INSTALLATION_OK intel_models public_models 36 | ifeq ($(SGX),1) 37 | all: benchmark_app.manifest.sgx benchmark_app.sig 38 | endif 39 | 40 | .PHONY: intel_models 41 | intel_models: $(VENV_DIR)/.INSTALLATION_OK 42 | @source $(VENV_DIR)/bin/activate \ 43 | && cd $(OPENVINO_DIR)/deployment_tools/open_model_zoo/tools/downloader \ 44 | && for model in $(INTEL_MODELS); do \ 45 | if [ ! -d $(abspath $(MODEL_DIR))/intel/$$model ]; then \ 46 | python3 ./downloader.py --name $$model -o $(abspath $(MODEL_DIR)); \ 47 | python3 ./converter.py --name $$model -d $(abspath $(MODEL_DIR)) -o $(abspath $(MODEL_DIR)); \ 48 | fi; \ 49 | done \ 50 | && deactivate 51 | 52 | .PHONY: public_models 53 | public_models: $(VENV_DIR)/.INSTALLATION_OK 54 | @source $(VENV_DIR)/bin/activate \ 55 | && cd $(OPENVINO_DIR)/deployment_tools/open_model_zoo/tools/downloader \ 56 | && for model in $(PUBLIC_MODELS); do \ 57 | if [ ! -d $(abspath $(MODEL_DIR))/public/$$model ]; then \ 58 | python3 ./downloader.py --name $$model -o $(abspath $(MODEL_DIR)); \ 59 | python3 ./converter.py --name $$model -d $(abspath $(MODEL_DIR)) -o $(abspath $(MODEL_DIR)); \ 60 | fi; \ 61 | done \ 62 | && deactivate 63 | 64 | .PRECIOUS: $(VENV_DIR)/.INSTALLATION_OK 65 | $(VENV_DIR)/.INSTALLATION_OK: 66 | mkdir -p model 67 | python3 -m venv $(VENV_DIR) \ 68 | && source $(VENV_DIR)/bin/activate \ 69 | && pip install --upgrade pip \ 70 | && pushd $(OPENVINO_DIR)/deployment_tools/open_model_zoo/tools/downloader \ 71 | && python3 -mpip install -r ./requirements.in \ 72 | && popd \ 73 | && pushd $(OPENVINO_DIR)/deployment_tools/model_optimizer \ 74 | && pip3 install -r requirements.txt \ 75 | && popd \ 76 | && deactivate \ 77 | && touch $@ 78 | 79 | benchmark_app.manifest: benchmark_app.manifest.template | benchmark_app 80 | gramine-manifest \ 81 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 82 | -Darch_libdir=$(ARCH_LIBDIR) \ 83 | -Dopenvino_dir=$(abspath $(OPENVINO_DIR)) \ 84 | -Dinference_engine_cpp_samples_build=$(abspath $(INFERENCE_ENGINE_CPP_SAMPLES_BUILD)) \ 85 | $< > $@ 86 | 87 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 88 | # for details on this workaround see 89 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 90 | benchmark_app.manifest.sgx benchmark_app.sig: sgx_sign 91 | @: 92 | 93 | .INTERMEDIATE: sgx_sign 94 | sgx_sign: benchmark_app.manifest 95 | gramine-sgx-sign \ 96 | --manifest $< \ 97 | --output $<.sgx 98 | 99 | benchmark_app: $(OPENVINO_DIR) 100 | mkdir -p $(INFERENCE_ENGINE_CPP_SAMPLES_BUILD) 101 | cd $(INFERENCE_ENGINE_CPP_SAMPLES_BUILD) \ 102 | && cmake -DCMAKE_BUILD_TYPE=Release $(OPENVINO_DIR)/inference_engine/samples/cpp \ 103 | && make 104 | ln -s $(INFERENCE_ENGINE_CPP_SAMPLES_BUILD)/intel64/Release/benchmark_app $@ 105 | 106 | .PHONY: clean 107 | clean: 108 | $(RM) *.manifest *.manifest.sgx *.token *.sig benchmark_app 109 | 110 | .PHONY: distclean 111 | distclean: clean 112 | $(RM) -r $(MODEL_DIR) $(VENV_DIR) $(INFERENCE_ENGINE_CPP_SAMPLES_BUILD) 113 | -------------------------------------------------------------------------------- /openvino/README.md: -------------------------------------------------------------------------------- 1 | # OpenVINO benchmark 2 | 3 | This directory contains a Makefile and a template manifest for the most recent version of OpenVINO 4 | toolkit (as of this writing, version 2021.4). We use the `Benchmark C++ Tool` (benchmark_app) from 5 | the OpenVINO distribution as a concrete application running under Gramine-SGX to estimate deep 6 | learning inference performance. We test only the CPU backend (i.e., no GPU or FPGA). 7 | 8 | ## Software requirements 9 | 10 | - OpenVINO: Please download latest OpenVINO toolkit (as of this writing, version 2021.4) for Linux 11 | from https://software.intel.com/content/www/us/en/develop/tools/openvino-toolkit/download.html. 12 | For OpenVINO installation step-by-step instructions please refer to this 13 | [link](https://docs.openvino.ai/2021.4/openvino_docs_install_guides_installing_openvino_linux.html). 14 | - Python (version 3.6 or higher) 15 | - Python virtual environment: `sudo apt-get install python3-venv` 16 | - CMake (version 3.10 or higher) 17 | 18 | ## Supported models for Gramine-SGX 19 | 20 | The following models have been tested with Gramine-SGX: 21 | 22 | - bert-large-uncased-whole-word-masking-squad-0001 (FP16/FP32) 23 | - bert-large-uncased-whole-word-masking-squad-int8-0001 (INT8) 24 | - brain-tumor-segmentation-0001 (FP16/FP32) 25 | - brain-tumor-segmentation-0002 (FP16/FP32) 26 | - resnet-50-tf (FP16/FP32) 27 | - ssd_mobilenet_v1_coco (FP16/FP32) 28 | 29 | ## Preparing the source 30 | 31 | 1. Set up OpenVINO environment variables by running: 32 | - root user: `source /opt/intel/openvino_2021/bin/setupvars.sh` 33 | - root user and set permanently: append `source /opt/intel/openvino_2021/bin/setupvars.sh` to 34 | `~/.bashrc` 35 | - regular user: `source /home//intel/openvino_2021/bin/setupvars.sh` 36 | 2. Build: `make SGX=1` 37 | 38 | ## Running the benchmark in Gramine-SGX 39 | 40 | The below commands are utilizing only socket 0. 41 | 42 | ### Throughput runs 43 | 44 | Options `-nireq`, `-nstreams` and `-nthreads` should be set to the *number of logical cores on the 45 | socket 0* for achieving maximum performance. 46 | 47 | ```bash 48 | $ export THREADS_CNT= 49 | $ KMP_AFFINITY=granularity=fine,noverbose,compact,1,0 numactl --cpubind=0 --membind=0 \ 50 | gramine-sgx benchmark_app -i \ 51 | -m model//// \ 52 | -d CPU -b 1 -t 20 \ 53 | -nstreams THREADS_CNT -nthreads THREADS_CNT -nireq THREADS_CNT 54 | ``` 55 | 56 | For example, in a system with 36 physical cores per socket and 2 threads per core, please export 57 | `THREADS_CNT` as below. 58 | ```bash 59 | $ export THREADS_CNT=72 60 | ``` 61 | 62 | ### Latency runs 63 | 64 | ```bash 65 | $ KMP_AFFINITY=granularity=fine,noverbose,compact,1,0 numactl --cpubind=0 --membind=0 \ 66 | gramine-sgx benchmark_app -i \ 67 | -m model//// \ 68 | -d CPU -b 1 -t 20 -api sync 69 | ``` 70 | 71 | ## Running the benchmark in non-SGX Gramine and natively 72 | 73 | To run the benchmark in non-SGX Gramine, replace `gramine-sgx benchmark_app` with 74 | `gramine-direct benchmark_app` in the above commands. 75 | 76 | To run the benchmark natively (outside Gramine), replace `gramine-sgx benchmark_app` with 77 | `./benchmark_app` in the above commands. 78 | 79 | ## Notes 80 | 81 | - The models require ~3GB of disk space. 82 | - After setting up OpenVINO environment variables if you want to re-build Gramine you need to unset 83 | `LD_LIBRARY_PATH`. Please make sure to set up OpenVINO environment variables after building 84 | Gramine again. 85 | - Option `-i ` is optional. The user may use this option to benchmark specific images 86 | rather than randomly generated ones. 87 | - Please tune the batch size to get the best performance on your system. 88 | - Models for bert-large can be found in `model/intel` directory; the rest of the models can be found 89 | in `model/public` directory. 90 | - For bert-large and brain-tumor-segmentation models the enclave size must be set to 64/128 GB for 91 | throughput runs. 92 | - In multi-socket systems for bert-large-uncased-whole-word-masking-squad-0001 and 93 | brain-tumor-segmentation-0001 FP32/FP16 models, add more NUMA nodes using `numactl --membind` if 94 | memory allocation fails (for throughput runs). 95 | 96 | ## Performance considerations 97 | 98 | ### CPU frequency scaling 99 | 100 | Linux systems have CPU frequency scaling governor that helps the system to scale the CPU frequency 101 | to achieve best performance or to save power based on the requirement. To achieve the best 102 | performance, please set the CPU frequency scaling governor to `performance` mode. 103 | 104 | ```bash 105 | for ((i=0; i<$(nproc); i++)); do 106 | echo 'performance' > /sys/devices/system/cpu/cpu$i/cpufreq/scaling_governor; 107 | done 108 | ``` 109 | 110 | ### Manifest options for performance 111 | 112 | - Preheat manifest option pre-faults the enclave memory and moves the performance penalty to 113 | Gramine-SGX startup (before the workload starts executing). To use the preheat option, make sure 114 | that `sgx.preheat_enclave = true` is added to the manifest template. 115 | - Skipping invalid user pointer checks when the application does not invoke system calls with 116 | invalid pointers (typical case) can help improve performance. To use this option, make sure that 117 | `libos.check_invalid_pointers = false` is added to the manifest template. 118 | 119 | ### Memory allocator libraries 120 | 121 | TCMalloc and mimalloc are memory allocator libraries from Google and Microsoft that can help improve 122 | performance significantly based on the workloads. Only one of these allocators can be used at the 123 | same time. 124 | 125 | #### TCMalloc 126 | 127 | (Please update the binary location and name if different from default.) 128 | 129 | - Install tcmalloc: `sudo apt-get install google-perftools` 130 | - Modify the manifest template file: 131 | - Add `loader.env.LD_PRELOAD = "/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4"` 132 | - Append below entries to `sgx.trusted_files`: 133 | - `"file:/usr/lib/x86_64-linux-gnu/libtcmalloc.so.4"` 134 | - `"file:/usr/lib/x86_64-linux-gnu/libunwind.so.8"` 135 | - Save the manifest template and rebuild this example. 136 | 137 | #### mimalloc 138 | 139 | (Please update the binary location and name if different from default.) 140 | 141 | - Install mimalloc using the steps from https://github.com/microsoft/mimalloc 142 | - Modify the manifest template file: 143 | - Add the `/usr/local` FS mount point: 144 | - `{ uri = "file:/usr/local", path = "/usr/local" }` 145 | - Add `loader.env.LD_PRELOAD = "/usr/local/lib/mimalloc-1.7/libmimalloc.so.1.7"` 146 | - Append below entry to `sgx.trusted_files`: 147 | - `"file:/usr/local/lib/mimalloc-1.7/libmimalloc.so.1.7"` 148 | - Save the manifest template and rebuild this example. 149 | -------------------------------------------------------------------------------- /openvino/benchmark_app.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | libos.entrypoint = "benchmark_app" 5 | 6 | loader.log_level = "{{ log_level }}" 7 | 8 | loader.env.LD_LIBRARY_PATH = "/lib:{{ openvino_dir }}/deployment_tools/inference_engine/external/tbb/lib:{{ openvino_dir }}/deployment_tools/inference_engine/lib/intel64:{{ openvino_dir }}/opencv/lib:{{ openvino_dir }}/deployment_tools/ngraph/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" 9 | 10 | fs.mounts = [ 11 | { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, 12 | { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, 13 | { uri = "file:/usr/{{ arch_libdir }}", path = "/usr/{{ arch_libdir }}" }, 14 | { uri = "file:/etc", path = "/etc" }, 15 | { uri = "file:{{ openvino_dir }}", path = "{{ openvino_dir }}" }, 16 | { uri = "file:{{ inference_engine_cpp_samples_build }}", path = "{{ inference_engine_cpp_samples_build }}" }, 17 | ] 18 | 19 | loader.insecure__use_cmdline_argv = true 20 | 21 | sgx.enclave_size = "32G" 22 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '196' }} 23 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 24 | 25 | sgx.preheat_enclave = {{ 'false' if env.get('EDMM', '0') == '1' else 'true' }} 26 | libos.check_invalid_pointers = false 27 | 28 | sgx.trusted_files = [ 29 | "file:benchmark_app", 30 | "file:{{ gramine.runtimedir() }}/", 31 | "file:{{ arch_libdir }}/", 32 | "file:/usr/{{ arch_libdir }}/", 33 | "file:{{ openvino_dir }}/deployment_tools/inference_engine/lib/intel64/", 34 | "file:{{ openvino_dir }}/deployment_tools/inference_engine/external/tbb/lib/", 35 | "file:{{ openvino_dir }}/opencv/lib/", 36 | "file:{{ openvino_dir }}/deployment_tools/ngraph/lib/", 37 | "file:{{ inference_engine_cpp_samples_build }}/intel64/Release/lib/", 38 | "file:model/", 39 | ] 40 | 41 | sgx.allowed_files = [ 42 | "file:/etc/ethers", 43 | "file:/etc/group", 44 | "file:/etc/hosts", 45 | "file:/etc/nsswitch.conf", 46 | "file:/etc/passwd", 47 | "file:output.txt", 48 | ] 49 | -------------------------------------------------------------------------------- /pytorch/.gitignore: -------------------------------------------------------------------------------- 1 | /*.pt 2 | /result.txt 3 | -------------------------------------------------------------------------------- /pytorch/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # PyTorch and the pre-trained model must be installed on the system. See README for details. 5 | 6 | SHELL := /bin/bash 7 | 8 | THIS_DIR := $(dir $(lastword $(MAKEFILE_LIST))) 9 | VENV_DIR ?= $(THIS_DIR)/my_venv 10 | ENTRYPOINT := $(VENV_DIR)/bin/python3 11 | 12 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 13 | 14 | ifeq ($(DEBUG),1) 15 | GRAMINE_LOG_LEVEL = debug 16 | else 17 | GRAMINE_LOG_LEVEL = error 18 | endif 19 | 20 | .PHONY: all 21 | all: $(VENV_DIR)/.INSTALLATION_OK pytorch.manifest 22 | ifeq ($(SGX),1) 23 | all: pytorch.manifest.sgx pytorch.sig 24 | endif 25 | 26 | .PRECIOUS: $(VENV_DIR)/.INSTALLATION_OK 27 | $(VENV_DIR)/.INSTALLATION_OK: 28 | python3 -m venv $(VENV_DIR) \ 29 | && source $(VENV_DIR)/bin/activate \ 30 | && pip3 install torchvision pillow \ 31 | && python3 download-pretrained-model.py \ 32 | && deactivate \ 33 | && touch $@ 34 | 35 | pytorch.manifest: pytorch.manifest.template $(VENV_DIR)/.INSTALLATION_OK 36 | gramine-manifest \ 37 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 38 | -Darch_libdir=$(ARCH_LIBDIR) \ 39 | -Dentrypoint=$(abspath $(ENTRYPOINT)) \ 40 | -Dvenv_dir=$(abspath $(VENV_DIR)) \ 41 | $< > $@ 42 | 43 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 44 | # for details on this workaround see 45 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 46 | pytorch.manifest.sgx pytorch.sig: sgx_sign 47 | @: 48 | 49 | .INTERMEDIATE: sgx_sign 50 | sgx_sign: pytorch.manifest 51 | gramine-sgx-sign \ 52 | --manifest $< \ 53 | --output $<.sgx 54 | 55 | .PHONY: clean 56 | clean: 57 | $(RM) *.token *.sig *.manifest.sgx *.manifest 58 | 59 | .PHONY: distclean 60 | distclean: clean 61 | $(RM) -r *.pt result.txt $(VENV_DIR) 62 | -------------------------------------------------------------------------------- /pytorch/README.md: -------------------------------------------------------------------------------- 1 | # PyTorch 2 | 3 | This directory contains steps and artifacts to run a PyTorch sample workload on 4 | Gramine. Specifically, this example uses a pre-trained model for image 5 | classification. 6 | 7 | The workload reads an image from a file on disk `input.jpg` and runs the 8 | classifier to detect what object is present in the image. For the image shipping 9 | with the workload, the output should be 10 | 11 | ``` 12 | [('Labrador retriever', 41.58518600463867), ('golden retriever', 16.59165382385254), ('Saluki, gazelle hound', 16.286855697631836), ('whippet', 2.853914976119995), ('Ibizan hound, Ibizan Podenco', 2.3924756050109863)] 13 | ``` 14 | 15 | With high probability (41%) the classifier detected the image to contain a 16 | Labrador retriever. 17 | 18 | # Pre-requisites 19 | The following steps should suffice to run the workload on a standard Ubuntu distribution. 20 | 21 | - `sudo apt install libnss-mdns libnss-myhostname` to install additional 22 | DNS-resolver libraries. 23 | - `sudo apt install python3-pip lsb-release` to install `pip` and `lsb_release`. 24 | The former is required to install additional Python packages while the latter 25 | is used by the Makefile. 26 | 27 | # Build 28 | 29 | Run `make` to build the non-SGX version and `make SGX=1` to build the SGX 30 | version. 31 | 32 | # Run 33 | 34 | Execute any one of the following commands to run the workload: 35 | 36 | - natively: `python3 pytorchexample.py` 37 | - Gramine w/o SGX: `gramine-direct ./pytorch ./pytorchexample.py` 38 | - Gramine with SGX: `gramine-sgx ./pytorch ./pytorchexample.py` 39 | -------------------------------------------------------------------------------- /pytorch/classes.txt: -------------------------------------------------------------------------------- 1 | tench, Tinca tinca 2 | goldfish, Carassius auratus 3 | great white shark, white shark, man-eater, man-eating shark, Carcharodon carcharias 4 | tiger shark, Galeocerdo cuvieri 5 | hammerhead, hammerhead shark 6 | electric ray, crampfish, numbfish, torpedo 7 | stingray 8 | cock 9 | hen 10 | ostrich, Struthio camelus 11 | brambling, Fringilla montifringilla 12 | goldfinch, Carduelis carduelis 13 | house finch, linnet, Carpodacus mexicanus 14 | junco, snowbird 15 | indigo bunting, indigo finch, indigo bird, Passerina cyanea 16 | robin, American robin, Turdus migratorius 17 | bulbul 18 | jay 19 | magpie 20 | chickadee 21 | water ouzel, dipper 22 | kite 23 | bald eagle, American eagle, Haliaeetus leucocephalus 24 | vulture 25 | great grey owl, great gray owl, Strix nebulosa 26 | European fire salamander, Salamandra salamandra 27 | common newt, Triturus vulgaris 28 | eft 29 | spotted salamander, Ambystoma maculatum 30 | axolotl, mud puppy, Ambystoma mexicanum 31 | bullfrog, Rana catesbeiana 32 | tree frog, tree-frog 33 | tailed frog, bell toad, ribbed toad, tailed toad, Ascaphus trui 34 | loggerhead, loggerhead turtle, Caretta caretta 35 | leatherback turtle, leatherback, leathery turtle, Dermochelys coriacea 36 | mud turtle 37 | terrapin 38 | box turtle, box tortoise 39 | banded gecko 40 | common iguana, iguana, Iguana iguana 41 | American chameleon, anole, Anolis carolinensis 42 | whiptail, whiptail lizard 43 | agama 44 | frilled lizard, Chlamydosaurus kingi 45 | alligator lizard 46 | Gila monster, Heloderma suspectum 47 | green lizard, Lacerta viridis 48 | African chameleon, Chamaeleo chamaeleon 49 | Komodo dragon, Komodo lizard, dragon lizard, giant lizard, Varanus komodoensis 50 | African crocodile, Nile crocodile, Crocodylus niloticus 51 | American alligator, Alligator mississipiensis 52 | triceratops 53 | thunder snake, worm snake, Carphophis amoenus 54 | ringneck snake, ring-necked snake, ring snake 55 | hognose snake, puff adder, sand viper 56 | green snake, grass snake 57 | king snake, kingsnake 58 | garter snake, grass snake 59 | water snake 60 | vine snake 61 | night snake, Hypsiglena torquata 62 | boa constrictor, Constrictor constrictor 63 | rock python, rock snake, Python sebae 64 | Indian cobra, Naja naja 65 | green mamba 66 | sea snake 67 | horned viper, cerastes, sand viper, horned asp, Cerastes cornutus 68 | diamondback, diamondback rattlesnake, Crotalus adamanteus 69 | sidewinder, horned rattlesnake, Crotalus cerastes 70 | trilobite 71 | harvestman, daddy longlegs, Phalangium opilio 72 | scorpion 73 | black and gold garden spider, Argiope aurantia 74 | barn spider, Araneus cavaticus 75 | garden spider, Aranea diademata 76 | black widow, Latrodectus mactans 77 | tarantula 78 | wolf spider, hunting spider 79 | tick 80 | centipede 81 | black grouse 82 | ptarmigan 83 | ruffed grouse, partridge, Bonasa umbellus 84 | prairie chicken, prairie grouse, prairie fowl 85 | peacock 86 | quail 87 | partridge 88 | African grey, African gray, Psittacus erithacus 89 | macaw 90 | sulphur-crested cockatoo, Kakatoe galerita, Cacatua galerita 91 | lorikeet 92 | coucal 93 | bee eater 94 | hornbill 95 | hummingbird 96 | jacamar 97 | toucan 98 | drake 99 | red-breasted merganser, Mergus serrator 100 | goose 101 | black swan, Cygnus atratus 102 | tusker 103 | echidna, spiny anteater, anteater 104 | platypus, duckbill, duckbilled platypus, duck-billed platypus, Ornithorhynchus anatinus 105 | wallaby, brush kangaroo 106 | koala, koala bear, kangaroo bear, native bear, Phascolarctos cinereus 107 | wombat 108 | jellyfish 109 | sea anemone, anemone 110 | brain coral 111 | flatworm, platyhelminth 112 | nematode, nematode worm, roundworm 113 | conch 114 | snail 115 | slug 116 | sea slug, nudibranch 117 | chiton, coat-of-mail shell, sea cradle, polyplacophore 118 | chambered nautilus, pearly nautilus, nautilus 119 | Dungeness crab, Cancer magister 120 | rock crab, Cancer irroratus 121 | fiddler crab 122 | king crab, Alaska crab, Alaskan king crab, Alaska king crab, Paralithodes camtschatica 123 | American lobster, Northern lobster, Maine lobster, Homarus americanus 124 | spiny lobster, langouste, rock lobster, crawfish, crayfish, sea crawfish 125 | crayfish, crawfish, crawdad, crawdaddy 126 | hermit crab 127 | isopod 128 | white stork, Ciconia ciconia 129 | black stork, Ciconia nigra 130 | spoonbill 131 | flamingo 132 | little blue heron, Egretta caerulea 133 | American egret, great white heron, Egretta albus 134 | bittern 135 | crane 136 | limpkin, Aramus pictus 137 | European gallinule, Porphyrio porphyrio 138 | American coot, marsh hen, mud hen, water hen, Fulica americana 139 | bustard 140 | ruddy turnstone, Arenaria interpres 141 | red-backed sandpiper, dunlin, Erolia alpina 142 | redshank, Tringa totanus 143 | dowitcher 144 | oystercatcher, oyster catcher 145 | pelican 146 | king penguin, Aptenodytes patagonica 147 | albatross, mollymawk 148 | grey whale, gray whale, devilfish, Eschrichtius gibbosus, Eschrichtius robustus 149 | killer whale, killer, orca, grampus, sea wolf, Orcinus orca 150 | dugong, Dugong dugon 151 | sea lion 152 | Chihuahua 153 | Japanese spaniel 154 | Maltese dog, Maltese terrier, Maltese 155 | Pekinese, Pekingese, Peke 156 | Shih-Tzu 157 | Blenheim spaniel 158 | papillon 159 | toy terrier 160 | Rhodesian ridgeback 161 | Afghan hound, Afghan 162 | basset, basset hound 163 | beagle 164 | bloodhound, sleuthhound 165 | bluetick 166 | black-and-tan coonhound 167 | Walker hound, Walker foxhound 168 | English foxhound 169 | redbone 170 | borzoi, Russian wolfhound 171 | Irish wolfhound 172 | Italian greyhound 173 | whippet 174 | Ibizan hound, Ibizan Podenco 175 | Norwegian elkhound, elkhound 176 | otterhound, otter hound 177 | Saluki, gazelle hound 178 | Scottish deerhound, deerhound 179 | Weimaraner 180 | Staffordshire bullterrier, Staffordshire bull terrier 181 | American Staffordshire terrier, Staffordshire terrier, American pit bull terrier, pit bull terrier 182 | Bedlington terrier 183 | Border terrier 184 | Kerry blue terrier 185 | Irish terrier 186 | Norfolk terrier 187 | Norwich terrier 188 | Yorkshire terrier 189 | wire-haired fox terrier 190 | Lakeland terrier 191 | Sealyham terrier, Sealyham 192 | Airedale, Airedale terrier 193 | cairn, cairn terrier 194 | Australian terrier 195 | Dandie Dinmont, Dandie Dinmont terrier 196 | Boston bull, Boston terrier 197 | miniature schnauzer 198 | giant schnauzer 199 | standard schnauzer 200 | Scotch terrier, Scottish terrier, Scottie 201 | Tibetan terrier, chrysanthemum dog 202 | silky terrier, Sydney silky 203 | soft-coated wheaten terrier 204 | West Highland white terrier 205 | Lhasa, Lhasa apso 206 | flat-coated retriever 207 | curly-coated retriever 208 | golden retriever 209 | Labrador retriever 210 | Chesapeake Bay retriever 211 | German short-haired pointer 212 | vizsla, Hungarian pointer 213 | English setter 214 | Irish setter, red setter 215 | Gordon setter 216 | Brittany spaniel 217 | clumber, clumber spaniel 218 | English springer, English springer spaniel 219 | Welsh springer spaniel 220 | cocker spaniel, English cocker spaniel, cocker 221 | Sussex spaniel 222 | Irish water spaniel 223 | kuvasz 224 | schipperke 225 | groenendael 226 | malinois 227 | briard 228 | kelpie 229 | komondor 230 | Old English sheepdog, bobtail 231 | Shetland sheepdog, Shetland sheep dog, Shetland 232 | collie 233 | Border collie 234 | Bouvier des Flandres, Bouviers des Flandres 235 | Rottweiler 236 | German shepherd, German shepherd dog, German police dog, alsatian 237 | Doberman, Doberman pinscher 238 | miniature pinscher 239 | Greater Swiss Mountain dog 240 | Bernese mountain dog 241 | Appenzeller 242 | EntleBucher 243 | boxer 244 | bull mastiff 245 | Tibetan mastiff 246 | French bulldog 247 | Great Dane 248 | Saint Bernard, St Bernard 249 | Eskimo dog, husky 250 | malamute, malemute, Alaskan malamute 251 | Siberian husky 252 | dalmatian, coach dog, carriage dog 253 | affenpinscher, monkey pinscher, monkey dog 254 | basenji 255 | pug, pug-dog 256 | Leonberg 257 | Newfoundland, Newfoundland dog 258 | Great Pyrenees 259 | Samoyed, Samoyede 260 | Pomeranian 261 | chow, chow chow 262 | keeshond 263 | Brabancon griffon 264 | Pembroke, Pembroke Welsh corgi 265 | Cardigan, Cardigan Welsh corgi 266 | toy poodle 267 | miniature poodle 268 | standard poodle 269 | Mexican hairless 270 | timber wolf, grey wolf, gray wolf, Canis lupus 271 | white wolf, Arctic wolf, Canis lupus tundrarum 272 | red wolf, maned wolf, Canis rufus, Canis niger 273 | coyote, prairie wolf, brush wolf, Canis latrans 274 | dingo, warrigal, warragal, Canis dingo 275 | dhole, Cuon alpinus 276 | African hunting dog, hyena dog, Cape hunting dog, Lycaon pictus 277 | hyena, hyaena 278 | red fox, Vulpes vulpes 279 | kit fox, Vulpes macrotis 280 | Arctic fox, white fox, Alopex lagopus 281 | grey fox, gray fox, Urocyon cinereoargenteus 282 | tabby, tabby cat 283 | tiger cat 284 | Persian cat 285 | Siamese cat, Siamese 286 | Egyptian cat 287 | cougar, puma, catamount, mountain lion, painter, panther, Felis concolor 288 | lynx, catamount 289 | leopard, Panthera pardus 290 | snow leopard, ounce, Panthera uncia 291 | jaguar, panther, Panthera onca, Felis onca 292 | lion, king of beasts, Panthera leo 293 | tiger, Panthera tigris 294 | cheetah, chetah, Acinonyx jubatus 295 | brown bear, bruin, Ursus arctos 296 | American black bear, black bear, Ursus americanus, Euarctos americanus 297 | ice bear, polar bear, Ursus Maritimus, Thalarctos maritimus 298 | sloth bear, Melursus ursinus, Ursus ursinus 299 | mongoose 300 | meerkat, mierkat 301 | tiger beetle 302 | ladybug, ladybeetle, lady beetle, ladybird, ladybird beetle 303 | ground beetle, carabid beetle 304 | long-horned beetle, longicorn, longicorn beetle 305 | leaf beetle, chrysomelid 306 | dung beetle 307 | rhinoceros beetle 308 | weevil 309 | fly 310 | bee 311 | ant, emmet, pismire 312 | grasshopper, hopper 313 | cricket 314 | walking stick, walkingstick, stick insect 315 | cockroach, roach 316 | mantis, mantid 317 | cicada, cicala 318 | leafhopper 319 | lacewing, lacewing fly 320 | dragonfly, darning needle, devil's darning needle, sewing needle, snake feeder, snake doctor, mosquito hawk, skeeter hawk 321 | damselfly 322 | admiral 323 | ringlet, ringlet butterfly 324 | monarch, monarch butterfly, milkweed butterfly, Danaus plexippus 325 | cabbage butterfly 326 | sulphur butterfly, sulfur butterfly 327 | lycaenid, lycaenid butterfly 328 | starfish, sea star 329 | sea urchin 330 | sea cucumber, holothurian 331 | wood rabbit, cottontail, cottontail rabbit 332 | hare 333 | Angora, Angora rabbit 334 | hamster 335 | porcupine, hedgehog 336 | fox squirrel, eastern fox squirrel, Sciurus niger 337 | marmot 338 | beaver 339 | guinea pig, Cavia cobaya 340 | sorrel 341 | zebra 342 | hog, pig, grunter, squealer, Sus scrofa 343 | wild boar, boar, Sus scrofa 344 | warthog 345 | hippopotamus, hippo, river horse, Hippopotamus amphibius 346 | ox 347 | water buffalo, water ox, Asiatic buffalo, Bubalus bubalis 348 | bison 349 | ram, tup 350 | bighorn, bighorn sheep, cimarron, Rocky Mountain bighorn, Rocky Mountain sheep, Ovis canadensis 351 | ibex, Capra ibex 352 | hartebeest 353 | impala, Aepyceros melampus 354 | gazelle 355 | Arabian camel, dromedary, Camelus dromedarius 356 | llama 357 | weasel 358 | mink 359 | polecat, fitch, foulmart, foumart, Mustela putorius 360 | black-footed ferret, ferret, Mustela nigripes 361 | otter 362 | skunk, polecat, wood pussy 363 | badger 364 | armadillo 365 | three-toed sloth, ai, Bradypus tridactylus 366 | orangutan, orang, orangutang, Pongo pygmaeus 367 | gorilla, Gorilla gorilla 368 | chimpanzee, chimp, Pan troglodytes 369 | gibbon, Hylobates lar 370 | siamang, Hylobates syndactylus, Symphalangus syndactylus 371 | guenon, guenon monkey 372 | patas, hussar monkey, Erythrocebus patas 373 | baboon 374 | macaque 375 | langur 376 | colobus, colobus monkey 377 | proboscis monkey, Nasalis larvatus 378 | marmoset 379 | capuchin, ringtail, Cebus capucinus 380 | howler monkey, howler 381 | titi, titi monkey 382 | spider monkey, Ateles geoffroyi 383 | squirrel monkey, Saimiri sciureus 384 | Madagascar cat, ring-tailed lemur, Lemur catta 385 | indri, indris, Indri indri, Indri brevicaudatus 386 | Indian elephant, Elephas maximus 387 | African elephant, Loxodonta africana 388 | lesser panda, red panda, panda, bear cat, cat bear, Ailurus fulgens 389 | giant panda, panda, panda bear, coon bear, Ailuropoda melanoleuca 390 | barracouta, snoek 391 | eel 392 | coho, cohoe, coho salmon, blue jack, silver salmon, Oncorhynchus kisutch 393 | rock beauty, Holocanthus tricolor 394 | anemone fish 395 | sturgeon 396 | gar, garfish, garpike, billfish, Lepisosteus osseus 397 | lionfish 398 | puffer, pufferfish, blowfish, globefish 399 | abacus 400 | abaya 401 | academic gown, academic robe, judge's robe 402 | accordion, piano accordion, squeeze box 403 | acoustic guitar 404 | aircraft carrier, carrier, flattop, attack aircraft carrier 405 | airliner 406 | airship, dirigible 407 | altar 408 | ambulance 409 | amphibian, amphibious vehicle 410 | analog clock 411 | apiary, bee house 412 | apron 413 | ashcan, trash can, garbage can, wastebin, ash bin, ash-bin, ashbin, dustbin, trash barrel, trash bin 414 | assault rifle, assault gun 415 | backpack, back pack, knapsack, packsack, rucksack, haversack 416 | bakery, bakeshop, bakehouse 417 | balance beam, beam 418 | balloon 419 | ballpoint, ballpoint pen, ballpen, Biro 420 | Band Aid 421 | banjo 422 | bannister, banister, balustrade, balusters, handrail 423 | barbell 424 | barber chair 425 | barbershop 426 | barn 427 | barometer 428 | barrel, cask 429 | barrow, garden cart, lawn cart, wheelbarrow 430 | baseball 431 | basketball 432 | bassinet 433 | bassoon 434 | bathing cap, swimming cap 435 | bath towel 436 | bathtub, bathing tub, bath, tub 437 | beach wagon, station wagon, wagon, estate car, beach waggon, station waggon, waggon 438 | beacon, lighthouse, beacon light, pharos 439 | beaker 440 | bearskin, busby, shako 441 | beer bottle 442 | beer glass 443 | bell cote, bell cot 444 | bib 445 | bicycle-built-for-two, tandem bicycle, tandem 446 | bikini, two-piece 447 | binder, ring-binder 448 | binoculars, field glasses, opera glasses 449 | birdhouse 450 | boathouse 451 | bobsled, bobsleigh, bob 452 | bolo tie, bolo, bola tie, bola 453 | bonnet, poke bonnet 454 | bookcase 455 | bookshop, bookstore, bookstall 456 | bottlecap 457 | bow 458 | bow tie, bow-tie, bowtie 459 | brass, memorial tablet, plaque 460 | brassiere, bra, bandeau 461 | breakwater, groin, groyne, mole, bulwark, seawall, jetty 462 | breastplate, aegis, egis 463 | broom 464 | bucket, pail 465 | buckle 466 | bulletproof vest 467 | bullet train, bullet 468 | butcher shop, meat market 469 | cab, hack, taxi, taxicab 470 | caldron, cauldron 471 | candle, taper, wax light 472 | cannon 473 | canoe 474 | can opener, tin opener 475 | cardigan 476 | car mirror 477 | carousel, carrousel, merry-go-round, roundabout, whirligig 478 | carpenter's kit, tool kit 479 | carton 480 | car wheel 481 | cash machine, cash dispenser, automated teller machine, automatic teller machine, automated teller, automatic teller, ATM 482 | cassette 483 | cassette player 484 | castle 485 | catamaran 486 | CD player 487 | cello, violoncello 488 | cellular telephone, cellular phone, cellphone, cell, mobile phone 489 | chain 490 | chainlink fence 491 | chain mail, ring mail, mail, chain armor, chain armour, ring armor, ring armour 492 | chain saw, chainsaw 493 | chest 494 | chiffonier, commode 495 | chime, bell, gong 496 | china cabinet, china closet 497 | Christmas stocking 498 | church, church building 499 | cinema, movie theater, movie theatre, movie house, picture palace 500 | cleaver, meat cleaver, chopper 501 | cliff dwelling 502 | cloak 503 | clog, geta, patten, sabot 504 | cocktail shaker 505 | coffee mug 506 | coffeepot 507 | coil, spiral, volute, whorl, helix 508 | combination lock 509 | computer keyboard, keypad 510 | confectionery, confectionary, candy store 511 | container ship, containership, container vessel 512 | convertible 513 | corkscrew, bottle screw 514 | cornet, horn, trumpet, trump 515 | cowboy boot 516 | cowboy hat, ten-gallon hat 517 | cradle 518 | crane 519 | crash helmet 520 | crate 521 | crib, cot 522 | Crock Pot 523 | croquet ball 524 | crutch 525 | cuirass 526 | dam, dike, dyke 527 | desk 528 | desktop computer 529 | dial telephone, dial phone 530 | diaper, nappy, napkin 531 | digital clock 532 | digital watch 533 | dining table, board 534 | dishrag, dishcloth 535 | dishwasher, dish washer, dishwashing machine 536 | disk brake, disc brake 537 | dock, dockage, docking facility 538 | dogsled, dog sled, dog sleigh 539 | dome 540 | doormat, welcome mat 541 | drilling platform, offshore rig 542 | drum, membranophone, tympan 543 | drumstick 544 | dumbbell 545 | Dutch oven 546 | electric fan, blower 547 | electric guitar 548 | electric locomotive 549 | entertainment center 550 | envelope 551 | espresso maker 552 | face powder 553 | feather boa, boa 554 | file, file cabinet, filing cabinet 555 | fireboat 556 | fire engine, fire truck 557 | fire screen, fireguard 558 | flagpole, flagstaff 559 | flute, transverse flute 560 | folding chair 561 | football helmet 562 | forklift 563 | fountain 564 | fountain pen 565 | four-poster 566 | freight car 567 | French horn, horn 568 | frying pan, frypan, skillet 569 | fur coat 570 | garbage truck, dustcart 571 | gasmask, respirator, gas helmet 572 | gas pump, gasoline pump, petrol pump, island dispenser 573 | goblet 574 | go-kart 575 | golf ball 576 | golfcart, golf cart 577 | gondola 578 | gong, tam-tam 579 | gown 580 | grand piano, grand 581 | greenhouse, nursery, glasshouse 582 | grille, radiator grille 583 | grocery store, grocery, food market, market 584 | guillotine 585 | hair slide 586 | hair spray 587 | half track 588 | hammer 589 | hamper 590 | hand blower, blow dryer, blow drier, hair dryer, hair drier 591 | hand-held computer, hand-held microcomputer 592 | handkerchief, hankie, hanky, hankey 593 | hard disc, hard disk, fixed disk 594 | harmonica, mouth organ, harp, mouth harp 595 | harp 596 | harvester, reaper 597 | hatchet 598 | holster 599 | home theater, home theatre 600 | honeycomb 601 | hook, claw 602 | hoopskirt, crinoline 603 | horizontal bar, high bar 604 | horse cart, horse-cart 605 | hourglass 606 | iPod 607 | iron, smoothing iron 608 | jack-o'-lantern 609 | jean, blue jean, denim 610 | jeep, landrover 611 | jersey, T-shirt, tee shirt 612 | jigsaw puzzle 613 | jinrikisha, ricksha, rickshaw 614 | joystick 615 | kimono 616 | knee pad 617 | knot 618 | lab coat, laboratory coat 619 | ladle 620 | lampshade, lamp shade 621 | laptop, laptop computer 622 | lawn mower, mower 623 | lens cap, lens cover 624 | letter opener, paper knife, paperknife 625 | library 626 | lifeboat 627 | lighter, light, igniter, ignitor 628 | limousine, limo 629 | liner, ocean liner 630 | lipstick, lip rouge 631 | Loafer 632 | lotion 633 | loudspeaker, speaker, speaker unit, loudspeaker system, speaker system 634 | loupe, jeweler's loupe 635 | lumbermill, sawmill 636 | magnetic compass 637 | mailbag, postbag 638 | mailbox, letter box 639 | maillot 640 | maillot, tank suit 641 | manhole cover 642 | maraca 643 | marimba, xylophone 644 | mask 645 | matchstick 646 | maypole 647 | maze, labyrinth 648 | measuring cup 649 | medicine chest, medicine cabinet 650 | megalith, megalithic structure 651 | microphone, mike 652 | microwave, microwave oven 653 | military uniform 654 | milk can 655 | minibus 656 | miniskirt, mini 657 | minivan 658 | missile 659 | mitten 660 | mixing bowl 661 | mobile home, manufactured home 662 | Model T 663 | modem 664 | monastery 665 | monitor 666 | moped 667 | mortar 668 | mortarboard 669 | mosque 670 | mosquito net 671 | motor scooter, scooter 672 | mountain bike, all-terrain bike, off-roader 673 | mountain tent 674 | mouse, computer mouse 675 | mousetrap 676 | moving van 677 | muzzle 678 | nail 679 | neck brace 680 | necklace 681 | nipple 682 | notebook, notebook computer 683 | obelisk 684 | oboe, hautboy, hautbois 685 | ocarina, sweet potato 686 | odometer, hodometer, mileometer, milometer 687 | oil filter 688 | organ, pipe organ 689 | oscilloscope, scope, cathode-ray oscilloscope, CRO 690 | overskirt 691 | oxcart 692 | oxygen mask 693 | packet 694 | paddle, boat paddle 695 | paddlewheel, paddle wheel 696 | padlock 697 | paintbrush 698 | pajama, pyjama, pj's, jammies 699 | palace 700 | panpipe, pandean pipe, syrinx 701 | paper towel 702 | parachute, chute 703 | parallel bars, bars 704 | park bench 705 | parking meter 706 | passenger car, coach, carriage 707 | patio, terrace 708 | pay-phone, pay-station 709 | pedestal, plinth, footstall 710 | pencil box, pencil case 711 | pencil sharpener 712 | perfume, essence 713 | Petri dish 714 | photocopier 715 | pick, plectrum, plectron 716 | pickelhaube 717 | picket fence, paling 718 | pickup, pickup truck 719 | pier 720 | piggy bank, penny bank 721 | pill bottle 722 | pillow 723 | ping-pong ball 724 | pinwheel 725 | pirate, pirate ship 726 | pitcher, ewer 727 | plane, carpenter's plane, woodworking plane 728 | planetarium 729 | plastic bag 730 | plate rack 731 | plow, plough 732 | plunger, plumber's helper 733 | Polaroid camera, Polaroid Land camera 734 | pole 735 | police van, police wagon, paddy wagon, patrol wagon, wagon, black Maria 736 | poncho 737 | pool table, billiard table, snooker table 738 | pop bottle, soda bottle 739 | pot, flowerpot 740 | potter's wheel 741 | power drill 742 | prayer rug, prayer mat 743 | printer 744 | prison, prison house 745 | projectile, missile 746 | projector 747 | puck, hockey puck 748 | punching bag, punch bag, punching ball, punchball 749 | purse 750 | quill, quill pen 751 | quilt, comforter, comfort, puff 752 | racer, race car, racing car 753 | racket, racquet 754 | radiator 755 | radio, wireless 756 | radio telescope, radio reflector 757 | rain barrel 758 | recreational vehicle, RV, R.V. 759 | reel 760 | reflex camera 761 | refrigerator, icebox 762 | remote control, remote 763 | restaurant, eating house, eating place, eatery 764 | revolver, six-gun, six-shooter 765 | rifle 766 | rocking chair, rocker 767 | rotisserie 768 | rubber eraser, rubber, pencil eraser 769 | rugby ball 770 | rule, ruler 771 | running shoe 772 | safe 773 | safety pin 774 | saltshaker, salt shaker 775 | sandal 776 | sarong 777 | sax, saxophone 778 | scabbard 779 | scale, weighing machine 780 | school bus 781 | schooner 782 | scoreboard 783 | screen, CRT screen 784 | screw 785 | screwdriver 786 | seat belt, seatbelt 787 | sewing machine 788 | shield, buckler 789 | shoe shop, shoe-shop, shoe store 790 | shoji 791 | shopping basket 792 | shopping cart 793 | shovel 794 | shower cap 795 | shower curtain 796 | ski 797 | ski mask 798 | sleeping bag 799 | slide rule, slipstick 800 | sliding door 801 | slot, one-armed bandit 802 | snorkel 803 | snowmobile 804 | snowplow, snowplough 805 | soap dispenser 806 | soccer ball 807 | sock 808 | solar dish, solar collector, solar furnace 809 | sombrero 810 | soup bowl 811 | space bar 812 | space heater 813 | space shuttle 814 | spatula 815 | speedboat 816 | spider web, spider's web 817 | spindle 818 | sports car, sport car 819 | spotlight, spot 820 | stage 821 | steam locomotive 822 | steel arch bridge 823 | steel drum 824 | stethoscope 825 | stole 826 | stone wall 827 | stopwatch, stop watch 828 | stove 829 | strainer 830 | streetcar, tram, tramcar, trolley, trolley car 831 | stretcher 832 | studio couch, day bed 833 | stupa, tope 834 | submarine, pigboat, sub, U-boat 835 | suit, suit of clothes 836 | sundial 837 | sunglass 838 | sunglasses, dark glasses, shades 839 | sunscreen, sunblock, sun blocker 840 | suspension bridge 841 | swab, swob, mop 842 | sweatshirt 843 | swimming trunks, bathing trunks 844 | swing 845 | switch, electric switch, electrical switch 846 | syringe 847 | table lamp 848 | tank, army tank, armored combat vehicle, armoured combat vehicle 849 | tape player 850 | teapot 851 | teddy, teddy bear 852 | television, television system 853 | tennis ball 854 | thatch, thatched roof 855 | theater curtain, theatre curtain 856 | thimble 857 | thresher, thrasher, threshing machine 858 | throne 859 | tile roof 860 | toaster 861 | tobacco shop, tobacconist shop, tobacconist 862 | toilet seat 863 | torch 864 | totem pole 865 | tow truck, tow car, wrecker 866 | toyshop 867 | tractor 868 | trailer truck, tractor trailer, trucking rig, rig, articulated lorry, semi 869 | tray 870 | trench coat 871 | tricycle, trike, velocipede 872 | trimaran 873 | tripod 874 | triumphal arch 875 | trolleybus, trolley coach, trackless trolley 876 | trombone 877 | tub, vat 878 | turnstile 879 | typewriter keyboard 880 | umbrella 881 | unicycle, monocycle 882 | upright, upright piano 883 | vacuum, vacuum cleaner 884 | vase 885 | vault 886 | velvet 887 | vending machine 888 | vestment 889 | viaduct 890 | violin, fiddle 891 | volleyball 892 | waffle iron 893 | wall clock 894 | wallet, billfold, notecase, pocketbook 895 | wardrobe, closet, press 896 | warplane, military plane 897 | washbasin, handbasin, washbowl, lavabo, wash-hand basin 898 | washer, automatic washer, washing machine 899 | water bottle 900 | water jug 901 | water tower 902 | whiskey jug 903 | whistle 904 | wig 905 | window screen 906 | window shade 907 | Windsor tie 908 | wine bottle 909 | wing 910 | wok 911 | wooden spoon 912 | wool, woolen, woollen 913 | worm fence, snake fence, snake-rail fence, Virginia fence 914 | wreck 915 | yawl 916 | yurt 917 | web site, website, internet site, site 918 | comic book 919 | crossword puzzle, crossword 920 | street sign 921 | traffic light, traffic signal, stoplight 922 | book jacket, dust cover, dust jacket, dust wrapper 923 | menu 924 | plate 925 | guacamole 926 | consomme 927 | hot pot, hotpot 928 | trifle 929 | ice cream, icecream 930 | ice lolly, lolly, lollipop, popsicle 931 | French loaf 932 | bagel, beigel 933 | pretzel 934 | cheeseburger 935 | hotdog, hot dog, red hot 936 | mashed potato 937 | head cabbage 938 | broccoli 939 | cauliflower 940 | zucchini, courgette 941 | spaghetti squash 942 | acorn squash 943 | butternut squash 944 | cucumber, cuke 945 | artichoke, globe artichoke 946 | bell pepper 947 | cardoon 948 | mushroom 949 | Granny Smith 950 | strawberry 951 | orange 952 | lemon 953 | fig 954 | pineapple, ananas 955 | banana 956 | jackfruit, jak, jack 957 | custard apple 958 | pomegranate 959 | hay 960 | carbonara 961 | chocolate sauce, chocolate syrup 962 | dough 963 | meat loaf, meatloaf 964 | pizza, pizza pie 965 | potpie 966 | burrito 967 | red wine 968 | espresso 969 | cup 970 | eggnog 971 | alp 972 | bubble 973 | cliff, drop, drop-off 974 | coral reef 975 | geyser 976 | lakeside, lakeshore 977 | promontory, headland, head, foreland 978 | sandbar, sand bar 979 | seashore, coast, seacoast, sea-coast 980 | valley, vale 981 | volcano 982 | ballplayer, baseball player 983 | groom, bridegroom 984 | scuba diver 985 | rapeseed 986 | daisy 987 | yellow lady's slipper, yellow lady-slipper, Cypripedium calceolus, Cypripedium parviflorum 988 | corn 989 | acorn 990 | hip, rose hip, rosehip 991 | buckeye, horse chestnut, conker 992 | coral fungus 993 | agaric 994 | gyromitra 995 | stinkhorn, carrion fungus 996 | earthstar 997 | hen-of-the-woods, hen of the woods, Polyporus frondosus, Grifola frondosa 998 | bolete 999 | ear, spike, capitulum 1000 | toilet tissue, toilet paper, bathroom tissue -------------------------------------------------------------------------------- /pytorch/download-pretrained-model.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-3.0-or-later 2 | 3 | from torchvision import models 4 | import torch 5 | 6 | output_filename = "alexnet-pretrained.pt" 7 | 8 | try: 9 | alexnet = models.alexnet(weights=models.AlexNet_Weights.IMAGENET1K_V1) 10 | except AttributeError: 11 | # older versions of torchvision (less than 0.13.0) use below now-deprecated parameter 12 | alexnet = models.alexnet(pretrained=True) 13 | 14 | torch.save(alexnet, output_filename) 15 | 16 | print("Pre-trained model was saved in \"%s\"" % output_filename) 17 | -------------------------------------------------------------------------------- /pytorch/input.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/gramineproject/examples/35a6928d8da8fd04ba9e00cc4c3c9dc7013fcda5/pytorch/input.jpg -------------------------------------------------------------------------------- /pytorch/pytorch.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # PyTorch manifest template 5 | 6 | libos.entrypoint = "{{ entrypoint }}" 7 | 8 | loader.log_level = "{{ log_level }}" 9 | 10 | loader.env.LD_LIBRARY_PATH = "/lib:/usr/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}" 11 | loader.env.HOME = "{{ env.HOME }}" 12 | 13 | # Restrict the maximum number of threads to prevent insufficient memory 14 | # issue, observed on CentOS/RHEL. 15 | loader.env.OMP_NUM_THREADS = "8" 16 | 17 | loader.insecure__use_cmdline_argv = true 18 | 19 | fs.mounts = [ 20 | { path = "{{ entrypoint }}", uri = "file:{{ entrypoint }}" }, 21 | { path = "/lib", uri = "file:{{ gramine.runtimedir() }}" }, 22 | { path = "/usr/lib", uri = "file:/usr/lib" }, 23 | { path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" }, 24 | { path = "/usr/{{ arch_libdir }}", uri = "file:/usr/{{ arch_libdir }}" }, 25 | { path = "{{ venv_dir }}", uri = "file:{{ venv_dir }}" }, 26 | {% for path in python.get_sys_path(entrypoint) %} 27 | { path = "{{ path }}", uri = "file:{{ path }}" }, 28 | {% endfor %} 29 | 30 | { type = "tmpfs", path = "/tmp" }, 31 | ] 32 | 33 | sgx.enclave_size = "4G" 34 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '32' }} 35 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 36 | 37 | # `use_exinfo = true` is needed because the application may trigger lazy allocation of pages 38 | # (through exception handling) when EDMM is enabled 39 | sgx.use_exinfo = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 40 | 41 | sgx.trusted_files = [ 42 | "file:{{ entrypoint }}", 43 | "file:{{ gramine.runtimedir() }}/", 44 | "file:/usr/lib/", 45 | "file:{{ arch_libdir }}/", 46 | "file:/usr/{{ arch_libdir }}/", 47 | "file:{{ venv_dir }}/", 48 | {% for path in python.get_sys_path(entrypoint) %} 49 | "file:{{ path }}{{ '/' if path.is_dir() else '' }}", 50 | {% endfor %} 51 | 52 | "file:pytorchexample.py", 53 | 54 | "file:classes.txt", 55 | "file:input.jpg", 56 | "file:alexnet-pretrained.pt", # Pre-trained model saved as a file 57 | ] 58 | 59 | sgx.allowed_files = [ 60 | "file:result.txt", 61 | ] 62 | 63 | # Gramine optionally provides patched OpenMP runtime library that runs faster inside SGX enclaves 64 | # (add `-Dlibgomp=enabled` when configuring the build). Uncomment the line below to use the patched 65 | # library. PyTorch's SGX perf overhead decreases on some workloads from 25% to 8% with this patched 66 | # library. Note that we need to preload the library because PyTorch's distribution renames 67 | # libgomp.so to smth like libgomp-7c85b1e2.so.1, so it's not just a matter of searching in the 68 | # Gramine's Runtime path first, but a matter of intercepting OpenMP functions. 69 | # loader.env.LD_PRELOAD = "/lib/libgomp.so.1" 70 | -------------------------------------------------------------------------------- /pytorch/pytorchexample.py: -------------------------------------------------------------------------------- 1 | # This PyTorch image classification example is based off 2 | # https://www.learnopencv.com/pytorch-for-beginners-image-classification-using-pre-trained-models/ 3 | 4 | from torchvision import models 5 | import torch 6 | 7 | # Load the model from a file 8 | alexnet = torch.load("alexnet-pretrained.pt") 9 | 10 | # Prepare a transform to get the input image into a format (e.g., x,y dimensions) the classifier 11 | # expects. 12 | from torchvision import transforms 13 | transform = transforms.Compose([ 14 | transforms.Resize(256), 15 | transforms.CenterCrop(224), 16 | transforms.ToTensor(), 17 | transforms.Normalize( 18 | mean=[0.485, 0.456, 0.406], 19 | std=[0.229, 0.224, 0.225] 20 | )]) 21 | 22 | # Load the image. 23 | from PIL import Image 24 | img = Image.open("input.jpg") 25 | 26 | # Apply the transform to the image. 27 | img_t = transform(img) 28 | 29 | # Magic (not sure what this does). 30 | batch_t = torch.unsqueeze(img_t, 0) 31 | 32 | # Prepare the model and run the classifier. 33 | alexnet.eval() 34 | out = alexnet(batch_t) 35 | 36 | # Load the classes from disk. 37 | with open('classes.txt') as f: 38 | classes = [line.strip() for line in f.readlines()] 39 | 40 | # Sort the predictions. 41 | _, indices = torch.sort(out, descending=True) 42 | 43 | # Convert into percentages. 44 | percentage = torch.nn.functional.softmax(out, dim=1)[0] * 100 45 | 46 | # Print the 5 most likely predictions. 47 | with open("result.txt", "w") as outfile: 48 | outfile.write(str([(classes[idx], percentage[idx].item()) for idx in indices[0][:5]])) 49 | 50 | print("Done. The result was written to `result.txt`.") 51 | -------------------------------------------------------------------------------- /r/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # Installation location of R. By default, Gramine will run the system R executable. 5 | R_HOME ?= /usr/lib/R 6 | R_EXEC = $(R_HOME)/bin/exec/R 7 | 8 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 9 | 10 | ifeq ($(DEBUG),1) 11 | GRAMINE_LOG_LEVEL = debug 12 | else 13 | GRAMINE_LOG_LEVEL = error 14 | endif 15 | 16 | LD_LIBRARY_PATH := $(LD_LIBRARY_PATH):$(R_HOME)/lib 17 | export LD_LIBRARY_PATH 18 | 19 | .PHONY: all 20 | all: R.manifest 21 | ifeq ($(SGX),1) 22 | all: R.manifest.sgx R.sig 23 | endif 24 | 25 | R.manifest: R.manifest.template 26 | gramine-manifest \ 27 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 28 | -Darch_libdir=$(ARCH_LIBDIR) \ 29 | -Dr_home=$(R_HOME) \ 30 | -Dr_exec=$(R_EXEC) \ 31 | $< >$@ 32 | 33 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 34 | # for details on this workaround see 35 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 36 | R.manifest.sgx R.sig: sgx_sign 37 | @: 38 | 39 | .INTERMEDIATE: sgx_sign 40 | sgx_sign: R.manifest 41 | gramine-sgx-sign \ 42 | --manifest $< \ 43 | --output $<.sgx 44 | 45 | ifeq ($(SGX),) 46 | GRAMINE = gramine-direct 47 | else 48 | GRAMINE = gramine-sgx 49 | endif 50 | 51 | .PHONY: check 52 | check: all 53 | $(GRAMINE) ./R --slave --vanilla -f scripts/sample.r > OUTPUT 2> /dev/null 54 | @grep -q "success" OUTPUT && echo "[ Success 1/1 ]" 55 | @$(RM) OUTPUT 56 | 57 | .PHONY: clean 58 | clean: 59 | $(RM) *.manifest *.manifest.sgx *.token *.sig OUTPUT 60 | 61 | .PHONY: distclean 62 | distclean: clean 63 | -------------------------------------------------------------------------------- /r/R.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # R manifest example 5 | 6 | libos.entrypoint = "{{ r_exec }}" 7 | 8 | loader.log_level = "{{ log_level }}" 9 | 10 | loader.env.LD_LIBRARY_PATH = "{{ r_home }}/lib:/lib:{{ arch_libdir }}:/usr/lib:/usr/{{ arch_libdir }}" 11 | loader.env.PATH = "{{ r_home }}/bin:/usr/bin:/bin" 12 | loader.env.USERNAME = "" 13 | loader.env.HOME = "" 14 | loader.env.PWD = "" 15 | loader.env.R_ARCH = "" 16 | loader.env.R_HOME = "{{ r_home }}" 17 | loader.env.OMP_NUM_THREADS = "4" 18 | 19 | loader.insecure__use_cmdline_argv = true 20 | 21 | sys.enable_sigterm_injection = true 22 | 23 | fs.mounts = [ 24 | { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, 25 | { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, 26 | { uri = "file:/usr", path = "/usr" }, 27 | { uri = "file:/bin", path = "/bin" }, 28 | { uri = "file:{{ r_home }}", path = "{{ r_home }}" }, 29 | 30 | { type = "tmpfs", path = "/tmp" }, 31 | ] 32 | 33 | sys.stack.size = "8M" 34 | sgx.enclave_size = "2G" # for the R-benchmark-25.R script, specify at least "16G" 35 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '8' }} 36 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 37 | 38 | # `use_exinfo = true` is needed because the application may trigger lazy allocation of pages 39 | # (through exception handling) when EDMM is enabled 40 | sgx.use_exinfo = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 41 | 42 | sgx.trusted_files = [ 43 | "file:{{ r_exec }}", 44 | "file:{{ gramine.runtimedir() }}/", 45 | "file:{{ arch_libdir }}/", 46 | "file:/usr/{{ arch_libdir }}/", 47 | "file:{{ r_home }}/", 48 | "file:scripts/", 49 | 50 | # R uses shell to delete files, so we need to allow /bin/sh and /bin/rm to be accessed. 51 | # strace snippet: execve("/bin/sh", ["sh", "-c", "rm -rf /tmp/RtmpEiedDF"], [/* 41 vars */]) 52 | "file:/bin/rm", 53 | "file:/bin/sh", 54 | ] 55 | -------------------------------------------------------------------------------- /r/README.md: -------------------------------------------------------------------------------- 1 | # R example 2 | 3 | This directory contains an example for running R in Gramine, including the 4 | Makefile and a template for generating the manifest. 5 | 6 | # Generating the manifest 7 | 8 | ## Building for Linux 9 | 10 | Run `make` (non-debug) or `make DEBUG=1` (debug) in the directory. 11 | 12 | ## Building for SGX 13 | 14 | Run `make SGX=1` (non-debug) or `make SGX=1 DEBUG=1` (debug) in the directory. 15 | 16 | ## Building with a local R installation 17 | 18 | By default, the `make` command creates the manifest for the system R binary 19 | (`/usr/lib/R/bin/exec/R`). If you have a local R installation, you may create 20 | the manifest with the `R_HOME` variable set accordingly. For example: 21 | 22 | ``` 23 | make R_HOME=/lib/R SGX=1 24 | ``` 25 | 26 | # Run R with Gramine 27 | 28 | When running R with Gramine, please use the `--vanilla` or `--no-save` option. 29 | 30 | Here's an example of running an R script under Gramine: 31 | 32 | Without SGX: 33 | ``` 34 | gramine-direct ./R --slave --vanilla -f scripts/sample.r 35 | gramine-direct ./R --slave --vanilla -f scripts/R-benchmark-25.R 36 | ``` 37 | 38 | With SGX: 39 | ``` 40 | gramine-sgx ./R --slave --vanilla -f scripts/sample.r 41 | gramine-sgx ./R --slave --vanilla -f scripts/R-benchmark-25.R 42 | ``` 43 | -------------------------------------------------------------------------------- /r/scripts/R-benchmark-25.R: -------------------------------------------------------------------------------- 1 | # R Benchmark 2.5 (06/2008) [Simon Urbanek] 2 | # version 2.5: scaled to get roughly 1s per test, R 2.7.0 @ 2.6GHz Mac Pro 3 | # R Benchmark 2.4 (06/2008) [Simon Urbanek] 4 | # version 2.4 adapted to more recent Matrix package 5 | # R Benchmark 2.3 (21 April 2004) 6 | # Warning: changes are not carefully checked yet! 7 | # version 2.3 adapted to R 1.9.0 8 | # Many thanks to Douglas Bates (bates@stat.wisc.edu) for improvements! 9 | # version 2.2 adapted to R 1.8.0 10 | # version 2.1 adapted to R 1.7.0 11 | # version 2, scaled to get 1 +/- 0.1 sec with R 1.6.2 12 | # using the standard ATLAS library (Rblas.dll) 13 | # on a Pentium IV 1.6 Ghz with 1 Gb Ram on Win XP pro 14 | 15 | # revised and optimized for R v. 1.5.x, 8 June 2002 16 | # Requires additionnal libraries: Matrix, SuppDists 17 | # Author : Philippe Grosjean 18 | # eMail : phgrosjean@sciviews.org 19 | # Web : http://www.sciviews.org 20 | # License: GPL 2 or above at your convenience (see: http://www.gnu.org) 21 | # 22 | # Several tests are adapted from the Splus Benchmark Test V. 2 23 | # by Stephan Steinhaus (stst@informatik.uni-frankfurt.de) 24 | # Reference for Escoufier's equivalents vectors (test III.5): 25 | # Escoufier Y., 1970. Echantillonnage dans une population de variables 26 | # aleatoires réelles. Publ. Inst. Statis. Univ. Paris 19 Fasc 4, 1-47. 27 | # 28 | # type source("c://R2.R") to start the test 29 | 30 | runs <- 3 # Number of times the tests are executed 31 | times <- rep(0, 15); dim(times) <- c(5,3) 32 | require(Matrix) # Optimized matrix operations 33 | require(SuppDists) # Optimized random number generators 34 | #Runif <- rMWC1019 # The fast uniform number generator 35 | Runif <- runif 36 | # If you don't have SuppDists, you can use: Runif <- runif 37 | #a <- rMWC1019(10, new.start=TRUE, seed=492166) # Init. the generator 38 | #Rnorm <- rziggurat # The fast normal number generator 39 | # If you don't have SuppDists, you can use: Rnorm <- rnorm 40 | #b <- rziggurat(10, new.start=TRUE) # Init. the generator 41 | Rnorm <- rnorm 42 | remove("a", "b") 43 | options(object.size=100000000) 44 | 45 | cat("\n\n R Benchmark 2.5\n") 46 | cat(" ===============\n") 47 | cat(c("Number of times each test is run__________________________: ", runs)) 48 | cat("\n\n") 49 | 50 | 51 | cat(" I. Matrix calculation\n") 52 | cat(" ---------------------\n") 53 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 54 | 55 | # (1) 56 | cumulate <- 0; a <- 0; b <- 0 57 | for (i in 1:runs) { 58 | invisible(gc()) 59 | timing <- system.time({ 60 | a <- matrix(Rnorm(2500*2500)/10, ncol=2500, nrow=2500); 61 | b <- t(a); 62 | dim(b) <- c(1250, 5000); 63 | a <- t(b) 64 | })[3] 65 | cumulate <- cumulate + timing 66 | } 67 | timing <- cumulate/runs 68 | times[1, 1] <- timing 69 | cat(c("Creation, transp., deformation of a 2500x2500 matrix (sec): ", timing, "\n")) 70 | remove("a", "b") 71 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 72 | 73 | # (2) 74 | cumulate <- 0; b <- 0 75 | for (i in 1:runs) { 76 | a <- abs(matrix(Rnorm(2500*2500)/2, ncol=2500, nrow=2500)); 77 | invisible(gc()) 78 | timing <- system.time({ 79 | b <- a^1000 80 | })[3] 81 | cumulate <- cumulate + timing 82 | } 83 | timing <- cumulate/runs 84 | times[2, 1] <- timing 85 | cat(c("2400x2400 normal distributed random matrix ^1000____ (sec): ", timing, "\n")) 86 | remove("a", "b") 87 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 88 | 89 | # (3) 90 | cumulate <- 0; b <- 0 91 | for (i in 1:runs) { 92 | a <- Rnorm(7000000) 93 | invisible(gc()) 94 | timing <- system.time({ 95 | b <- sort(a, method="quick") # Sort is modified in v. 1.5.x 96 | # And there is now a quick method that better competes with other packages!!! 97 | })[3] 98 | cumulate <- cumulate + timing 99 | } 100 | timing <- cumulate/runs 101 | times[3, 1] <- timing 102 | cat(c("Sorting of 7,000,000 random values__________________ (sec): ", timing, "\n")) 103 | remove("a", "b") 104 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 105 | 106 | # (4) 107 | cumulate <- 0; b <- 0 108 | for (i in 1:runs) { 109 | a <- Rnorm(2800*2800); dim(a) <- c(2800, 2800) 110 | invisible(gc()) 111 | timing <- system.time({ 112 | b <- crossprod(a) # equivalent to: b <- t(a) %*% a 113 | })[3] 114 | cumulate <- cumulate + timing 115 | } 116 | timing <- cumulate/runs 117 | times[4, 1] <- timing 118 | cat(c("2800x2800 cross-product matrix (b = a' * a)_________ (sec): ", timing, "\n")) 119 | remove("a", "b") 120 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 121 | 122 | # (5) 123 | cumulate <- 0; c <- 0; qra <-0 124 | for (i in 1:runs) { 125 | a <- new("dgeMatrix", x = Rnorm(2000*2000), Dim = as.integer(c(2000,2000))) 126 | b <- as.double(1:2000) 127 | invisible(gc()) 128 | timing <- system.time({ 129 | c <- solve(crossprod(a), crossprod(a,b)) 130 | })[3] 131 | cumulate <- cumulate + timing 132 | 133 | # This is the old method 134 | #a <- Rnorm(600*600); dim(a) <- c(600,600) 135 | #b <- 1:600 136 | #invisible(gc()) 137 | #timing <- system.time({ 138 | # qra <- qr(a, tol = 1e-7); 139 | # c <- qr.coef(qra, b) 140 | # #Rem: a little faster than c <- lsfit(a, b, inter=F)$coefficients 141 | #})[3] 142 | #cumulate <- cumulate + timing 143 | } 144 | timing <- cumulate/runs 145 | times[5, 1] <- timing 146 | cat(c("Linear regr. over a 3000x3000 matrix (c = a \\ b')___ (sec): ", timing, "\n")) 147 | remove("a", "b", "c", "qra") 148 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 149 | 150 | times[ , 1] <- sort(times[ , 1]) 151 | cat(" --------------------------------------------\n") 152 | cat(c(" Trimmed geom. mean (2 extremes eliminated): ", exp(mean(log(times[2:4, 1]))), "\n\n")) 153 | 154 | cat(" II. Matrix functions\n") 155 | cat(" --------------------\n") 156 | if (R.Version()$os == "Win32") flush.console() 157 | 158 | # (1) 159 | cumulate <- 0; b <- 0 160 | for (i in 1:runs) { 161 | a <- Rnorm(2400000) 162 | invisible(gc()) 163 | timing <- system.time({ 164 | b <- fft(a) 165 | })[3] 166 | cumulate <- cumulate + timing 167 | } 168 | timing <- cumulate/runs 169 | times[1, 2] <- timing 170 | cat(c("FFT over 2,400,000 random values____________________ (sec): ", timing, "\n")) 171 | remove("a", "b") 172 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 173 | 174 | # (2) 175 | cumulate <- 0; b <- 0 176 | for (i in 1:runs) { 177 | a <- array(Rnorm(600*600), dim = c(600, 600)) 178 | # Only needed if using eigen.Matrix(): Matrix.class(a) 179 | invisible(gc()) 180 | timing <- system.time({ 181 | b <- eigen(a, symmetric=FALSE, only.values=TRUE)$Value 182 | # Rem: on my machine, it is faster than: 183 | # b <- La.eigen(a, symmetric=F, only.values=T, method="dsyevr")$Value 184 | # b <- La.eigen(a, symmetric=F, only.values=T, method="dsyev")$Value 185 | # b <- eigen.Matrix(a, vectors = F)$Value 186 | })[3] 187 | cumulate <- cumulate + timing 188 | } 189 | timing <- cumulate/runs 190 | times[2, 2] <- timing 191 | cat(c("Eigenvalues of a 640x640 random matrix______________ (sec): ", timing, "\n")) 192 | remove("a", "b") 193 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 194 | 195 | # (3) 196 | cumulate <- 0; b <- 0 197 | for (i in 1:runs) { 198 | a <- Rnorm(2500*2500); dim(a) <- c(2500, 2500) 199 | #Matrix.class(a) 200 | invisible(gc()) 201 | timing <- system.time({ 202 | #b <- determinant(a, logarithm=F) 203 | # Rem: the following is slower on my computer! 204 | # b <- det.default(a) 205 | b <- det(a) 206 | })[3] 207 | cumulate <- cumulate + timing 208 | } 209 | timing <- cumulate/runs 210 | times[3, 2] <- timing 211 | cat(c("Determinant of a 2500x2500 random matrix____________ (sec): ", timing, "\n")) 212 | remove("a", "b") 213 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 214 | 215 | # (4) 216 | cumulate <- 0; b <- 0 217 | for (i in 1:runs) { 218 | a <- crossprod(new("dgeMatrix", x = Rnorm(3000*3000), 219 | Dim = as.integer(c(3000, 3000)))) 220 | invisible(gc()) 221 | #a <- Rnorm(900*900); dim(a) <- c(900, 900) 222 | #a <- crossprod(a, a) 223 | timing <- system.time({ 224 | b <- chol(a) 225 | })[3] 226 | cumulate <- cumulate + timing 227 | } 228 | timing <- cumulate/runs 229 | times[4, 2] <- timing 230 | cat(c("Cholesky decomposition of a 3000x3000 matrix________ (sec): ", timing, "\n")) 231 | remove("a", "b") 232 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 233 | 234 | # (5) 235 | cumulate <- 0; b <- 0 236 | for (i in 1:runs) { 237 | a <- new("dgeMatrix", x = Rnorm(1600*1600), Dim = as.integer(c(1600, 1600))) 238 | invisible(gc()) 239 | #a <- Rnorm(400*400); dim(a) <- c(400, 400) 240 | timing <- system.time({ 241 | # b <- qr.solve(a) 242 | # Rem: a little faster than 243 | b <- solve(a) 244 | })[3] 245 | cumulate <- cumulate + timing 246 | } 247 | timing <- cumulate/runs 248 | times[5, 2] <- timing 249 | cat(c("Inverse of a 1600x1600 random matrix________________ (sec): ", timing, "\n")) 250 | remove("a", "b") 251 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 252 | 253 | times[ , 2] <- sort(times[ , 2]) 254 | cat(" --------------------------------------------\n") 255 | cat(c(" Trimmed geom. mean (2 extremes eliminated): ", exp(mean(log(times[2:4, 2]))), "\n\n")) 256 | 257 | cat(" III. Programmation\n") 258 | cat(" ------------------\n") 259 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 260 | 261 | # (1) 262 | cumulate <- 0; a <- 0; b <- 0; phi <- 1.6180339887498949 263 | for (i in 1:runs) { 264 | a <- floor(Runif(3500000)*1000) 265 | invisible(gc()) 266 | timing <- system.time({ 267 | b <- (phi^a - (-phi)^(-a))/sqrt(5) 268 | })[3] 269 | cumulate <- cumulate + timing 270 | } 271 | timing <- cumulate/runs 272 | times[1, 3] <- timing 273 | cat(c("3,500,000 Fibonacci numbers calculation (vector calc)(sec): ", timing, "\n")) 274 | remove("a", "b", "phi") 275 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 276 | 277 | # (2) 278 | cumulate <- 0; a <- 3000; b <- 0 279 | for (i in 1:runs) { 280 | invisible(gc()) 281 | timing <- system.time({ 282 | b <- rep(1:a, a); dim(b) <- c(a, a); 283 | b <- 1 / (t(b) + 0:(a-1)) 284 | # Rem: this is twice as fast as the following code proposed by R programmers 285 | # a <- 1:a; b <- 1 / outer(a - 1, a, "+") 286 | })[3] 287 | cumulate <- cumulate + timing 288 | } 289 | timing <- cumulate/runs 290 | times[2, 3] <- timing 291 | cat(c("Creation of a 3000x3000 Hilbert matrix (matrix calc) (sec): ", timing, "\n")) 292 | remove("a", "b") 293 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 294 | 295 | # (3) 296 | cumulate <- 0; c <- 0 297 | gcd2 <- function(x, y) {if (sum(y > 1.0E-4) == 0) x else {y[y == 0] <- x[y == 0]; Recall(y, x %% y)}} 298 | for (i in 1:runs) { 299 | a <- ceiling(Runif(400000)*1000) 300 | b <- ceiling(Runif(400000)*1000) 301 | invisible(gc()) 302 | timing <- system.time({ 303 | c <- gcd2(a, b) # gcd2 is a recursive function 304 | })[3] 305 | cumulate <- cumulate + timing 306 | } 307 | timing <- cumulate/runs 308 | times[3, 3] <- timing 309 | cat(c("Grand common divisors of 400,000 pairs (recursion)__ (sec): ", timing, "\n")) 310 | remove("a", "b", "c", "gcd2") 311 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 312 | 313 | # (4) 314 | cumulate <- 0; b <- 0 315 | for (i in 1:runs) { 316 | b <- rep(0, 500*500); dim(b) <- c(500, 500) 317 | invisible(gc()) 318 | timing <- system.time({ 319 | # Rem: there are faster ways to do this 320 | # but here we want to time loops (220*220 'for' loops)! 321 | for (j in 1:500) { 322 | for (k in 1:500) { 323 | b[k,j] <- abs(j - k) + 1 324 | } 325 | } 326 | })[3] 327 | cumulate <- cumulate + timing 328 | } 329 | timing <- cumulate/runs 330 | times[4, 3] <- timing 331 | cat(c("Creation of a 500x500 Toeplitz matrix (loops)_______ (sec): ", timing, "\n")) 332 | remove("b", "j", "k") 333 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 334 | 335 | # (5) 336 | cumulate <- 0; p <- 0; vt <- 0; vr <- 0; vrt <- 0; rvt <- 0; RV <- 0; j <- 0; k <- 0; 337 | x2 <- 0; R <- 0; Rxx <- 0; Ryy <- 0; Rxy <- 0; Ryx <- 0; Rvmax <- 0 338 | # Calculate the trace of a matrix (sum of its diagonal elements) 339 | Trace <- function(y) {sum(c(y)[1 + 0:(min(dim(y)) - 1) * (dim(y)[1] + 1)], na.rm=FALSE)} 340 | for (i in 1:runs) { 341 | x <- abs(Rnorm(45*45)); dim(x) <- c(45, 45) 342 | invisible(gc()) 343 | timing <- system.time({ 344 | # Calculation of Escoufier's equivalent vectors 345 | p <- ncol(x) 346 | vt <- 1:p # Variables to test 347 | vr <- NULL # Result: ordered variables 348 | RV <- 1:p # Result: correlations 349 | vrt <- NULL 350 | for (j in 1:p) { # loop on the variable number 351 | Rvmax <- 0 352 | for (k in 1:(p-j+1)) { # loop on the variables 353 | x2 <- cbind(x, x[,vr], x[,vt[k]]) 354 | R <- cor(x2) # Correlations table 355 | Ryy <- R[1:p, 1:p] 356 | Rxx <- R[(p+1):(p+j), (p+1):(p+j)] 357 | Rxy <- R[(p+1):(p+j), 1:p] 358 | Ryx <- t(Rxy) 359 | rvt <- Trace(Ryx %*% Rxy) / sqrt(Trace(Ryy %*% Ryy) * Trace(Rxx %*% Rxx)) # RV calculation 360 | if (rvt > Rvmax) { 361 | Rvmax <- rvt # test of RV 362 | vrt <- vt[k] # temporary held variable 363 | } 364 | } 365 | vr[j] <- vrt # Result: variable 366 | RV[j] <- Rvmax # Result: correlation 367 | vt <- vt[vt!=vr[j]] # reidentify variables to test 368 | } 369 | })[3] 370 | cumulate <- cumulate + timing 371 | } 372 | times[5, 3] <- timing 373 | cat(c("Escoufier's method on a 45x45 matrix (mixed)________ (sec): ", timing, "\n")) 374 | remove("x", "p", "vt", "vr", "vrt", "rvt", "RV", "j", "k") 375 | remove("x2", "R", "Rxx", "Ryy", "Rxy", "Ryx", "Rvmax", "Trace") 376 | if (R.Version()$os == "Win32" || R.Version()$os == "mingw32") flush.console() 377 | 378 | times[ , 3] <- sort(times[ , 3]) 379 | cat(" --------------------------------------------\n") 380 | cat(c(" Trimmed geom. mean (2 extremes eliminated): ", exp(mean(log(times[2:4, 3]))), "\n\n\n")) 381 | 382 | cat(c("Total time for all 15 tests_________________________ (sec): ", sum(times), "\n")) 383 | cat(c("Overall mean (sum of I, II and III trimmed means/3)_ (sec): ", exp(mean(log(times[2:4, ]))), "\n")) 384 | remove("cumulate", "timing", "times", "runs", "i") 385 | cat(" --- End of test ---\n\n") 386 | -------------------------------------------------------------------------------- /r/scripts/sample.r: -------------------------------------------------------------------------------- 1 | # Copied from https://www.rexamples.com/14/Sample() 2 | 3 | print(sample(1:3)) 4 | print(sample(1:3, size=3, replace=FALSE)) # same as previous line 5 | print(sample(c(2,5,3), size=4, replace=TRUE)) 6 | print(sample(1:2, size=10, prob=c(1,3), replace=TRUE)) 7 | print("success") 8 | -------------------------------------------------------------------------------- /scikit-learn-intelex/.gitignore: -------------------------------------------------------------------------------- 1 | /data/ 2 | /OUTPUT 3 | -------------------------------------------------------------------------------- /scikit-learn-intelex/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 5 | 6 | ifeq ($(DEBUG),1) 7 | GRAMINE_LOG_LEVEL = debug 8 | else 9 | GRAMINE_LOG_LEVEL = error 10 | endif 11 | 12 | .PHONY: all 13 | all: sklearnex.manifest 14 | ifeq ($(SGX),1) 15 | all: sklearnex.manifest.sgx sklearnex.sig 16 | endif 17 | 18 | sklearnex.manifest: sklearnex.manifest.template 19 | gramine-manifest \ 20 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 21 | -Darch_libdir=$(ARCH_LIBDIR) \ 22 | -Denv_user_uid=$(shell id -u) \ 23 | -Denv_user_gid=$(shell id -g) \ 24 | -Dentrypoint=$(realpath $(shell sh -c "command -v python3")) \ 25 | $< >$@ 26 | 27 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 28 | # for details on this workaround see 29 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 30 | sklearnex.manifest.sgx sklearnex.sig: sgx_sign 31 | @: 32 | 33 | .INTERMEDIATE: sgx_sign 34 | sgx_sign: sklearnex.manifest 35 | gramine-sgx-sign \ 36 | --manifest $< \ 37 | --output $<.sgx 38 | 39 | .PHONY: clean 40 | clean: 41 | $(RM) *.manifest *.manifest.sgx *.token *.sig OUTPUT* TEST_STDOUT TEST_STDERR 42 | $(RM) -r __pycache__ 43 | $(RM) -r scripts/__pycache__ 44 | 45 | .PHONY: distclean 46 | distclean: clean 47 | -------------------------------------------------------------------------------- /scikit-learn-intelex/README.md: -------------------------------------------------------------------------------- 1 | # Intel(R) Extension for Scikit-learn example 2 | 3 | This directory contains an example for running Intel(R) Extension for 4 | Scikit-learn with Gramine, including the Makefile and a template for generating 5 | the manifest. 6 | 7 | **NOTE**: This example works only on post-v1.3.1 Gramine, due to the manifest 8 | file requiring special Python-templates handling. This example will work 9 | correctly on Gramine v1.4 once the latter is released. 10 | 11 | This example was tested with the following configuration: 12 | - scikit-learn-intelex v2023.0.1 13 | - scikit-learn v1.2.0 14 | - pandas v1.5.2 15 | - daal4py v2023.0.1 16 | - daal v2023.0.1 17 | - scipy v1.10.0 18 | - numpy v1.24.1 19 | 20 | # Generating the manifest 21 | 22 | ## Installing prerequisites 23 | 24 | For generating the manifest and running the test scripts, please run the 25 | following command to install the required packages (Ubuntu-specific): 26 | 27 | ```sh 28 | # required for Ubuntu 18.04 as its default pip doesn't have scikit-learn package 29 | python3 -m pip install --upgrade pip 30 | 31 | python3 -m pip install scikit-learn-intelex==2023.0.1 pandas 32 | ``` 33 | 34 | ## Download datasets 35 | 36 | Before run, please download MNIST dataset by the following command: 37 | 38 | ```sh 39 | python3 scripts/download_dataset.py 40 | ``` 41 | 42 | ## Building for Linux 43 | 44 | Run `make` (non-debug) or `make DEBUG=1` (debug) in the directory. 45 | 46 | ## Building for SGX 47 | 48 | Run `make SGX=1` (non-debug) or `make SGX=1 DEBUG=1` (debug) in the directory. 49 | 50 | # Run Intel(R) Extension for Scikit-learn with Gramine 51 | 52 | Without SGX: 53 | 54 | ```sh 55 | gramine-direct ./sklearnex scripts/kmeans_example.py 56 | gramine-direct ./sklearnex scripts/kmeans_perf_eval.py 57 | ``` 58 | 59 | **NOTE**: `kmeans_perf_eval.py` can exceed the process's maximum number of 60 | mappings in Linux. You may need to increase the value in 61 | `/proc/sys/vm/max_map_count`: 62 | 63 | ``` 64 | # the value is just an example 65 | sudo sysctl vm.max_map_count=1310720 66 | ``` 67 | 68 | With SGX: 69 | 70 | ```sh 71 | gramine-sgx ./sklearnex scripts/kmeans_example.py 72 | gramine-sgx ./sklearnex scripts/kmeans_perf_eval.py 73 | ``` 74 | 75 | You can also manually run included tests: 76 | 77 | ```sh 78 | SGX=1 ./run_tests.sh 79 | ``` 80 | -------------------------------------------------------------------------------- /scikit-learn-intelex/run_tests.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Copyright (C) 2024 Gramine contributors 4 | # SPDX-License-Identifier: BSD-3-Clause 5 | 6 | set -e 7 | 8 | if test -n "$SGX" 9 | then 10 | GRAMINE=gramine-sgx 11 | else 12 | GRAMINE=gramine-direct 13 | fi 14 | 15 | # === Kmeans example === 16 | echo -e "\n\nRunning kmeans_example.py:" 17 | $GRAMINE ./sklearnex scripts/kmeans_example.py > OUTPUT 18 | grep -q "Kmeans example finished" OUTPUT && echo "[ Success 1/2 ]" && rm OUTPUT 19 | 20 | # === Kmeans perf eval === 21 | echo -e "\n\nRunning kmeans_perf_eval.py:" 22 | $GRAMINE ./sklearnex scripts/kmeans_perf_eval.py > OUTPUT 23 | grep -q "Kmeans perf evaluation finished" OUTPUT && echo "[ Success 2/2 ]" && rm OUTPUT 24 | -------------------------------------------------------------------------------- /scikit-learn-intelex/scripts/download_dataset.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-3.0-or-later 2 | # Copyright (C) 2021 Intel Corporation 3 | # Andrey Morkovkin 4 | 5 | from sklearn.datasets import fetch_openml 6 | 7 | def main(): 8 | X, y = fetch_openml(name='mnist_784', version=1, return_X_y=True, data_home='data', parser='auto') 9 | X.to_csv('data/X.csv', index=False, header=False) 10 | y.to_csv('data/y.csv', index=False, header=False) 11 | 12 | if __name__ == '__main__': 13 | main() 14 | -------------------------------------------------------------------------------- /scikit-learn-intelex/scripts/kmeans_example.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-3.0-or-later 2 | # Copyright (C) 2021 Intel Corporation 3 | # Andrey Morkovkin 4 | 5 | 6 | from timeit import default_timer as timer 7 | import pandas as pd 8 | 9 | from sklearnex import patch_sklearn 10 | patch_sklearn() 11 | 12 | from sklearn.model_selection import train_test_split 13 | from sklearn.preprocessing import MinMaxScaler 14 | from sklearn.cluster import KMeans 15 | from sklearn.metrics import davies_bouldin_score 16 | 17 | def main(): 18 | X = pd.read_csv('data/X.csv') 19 | y = pd.read_csv('data/y.csv') 20 | 21 | x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=123) 22 | 23 | scaler_x = MinMaxScaler() 24 | scaler_x.fit(x_train) 25 | x_train = scaler_x.transform(x_train) 26 | x_test = scaler_x.transform(x_test) 27 | 28 | params = { 29 | 'n_clusters': 10, 30 | 'random_state': 123, 31 | 'copy_x': False, 32 | } 33 | 34 | start = timer() 35 | model = KMeans(**params).fit(x_train, y_train) 36 | train_patched = timer() - start 37 | print(f'Intel extension for Scikit-learn train time: {train_patched:.3f} s') 38 | 39 | inertia_opt = model.inertia_ 40 | n_iter_opt = model.n_iter_ 41 | print(f'Intel extension for Scikit-learn inertia: {inertia_opt:.3f}') 42 | print(f'Intel extension for Scikit-learn number of iterations: {n_iter_opt}') 43 | 44 | davies_bouldin_value = davies_bouldin_score(x_train, model.labels_) 45 | print(f'Intel extension for Scikit-learn Davies-Bouldin metric on train data: {davies_bouldin_value:.3f}') 46 | 47 | start = timer() 48 | predicted_labels = model.predict(x_test) 49 | test_time = timer() - start 50 | print(f'Intel extension for Scikit-learn predict time: {test_time:.3f} s') 51 | 52 | davies_bouldin_value = davies_bouldin_score(x_test, predicted_labels) 53 | print(f'Intel extension for Scikit-learn Davies-Bouldin metric on test data: {davies_bouldin_value:.3f}') 54 | print('Kmeans example finished') 55 | 56 | if __name__ == '__main__': 57 | main() 58 | -------------------------------------------------------------------------------- /scikit-learn-intelex/scripts/kmeans_perf_eval.py: -------------------------------------------------------------------------------- 1 | # SPDX-License-Identifier: LGPL-3.0-or-later 2 | # Copyright (C) 2021 Intel Corporation 3 | # Andrey Morkovkin 4 | 5 | from timeit import default_timer as timer 6 | import pandas as pd 7 | 8 | def run(X, y, is_patched): 9 | if is_patched: 10 | from sklearnex import patch_sklearn 11 | patch_sklearn() 12 | 13 | from sklearn.model_selection import train_test_split 14 | from sklearn.preprocessing import MinMaxScaler 15 | from sklearn.cluster import KMeans 16 | from sklearn.metrics import davies_bouldin_score 17 | 18 | x_train, x_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=123) 19 | 20 | scaler_x = MinMaxScaler() 21 | scaler_x.fit(x_train) 22 | x_train = scaler_x.transform(x_train) 23 | x_test = scaler_x.transform(x_test) 24 | 25 | params = { 26 | 'n_clusters': 10, 27 | 'n_init': 10, 28 | 'random_state': 123, 29 | 'copy_x': False, 30 | } 31 | 32 | start = timer() 33 | model = KMeans(**params).fit(x_train) 34 | train_time = timer() - start 35 | print(f'Train time: {train_time:.3f} s') 36 | 37 | inertia_opt = model.inertia_ 38 | n_iter_opt = model.n_iter_ 39 | davies_bouldin_value = davies_bouldin_score(x_train, model.labels_) 40 | print(f'Inertia: {inertia_opt:.3f}') 41 | print(f'Number of iterations: {n_iter_opt}') 42 | print(f'Davies-Bouldin metric on train data: {davies_bouldin_value:.3f}') 43 | 44 | start = timer() 45 | predicted_labels = model.predict(x_test) 46 | test_time = timer() - start 47 | print(f'Predict time: {test_time:.3f} s') 48 | 49 | davies_bouldin_value = davies_bouldin_score(x_test, predicted_labels) 50 | print(f'Davies-Bouldin metric on test data: {davies_bouldin_value:.3f}') 51 | 52 | 53 | def main(): 54 | X = pd.read_csv('data/X.csv') 55 | y = pd.read_csv('data/y.csv') 56 | 57 | print('*** Stock Scikit-learn ***') 58 | run(X, y, is_patched=False) 59 | print('*** Intel extension for Scikit-learn ***') 60 | run(X, y, is_patched=True) 61 | print('Kmeans perf evaluation finished') 62 | 63 | if __name__ == '__main__': 64 | main() 65 | -------------------------------------------------------------------------------- /scikit-learn-intelex/sklearnex.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # Intel(R) Extension for Scikit-learn* manifest example 5 | 6 | libos.entrypoint = "{{ entrypoint }}" 7 | 8 | loader.log_level = "{{ log_level }}" 9 | 10 | loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}:/home/user/.local/lib" 11 | loader.env.HOME = "{{ env.HOME }}" 12 | 13 | loader.insecure__use_cmdline_argv = true 14 | 15 | loader.env.OMP_NUM_THREADS = "8" 16 | 17 | loader.uid = {{ env_user_uid }} 18 | loader.gid = {{ env_user_gid }} 19 | 20 | sys.stack.size = "8M" 21 | sys.enable_extra_runtime_domain_names_conf = true 22 | 23 | fs.mounts = [ 24 | { path = "{{ entrypoint }}", uri = "file:{{ entrypoint }}" }, 25 | { path = "/lib", uri = "file:{{ gramine.runtimedir() }}" }, 26 | { path = "{{ arch_libdir }}", uri = "file:{{ arch_libdir }}" }, 27 | { path = "/usr/{{ arch_libdir }}", uri = "file:/usr/{{ arch_libdir }}" }, 28 | {% for path in python.get_sys_path(entrypoint) %} 29 | { path = "{{ path }}", uri = "file:{{ path }}" }, 30 | {% endfor %} 31 | 32 | # scikit-learn and its dependencies install shared libs under this path (e.g. daal4py package 33 | # installs libonedal_core.so lib); note that we use `/home/user/` prefix inside Gramine and 34 | # specify this prefix in LD_LIBRARY_PATH envvar above 35 | { path = "/home/user/.local/lib", uri = "file:{{ env.HOME }}/.local/lib" }, 36 | 37 | # Scikit imports pandas which in turn relies on the pytz library. The newer pytz versions fail if 38 | # they cannot find files under /usr/share/zoneinfo (found on pytz version 2022.1, installed by 39 | # apt). 40 | { path = "/usr/share/zoneinfo/", uri = "file:/usr/share/zoneinfo/" }, 41 | 42 | { type = "tmpfs", path = "/tmp" }, 43 | ] 44 | 45 | sgx.enclave_size = "16G" 46 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '128' }} 47 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 48 | 49 | sgx.trusted_files = [ 50 | "file:{{ entrypoint }}", 51 | "file:{{ gramine.runtimedir() }}/", 52 | "file:{{ arch_libdir }}/", 53 | "file:/usr/{{ arch_libdir }}/", 54 | {% for path in python.get_sys_path(entrypoint) %} 55 | "file:{{ path }}{{ '/' if path.is_dir() else '' }}", 56 | {% endfor %} 57 | "file:{{ env.HOME }}/.local/lib/", 58 | "file:data/", 59 | "file:scripts/", 60 | "file:/usr/share/zoneinfo/", 61 | ] 62 | -------------------------------------------------------------------------------- /tensorflow-lite/.gitignore: -------------------------------------------------------------------------------- 1 | /bazel-*-installer-linux-*.sh 2 | /image.bmp 3 | /inception_v3.pb 4 | /inception_v3.tflite 5 | /inception_v3_2018_04_27.tgz 6 | /label_image 7 | /labels.txt 8 | /tensorflow 9 | /tensorflow.tar.gz 10 | -------------------------------------------------------------------------------- /tensorflow-lite/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | manifests = $(addsuffix .manifest,label_image) 5 | exec_target = $(manifests) 6 | target = label_image 7 | 8 | ARCH_LIBDIR ?= /lib/$(shell $(CC) -dumpmachine) 9 | 10 | TF_DIR ?= tensorflow 11 | BAZEL_BIN ?= $(HOME)/bin/bazel 12 | 13 | GIT_COMMIT ?= v1.9.0 14 | TAR_SHA256 ?= ffc3151b06823d57b4a408261ba8efe53601563dfe93af0866751d4f6ca5068c 15 | 16 | ifeq ($(DEBUG),1) 17 | GRAMINE_LOG_LEVEL = debug 18 | else 19 | GRAMINE_LOG_LEVEL = error 20 | endif 21 | 22 | .PHONY: all 23 | all: label_image.manifest 24 | ifeq ($(SGX),1) 25 | all: label_image.manifest.sgx label_image.sig 26 | endif 27 | 28 | ifeq ($(SGX),) 29 | GRAMINE = gramine-direct 30 | else 31 | GRAMINE = gramine-sgx 32 | endif 33 | 34 | $(TF_DIR)/configure: 35 | ../common_tools/download --output tensorflow.tar.gz --sha256 $(TAR_SHA256)\ 36 | --url https://github.com/tensorflow/tensorflow/archive/$(GIT_COMMIT).tar.gz 37 | mkdir $(TF_DIR) 38 | tar -C $(TF_DIR) --strip-components=1 -xf tensorflow.tar.gz 39 | 40 | $(TF_DIR)/bazel-bin/tensorflow/contrib/lite/examples/label_image/label_image: $(TF_DIR)/configure 41 | cd $(TF_DIR) && $(BAZEL_BIN) build tensorflow/contrib/lite/examples/label_image 42 | 43 | label_image: $(TF_DIR)/bazel-bin/tensorflow/contrib/lite/examples/label_image/label_image 44 | cp $^ . 45 | 46 | libtensorflow_framework.so: label_image 47 | cp $(TF_DIR)/bazel-bin/tensorflow/libtensorflow_framework.so $@ 48 | 49 | INCEPTION_HASH=b1a1f91276e48a9ddf0cb0d854f044ebfbf985dc2c2cedceb52b3d668894299a 50 | inception_v3.tflite: 51 | ../common_tools/download --output inception_v3_2018_04_27.tgz --sha256 $(INCEPTION_HASH)\ 52 | --url https://storage.googleapis.com/download.tensorflow.org/models/tflite/model_zoo/upload_20180427/inception_v3_2018_04_27.tgz 53 | tar xfz inception_v3_2018_04_27.tgz 54 | 55 | labels.txt: $(TF_DIR)/tensorflow/contrib/lite/java/ovic/src/testdata/labels.txt 56 | cp $^ $@ 57 | 58 | image.bmp: $(TF_DIR)/tensorflow/contrib/lite/examples/label_image/testdata/grace_hopper.bmp 59 | cp $^ $@ 60 | 61 | label_image.manifest: label_image.manifest.template libtensorflow_framework.so label_image \ 62 | inception_v3.tflite labels.txt image.bmp 63 | gramine-manifest \ 64 | -Dlog_level=$(GRAMINE_LOG_LEVEL) \ 65 | -Darch_libdir=$(ARCH_LIBDIR) \ 66 | $< > $@ 67 | 68 | # Make on Ubuntu <= 20.04 doesn't support "Rules with Grouped Targets" (`&:`), 69 | # for details on this workaround see 70 | # https://github.com/gramineproject/gramine/blob/e8735ea06c/CI-Examples/helloworld/Makefile 71 | label_image.manifest.sgx label_image.sig: sgx_sign 72 | @: 73 | 74 | .INTERMEDIATE: sgx_sign 75 | sgx_sign: label_image.manifest 76 | gramine-sgx-sign \ 77 | --manifest $< \ 78 | --output $<.sgx 79 | 80 | .PHONY: check 81 | check: all 82 | $(GRAMINE) ./label_image -m inception_v3.tflite -i image.bmp -t 4 83 | 84 | .PHONY: run-native 85 | run-native: all 86 | ./label_image -m inception_v3.tflite -i image.bmp -t 4 87 | 88 | .PHONY: run-gramine 89 | run-gramine: all 90 | $(GRAMINE) ./label_image -m inception_v3.tflite -i image.bmp -t 4 91 | 92 | .PHONY: clean 93 | clean: 94 | $(RM) label_image.manifest label_image.manifest.sgx label_image.sig label_image.token 95 | 96 | .PHONY: distclean 97 | distclean: clean 98 | $(RM) -r label_image 99 | $(RM) inception_v3_2018_04_27.tgz inception_v3.pb inception_v3.tflite labels.txt image.bmp 100 | $(RM) -r $(TF_DIR) tensorflow.tar.gz libtensorflow_framework.so bazel-*-installer-linux-*.sh 101 | 102 | BAZEL_INSTALLER_HASH=17ab70344645359fd4178002f367885e9019ae7507c9c1ade8220f3628383444 103 | .PHONY: install-dependencies-ubuntu 104 | install-dependencies-ubuntu: 105 | apt-get update 106 | apt-get install -y python-dev python-pip wget git 107 | # https://docs.bazel.build/versions/master/install-ubuntu.html 108 | apt-get install -y pkg-config zip g++ zlib1g-dev unzip python 109 | ../common_tools/download --output bazel-0.16.1-installer-linux-x86_64.sh --sha256 $(BAZEL_INSTALLER_HASH)\ 110 | --url https://github.com/bazelbuild/bazel/releases/download/0.16.1/bazel-0.16.1-installer-linux-x86_64.sh 111 | chmod +x bazel-0.16.1-installer-linux-x86_64.sh 112 | ./bazel-0.16.1-installer-linux-x86_64.sh --user 113 | 114 | .PHONY: install-dependencies-fedora 115 | install-dependencies-fedora: 116 | dnf -y install python3-devel python3-pip wget git pkg-config zip gcc-g++ zlib-devel unzip 117 | ../common_tools/download --output bazel-0.16.1-installer-linux-x86_64.sh --sha256 $(BAZEL_INSTALLER_HASH)\ 118 | --url https://github.com/bazelbuild/bazel/releases/download/0.16.1/bazel-0.16.1-installer-linux-x86_64.sh 119 | chmod +x bazel-0.16.1-installer-linux-x86_64.sh 120 | ./bazel-0.16.1-installer-linux-x86_64.sh --user 121 | -------------------------------------------------------------------------------- /tensorflow-lite/README.md: -------------------------------------------------------------------------------- 1 | # TensorFlow Lite 2 | 3 | This example demonstrates how to run TensorFlow Lite v1.9. In particular, the 4 | example runs `label_image` program on Gramine. It reads an input image 5 | `image.bmp` from the current directory and uses TensorFlow Lite and the 6 | Inception v3 model to label the image. 7 | 8 | To install build dependencies on Ubuntu there is a convenience target invoked 9 | with `make install-dependencies-ubuntu`. This also serves as a starting point to 10 | figure out which packages to install on newer releases of Ubuntu. 11 | 12 | # Quick Start 13 | 14 | To build TensorFlow Lite and Gramine artifacts: 15 | - without SGX do `make` 16 | - with SGX do `make SGX=1 ` 17 | 18 | To run the image labeling example: 19 | - without Gramine do `make run-native` 20 | - with Gramine do `make run-gramine` 21 | - with Gramine-SGX do `make SGX=1 run-gramine` 22 | -------------------------------------------------------------------------------- /tensorflow-lite/label_image.manifest.template: -------------------------------------------------------------------------------- 1 | # Copyright (C) 2024 Gramine contributors 2 | # SPDX-License-Identifier: BSD-3-Clause 3 | 4 | # TensorFlow Lite example 5 | 6 | libos.entrypoint = "label_image" 7 | 8 | loader.log_level = "{{ log_level }}" 9 | 10 | loader.env.LD_LIBRARY_PATH = "/lib:{{ arch_libdir }}:/usr/{{ arch_libdir }}:." 11 | loader.env.PATH = "/bin:/usr/bin" 12 | 13 | loader.insecure__use_cmdline_argv = true 14 | 15 | fs.mounts = [ 16 | { uri = "file:{{ gramine.runtimedir() }}", path = "/lib" }, 17 | { uri = "file:{{ arch_libdir }}", path = "{{ arch_libdir }}" }, 18 | { uri = "file:/usr/{{ arch_libdir }}", path = "/usr/{{ arch_libdir }}" }, 19 | ] 20 | 21 | sgx.enclave_size = "2G" 22 | sgx.max_threads = {{ '1' if env.get('EDMM', '0') == '1' else '16' }} 23 | sgx.edmm_enable = {{ 'true' if env.get('EDMM', '0') == '1' else 'false' }} 24 | 25 | sgx.trusted_files = [ 26 | "file:label_image", 27 | "file:{{ gramine.runtimedir() }}/", 28 | "file:{{ arch_libdir }}/", 29 | "file:/usr/{{ arch_libdir }}/", 30 | "file:libtensorflow_framework.so", 31 | "file:inception_v3.tflite", 32 | "file:labels.txt", 33 | ] 34 | 35 | sgx.allowed_files = [ 36 | "file:image.bmp", 37 | ] 38 | --------------------------------------------------------------------------------