Skip to content
Open
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
6 changes: 6 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Language: Cpp
BasedOnStyle: Google
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false
PenaltyBreakComment: 100
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ nosetests.xml

# Project specific
tsne/bh_sne.cpp
tsne/bh_sne_3d.cpp
tsne/bh_sne_src/bh_tsne
*.pkl.gz
.cache
.pytest_cache/
31 changes: 8 additions & 23 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,37 +1,22 @@
language: python

python:
- "2.7"
# - "3.4"
- "2.7"
compiler: clang
env:
- CC="clang" CXX="clang++" LDFLAGS="-fuse-ld=lld"

dist: xenial
addons:
apt:
packages:
- build-essential
- libatlas-base-dev

sudo: false
- liblapack3

install:
- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then
wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh -O miniconda.sh;
else
wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
fi
- bash miniconda.sh -b -p $HOME/miniconda
- export PATH="$HOME/miniconda/bin:$PATH"
- conda config --set always_yes yes --set changeps1 no
- conda update -q conda
- conda info -a

- conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION
- source activate test-environment
- conda install numpy cython scipy pytest scikit-learn
- python setup.py install
- source deactivate

- pip install numpy==1.14.2 cython==0.28.2 pytest==3.5.1 scikit-learn==0.19.1 scipy==1.0.1
script:
- pwd
- source activate test-environment
- python setup.py install
- cd tsne/tests
- py.test -s -vv
44 changes: 35 additions & 9 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,13 +1,39 @@
build:
python setup.py build_ext --inplace
.PHONY: build

