xref: /petsc/src/sys/classes/viewer/impls/mathematica/runtime.c (revision d71ae5a4db6382e7f06317b8d368875286fe9008)
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 
11*d71ae5a4SJacob Faibussowitsch static PetscErroCode setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode)
12*d71ae5a4SJacob Faibussowitsch {
135c6c1daeSBarry Smith   int   argc = 5;
145c6c1daeSBarry Smith   char *argv[5];
155c6c1daeSBarry Smith   char  hostname[256];
165c6c1daeSBarry Smith   long  lerr;
175c6c1daeSBarry Smith   int   ierr;
185c6c1daeSBarry Smith 
195c6c1daeSBarry Smith   PetscFunctionBegin;
205c6c1daeSBarry Smith   /* Link name */
215c6c1daeSBarry Smith   argv[0] = "-linkname";
225c6c1daeSBarry Smith   argv[1] = "8001";
23a297a907SKarl Rupp 
245c6c1daeSBarry Smith   /* Link host */
255c6c1daeSBarry Smith   argv[2] = "-linkhost";
265c6c1daeSBarry Smith   if (!linkhost) {
279566063dSJacob Faibussowitsch     PetscCall(PetscGetHostName(hostname, sizeof(hostname)));
285c6c1daeSBarry Smith     argv[3] = hostname;
29a297a907SKarl Rupp   } else argv[3] = (char *)linkhost;
30a297a907SKarl Rupp 
315c6c1daeSBarry Smith   /* Link mode */
325c6c1daeSBarry Smith   switch (linkmode) {
33*d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_CREATE:
34*d71ae5a4SJacob Faibussowitsch     argv[4] = "-linkcreate";
35*d71ae5a4SJacob Faibussowitsch     break;
36*d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_CONNECT:
37*d71ae5a4SJacob Faibussowitsch     argv[4] = "-linkconnect";
38*d71ae5a4SJacob Faibussowitsch     break;
39*d71ae5a4SJacob Faibussowitsch   case MATHEMATICA_LINK_LAUNCH:
40*d71ae5a4SJacob Faibussowitsch     argv[4] = "-linklaunch";
41*d71ae5a4SJacob Faibussowitsch     break;
425c6c1daeSBarry Smith   }
435c6c1daeSBarry Smith 
445c6c1daeSBarry Smith   *env = MLInitialize(0);
45a297a907SKarl Rupp   for (lerr = 0; lerr < argc; lerr++) printf("argv[%ld] = %s\n", lerr, argv[lerr]);
465c6c1daeSBarry Smith   *link = MLOpenInEnv(*env, argc, argv, &lerr);
475c6c1daeSBarry Smith   printf("lerr = %ld\n", lerr);
485c6c1daeSBarry Smith   PetscFunctionReturn(0);
495c6c1daeSBarry Smith }
505c6c1daeSBarry Smith 
51*d71ae5a4SJacob Faibussowitsch static PetscErrorCode printIndent(int indent)
52*d71ae5a4SJacob Faibussowitsch {
535c6c1daeSBarry Smith   int i;
545c6c1daeSBarry Smith 
555c6c1daeSBarry Smith   PetscFunctionBegin;
565c6c1daeSBarry Smith   for (i = 0; i < indent; i++) printf(" ");
575c6c1daeSBarry Smith   PetscFunctionReturn(0);
585c6c1daeSBarry Smith }
595c6c1daeSBarry Smith 
60*d71ae5a4SJacob Faibussowitsch static PetscErrorCode processPacket(MLINK link, int indent, int *result)
61*d71ae5a4SJacob Faibussowitsch {
625c6c1daeSBarry Smith   static int isHead    = 0;
635c6c1daeSBarry Smith   int        tokenType = MLGetNext(link);
645c6c1daeSBarry Smith   int        ierr;
655c6c1daeSBarry Smith 
665c6c1daeSBarry Smith   PetscFunctionBegin;
679566063dSJacob Faibussowitsch   PetscCall(printIndent(indent));
685c6c1daeSBarry Smith   switch (tokenType) {
699371c9d4SSatish Balay   case MLTKFUNC: {
705c6c1daeSBarry Smith     long numArguments;
715c6c1daeSBarry Smith     int  arg;
725c6c1daeSBarry Smith 
735c6c1daeSBarry Smith     printf("Function:\n");
745c6c1daeSBarry Smith     MLGetArgCount(link, &numArguments);
755c6c1daeSBarry Smith     /* Process head */
765c6c1daeSBarry Smith     printf("  Head:\n");
775c6c1daeSBarry Smith     isHead = 1;
7811cc89d2SBarry Smith     PetscCall(processPacket(link, indent + 4, result));
7911cc89d2SBarry Smith     if (*result) PetscFunctionReturn(0);
805c6c1daeSBarry Smith     isHead = 0;
815c6c1daeSBarry Smith     /* Process arguments */
825c6c1daeSBarry Smith     printf("  Arguments:\n");
8348a46eb9SPierre Jolivet     for (arg = 0; arg < numArguments; arg++) PetscCall(processPacket(link, indent + 4));
849371c9d4SSatish Balay   } break;
859371c9d4SSatish Balay   case MLTKSYM: {
865c6c1daeSBarry Smith     const char *symbol;
875c6c1daeSBarry Smith 
885c6c1daeSBarry Smith     MLGetSymbol(link, &symbol);
895c6c1daeSBarry Smith     printf("Symbol: %s\n", symbol);
905c6c1daeSBarry Smith     if (isHead && !strcmp(symbol, "Shutdown")) {
915c6c1daeSBarry Smith       MLDisownSymbol(link, symbol);
9211cc89d2SBarry Smith       *result = 2;
9311cc89d2SBarry Smith       PetscFunctionReturn(0);
945c6c1daeSBarry Smith     }
955c6c1daeSBarry Smith     MLDisownSymbol(link, symbol);
969371c9d4SSatish Balay   } break;
979371c9d4SSatish Balay   case MLTKINT: {
985c6c1daeSBarry Smith     int i;
995c6c1daeSBarry Smith 
1005c6c1daeSBarry Smith     MLGetInteger(link, &i);
1015c6c1daeSBarry Smith     printf("Integer: %d\n", i);
1029371c9d4SSatish Balay   } break;
1039371c9d4SSatish Balay   case MLTKREAL: {
1045c6c1daeSBarry Smith     double r;
1055c6c1daeSBarry Smith 
1065c6c1daeSBarry Smith     MLGetReal(link, &r);
1075c6c1daeSBarry Smith     printf("Real: %g\n", r);
1089371c9d4SSatish Balay   } break;
1099371c9d4SSatish Balay   case MLTKSTR: {
1105c6c1daeSBarry Smith     const char *string;
1115c6c1daeSBarry Smith 
1125c6c1daeSBarry Smith     MLGetString(link, &string);
1135c6c1daeSBarry Smith     printf("String: %s\n", string);
1145c6c1daeSBarry Smith     MLDisownString(link, string);
1159371c9d4SSatish Balay   } break;
1165c6c1daeSBarry Smith   default:
1175c6c1daeSBarry Smith     printf("Unknown code %d\n", tokenType);
1185c6c1daeSBarry Smith     MLClearError(link);
1195c6c1daeSBarry Smith     fprintf(stderr, "ERROR: %s\n", (char *)MLErrorMessage(link));
12011cc89d2SBarry Smith     *result = 1;
12111cc89d2SBarry Smith     PetscFunctionReturn(0);
1225c6c1daeSBarry Smith   }
1235c6c1daeSBarry Smith   PetscFunctionReturn(0);
1245c6c1daeSBarry Smith }
1255c6c1daeSBarry Smith 
126*d71ae5a4SJacob Faibussowitsch static PetscErrorCode processPackets(MLINK link)
127*d71ae5a4SJacob Faibussowitsch {
1285c6c1daeSBarry Smith   int packetType;
1295c6c1daeSBarry Smith   int loop   = 1;
1305c6c1daeSBarry Smith   int errors = 0;
13111cc89d2SBarry Smith   int err, result;
1325c6c1daeSBarry Smith 
1335c6c1daeSBarry Smith   PetscFunctionBegin;
1345c6c1daeSBarry Smith   while (loop) {
1355c6c1daeSBarry Smith     while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) {
1365c6c1daeSBarry Smith       switch (packetType) {
137*d71ae5a4SJacob Faibussowitsch       case BEGINDLGPKT:
138*d71ae5a4SJacob Faibussowitsch         printf("Begin dialog packet\n");
139*d71ae5a4SJacob Faibussowitsch         break;
140*d71ae5a4SJacob Faibussowitsch       case CALLPKT:
141*d71ae5a4SJacob Faibussowitsch         printf("Call packet\n");
142*d71ae5a4SJacob Faibussowitsch         break;
143*d71ae5a4SJacob Faibussowitsch       case DISPLAYPKT:
144*d71ae5a4SJacob Faibussowitsch         printf("Display packet\n");
145*d71ae5a4SJacob Faibussowitsch         break;
146*d71ae5a4SJacob Faibussowitsch       case DISPLAYENDPKT:
147*d71ae5a4SJacob Faibussowitsch         printf("Display end packet\n");
148*d71ae5a4SJacob Faibussowitsch         break;
149*d71ae5a4SJacob Faibussowitsch       case ENDDLGPKT:
150*d71ae5a4SJacob Faibussowitsch         printf("End dialog packet\n");
151*d71ae5a4SJacob Faibussowitsch         break;
152*d71ae5a4SJacob Faibussowitsch       case ENTERTEXTPKT:
153*d71ae5a4SJacob Faibussowitsch         printf("Enter text packet\n");
154*d71ae5a4SJacob Faibussowitsch         break;
155*d71ae5a4SJacob Faibussowitsch       case ENTEREXPRPKT:
156*d71ae5a4SJacob Faibussowitsch         printf("Enter expression packet\n");
157*d71ae5a4SJacob Faibussowitsch         break;
158*d71ae5a4SJacob Faibussowitsch       case EVALUATEPKT:
159*d71ae5a4SJacob Faibussowitsch         printf("Evaluate packet\n");
160*d71ae5a4SJacob Faibussowitsch         break;
161*d71ae5a4SJacob Faibussowitsch       case INPUTPKT:
162*d71ae5a4SJacob Faibussowitsch         printf("Input packet\n");
163*d71ae5a4SJacob Faibussowitsch         break;
164*d71ae5a4SJacob Faibussowitsch       case INPUTNAMEPKT:
165*d71ae5a4SJacob Faibussowitsch         printf("Input name packet\n");
166*d71ae5a4SJacob Faibussowitsch         break;
167*d71ae5a4SJacob Faibussowitsch       case INPUTSTRPKT:
168*d71ae5a4SJacob Faibussowitsch         printf("Input string packet\n");
169*d71ae5a4SJacob Faibussowitsch         break;
170*d71ae5a4SJacob Faibussowitsch       case MENUPKT:
171*d71ae5a4SJacob Faibussowitsch         printf("Menu packet\n");
172*d71ae5a4SJacob Faibussowitsch         break;
173*d71ae5a4SJacob Faibussowitsch       case MESSAGEPKT:
174*d71ae5a4SJacob Faibussowitsch         printf("Message packet\n");
175*d71ae5a4SJacob Faibussowitsch         break;
176*d71ae5a4SJacob Faibussowitsch       case OUTPUTNAMEPKT:
177*d71ae5a4SJacob Faibussowitsch         printf("Output name packet\n");
178*d71ae5a4SJacob Faibussowitsch         break;
179*d71ae5a4SJacob Faibussowitsch       case RESUMEPKT:
180*d71ae5a4SJacob Faibussowitsch         printf("Resume packet\n");
181*d71ae5a4SJacob Faibussowitsch         break;
182*d71ae5a4SJacob Faibussowitsch       case RETURNTEXTPKT:
183*d71ae5a4SJacob Faibussowitsch         printf("Return text packet\n");
184*d71ae5a4SJacob Faibussowitsch         break;
185*d71ae5a4SJacob Faibussowitsch       case RETURNEXPRPKT:
186*d71ae5a4SJacob Faibussowitsch         printf("Return expression packet\n");
187*d71ae5a4SJacob Faibussowitsch         break;
188*d71ae5a4SJacob Faibussowitsch       case SUSPENDPKT:
189*d71ae5a4SJacob Faibussowitsch         printf("Suspend packet\n");
190*d71ae5a4SJacob Faibussowitsch         break;
191*d71ae5a4SJacob Faibussowitsch       case SYNTAXPKT:
192*d71ae5a4SJacob Faibussowitsch         printf("Syntax packet\n");
193*d71ae5a4SJacob Faibussowitsch         break;
194*d71ae5a4SJacob Faibussowitsch       case TEXTPKT:
195*d71ae5a4SJacob Faibussowitsch         printf("Text packet\n");
196*d71ae5a4SJacob Faibussowitsch         break;
1975c6c1daeSBarry Smith       }
1985c6c1daeSBarry Smith       MLNewPacket(link);
1995c6c1daeSBarry Smith     }
2005c6c1daeSBarry Smith 
2015c6c1daeSBarry Smith     /* Got a Return packet */
2025c6c1daeSBarry Smith     if (!packetType) {
2035c6c1daeSBarry Smith       MLClearError(link);
2045c6c1daeSBarry Smith       printf("ERROR: %s\n", (char *)MLErrorMessage(link));
2055c6c1daeSBarry Smith       errors++;
2065c6c1daeSBarry Smith     } else if (packetType == RETURNPKT) {
20711cc89d2SBarry Smith       PetscCall(processPacket(link, result));
20811cc89d2SBarry Smith       if (result == 2) loop = 0;
2095c6c1daeSBarry Smith     } else {
2105c6c1daeSBarry Smith       fprintf(stderr, "Invalid packet type %d\n", packetType);
2115c6c1daeSBarry Smith       loop = 0;
2125c6c1daeSBarry Smith     }
2135c6c1daeSBarry Smith     if (errors > 10) loop = 0;
2145c6c1daeSBarry Smith   }
2155c6c1daeSBarry Smith   PetscFunctionReturn(0);
2165c6c1daeSBarry Smith }
2175c6c1daeSBarry Smith 
218*d71ae5a4SJacob Faibussowitsch static PetscErrorCode cleanupConnection(MLENV env, MLINK link)
219*d71ae5a4SJacob Faibussowitsch {
2205c6c1daeSBarry Smith   PetscFunctionBegin;
2215c6c1daeSBarry Smith   MLClose(link);
2225c6c1daeSBarry Smith   MLDeinitialize(env);
2235c6c1daeSBarry Smith   PetscFunctionReturn(0);
2245c6c1daeSBarry Smith }
2255c6c1daeSBarry Smith 
226*d71ae5a4SJacob Faibussowitsch int main(int argc, char *argv[])
227*d71ae5a4SJacob Faibussowitsch {
2285c6c1daeSBarry Smith   MLENV env;
2295c6c1daeSBarry Smith   MLINK link;
2305c6c1daeSBarry Smith 
2319566063dSJacob Faibussowitsch   PetscCall(PetscInitialize(&argc, &argv, NULL, help));
2329566063dSJacob Faibussowitsch   PetscCall(setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT));
2339566063dSJacob Faibussowitsch   PetscCall(processPackets(link));
2349566063dSJacob Faibussowitsch   PetscCall(cleanupConnection(env, link));
2359566063dSJacob Faibussowitsch   PetscCall(PetscFinalize());
23611cc89d2SBarry Smith   return 0;
2375c6c1daeSBarry Smith }
238