Check in CCS interface for python. This interface currently works for Chare, Group...
authorFilippo Gioachin <gioachin@illinois.edu>
Wed, 2 Jun 2004 00:39:00 +0000 (00:39 +0000)
committerFilippo Gioachin <gioachin@illinois.edu>
Wed, 2 Jun 2004 00:39:00 +0000 (00:39 +0000)
It works also in the SMP version, even if the execution is serialized due to a conflict with multi-threads. This has to be fixed.
The interface provide the following methods to python code through the "ck" module:
printstr, mype, numpes, myindex (only for array1D), read, write
the last two must be reimplemented in the user code and will allow python to access data variables into the running program

src/libs/ck-libs/pythonCCS/Makefile [new file with mode: 0644]
src/libs/ck-libs/pythonCCS/PythonCCS.C [new file with mode: 0644]
src/libs/ck-libs/pythonCCS/PythonCCS.ci [new file with mode: 0644]
src/libs/ck-libs/pythonCCS/PythonCCS.h [new file with mode: 0644]

diff --git a/src/libs/ck-libs/pythonCCS/Makefile b/src/libs/ck-libs/pythonCCS/Makefile
new file mode 100644 (file)
index 0000000..a5e2485
--- /dev/null
@@ -0,0 +1,25 @@
+CDIR=../../../..
+CHARMC=$(CDIR)/bin/charmc $(OPTS)
+
+HEADERS=PythonCCS.h PythonCCS.decl.h PythonCCS.def.h
+HEADDEP=$(HEADERS)
+OBJS=PythonCCS.o
+DEST=$(CDIR)/lib/libmodulePythonCCS.a
+
+all: $(DEST)
+
+$(DEST): $(OBJS) $(COMPAT) headers
+       $(CHARMC) $(OBJS) $(COMPAT) -o $@
+
+headers: $(HEADERS)
+       cp $(HEADERS) $(CDIR)/include/
+       touch headers
+
+PythonCCS.o: PythonCCS.C $(HEADDEP)
+       $(CHARMC) -c $(FLAGS) PythonCCS.C
+
+PythonCCS.decl.h PythonCCS.def.h: PythonCCS.ci
+       $(CHARMC) PythonCCS.ci
+
+clean:
+       rm -rf *.a *.def.h *.decl.h *.o SunWS_cache $(DEST) headers
diff --git a/src/libs/ck-libs/pythonCCS/PythonCCS.C b/src/libs/ck-libs/pythonCCS/PythonCCS.C
new file mode 100644 (file)
index 0000000..3def43b
--- /dev/null
@@ -0,0 +1,174 @@
+#include "PythonCCS.h"
+
+//CProxy_PythonGroup python;
+
+PythonMain::PythonMain (CkArgMsg *msg) {
+  //CProxy_PythonGroup python = CProxy_PythonGroup::ckNew();
+
+  //CcsRegisterHandler("pyCode", CkCallback(CkIndex_PythonGroup::execute(0),python));
+}
+
+CsvStaticDeclare(CmiNodeLock, pyLock);
+CsvStaticDeclare(PythonTable *, pyWorkers);
+CsvStaticDeclare(int, pyNumber);
+/*
+CkpvStaticDeclare(PythonChare *, curWorkerChare);
+CkpvStaticDeclare(PythonGroup *, curWorkerGroup);
+CkpvStaticDeclare(PythonNodeGroup *, curWorkerNodeGroup);
+CkpvStaticDeclare(PythonArray1D *, curWorkerArray1D);
+CkpvStaticDeclare(PythonArray2D *, curWorkerArray2D);
+*/
+
+// One-time per-processor setup routine
+// main interface for python to access common charm methods
+static PyObject *CkPy_printstr(PyObject *self, PyObject *args) {
+  char *stringToPrint;
+  if (!PyArg_ParseTuple(args, "s:printstr", &stringToPrint))
+    return NULL;
+  CkPrintf("%s\n",stringToPrint);
+  Py_INCREF(Py_None);return Py_None; //Return-nothing idiom
+}
+
+static PyObject *CkPy_mype(PyObject *self, PyObject *args) {
+  if (!PyArg_ParseTuple(args, ":mype")) return NULL;
+  return Py_BuildValue("i", CkMyPe());
+}
+
+static PyObject *CkPy_numpes(PyObject *self, PyObject *args) {
+  if (!PyArg_ParseTuple(args, ":numpes")) return NULL;
+  return Py_BuildValue("i", CkNumPes());
+}
+
+static PyObject *CkPy_myindex(PyObject *self, PyObject *args) {
+  if (!PyArg_ParseTuple(args, ":myindex")) return NULL;
+  PythonArray1D *pyArray;
+  if ((pyArray = (dynamic_cast<PythonArray1D*>((*CsvAccess(pyWorkers))[0])))) return Py_BuildValue("i", pyArray->thisIndex);
+  else { Py_INCREF(Py_None);return Py_None;}
+  //return Py_BuildValue("i", (*CsvAccess(pyWorkers))[0]->thisIndex);
+}
+
+// method to read a variable and convert it to a python object
+static PyObject *CkPy_read(PyObject *self, PyObject *args) {
+  char * str;
+  if (!PyArg_ParseTuple(args, "s:read", str)) return NULL;
+  std::string cstr = str;
+  PythonObject *pyWorker = (*CsvAccess(pyWorkers))[0];
+  TypedValue result = pyWorker->read(cstr);
+  switch (result.type) {
+  case PY_INT:
+    return Py_BuildValue("i", result.value.i);
+
+  case PY_LONG:
+    return Py_BuildValue("l", result.value.l);
+  case PY_FLOAT:
+    return Py_BuildValue("f", result.value.f);
+  case PY_DOUBLE:
+    return Py_BuildValue("d", result.value.d);
+  }
+}
+
+// method to convert a python object into a variable and write it
+static PyObject *CkPy_write(PyObject *self, PyObject *args) {
+  char * str;
+  PyObject *obj;
+  if (!PyArg_ParseTuple(args, "sO:write", &str, &obj)) return NULL;
+  std::string cstr = str;
+  Py_types varType = (*CsvAccess(pyWorkers))[0]->getType(cstr);
+  (*CsvAccess(pyWorkers))[0]->write(cstr, TypedValue(varType, obj));
+  Py_INCREF(Py_None);return Py_None;
+}
+
+static PyMethodDef CkPy_MethodsDefault[] = {
+  {"printstr", CkPy_printstr , METH_VARARGS},
+  {"mype", CkPy_mype, METH_VARARGS},
+  {"numpes", CkPy_numpes, METH_VARARGS},
+  {"myindex", CkPy_myindex, METH_VARARGS},
+  {"read", CkPy_read, METH_VARARGS},
+  {"write", CkPy_write, METH_VARARGS},
+  {NULL,      NULL}        /* Sentinel */
+};
+
+void PythonObject::execute (CkCcsRequestMsg *msg) {
+  CkPrintf("executing script\n");
+  CmiLock(CsvAccess(pyLock));
+  //CsvAccess(pyWorkers)[++CsvAccess(pyNumber)] = this;
+  (*CsvAccess(pyWorkers))[CsvAccess(pyNumber)] = this;
+  PyThreadState *pts = Py_NewInterpreter();
+  Py_InitModule("ck", CkPy_MethodsDefault);
+  PyRun_SimpleString((char *)msg->data);
+  Py_EndInterpreter(pts);
+  CmiUnlock(CsvAccess(pyLock));
+}
+/*
+void PythonChare::execute (CkCcsRequestMsg *msg) {
+  CkPrintf("executing chare script\n");
+  CsvAccess(curWorkerChare)=this;
+  PyThreadState *pts = Py_NewInterpreter();
+  Py_InitModule("ck", CkPy_MethodsDefault);
+  PyRun_SimpleString((char *)msg->data);
+  Py_EndInterpreter(pts);
+}
+
+void PythonGroup::execute (CkCcsRequestMsg *msg) {
+  CkPrintf("executing group script\n");
+  CsvAccess(curWorkerGroup)=this;
+  PyThreadState *pts = Py_NewInterpreter();
+  Py_InitModule("ck", CkPy_MethodsDefault);
+  PyRun_SimpleString((char *)msg->data);
+  Py_EndInterpreter(pts);
+}
+
+void PythonNodeGroup::execute (CkCcsRequestMsg *msg) {
+  CkPrintf("executing node group script\n");
+  CsvAccess(curWorkerNodeGroup)=this;
+  PyThreadState *pts = Py_NewInterpreter();
+  Py_InitModule("ck", CkPy_MethodsDefault);
+  PyRun_SimpleString((char *)msg->data);
+  Py_EndInterpreter(pts);
+}
+
+void PythonArray1D::execute (CkCcsRequestMsg *msg) {
+  CkPrintf("executing array 1D script\n");
+  CsvAccess(curWorkerArray1D)=this;
+  //PyThreadState *pts = Py_NewInterpreter();
+  //Py_InitModule("ck", CkPy_MethodsDefault);
+  PyRun_SimpleString((char *)msg->data);
+  //Py_EndInterpreter(pts);
+}
+
+void PythonArray2D::execute (CkCcsRequestMsg *msg) {
+  CkPrintf("executing array2D script\n");
+  CsvAccess(curWorkerArray2D)=this;
+  PyThreadState *pts = Py_NewInterpreter();
+  Py_InitModule("ck", CkPy_MethodsDefault);
+  PyRun_SimpleString((char *)msg->data);
+  Py_EndInterpreter(pts);
+}
+*/
+
+static void initializePythonDefault(void) {
+  CsvInitialize(int, pyNumber);
+  CsvAccess(pyNumber) = 0;
+  CsvInitialize(PythonTable *,pyWorkers);
+  CsvAccess(pyWorkers) = new PythonTable();
+  CsvInitialize(CmiNodeLock, pyLock);
+  CsvAccess(pyLock) = CmiCreateLock();
+
+  /*
+  CkpvInitialize(PythonChare *,curWorkerChare);
+  CkpvInitialize(PythonGroup *,curWorkerGroup);
+  CkpvInitialize(PythonNodeGroup *,curWorkerNodeGroup);
+  CkpvInitialize(PythonArray1D *,curWorkerArray1D);
+  CkpvInitialize(PythonArray2D *,curWorkerArray2D);
+  CkpvAccess(curWorkerChare)=NULL;
+  CkpvAccess(curWorkerGroup)=NULL;
+  CkpvAccess(curWorkerNodeGroup)=NULL;
+  CkpvAccess(curWorkerArray1D)=NULL;
+  CkpvAccess(curWorkerArray2D)=NULL;
+  */
+
+  Py_Initialize();
+  PyObject *ck = Py_InitModule("ck", CkPy_MethodsDefault);
+}
+
+#include "PythonCCS.def.h"
diff --git a/src/libs/ck-libs/pythonCCS/PythonCCS.ci b/src/libs/ck-libs/pythonCCS/PythonCCS.ci
new file mode 100644 (file)
index 0000000..ba7fb6a
--- /dev/null
@@ -0,0 +1,35 @@
+module PythonCCS {
+
+       //readonly CProxy_PythonGroup python;
+
+       mainchare PythonMain {
+               entry PythonMain(CkArgMsg *msg);
+       }
+
+       chare PythonChare {
+               entry PythonChare(void);
+               entry void execute (CkCcsRequestMsg *msg);
+       }
+
+       group PythonGroup {
+               entry PythonGroup(void);
+               entry void execute (CkCcsRequestMsg *msg);
+       }
+
+       nodegroup PythonNodeGroup {
+               entry PythonNodeGroup(void);
+               entry void execute (CkCcsRequestMsg *msg);
+       }
+
+       array [1D] PythonArray1D {
+               entry PythonArray1D(void);
+               entry void execute (CkCcsRequestMsg *msg);
+       }
+
+       array [2D] PythonArray2D {
+               entry PythonArray2D(void);
+               entry void execute (CkCcsRequestMsg *msg);
+       }
+
+       initnode void initializePythonDefault(void);
+}
diff --git a/src/libs/ck-libs/pythonCCS/PythonCCS.h b/src/libs/ck-libs/pythonCCS/PythonCCS.h
new file mode 100644 (file)
index 0000000..aaa4bce
--- /dev/null
@@ -0,0 +1,148 @@
+#include "ckcallback-ccs.h"
+#include "python2.2/Python.h"
+#include "PythonCCS.decl.h"
+#include "string"
+#include "map"
+
+class PythonMain : public Chare {
+ public:
+  PythonMain(CkArgMsg *msg);
+};
+
+//#define PY_INT     0
+//#define PY_LONG    1
+//#define PY_FLOAT   2
+//#define PY_DOUBLE  3
+
+enum Py_types {PY_INT, PY_LONG, PY_FLOAT, PY_DOUBLE};
+enum Py_objects {PY_CHARE, PY_GROUP, PY_NODEGROUP, PY_ARRAY1D, PY_ARRAY2D};
+
+typedef struct TypedValue_ {
+  Py_types type;
+  union {
+    int i;
+    long l;
+    float f;
+    double d;
+  } value;
+
+  TypedValue_(Py_types t, int i0) {
+    type = t;
+    value.i = i0;
+  };
+
+  TypedValue_(Py_types t, PyObject *o) {
+    int i0;
+    long l0;
+    float f0;
+    double d0;
+    type = t;
+    switch (t) {
+    case PY_INT:
+      i0 = (int)PyInt_AsLong(o);
+      value.i = i0;
+      break;
+    case PY_LONG:
+      l0 = PyLong_AsLong(o);
+      value.l = l0;
+      break;
+    case PY_FLOAT:
+      f0 = (float)PyFloat_AsDouble(o);
+      value.f = f0;
+      break;
+    case PY_DOUBLE:
+      d0 = PyFloat_AsDouble(o);
+      value.d = d0;
+      break;
+    }
+  }
+} TypedValue;
+
+class PythonObject {
+ public:
+  Py_objects type;
+  void execute(CkCcsRequestMsg *msg);
+
+  // the following three methods should be overwritten by the user
+  virtual TypedValue read(std::string) {CkAbort("PythonCCS: Method read should be reimplemented");};
+  virtual void write(std::string, TypedValue) {CkAbort("PythonCCS: Method write should be reimplemented");};
+  virtual Py_types getType(std::string) {CkAbort("PythonCCS: Method getType should be reimplemented");};
+  //virtual void registerPython();
+};
+
+typedef std::map<int,PythonObject*>  PythonTable;
+
+class PythonChare : public Chare, public PythonObject {
+ public:
+  PythonChare() {}
+  PythonChare(CkMigrateMessage *msg) {}
+  //void execute(CkCcsRequestMsg *msg);
+
+  /*
+  // the following two methods should be overwritten by the user
+  virtual TypedValue read(std::string) {CkAbort("PythonCCS: Method read should be reimplemented");};
+  virtual void write(std::string, TypedValue) {CkAbort("PythonCCS: Method write should be reimplemented");};
+  virtual Py_types getType(std::string) {CkAbort("PythonCCS: Method getType should be reimplemented");};
+  //virtual void registerPython();
+  */
+};
+
+class PythonGroup : public Group, public PythonObject {
+ public:
+  PythonGroup() {}
+  PythonGroup(CkMigrateMessage *msg) {}
+  //void execute(CkCcsRequestMsg *msg);
+
+  /*
+  // the following three methods should be overwritten by the user
+  virtual TypedValue read(std::string) {CkAbort("PythonCCS: Method read should be reimplemented");};
+  virtual void write(std::string, TypedValue) {CkAbort("PythonCCS: Method write should be reimplemented");};
+  virtual Py_types getType(std::string) {CkAbort("PythonCCS: Method getType should be reimplemented");};
+  //virtual void registerPython();
+  */
+};
+
+class PythonNodeGroup : public NodeGroup, public PythonObject {
+ public:
+  PythonNodeGroup() {}
+  PythonNodeGroup(CkMigrateMessage *msg) {}
+  //void execute(CkCcsRequestMsg *msg);
+
+  /*
+  // the following two methods should be overwritten by the user
+  virtual TypedValue read(std::string) {CkAbort("PythonCCS: Method read should be reimplemented");};
+  virtual void write(std::string, TypedValue) {CkAbort("PythonCCS: Method write should be reimplemented");};
+  virtual Py_types getType(std::string) {CkAbort("PythonCCS: Method getType should be reimplemented");};
+  //virtual void registerPython();
+  */
+};
+
+class PythonArray1D : public CBase_PythonArray1D, public PythonObject {
+ public:
+  PythonArray1D() {}
+  PythonArray1D(CkMigrateMessage *msg) {}
+  //void execute(CkCcsRequestMsg *msg);
+
+  /*
+  // the following two methods should be overwritten by the user
+  virtual TypedValue read(std::string) {CkAbort("PythonCCS: Method read should be reimplemented");};
+  virtual void write(std::string, TypedValue) {CkAbort("PythonCCS: Method write should be reimplemented");};
+  virtual Py_types getType(std::string) {CkAbort("PythonCCS: Method getType should be reimplemented");};
+  //virtual void registerPython();
+  */
+};
+
+class PythonArray2D : public CBase_PythonArray2D, public PythonObject {
+ public:
+  PythonArray2D() {}
+  PythonArray2D(CkMigrateMessage *msg) {}
+  //void execute(CkCcsRequestMsg *msg);
+
+  /*
+  // the following two methods should be overwritten by the user
+  virtual TypedValue read(std::string) {CkAbort("PythonCCS: Method read should be reimplemented");};
+  virtual void write(std::string, TypedValue) {CkAbort("PythonCCS: Method write should be reimplemented");};
+  virtual Py_types getType(std::string) {CkAbort("PythonCCS: Method getType should be reimplemented");};
+  //virtual void registerPython();
+  */
+};