xref: /petsc/src/sys/classes/viewer/impls/mathematica/runtime.c (revision 48a46eb9bd028bec07ec0f396b1a3abb43f14558)
15c6c1daeSBarry Smith static const char help[] = "Tests PETSc -- Mathematica connection\n";
25c6c1daeSBarry Smith #include <petscksp.h>
35c6c1daeSBarry Smith #include <mathlink.h>
45c6c1daeSBarry Smith 
59371c9d4SSatish Balay typedef enum {
69371c9d4SSatish Balay   MATHEMATICA_LINK_CREATE,
79371c9d4SSatish Balay   MATHEMATICA_LINK_CONNECT,
89371c9d4SSatish Balay   MATHEMATICA_LINK_LAUNCH
99371c9d4SSatish Balay } LinkMode;
105c6c1daeSBarry Smith 
119371c9d4SSatish Balay static int setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode) {
125c6c1daeSBarry Smith   int   argc = 5;
135c6c1daeSBarry Smith   char *argv[5];
145c6c1daeSBarry Smith   char  hostname[256];
155c6c1daeSBarry Smith   long  lerr;
165c6c1daeSBarry Smith   int   ierr;
175c6c1daeSBarry Smith 
185c6c1daeSBarry Smith   PetscFunctionBegin;
195c6c1daeSBarry Smith   /* Link name */
205c6c1daeSBarry Smith   argv[0] = "-linkname";
215c6c1daeSBarry Smith   argv[1] = "8001";
22a297a907SKarl Rupp 
235c6c1daeSBarry Smith   /* Link host */
245c6c1daeSBarry Smith   argv[2] = "-linkhost";
255c6c1daeSBarry Smith   if (!linkhost) {
269566063dSJacob Faibussowitsch     PetscCall(PetscGetHostName(hostname, sizeof(hostname)));
275c6c1daeSBarry Smith     argv[3] = hostname;
28a297a907SKarl Rupp   } else argv[3] = (char *)linkhost;
29a297a907SKarl Rupp 
305c6c1daeSBarry Smith   /* Link mode */
315c6c1daeSBarry Smith   switch (linkmode) {
329371c9d4SSatish Balay   case MATHEMATICA_LINK_CREATE: argv[4] = "-linkcreate"; break;
339371c9d4SSatish Balay   case MATHEMATICA_LINK_CONNECT: argv[4] = "-linkconnect"; break;
349371c9d4SSatish Balay   case MATHEMATICA_LINK_LAUNCH: argv[4] = "-linklaunch"; break;
355c6c1daeSBarry Smith   }
365c6c1daeSBarry Smith 
375c6c1daeSBarry Smith   *env = MLInitialize(0);
38a297a907SKarl Rupp   for (lerr = 0; lerr < argc; lerr++) printf("argv[%ld] = %s\n", lerr, argv[lerr]);
395c6c1daeSBarry Smith   *link = MLOpenInEnv(*env, argc, argv, &lerr);
405c6c1daeSBarry Smith   printf("lerr = %ld\n", lerr);
415c6c1daeSBarry Smith   PetscFunctionReturn(0);
425c6c1daeSBarry Smith }
435c6c1daeSBarry Smith 
449371c9d4SSatish Balay static int printIndent(int indent) {
455c6c1daeSBarry Smith   int i;
465c6c1daeSBarry Smith 
475c6c1daeSBarry Smith   PetscFunctionBegin;
485c6c1daeSBarry Smith   for (i = 0; i < indent; i++) printf(" ");
495c6c1daeSBarry Smith   PetscFunctionReturn(0);
505c6c1daeSBarry Smith }
515c6c1daeSBarry Smith 
529371c9d4SSatish Balay static int processPacket(MLINK link, int indent) {
535c6c1daeSBarry Smith   static int isHead    = 0;
545c6c1daeSBarry Smith   int        tokenType = MLGetNext(link);
555c6c1daeSBarry Smith   int        ierr;
565c6c1daeSBarry Smith 
575c6c1daeSBarry Smith   PetscFunctionBegin;
589566063dSJacob Faibussowitsch   PetscCall(printIndent(indent));
595c6c1daeSBarry Smith   switch (tokenType) {
609371c9d4SSatish Balay   case MLTKFUNC: {
615c6c1daeSBarry Smith     long numArguments;
625c6c1daeSBarry Smith     int  arg;
635c6c1daeSBarry Smith 
645c6c1daeSBarry Smith     printf("Function:\n");
655c6c1daeSBarry Smith     MLGetArgCount(link, &numArguments);
665c6c1daeSBarry Smith     /* Process head */
675c6c1daeSBarry Smith     printf("  Head:\n");
685c6c1daeSBarry Smith     isHead = 1;
695c6c1daeSBarry Smith     ierr   = processPacket(link, indent + 4);
705c6c1daeSBarry Smith     if (ierr) PetscFunctionReturn(ierr);
715c6c1daeSBarry Smith     isHead = 0;
725c6c1daeSBarry Smith     /* Process arguments */
735c6c1daeSBarry Smith     printf("  Arguments:\n");
74*48a46eb9SPierre Jolivet     for (arg = 0; arg < numArguments; arg++) PetscCall(processPacket(link, indent + 4));
759371c9d4SSatish Balay   } break;
769371c9d4SSatish Balay   case MLTKSYM: {
775c6c1daeSBarry Smith     const char *symbol;
785c6c1daeSBarry Smith 
795c6c1daeSBarry Smith     MLGetSymbol(link, &symbol);
805c6c1daeSBarry Smith     printf("Symbol: %s\n", symbol);
815c6c1daeSBarry Smith     if (isHead && !strcmp(symbol, "Shutdown")) {
825c6c1daeSBarry Smith       MLDisownSymbol(link, symbol);
835c6c1daeSBarry Smith       PetscFunctionReturn(2);
845c6c1daeSBarry Smith     }
855c6c1daeSBarry Smith     MLDisownSymbol(link, symbol);
869371c9d4SSatish Balay   } break;
879371c9d4SSatish Balay   case MLTKINT: {
885c6c1daeSBarry Smith     int i;
895c6c1daeSBarry Smith 
905c6c1daeSBarry Smith     MLGetInteger(link, &i);
915c6c1daeSBarry Smith     printf("Integer: %d\n", i);
929371c9d4SSatish Balay   } break;
939371c9d4SSatish Balay   case MLTKREAL: {
945c6c1daeSBarry Smith     double r;
955c6c1daeSBarry Smith 
965c6c1daeSBarry Smith     MLGetReal(link, &r);
975c6c1daeSBarry Smith     printf("Real: %g\n", r);
989371c9d4SSatish Balay   } break;
999371c9d4SSatish Balay   case MLTKSTR: {
1005c6c1daeSBarry Smith     const char *string;
1015c6c1daeSBarry Smith 
1025c6c1daeSBarry Smith     MLGetString(link, &string);
1035c6c1daeSBarry Smith     printf("String: %s\n", string);
1045c6c1daeSBarry Smith     MLDisownString(link, string);
1059371c9d4SSatish Balay   } break;
1065c6c1daeSBarry Smith   default:
1075c6c1daeSBarry Smith     printf("Unknown code %d\n", tokenType);
1085c6c1daeSBarry Smith     MLClearError(link);
1095c6c1daeSBarry Smith     fprintf(stderr, "ERROR: %s\n", (char *)MLErrorMessage(link));
1105c6c1daeSBarry Smith     PetscFunctionReturn(1);
1115c6c1daeSBarry Smith   }
1125c6c1daeSBarry Smith   PetscFunctionReturn(0);
1135c6c1daeSBarry Smith }
1145c6c1daeSBarry Smith 
1159371c9d4SSatish Balay static int processPackets(MLINK link) {
1165c6c1daeSBarry Smith   int packetType;
1175c6c1daeSBarry Smith   int loop   = 1;
1185c6c1daeSBarry Smith   int errors = 0;
1192e58f0efSBarry Smith   int err;
1205c6c1daeSBarry Smith 
1215c6c1daeSBarry Smith   PetscFunctionBegin;
1225c6c1daeSBarry Smith   while (loop) {
1235c6c1daeSBarry Smith     while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) {
1245c6c1daeSBarry Smith       switch (packetType) {
1259371c9d4SSatish Balay       case BEGINDLGPKT: printf("Begin dialog packet\n"); break;
1269371c9d4SSatish Balay       case CALLPKT: printf("Call packet\n"); break;
1279371c9d4SSatish Balay       case DISPLAYPKT: printf("Display packet\n"); break;
1289371c9d4SSatish Balay       case DISPLAYENDPKT: printf("Display end packet\n"); break;
1299371c9d4SSatish Balay       case ENDDLGPKT: printf("End dialog packet\n"); break;
1309371c9d4SSatish Balay       case ENTERTEXTPKT: printf("Enter text packet\n"); break;
1319371c9d4SSatish Balay       case ENTEREXPRPKT: printf("Enter expression packet\n"); break;
1329371c9d4SSatish Balay       case EVALUATEPKT: printf("Evaluate packet\n"); break;
1339371c9d4SSatish Balay       case INPUTPKT: printf("Input packet\n"); break;
1349371c9d4SSatish Balay       case INPUTNAMEPKT: printf("Input name packet\n"); break;
1359371c9d4SSatish Balay       case INPUTSTRPKT: printf("Input string packet\n"); break;
1369371c9d4SSatish Balay       case MENUPKT: printf("Menu packet\n"); break;
1379371c9d4SSatish Balay       case MESSAGEPKT: printf("Message packet\n"); break;
1389371c9d4SSatish Balay       case OUTPUTNAMEPKT: printf("Output name packet\n"); break;
1399371c9d4SSatish Balay       case RESUMEPKT: printf("Resume packet\n"); break;
1409371c9d4SSatish Balay       case RETURNTEXTPKT: printf("Return text packet\n"); break;
1419371c9d4SSatish Balay       case RETURNEXPRPKT: printf("Return expression packet\n"); break;
1429371c9d4SSatish Balay       case SUSPENDPKT: printf("Suspend packet\n"); break;
1439371c9d4SSatish Balay       case SYNTAXPKT: printf("Syntax packet\n"); break;
1449371c9d4SSatish Balay       case TEXTPKT: printf("Text packet\n"); break;
1455c6c1daeSBarry Smith       }
1465c6c1daeSBarry Smith       MLNewPacket(link);
1475c6c1daeSBarry Smith     }
1485c6c1daeSBarry Smith 
1495c6c1daeSBarry Smith     /* Got a Return packet */
1505c6c1daeSBarry Smith     if (!packetType) {
1515c6c1daeSBarry Smith       MLClearError(link);
1525c6c1daeSBarry Smith       printf("ERROR: %s\n", (char *)MLErrorMessage(link));
1535c6c1daeSBarry Smith       errors++;
1545c6c1daeSBarry Smith     } else if (packetType == RETURNPKT) {
1552e58f0efSBarry Smith       err = processPacket(link, 0);
15608401ef6SPierre Jolivet       PetscCheck(err != 1, PETSC_COMM_SELF, PETSC_ERR_LIB, "Error returned from Mathematica");
1572e58f0efSBarry Smith       if (err == 2) loop = 0;
1585c6c1daeSBarry Smith     } else {
1595c6c1daeSBarry Smith       fprintf(stderr, "Invalid packet type %d\n", packetType);
1605c6c1daeSBarry Smith       loop = 0;
1615c6c1daeSBarry Smith     }
1625c6c1daeSBarry Smith     if (errors > 10) loop = 0;
1635c6c1daeSBarry Smith   }
1645c6c1daeSBarry Smith   PetscFunctionReturn(0);
1655c6c1daeSBarry Smith }
1665c6c1daeSBarry Smith 
1679371c9d4SSatish Balay static int cleanupConnection(MLENV env, MLINK link) {
1685c6c1daeSBarry Smith   PetscFunctionBegin;
1695c6c1daeSBarry Smith   MLClose(link);
1705c6c1daeSBarry Smith   MLDeinitialize(env);
1715c6c1daeSBarry Smith   PetscFunctionReturn(0);
1725c6c1daeSBarry Smith }
1735c6c1daeSBarry Smith 
1749371c9d4SSatish Balay int main(int argc, char *argv[]) {
1755c6c1daeSBarry Smith   MLENV env;
1765c6c1daeSBarry Smith   MLINK link;
1775c6c1daeSBarry Smith   int   ierr;
1785c6c1daeSBarry Smith 
1799566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
1809566063dSJacob Faibussowitsch   PetscCall(setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT));
1819566063dSJacob Faibussowitsch   PetscCall(processPackets(link));
1829566063dSJacob Faibussowitsch   PetscCall(cleanupConnection(env, link));
1839566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
184095b3734SBarry Smith   return (ierr);
1855c6c1daeSBarry Smith }
186