Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

python: PyPerf: Aarch64 support #287

Draft
wants to merge 39 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
50d09fd
wip
Jongy Jan 29, 2022
4c66f63
python: Allow PyPerf on aarch64
Jongy Jan 31, 2022
c5937a6
wip update bpf helpers to aarch64 revisions
Jongy Jan 31, 2022
76eba37
wip
Jongy Jan 31, 2022
f4151dc
more aarch64 fixes
Jongy Jan 31, 2022
e666923
.
Jongy Jan 31, 2022
d5cdcd8
.
Jongy Jan 31, 2022
0c858d5
Add -DENABLE_LLVM_SHARED=1
Jongy Feb 1, 2022
de1ccf4
upgrade bcc
Jongy Feb 1, 2022
3e6c9b7
.
Jongy Feb 1, 2022
ff06bb1
fix llvm versioning
Jongy Feb 1, 2022
2f9d880
wip
Jongy Feb 1, 2022
9de406b
wip
Jongy Feb 1, 2022
99b12f4
wip
Jongy Feb 1, 2022
bcf3274
wip
Jongy Feb 1, 2022
1ae2954
wip
Jongy Feb 1, 2022
e5b3f32
wip
Jongy Feb 1, 2022
a42596c
wip
Jongy Feb 1, 2022
d86dfb0
pyperf verbose
Jongy Feb 2, 2022
a0f8d6a
wip
Jongy Feb 2, 2022
69dbff0
wip
Jongy Feb 2, 2022
c0677d2
wip
Jongy Feb 2, 2022
6db367d
wip
Jongy Feb 3, 2022
af42724
wip
Jongy Feb 4, 2022
118f411
wip
Jongy Feb 4, 2022
21a0368
Merge remote-tracking branch 'origin/master' into pyperf-aarch64
Jongy Oct 16, 2022
9a0e53b
remove x86_64 reference
Jongy Oct 16, 2022
8d4b368
Merge remote-tracking branch 'origin/master' into pyperf-aarch64
Jongy Nov 29, 2022
7792920
builds again
Jongy Nov 29, 2022
2adb7eb
fixes
Jongy Nov 29, 2022
2e036d7
update rev
Jongy Nov 29, 2022
29c209d
fix
Jongy Nov 29, 2022
890c56a
fix shellcheck
Jongy Nov 30, 2022
6ae66d1
test update granulate-utils
Jongy Nov 30, 2022
d182212
Merge remote-tracking branch 'origin/master' into pyperf-aarch64
Jongy Dec 16, 2022
c0d3d99
update build
Jongy Dec 17, 2022
ebbe830
update
Jongy Dec 17, 2022
8b334f7
wip
Jongy Dec 17, 2022
bbd17d1
Update pyi.Dockerfile
Jongy Dec 17, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 17 additions & 21 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -84,22 +84,21 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends \
git \
ca-certificates \
&& \
if [ "$(uname -m)" != "aarch64" ]; then \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
build-essential \
iperf llvm-9-dev \
libclang-9-dev \
cmake \
python3 \
flex \
libfl-dev \
bison \
libelf-dev \
libz-dev \
liblzma-dev; \
fi
&& \
DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \
curl \
build-essential \
iperf \
llvm-9-dev \
libclang-9-dev \
cmake \
python3 \
flex \
libfl-dev \
bison \
libelf-dev \
libz-dev \
liblzma-dev;

# bcc helpers
FROM bcc-builder-base AS bcc-helpers
Expand All @@ -118,15 +117,12 @@ FROM bcc-builder-base AS bcc-builder
WORKDIR /tmp

COPY ./scripts/libunwind_build.sh .
RUN if [ "$(uname -m)" = "aarch64" ]; then \
exit 0; \
fi && \
./libunwind_build.sh
RUN ./libunwind_build.sh

WORKDIR /bcc

COPY ./scripts/pyperf_build.sh .
RUN ./pyperf_build.sh
RUN ./pyperf_build.sh container

