diff --git a/digits/config/caffe_option.py b/digits/config/caffe_option.py index 70b8be2cc..ca8eea9d2 100644 --- a/digits/config/caffe_option.py +++ b/digits/config/caffe_option.py @@ -65,6 +65,8 @@ def validate(cls, value): if value == '': # Find the executable executable = cls.find_executable('caffe') + if not executable: + executable = cls.find_executable('caffe.exe') if not executable: raise config_option.BadValue('caffe binary not found in PATH') cls.validate_version(executable) @@ -187,6 +189,9 @@ def get_version(executable): elif platform.system() == 'Darwin': # XXX: guess and let the user figure out errors later return (0,11,0) + elif platform.system() == 'Windows': + # XXX: guess and let the user figure out errors later + return (0,12,0) else: print 'WARNING: platform "%s" not supported' % platform.system() return None @@ -197,6 +202,8 @@ def _set_config_dict_value(self, value): else: if value == '': executable = self.find_executable('caffe') + if not executable: + executable = self.find_executable('caffe.exe') else: executable = os.path.join(value, 'build', 'tools', 'caffe') diff --git a/digits/model/tasks/caffe_train.py b/digits/model/tasks/caffe_train.py index e73e0e6ce..bca562e93 100644 --- a/digits/model/tasks/caffe_train.py +++ b/digits/model/tasks/caffe_train.py @@ -231,7 +231,7 @@ def save_prototxt_files(self): val_data_layer.data_param.backend = caffe_pb2.DataParameter.LMDB if self.use_mean: mean_pixel = None - with open(self.dataset.path(self.dataset.train_db_task().mean_file)) as f: + with open(self.dataset.path(self.dataset.train_db_task().mean_file),'rb') as f: blob = caffe_pb2.BlobProto() blob.MergeFromString(f.read()) mean = np.reshape(blob.data, diff --git a/digits/task.py b/digits/task.py index 03d4bbd36..2aaf03c9a 100644 --- a/digits/task.py +++ b/digits/task.py @@ -15,6 +15,8 @@ from config import config_value from status import Status, StatusCls +import platform + # NOTE: Increment this everytime the pickled version changes PICKLE_VERSION = 1 @@ -128,7 +130,7 @@ def path(self, filename, relative=False): path = os.path.join(self.job_dir, filename) if relative: path = os.path.relpath(path, config_value('jobs_dir')) - return str(path) + return str(path).replace("\\","/") def ready_to_queue(self): """ @@ -193,7 +195,7 @@ def run(self, resources): stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=self.job_dir, - close_fds=True, + close_fds=False if platform.system() == 'Windows' else True, ) try: diff --git a/digits/utils/__init__.py b/digits/utils/__init__.py index daac0468e..a32460ca7 100644 --- a/digits/utils/__init__.py +++ b/digits/utils/__init__.py @@ -2,12 +2,15 @@ import os import math -import fcntl import locale from random import uniform from urlparse import urlparse from io import BlockingIOError import inspect +import platform + +if not platform.system() == 'Windows': + import fcntl HTTP_TIMEOUT = 6.05 @@ -27,8 +30,9 @@ def nonblocking_readlines(f): Newlines are normalized to the Unix standard. """ fd = f.fileno() - fl = fcntl.fcntl(fd, fcntl.F_GETFL) - fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) + if not platform.system() == 'Windows': + fl = fcntl.fcntl(fd, fcntl.F_GETFL) + fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) enc = locale.getpreferredencoding(False) buf = bytearray() diff --git a/docs/API.md b/docs/API.md index 5a22d3721..6bb6f8464 100644 --- a/docs/API.md +++ b/docs/API.md @@ -1,6 +1,6 @@ # REST API -*Generated Aug 05, 2015* +*Generated Aug 07, 2015* DIGITS exposes its internal functionality through a REST API. You can access these endpoints by performing a GET or POST on the route, and a JSON object will be returned. diff --git a/docs/FlaskRoutes.md b/docs/FlaskRoutes.md index 60e99d9a5..6e9a5bfe5 100644 --- a/docs/FlaskRoutes.md +++ b/docs/FlaskRoutes.md @@ -1,6 +1,6 @@ # Flask Routes -*Generated Aug 05, 2015* +*Generated Aug 07, 2015* Documentation on the various routes used internally for the web application. @@ -334,7 +334,7 @@ Location: [`digits/model/views.py@90`](../digits/model/views.py#L90) Methods: **GET** -Location: [`digits/views.py@245`](../digits/views.py#L245) +Location: [`digits/views.py@242`](../digits/views.py#L242) ### `/files/` diff --git a/scripts/generate_docs.py b/scripts/generate_docs.py index 708e7f686..29834632e 100755 --- a/scripts/generate_docs.py +++ b/scripts/generate_docs.py @@ -158,10 +158,10 @@ def _print_route(self, route): ) filename = os.path.normpath(route['location']['filename']) if filename.startswith(digits_root): - filename = os.path.relpath(filename, digits_root) + filename = os.path.relpath(filename, digits_root).replace("\\","/") self.w('Location: [`%s@%s`](%s#L%s)' % ( filename, route['location']['line'], - os.path.join('..', filename), route['location']['line'], + os.path.join('..', filename).replace("\\","/"), route['location']['line'], )) self.w() diff --git a/tools/create_db.py b/tools/create_db.py index 33c9916f4..30373099d 100755 --- a/tools/create_db.py +++ b/tools/create_db.py @@ -23,7 +23,7 @@ import numpy as np import PIL.Image -import leveldb + import lmdb from cStringIO import StringIO # must call digits.config.load_config() before caffe to set the path @@ -36,6 +36,12 @@ logger = logging.getLogger('digits.tools.create_db') +try: + import leveldb +except ImportError: + logger.warning('leveldb support is missing') + + class DbCreator: """ Creates a database for a neural network imageset @@ -286,7 +292,7 @@ def create(self, input_file, width, height, blob.channels, blob.height, blob.width = data.shape blob.data.extend(data.astype(float).flat) - with open(mean_file, 'w') as outfile: + with open(mean_file, 'wb') as outfile: outfile.write(blob.SerializeToString()) elif mean_file.lower().endswith(('.jpg', '.jpeg', '.png')): image = PIL.Image.fromarray(mean)