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

Python3 migration & Emscripten update #133

Merged
merged 17 commits into from
Feb 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/workflows/build-dev.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: build-dev

on:
push:
branches:
- dev
- master
paths:
- 'src/python/requirements.txt'
albincorreya marked this conversation as resolved.
Show resolved Hide resolved
- 'build-libs.sh'
- 'Dockerfile'
- 'Makefile'
pull_request:
branches:
- dev
- master
paths:
- 'src/python/requirements.txt'
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

- 'build-libs.sh'
- 'Dockerfile'
- 'Makefile'
types:
- opened
- edited
- synchronize
- reopened

jobs:
build:
runs-on: ubuntu-latest
steps:
- name: Checkout close
uses: actions/checkout@v2
- name: Build new Docker image
working-directory: ${{ github.workspace }}
run: docker build -t mtgupf/essentia-emscripten:dev .
- name: Build library
working-directory: ${{ github.workspace }}
run: |
docker run --rm -v `pwd`:/essentia/ mtgupf/essentia-emscripten:dev /essentia/build-libs.sh
shell: bash

# unit-test:
2 changes: 1 addition & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
# - 'test/**'
- 'build-libs.sh'
- 'Dockerfile'
- 'Makefile.essentiajs'
- 'Makefile'
- 'rollup*.js'
- 'tsconfig.json'
- '!docs/**'
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/integration.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ on:
# - 'test/**'
- 'build-libs.sh'
- 'Dockerfile'
- 'Makefile.essentiajs'
- 'Makefile'
- 'rollup*.js'
- 'tsconfig.json'
- '!docs/**'
Expand All @@ -24,7 +24,7 @@ on:
# - 'test/**'
- 'build-libs.sh'
- 'Dockerfile'
- 'Makefile.essentiajs'
- 'Makefile'
- 'rollup*.js'
- 'tsconfig.json'
- '!docs/**'
Expand Down
16 changes: 8 additions & 8 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
ARG EMSCRIPTEN_VERSION=1.39.19
ARG EMSCRIPTEN_VERSION=3.1.24
FROM emscripten/emsdk:${EMSCRIPTEN_VERSION}

ENV LANG C.UTF-8