# phpspy
FROM ubuntu${PHPSPY_BUILDER_UBUNTU} AS phpspy-builder
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -395,7 +395,7 @@ The runtime stacks are then merged into the data collected by `perf`, substituti
| perf (native, Golang, ...) | :heavy_check_mark: | :heavy_check_mark: |
| Java (async-profiler) | :heavy_check_mark: | :heavy_check_mark: |
| Python (py-spy) | :heavy_check_mark: | :heavy_check_mark: |
| Python (PyPerf eBPF) | :heavy_check_mark: | :x: |
| Python (PyPerf eBPF) | :heavy_check_mark: | :heavy_check_mark: (experimental) |
| Ruby (rbspy) | :heavy_check_mark: | :heavy_check_mark: |
| PHP (phpspy) | :heavy_check_mark: | :heavy_check_mark: (experimental) |
| NodeJS (perf) | :heavy_check_mark: | :heavy_check_mark: |
Expand Down
8 changes: 2 additions & 6 deletions gprofiler/profilers/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@
from gprofiler.metadata import application_identifiers
from gprofiler.metadata.application_metadata import ApplicationMetadata
from gprofiler.metadata.py_module_version import get_modules_versions
from gprofiler.metadata.system_metadata import get_arch
from gprofiler.platform import is_linux, is_windows
from gprofiler.profilers.profiler_base import ProfilerInterface, SpawningProcessProfilerBase
from gprofiler.profilers.registry import ProfilerArgument, register_profiler
Expand Down Expand Up @@ -295,9 +294,6 @@ def _should_skip_process(self, process: Process) -> bool:
# py-spy is like pyspy, it's confusing and I mix between them
possible_modes=["auto", "pyperf", "pyspy", "py-spy", "disabled"],
default_mode="auto",
# we build pyspy for both, pyperf only for x86_64.
# TODO: this inconsistency shows that py-spy and pyperf should have different Profiler classes,
# we should split them in the future.
supported_archs=["x86_64", "aarch64"],
supported_windows_archs=["AMD64"],
profiler_mode_argument_help="Select the Python profiling mode: auto (try PyPerf, resort to py-spy if it fails), "
Expand Down Expand Up @@ -348,9 +344,9 @@ def __init__(

assert python_mode in ("auto", "pyperf", "pyspy"), f"unexpected mode: {python_mode}"

if get_arch() != "x86_64" or is_windows():
if is_windows():
if python_mode == "pyperf":
logger.warning("PyPerf is supported only on x86_64, falling back to py-spy")
logger.warning("PyPerf is supported only on Linux, falling back to py-spy")
python_mode = "pyspy"

if python_mode in ("auto", "pyperf"):
Expand Down
75 changes: 32 additions & 43 deletions pyi.Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -125,18 +125,14 @@ USER 1001
FROM ubuntu${PYPERF_BUILDER_UBUNTU} AS bcc-helpers
WORKDIR /tmp

RUN if [ "$(uname -m)" = "aarch64" ]; then \
exit 0; \
fi && \
apt-get update && \
apt-get install -y --no-install-recommends \
clang-10 \
libelf-dev \
make \
build-essential \
llvm \
ca-certificates \
git
RUN apt-get update && apt-get install -y --no-install-recommends \
clang-10 \
libelf-dev \
make \
build-essential \
llvm \
ca-certificates \
git

COPY --from=perf-builder /bpftool /bpftool

Expand Down Expand Up @@ -177,53 +173,45 @@ RUN ./python310_build.sh
# TODO: copied from the main Dockerfile... but modified a lot. we'd want to share it some day.

RUN yum install -y git && yum clean all

WORKDIR /bcc
# these are needed to build PyPerf, which we don't build on Aarch64, hence not installing them here.
RUN if [ "$(uname -m)" = "aarch64" ]; then exit 0; fi; yum install -y \

# these are needed to build PyPerf
RUN yum install -y \
curl \
cmake \
patch \
flex \
bison \
zlib-devel.x86_64 \
zlib-devel \
xz-devel \
ncurses-devel \
elfutils-libelf-devel && \
yum clean all

RUN if [ "$(uname -m)" = "aarch64" ]; \
then exit 0; \
fi && \
yum install -y centos-release-scl-rh && \
yum clean all
RUN yum install -y centos-release-scl-rh && yum clean all
# mostly taken from https://github.com/iovisor/bcc/blob/master/INSTALL.md#install-and-compile-llvm
RUN if [ "$(uname -m)" = "aarch64" ]; \
then exit 0; \
fi && \
yum install -y devtoolset-8 \
llvm-toolset-7 \
llvm-toolset-7-llvm-devel \
llvm-toolset-7-llvm-static \
llvm-toolset-7-clang-devel \
devtoolset-8-elfutils-libelf-devel && \
# on x86_64, the package is named llvm-toolset-7. on aarch64, it is named llvm-toolset-7.0...
RUN if [ "$(uname -m)" = "aarch64" ]; then v="7.0"; else v="7"; fi; yum install -y devtoolset-8 \
llvm-toolset-$v \
llvm-toolset-$v-llvm-devel \
llvm-toolset-$v-llvm-static \
llvm-toolset-$v-clang-devel \
devtoolset-8-elfutils-libelf-devel && \
yum clean all

COPY ./scripts/libunwind_build.sh .
# hadolint ignore=SC1091
RUN if [ "$(uname -m)" = "aarch64" ]; then \
exit 0; \
fi && \
source scl_source enable devtoolset-8 && \
RUN source scl_source enable devtoolset-8 && \
./libunwind_build.sh

WORKDIR /bcc

COPY ./scripts/pyperf_build.sh .
# hadolint ignore=SC1091
RUN set -e; \
if [ "$(uname -m)" != "aarch64" ]; then \
source scl_source enable devtoolset-8 llvm-toolset-7; \
fi && \
source ./pyperf_build.sh

RUN if [ "$(uname -m)" = "aarch64" ]; then v="7.0"; else v="7"; fi && \
source scl_source enable devtoolset-8 "llvm-toolset-$v" && \
source ./pyperf_build.sh exe
# gProfiler part

WORKDIR /app
Expand All @@ -240,11 +228,13 @@ RUN set -e; \
yum install -y glibc-static zlib-devel.aarch64 && \
yum clean all; \
fi
# needed for aarch64, scons & wheel are needed to build staticx

RUN set -e; \
if [ "$(uname -m)" = "aarch64" ]; then \
ln -s /usr/lib64/python3.10/lib-dynload /usr/lib/python3.10/lib-dynload; \
fi

# needed for aarch64, scons & wheel are needed to build staticx
RUN set -e; \
if [ "$(uname -m)" = "aarch64" ]; then \
python3 -m pip install --no-cache-dir 'wheel==0.37.0' 'scons==4.2.0'; \
Expand Down Expand Up @@ -339,9 +329,8 @@ COPY ./scripts/list_needed_libs.sh ./scripts/list_needed_libs.sh
# using scl here to get the proper LD_LIBRARY_PATH set
# hadolint ignore=SC2046,SC2086
RUN set -e; \
if [ $(uname -m) != "aarch64" ]; then \
source scl_source enable devtoolset-8 llvm-toolset-7 ; \
fi && \
if [ $(uname -m) = "aarch64" ]; then v="7.0"; else v="7"; fi; \
source scl_source enable devtoolset-8 "llvm-toolset-$v" && \
LIBS=$(./scripts/list_needed_libs.sh) && \
staticx $LIBS dist/gprofiler dist/gprofiler

Expand Down
16 changes: 4 additions & 12 deletions scripts/bcc_helpers_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,19 @@
#
set -euo pipefail

# TODO support aarch64, after we support it in PyPerf
if [ "$(uname -m)" != "x86_64" ]; then
mkdir -p /bpf_get_fs_offset /bpf_get_stack_offset
touch /bpf_get_fs_offset/get_fs_offset
touch /bpf_get_stack_offset/get_stack_offset
exit 0
fi

LLVM_STRIP=llvm-strip
if ! command -v "$LLVM_STRIP" > /dev/null 2>&1 ; then
LLVM_STRIP=llvm-strip-10
fi

LIBBPF_MAKE_FLAGS="BPFTOOL=/bpftool CLANG=clang-10 LLVM_STRIP=$LLVM_STRIP CFLAGS=-static"

cd / && git clone -b v0.0.2 --depth=1 --recurse-submodules https://github.com/Jongy/bpf_get_fs_offset.git
cd /bpf_get_fs_offset && git reset --hard 8326d39cf44845d4b643ed4267994afca8ccecb3
cd / && git clone -b aarch64 --depth=1 --recurse-submodules https://github.com/Jongy/bpf_get_fs_offset.git
cd /bpf_get_fs_offset && git reset --hard 094e93f979308d46dffb8d4ea88823f68d53ba85
# shellcheck disable=SC2086
cd /bpf_get_fs_offset && make $LIBBPF_MAKE_FLAGS

cd / && git clone -b v0.0.3 --depth=1 --recurse-submodules https://github.com/Jongy/bpf_get_stack_offset.git
cd /bpf_get_stack_offset && git reset --hard 54b70ee65708cc8d3d7817277e82376d95205356
cd / && git clone -b aarch64 --depth=1 --recurse-submodules https://github.com/Jongy/bpf_get_stack_offset.git
cd /bpf_get_stack_offset && git reset --hard d8b77ce6da674c38ad0bb856686fde1e63ad0814
# shellcheck disable=SC2086
cd /bpf_get_stack_offset && make $LIBBPF_MAKE_FLAGS
20 changes: 10 additions & 10 deletions scripts/pyperf_build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
#
set -euo pipefail

git clone --depth 1 -b v1.2.6 https://github.com/Granulate/bcc.git && cd bcc && git reset --hard 6a995642d12287f26cbb97edd3d29e62a5fde337

# (after clone, because we copy the licenses)
# TODO support aarch64
if [ "$(uname -m)" != "x86_64" ]; then
mkdir -p /bcc/root/share/bcc/examples/cpp/
touch /bcc/root/share/bcc/examples/cpp/PyPerf
exit 0
fi
git clone --depth 1 -b aarch64 https://github.com/Granulate/bcc.git && cd bcc && git reset --hard 846228b6e3f244732783540e3e0b868271902e2d

mkdir build
cd build
cmake -DPYTHON_CMD=python3 -DINSTALL_CPP_EXAMPLES=y -DCMAKE_INSTALL_PREFIX=/bcc/root ..

SHARED_ARG=""
# need in aarch64 as mentioned here: https://github.com/iovisor/bcc/issues/3333#issuecomment-803432248
# container mdoe doesn't want it - we don't have the libs bundled.
# exe mode in x86_64 works fine so I don't change it.
if [ "$(uname -m)" = "aarch64" ] && [ "$1" == "exe" ]; then
SHARED_ARG=" -DENABLE_LLVM_SHARED=1"
fi
cmake -DPYTHON_CMD=python3 -DINSTALL_CPP_EXAMPLES=y -DCMAKE_INSTALL_PREFIX=/bcc/root "$SHARED_ARG" ..
make -C examples/cpp/pyperf -j -l VERBOSE=1 install