Skip to content
Snippets Groups Projects
Commit c0903e2a authored by Cyril Moineau's avatar Cyril Moineau
Browse files

Merge branch 'backend_export' into allowNoInputProducer

parents ba833c32 8173574a
No related branches found
No related tags found
3 merge requests!279v0.4.0,!253v0.4.0,!163Export refactor
Showing
with 465 additions and 1073 deletions
# general
.cache
# C++ Build # C++ Build
build*/ build*/
install*/ install*/
cppcheck-result.xml
# VSCode # VSCode
.vscode .vscode
# Python ## Python
# build/packaging artifacts
*.so *.so
__pycache__ __pycache__
*.pyc *.pyc
*.egg-info
dist*/ dist*/
*.egg-info
wheelhouse/*
aidge_core/_version.py
# test artifact
aidge_core/dummy_export/*
*xmlrunner-results.xml
# Mermaid # Mermaid
*.mmd *.mmd
...@@ -19,4 +29,4 @@ dist*/ ...@@ -19,4 +29,4 @@ dist*/
xml*/ xml*/
# ONNX # ONNX
*.onnx *.onnx
\ No newline at end of file
############################################################################### ###############################################################################
# Aidge Continious Integration and Continious Deployment # # Aidge Continuous Integration and Deployment #
# # # #
############################################################################### ###############################################################################
stages: stages:
# Analyse code
- static_analysis - static_analysis
# Build Aidge
- build - build
# Unit test stage
- test - test
# Code coverage
- coverage - coverage
- release
- deploy
include: include:
- local: '/.gitlab/ci/_global.gitlab-ci.yml' - project: 'eclipse/aidge/gitlab_shared_files'
- local: '/.gitlab/ci/static_analysis.gitlab-ci.yml' ref: 'main'
- local: '/.gitlab/ci/build.gitlab-ci.yml' file:
- local: '/.gitlab/ci/test.gitlab-ci.yml' # choose which jobs to run by including the corresponding files.
- local: '/.gitlab/ci/coverage.gitlab-ci.yml' - '.gitlab/ci/ubuntu_cpp.gitlab-ci.yml'
- '.gitlab/ci/ubuntu_python.gitlab-ci.yml'
- '.gitlab/ci/release/cibuildwheel_ubuntu.gitlab-ci.yml'
- '.gitlab/ci/windows_cpp.gitlab-ci.yml'
- '.gitlab/ci/windows_python.gitlab-ci.yml'
- '.gitlab/ci/release/cibuildwheel_windows.gitlab-ci.yml'
# Required bc of test_export that cannot run in parallel in test and in coverage
coverage:ubuntu_python:
needs:
- build:ubuntu_python
- test:ubuntu_python
################################################################################
# Centralized definitions of common job parameter values. #
# Parameters with many optional configurations may be in separate files. #
# #
################################################################################
variables:
GIT_SUBMODULE_STRATEGY: recursive
OMP_NUM_THREADS: 4
GIT_SSL_NO_VERIFY: 1
DEBIAN_FRONTEND: noninteractive
# See https://docs.gitlab.com/ee/ci/yaml/workflow.html#switch-between-branch-pipelines-and-merge-request-pipelines
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
when: never
- if: $CI_COMMIT_BRANCH
default:
image: nvidia/cuda:12.2.0-devel-ubuntu22.04
before_script:
- apt update
- apt install -y cmake cppcheck python-is-python3 pip git gcovr
build:ubuntu_cpp:
stage: build
needs: []
tags:
- docker
script:
- mkdir -p build_cpp
- mkdir -p install_cpp
- cd build_cpp
- cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=ON ..
- make -j4 all install
artifacts:
expire_in: 1 week
paths:
- build_cpp/
- install_cpp/
build:ubuntu_cpp_g++10:
stage: build
needs: []
tags:
- docker
script:
- apt install -y g++-10
- mkdir -p build_cpp
- mkdir -p install_cpp
- cd build_cpp
- export CXX=/usr/bin/g++-10
- cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=ON ..
- make -j4 all install
build:ubuntu_cpp_g++12:
stage: build
needs: []
tags:
- docker
script:
- apt install -y g++-12
- mkdir -p build_cpp
- mkdir -p install_cpp
- cd build_cpp
- export CXX=/usr/bin/g++-12
- cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=ON ..
- make -j4 all install
build:ubuntu_cpp_clang12:
stage: build
needs: []
tags:
- docker
script:
- apt install -y clang-12
- mkdir -p build_cpp
- mkdir -p install_cpp
- cd build_cpp
- export CXX=/usr/bin/clang++-12
- cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=ON ..
- make -j4 all install
build:ubuntu_cpp_clang15:
stage: build
needs: []
tags:
- docker
script:
- apt install -y clang-15
- mkdir -p build_cpp
- mkdir -p install_cpp
- cd build_cpp
- export CXX=/usr/bin/clang++-15
- cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug -DWERROR=ON -DCOVERAGE=ON ..
- make -j4 all install
build:ubuntu_python:
stage: build
needs: []
tags:
- docker
script:
- python3 -m pip install virtualenv
- virtualenv venv
- source venv/bin/activate
# Numpy dependancy for unit test
- python3 -m pip install -r requirements.txt
- python3 -m pip install .
artifacts:
expire_in: 1 week
paths:
- venv/
build:windows_cpp:
stage: build
needs: []
tags:
- windows
image: buildtools
before_script:
# Install Chocolatey
- Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
# Install dependencies
- choco install cmake.install --installargs '"ADD_CMAKE_TO_PATH=System"' -Y
- choco install git -Y
- choco install python -Y
# Update PATH
- $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
script:
- mkdir -p build_cpp
- mkdir -p install_cpp
- cd build_cpp
- cmake -DCMAKE_INSTALL_PREFIX:PATH=../install_cpp -DCMAKE_BUILD_TYPE=Debug ..
- cmake --build . -j2
- cmake --install . --config Debug
artifacts:
expire_in: 1 week
paths:
- build_cpp/
- install_cpp/
build:windows_python:
stage: build
needs: []
tags:
- windows
image: buildtools
before_script:
# Install Chocolatey
- Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
# Install dependencies
- choco install cmake.install --installargs '"ADD_CMAKE_TO_PATH=System"' -Y
- choco install git -Y
- choco install python -Y
# Update PATH
- $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
script:
- python -m pip install virtualenv
- virtualenv venv
- venv\Scripts\Activate.ps1
# Numpy dependancy for unit test
- python -m pip install -r requirements.txt
- python -m pip install .
artifacts:
expire_in: 1 week
paths:
- venv/
$ErrorActionPreference = "Stop"
# Retrieve and clean the dependencies string from the environment variable
$AIDGE_DEPENDENCIES = $env:AIDGE_DEPENDENCIES -split ' '
Write-Host "Aidge dependencies : $AIDGE_DEPENDENCIES"
if ( $($AIDGE_DEPENDENCIES.Length) -eq 0) {
Write-Host "- No dependencies provided for current repsitory"
New-Item -ItemType Directory -Force -Path ".\build" | Out-Null
Remove-Item -Path ".\build\*" -Recurse -Force
} else {
Write-Host "Retrieving given dependencies to build current package : $AIDGE_DEPENDENCIES"
foreach ($dep in $($AIDGE_DEPENDENCIES -split " ")) {
Write-Host "Retrieving : $dep"
$curr_loc=$(Get-Location)
Set-Location ../$dep
Get-Location
Get-ChildItem .
New-Item -Path ".\build" -ItemType Directory -Force | Out-Null
Get-ChildItem -Path ".\build" -File | Remove-Item -Force
python -m pip install . -v
Set-Location $curr_loc
}
}
#!/bin/bash
set -e
if [[ "$1" == "" ]]; then
echo "build aidge deps in cibuildwheel container before building wheel."
echo "search path defines where the dependencies will be searched."
echo "Hint : In wheel containers, files are mounted on /host by default."
echo "\nusage : ./cibuildwheel_build_deps_before_build_wheel.sh $search_path"
fi
set -x
if [[ $AIDGE_DEPENDENCIES == "" ]]; then # case for aidge_ core
mkdir -p build # creating build if its not already there to hold the build of cpp files
rm -rf build/* # build from scratch
else
for repo in $AIDGE_DEPENDENCIES ; do # case for other projects
search_path=$1
REPO_PATH=$(find $search_path ! -writable -prune -o -type d \
-name "$repo" \
-not -path "*/install/*" \
-not -path "*/.git/*" \
-not -path "*/miniconda/*" \
-not -path "*/conda/*" \
-not -path "*/.local/*" \
-not -path "*/lib/*" \
-not -path "*/$repo/$repo/*" \
-not -path "*/proc/*" \
-print -quit)
if [[ -z "$REPO_PATH" ]]; then
echo "ERROR : dependency $repo not found in search_path \"$search_path\". ABORTING."
exit -1
fi
cd $REPO_PATH
mkdir -p build # creating build if its not already there to hold the build of cpp files
rm -rf build/* # build from scratch
pip install . -v
cd -
done
fi
set +x
set +e
coverage:ubuntu_cpp:
stage: coverage
needs: ["build:ubuntu_cpp"]
tags:
- docker
script:
- cd build_cpp
- ctest --output-on-failure
- gcovr --xml-pretty --exclude-unreachable-branches --print-summary -o coverage.xml --root ${CI_PROJECT_DIR} --filter '\.\./include/' --filter '\.\./src/'
coverage: /^\s*lines:\s*\d+.\d+\%/
artifacts:
name: ${CI_JOB_NAME}-${CI_COMMIT_REF_NAME}-${CI_COMMIT_SHA}
expire_in: 2 days
reports:
coverage_report:
coverage_format: cobertura
path: build_cpp/coverage.xml
coverage:ubuntu_python:
stage: coverage
needs: ["build:ubuntu_python"]
tags:
- docker
script:
- source venv/bin/activate
- python3 -m pip install numpy coverage
- cd ${CI_PROJECT_NAME}
# Retrieve the installation path of the module, since it is installed with pip.
- export MODULE_LOCATION=`python -c "import ${CI_PROJECT_NAME} as _; print(_.__path__[0])"`
- python3 -m coverage run --source=$MODULE_LOCATION -m unittest discover -s unit_tests/ -v -b
- python3 -m coverage report
- python3 -m coverage xml
coverage: '/(?i)total.*? (100(?:\.0+)?\%|[1-9]?\d(?:\.\d+)?\%)$/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: ${CI_PROJECT_NAME}/coverage.xml
static_analysis:cpp:
stage: static_analysis
tags:
- static_analysis
allow_failure: true
script:
- mkdir -p $CI_COMMIT_REF_NAME
- cppcheck -j 4 --enable=all --inconclusive --force --xml --xml-version=2 . 2> cppcheck-result.xml
- python -m pip install Pygments
- cppcheck-htmlreport --file=cppcheck-result.xml --report-dir=$CI_COMMIT_REF_NAME --source-dir=.
- python3 -m pip install -U cppcheck_codequality
- cppcheck-codequality --input-file=cppcheck-result.xml --output-file=cppcheck.json
- mkdir -p public/cpp
- mv $CI_COMMIT_REF_NAME public/cpp/
artifacts:
paths:
- public
reports:
codequality: cppcheck.json
static_analysis:python:
stage: static_analysis
tags:
- static_analysis
allow_failure: true
script:
- pip install pylint
- pip install pylint-gitlab
- pylint --rcfile=.pylintrc --exit-zero --output-format=pylint_gitlab.GitlabCodeClimateReporter ${CI_PROJECT_NAME}/ > codeclimate.json
- pylint --rcfile=.pylintrc --exit-zero --output-format=pylint_gitlab.GitlabPagesHtmlReporter ${CI_PROJECT_NAME}/ > pylint.html
- mkdir -p public/python/$CI_COMMIT_REF_NAME
- mv pylint.html public/python/$CI_COMMIT_REF_NAME/
artifacts:
paths:
- public
reports:
codequality: codeclimate.json
\ No newline at end of file
test:ubuntu_cpp:
stage: test
needs: ["build:ubuntu_cpp"]
tags:
- docker
script:
- cd build_cpp
- ctest --output-junit ctest-results.xml --output-on-failure
artifacts:
reports:
junit: build_cpp/ctest-results.xml
test:ubuntu_python:
stage: test
needs: ["build:ubuntu_python"]
tags:
- docker
script:
- source venv/bin/activate
- cd ${CI_PROJECT_NAME}
- python3 -m pip install unittest-xml-reporting
- python3 -m pip list
# Run on discovery all tests located in core/unit_tests/python
- python3 -m xmlrunner discover -s unit_tests/ -v -b --output-file xmlrunner-results.xml
artifacts:
reports:
junit: ${CI_PROJECT_NAME}/xmlrunner-results.xml
test:windows_cpp:
stage: test
needs: ["build:windows_cpp"]
tags:
- windows
image: buildtools
before_script:
# Install Chocolatey
- Set-ExecutionPolicy Bypass -Scope Process -Force; [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'))
# Install dependencies
- choco install cmake.install --installargs '"ADD_CMAKE_TO_PATH=System"' -Y
- choco install python -Y
# Update PATH
- $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")
script:
- cd build_cpp
- ctest --output-junit ctest-results.xml --output-on-failure
artifacts:
reports:
junit: build_cpp/ctest-results.xml
This diff is collapsed.
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.15)
set(CXX_STANDARD 14)
file(READ "${CMAKE_SOURCE_DIR}/version.txt" version) file(STRINGS "${CMAKE_SOURCE_DIR}/version.txt" version)
file(READ "${CMAKE_SOURCE_DIR}/project_name.txt" project)
message(STATUS "Project name: ${project}") project(aidge_core
VERSION ${version}
DESCRIPTION "Core algorithms for operators and graph of the AIDGE framework"
LANGUAGES CXX)
message(STATUS "Project name: ${CMAKE_PROJECT_NAME}")
message(STATUS "Project version: ${version}") message(STATUS "Project version: ${version}")
add_definitions(-DPROJECT_VERSION="${version}")
# Note : project name is {project} and python module name is also {project} message(STATUS "Project name: ${CMAKE_PROJECT_NAME}")
set(module_name _${project}) # target name message(STATUS "Project version: ${version}")
project(${project}) # Note : project name is {project} and python module name is also {project}
set(CXX_STANDARD 14) set(module_name _${CMAKE_PROJECT_NAME}) # target name
set(pybind_module_name ${CMAKE_PROJECT_NAME}) # name of submodule for python bindings
############################################## ##############################################
# Define options # Define options
option(PYBIND "python binding" ON) option(PYBIND "python binding" OFF)
option(WERROR "Warning as error" OFF) option(WERROR "Warning as error" OFF)
option(TEST "Enable tests" ON) option(TEST "Enable tests" ON)
option(COVERAGE "Enable coverage" OFF) option(COVERAGE "Enable coverage" OFF)
...@@ -24,7 +29,6 @@ option(ENABLE_ASAN "Enable ASan (AddressSanitizer) for runtime analysis of memor ...@@ -24,7 +29,6 @@ option(ENABLE_ASAN "Enable ASan (AddressSanitizer) for runtime analysis of memor
############################################## ##############################################
# Import utils CMakeLists # Import utils CMakeLists
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
include(PybindModuleCreation)
if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE) if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE)
Include(CodeCoverage) Include(CodeCoverage)
...@@ -34,10 +38,12 @@ endif() ...@@ -34,10 +38,12 @@ endif()
# Find system dependencies # Find system dependencies
Include(FetchContent) Include(FetchContent)
set(FMT_VERSION 10.2.1)
message(STATUS "Retrieving fmt ${FMT_VERSION} from git")
FetchContent_Declare( FetchContent_Declare(
fmt fmt
GIT_REPOSITORY https://github.com/fmtlib/fmt.git GIT_REPOSITORY https://github.com/fmtlib/fmt.git
GIT_TAG 10.2.1 # or a later release GIT_TAG ${FMT_VERSION} # or a later release
) )
set(FMT_SYSTEM_HEADERS ON) set(FMT_SYSTEM_HEADERS ON)
...@@ -79,14 +85,19 @@ endif() ...@@ -79,14 +85,19 @@ endif()
# PYTHON BINDING # PYTHON BINDING
if (PYBIND) if (PYBIND)
generate_python_binding(${project} ${module_name}) # Python binding lib is by default installed in <prefix>/python_packages/<package>/
# When installed from python, setup.py should set it to the python package dir
set(PYBIND_INSTALL_PREFIX python_packages/${pybind_module_name} CACHE PATH "Python package install prefix")
include(PybindModuleCreation)
generate_python_binding(${pybind_module_name} ${module_name})
# Handles Python + pybind11 headers dependencies # Handles Python + pybind11 headers dependencies
target_link_libraries(${module_name} target_link_libraries(${module_name}
PUBLIC PUBLIC
pybind11::pybind11 pybind11::pybind11
PRIVATE PRIVATE
Python::Python Python::Module
) )
endif() endif()
...@@ -133,11 +144,15 @@ endif() ...@@ -133,11 +144,15 @@ endif()
############################################## ##############################################
# Installation instructions # Installation instructions
if(NOT $ENV{AIDGE_INSTALL} STREQUAL "")
set(CMAKE_INSTALL_PREFIX $ENV{AIDGE_INSTALL})
message(WARNING "CMAKE_INSTALL_PREFIX set to env variable AIDGE_INSTALL by default = ${CMAKE_INSTALL_PREFIX}")
endif()
include(GNUInstallDirs) include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${project}) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME})
install(TARGETS ${module_name} EXPORT ${project}-targets install(TARGETS ${module_name} EXPORT ${CMAKE_PROJECT_NAME}-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
...@@ -146,10 +161,16 @@ install(TARGETS ${module_name} EXPORT ${project}-targets ...@@ -146,10 +161,16 @@ install(TARGETS ${module_name} EXPORT ${project}-targets
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if (PYBIND)
install(TARGETS ${pybind_module_name}
DESTINATION ${PYBIND_INSTALL_PREFIX}
)
endif()
#Export the targets to a script #Export the targets to a script
install(EXPORT ${project}-targets install(EXPORT ${CMAKE_PROJECT_NAME}-targets
FILE "${project}-targets.cmake" FILE "${CMAKE_PROJECT_NAME}-targets.cmake"
DESTINATION ${INSTALL_CONFIGDIR} DESTINATION ${INSTALL_CONFIGDIR}
# COMPONENT ${module_name} # COMPONENT ${module_name}
) )
...@@ -158,32 +179,37 @@ install(EXPORT ${project}-targets ...@@ -158,32 +179,37 @@ install(EXPORT ${project}-targets
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
write_basic_package_version_file( write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config-version.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
VERSION ${version} VERSION ${version}
COMPATIBILITY AnyNewerVersion COMPATIBILITY AnyNewerVersion
) )
configure_package_config_file("${project}-config.cmake.in" configure_package_config_file("${CMAKE_PROJECT_NAME}-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION ${INSTALL_CONFIGDIR} INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
) )
#Install the config, configversion and custom find modules #Install the config, configversion and custom find modules
install(FILES install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config-version.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
DESTINATION ${INSTALL_CONFIGDIR} DESTINATION ${INSTALL_CONFIGDIR}
) )
############################################## ##############################################
## Exporting from the build tree ## Exporting from the build tree
export(EXPORT ${project}-targets message(STATUS "Exporting created targets to use them in another build")
FILE "${CMAKE_CURRENT_BINARY_DIR}/${project}-targets.cmake") export(EXPORT ${CMAKE_PROJECT_NAME}-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-targets.cmake")
############################################## ##############################################
## Add test ## Add test
if(TEST) if(TEST)
if(PYBIND)
message(FATAL_ERROR "PYBIND and TEST are both enabled. But cannot compile with catch_2.\nChoose between pybind and Catch2 for compilation.")
endif()
enable_testing() enable_testing()
add_subdirectory(unit_tests) add_subdirectory(unit_tests)
endif() endif()
include MANIFEST.in include README.md LICENCE
include LICENSE recursive-include aidge_core *.py
include README.md recursive-exclude aidge_core/unit_tests *.py
recursive-include aidge_core *
include setup.py recursive-include aidge_core/aidge_export_aidge *
include version.txt recursive-include include *.hpp
recursive-include src *.cpp
recursive-include python_binding *.cpp
include CMakeLists.txt
...@@ -4,21 +4,64 @@ ...@@ -4,21 +4,64 @@
You can find here the C++ code of the Core library of Aidge. You can find here the C++ code of the Core library of Aidge.
## Pip installation [TOC]
## Pip installation
To install aidge_core using pip, run the following command in your python environnement : To install aidge_core using pip, run the following command in your python environnement :
``` bash ``` bash
pip install . -v pip install . -v
``` ```
> **TIPS :** Use environment variables to change compilation options:
> - `AIDGE_INSTALL` : to set the installation folder. Defaults to `<python_prefix>/lib/libAidge`
> - `AIDGE_PYTHON_BUILD_TYPE` : to set the compilation mode to **Debug** or **Release** or "" (for default flags). Defaults to **Release**.
> - `AIDGE_BUILD_GEN` : to set the build backend (for development mode) or "" for the cmake default. Default to "".
## Pip installation for development
To setup aidge_core using pip in development (or editable mode), use the `--no-build-isolation -e` options to pip.
**Note:** you can specify a custom install folder by setting an environment variable: For instance run the following command in your python environnement for a typical setup :
``` bash
export AIDGE_PYTHON_BUILD_TYPE= # default flags (no debug info but fastest build time)
export AIDGE_PYTHON_BUILD_TYPE=Debug # or if one really need to debug the C++ code
pip install setuptools setuptools_scm[toml] cmake # Pre-install build requirements (refer to the pyproject.toml [build-system] section)
pip install -v --no-build-isolation -e .
```
In this configuration python files can be modified directly without re-installation.
The C++ build dir will be created in `build/` and recompilation and install of python bindings can be done directly with:
```bash
make -C build install -j $(nproc)
# or with cmake
cmake --build build -j $(nproc) && cmake --install build
```
One can also use an alternate cmake build backend such as ninja which can be installed easily though pip, for instance :
``` bash ``` bash
export AIDGE_INSTALL='<path_to_aidge>/install' pip install ninja
export AIDGE_BUILD_GEN=Ninja
pip install -v --no-build-isolation -e .
```
In this case ninja is used instead of make as build backend, and recompilation when needed is done with:
```bash
ninja -C build install # note that by default ninja use available parallelism, no need for -j option
# or with cmake
cmake --build build && cmake --install build
``` ```
Note that python development (or editable mode) is not always robust to changes in the python package setup,
or when changing the build backend with `AIDGE_BUILD_GEN`.
In order to re-install when the build breaks, re-execute the commands:
```bash
rm -rf *-egg-info build/
pip install -v --no-build-isolation -e .
```
## Standard C++ Compilation ## Standard C++ Compilation
Create two directories ``build`` and ``ìnstall``. Create two directories ``build`` and ``ìnstall``.
...@@ -40,22 +83,19 @@ make all install ...@@ -40,22 +83,19 @@ make all install
| Option | Value type | Description | | Option | Value type | Description |
|:----------:|:----------:|:-----------:| |:----------:|:----------:|:-----------:|
| *-DCMAKE_INSTALL_PREFIX:PATH* | ``str`` | Path to the install folder | | *-DCMAKE_INSTALL_PREFIX:PATH* | ``str`` | Path to the install folder |
| *-DCMAKE_BUILD_TYPE* | ``str`` | If ``Debug``, compile in debug mode, ``Release`` compile with highest optimisations, default= ``Release`` | | *-DCMAKE_BUILD_TYPE* | ``str`` | If ``Debug``, compile in debug mode, ``Release`` compile with highest optimisations or "" (empty) , default= ``Release`` |
| *-DWERROR* | ``bool`` | If ``ON`` show warning as error during compilation phase, default=``OFF`` | | *-DWERROR* | ``bool`` | If ``ON`` show warning as error during compilation phase, default=``OFF`` |
| *-DPYBIND* | ``bool`` | If ``ON`` activate python binding, default=``ON`` | | *-DPYBIND* | ``bool`` | If ``ON`` activate python binding, default=``ON`` |
If you have compiled with PyBind you can find at the root of the ``build`` file the python lib ``aidge_core.cpython*.so`` If you have compiled with PyBind you can find at the root of the ``build`` file the python lib ``aidge_core.cpython*.so``
## Run tests ## Run tests
### CPP ### CPP
Inside of the build file run: Inside of the build file run:
```bash ```bash
ctest --output-on-failure ctest --output-on-failure
``` ```
### Python ### Python
......
...@@ -8,8 +8,7 @@ http://www.eclipse.org/legal/epl-2.0. ...@@ -8,8 +8,7 @@ http://www.eclipse.org/legal/epl-2.0.
SPDX-License-Identifier: EPL-2.0 SPDX-License-Identifier: EPL-2.0
""" """
from aidge_core.aidge_core import * # import so generated by PyBind from aidge_core.aidge_core import * # import so generated by PyBind
# from aidge_core.export_utils import ExportNodeCpp, ExportNode, generate_file, generate_str
import aidge_core.export_utils import aidge_core.export_utils
import aidge_core.utils import aidge_core.utils
from aidge_core.aidge_export_aidge import serialize_to_cpp from aidge_core.aidge_export_aidge import serialize_to_cpp
from ._version import *
cmake_minimum_required(VERSION 3.15) cmake_minimum_required(VERSION 3.15)
set(CXX_STANDARD 14)
file(STRINGS "${CMAKE_SOURCE_DIR}/project_name.txt" project_name)
file(STRINGS "${CMAKE_SOURCE_DIR}/version.txt" version) file(STRINGS "${CMAKE_SOURCE_DIR}/version.txt" version)
file(STRINGS "${CMAKE_SOURCE_DIR}/project_name.txt" project)
message(STATUS "Project name: ${project}") project(${project_name}
message(STATUS "Project version: ${version}") VERSION ${version}
DESCRIPTION "Export of aidge"
LANGUAGES CXX)
# Note : project name is {project} and python module name is also {project} message(STATUS "Project name: ${CMAKE_PROJECT_NAME}")
set(module_name _${project}) # target name message(STATUS "Project version: ${version}")
project(${project}) # Note : project name is ${CMAKE_PROJECT_NAME} and python module name is also ${CMAKE_PROJECT_NAME}
set(CXX_STANDARD 14) set(module_name _${CMAKE_PROJECT_NAME}) # target name
############################################## ##############################################
# Define options # Define options
option(PYBIND "python binding" ON) option(PYBIND "python binding" ON)
option(WERROR "Warning as error" OFF) option(WERROR "Warning as error" OFF)
option(TEST "Enable tests" ON) option(TEST "Enable tests" OFF)
option(COVERAGE "Enable coverage" OFF) option(COVERAGE "Enable coverage" OFF)
option(ENABLE_ASAN "Enable ASan (AddressSanitizer) for runtime analysis of memory use (over/underflow, memory leak, ...)" OFF) option(ENABLE_ASAN "Enable ASan (AddressSanitizer) for runtime analysis of memory use (over/underflow, memory leak, ...)" OFF)
############################################## ##############################################
# Import utils CMakeLists # Import utils CMakeLists
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake") set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
include(PybindModuleCreation)
if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE) if(CMAKE_COMPILER_IS_GNUCXX AND COVERAGE)
Include(CodeCoverage) Include(CodeCoverage)
endif() endif()
############################################## ##############################################
# Find system dependencies # FIND Dependencies
if(NOT $ENV{AIDGE_INSTALL} STREQUAL "")
set(CMAKE_INSTALL_PREFIX $ENV{AIDGE_INSTALL})
list(APPEND CMAKE_PREFIX_PATH $ENV{AIDGE_INSTALL})
message(WARNING "Env var AIDGE_INSTALL detected : $ENV{AIDGE_INSTALL}. Set CMAKE_INSTALL_PREFIX to AIDGE_INSTALL & added to CMAKE_PREFIX_PATH"
"\n\tCMAKE_INSTALL_PREFIX = ${CMAKE_INSTALL_PREFIX}"
"\n\tCMAKE_PREFIX_PATH = ${CMAKE_PREFIX_PATH}")
endif()
find_package(aidge_core REQUIRED) find_package(aidge_core REQUIRED)
# Example of adding dependency to backend CPU # find_package(aidge_backend_cpu REQUIRED) # example if you want to add aidge_backend_cpu as dependency to your export
# find_package(aidge_backend_cpu REQUIRED)
############################################## ##############################################
# Create target and set properties # Create target and set properties
...@@ -42,15 +49,30 @@ file(GLOB_RECURSE src_files "src/*.cpp") ...@@ -42,15 +49,30 @@ file(GLOB_RECURSE src_files "src/*.cpp")
file(GLOB_RECURSE inc_files "include/*.hpp") file(GLOB_RECURSE inc_files "include/*.hpp")
add_library(${module_name} ${src_files} ${inc_files}) add_library(${module_name} ${src_files} ${inc_files})
target_link_libraries(${module_name} target_link_libraries(${module_name}
PUBLIC PUBLIC
_aidge_core # _ is added because we link the target not the project _aidge_core # _ is added because we link the exported target and not the project
# _aidge_backend_cpu # Example of adding dependency to backend CPUs # _aidge_backend_cpu # example if you want to add aidge_backend_cpu as dependency to your export
) )
#Set target properties #Set target properties
set_property(TARGET ${module_name} PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET ${module_name} PROPERTY POSITION_INDEPENDENT_CODE ON)
# PYTHON BINDING
if (PYBIND)
# Handles Python + pybind11 headers dependencies
include(PybindModuleCreation)
generate_python_binding(${CMAKE_PROJECT_NAME} ${module_name})
target_link_libraries(${module_name}
PUBLIC
pybind11::pybind11
PRIVATE
Python::Python
)
endif()
if( ${ENABLE_ASAN} ) if( ${ENABLE_ASAN} )
message("Building ${module_name} with ASAN.") message("Building ${module_name} with ASAN.")
set(SANITIZE_FLAGS -fsanitize=address -fno-omit-frame-pointer) set(SANITIZE_FLAGS -fsanitize=address -fno-omit-frame-pointer)
...@@ -72,17 +94,7 @@ target_include_directories(${module_name} ...@@ -72,17 +94,7 @@ target_include_directories(${module_name}
${CMAKE_CURRENT_SOURCE_DIR}/src ${CMAKE_CURRENT_SOURCE_DIR}/src
) )
# PYTHON BINDING target_link_libraries(${module_name} PUBLIC fmt::fmt)
if (PYBIND)
generate_python_binding(${project} ${module_name})
# Handles Python + pybind11 headers dependencies
target_link_libraries(${module_name}
PUBLIC
pybind11::pybind11
)
endif()
target_compile_features(${module_name} PRIVATE cxx_std_14) target_compile_features(${module_name} PRIVATE cxx_std_14)
target_compile_options(${module_name} PRIVATE target_compile_options(${module_name} PRIVATE
...@@ -98,22 +110,19 @@ endif() ...@@ -98,22 +110,19 @@ endif()
############################################## ##############################################
# Installation instructions # Installation instructions
include(GNUInstallDirs) include(GNUInstallDirs)
set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${project}) set(INSTALL_CONFIGDIR ${CMAKE_INSTALL_LIBDIR}/cmake/${CMAKE_PROJECT_NAME})
install(TARGETS ${module_name} EXPORT ${project}-targets install(TARGETS ${module_name} EXPORT ${CMAKE_PROJECT_NAME}-targets
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
) )
install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) install(DIRECTORY include/ DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
#Export the targets to a script #Export the targets to a script
install(EXPORT ${CMAKE_PROJECT_NAME}-targets
install(EXPORT ${project}-targets FILE "${CMAKE_PROJECT_NAME}-targets.cmake"
FILE "${project}-targets.cmake"
DESTINATION ${INSTALL_CONFIGDIR} DESTINATION ${INSTALL_CONFIGDIR}
COMPONENT ${module_name} COMPONENT ${module_name}
) )
...@@ -121,26 +130,27 @@ install(EXPORT ${project}-targets ...@@ -121,26 +130,27 @@ install(EXPORT ${project}-targets
#Create a ConfigVersion.cmake file #Create a ConfigVersion.cmake file
include(CMakePackageConfigHelpers) include(CMakePackageConfigHelpers)
write_basic_package_version_file( write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config-version.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
VERSION ${version} VERSION ${version}
COMPATIBILITY AnyNewerVersion COMPATIBILITY AnyNewerVersion
) )
configure_package_config_file("${project}-config.cmake.in" configure_package_config_file("${CMAKE_PROJECT_NAME}-config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
INSTALL_DESTINATION ${INSTALL_CONFIGDIR} INSTALL_DESTINATION ${INSTALL_CONFIGDIR}
) )
#Install the config, configversion and custom find modules #Install the config, configversion and custom find modules
install(FILES install(FILES
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${project}-config-version.cmake" "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_PROJECT_NAME}-config-version.cmake"
DESTINATION ${INSTALL_CONFIGDIR} DESTINATION ${INSTALL_CONFIGDIR}
) )
############################################## ##############################################
## Exporting from the build tree ## Exporting from the build tree
export(EXPORT ${project}-targets message(STATUS "Exporting created targets to use them in another build")
export(EXPORT ${CMAKE_PROJECT_NAME}-targets
FILE "${CMAKE_CURRENT_BINARY_DIR}/${project}-targets.cmake") FILE "${CMAKE_CURRENT_BINARY_DIR}/${project}-targets.cmake")
# Compile executable # Compile executable
......
function(generate_python_binding name target_to_bind) function(generate_python_binding name target_to_bind)
find_package(Python COMPONENTS Interpreter Development)
add_definitions(-DPYBIND) add_definitions(-DPYBIND)
Include(FetchContent) Include(FetchContent)
FetchContent_Declare( FetchContent_Declare(
PyBind11 PyBind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG v2.10.4 # or a later release GIT_TAG v2.10.4 # or a later release
) )
# Use the New FindPython mode, recommanded. Requires CMake 3.15+
find_package(Python COMPONENTS Interpreter Development)
FetchContent_MakeAvailable(PyBind11) FetchContent_MakeAvailable(PyBind11)
message(STATUS "Creating binding for module ${name}") message(STATUS "Creating binding for module ${name}")
...@@ -17,5 +16,10 @@ function(generate_python_binding name target_to_bind) ...@@ -17,5 +16,10 @@ function(generate_python_binding name target_to_bind)
pybind11_add_module(${name} MODULE ${pybind_src_files} "NO_EXTRAS") # NO EXTRA recquired for pip install pybind11_add_module(${name} MODULE ${pybind_src_files} "NO_EXTRAS") # NO EXTRA recquired for pip install
target_include_directories(${name} PUBLIC "python_binding") target_include_directories(${name} PUBLIC "python_binding")
target_link_libraries(${name} PUBLIC ${target_to_bind})
# Handles Python + pybind11 headers dependencies
target_link_libraries(${name}
PUBLIC
${target_to_bind}
)
endfunction() endfunction()
...@@ -122,7 +122,6 @@ class ExportNode(ABC): ...@@ -122,7 +122,6 @@ class ExportNode(ABC):
- **mem_info_cont_offset**: old N2D2 - **mem_info_cont_offset**: old N2D2
- **mem_info_wrap_offset**: old N2D2 - **mem_info_wrap_offset**: old N2D2
- **mem_info_wrap_size**: old N2D2 - **mem_info_wrap_size**: old N2D2
""" """
@abstractmethod @abstractmethod
......
# TODO: this file is here for prototyping only
# IT NEEDS TO BE REMOVED BEFORE ANY MERGE!
import aidge_core
# Export class for "arm_cortexm". The same class needs to be registered for
# all operators supported by the export.
class OperatorExport_arm_cortexm(aidge_core.OperatorImpl):
# Registry for all "arm_cortexm" operator exports
registry = dict()
def __init__(self, operator):
super(OperatorExport_arm_cortexm, self).__init__(operator, "export_arm_cortexm")
# Override the virtual OperatorImpl method, in order to provide available
# implementation specifications
def get_available_impl_specs(self):
if self.get_operator().type() in self.registry:
return list(self.registry[self.get_operator().type()].keys())
else:
return []
# Decorator to register kernels for this export
@staticmethod
def register(type, spec):
def decorator(operator):
def wrapper(*args, **kwargs):
return operator(*args, **kwargs)
if (type not in OperatorExport_arm_cortexm.registry):
OperatorExport_arm_cortexm.registry[type] = dict()
OperatorExport_arm_cortexm.registry[type][spec] = operator
return wrapper
return decorator
# Register kernels: for a given type and a given implementation specification
# TODO: the FCOpKernel could inherit from a generic base class for this export or all export types...
@OperatorExport_arm_cortexm.register(aidge_core.FCOp.Type, aidge_core.ImplSpec(aidge_core.IOSpec(aidge_core.dtype.int16)))
class FCOpKernel():
def generate():
print("Gen code for FCOp")
# TODO: register other kernels...
# Register all operator types to the same export class
aidge_core.register_FCOp("export_arm_cortexm", OperatorExport_arm_cortexm)
aidge_core.register_ReLUOp("export_arm_cortexm", OperatorExport_arm_cortexm)
# TODO: register other operators...
# Use the CPU backend for Tensor in the "export_arm_cortexm" backend
aidge_core.register_Tensor(["export_arm_cortexm", aidge_core.dtype.float32],
aidge_core.get_key_value_Tensor(["cpu", aidge_core.dtype.float32]))
################################################################################
# TEST
################################################################################
model = aidge_core.sequential(
[
aidge_core.FC(
in_channels=32 * 32 * 3, out_channels=512, name="InputNode"
),
aidge_core.ReLU(name="Relu0"),
aidge_core.FC(in_channels=512, out_channels=256, name="FC1"),
aidge_core.ReLU(name="Relu1"),
aidge_core.FC(in_channels=256, out_channels=128, name="FC2"),
aidge_core.ReLU(name="Relu2"),
aidge_core.FC(in_channels=128, out_channels=10, name="OutputNode"),
]
)
model.set_backend("export_arm_cortexm")
aidge_core.adapt_to_backend(model)
model.save("test", verbose=True)
...@@ -8,15 +8,15 @@ http://www.eclipse.org/legal/epl-2.0. ...@@ -8,15 +8,15 @@ http://www.eclipse.org/legal/epl-2.0.
SPDX-License-Identifier: EPL-2.0 SPDX-License-Identifier: EPL-2.0
""" """
import unittest
import aidge_core import aidge_core
from functools import reduce from aidge_core.utils import run_command
import pathlib import unittest
import os import os
import sys import pathlib
import subprocess
import shutil import shutil
import numpy as np import subprocess
import sys
def initFiller(model): def initFiller(model):
# Initialize parameters (weights and biases) # Initialize parameters (weights and biases)
...@@ -27,42 +27,64 @@ def initFiller(model): ...@@ -27,42 +27,64 @@ def initFiller(model):
value.set_backend("cpu") value.set_backend("cpu")
tuple_out = node.output(0)[0] tuple_out = node.output(0)[0]
# No conv in current network # No conv in current network
if tuple_out[0].type() == "Conv" and tuple_out[1]==1: if tuple_out[0].type() == "Conv" and tuple_out[1] == 1:
# Conv weight # Conv weight
aidge_core.xavier_uniform_filler(value) aidge_core.xavier_uniform_filler(value)
elif tuple_out[0].type() == "Conv" and tuple_out[1]==2: elif tuple_out[0].type() == "Conv" and tuple_out[1] == 2:
# Conv bias # Conv bias
aidge_core.constant_filler(value, 0.01) aidge_core.constant_filler(value, 0.01)
elif tuple_out[0].type() == "FC" and tuple_out[1]==1: elif tuple_out[0].type() == "FC" and tuple_out[1] == 1:
# FC weight # FC weight
aidge_core.normal_filler(value) aidge_core.normal_filler(value)
elif tuple_out[0].type() == "FC" and tuple_out[1]==2: elif tuple_out[0].type() == "FC" and tuple_out[1] == 2:
# FC bias # FC bias
aidge_core.constant_filler(value, 0.01) aidge_core.constant_filler(value, 0.01)
else: else:
pass pass
def clean_dir(dir: pathlib.Path) -> None:
if not dir.is_dir():
print(f"Error : directory {dir} doesn't exist. Exiting clean_dir().")
return
for filename in os.listdir(dir):
file_path = os.path.join(dir, filename)
try:
if os.path.isfile(file_path) or os.path.islink(file_path):
os.unlink(file_path)
elif os.path.isdir(file_path):
shutil.rmtree(file_path)
except Exception as e:
print(f"Failed to delete {file_path}. Reason: {e}")
return
class test_export(unittest.TestCase): class test_export(unittest.TestCase):
"""Test aidge export """Test aidge export"""
"""
def setUp(self): def setUp(self):
self.EXPORT_PATH = pathlib.Path("myexport") self.EXPORT_PATH: pathlib.Path = pathlib.Path("dummy_export")
self.BUILD_DIR: pathlib.Path = self.EXPORT_PATH / "build"
def tearDown(self): def tearDown(self):
pass pass
def test_generate_export(self): def test_generate_export(self):
# Create model # Create model
model = aidge_core.sequential([ model = aidge_core.sequential(
aidge_core.FC(in_channels=32*32*3, out_channels=512, name="InputNode"), [
aidge_core.ReLU(name="Relu0"), aidge_core.FC(
aidge_core.FC(in_channels=512, out_channels=256, name="FC1"), in_channels=32 * 32 * 3, out_channels=512, name="InputNode"
aidge_core.ReLU(name="Relu1"), ),
aidge_core.FC(in_channels=256, out_channels=128, name="FC2"), aidge_core.ReLU(name="Relu0"),
aidge_core.ReLU(name="Relu2"), aidge_core.FC(in_channels=512, out_channels=256, name="FC1"),
aidge_core.FC(in_channels=128, out_channels=10, name="OutputNode"), aidge_core.ReLU(name="Relu1"),
]) aidge_core.FC(in_channels=256, out_channels=128, name="FC2"),
aidge_core.ReLU(name="Relu2"),
aidge_core.FC(in_channels=128, out_channels=10, name="OutputNode"),
]
)
initFiller(model) initFiller(model)
...@@ -72,12 +94,55 @@ class test_export(unittest.TestCase): ...@@ -72,12 +94,55 @@ class test_export(unittest.TestCase):
os.makedirs(self.EXPORT_PATH / "build", exist_ok=True) os.makedirs(self.EXPORT_PATH / "build", exist_ok=True)
# Test compilation of export # Test compilation of export
install_path = os.path.join(sys.prefix, "lib", "libAidge") if "AIDGE_INSTALL" not in os.environ else os.environ["AIDGE_INSTALL"] install_path = (
os.path.join(sys.prefix, "lib", "libAidge")
if "AIDGE_INSTALL" not in os.environ
else os.environ["AIDGE_INSTALL"]
)
shutil.copyfile(
pathlib.Path(__file__).parent / "static/main.cpp",
self.EXPORT_PATH / "main.cpp",
)
##########################
# CMAKE EXPORT
try:
for std_line in run_command(
[
"cmake",
str(self.EXPORT_PATH.absolute()),
"-DPYBIND=1",
f"-DCMAKE_INSTALL_PREFIX:PATH={install_path}",
],
cwd=str(self.BUILD_DIR),
):
print(std_line, end="")
except subprocess.CalledProcessError as e:
print(f"An error occurred: {e}\nFailed to configure export.")
##########################
# BUILD EXPORT
try:
for std_line in run_command(
["cmake", "--build", "."],
cwd=str(self.BUILD_DIR),
):
print(std_line, end="")
except subprocess.CalledProcessError as e:
print(f"An error occurred: {e}\nFailed to build export.")
shutil.copyfile(pathlib.Path(__file__).parent / "static/main.cpp", self.EXPORT_PATH / "main.cpp") ##########################
# INSTALL EXPORT
try:
for std_line in run_command(
["cmake", "--install", "."],
cwd=str(self.BUILD_DIR),
):
print(std_line, end="")
except subprocess.CalledProcessError as e:
print(f"An error occurred: {e}\nFailed to install export.")
subprocess.check_call(['cmake', str(self.EXPORT_PATH.absolute()), f'-DCMAKE_INSTALL_PREFIX:PATH={install_path}'], cwd=str(self.EXPORT_PATH / "build"))
subprocess.check_call(['make', 'all', 'install'], cwd=str(self.EXPORT_PATH / "build"))
if __name__ == '__main__': if __name__ == "__main__":
unittest.main() unittest.main()
...@@ -73,15 +73,26 @@ class test_operator_binding(unittest.TestCase): ...@@ -73,15 +73,26 @@ class test_operator_binding(unittest.TestCase):
self.assertEqual(attrs.get_attr("b"), "test") self.assertEqual(attrs.get_attr("b"), "test")
self.assertEqual(attrs.has_attr("c"), True) self.assertEqual(attrs.has_attr("c"), True)
self.assertEqual(attrs.get_attr("c"), [True, False, True]) self.assertEqual(attrs.get_attr("c"), [True, False, True])
self.assertEqual(attrs.dict().keys(), {"a", "b", "c"}) self.assertEqual(attrs.dict().keys(), {"a", "b", "c", "mem", "impl"})
self.assertEqual(attrs.has_attr("d"), False) self.assertEqual(attrs.has_attr("d"), False)
self.assertEqual(attrs.has_attr("mem.a"), True)
self.assertEqual(attrs.get_attr("mem.a"), 1)
self.assertEqual(attrs.has_attr("mem.data.b"), True)
self.assertEqual(attrs.get_attr("mem.data.b"), 1.0)
self.assertEqual(attrs.get_attr("mem").get_attr("data").get_attr("b"), 1.0)
self.assertEqual(attrs.has_attr("impl.c"), True)
self.assertEqual(attrs.get_attr("impl.c"), "test")
# Add Python attributes # Add Python attributes
attrs.add_attr("d", 18.56) attrs.add_attr("d", 18.56)
self.assertEqual(attrs.get_attr("d"), 18.56) self.assertEqual(attrs.get_attr("d"), 18.56)
self.assertEqual(attrs.has_attr("d"), True) self.assertEqual(attrs.has_attr("d"), True)
self.assertEqual(attrs.dict().keys(), {"a", "b", "c", "d"}) self.assertEqual(attrs.dict().keys(), {"a", "b", "c", "d", "mem", "impl"})
self.assertEqual(attrs.has_attr("e"), False) self.assertEqual(attrs.has_attr("e"), False)
attrs.add_attr("mem.data.c", 19.36)
self.assertEqual(attrs.get_attr("mem.data.c"), 19.36)
self.assertEqual(attrs.has_attr("mem.data.c"), True)
self.assertEqual(attrs.dict().keys(), {"a", "b", "c", "d", "mem", "impl"})
# Check that added Python attribute is accessible in C++ # Check that added Python attribute is accessible in C++
# Return the value of an attribute named "d" of type float64 (double in C++) # Return the value of an attribute named "d" of type float64 (double in C++)
...@@ -89,6 +100,23 @@ class test_operator_binding(unittest.TestCase): ...@@ -89,6 +100,23 @@ class test_operator_binding(unittest.TestCase):
attrs.d = 23.89 attrs.d = 23.89
self.assertEqual(aidge_core.test_DynamicAttributes_binding_check(attrs), 23.89) self.assertEqual(aidge_core.test_DynamicAttributes_binding_check(attrs), 23.89)
op = aidge_core.GenericOperatorOp("any_type", 1,0,1)
with self.assertRaises(RuntimeError):
op.attr.something
op.attr.something = aidge_core.DynamicAttributes()
try:
self.assertEqual(str(op.attr), "AttrDict({'something': AttrDict({})})")
except Exception:
self.fail("op.attr.something raised Exception unexpectedly!")
op.attr.something.arg1 = 4
self.assertEqual(op.attr.something.arg1, 4)
# auto create the namespace another_thing (not enabled)
#op.attr.another_thing.arg = 44
#self.assertEqual(op.attr.another_thing.arg, 44)
def test_forward_dims(self): def test_forward_dims(self):
in_dims=[25, 25] in_dims=[25, 25]
input = aidge_core.Producer(in_dims, name="In") input = aidge_core.Producer(in_dims, name="In")
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment