Skip to content

Commit

Permalink
Use CMake and vcpkg
Browse files Browse the repository at this point in the history
  • Loading branch information
krypty committed Apr 27, 2018
1 parent c816676 commit 34579b5
Show file tree
Hide file tree
Showing 13 changed files with 204 additions and 79 deletions.
30 changes: 30 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 1,30 @@
cmake_minimum_required(VERSION 3.1)
project(pyFUGE)
set(SOURCE_DIR pyfuge/py_fiseval)

set(CMAKE_POSITION_INDEPENDENT_CODE ON)

find_package(Eigen3 3.3 REQUIRED NO_MODULE)
find_package(Catch2 REQUIRED NO_MODULE)
find_package(OpenMP)
if(OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()
include_directories(
# ${SOURCE_DIR}
${CMAKE_SOURCE_DIR}/pyfuge/py_fiseval/FISEval/include
${EIGEN3_INCLUDE_DIR}
)
# get_cmake_property(_variableNames VARIABLES)
# list (SORT _variableNames)
# foreach (_variableName ${_variableNames})
# message(STATUS "${_variableName}=${${_variableName}}")
# endforeach()
add_subdirectory(${SOURCE_DIR}/FISEval)
add_subdirectory(${SOURCE_DIR}/pybind11)
pybind11_add_module(pyfuge_c SHARED "${SOURCE_DIR}/fiseval_bindings.cpp" ${SOURCE_DIR}/FISEval)
target_link_libraries(pyfuge_c PRIVATE pyfuge)

message(STATUS "${SOURCES}")
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 31,9 @@ from pyfuge.evo.examples import evo_cancer
evo_cancer.run_with_simple_evo()
```

# NEW !
```bash
export VCPKG_ROOT=/home/gary/CI4CB/PyFUGE/pyfuge/py_fiseval/FISEval/vcpkg
#activate your virtualenv
python setup.py install
```
2 changes: 2 additions & 0 deletions pyfuge/evo/examples/evo_cancer.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 169,8 @@ def run_with_simple_evo():
acc = _compute_accuracy(ds_test.y, y_pred_test)
print("acc test ", acc)

def run():
run_with_simple_evo()

if __name__ == '__main__':
t0 = time()
Expand Down
63 changes: 63 additions & 0 deletions pyfuge/py_fiseval/FISEval/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 1,63 @@
cmake_minimum_required(VERSION 3.1)
project(FISEval)

# set( CMAKE_VERBOSE_MAKEFILE on )

# Enable C 14 features
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

# Set build type
# set(CMAKE_BUILD_TYPE Release)


find_package(Eigen3 3.3 REQUIRED NO_MODULE)
find_package(Catch2 REQUIRED NO_MODULE)
find_package(OpenMP)

if(OPENMP_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
endif()

# Compiler specific flags
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ftree-vectorize -mtune=native -march=native -mavx")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
endif()

include_directories(include)

set(LINK_LIBRARIES
Catch2::Catch
Eigen3::Eigen
)

set(SOURCES
src/fis.cpp
)

set(SOURCES_TEST
tests/fis_lininterp_test.cpp
tests/tests.cpp
)
set(SOURCES_TEST ${SOURCES_TEST} ${SOURCES})


# Make executable
add_library(pyfuge ${SOURCES})
target_link_libraries(pyfuge ${LINK_LIBRARIES})


# compile tests only if debug
# TODO: use cmake built-in test mecanisms
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
# remove the main from SOURCE to only use the main from tests.cpp
list(REMOVE_ITEM SOURCES_TEST src/main.cpp)
add_executable(run_tests ${SOURCES_TEST})
target_link_libraries(run_tests ${LINK_LIBRARIES})
endif()
41 changes: 0 additions & 41 deletions pyfuge/py_fiseval/FISEval/Makefile

This file was deleted.

Empty file.
Original file line number Diff line number Diff line change
@@ -1,6 1,7 @@
#ifndef CUSTOM_EG_TD
#define CUSTOM_EG_TD


#include <Eigen/Core>

typedef Eigen::Matrix<double, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor> MatXd;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 1,7 @@
#ifndef FIS_H
#define FIS_H

#include "../hpp/custom_eigen_td.h"
#include "custom_eigen_td.h"
#include <Eigen/Core>
#include <iostream>
#include <vector>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
#include "../hpp/fis.h"
#include "fis.h"
#include "omp.h"
#include <algorithm>
#include <cmath>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 1,8 @@
#include "../vendor/catch/catch.hpp"
#include "catch.hpp"

#include "../hpp/fis.h"
#include "fis.h"

#include "../hpp/custom_eigen_td.h"
#include "custom_eigen_td.h"
#include <Eigen/Core>

using namespace std;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 4,7 @@
// Let Catch provide main():
#define CATCH_CONFIG_MAIN

#include "../vendor/catch/catch.hpp"
#include "catch.hpp"

// That's it

Expand Down
2 changes: 1 addition & 1 deletion pyfuge/py_fiseval/fiseval_bindings.cpp
Original file line number Diff line number Diff line change
@@ -1,4 1,4 @@
#include "FISEval/cpp/hpp/fis.h"
#include "fis.h"
#include <pybind11/numpy.h>
#include <pybind11/pybind11.h>

Expand Down
126 changes: 95 additions & 31 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,40 1,102 @@
import glob
import os
import platform
import re
import subprocess
import sys
import sysconfig
from distutils.version import LooseVersion
from shutil import copyfile, copymode

from setuptools import setup, find_packages, Extension
from setuptools import Extension, find_packages, setup
from setuptools.command.build_ext import build_ext

HERE = os.path.dirname(os.path.abspath(__file__))

extra_compile_args = ["-fopenmp"]
extra_link_args = ["-fopenmp"]

if sys.platform == "win32":
extra_compile_args = ["-D_hypot=hypot", "-openmp"]
extra_link_args = ["-static"]

pyfuge_module = Extension(
'pyfuge_c',
include_dirs=[
os.path.join(HERE,
'pyfuge/py_fiseval/FISEval/cpp/vendor/catch'),
os.path.join(HERE,
'pyfuge/py_fiseval/FISEval/cpp/vendor/eigen'),
os.path.join(HERE,
'pyfuge/py_fiseval/pybind11/include'),
],
sources=(
# sources for fiseval itself
glob.glob(os.path.join(HERE, 'pyfuge/py_fiseval/FISEval/cpp/src/*.cpp'))

# sources for the python bindings
glob.glob(os.path.join(HERE, 'pyfuge/py_fiseval/*.cpp'))
),
depends=glob.glob(
os.path.join(HERE, 'pyfuge/py_fiseval/FISEval/cpp/src/*.hpp')),
extra_compile_args=extra_compile_args,
extra_link_args=extra_link_args,
)

class CMakeExtension(Extension):
def __init__(self, name, sourcedir=''):
Extension.__init__(self, name, sources=[])
self.sourcedir = os.path.abspath(sourcedir)


class CMakeBuild(build_ext):
def run(self):
try:
out = subprocess.check_output(['cmake', '--version'])
except OSError:
raise RuntimeError(
"CMake must be installed to build the following extensions: "
", ".join(e.name for e in self.extensions))

if platform.system() == "Windows":
cmake_version = LooseVersion(re.search(r'version\s*([\d.] )',
out.decode()).group(1))
if cmake_version < '3.1.0':
raise RuntimeError("CMake >= 3.1.0 is required on Windows")

for ext in self.extensions:
self.build_extension(ext)

def build_extension(self, ext):
extdir = os.path.abspath(
os.path.dirname(self.get_ext_fullpath(ext.name)))
cmake_args = [
'-DCMAKE_TOOLCHAIN_FILE={}/scripts/buildsystems/vcpkg.cmake'.format(
os.environ["VCPKG_ROOT"]),
'-DCMAKE_LIBRARY_OUTPUT_DIRECTORY=' extdir,
'-DPYTHON_EXECUTABLE=' sys.executable
]

cfg = 'Debug' if self.debug else 'Release'
build_args = ['--config', cfg]

if platform.system() == "Windows":
cmake_args = ['-DCMAKE_LIBRARY_OUTPUT_DIRECTORY_{}={}'.format(
cfg.upper(),
extdir)]
if sys.maxsize > 2**32:
cmake_args = ['-A', 'x64']
build_args = ['--', '/m']
else:
cmake_args = ['-DCMAKE_BUILD_TYPE=' cfg]
# build_args = ['--', '-j2']

env = os.environ.copy()
env['CXXFLAGS'] = '{} -DVERSION_INFO=\\"{}\\"'.format(
env.get('CXXFLAGS', ''),
self.distribution.get_version())
if not os.path.exists(self.build_temp):
os.makedirs(self.build_temp)
subprocess.check_call(['cmake', ext.sourcedir] cmake_args,
cwd=self.build_temp, env=env)
subprocess.check_call(['cmake', '--build', '.'] build_args,
cwd=self.build_temp)
# Copy *_test file to tests directory
# test_bin = os.path.join(self.build_temp, 'python_cpp_example_test')
# self.copy_test_file(test_bin)
print() # Add an empty line for cleaner output

def copy_test_file(self, src_file):
'''
Copy ``src_file`` to ``dest_file`` ensuring parent directory exists.
By default, message like `creating directory /path/to/package` and
`copying directory /src/path/to/package -> path/to/package` are displayed on standard output. Adapted from scikit-build.
'''
# Create directory if needed
dest_dir = os.path.join(os.path.dirname(
os.path.abspath(__file__)), 'tests', 'bin')
if dest_dir != "" and not os.path.exists(dest_dir):
print("creating directory {}".format(dest_dir))
os.makedirs(dest_dir)

# Copy file
dest_file = os.path.join(dest_dir, os.path.basename(src_file))
print("copying {} -> {}".format(src_file, dest_file))
copyfile(src_file, dest_file)
copymode(src_file, dest_file)


pyfuge_module = CMakeExtension("pyfuge")

setup(
name='pyfuge',
Expand All @@ -44,6 106,7 @@
url='http://iict-space.heig-vd.ch/cpn/',
long_description=open(os.path.join(HERE, "README.md")).read(),
ext_modules=[pyfuge_module],
cmdclass=dict(build_ext=CMakeBuild),
packages=find_packages(exclude=[
"*playground*", "*.tests", "*.tests.*", "tests.*", "tests"
]),
Expand All @@ -58,4 121,5 @@
],
setup_requires=['pytest-runner'],
tests_require=["pytest==3.3.2"],
zip_safe=False,
)

0 comments on commit 34579b5

Please sign in to comment.