install:
python setup.py build_ext --inplace
python setup.py install
build: setup.py tsne/bh_sne.pyx \
$(wildcard tsne/bh_sne_src/*.h) \
$(wildcard tsne/bh_sne_src/*.cpp)
python $< build_ext --inplace

sdist:
python setup.py sdist
PROFILE_LOCATION=$(shell pwd)/profile

$(PROFILE_LOCATION)/bh_sne.profdata: PROFILE=generate
$(PROFILE_LOCATION)/bh_sne.profdata: setup.py Makefile tsne/bh_sne.pyx \
$(wildcard tsne/bh_sne_src/*.h) \
$(wildcard tsne/bh_sne_src/*.cpp)
rm -rf build tsne/*.so *.so $(PROFILE_LOCATION)/*.profraw
PROFILE=generate python $< build_ext --inplace
mkdir -p $(PROFILE_LOCATION)
cd tsne/tests && LLVM_PROFILE_FILE="$(PROFILE_LOCATION)/%p-%m.profraw" py.test
llvm-profdata merge -output=$@ $(PROFILE_LOCATION)/*.profraw
rm -rf tsne/*.so *.so build tsne/*.o

build_pgo: setup.py $(PROFILE_LOCATION)/bh_sne.profdata
PROFILE="$(PROFILE_LOCATION)/bh_sne.profdata" python $< build_ext --inplace

install: setup.py build
python $< install

sdist: setup.py tsne/bh_sne.pyx \
$(wildcard tsne/bh_sne_src/*.h) \
$(wildcard tsne/bh_sne_src/*.cpp)
python $< sdist

test: build
cd tsne/tests && time py.test -s -vv

clean:
rm -rf *.pyc *.so build/ bh_sne.cpp
rm -rf tsne/*.pyc tsne/*.so tsne/build/ tsne/bh_sne.cpp
make -C tsne/bh_sne_src clean
rm -rf *.pyc *.so build/ profile/ bh_sne.cpp
rm -rf tsne/*.pyc tsne/*.so tsne/*.o tsne/build/ tsne/bh_sne.cpp
rm -rf .pytest_cache/
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ Requirements
* [numpy](numpy.scipy.org) > =1.7.1
* [scipy](http://www.scipy.org/) >= 0.12.0
* [cython](cython.org) >= 0.19.1
* [cblas](http://www.netlib.org/blas/) or [openblas](https://github.com/xianyi/OpenBLAS). Tested version is v0.2.5 and v0.2.6 (not necessary for OSX).

[Anaconda](http://continuum.io/downloads) is recommended.

Expand Down
57 changes: 34 additions & 23 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
"""

import sys
import os
import platform

from distutils.core import setup
Expand All @@ -28,35 +29,45 @@

if v2 >= 10:
# More than 10.10
extra_compile_args=['-I/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/Headers']
extra_compile_args = [
'-I/System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/Headers']
else:
extra_compile_args=['-I/System/Library/Frameworks/vecLib.framework/Headers']
extra_compile_args = [
'-I/System/Library/Frameworks/vecLib.framework/Headers']

ext_modules = [Extension(name='bh_sne',
sources=['tsne/bh_sne_src/sptree.cpp', 'tsne/bh_sne_src/tsne.cpp', 'tsne/bh_sne.pyx'],
include_dirs=[numpy.get_include(), 'tsne/bh_sne_src/'],
extra_compile_args=extra_compile_args + ['-ffast-math', '-O3'],
extra_link_args=['-Wl,-framework', '-Wl,Accelerate', '-lcblas'],
language='c++')]
sources=['tsne/bh_sne_src/sptree.cpp',
'tsne/bh_sne_src/tsne.cpp', 'tsne/bh_sne.pyx'],
include_dirs=[
numpy.get_include(), 'tsne/bh_sne_src/'],
extra_compile_args=extra_compile_args +
['-ffast-math', '-O3', '-std=c++14'],
extra_link_args=['-Wl,-framework',
'-Wl,Accelerate'],
language='c++')]

else:
# LINUX

opt_flags = ['-msse3', '-O3', '-flto']
if 'PROFILE' in os.environ:
if os.environ['PROFILE'] == 'generate':
opt_flags.append('-fprofile-instr-generate')
elif os.path.isfile(os.environ['PROFILE']):
opt_flags.append('-fprofile-instr-use='+os.environ['PROFILE'])
ldflags = list(opt_flags)
if 'LDFLAGS' in os.environ and os.environ['LDFLAGS']:
ldflags.extend(os.environ['LDFLAGS'].split(' '))
ldflags.extend(['-Wl,-Bdynamic,--as-needed', '-lgcc_s'])
ext_modules = [Extension(name='bh_sne',
sources=['tsne/bh_sne_src/sptree.cpp', 'tsne/bh_sne_src/tsne.cpp', 'tsne/bh_sne.pyx'],
include_dirs=[numpy.get_include(), '/usr/local/include', 'tsne/bh_sne_src/'],
library_dirs=['/usr/local/lib', '/usr/lib64/atlas'],
extra_compile_args=['-msse3', '-O3', '-fPIC', '-w', '-ffast-math'],
extra_link_args=['-Wl,-Bdynamic,--as-needed', '-lgcc_s'],
language='c++'),

Extension(name='bh_sne_3d',
sources=['tsne/bh_sne_src/sptree.cpp', 'tsne/bh_sne_src/tsne.cpp', 'tsne/bh_sne_3d.pyx'],
include_dirs=[numpy.get_include(), '/usr/local/include', 'tsne/bh_sne_src/'],
library_dirs=['/usr/local/lib', '/usr/lib64/atlas'],
extra_compile_args=['-msse3', '-O3', '-fPIC', '-w', '-ffast-math', '-DTSNE3D'],
extra_link_args=['-Wl,-Bdynamic,--as-needed', '-lgcc_s'],
language='c++')]
sources=['tsne/bh_sne_src/sptree.cpp',
'tsne/bh_sne_src/tsne.cpp', 'tsne/bh_sne.pyx'],
include_dirs=[
numpy.get_include(), 'tsne/bh_sne_src/'],
extra_compile_args=opt_flags +
['-Wall', '-fPIC', '-std=c++14', '-w'],
extra_link_args=ldflags,
language='c++'),
]

ext_modules = cythonize(ext_modules)

Expand All @@ -77,4 +88,4 @@
packages=find_packages(),
ext_modules=ext_modules,
install_requires=required
)
)
16 changes: 8 additions & 8 deletions tsne/__init__.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# encoding: utf-8
from __future__ import division

import numpy as np
import scipy.linalg as la
import sys
from bh_sne import BH_SNE
from bh_sne_3d import BH_SNE_3D


def bh_sne(data, pca_d=None, d=2, perplexity=30., theta=0.5,
random_state=None, copy_data=False, init=None,
Expand Down Expand Up @@ -79,17 +80,16 @@ def bh_sne(data, pca_d=None, d=2, perplexity=30., theta=0.5,
if mom_switch_iter is None:
mom_switch_iter = 250

if d == 2:
tsne = BH_SNE()
elif d == 3:
tsne = BH_SNE_3D()
else:
if d != 2 and d != 3:
raise Exception("TSNE dimensions must be 2 or 3")

Y = tsne.run(X, N, X.shape[1], d, perplexity, theta, seed, init=init, use_init=use_init,
max_iter=max_iter, stop_lying_iter=stop_lying_iter, mom_switch_iter=mom_switch_iter)
Y = BH_SNE.run(X, d,
perplexity, theta,
seed, init=init, use_init=use_init,
max_iter=max_iter, stop_lying_iter=stop_lying_iter, mom_switch_iter=mom_switch_iter)
return Y


from ._version import get_versions
__version__ = get_versions()['version']
del get_versions
41 changes: 25 additions & 16 deletions tsne/bh_sne.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -5,24 +5,33 @@ cimport cython
from libcpp cimport bool

cdef extern from "tsne.h":
cdef cppclass TSNE:
TSNE()
void run(double* X, int N, int D, double* Y, int no_dims, double perplexity, double theta, int rand_seed, bool skip_random_init, double *init, bool use_init, int max_iter, int stop_lying_iter, int mom_switch_iter)
void _c_run "run" (
double* X, int N, int D, double* Y,
int no_dims, double perplexity,
double theta, int rand_seed,
bool skip_random_init, double *init, bool use_init,
int max_iter, int stop_lying_iter, int mom_switch_iter) nogil

cdef class BH_SNE:
cdef TSNE* thisptr # hold a C++ instance

def __cinit__(self):
self.thisptr = new TSNE()

def __dealloc__(self):
del self.thisptr

@cython.boundscheck(False)
@cython.wraparound(False)
def run(self, X, N, D, d, perplexity, theta, seed, init, use_init, max_iter, stop_lying_iter, mom_switch_iter):
cdef np.ndarray[np.float64_t, ndim=2, mode='c'] _X = np.ascontiguousarray(X)
cdef np.ndarray[np.float64_t, ndim=2, mode='c'] _init = np.ascontiguousarray(init)
cdef np.ndarray[np.float64_t, ndim=2, mode='c'] Y = np.zeros((N, d), dtype=np.float64)
self.thisptr.run(&_X[0,0], N, D, &Y[0,0], d, perplexity, theta, seed, False, &_init[0,0], use_init, max_iter, stop_lying_iter, mom_switch_iter)
@staticmethod
def run(X, int d,
double perplexity, double theta,
int seed, init, bool use_init,
int max_iter, int stop_lying_iter, int mom_switch_iter):
cdef int N = X.shape[0]
cdef int D = X.shape[1]
cdef np.ndarray[np.float64_t, ndim=2, mode='c'] _X = np.ascontiguousarray(
X, dtype=np.float64)
cdef np.ndarray[np.float64_t, ndim=2, mode='c'] _init = np.ascontiguousarray(
init, dtype=np.float64)
cdef np.ndarray[np.float64_t, ndim=2, mode='c'] Y = np.zeros(
(N, d), dtype=np.float64, order='C')
with nogil:
_c_run(&_X[0,0], N, D, &Y[0,0],
d, perplexity,
theta, seed,
False, &_init[0,0], use_init,
max_iter, stop_lying_iter, mom_switch_iter)
return Y
28 changes: 0 additions & 28 deletions tsne/bh_sne_3d.pyx

This file was deleted.

23 changes: 10 additions & 13 deletions tsne/bh_sne_src/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,22 @@
#CFLAGS = -march=haswell -ffast-math -O3 -Rpass=loop-vectorize -Rpass-missed=loop-vectorize -Rpass-analysis=loop-vectorize
#CFLAGS = -march=haswell -ffast-math -O3

CXX = g++
CFLAGS = -ffast-math -O3
CXX?=g++
CFLAGS?=-ffast-math -O3 -Wall -std=c++14

all: bh_tsne bh_tsne_3d
all: bh_tsne

bh_tsne: tsne.o sptree.o
$(CXX) $(CFLAGS) tsne.o sptree.o -o bh_tsne

bh_tsne_3d: tsne_3d.o sptree.o
$(CXX) $(CFLAGS) tsne_3d.o sptree.o -o bh_tsne_3d
bh_tsne: main.o tsne.o sptree.o
$(CXX) $(CFLAGS) $(LDFLAGS) $^ -o $@

sptree.o: sptree.cpp sptree.h
$(CXX) $(CFLAGS) -c sptree.cpp
$(CXX) $(CFLAGS) -c $<

tsne.o: tsne.cpp tsne.h sptree.h vptree.h
$(CXX) $(CFLAGS) -c tsne.cpp
$(CXX) $(CFLAGS) -c $<

tsne_3d.o: tsne.cpp tsne.h sptree.h vptree.h
$(CXX) $(CFLAGS) -DTSNE3D -c tsne.cpp
main.o: main.cpp tsne.h
$(CXX) $(CFLAGS) -c $<

clean:
rm -Rf *.o bh_tsne bh_tsne_3d
rm -Rf *.o bh_tsne
Loading