-
tqtg authored0411fd52
setup.py 10.13 KiB
# Copyright 2018 The Cornac Authors. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================
"""
Release instruction:
- Check that tests run correctly with all CI tools.
- Change __version__ in setup.py, cornac/__init__.py, docs/source/conf.py.
- Commit and release a version on GitHub, Actions will be triggered to build and upload to PyPI.
- Update conda-forge feedstock with new version and SHA256 hash of the new .tar.gz archive on PyPI (optional), the conda-forge bot will detect a new version and create PR after a while.
- Check on https://anaconda.org/conda-forge/cornac that new version is available for all platforms.
"""
import os
import sys
import glob
from setuptools import Extension, setup, find_packages
import numpy as np
try:
from Cython.Build import cythonize
from Cython.Distutils import build_ext
except ImportError:
USE_CYTHON = False
else:
USE_CYTHON = True
with open("README.md", "r") as fh:
long_description = fh.read()
USE_OPENMP = True
def extract_gcc_binaries():
"""Try to find GCC on OSX for OpenMP support."""
patterns = [
"/opt/local/bin/g++-mp-[0-9].[0-9]",
"/opt/local/bin/g++-mp-[0-9]",
"/usr/local/bin/g++-[0-9].[0-9]",
"/usr/local/bin/g++-[0-9]",
]
if sys.platform.startswith("darwin"):
gcc_binaries = []
for pattern in patterns:
gcc_binaries += glob.glob(pattern)
gcc_binaries.sort()
if gcc_binaries:
_, gcc = os.path.split(gcc_binaries[-1])
return gcc
else:
return None
else:
return None
if sys.platform.startswith("win"):
# compile args from
# https://msdn.microsoft.com/en-us/library/fwkeyyhe.aspx
compile_args = ["/O2", "/openmp"]
link_args = []
else:
gcc = extract_gcc_binaries()
if gcc is not None:
rpath = "/usr/local/opt/gcc/lib/gcc/" + gcc[-1] + "/"
link_args = ["-Wl,-rpath," + rpath]
else:
link_args = []
compile_args = [
"-Wno-unused-function",
"-Wno-maybe-uninitialized",
"-O3",
"-ffast-math",
]
if sys.platform.startswith("darwin"):
if gcc is not None:
os.environ["CC"] = gcc
os.environ["CXX"] = gcc
else:
USE_OPENMP = False
print("No GCC available. Install gcc from Homebrew using brew install gcc.")
# required arguments for default gcc of OSX
compile_args.extend(["-O2", "-stdlib=libc++", "-mmacosx-version-min=10.7"])
link_args.extend(["-O2", "-stdlib=libc++", "-mmacosx-version-min=10.7"])
if USE_OPENMP:
compile_args.append("-fopenmp")
link_args.append("-fopenmp")
compile_args.append("-std=c++11")
link_args.append("-std=c++11")
ext = ".pyx" if USE_CYTHON else ".cpp"
extensions = [
Extension(
name="cornac.models.c2pf.c2pf",
sources=[
"cornac/models/c2pf/cython/c2pf" + ext,
"cornac/models/c2pf/cpp/cpp_c2pf.cpp",
],
include_dirs=[
"cornac/models/c2pf/cpp/",
"cornac/utils/external/eigen/Eigen",
"cornac/utils/external/eigen/unsupported/Eigen/",
],
language="c++",
),
Extension(
name="cornac.models.nmf.recom_nmf",
sources=["cornac/models/nmf/recom_nmf" + ext],
include_dirs=[np.get_include()],
language="c++",
),
Extension(
name="cornac.models.pmf.pmf",
sources=["cornac/models/pmf/cython/pmf" + ext],
language="c++",
),
Extension(
name="cornac.models.mcf.mcf",
sources=["cornac/models/mcf/cython/mcf" + ext],
language="c++",
),
Extension(
name="cornac.models.sorec.sorec",
sources=["cornac/models/sorec/cython/sorec" + ext],
language="c++",
),
Extension(
"cornac.models.hpf.hpf",
sources=[
"cornac/models/hpf/cython/hpf" + ext,
"cornac/models/hpf/cpp/cpp_hpf.cpp",
],
include_dirs=[
"cornac/models/hpf/cpp/",
"cornac/utils/external/eigen/Eigen",
"cornac/utils/external/eigen/unsupported/Eigen/",
],
language="c++",
),
Extension(
name="cornac.models.mf.recom_mf",
sources=["cornac/models/mf/recom_mf" + ext],
include_dirs=[np.get_include()],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.baseline_only.recom_bo",
sources=["cornac/models/baseline_only/recom_bo" + ext],
include_dirs=[np.get_include()],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.efm.recom_efm",
sources=["cornac/models/efm/recom_efm" + ext],
include_dirs=[np.get_include()],
language="c++",
),
Extension(
name="cornac.models.comparer.recom_comparer_obj",
sources=["cornac/models/comparer/recom_comparer_obj" + ext],
include_dirs=[np.get_include()],
language="c++",
),
Extension(
name="cornac.models.bpr.recom_bpr",
sources=["cornac/models/bpr/recom_bpr" + ext],
include_dirs=[np.get_include(), "cornac/utils/external"],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.bpr.recom_wbpr",
sources=["cornac/models/bpr/recom_wbpr" + ext],
include_dirs=[np.get_include(), "cornac/utils/external"],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.sbpr.recom_sbpr",
sources=["cornac/models/sbpr/recom_sbpr" + ext],
include_dirs=[np.get_include(), "cornac/utils/external"],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.mter.recom_mter",
sources=["cornac/models/mter/recom_mter" + ext],
include_dirs=[np.get_include(), "cornac/utils/external"],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.comparer.recom_comparer_sub",
sources=["cornac/models/comparer/recom_comparer_sub" + ext],
include_dirs=[np.get_include(), "cornac/utils/external"],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.mmmf.recom_mmmf",
sources=["cornac/models/mmmf/recom_mmmf" + ext],
include_dirs=[np.get_include(), "cornac/utils/external"],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.models.knn.similarity",
sources=["cornac/models/knn/similarity" + ext],
include_dirs=[np.get_include()],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.utils.fast_dict",
sources=["cornac/utils/fast_dict" + ext],
include_dirs=[np.get_include()],
language="c++",
),
Extension(
name="cornac.utils.fast_dot",
sources=["cornac/utils/fast_dot" + ext],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
),
Extension(
name="cornac.utils.fast_sparse_funcs",
sources=["cornac/utils/fast_sparse_funcs" + ext],
include_dirs=[np.get_include()],
language="c++",
),
]
if sys.platform.startswith("linux"): # Linux supported only
extensions += [
Extension(
name="cornac.models.fm.recom_fm",
sources=["cornac/models/fm/recom_fm" + ext],
include_dirs=[
np.get_include(),
"cornac/models/fm/libfm/util",
"cornac/models/fm/libfm/fm_core/",
"cornac/models/fm/libfm/libfm/src/",
],
language="c++",
extra_compile_args=compile_args,
extra_link_args=link_args,
)
]
cmdclass = {}
# cythonize c++ modules
if USE_CYTHON:
extensions = cythonize(extensions)
cmdclass.update({"build_ext": build_ext})
setup(
name="cornac",
version="1.15.2",
description="A Comparative Framework for Multimodal Recommender Systems",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://cornac.preferred.ai",
keywords=[
"recommender system",
"collaborative filtering",
"multimodal",
"preference learning",
"recommendation",
],
ext_modules=extensions,
install_requires=["numpy", "scipy", "tqdm>=4.19", "powerlaw"],
extras_require={"tests": ["pytest", "pytest-pep8", "pytest-xdist", "pytest-cov"]},
cmdclass=cmdclass,
packages=find_packages(),
classifiers=[
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Science/Research",
"Intended Audience :: Education",
"Intended Audience :: Developers",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"License :: OSI Approved :: Apache Software License",
"Topic :: Software Development",
"Topic :: Scientific/Engineering",
],
)