added capability of lowlovel interface with iteration
authorFilippo Gioachin <gioachin@illinois.edu>
Sat, 21 Aug 2004 02:34:00 +0000 (02:34 +0000)
committerFilippo Gioachin <gioachin@illinois.edu>
Sat, 21 Aug 2004 02:34:00 +0000 (02:34 +0000)
src/libs/ck-libs/pythonCCS/PythonCCS.C
src/libs/ck-libs/pythonCCS/PythonCCS.ci
src/libs/ck-libs/pythonCCS/PythonCCS.h

index 78dba784c34670d2f3899a5420cd1f76922f7ce9..1123d25b7d38adc9cbd3a4032d628eeabe3dd4f9 100644 (file)
@@ -34,10 +34,11 @@ static PyObject *CkPy_numpes(PyObject *self, PyObject *args) {
 
 static PyObject *CkPy_myindex(PyObject *self, PyObject *args) {
   if (!PyArg_ParseTuple(args, ":myindex")) return NULL;
+  int pyNumber = PyInt_AsLong(PyDict_GetItemString(PyModule_GetDict(PyImport_AddModule("__main__")),"charmNumber"));
   CmiLock(CsvAccess(pyLock));
-  PythonArray1D *pyArray = dynamic_cast<PythonArray1D*>((*CsvAccess(pyWorkers))[0]);
+  PythonArray1D *pyArray = dynamic_cast<PythonArray1D*>((*CsvAccess(pyWorkers))[pyNumber]);
   CmiUnlock(CsvAccess(pyLock));
-  if ((pyArray = (dynamic_cast<PythonArray1D*>((*CsvAccess(pyWorkers))[0])))) return Py_BuildValue("i", pyArray->thisIndex);
+  if (pyArray) return Py_BuildValue("i", pyArray->thisIndex);
   else { Py_INCREF(Py_None);return Py_None;}
   //return Py_BuildValue("i", (*CsvAccess(pyWorkers))[0]->thisIndex);
 }
@@ -45,8 +46,9 @@ static PyObject *CkPy_myindex(PyObject *self, PyObject *args) {
 // method to read a variable and convert it to a python object
 static PyObject *CkPy_read(PyObject *self, PyObject *args) {
   if (!PyArg_ParseTuple(args, "O:read")) return NULL;
+  int pyNumber = PyInt_AsLong(PyDict_GetItemString(PyModule_GetDict(PyImport_AddModule("__main__")),"charmNumber"));
   CmiLock(CsvAccess(pyLock));
-  PythonObject *pyWorker = (*CsvAccess(pyWorkers))[0];
+  PythonObject *pyWorker = (*CsvAccess(pyWorkers))[pyNumber];
   CmiUnlock(CsvAccess(pyLock));
   return pyWorker->read(args);
 }
@@ -55,8 +57,9 @@ static PyObject *CkPy_read(PyObject *self, PyObject *args) {
 static PyObject *CkPy_write(PyObject *self, PyObject *args) {
   PyObject *where, *what;
   if (!PyArg_ParseTuple(args, "OO:write",&where,&what)) return NULL;
+  int pyNumber = PyInt_AsLong(PyDict_GetItemString(PyModule_GetDict(PyImport_AddModule("__main__")),"charmNumber"));
   CmiLock(CsvAccess(pyLock));
-  PythonObject *pyWorker = (*CsvAccess(pyWorkers))[0];
+  PythonObject *pyWorker = (*CsvAccess(pyWorkers))[pyNumber];
   CmiUnlock(CsvAccess(pyLock));
   pyWorker->write(where, what);
   Py_INCREF(Py_None);return Py_None;
@@ -73,17 +76,97 @@ static PyMethodDef CkPy_MethodsDefault[] = {
 };
 
 void PythonObject::execute (CkCcsRequestMsg *msg) {
-  CkPrintf("executing script\n");
+  char pyString[25];
+
+  // update the reference number, used to access the current chare
   CmiLock(CsvAccess(pyLock));
-  //CsvAccess(pyWorkers)[++CsvAccess(pyNumber)] = this;
-  (*CsvAccess(pyWorkers))[CsvAccess(pyNumber)] = this;
+  int pyReference = CsvAccess(pyNumber)++;
+  CsvAccess(pyNumber) &= ~(1<<31);
+  (*CsvAccess(pyWorkers))[pyReference] = this;
+  //printf("map number:%d\n",CsvAccess(pyWorkers)->size());
   CmiUnlock(CsvAccess(pyLock));
+  sprintf(pyString, "charmNumber=%d", pyReference);
+
+  // create the new interpreter
   PyEval_AcquireLock();
   PyThreadState *pts = Py_NewInterpreter();
   Py_InitModule("ck", CkPy_MethodsDefault);
+
+  // insert into the dictionary a variable with the reference number
+  PyObject *mod = PyImport_AddModule("__main__");
+  PyObject *dict = PyModule_GetDict(mod);
+  PyRun_String(pyString,Py_file_input,dict,dict);
+
+  // run the program
   PyRun_SimpleString((char *)msg->data);
+
+  // distroy map element in pyWorkers and terminate interpreter
+  Py_EndInterpreter(pts);
+  PyEval_ReleaseLock();
+  CmiLock(CsvAccess(pyLock));
+  CsvAccess(pyWorkers)->erase(pyReference);
+  CmiUnlock(CsvAccess(pyLock));
+}
+
+void PythonObject::iterate (CkCcsRequestMsg *msg) {
+  char pyString[25];
+
+  // update the reference number, used to access the current chare
+  CmiLock(CsvAccess(pyLock));
+  int pyReference = CsvAccess(pyNumber)++;
+  CsvAccess(pyNumber) &= ~(1<<31);
+  (*CsvAccess(pyWorkers))[pyReference] = this;
+  //printf("map number:%d\n",CsvAccess(pyWorkers)->size());
+  CmiUnlock(CsvAccess(pyLock));
+  sprintf(pyString, "charmNumber=%d", pyReference);
+
+  // create the new interpreter
+  PyEval_AcquireLock();
+  PyThreadState *pts = Py_NewInterpreter();
+  Py_InitModule("ck", CkPy_MethodsDefault);
+
+  // insert into the dictionary a variable with the reference number
+  PyObject *mod = PyImport_AddModule("__main__");
+  PyObject *dict = PyModule_GetDict(mod);
+  PyRun_String(pyString,Py_file_input,dict,dict);
+
+  // compile the program
+  char *userCode = (char *)msg->data;
+  struct _node* programNode = PyParser_SimpleParseString(userCode, Py_file_input);
+  if (programNode==NULL) { CkPrintf("Program error\n"); return; }
+  PyCodeObject *program = PyNode_Compile(programNode, "");
+  if (program==NULL) { CkPrintf("Program error\n"); return; }
+  PyObject *code = PyEval_EvalCode(program, dict, dict);
+  if (code==NULL) { CkPrintf("Program error\n"); return; }
+
+  // load the user defined method
+  char *userMethod = userCode + strlen(userCode) + 1;
+  PyObject *item = PyDict_GetItemString(dict, userMethod);
+  if (item==NULL) { CkPrintf("Method not found\n"); return; }
+
+  // create the container for the data
+  PyRun_String("class Particle:\n\tpass\n\n", Py_file_input, dict, dict);
+  PyObject *part = PyRun_String("Particle()", Py_eval_input, dict, dict);
+  PyObject *arg = PyTuple_New(1);
+  PyTuple_SetItem(arg, 0, part);
+
+  // construct the iterator calling the user defined method in the interiting class
+  void *userIterator = (void *)(userMethod + strlen(userMethod) + 1);
+  int more = buildIterator(part, userIterator);
+
+  // iterate over all the provided iterators from the user class
+  PyObject *result;
+  while (more) {
+    result = PyObject_CallObject(item, arg);
+    more = nextIteratorUpdate(part, result, userIterator);
+  }
+
+  // distroy map element in pyWorkers and terminate interpreter
   Py_EndInterpreter(pts);
   PyEval_ReleaseLock();
+  CmiLock(CsvAccess(pyLock));
+  CsvAccess(pyWorkers)->erase(pyReference);
+  CmiUnlock(CsvAccess(pyLock));
 }
 
 static void initializePythonDefault(void) {
@@ -96,8 +179,9 @@ static void initializePythonDefault(void) {
 
   Py_Initialize();
   PyEval_InitThreads();
-  PyEval_ReleaseLock();
   PyObject *ck = Py_InitModule("ck", CkPy_MethodsDefault);
+
+  PyEval_ReleaseLock();
 }
 
 #include "PythonCCS.def.h"
index 2e85fd6d95d3f7e064d64f5efe42b714baec9e21..a76495a21a2a157faa612e95c69daa9af9cf8cc2 100644 (file)
@@ -9,31 +9,37 @@ module PythonCCS {
        chare PythonChare {
                entry PythonChare(void);
                entry void execute (CkCcsRequestMsg *msg);
+               entry void iterate (CkCcsRequestMsg *msg);
        }
 
        group PythonGroup {
                entry PythonGroup(void);
                entry void execute (CkCcsRequestMsg *msg);
+               entry void iterate (CkCcsRequestMsg *msg);
        }
 
        nodegroup PythonNodeGroup {
                entry PythonNodeGroup(void);
                entry void execute (CkCcsRequestMsg *msg);
+               entry void iterate (CkCcsRequestMsg *msg);
        }
 
        array [1D] PythonArray1D {
                entry PythonArray1D(void);
                entry void execute (CkCcsRequestMsg *msg);
+               entry void iterate (CkCcsRequestMsg *msg);
        }
 
        array [2D] PythonArray2D {
                entry PythonArray2D(void);
                entry void execute (CkCcsRequestMsg *msg);
+               entry void iterate (CkCcsRequestMsg *msg);
        }
 
        array [3D] PythonArray3D {
                entry PythonArray3D(void);
                entry void execute (CkCcsRequestMsg *msg);
+               entry void iterate (CkCcsRequestMsg *msg);
        }
 
        initnode void initializePythonDefault(void);
index fc2118f37f9325bf97266e50360ef8a364730a43..612a23f21b14421f2124a4be5c3ae267e77dc01e 100644 (file)
@@ -3,6 +3,8 @@
 
 #include "ckcallback-ccs.h"
 #include "python/Python.h"
+#include "python/compile.h"
+#include "python/eval.h"
 #include "PythonCCS.decl.h"
 #include "string"
 #include "map"
@@ -65,12 +67,19 @@ typedef struct TypedValue_ {
 
 class PythonObject {
  public:
-  Py_objects type;
   void execute(CkCcsRequestMsg *msg);
+  void iterate(CkCcsRequestMsg *msg);
 
-  // the following three methods should be overwritten by the user
+  // the following methods should be overwritten by the user if used
+
+  // methods for accessing charm varibles from inside python
   virtual PyObject* read(PyObject*) {CkAbort("PythonCCS: Method read should be reimplemented");};
   virtual void write(PyObject*, PyObject*) {CkAbort("PythonCCS: Method write should be reimplemented");};
+
+  // methods to create iterators for iterative python invocations
+  virtual int buildIterator(PyObject*, void*) {CkAbort("PythonCCS: Method buildIterator should be reimplemented");};
+  virtual int nextIteratorUpdate(PyObject*, PyObject*, void*) {CkAbort("PythonCCS: Method nextIteratorUpdate should be reimplemented");};
+
   //virtual void registerPython();
 };