# compile essentia with emscripten and selected third-party dependencies
RUN apt-get update \
&& apt-get install -y cmake curl nano python-dev python-numpy-dev libpython2.7 python-pip libeigen3-dev \
&& apt-get install -y cmake curl nano python3-dev python3-numpy-dev python3-numpy python3-yaml python3-six libeigen3-dev python3-pip \
&& mkdir /essentia && cd /essentia && git clone https://github.com/MTG/essentia.git \
&& cd /essentia/essentia/packaging/debian_3rdparty \
&& bash -C "./build_eigen3.sh" && cd ../../ && chmod +x waf \
&& emconfigure sh -c './waf configure --prefix=$EMSCRIPTEN/system/local/ --build-static --fft=KISS --emscripten --static-dependencies' \
&& emmake ./waf && emmake ./waf install \
&& apt-get remove -y python-dev libeigen3-dev \
&& emconfigure sh -c 'python3 waf configure --prefix=$EMSCRIPTEN/system/local/ --build-static --fft=KISS --emscripten --static-dependencies' \
&& emmake python3 waf && emmake python3 waf install \
&& apt-get remove -y python3-dev libeigen3-dev \
&& apt-get autoremove -y \
&& apt-get clean -y \
&& rm -rf /var/lib/apt/lists/* \
&& cd / && rm -rf /essentia/essentia

# copy and install python dependencies
COPY src/python/requirements.txt /tmp/requirements.txt
RUN pip install --upgrade setuptools \
&& pip install --no-cache-dir -r /tmp/requirements.txt \
RUN pip3 install --upgrade setuptools \
&& pip3 install --no-cache-dir -r /tmp/requirements.txt \
&& rm /tmp/requirements.txt

# add latest eigen3 header files for linking the essentia.js binding builds
Expand All @@ -30,6 +30,6 @@ RUN wget -P /usr/local/include/ "https://gitlab.com/libeigen/eigen/-/archive/3.
&& rm -f eigen-${EIGEN_VERSION}.tar.gz && mv eigen-${EIGEN_VERSION} eigen3

ENV EIGEN_PATH /usr/local/include/eigen3
ENV EMSCRIPTEN /emsdk/upstream/emscripten
ENV EMSCRIPTEN /emsdk/upstream/emscripten

WORKDIR /essentia/
31 changes: 12 additions & 19 deletions Makefile.essentiajs → Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
ESSENTIAJS_VERSION=0.1.3
## Path to libs for Emscripten
LIB_DIR_ESSENTIA=$(EMSCRIPTEN)/system/local/lib
INCLUDE_DIR_ESSENTIA=$(EMSCRIPTEN)/system/local/include
EIGEN_PATH=/usr/local/include/eigen3
## Pass custom build and dist directories using system environment variables
BUILD_DIR_ES := $(or $(ESSENTIAJS_WASM_BUILDS_DIR),builds)
Expand All @@ -22,25 +23,18 @@ POST_JS_UMD_WASM=src/js/wasm.umd.post.js

codegen:
@echo "Generating cpp source code from essentia python bindings ..."
@cd src/python && python configure_bindings.py
@cd src/python && python3 configure_bindings.py

build:
@mkdir -p $(BUILD_DIR_ES)

@echo "Compiling the emscripten embind cpp bindings to bitcode ..."
@echo "Compiling + linking emscripten embind cpp bindings directly to js, wasm files ..."

@emcc -I $(EIGEN_PATH) \
--bind -Oz $(BINDING_ESSENTIAJS) $(INCLUDE_ESSENTIAJS) \
-o $(BUILD_DIR_ES)/essentiajs.bc \
-s EXCEPTION_DEBUG \
-s ASSERTIONS=2 \
-s DISABLE_EXCEPTION_CATCHING=2 || exit 1
@echo "Done ..."

@echo "Linking and compiling the bindings with essentia to js, wasm files ..."
@echo "compiling async builds..."
@emcc --bind -Oz $(BUILD_DIR_ES)/essentiajs.bc ${LIB_DIR_ESSENTIA}/essentia.a \
-s WASM=1 \
@echo "... compiling async builds..."
@emcc -lembind -Oz $(BINDING_ESSENTIAJS) $(INCLUDE_ESSENTIAJS) \
-lembind -lessentia -L $(LIB_DIR_ESSENTIA) \
-I $(EIGEN_PATH) -I $(INCLUDE_DIR_ESSENTIA)\
-s WASM=1 \
-o $(ESSENTIA_JS_WEB) \
-s EXCEPTION_DEBUG \
-s ASSERTIONS=2 \
Expand All @@ -51,8 +45,10 @@ build:
-s ALLOW_MEMORY_GROWTH=1 || exit 1
@echo "Done ..."

@echo "compiling sync builds..."
@emcc --bind -Oz $(BUILD_DIR_ES)/essentiajs.bc ${LIB_DIR_ESSENTIA}/essentia.a \
@echo "... compiling sync builds..."
@emcc --bind -Oz $(BINDING_ESSENTIAJS) $(INCLUDE_ESSENTIAJS) \
-lembind -lessentia -L $(LIB_DIR_ESSENTIA) \
-I $(EIGEN_PATH) -I $(INCLUDE_DIR_ESSENTIA)\
-s WASM=1 \
-o $(ESSENTIA_JS_MODULE) \
-s BINARYEN_ASYNC_COMPILATION=0 \
Expand All @@ -78,9 +74,6 @@ build:

@echo "Done ..."

@echo "Removing unnecessary files ..."
@rm $(BUILD_DIR_ES)/essentiajs.bc

@echo "Builds ..."
@ls $(BUILD_DIR_ES)

Expand Down
18 changes: 9 additions & 9 deletions build-libs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,26 @@ set -e -x
# Custom path to the node installation in the essentia-emscripten docker image
# provided along with emsdk. This can be removed once the
# entrypoint issues in the essentia-emscripten docker image got resolved.
NPM_PATH=/emsdk/node/12.18.1_64bit/bin/npm
NODE_PATH=/emsdk/node/12.18.1_64bit/bin/node
# NPM_PATH=/emsdk/node/12.18.1_64bit/bin/npm
# NODE_PATH=/emsdk/node/12.18.1_64bit/bin/node
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we can remove these comments if the entrypoint issues are resolved

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes, I didn't find any issues with the latest emscripten base docker image

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

However I can see the CI build workflow failing because it grabs the pre-built docker image from Docker Hub, so the change to the newer emscripten version is not reflected on the CI workflow.
I wonder if there is a way to build the image from the Dockerfile on the github CI workflow for these changes to the build pipeline instead of grabbing from Docker Hub...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's definitely possible to build the Docker image in a GitHub workflow, but I should create a new build-dev workflow for when we commit changes to the Dockerfile itself and the other build scripts.

I can do that on this PR to ensure that the other changes result in a successful build process.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have done this now and checks are passing. I would remove the files being watched on the new "build-dev" workflow from the other two workflows (integration.yml and deploy.yml), let me know what you think about that @albincorreya

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job! We could remove these comments in build-libs.sh since it is not needed anymore?

# set permission
ln -sf $NODE_PATH /usr/bin/node
# ln -sf $NODE_PATH /usr/bin/node

# Generate Essentia.js source code from Essentia docs
$NPM_PATH run gen-code
npm run gen-code

# Build Essentia WASM backend
$NPM_PATH run build-wasm
npm run build-wasm

# Install essentia.js node dependecies
$NPM_PATH install
npm install

# Build essentia.js JS API and add-on modules
$NPM_PATH run build-js-api
npm run build-js-api

# Minified build of JS API and add-on modules
$NPM_PATH run build-js-api rollup.config.min.js
npm run build-js-api rollup.config.min.js

# Run tests
echo "Running tests ..."
$NPM_PATH test
npm test
4 changes: 2 additions & 2 deletions docs/tutorials/4. Building from source.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ You need to have a local installation of docker.
docker run --rm -v `pwd`:/srv/workspace/ \
mtgupf/essentia-emscripten:latest \
/srv/workspace/build-bindings.sh \
Makefile.essentiajs
Makefile
```

OR
Expand Down Expand Up @@ -101,7 +101,7 @@ OR
Spawn a subshell inside the emscripten `emconfigure` in order to properlly access the emscripten variables.

```bash
emconfigure sh -c './build-bindings.sh Makefile.essentiajs'
emconfigure sh -c './build-bindings.sh Makefile'
```

> Note: make you added the emscripten env variables to your bash profile.
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
"CHANGELOG.md"
],
"scripts": {
"gen-code": "make -f Makefile.essentiajs codegen",
"build-wasm": "make -f Makefile.essentiajs build",
"gen-code": "make -f Makefile codegen",
"build-wasm": "make -f Makefile build",
"build-js-api": "rollup --config",
"build-api-docs": "./build-docs.sh",
"test": "mocha"
Expand Down
2 changes: 1 addition & 1 deletion src/python/bindings.cog
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ EMSCRIPTEN_BINDINGS(CLASS_EssentiaJS) {
/*[[[cog
import logging
import cog
from .code_generator import TO_INCLUDE_ALGOS
from code_generator import TO_INCLUDE_ALGOS
logging.basicConfig(level='INFO')
logging.info("Generating emscripten bindings for the essentia...")
for algo_name in TO_INCLUDE_ALGOS:
Expand Down
3 changes: 3 additions & 0 deletions src/python/configure_bindings.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# -*- coding: utf-8 -*-
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume we will migrate these old python2 scripts to python3 after fixing the build pipeline?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as above, my intention is to do it on this PR
I think all scripts now are compatible with Python 3, but let me know if you see anything that should clearly be changed

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like code_generator.py script has python2 string formatting, not sure if python3 supports that? maybe I missed something here

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@albincorreya I see what you mean. It seems that modulo string formatting still works in Python3, although f-strings are the preferred syntax. If it's okay with you, I think it makes sense to do the switch to f-strings on the code_generator.py script on the object-oriented PR that I'm working on, because that will already change significant portions of the script.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jmarcosfer make sense, let's merge this then 💯

from __future__ import print_function
from builtins import str
import os
import argparse
import essentia.standard as estd
Expand Down Expand Up @@ -30,6 +32,7 @@ def savelist_to_file(path_list, filename):
# requires Gaia and Tensorflow dependencies
'GaiaTransform', 'MusicExtractorSVM',
'TensorflowPredict', 'TensorflowPredictMusiCNN', 'TensorflowPredictVGGish',
'TensorNormalize', 'TensorTranspose',
# these algortihms expect a matrix_real input or output types which are not yet supported for the JS bindings
'BpmHistogram', 'FadeDetection', 'HumDetector', 'Onsets', 'Panning', 'SBic', 'SingleGaussian',
# these algorithms expect std::complex** type for wither input, parameters or outputs, which are not yet supported for the JS bindings
Expand Down
2 changes: 2 additions & 0 deletions src/python/excluded_algos.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ MusicExtractorSVM
TensorflowPredict
TensorflowPredictMusiCNN
TensorflowPredictVGGish
TensorNormalize
TensorTranspose
BpmHistogram
FadeDetection
HumDetector
Expand Down
2 changes: 1 addition & 1 deletion src/python/header.cog
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class EssentiaJS {
// NOTE: The following code snippets are machine generated. Do not edit.
/*[[[cog
import cog
from .code_generator import generate_headers, TO_INCLUDE_ALGOS
from code_generator import generate_headers, TO_INCLUDE_ALGOS
cog.outl(" ")
cog.outl("// class property which stores all the list of essentia algorithm names available in essentia.js")
c_algo_list = str(TO_INCLUDE_ALGOS)
Expand Down
1 change: 1 addition & 0 deletions src/python/included_algos.md
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ TempoTapDegara
TempoTapMaxAgreement
TempoTapTicks
TensorflowInputMusiCNN
TensorflowInputTempoCNN
TensorflowInputVGGish
TonalExtractor
TonicIndianArtMusic
Expand Down
2 changes: 1 addition & 1 deletion src/python/js_wrapper.cog
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ class Essentia {
// NOTE: The following code snippets are machine generated. Do not edit.
/*[[[cog
import cog
from .code_generator import generate_typescript_wrapper
from code_generator import generate_typescript_wrapper
algos = generate_typescript_wrapper()
for algo in algos:
for ln in algo:
Expand Down
2 changes: 1 addition & 1 deletion src/python/library.cog
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ val EssentiaJS::LoudnessEBUR128(std::vector<float>& left_channel, std::vector<fl
// NOTE: The following code snippets are machine generated. Do not edit.
/*[[[cog
import cog
from .code_generator import generate_algorithms
from code_generator import generate_algorithms
algos = generate_algorithms()
for algo in algos:
for ln in algo:
Expand Down
Loading