From 64f2ccbefd5851ed655836a03c9e1f5981a54fc4 Mon Sep 17 00:00:00 2001 From: Ali Ebrahim Date: Wed, 26 Mar 2014 22:23:00 -0700 Subject: [PATCH 1/5] Windows support Pymatbridge can be successfully used on Windows. messenger.c now can be compiled into a mex with visual studio --- messenger/src/messenger.c | 26 +++++++++++++------------- pymatbridge/pymatbridge.py | 5 ++++- setup.py | 24 ++++++++++++++---------- 3 files changed, 31 insertions(+), 24 deletions(-) diff --git a/messenger/src/messenger.c b/messenger/src/messenger.c index b9cca29..beb9a03 100644 --- a/messenger/src/messenger.c +++ b/messenger/src/messenger.c @@ -6,15 +6,15 @@ /* Set a 200MB receiver buffer size */ #define BUFLEN 200000000 -void *ctx, *socket; +void *ctx, *socket_ptr; static int initialized = 0; /* Initialize a ZMQ server */ int initialize(char *socket_addr) { - + int rc; ctx = zmq_ctx_new(); - socket = zmq_socket(ctx, ZMQ_REP); - int rc = zmq_bind(socket, socket_addr); + socket_ptr = zmq_socket(ctx, ZMQ_REP); + rc = zmq_bind(socket_ptr, socket_addr); if (!rc) { initialized = 1; @@ -33,7 +33,7 @@ int listen(char *buffer, int buflen) { mexErrMsgTxt("Error: ZMQ session not initialized"); } - return zmq_recv(socket, buffer, buflen, 0); + return zmq_recv(socket_ptr, buffer, buflen, 0); } /* Sending out a message */ @@ -42,17 +42,16 @@ int respond(char *msg_out, int len) { mexErrMsgTxt("Error: ZMQ session not initialized"); } - int bytesent = zmq_send(socket, msg_out, len, 0); + return zmq_send(socket_ptr, msg_out, len, 0); - return bytesent; } /* Cleaning up after session finished */ void cleanup (void) { /* Send a confirmation message to the client */ - zmq_send(socket, "exit", 4, 0); + zmq_send(socket_ptr, "exit", 4, 0); - zmq_close(socket); + zmq_close(socket_ptr); mexPrintf("Socket closed\n"); zmq_term(ctx); mexPrintf("Context terminated\n"); @@ -62,14 +61,13 @@ void cleanup (void) { /* Gateway function with Matlab */ void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) { - + char *cmd; /* If no input argument, print out the usage */ if (nrhs == 0) { mexErrMsgTxt("Usage: messenger('init|listen|respond', extra1, extra2, ...)"); } /* Get the input command */ - char *cmd; if(!(cmd = mxArrayToString(prhs[0]))) { mexErrMsgTxt("Cannot read the command"); } @@ -123,6 +121,8 @@ void mexFunction(int nlhs, mxArray *plhs[], /* Send a message out */ } else if (strcmp(cmd, "respond") == 0) { + size_t msglen; + char *msg_out; mxLogical *p; /* Check if the input format is valid */ @@ -130,8 +130,8 @@ void mexFunction(int nlhs, mxArray *plhs[], mexErrMsgTxt("Please provide the message to send"); } - size_t msglen = mxGetNumberOfElements(prhs[1]); - char *msg_out = mxArrayToString(prhs[1]); + msglen = mxGetNumberOfElements(prhs[1]); + msg_out = mxArrayToString(prhs[1]); plhs[0] = mxCreateLogicalMatrix(1, 1); p = mxGetLogicals(plhs[0]); diff --git a/pymatbridge/pymatbridge.py b/pymatbridge/pymatbridge.py index 5a135db..e3003f8 100644 --- a/pymatbridge/pymatbridge.py +++ b/pymatbridge/pymatbridge.py @@ -57,7 +57,7 @@ class Matlab(object): A class for communicating with a matlab session """ - def __init__(self, matlab='matlab', socket_addr='ipc:///tmp/pymatbridge', + def __init__(self, matlab='matlab', socket_addr=None, id='python-matlab-bridge', log=False, maxtime=60, platform=None, startup_options=None): """ @@ -104,6 +104,9 @@ def __init__(self, matlab='matlab', socket_addr='ipc:///tmp/pymatbridge', else: self.platform = platform + if self.socket_addr is None: # use the default + self.socket_addr = "tcp://127.0.0.1:55555" if self.platform == "win32" else "ipc:///tmp/pymatbridge" + if startup_options: self.startup_options = startup_options elif self.platform == 'Windows': diff --git a/setup.py b/setup.py index bc27f56..d435232 100755 --- a/setup.py +++ b/setup.py @@ -13,27 +13,31 @@ from distutils.core import setup # Find the messenger binary file and copy it to /matlab folder. -bin_location = "" + +def copy_bin(bin_path): + if os.path.exists(bin_path): + shutil.copy(bin_path, "./pymatbridge/matlab") + return True + else: + return False + if sys.platform == "darwin": - if not os.path.exists("./messenger/mexmaci64/messenger.mexmaci64"): + if not copy_bin("./messenger/mexmaci64/messenger.mexmaci64"): raise ValueError("messenger.mexmaci64 is not built yet. Please build it yourself.") - bin_location = "./messenger/mexmaci64/messenger.mexmaci64" elif sys.platform == "linux2": - if not os.path.exists("./messenger/mexa64/messenger.mexa64"): + if not copy_bin("./messenger/mexa64/messenger.mexa64"): raise ValueError("messenger.mexa64 is not built yet. Please build it yourself.") - bin_location = "./messenger/mexa64/messenger.mexa64" elif sys.platform == "win32": - if not os.path.exists("./messenger/mexw32/messenger.mexw32"): - raise ValueError("messenger.mexw32 is not built yet. Please build it yourself.") - bin_location = "./messenger/mexw32/messenger.mexw32" + t1 = copy_bin("./messenger/mexw64/messenger.mexw64") + t2 = copy_bin("./messenger/mexw32/messenger.mexw32") + if not (t1 or t2): + raise ValueError("Neither messenger.mexw32 or mex264 is built yet. Please build the appropriate one yourself") else: raise ValueError("Known platform") -shutil.copy(bin_location, "./pymatbridge/matlab") - # Get version and release info, which is all stored in pymatbridge/version.py ver_file = os.path.join('pymatbridge', 'version.py') execfile(ver_file) From ca59b30b136ae40dabfd7382c3b45a7245da003c Mon Sep 17 00:00:00 2001 From: Ali Ebrahim Date: Fri, 28 Mar 2014 14:13:18 -0700 Subject: [PATCH 2/5] add windows binary MATLAB messenger (mexw64) --- messenger/mexw64/messenger.mexw64 | Bin 0 -> 8704 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 messenger/mexw64/messenger.mexw64 diff --git a/messenger/mexw64/messenger.mexw64 b/messenger/mexw64/messenger.mexw64 new file mode 100644 index 0000000000000000000000000000000000000000..9952c40598f0859d3e5eada21dacfbc7d5972e5f GIT binary patch literal 8704 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 LUZ1v4Tm=3HqKR~- literal 0 HcmV?d00001 From a7afee936c3aa6241f0847dfa7535aa28228a2b1 Mon Sep 17 00:00:00 2001 From: Ali Ebrahim Date: Fri, 28 Mar 2014 14:41:07 -0700 Subject: [PATCH 3/5] Add windows installation instructions to README.md --- README.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/README.md b/README.md index 47dee20..2c504cd 100644 --- a/README.md +++ b/README.md @@ -8,8 +8,6 @@ extension, which provides a simple interface for weaving python and Matlab code together (requires ipython > 0.13). -***AT PRESENT THIS DOES NOT WORK ON WINDOWS*** - ## Installation Pymatbridge communicates with Matlab using zeromq. So before installing @@ -25,11 +23,11 @@ build and install zmq. After zmq is installed, make sure you can find the locati libzmq is installed. The library extension name and default location on different systems are listed below. -| Platform | library name | Default locations | -| ------------- | ------------- | -------------------------- | -| MacOS | libzmq.dylib | /usr/lib or /usr/local/lib | -| Linux | libzmq.so.3 | /usr/lib or /usr/local/lib | -| Windows | libzmq.dll | TBD | +| Platform | library name | Default locations | +| ------------- | ------------- | --------------------------------- | +| MacOS | libzmq.dylib | /usr/lib or /usr/local/lib | +| Linux | libzmq.so.3 | /usr/lib or /usr/local/lib | +| Windows | libzmq.dll | C:\Program Files\ZeroMQ 3.2.4\bin | If you specified a prefix when installing zmq, the library file should be located at the same prefix location. @@ -43,9 +41,7 @@ On Linux, add the following line to your .bash_profile: export LD_LIBRARY_PATH=$DYLD_LIBRARY_PATH: -On Windows, - - TBD +On Windows, add the install location of libzmq.dll to the PATH environmental variable. ### Install pyzmq After step 1 is finished, please grab the latest version of @@ -131,9 +127,7 @@ sessions by adding code to the `~/startup.m` file. The Matlab magic allows you to use pymatbridge in the context of the IPython notebook format. - import pymatbridge as pymat - ip = get_ipython() - pymat.load_ipython_extension(ip) + %load_ext pymatbridge These lines will automatically start the matlab session for you. Then, you can simply decorate a line/cell with the '%matlab' or '%%matlab' decorator and From cbe2410fd135b178287669d95dd96888d5d218ef Mon Sep 17 00:00:00 2001 From: Ali Ebrahim Date: Fri, 28 Mar 2014 14:48:50 -0700 Subject: [PATCH 4/5] Update README.md Explain how to edit environment variable on windows. --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2c504cd..2e1a852 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,9 @@ On Linux, add the following line to your .bash_profile: export LD_LIBRARY_PATH=$DYLD_LIBRARY_PATH: -On Windows, add the install location of libzmq.dll to the PATH environmental variable. +On Windows, add the install location of libzmq.dll to the PATH environment variable. +On Windows 7+, typing "environment variables" into the start menu will bring up the +apporpriate Control Panel links. ### Install pyzmq After step 1 is finished, please grab the latest version of From c5002cdd964574510591dcf1b061cfe7e9c62bab Mon Sep 17 00:00:00 2001 From: Ali Ebrahim Date: Fri, 28 Mar 2014 15:13:08 -0700 Subject: [PATCH 5/5] prevent windows from being spawned on windows Command line options were checking for sys.platform being "Windows", not "win32" --- pymatbridge/pymatbridge.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pymatbridge/pymatbridge.py b/pymatbridge/pymatbridge.py index e3003f8..909df21 100644 --- a/pymatbridge/pymatbridge.py +++ b/pymatbridge/pymatbridge.py @@ -109,7 +109,7 @@ def __init__(self, matlab='matlab', socket_addr=None, if startup_options: self.startup_options = startup_options - elif self.platform == 'Windows': + elif self.platform == 'win32': self.startup_options = ' -automation -noFigureWindows' else: self.startup_options = ' -nodesktop -nodisplay'