Skip to content

Commit f513e14

Browse files
authored
Tidy-up and latest CPython (#4)
* Removed libffi imports from this dir * Latest sysroot * Version bump * Typo * Small syntax fix * Fixing discrepancies in host interface calls * Refactor of runtime task * Add copying lib and includes to cpython build * Refactoring pyfaasm * Add faasm library to linking * Update tasks env * Removed use of special wasm interface library * Latest cpython * Latest cpython * Removed unused task * Fix for cpython copy missing dir * Sysroot version * Fix tests
1 parent 7e64f3d commit f513e14

File tree

11 files changed

+134
-93
lines changed

11 files changed

+134
-93
lines changed

.github/workflows/tests.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ jobs:
1212
if: github.event.pull_request.draft == false
1313
runs-on: ubuntu-20.04
1414
container:
15-
image: faasm/cpython:0.0.8
15+
image: faasm/cpython:0.0.9
1616
defaults:
1717
run:
1818
working-directory: /code/faasm-cpython
@@ -36,7 +36,7 @@ jobs:
3636
REDIS_QUEUE_HOST: redis
3737
REDIS_STATE_HOST: redis
3838
container:
39-
image: faasm/cpython:0.0.8
39+
image: faasm/cpython:0.0.9
4040
defaults:
4141
run:
4242
working-directory: /code/faasm-cpython

Dockerfile

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM faasm/cpp-sysroot:0.0.16
1+
FROM faasm/cpp-sysroot:0.0.18
22
ARG FAASM_CPYTHON_VERSION
33

44
RUN apt install -y \
@@ -26,7 +26,6 @@ RUN git clone \
2626
WORKDIR /code/faasm-cpython
2727
RUN git submodule update --init
2828

29-
3029
# Install pyfaasm natively
3130
RUN inv pyfaasm.native
3231

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This build cross-compiles CPython and a number of Python modules to WebAssembly
44
for use in [Faasm](https://github.com/faasm/faasm).
55

6-
It also provides a [small Python librar](pyfaasm/) which uses `ctypes` to
6+
It also provides a [small Python library](pyfaasm/) which uses `ctypes` to
77
support calls to the [Faasm host
88
interface](https://github.com/faasm/faasm/blob/master/docs/host_interface.md).
99

@@ -47,7 +47,7 @@ Several of the code changes to CPython and numpy were borrowed from
4747
This repo gets built as a container, `faasm/cpython`. If you want to release a
4848
new version, you can:
4949

50-
- Update the version in `VERSION` and `.env`
50+
- Update the version in `VERSION`, `.github` and `.env`
5151
- Commit to your branch
5252
- Check that the normal build works in CI
5353
- Run `inv git.tag`

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.0.8
1+
0.0.9

libffi.imports

Lines changed: 0 additions & 1 deletion
This file was deleted.

pyfaasm/pyfaasm/core.py

Lines changed: 61 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,62 +7,96 @@
77
# Faasm host interface:
88
# https://github.com/faasm/faasm/blob/master/include/faasm/host_interface.h
99

10-
HOST_INTERFACE_LIB = "libemulator.so"
11-
12-
SUPPORTING_LIBS = [
10+
NATIVE_SUPPORTING_LIBS = [
1311
"libpistache.so",
1412
"libfaabricmpi.so",
1513
]
1614

17-
HOST_INTERFACE_LIB = "libemulator.so"
18-
PYTHON_LOCAL_CHAINING = bool(os.environ.get("PYTHON_LOCAL_CHAINING"))
19-
PYTHON_LOCAL_OUTPUT = bool(os.environ.get("PYTHON_LOCAL_OUTPUT"))
15+
NATIVE_INTERFACE_LIB = "libemulator.so"
16+
17+
env_cache = dict()
2018

2119
input_data = None
2220
output_data = None
2321

2422
_host_interface = None
2523

2624

27-
def _init_host_interface():
28-
global _host_interface
25+
def get_env_bool(var_name):
26+
global env_cache
2927

30-
if _host_interface is None:
31-
# Load all supporting libs as globally linkable
32-
for lib in SUPPORTING_LIBS:
33-
ctypes.CDLL(lib, mode=ctypes.RTLD_GLOBAL)
28+
if var_name not in env_cache:
29+
value = os.environ.get(var_name)
30+
env_cache[var_name] = bool(value)
31+
32+
return env_cache[var_name]
33+
34+
35+
def set_env_bool(var_name, value):
36+
global env_cache
37+
env_cache[var_name] = value
38+
39+
40+
def is_wasm():
41+
return get_env_bool("PYTHONWASM")
42+
43+
44+
def is_local_chaining():
45+
return get_env_bool("PYTHON_LOCAL_CHAINING")
3446

35-
# Load main Faasm host interface lib
36-
_host_interface = ctypes.CDLL("libemulator.so")
37-
print("Loaded Faasm host interface: {}".format(_host_interface))
47+
48+
def is_local_output():
49+
return get_env_bool("PYTHON_LOCAL_OUTPUT")
3850

3951

4052
def set_local_chaining(value):
41-
global PYTHON_LOCAL_CHAINING
42-
PYTHON_LOCAL_CHAINING = value
53+
set_env_bool("PYTHON_LOCAL_CHAINING", value)
4354

4455

4556
def set_local_input_output(value):
46-
global PYTHON_LOCAL_OUTPUT
47-
PYTHON_LOCAL_OUTPUT = value
57+
set_env_bool("PYTHON_LOCAL_OUTPUT", value)
58+
59+
60+
def _init_host_interface():
61+
global _host_interface
62+
63+
if _host_interface is None:
64+
# Wasm and native environments are different
65+
if is_wasm():
66+
# Wasm expects the main application to handle the relevant calls
67+
_host_interface = ctypes.CDLL(None)
68+
else:
69+
# Load all supporting libs as globally linkable
70+
for lib in NATIVE_SUPPORTING_LIBS:
71+
ctypes.CDLL(lib, mode=ctypes.RTLD_GLOBAL)
72+
73+
# Load main Faasm host interface lib
74+
_host_interface = ctypes.CDLL(NATIVE_INTERFACE_LIB)
75+
76+
77+
def get_input_len():
78+
_init_host_interface()
79+
return _host_interface.__faasm_read_input(None, 0)
4880

4981

50-
def read_input():
82+
def read_input(input_len):
5183
_init_host_interface()
52-
return _host_interface.__faasm_read_input()
84+
input_len = int(input_len)
85+
buff = ctypes.create_string_buffer(input_len)
86+
return _host_interface.__faasm_read_input(buff, input_len)
5387

5488

5589
def write_output(output):
56-
if PYTHON_LOCAL_OUTPUT:
90+
if is_local_output():
5791
global output_data
5892
output_data = output
5993
else:
6094
_init_host_interface()
61-
_host_interface.__faasm_write_output(output)
95+
_host_interface.__faasm_write_output(output, len(output))
6296

6397

6498
def get_output():
65-
if PYTHON_LOCAL_OUTPUT:
99+
if is_local_output():
66100
global output_data
67101
return output_data
68102
else:
@@ -129,7 +163,7 @@ def pull_state(key, state_len):
129163

130164

131165
def chain(func, input_data):
132-
if PYTHON_LOCAL_CHAINING:
166+
if is_local_chaining():
133167
# Run function directly
134168
func(input_data)
135169
return 0
@@ -144,7 +178,7 @@ def chain(func, input_data):
144178

145179

146180
def await_call(call_id):
147-
if PYTHON_LOCAL_CHAINING:
181+
if is_local_chaining():
148182
# Calls are run immediately in local chaining
149183
return 0
150184
else:
@@ -156,7 +190,7 @@ def set_emulator_message(message_json):
156190
_init_host_interface()
157191

158192
message_bytes = bytes(message_json, "utf-8")
159-
if PYTHON_LOCAL_OUTPUT:
193+
if is_local_output():
160194
global output_data
161195
output_data = None
162196

pyfaasm/test/test_emulator.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
set_emulator_message,
77
get_output,
88
write_output,
9-
PYTHON_LOCAL_OUTPUT,
9+
is_local_output,
1010
)
1111

1212

@@ -16,7 +16,7 @@ class TestEmulator(unittest.TestCase):
1616
@classmethod
1717
def setUpClass(cls):
1818
# Check what local output already set to
19-
cls.original_local_output = PYTHON_LOCAL_OUTPUT
19+
cls.original_local_output = is_local_output()
2020

2121
@classmethod
2222
def tearDownClass(cls):

tasks/cpython.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
import os
2+
import shutil
23

34
from copy import copy
4-
from tasks.env import PROJ_ROOT, USABLE_CPUS
5+
from tasks.env import PROJ_ROOT, USABLE_CPUS, FAASM_RUNTIME_ROOT
56
from os.path import join, exists
67
from subprocess import run
78

8-
from faasmtools.build import build_config_cmd
9+
from faasmtools.build import build_config_cmd, WASM_LIB_INSTALL, WASM_SYSROOT
910

1011
from invoke import task
1112

@@ -39,6 +40,17 @@
3940
}
4041
)
4142

43+
WASM_INCLUDES_DIR = join(WASM_SYSROOT, "include")
44+
45+
LIB_SRC_DIR = join(INSTALL_DIR, "lib")
46+
LIB_DEST_DIR = join(FAASM_RUNTIME_ROOT, "lib")
47+
48+
LIBPYTHON_SRC_PATH = join(LIB_SRC_DIR, "libpython3.8.a")
49+
LIBPYTHON_DEST_PATH = join(WASM_LIB_INSTALL, "libpython3.8.a")
50+
51+
INCLUDE_SRC_DIR = join(INSTALL_DIR, "include", "python3.8")
52+
INCLUDE_DEST_DIR = join(WASM_INCLUDES_DIR, "python3.8")
53+
4254
# See the CPython docs for more info:
4355
# - General: https://devguide.python.org/setup/#compile-and-build
4456
# - Static builds: https://wiki.python.org/moin/BuildStatically
@@ -66,7 +78,7 @@ def build(ctx, clean=False, noconf=False, nobuild=False):
6678
# relevant in the module builds.
6779

6880
# Link in extra wasi-libc long double support (see wasi-libc docs)
69-
link_libs = "-lc-printscan-long-double"
81+
link_libs = "-lc-printscan-long-double -lfaasm"
7082

7183
# Configure
7284
configure_cmd = build_config_cmd(
@@ -100,3 +112,32 @@ def build(ctx, clean=False, noconf=False, nobuild=False):
100112
# Run specific install tasks (see cpython/Makefile)
101113
_run_cpython_cmd("commoninstall", ["make", "commoninstall"])
102114
_run_cpython_cmd("bininstall", ["make", "bininstall"])
115+
116+
# Prepare destinations
117+
os.makedirs(WASM_INCLUDES_DIR, exist_ok=True)
118+
os.makedirs(WASM_LIB_INSTALL, exist_ok=True)
119+
120+
shutil.rmtree(INCLUDE_DEST_DIR, ignore_errors=True)
121+
122+
print(
123+
"Copying libpython from {} to {}".format(
124+
LIBPYTHON_SRC_PATH, LIBPYTHON_DEST_PATH
125+
)
126+
)
127+
print(
128+
"Copying includes from {} to {}".format(
129+
INCLUDE_SRC_DIR, INCLUDE_DEST_DIR
130+
)
131+
)
132+
133+
shutil.copy(LIBPYTHON_SRC_PATH, LIBPYTHON_DEST_PATH)
134+
shutil.copytree(INCLUDE_SRC_DIR, INCLUDE_DEST_DIR)
135+
136+
os.makedirs(LIB_DEST_DIR, exist_ok=True)
137+
138+
print("Copying contents of {} to {}".format(LIB_SRC_DIR, LIB_DEST_DIR))
139+
run(
140+
"cp -r {}/* {}/".format(LIB_SRC_DIR, LIB_DEST_DIR),
141+
shell=True,
142+
check=True,
143+
)

tasks/env.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
from multiprocessing import cpu_count
22
from os.path import join, dirname, realpath
3+
from faasmtools.build import FAASM_LOCAL_DIR
34

45
PROJ_ROOT = dirname(dirname(realpath(__file__)))
56

67
THIRD_PARTY_DIR = join(PROJ_ROOT, "third-party")
78
CROSSENV_DIR = join(PROJ_ROOT, "cross_venv", "cross")
89

10+
FAASM_RUNTIME_ROOT = join(FAASM_LOCAL_DIR, "runtime_root")
11+
912
USABLE_CPUS = str(int(cpu_count()) - 1)
1013
VERSION_FILE = join(PROJ_ROOT, "VERSION")
1114

0 commit comments

Comments
 (0)