From 8796d431cef16f271a7c6ab1a3d64b2a32eac0f7 Mon Sep 17 00:00:00 2001 From: frkhit Date: Fri, 14 Dec 2018 00:08:41 +0800 Subject: [PATCH 1/2] support py3.6+linux --- README.md | 2 +- requirements.txt | 11 +++++----- science_rcn/dilation/dilation.cc | 35 ++++++++++++++++++++++++++++---- science_rcn/inference.py | 5 ++--- science_rcn/preproc.py | 4 ++-- science_rcn/run.py | 4 ++-- setup.py | 9 ++++---- 7 files changed, 48 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 964ce32..fe66ebb 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ Reference implementation of a two-level RCN model on MNIST classification. See t ## Setup -Note: Python 2.7 is supported. The code was tested on OSX 10.11. It may work on other system platforms but not guaranteed. +Note: Python 2.7 and python 3.6 is supported. The code was tested on OSX 10.11. It may work on other system platforms but not guaranteed. Before starting please make sure gcc is installed (`brew install gcc`) and up to date in order to compile the various dependencies (particularly numpy). diff --git a/requirements.txt b/requirements.txt index 85af58d..b9256bd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,6 @@ -decorator==4.1.2 +decorator>=4.1.2 networkx==1.11 -numpy==1.13.3 -olefile==0.44 -Pillow==4.1.1 -rcn-ref==1.0.0 -scipy==0.19.1 +numpy>=1.13.3 +olefile>=0.44 +Pillow>=4.1.1 +scipy>=0.19.1 diff --git a/science_rcn/dilation/dilation.cc b/science_rcn/dilation/dilation.cc index bc2d63b..535180a 100644 --- a/science_rcn/dilation/dilation.cc +++ b/science_rcn/dilation/dilation.cc @@ -24,13 +24,40 @@ static PyMethodDef dilationmethods[] = { /* ==== Initialize the C_test functions ====================== */ -extern "C" { -void init_dilation() +/* This initiates the module using the above definitions. */ +#if PY_VERSION_HEX >= 0x03000000 +static struct PyModuleDef moduledef = { + PyModuleDef_HEAD_INIT, + "_dilation", + NULL, + -1, + dilationmethods, + NULL, + NULL, + NULL, + NULL +}; + +PyMODINIT_FUNC PyInit__dilation(void) { - (void) Py_InitModule("_dilation", dilationmethods); - import_array(); // Must be present for NumPy. Called first after above line. + PyObject *m; + m = PyModule_Create(&moduledef); + if (!m) { + return NULL; + } + return m; } +#else +PyMODINIT_FUNC init_dilation(void) +{ + PyObject *m; + + m = Py_InitModule("_dilation", dilationmethods); + if (m == NULL) { + return; + } } +#endif /// Check condition and return NULL (which will cause a python exception) if /// it's false, and include an arbitrary format string as the error message diff --git a/science_rcn/inference.py b/science_rcn/inference.py index 3fb936b..fbb6672 100644 --- a/science_rcn/inference.py +++ b/science_rcn/inference.py @@ -6,7 +6,6 @@ Note that we use a faster implementation of 2D dilation, instead of the slower scipy.ndimage.morphology.grey_dilation. """ -from itertools import izip import logging import numpy as np import networkx as nx @@ -56,7 +55,7 @@ def test_image(img, model_factors, # Forward pass inference fp_scores = np.zeros(len(model_factors[0])) - for i, (frcs, _, graph) in enumerate(izip(*model_factors)): + for i, (frcs, _, graph) in enumerate(list(zip(*model_factors))): fp_scores[i] = forward_pass(frcs, bu_msg, graph, @@ -315,7 +314,7 @@ def infer_pbp(self): """Parallel loopy BP message passing, modifying state of `lat_messages`. See bwd_pass() for parameters. """ - for it in xrange(self.n_iters): + for it in range(self.n_iters): new_lat_messages = self.new_messages() delta = new_lat_messages - self.lat_messages self.lat_messages += self.damping * delta diff --git a/science_rcn/preproc.py b/science_rcn/preproc.py index 4ff9733..e8cd471 100644 --- a/science_rcn/preproc.py +++ b/science_rcn/preproc.py @@ -131,7 +131,7 @@ def generate_suppression_masks(filter_scale=4., num_orients=16): # Compute for orientations [0, pi), then flip for [pi, 2*pi) for i, angle in enumerate(np.linspace(0., np.pi, num_orients // 2, endpoint=False)): x, y = np.cos(angle), np.sin(angle) - for r in xrange(1, int(np.sqrt(2) * size / 2)): + for r in range(1, int(np.sqrt(2) * size / 2)): dx, dy = round(r * x), round(r * y) if abs(dx) > cx or abs(dy) > cy: continue @@ -160,7 +160,7 @@ def local_nonmax_suppression(filtered, suppression_masks, num_orients=16): localized = np.zeros_like(filtered) cross_orient_max = filtered.max(0) filtered[filtered < 0] = 0 - for i, (layer, suppress_mask) in enumerate(zip(filtered, suppression_masks)): + for i, (layer, suppress_mask) in enumerate(list(zip(filtered, suppression_masks))): competitor_maxs = maximum_filter(layer, footprint=suppress_mask, mode='nearest') localized[i] = competitor_maxs <= layer localized[cross_orient_max > filtered] = 0 diff --git a/science_rcn/run.py b/science_rcn/run.py index 97de75d..cb43722 100644 --- a/science_rcn/run.py +++ b/science_rcn/run.py @@ -81,7 +81,7 @@ def run_experiment(data_dir='data/MNIST', train_partial = partial(train_image, perturb_factor=perturb_factor) train_results = pool.map_async(train_partial, [d[0] for d in train_data]).get(9999999) - all_model_factors = zip(*train_results) + all_model_factors = list(zip(*train_results)) LOG.info("Testing on {} images...".format(len(test_data))) test_partial = partial(test_image, model_factors=all_model_factors, @@ -92,7 +92,7 @@ def run_experiment(data_dir='data/MNIST', correct = 0 for test_idx, (winner_idx, _) in enumerate(test_results): correct += int(test_data[test_idx][1]) == winner_idx // (train_size // 10) - print "Total test accuracy = {}".format(float(correct) / len(test_results)) + print("Total test accuracy = {}".format(float(correct) / len(test_results))) return all_model_factors, test_results diff --git a/setup.py b/setup.py index 7c7df5d..91dc057 100644 --- a/setup.py +++ b/setup.py @@ -24,7 +24,7 @@ def _findRequirements(): # Check for MNIST data dir if not os.path.isdir('./data/MNIST'): if os.path.exists('./data/MNIST.zip'): - print "Extracting MNIST data..." + print("Extracting MNIST data...") with zipfile.ZipFile('./data/MNIST.zip', 'r') as z: z.extractall('./data/') else: @@ -62,9 +62,9 @@ def finalize_options(self): setup_requires=['numpy>=1.13.3'], install_requires=[ 'networkx>=1.11,<1.12', - 'numpy==1.13.3', - 'pillow>=4.1.0,<4.2', - 'scipy>=0.19.0,<0.20', + 'numpy>=1.13.3', + 'pillow>=4.1.0', + 'scipy>=0.19.0', 'setuptools>=36.5.0' ], ext_modules=[dilation_module], @@ -73,6 +73,7 @@ def finalize_options(self): 'Natural Language :: English', 'Operating System :: MacOS :: MacOS X', 'Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.6', 'Programming Language :: Python :: Implementation :: CPython', 'Programming Language :: C'], keywords='rcn', From fe736b9a7e6aab0591dfe33c18f9585887f7b2aa Mon Sep 17 00:00:00 2001 From: frkhit Date: Fri, 14 Dec 2018 23:43:48 +0800 Subject: [PATCH 2/2] fix bug: Segmentation fault (core dumped) fix bug for py3.6: Segmentation fault (core dumped) --- science_rcn/dilation/dilation.cc | 22 +++++++--------------- 1 file changed, 7 insertions(+), 15 deletions(-) diff --git a/science_rcn/dilation/dilation.cc b/science_rcn/dilation/dilation.cc index 535180a..fde1c9f 100644 --- a/science_rcn/dilation/dilation.cc +++ b/science_rcn/dilation/dilation.cc @@ -17,9 +17,9 @@ using namespace std; /* ==== Set up the methods table ====================== */ static PyMethodDef dilationmethods[] = { - {"max_filter1d", py_max_filter1d, METH_VARARGS}, - {"brute_max_filter1d", py_brute_max_filter1d, METH_VARARGS}, - {NULL, NULL} /* Sentinel - marks the end of this structure */ + {"max_filter1d", py_max_filter1d, METH_VARARGS, "max filter1d"}, + {"brute_max_filter1d", py_brute_max_filter1d, METH_VARARGS, "brute max filter1d"}, + {NULL, NULL, 0, NULL} }; @@ -40,22 +40,14 @@ static struct PyModuleDef moduledef = { PyMODINIT_FUNC PyInit__dilation(void) { - PyObject *m; - m = PyModule_Create(&moduledef); - if (!m) { - return NULL; - } - return m; + import_array(); + return PyModule_Create(&moduledef); } #else PyMODINIT_FUNC init_dilation(void) { - PyObject *m; - - m = Py_InitModule("_dilation", dilationmethods); - if (m == NULL) { - return; - } + (void) Py_InitModule("_dilation", dilationmethods); + import_array(); } #endif