Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[MRG+1] ENH: only call clock() if verbosity level warrants it #10091

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

Merged

Conversation

oleksandr-pavlyk
Copy link
Contributor

Put calls to clock() in routines in _barnes_hut_tsne.pyx inside conditional statements, so that clock() is only called when verbosity level warrants it.

This helps combat thread contention when executing TSNE in sklearn, when native extensions are compiled with icc.

Running TSNE on MNIST dataset (training + validation + test) of 70_000 hand-written images 28 by 28 pixels each, time of TSNE drops from 92 seconds to 81 seconds from this change alone.

This is the Intel (R) Vtune (TM) Amplifier snapshot with unmodified scikit-learn 0.19.1 sources, compiled with Intel (R) C Compiler, showing significant thread spinning, and clock being a bottleneck:

image

running the following example

import numpy as np
import gzip
import pickle
from sklearn.manifold.t_sne import TSNE

import os, os.path
fn = "mnist.pkl.gz"
if not os.path.exists(fn):
    def download_file(url):
        import requests
        local_filename = url.split('/')[-1]
        r = requests.get(url, stream=True)
        with open(local_filename, 'wb') as f:
            for chunk in r.iter_content(chunk_size=1024): 
                if chunk:
                    f.write(chunk)
        return local_filename

    url = "http://deeplearning.net/data/mnist/"
    download_file(url + fn)

with gzip.open(fn, "rb") as f:
    train, val, test = pickle.load(f, encoding='latin1')

X = np.vstack((train[0], val[0], test[0]))
y = np.hstack((train[1], val[1], test[1]))

sz=3000
np.random.seed(112017)
pos = np.random.choice(len(y), sz, replace=False)

def _embed(X):
    return TSNE(init='pca').fit_transform(X)

import timeit
t0 = timeit.default_timer()
X2d = _embed(X[pos])
t1 = timeit.default_timer()

print(t1-t0)

After the change, the VTune trace looks better (no thread spinning):

image

The execution also becomes faster, 81 seconds after the change, with 91 seconds before.

Copy link
Member

@jnothman jnothman left a comment

Choose a reason for hiding this comment

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

clock_it is a bit of an unconventional name (timing or use_clock might be more conventional), but otherwise LGTM

@jnothman jnothman changed the title MAINT: only call clock() if verbosity level warrants it [MRG+1] MAINT: only call clock() if verbosity level warrants it Nov 8, 2017
@jnothman jnothman changed the title [MRG+1] MAINT: only call clock() if verbosity level warrants it [MRG+1] ENH: only call clock() if verbosity level warrants it Nov 8, 2017
Put calls to `clock()` inside conditional statements.

This helps combat thread contention when executing TSNE in sklearn, compiled with icc.

Running TSNE on MNIST dataset (training + validation + test) of 70_000 hand-written images 28 by 28 pixels each, time of TSNE drops from 92 seconds to 81 seconds from this change alone.
@oleksandr-pavlyk oleksandr-pavlyk force-pushed the tsne-call-clock-if-needed branch from 9a05a89 to 1ac0c31 Compare November 8, 2017 23:49
@codecov
Copy link

codecov bot commented Nov 8, 2017

Codecov Report

Merging #10091 into master will not change coverage.
The diff coverage is n/a.

Impacted file tree graph

@@           Coverage Diff           @@
##           master   #10091   +/-   ##
=======================================
  Coverage   96.19%   96.19%           
=======================================
  Files         337      337           
  Lines       62772    62772           
=======================================
  Hits        60386    60386           
  Misses       2386     2386

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 3fa7a06...1ac0c31. Read the comment docs.

@oleksandr-pavlyk
Copy link
Contributor Author

@jnothman I have renamed clock_it to take_timing.

@lesteve
Copy link
Member

lesteve commented Nov 10, 2017

LGTM, merging, thanks!

@lesteve lesteve merged commit 01e0639 into scikit-learn:master Nov 10, 2017
maskani-moh pushed a commit to maskani-moh/scikit-learn that referenced this pull request Nov 15, 2017
…#10091)

Put calls to `clock()` inside conditional statements.

This helps combat thread contention when executing TSNE in sklearn, compiled with icc.

Running TSNE on MNIST dataset (training + validation + test) of 70_000 hand-written images 28 by 28 pixels each, time of TSNE drops from 92 seconds to 81 seconds from this change alone.
jwjohnson314 pushed a commit to jwjohnson314/scikit-learn that referenced this pull request Dec 18, 2017
…#10091)

Put calls to `clock()` inside conditional statements.

This helps combat thread contention when executing TSNE in sklearn, compiled with icc.

Running TSNE on MNIST dataset (training + validation + test) of 70_000 hand-written images 28 by 28 pixels each, time of TSNE drops from 92 seconds to 81 seconds from this change alone.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants