Skip to content

Commit

Permalink
Added ZeroMQ communication interface
Browse files Browse the repository at this point in the history
  • Loading branch information
adeas31 committed Jun 13, 2017
1 parent e2bcaf3 commit 579677b
Show file tree
Hide file tree
Showing 15 changed files with 284 additions and 8 deletions.
2 changes: 1 addition & 1 deletion Compiler/CMakeLists.txt
Expand Up @@ -21,7 +21,7 @@ SET(SRCMO Absyn.mo AbsynDep.mo Algorithm.mo Builtin.mo
ConnectUtil.mo Dependency.mo)

SET(ALLMO ${SRCMO} DAEEXT.mo DynLoad.mo Print.mo System.mo Parser.mo
TaskGraphExt.mo Corba.mo Socket.mo ErrorExt.mo Settings.mo
TaskGraphExt.mo Corba.mo Socket.mo ZeroMQ.mo ErrorExt.mo Settings.mo
UnitParserExt.mo SimulationResults.mo Serializer.mo)

# RML
Expand Down
45 changes: 45 additions & 0 deletions Compiler/Main/Main.mo
Expand Up @@ -79,6 +79,7 @@ import StackOverflow;
import System;
import TplMain;
import Util;
import ZeroMQ;

protected function serverLoop
"This function is the main loop of the server listening
Expand Down Expand Up @@ -115,6 +116,40 @@ algorithm
end match;
end serverLoop;

protected function serverLoopZMQ
"This function is the main loop of the ZeroMQ server listening
to a port which recieves modelica expressions."
input Boolean cont;
input Option<Integer> inZMQSocket;
input GlobalScript.SymbolTable inInteractiveSymbolTable;
output GlobalScript.SymbolTable outInteractiveSymbolTable;
algorithm
outInteractiveSymbolTable := match (cont,inZMQSocket,inInteractiveSymbolTable)
local
Boolean b;
String str,replystr;
GlobalScript.SymbolTable newsymb,ressymb,isymb;
Option<Integer> zmqSocket;
case (false,_,isymb) then isymb;
case (_,SOME(0),_) then fail();
case (_,zmqSocket,isymb)
equation
str = ZeroMQ.handleRequest(zmqSocket);
if Flags.isSet(Flags.INTERACTIVE_DUMP) then
Debug.trace("------- Recieved Data from client -----\n");
Debug.trace(str);
Debug.trace("------- End recieved Data-----\n");
end if;
(b,replystr,newsymb) = handleCommand(str, isymb) "Print.clearErrorBuf &" ;
replystr = if b then replystr else "quit requested, shutting server down\n";
ZeroMQ.sendReply(zmqSocket, replystr);
if not b then
ZeroMQ.close(zmqSocket);
end if;
then serverLoopZMQ(b, zmqSocket, newsymb);
end match;
end serverLoopZMQ;

protected function makeDebugResult
input Flags.DebugFlag inFlag;
input String res;
Expand Down Expand Up @@ -655,6 +690,14 @@ algorithm
end try;
end interactivemodeCorba;

protected function interactivemodeZMQ
"Initiate the interactive mode using ZMQ communication."
input GlobalScript.SymbolTable symbolTable;
algorithm
print("Starting a ZeroMQ server on port " + intString(29500) + "\n");
serverLoopZMQ(true, ZeroMQ.initialize(29500), symbolTable);
end interactivemodeZMQ;

protected function serverLoopCorba
"This function is the main loop of the server for a CORBA impl."
input GlobalScript.SymbolTable inSettings;
Expand Down Expand Up @@ -866,6 +909,8 @@ algorithm
interactivemode(readSettings(args));
elseif Flags.isSet(Flags.INTERACTIVE_CORBA) then
interactivemodeCorba(readSettings(args));
elseif Flags.isSet(Flags.INTERACTIVE_ZMQ) then
interactivemodeZMQ(readSettings(args));
else // No interactive flag given, try to flatten the file.
readSettings(args);
FGraphStream.start();
Expand Down
5 changes: 4 additions & 1 deletion Compiler/Util/Flags.mo
Expand Up @@ -513,6 +513,8 @@ constant DebugFlag DISABLE_COLORING = DEBUG_FLAG(169, "disableColoring", false,
Util.gettext("Disables coloring algorithm while spasity detection."));
constant DebugFlag MERGE_ALGORITHM_SECTIONS = DEBUG_FLAG(170, "mergeAlgSections", false,
Util.gettext("Disables coloring algorithm while spasity detection."));
constant DebugFlag INTERACTIVE_ZMQ = DEBUG_FLAG(171, "interactiveZMQ", false,
Util.gettext("Starts omc as a ZeroMQ server listening on the socket interface."));


// This is a list of all debug flags, to keep track of which flags are used. A
Expand Down Expand Up @@ -690,7 +692,8 @@ constant list<DebugFlag> allDebugFlags = {
EVAL_PARAM_DUMP,
NF_UNITCHECK,
DISABLE_COLORING,
MERGE_ALGORITHM_SECTIONS
MERGE_ALGORITHM_SECTIONS,
INTERACTIVE_ZMQ
};

public
Expand Down
70 changes: 70 additions & 0 deletions Compiler/Util/ZeroMQ.mo
@@ -0,0 +1,70 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2014, Open Source Modelica Consortium (OSMC),
* c/o Linköpings universitet, Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF GPL VERSION 3 LICENSE OR
* THIS OSMC PUBLIC LICENSE (OSMC-PL) VERSION 1.2.
* ANY USE, REPRODUCTION OR DISTRIBUTION OF THIS PROGRAM CONSTITUTES
* RECIPIENT'S ACCEPTANCE OF THE OSMC PUBLIC LICENSE OR THE GPL VERSION 3,
* ACCORDING TO RECIPIENTS CHOICE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from OSMC, either from the above address,
* from the URLs: http://www.ida.liu.se/projects/OpenModelica or
* http://www.openmodelica.org, and in the OpenModelica distribution.
* GNU version 3 is obtained from: http://www.gnu.org/copyleft/gpl.html.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

encapsulated package ZeroMQ
" file: ZeroMQ.mo
package: ZeroMQ
description: ZeroMQ communication module


This is the ZeroMQ connection module of the compiler
Used in interactive mode if omc is started with +d=interactiveZMQ
Implemented in ./runtime/zeromqimpl.c"

public function initialize
input Integer port;
output Option<Integer> zmqSocket;

external "C" zmqSocket = ZeroMQ_initialize(port) annotation(Library = "omcruntime");
end initialize;

public function handleRequest
input Option<Integer> zmqSocket;
output String request;

external "C" request = ZeroMQ_handleRequest(zmqSocket) annotation(Library = "omcruntime");
end handleRequest;

public function sendReply
input Option<Integer> zmqSocket;
input String reply;

external "C" ZeroMQ_sendReply(zmqSocket, reply) annotation(Library = "omcruntime");
end sendReply;

public function close
input Option<Integer> zmqSocket;

external "C" ZeroMQ_close(zmqSocket) annotation(Library = "omcruntime");
end close;

annotation(__OpenModelica_Interface="util");
end ZeroMQ;
3 changes: 2 additions & 1 deletion Compiler/boot/LoadCompilerSources.mos
Expand Up @@ -226,7 +226,8 @@ if true then /* Suppress output */
"../Util/Socket.mo",
"../Util/System.mo",
"../Util/Util.mo",
"../Util/VarTransform.mo"
"../Util/VarTransform.mo",
"../Util/ZeroMQ.mo"
};
backendfiles := if OpenModelica.Scripting.getEnvironmentVar("OPENMODELICA_BACKEND_STUBS")<>"" then
{
Expand Down
2 changes: 1 addition & 1 deletion Compiler/boot/Makefile.in
Expand Up @@ -12,7 +12,7 @@ EXE_EXT=@EXE@
EXE_SUFFIX=

LIB_OMC=lib/@host_short@/omc
LDFLAGS=-L. -L$(GEN_DIR) -L"$(OMHOME)/$(LIB_OMC)" $(LOMPARSE) $(LCOMPILERRUNTIME) -lOpenModelicaRuntimeC -lModelicaExternalC -lomantlr3 $(CORBALIBS) $(FMILIB_OR_BOOT) $(GSLIB) @RT_LDFLAGS@ @LIBSOCKET@ @LIBLPSOLVE55@ @OMC_LIBS@ @GRAPHLIB@ @LD_LAPACK@
LDFLAGS=-L. -L$(GEN_DIR) -L"$(OMHOME)/$(LIB_OMC)" $(LOMPARSE) $(LCOMPILERRUNTIME) -lOpenModelicaRuntimeC -lModelicaExternalC -lomantlr3 $(CORBALIBS) $(FMILIB_OR_BOOT) $(GSLIB) @RT_LDFLAGS@ @LIBSOCKET@ @LIBLPSOLVE55@ @OMC_LIBS@ @GRAPHLIB@ @LD_LAPACK@ -lzmq
LDFLAGS_SHARED_MAIN=-L"$(OMHOME)/$(LIB_OMC)" @RT_LDFLAGS_SHARED@
ifeq (@WITH_FMIL@,yes)
FMILIB = -L$(TOP_DIR)/3rdParty/FMIL/install/lib -lfmilib
Expand Down
1 change: 1 addition & 0 deletions Compiler/boot/Makefile.omdev.mingw
Expand Up @@ -19,6 +19,7 @@ LDFLAGS=-L./ $(LOMPARSE) $(LCOMPILERRUNTIME) -L"$(OMHOME)/lib/omc" \
-Wl,--enable-stdcall-fixup -lstdc++ -static-libgcc \
-L../../3rdParty/lpsolve/build/lib \
-lgfortran -ltre -lomniORB420_rt -lomnithread40_rt \
-lzmq \
$(EXTRA_LD_FLAGS)

FMILIB = -L$(TOP_DIR)/3rdParty/FMIL/install/lib -lfmilib
Expand Down
3 changes: 2 additions & 1 deletion Compiler/runtime/Makefile.common
Expand Up @@ -24,7 +24,7 @@ OMC_OBJ_SHARED = Dynload_omc$(OBJEXT) Error_omc$(OBJEXT) \
ErrorMessage$(OBJEXT) systemimplmisc.o System_omc$(OBJEXT) \
Lapack_omc.o Settings_omc$(OBJEXT) \
UnitParserExt_omc.o unitparser.o \
IOStreamExt_omc.o Socket_omc.o getMemorySize.o \
IOStreamExt_omc.o Socket_omc.o ZeroMQ_omc.o getMemorySize.o \
is_utf8.o

OMC_OBJ_STUBS = corbaimpl_stub_omc.o
Expand Down Expand Up @@ -98,6 +98,7 @@ IOStreamExt_omc.o : IOStreamExt.c
ErrorMessage.o : ErrorMessage.cpp ErrorMessage.hpp errorext.h
serializer.o: serializer.cpp
Socket_omc.o : socketimpl.c
ZeroMQ_omc.o : zeromqimpl.c
UnitParserExt_omc.o : unitparserext.cpp unitparser.h
BackendDAEEXT_omc.o : BackendDAEEXT.cpp $(RML_COMPAT) matching.c matchmaker.h matching_cheap.c

Expand Down
3 changes: 2 additions & 1 deletion Compiler/runtime/Makefile.omdev.mingw
Expand Up @@ -27,6 +27,7 @@ CJSONINCLUDE = ../../3rdParty/cJSON/
OMBUILDDIR = ../../../build
LPSOLVEINCLUDE = ../../3rdParty/lpsolve/build/include/
SQLITE3INCLUDE = ../../3rdParty/sqlite3/build/include/
ZMQINCLUDE = ../../3rdParty/libzmq/include
OMC=$(OMBUILDDIR)/bin/omc
SHREXT=.a
OMPCC = gcc -fopenmp
Expand All @@ -46,7 +47,7 @@ OMCCORBASRC = omc_communication.o omc_communication_impl.o Corba_omc.o
SHELL = /bin/sh
CC = gcc
CXX = g++
override CFLAGS += -I. $(USE_CORBA) $(USE_METIS) -Wall -Wno-unused-variable -I../../ -I$(top_builddir) -I$(top_builddir)/SimulationRuntime/c -I$(top_builddir)/SimulationRuntime/c/simulation/results -I$(top_builddir)/SimulationRuntime/c/util -I$(top_builddir)/SimulationRuntime/c/meta -I$(top_builddir)/SimulationRuntime/c/meta/gc $(CORBAINCL) -I$(FMIINCLUDE) -I../../3rdParty/gc/include -I$(GRAPHSTREAMINCLUDE) -I$(CJSONINCLUDE) -I$(GRAPHINCLUDE) -I$(LPSOLVEINCLUDE) -I$(SQLITE3INCLUDE)
override CFLAGS += -I. $(USE_CORBA) $(USE_METIS) -Wall -Wno-unused-variable -I../../ -I$(top_builddir) -I$(top_builddir)/SimulationRuntime/c -I$(top_builddir)/SimulationRuntime/c/simulation/results -I$(top_builddir)/SimulationRuntime/c/util -I$(top_builddir)/SimulationRuntime/c/meta -I$(top_builddir)/SimulationRuntime/c/meta/gc $(CORBAINCL) -I$(FMIINCLUDE) -I../../3rdParty/gc/include -I$(GRAPHSTREAMINCLUDE) -I$(CJSONINCLUDE) -I$(GRAPHINCLUDE) -I$(LPSOLVEINCLUDE) -I$(SQLITE3INCLUDE) -I$(ZMQINCLUDE)
CXXFLAGS = $(CFLAGS)

include Makefile.common
49 changes: 49 additions & 0 deletions Compiler/runtime/ZeroMQ_omc.c
@@ -0,0 +1,49 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2010, Linköpings University,
* Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THIS OSMC PUBLIC
* LICENSE (OSMC-PL). ANY USE, REPRODUCTION OR DISTRIBUTION OF
* THIS PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THE OSMC
* PUBLIC LICENSE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from Linköpings University, either from the above address,
* from the URL: http://www.ida.liu.se/projects/OpenModelica
* and in the OpenModelica distribution.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
* OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

#if defined(_MSC_VER) || defined(__MINGW32__)
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#endif

#include <stdio.h>
#include <meta_modelica.h>

#include "zeromqimpl.c"
#include "meta_modelica.h"
#include "ModelicaUtilities.h"

extern const char* ZeroMQ_handleRequest(void* mmcZmqSocket)
{
char *str = ZeroMQImpl_handleRequest(mmcZmqSocket);
char *res = strcpy(ModelicaAllocateString(strlen(str)),str);
free(str);
return res;
}
82 changes: 82 additions & 0 deletions Compiler/runtime/zeromqimpl.c
@@ -0,0 +1,82 @@
/*
* This file is part of OpenModelica.
*
* Copyright (c) 1998-2010, Linköpings University,
* Department of Computer and Information Science,
* SE-58183 Linköping, Sweden.
*
* All rights reserved.
*
* THIS PROGRAM IS PROVIDED UNDER THE TERMS OF THIS OSMC PUBLIC
* LICENSE (OSMC-PL). ANY USE, REPRODUCTION OR DISTRIBUTION OF
* THIS PROGRAM CONSTITUTES RECIPIENT'S ACCEPTANCE OF THE OSMC
* PUBLIC LICENSE.
*
* The OpenModelica software and the Open Source Modelica
* Consortium (OSMC) Public License (OSMC-PL) are obtained
* from Linköpings University, either from the above address,
* from the URL: http://www.ida.liu.se/projects/OpenModelica
* and in the OpenModelica distribution.
*
* This program is distributed WITHOUT ANY WARRANTY; without
* even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE, EXCEPT AS EXPRESSLY SET FORTH
* IN THE BY RECIPIENT SELECTED SUBSIDIARY LICENSE CONDITIONS
* OF OSMC-PL.
*
* See the full OSMC Public License conditions for more details.
*
*/

#include <zmq.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

#include "modelica_string.h"

void* ZeroMQ_initialize(int port)
{
// Create a pointer for storing the ZeroMQ socket
void *mmcZmqSocket = mmc_mk_some(0);
// Create the ZeroMQ context
void *context = zmq_ctx_new();
void *zmqSocket = zmq_socket(context, ZMQ_REP);
char hostname[20];
sprintf(hostname, "tcp://*:%d", port);
int rc = zmq_bind(zmqSocket, hostname);
if (rc != 0) {
printf("Error creating ZeroMQ Server\n");
return mmcZmqSocket;
}
mmcZmqSocket = mmc_mk_some(zmqSocket);
return mmcZmqSocket;
}

extern char* ZeroMQImpl_handleRequest(void *mmcZmqSocket)
{
int bufferSize = 4000;
char *buffer = (char*)malloc(bufferSize + 1);
// Convert the void* to ZeroMQ Socket
intptr_t zmqSocket = (intptr_t)MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(mmcZmqSocket),1));
zmq_recv((void*)zmqSocket, buffer, bufferSize, 0);
fprintf(stdout, "Recieved message %s\n", buffer);fflush(NULL);
return buffer;
}

void ZeroMQ_sendReply(void *mmcZmqSocket, const char* reply)
{
// Convert the void* to ZeroMQ Socket
intptr_t zmqSocket = (intptr_t)MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(mmcZmqSocket),1));
// send the reply
fprintf(stdout, "Sending message %s\n", reply);fflush(NULL);
zmq_send((void*)zmqSocket, reply, strlen(reply) + 1, 0);
}

void ZeroMQ_close(void *mmcZmqSocket)
{
// Convert the void* to ZeroMQ Socket
intptr_t zmqSocket = (intptr_t)MMC_FETCH(MMC_OFFSET(MMC_UNTAGPTR(mmcZmqSocket),1));
// close the ZeroMQ socket
zmq_close((void*)zmqSocket);
}

0 comments on commit 579677b

Please sign in to comment.