xref: /petsc/src/sys/classes/viewer/impls/mathematica/runtime.c (revision 1147fc2a6bf7922defbbca15fc6c33f234803ff0)
1 static const char help[] = "Tests PETSc -- Mathematica connection\n";
2 #include <petscksp.h>
3 #include <mathlink.h>
4 
5 typedef enum {MATHEMATICA_LINK_CREATE, MATHEMATICA_LINK_CONNECT, MATHEMATICA_LINK_LAUNCH} LinkMode;
6 
7 #undef __FUNCT__
8 #define __FUNCT__ "setupConnection"
9 static int setupConnection(MLENV *env, MLINK *link, const char *linkhost, LinkMode linkmode)
10 {
11   int   argc = 5;
12   char *argv[5];
13   char  hostname[256];
14   long  lerr;
15   int   ierr;
16 
17   PetscFunctionBegin;
18   /* Link name */
19   argv[0] = "-linkname";
20   argv[1] = "8001";
21   /* Link host */
22   argv[2] = "-linkhost";
23   if (!linkhost) {
24     ierr = PetscGetHostName(hostname, 255);CHKERRQ(ierr);
25     argv[3] = hostname;
26   } else {
27     argv[3] = (char *) linkhost;
28   }
29   /* Link mode */
30   switch (linkmode) {
31   case MATHEMATICA_LINK_CREATE:
32     argv[4] = "-linkcreate";
33     break;
34   case MATHEMATICA_LINK_CONNECT:
35     argv[4] = "-linkconnect";
36     break;
37   case MATHEMATICA_LINK_LAUNCH:
38     argv[4] = "-linklaunch";
39     break;
40   }
41 
42   *env  = MLInitialize(0);
43   for (lerr = 0; lerr < argc; lerr++) {
44     printf("argv[%ld] = %s\n", lerr, argv[lerr]);
45   }
46   *link = MLOpenInEnv(*env, argc, argv, &lerr);
47   printf("lerr = %ld\n", lerr);
48   PetscFunctionReturn(0);
49 }
50 
51 #undef __FUNCT__
52 #define __FUNCT__ "printIndent"
53 static int printIndent(int indent)
54 {
55   int i;
56 
57   PetscFunctionBegin;
58   for (i = 0; i < indent; i++) printf(" ");
59   PetscFunctionReturn(0);
60 }
61 
62 #undef __FUNCT__
63 #define __FUNCT__ "processPacket"
64 static int processPacket(MLINK link, int indent)
65 {
66   static int isHead    = 0;
67   int        tokenType = MLGetNext(link);
68   int        ierr;
69 
70   PetscFunctionBegin;
71   ierr = printIndent(indent);CHKERRQ(ierr);
72   switch (tokenType) {
73   case MLTKFUNC:
74     {
75       long numArguments;
76       int  arg;
77 
78       printf("Function:\n");
79       MLGetArgCount(link, &numArguments);
80       /* Process head */
81       printf("  Head:\n");
82       isHead = 1;
83       ierr = processPacket(link, indent+4);
84       if (ierr) PetscFunctionReturn(ierr);
85       isHead = 0;
86       /* Process arguments */
87       printf("  Arguments:\n");
88       for (arg = 0; arg < numArguments; arg++) {
89         ierr = processPacket(link, indent+4);CHKERRQ(ierr);
90       }
91     }
92     break;
93   case MLTKSYM:
94     {
95       const char *symbol;
96 
97       MLGetSymbol(link, &symbol);
98       printf("Symbol: %s\n", symbol);
99       if (isHead && !strcmp(symbol, "Shutdown")) {
100         MLDisownSymbol(link, symbol);
101         PetscFunctionReturn(2);
102       }
103       MLDisownSymbol(link, symbol);
104     }
105     break;
106   case MLTKINT:
107     {
108       int i;
109 
110       MLGetInteger(link, &i);
111       printf("Integer: %d\n", i);
112     }
113     break;
114   case MLTKREAL:
115     {
116       double r;
117 
118       MLGetReal(link, &r);
119       printf("Real: %g\n", r);
120     }
121     break;
122   case MLTKSTR:
123     {
124       const char *string;
125 
126       MLGetString(link, &string);
127       printf("String: %s\n", string);
128       MLDisownString(link, string);
129     }
130     break;
131   default:
132     printf("Unknown code %d\n", tokenType);
133     MLClearError(link);
134     fprintf(stderr, "ERROR: %s\n", (char *) MLErrorMessage(link));
135     PetscFunctionReturn(1);
136   }
137   PetscFunctionReturn(0);
138 }
139 
140 #undef __FUNCT__
141 #define __FUNCT__ "processPackets"
142 static int processPackets(MLINK link)
143 {
144   int packetType;
145   int loop   = 1;
146   int errors = 0;
147   int ierr;
148 
149   PetscFunctionBegin;
150   while (loop) {
151     while ((packetType = MLNextPacket(link)) && (packetType != RETURNPKT)) {
152       switch (packetType) {
153       case BEGINDLGPKT:
154         printf("Begin dialog packet\n");
155         break;
156       case CALLPKT:
157         printf("Call packet\n");
158         break;
159       case DISPLAYPKT:
160         printf("Display packet\n");
161         break;
162       case DISPLAYENDPKT:
163         printf("Display end packet\n");
164         break;
165       case ENDDLGPKT:
166         printf("End dialog packet\n");
167         break;
168       case ENTERTEXTPKT:
169         printf("Enter text packet\n");
170         break;
171       case ENTEREXPRPKT:
172         printf("Enter expression packet\n");
173         break;
174       case EVALUATEPKT:
175         printf("Evaluate packet\n");
176         break;
177       case INPUTPKT:
178         printf("Input packet\n");
179         break;
180       case INPUTNAMEPKT:
181         printf("Input name packet\n");
182         break;
183       case INPUTSTRPKT:
184         printf("Input string packet\n");
185         break;
186       case MENUPKT:
187         printf("Menu packet\n");
188         break;
189       case MESSAGEPKT:
190         printf("Message packet\n");
191         break;
192       case OUTPUTNAMEPKT:
193         printf("Output name packet\n");
194         break;
195       case RESUMEPKT:
196         printf("Resume packet\n");
197         break;
198       case RETURNTEXTPKT:
199         printf("Return text packet\n");
200         break;
201       case RETURNEXPRPKT:
202         printf("Return expression packet\n");
203         break;
204       case SUSPENDPKT:
205         printf("Suspend packet\n");
206         break;
207       case SYNTAXPKT:
208         printf("Syntax packet\n");
209         break;
210       case TEXTPKT:
211         printf("Text packet\n");
212         break;
213       }
214       MLNewPacket(link);
215     }
216 
217     /* Got a Return packet */
218     if (!packetType) {
219       MLClearError(link);
220       printf("ERROR: %s\n", (char *) MLErrorMessage(link));
221       errors++;
222     } else if (packetType == RETURNPKT) {
223       ierr = processPacket(link, 0);
224       if (ierr == 1) CHKERRQ(ierr);
225       if (ierr == 2) loop = 0;
226     } else {
227       fprintf(stderr, "Invalid packet type %d\n", packetType);
228       loop = 0;
229     }
230     if (errors > 10) loop = 0;
231   }
232   PetscFunctionReturn(0);
233 }
234 
235 #undef __FUNCT__
236 #define __FUNCT__ "cleanupConnection"
237 static int cleanupConnection(MLENV env, MLINK link)
238 {
239   PetscFunctionBegin;
240   MLClose(link);
241   MLDeinitialize(env);
242   PetscFunctionReturn(0);
243 }
244 
245 #undef __FUNCT__
246 #define __FUNCT__ "main"
247 int main(int argc, char *argv[])
248 {
249   MLENV env;
250   MLINK link;
251   int   ierr;
252 
253   ierr = PetscInitialize(&argc, &argv, PETSC_NULL, help);CHKERRABORT(PETSC_COMM_WORLD, ierr);
254   ierr = setupConnection(&env, &link, "192.168.119.1", MATHEMATICA_LINK_CONNECT);CHKERRABORT(PETSC_COMM_WORLD, ierr);
255   ierr = processPackets(link);CHKERRABORT(PETSC_COMM_WORLD, ierr);
256   ierr = cleanupConnection(env, link);CHKERRABORT(PETSC_COMM_WORLD, ierr);
257   ierr = PetscFinalize();CHKERRABORT(PETSC_COMM_WORLD, ierr);
258   return(0);
259 }
260