1*5c6c1daeSBarry Smith 2*5c6c1daeSBarry Smith #include <petscsys.h> 3*5c6c1daeSBarry Smith 4*5c6c1daeSBarry Smith #if defined(PETSC_NEEDS_UTYPE_TYPEDEFS) 5*5c6c1daeSBarry Smith /* Some systems have inconsistent include files that use but do not 6*5c6c1daeSBarry Smith ensure that the following definitions are made */ 7*5c6c1daeSBarry Smith typedef unsigned char u_char; 8*5c6c1daeSBarry Smith typedef unsigned short u_short; 9*5c6c1daeSBarry Smith typedef unsigned short ushort; 10*5c6c1daeSBarry Smith typedef unsigned int u_int; 11*5c6c1daeSBarry Smith typedef unsigned long u_long; 12*5c6c1daeSBarry Smith #endif 13*5c6c1daeSBarry Smith 14*5c6c1daeSBarry Smith #include <errno.h> 15*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_STDLIB_H) 16*5c6c1daeSBarry Smith #include <stdlib.h> 17*5c6c1daeSBarry Smith #endif 18*5c6c1daeSBarry Smith #include <sys/types.h> 19*5c6c1daeSBarry Smith #include <ctype.h> 20*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_MACHINE_ENDIAN_H) 21*5c6c1daeSBarry Smith #include <machine/endian.h> 22*5c6c1daeSBarry Smith #endif 23*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_UNISTD_H) 24*5c6c1daeSBarry Smith #include <unistd.h> 25*5c6c1daeSBarry Smith #endif 26*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_SYS_SOCKET_H) 27*5c6c1daeSBarry Smith #include <sys/socket.h> 28*5c6c1daeSBarry Smith #endif 29*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_SYS_WAIT_H) 30*5c6c1daeSBarry Smith #include <sys/wait.h> 31*5c6c1daeSBarry Smith #endif 32*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_NETINET_IN_H) 33*5c6c1daeSBarry Smith #include <netinet/in.h> 34*5c6c1daeSBarry Smith #endif 35*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_NETDB_H) 36*5c6c1daeSBarry Smith #include <netdb.h> 37*5c6c1daeSBarry Smith #endif 38*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_FCNTL_H) 39*5c6c1daeSBarry Smith #include <fcntl.h> 40*5c6c1daeSBarry Smith #endif 41*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_IO_H) 42*5c6c1daeSBarry Smith #include <io.h> 43*5c6c1daeSBarry Smith #endif 44*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_WINSOCK2_H) 45*5c6c1daeSBarry Smith #include <Winsock2.h> 46*5c6c1daeSBarry Smith #endif 47*5c6c1daeSBarry Smith #include <sys/stat.h> 48*5c6c1daeSBarry Smith #include <../src/sys/classes/viewer/impls/socket/socket.h> 49*5c6c1daeSBarry Smith 50*5c6c1daeSBarry Smith EXTERN_C_BEGIN 51*5c6c1daeSBarry Smith #if defined(PETSC_NEED_CLOSE_PROTO) 52*5c6c1daeSBarry Smith extern int close(int); 53*5c6c1daeSBarry Smith #endif 54*5c6c1daeSBarry Smith #if defined(PETSC_NEED_SOCKET_PROTO) 55*5c6c1daeSBarry Smith extern int socket(int,int,int); 56*5c6c1daeSBarry Smith #endif 57*5c6c1daeSBarry Smith #if defined(PETSC_NEED_SLEEP_PROTO) 58*5c6c1daeSBarry Smith extern int sleep(unsigned); 59*5c6c1daeSBarry Smith #endif 60*5c6c1daeSBarry Smith #if defined(PETSC_NEED_CONNECT_PROTO) 61*5c6c1daeSBarry Smith extern int connect(int,struct sockaddr *,int); 62*5c6c1daeSBarry Smith #endif 63*5c6c1daeSBarry Smith EXTERN_C_END 64*5c6c1daeSBarry Smith 65*5c6c1daeSBarry Smith /*--------------------------------------------------------------*/ 66*5c6c1daeSBarry Smith #undef __FUNCT__ 67*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerDestroy_Socket" 68*5c6c1daeSBarry Smith static PetscErrorCode PetscViewerDestroy_Socket(PetscViewer viewer) 69*5c6c1daeSBarry Smith { 70*5c6c1daeSBarry Smith PetscViewer_Socket *vmatlab = (PetscViewer_Socket*)viewer->data; 71*5c6c1daeSBarry Smith PetscErrorCode ierr; 72*5c6c1daeSBarry Smith 73*5c6c1daeSBarry Smith PetscFunctionBegin; 74*5c6c1daeSBarry Smith if (vmatlab->port) { 75*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_CLOSESOCKET) 76*5c6c1daeSBarry Smith ierr = closesocket(vmatlab->port); 77*5c6c1daeSBarry Smith #else 78*5c6c1daeSBarry Smith ierr = close(vmatlab->port); 79*5c6c1daeSBarry Smith #endif 80*5c6c1daeSBarry Smith if (ierr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"System error closing socket"); 81*5c6c1daeSBarry Smith } 82*5c6c1daeSBarry Smith ierr = PetscFree(vmatlab);CHKERRQ(ierr); 83*5c6c1daeSBarry Smith PetscFunctionReturn(0); 84*5c6c1daeSBarry Smith } 85*5c6c1daeSBarry Smith 86*5c6c1daeSBarry Smith /*--------------------------------------------------------------*/ 87*5c6c1daeSBarry Smith #undef __FUNCT__ 88*5c6c1daeSBarry Smith #define __FUNCT__ "PetscOpenSocket" 89*5c6c1daeSBarry Smith /* 90*5c6c1daeSBarry Smith PetscSocketOpen - handles connected to an open port where someone is waiting. 91*5c6c1daeSBarry Smith 92*5c6c1daeSBarry Smith .seealso: PetscSocketListen(), PetscSocketEstablish() 93*5c6c1daeSBarry Smith */ 94*5c6c1daeSBarry Smith PetscErrorCode PetscOpenSocket(char *hostname,int portnum,int *t) 95*5c6c1daeSBarry Smith { 96*5c6c1daeSBarry Smith struct sockaddr_in sa; 97*5c6c1daeSBarry Smith struct hostent *hp; 98*5c6c1daeSBarry Smith int s = 0; 99*5c6c1daeSBarry Smith PetscErrorCode ierr; 100*5c6c1daeSBarry Smith PetscBool flg = PETSC_TRUE; 101*5c6c1daeSBarry Smith 102*5c6c1daeSBarry Smith PetscFunctionBegin; 103*5c6c1daeSBarry Smith if (!(hp=gethostbyname(hostname))) { 104*5c6c1daeSBarry Smith perror("SEND: error gethostbyname: "); 105*5c6c1daeSBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error open connection to %s",hostname); 106*5c6c1daeSBarry Smith } 107*5c6c1daeSBarry Smith ierr = PetscMemzero(&sa,sizeof(sa));CHKERRQ(ierr); 108*5c6c1daeSBarry Smith ierr = PetscMemcpy(&sa.sin_addr,hp->h_addr_list[0],hp->h_length);CHKERRQ(ierr); 109*5c6c1daeSBarry Smith 110*5c6c1daeSBarry Smith sa.sin_family = hp->h_addrtype; 111*5c6c1daeSBarry Smith sa.sin_port = htons((u_short) portnum); 112*5c6c1daeSBarry Smith while (flg) { 113*5c6c1daeSBarry Smith if ((s=socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) { 114*5c6c1daeSBarry Smith perror("SEND: error socket"); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error"); 115*5c6c1daeSBarry Smith } 116*5c6c1daeSBarry Smith if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) { 117*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_WSAGETLASTERROR) 118*5c6c1daeSBarry Smith ierr = WSAGetLastError(); 119*5c6c1daeSBarry Smith if (ierr == WSAEADDRINUSE) { 120*5c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: address is in use\n"); 121*5c6c1daeSBarry Smith } else if (ierr == WSAEALREADY) { 122*5c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: socket is non-blocking \n"); 123*5c6c1daeSBarry Smith } else if (ierr == WSAEISCONN) { 124*5c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: socket already connected\n"); 125*5c6c1daeSBarry Smith Sleep((unsigned) 1); 126*5c6c1daeSBarry Smith } else if (ierr == WSAECONNREFUSED) { 127*5c6c1daeSBarry Smith /* (*PetscErrorPrintf)("SEND: forcefully rejected\n"); */ 128*5c6c1daeSBarry Smith Sleep((unsigned) 1); 129*5c6c1daeSBarry Smith } else { 130*5c6c1daeSBarry Smith perror(NULL); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error"); 131*5c6c1daeSBarry Smith } 132*5c6c1daeSBarry Smith #else 133*5c6c1daeSBarry Smith if (errno == EADDRINUSE) { 134*5c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: address is in use\n"); 135*5c6c1daeSBarry Smith } else if (errno == EALREADY) { 136*5c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: socket is non-blocking \n"); 137*5c6c1daeSBarry Smith } else if (errno == EISCONN) { 138*5c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: socket already connected\n"); 139*5c6c1daeSBarry Smith sleep((unsigned) 1); 140*5c6c1daeSBarry Smith } else if (errno == ECONNREFUSED) { 141*5c6c1daeSBarry Smith /* (*PetscErrorPrintf)("SEND: forcefully rejected\n"); */ 142*5c6c1daeSBarry Smith ierr = PetscInfo(0,"Connection refused in attaching socket, trying again");CHKERRQ(ierr); 143*5c6c1daeSBarry Smith sleep((unsigned) 1); 144*5c6c1daeSBarry Smith } else { 145*5c6c1daeSBarry Smith perror(NULL); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error"); 146*5c6c1daeSBarry Smith } 147*5c6c1daeSBarry Smith #endif 148*5c6c1daeSBarry Smith flg = PETSC_TRUE; 149*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_CLOSESOCKET) 150*5c6c1daeSBarry Smith closesocket(s); 151*5c6c1daeSBarry Smith #else 152*5c6c1daeSBarry Smith close(s); 153*5c6c1daeSBarry Smith #endif 154*5c6c1daeSBarry Smith } 155*5c6c1daeSBarry Smith else flg = PETSC_FALSE; 156*5c6c1daeSBarry Smith } 157*5c6c1daeSBarry Smith *t = s; 158*5c6c1daeSBarry Smith PetscFunctionReturn(0); 159*5c6c1daeSBarry Smith } 160*5c6c1daeSBarry Smith 161*5c6c1daeSBarry Smith #define MAXHOSTNAME 100 162*5c6c1daeSBarry Smith #undef __FUNCT__ 163*5c6c1daeSBarry Smith #define __FUNCT__ "PetscSocketEstablish" 164*5c6c1daeSBarry Smith /* 165*5c6c1daeSBarry Smith PetscSocketEstablish - starts a listener on a socket 166*5c6c1daeSBarry Smith 167*5c6c1daeSBarry Smith .seealso: PetscSocketListen() 168*5c6c1daeSBarry Smith */ 169*5c6c1daeSBarry Smith PetscErrorCode PetscSocketEstablish(int portnum,int *ss) 170*5c6c1daeSBarry Smith { 171*5c6c1daeSBarry Smith char myname[MAXHOSTNAME+1]; 172*5c6c1daeSBarry Smith int s; 173*5c6c1daeSBarry Smith PetscErrorCode ierr; 174*5c6c1daeSBarry Smith struct sockaddr_in sa; 175*5c6c1daeSBarry Smith struct hostent *hp; 176*5c6c1daeSBarry Smith 177*5c6c1daeSBarry Smith PetscFunctionBegin; 178*5c6c1daeSBarry Smith ierr = PetscGetHostName(myname,MAXHOSTNAME);CHKERRQ(ierr); 179*5c6c1daeSBarry Smith 180*5c6c1daeSBarry Smith ierr = PetscMemzero(&sa,sizeof(struct sockaddr_in));CHKERRQ(ierr); 181*5c6c1daeSBarry Smith 182*5c6c1daeSBarry Smith hp = gethostbyname(myname); 183*5c6c1daeSBarry Smith if (!hp) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Unable to get hostent information from system"); 184*5c6c1daeSBarry Smith 185*5c6c1daeSBarry Smith sa.sin_family = hp->h_addrtype; 186*5c6c1daeSBarry Smith sa.sin_port = htons((u_short)portnum); 187*5c6c1daeSBarry Smith 188*5c6c1daeSBarry Smith if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Error running socket() command"); 189*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_SO_REUSEADDR) 190*5c6c1daeSBarry Smith { 191*5c6c1daeSBarry Smith int optval = 1; /* Turn on the option */ 192*5c6c1daeSBarry Smith ierr = setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char *)&optval,sizeof(optval));CHKERRQ(ierr); 193*5c6c1daeSBarry Smith } 194*5c6c1daeSBarry Smith #endif 195*5c6c1daeSBarry Smith 196*5c6c1daeSBarry Smith while (bind(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) { 197*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_WSAGETLASTERROR) 198*5c6c1daeSBarry Smith ierr = WSAGetLastError(); 199*5c6c1daeSBarry Smith if (ierr != WSAEADDRINUSE) { 200*5c6c1daeSBarry Smith #else 201*5c6c1daeSBarry Smith if (errno != EADDRINUSE) { 202*5c6c1daeSBarry Smith #endif 203*5c6c1daeSBarry Smith close(s); 204*5c6c1daeSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Error from bind()"); 205*5c6c1daeSBarry Smith } 206*5c6c1daeSBarry Smith } 207*5c6c1daeSBarry Smith listen(s,0); 208*5c6c1daeSBarry Smith *ss = s; 209*5c6c1daeSBarry Smith return(0); 210*5c6c1daeSBarry Smith } 211*5c6c1daeSBarry Smith 212*5c6c1daeSBarry Smith #undef __FUNCT__ 213*5c6c1daeSBarry Smith #define __FUNCT__ "PetscSocketListen" 214*5c6c1daeSBarry Smith /* 215*5c6c1daeSBarry Smith PetscSocketListens - Listens at a socket created with PetscSocketEstablish() 216*5c6c1daeSBarry Smith 217*5c6c1daeSBarry Smith .seealso: PetscSocketEstablish() 218*5c6c1daeSBarry Smith */ 219*5c6c1daeSBarry Smith PetscErrorCode PetscSocketListen(int listenport,int *t) 220*5c6c1daeSBarry Smith { 221*5c6c1daeSBarry Smith struct sockaddr_in isa; 222*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_ACCEPT_SIZE_T) 223*5c6c1daeSBarry Smith size_t i; 224*5c6c1daeSBarry Smith #else 225*5c6c1daeSBarry Smith int i; 226*5c6c1daeSBarry Smith #endif 227*5c6c1daeSBarry Smith 228*5c6c1daeSBarry Smith PetscFunctionBegin; 229*5c6c1daeSBarry Smith /* wait for someone to try to connect */ 230*5c6c1daeSBarry Smith i = sizeof(struct sockaddr_in); 231*5c6c1daeSBarry Smith if ((*t = accept(listenport,(struct sockaddr *)&isa,(socklen_t *)&i)) < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"error from accept()\n"); 232*5c6c1daeSBarry Smith PetscFunctionReturn(0); 233*5c6c1daeSBarry Smith } 234*5c6c1daeSBarry Smith 235*5c6c1daeSBarry Smith #undef __FUNCT__ 236*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerSocketOpen" 237*5c6c1daeSBarry Smith /*@C 238*5c6c1daeSBarry Smith PetscViewerSocketOpen - Opens a connection to a MATLAB or other socket 239*5c6c1daeSBarry Smith based server. 240*5c6c1daeSBarry Smith 241*5c6c1daeSBarry Smith Collective on MPI_Comm 242*5c6c1daeSBarry Smith 243*5c6c1daeSBarry Smith Input Parameters: 244*5c6c1daeSBarry Smith + comm - the MPI communicator 245*5c6c1daeSBarry Smith . machine - the machine the server is running on,, use PETSC_NULL for the local machine, use "server" to passively wait for 246*5c6c1daeSBarry Smith a connection from elsewhere 247*5c6c1daeSBarry Smith - port - the port to connect to, use PETSC_DEFAULT for the default 248*5c6c1daeSBarry Smith 249*5c6c1daeSBarry Smith Output Parameter: 250*5c6c1daeSBarry Smith . lab - a context to use when communicating with the server 251*5c6c1daeSBarry Smith 252*5c6c1daeSBarry Smith Level: intermediate 253*5c6c1daeSBarry Smith 254*5c6c1daeSBarry Smith Notes: 255*5c6c1daeSBarry Smith Most users should employ the following commands to access the 256*5c6c1daeSBarry Smith MATLAB PetscViewers 257*5c6c1daeSBarry Smith $ 258*5c6c1daeSBarry Smith $ PetscViewerSocketOpen(MPI_Comm comm, char *machine,int port,PetscViewer &viewer) 259*5c6c1daeSBarry Smith $ MatView(Mat matrix,PetscViewer viewer) 260*5c6c1daeSBarry Smith $ 261*5c6c1daeSBarry Smith $ or 262*5c6c1daeSBarry Smith $ 263*5c6c1daeSBarry Smith $ PetscViewerSocketOpen(MPI_Comm comm,char *machine,int port,PetscViewer &viewer) 264*5c6c1daeSBarry Smith $ VecView(Vec vector,PetscViewer viewer) 265*5c6c1daeSBarry Smith 266*5c6c1daeSBarry Smith Options Database Keys: 267*5c6c1daeSBarry Smith For use with PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF, 268*5c6c1daeSBarry Smith PETSC_VIEWER_SOCKET_() or if 269*5c6c1daeSBarry Smith PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port 270*5c6c1daeSBarry Smith $ -viewer_socket_machine <machine> 271*5c6c1daeSBarry Smith $ -viewer_socket_port <port> 272*5c6c1daeSBarry Smith 273*5c6c1daeSBarry Smith Environmental variables: 274*5c6c1daeSBarry Smith + PETSC_VIEWER_SOCKET_PORT portnumber 275*5c6c1daeSBarry Smith - PETSC_VIEWER_SOCKET_MACHINE machine name 276*5c6c1daeSBarry Smith 277*5c6c1daeSBarry Smith Currently the only socket client available is MATLAB. See 278*5c6c1daeSBarry Smith src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage. 279*5c6c1daeSBarry Smith 280*5c6c1daeSBarry Smith Notes: The socket viewer is in some sense a subclass of the binary viewer, to read and write to the socket 281*5c6c1daeSBarry Smith use PetscViewerBinaryRead/Write/GetDescriptor(). 282*5c6c1daeSBarry Smith 283*5c6c1daeSBarry Smith Concepts: MATLAB^sending data 284*5c6c1daeSBarry Smith Concepts: sockets^sending data 285*5c6c1daeSBarry Smith 286*5c6c1daeSBarry Smith .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerSetType(), 287*5c6c1daeSBarry Smith PetscViewerSocketSetConnection(), PETSC_VIEWER_SOCKET_, PETSC_VIEWER_SOCKET_WORLD, 288*5c6c1daeSBarry Smith PETSC_VIEWER_SOCKET_SELF, PetscViewerBinaryWrite(), PetscViewerBinaryRead(), PetscViewerBinaryWriteStringArray(), 289*5c6c1daeSBarry Smith PetscBinaryViewerGetDescriptor() 290*5c6c1daeSBarry Smith @*/ 291*5c6c1daeSBarry Smith PetscErrorCode PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab) 292*5c6c1daeSBarry Smith { 293*5c6c1daeSBarry Smith PetscErrorCode ierr; 294*5c6c1daeSBarry Smith 295*5c6c1daeSBarry Smith PetscFunctionBegin; 296*5c6c1daeSBarry Smith ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 297*5c6c1daeSBarry Smith ierr = PetscViewerSetType(*lab,PETSCVIEWERSOCKET);CHKERRQ(ierr); 298*5c6c1daeSBarry Smith ierr = PetscViewerSocketSetConnection(*lab,machine,port);CHKERRQ(ierr); 299*5c6c1daeSBarry Smith PetscFunctionReturn(0); 300*5c6c1daeSBarry Smith } 301*5c6c1daeSBarry Smith 302*5c6c1daeSBarry Smith #undef __FUNCT__ 303*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerSetFromOptions_Socket" 304*5c6c1daeSBarry Smith PetscErrorCode PetscViewerSetFromOptions_Socket(PetscViewer v) 305*5c6c1daeSBarry Smith { 306*5c6c1daeSBarry Smith PetscErrorCode ierr; 307*5c6c1daeSBarry Smith PetscInt def = -1; 308*5c6c1daeSBarry Smith char sdef[256]; 309*5c6c1daeSBarry Smith PetscBool tflg; 310*5c6c1daeSBarry Smith 311*5c6c1daeSBarry Smith PetscFunctionBegin; 312*5c6c1daeSBarry Smith /* 313*5c6c1daeSBarry Smith These options are not processed here, they are processed in PetscViewerSocketSetConnection(), they 314*5c6c1daeSBarry Smith are listed here for the GUI to display 315*5c6c1daeSBarry Smith */ 316*5c6c1daeSBarry Smith ierr = PetscOptionsHead("Socket PetscViewer Options");CHKERRQ(ierr); 317*5c6c1daeSBarry Smith ierr = PetscOptionsGetenv(((PetscObject)v)->comm,"PETSC_VIEWER_SOCKET_PORT",sdef,16,&tflg);CHKERRQ(ierr); 318*5c6c1daeSBarry Smith if (tflg) { 319*5c6c1daeSBarry Smith ierr = PetscOptionsStringToInt(sdef,&def);CHKERRQ(ierr); 320*5c6c1daeSBarry Smith } else { 321*5c6c1daeSBarry Smith def = PETSCSOCKETDEFAULTPORT; 322*5c6c1daeSBarry Smith } 323*5c6c1daeSBarry Smith ierr = PetscOptionsInt("-viewer_socket_port","Port number to use for socket","PetscViewerSocketSetConnection",def,0,0);CHKERRQ(ierr); 324*5c6c1daeSBarry Smith 325*5c6c1daeSBarry Smith ierr = PetscOptionsString("-viewer_socket_machine","Machine to use for socket","PetscViewerSocketSetConnection",sdef,0,0,0);CHKERRQ(ierr); 326*5c6c1daeSBarry Smith ierr = PetscOptionsGetenv(((PetscObject)v)->comm,"PETSC_VIEWER_SOCKET_MACHINE",sdef,256,&tflg);CHKERRQ(ierr); 327*5c6c1daeSBarry Smith if (!tflg) { 328*5c6c1daeSBarry Smith ierr = PetscGetHostName(sdef,256);CHKERRQ(ierr); 329*5c6c1daeSBarry Smith } 330*5c6c1daeSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 331*5c6c1daeSBarry Smith PetscFunctionReturn(0); 332*5c6c1daeSBarry Smith } 333*5c6c1daeSBarry Smith 334*5c6c1daeSBarry Smith EXTERN_C_BEGIN 335*5c6c1daeSBarry Smith #undef __FUNCT__ 336*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerCreate_Socket" 337*5c6c1daeSBarry Smith PetscErrorCode PetscViewerCreate_Socket(PetscViewer v) 338*5c6c1daeSBarry Smith { 339*5c6c1daeSBarry Smith PetscViewer_Socket *vmatlab; 340*5c6c1daeSBarry Smith PetscErrorCode ierr; 341*5c6c1daeSBarry Smith 342*5c6c1daeSBarry Smith PetscFunctionBegin; 343*5c6c1daeSBarry Smith ierr = PetscNewLog(v,PetscViewer_Socket,&vmatlab);CHKERRQ(ierr); 344*5c6c1daeSBarry Smith vmatlab->port = 0; 345*5c6c1daeSBarry Smith v->data = (void*)vmatlab; 346*5c6c1daeSBarry Smith v->ops->destroy = PetscViewerDestroy_Socket; 347*5c6c1daeSBarry Smith v->ops->flush = 0; 348*5c6c1daeSBarry Smith v->ops->setfromoptions = PetscViewerSetFromOptions_Socket; 349*5c6c1daeSBarry Smith 350*5c6c1daeSBarry Smith /* lie and say this is a binary viewer; then all the XXXView_Binary() methods will work correctly on it */ 351*5c6c1daeSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)v,PETSCVIEWERBINARY);CHKERRQ(ierr); 352*5c6c1daeSBarry Smith PetscFunctionReturn(0); 353*5c6c1daeSBarry Smith } 354*5c6c1daeSBarry Smith EXTERN_C_END 355*5c6c1daeSBarry Smith 356*5c6c1daeSBarry Smith #undef __FUNCT__ 357*5c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerSocketSetConnection" 358*5c6c1daeSBarry Smith /*@C 359*5c6c1daeSBarry Smith PetscViewerSocketSetConnection - Sets the machine and port that a PETSc socket 360*5c6c1daeSBarry Smith viewer is to use 361*5c6c1daeSBarry Smith 362*5c6c1daeSBarry Smith Logically Collective on PetscViewer 363*5c6c1daeSBarry Smith 364*5c6c1daeSBarry Smith Input Parameters: 365*5c6c1daeSBarry Smith + v - viewer to connect 366*5c6c1daeSBarry Smith . machine - host to connect to, use PETSC_NULL for the local machine,use "server" to passively wait for 367*5c6c1daeSBarry Smith a connection from elsewhere 368*5c6c1daeSBarry Smith - port - the port on the machine one is connecting to, use PETSC_DEFAULT for default 369*5c6c1daeSBarry Smith 370*5c6c1daeSBarry Smith Level: advanced 371*5c6c1daeSBarry Smith 372*5c6c1daeSBarry Smith .seealso: PetscViewerSocketOpen() 373*5c6c1daeSBarry Smith @*/ 374*5c6c1daeSBarry Smith PetscErrorCode PetscViewerSocketSetConnection(PetscViewer v,const char machine[],int port) 375*5c6c1daeSBarry Smith { 376*5c6c1daeSBarry Smith PetscErrorCode ierr; 377*5c6c1daeSBarry Smith PetscMPIInt rank; 378*5c6c1daeSBarry Smith char mach[256]; 379*5c6c1daeSBarry Smith PetscBool tflg; 380*5c6c1daeSBarry Smith PetscViewer_Socket *vmatlab = (PetscViewer_Socket *)v->data; 381*5c6c1daeSBarry Smith 382*5c6c1daeSBarry Smith PetscFunctionBegin; 383*5c6c1daeSBarry Smith /* PetscValidLogicalCollectiveInt(v,port,3); not a PetscInt */ 384*5c6c1daeSBarry Smith if (port <= 0) { 385*5c6c1daeSBarry Smith char portn[16]; 386*5c6c1daeSBarry Smith ierr = PetscOptionsGetenv(((PetscObject)v)->comm,"PETSC_VIEWER_SOCKET_PORT",portn,16,&tflg);CHKERRQ(ierr); 387*5c6c1daeSBarry Smith if (tflg) { 388*5c6c1daeSBarry Smith PetscInt pport; 389*5c6c1daeSBarry Smith ierr = PetscOptionsStringToInt(portn,&pport);CHKERRQ(ierr); 390*5c6c1daeSBarry Smith port = (int)pport; 391*5c6c1daeSBarry Smith } else { 392*5c6c1daeSBarry Smith port = PETSCSOCKETDEFAULTPORT; 393*5c6c1daeSBarry Smith } 394*5c6c1daeSBarry Smith } 395*5c6c1daeSBarry Smith if (!machine) { 396*5c6c1daeSBarry Smith ierr = PetscOptionsGetenv(((PetscObject)v)->comm,"PETSC_VIEWER_SOCKET_MACHINE",mach,256,&tflg);CHKERRQ(ierr); 397*5c6c1daeSBarry Smith if (!tflg) { 398*5c6c1daeSBarry Smith ierr = PetscGetHostName(mach,256);CHKERRQ(ierr); 399*5c6c1daeSBarry Smith } 400*5c6c1daeSBarry Smith } else { 401*5c6c1daeSBarry Smith ierr = PetscStrncpy(mach,machine,256);CHKERRQ(ierr); 402*5c6c1daeSBarry Smith } 403*5c6c1daeSBarry Smith 404*5c6c1daeSBarry Smith ierr = MPI_Comm_rank(((PetscObject)v)->comm,&rank);CHKERRQ(ierr); 405*5c6c1daeSBarry Smith if (!rank) { 406*5c6c1daeSBarry Smith ierr = PetscStrcmp(mach,"server",&tflg);CHKERRQ(ierr); 407*5c6c1daeSBarry Smith if (tflg) { 408*5c6c1daeSBarry Smith int listenport; 409*5c6c1daeSBarry Smith ierr = PetscInfo1(v,"Waiting for connection from socket process on port %D\n",port);CHKERRQ(ierr); 410*5c6c1daeSBarry Smith ierr = PetscSocketEstablish(port,&listenport);CHKERRQ(ierr); 411*5c6c1daeSBarry Smith ierr = PetscSocketListen(listenport,&vmatlab->port);CHKERRQ(ierr); 412*5c6c1daeSBarry Smith close(listenport); 413*5c6c1daeSBarry Smith } else { 414*5c6c1daeSBarry Smith ierr = PetscInfo2(v,"Connecting to socket process on port %D machine %s\n",port,mach);CHKERRQ(ierr); 415*5c6c1daeSBarry Smith ierr = PetscOpenSocket(mach,port,&vmatlab->port);CHKERRQ(ierr); 416*5c6c1daeSBarry Smith } 417*5c6c1daeSBarry Smith } 418*5c6c1daeSBarry Smith PetscFunctionReturn(0); 419*5c6c1daeSBarry Smith } 420*5c6c1daeSBarry Smith 421*5c6c1daeSBarry Smith /* ---------------------------------------------------------------------*/ 422*5c6c1daeSBarry Smith /* 423*5c6c1daeSBarry Smith The variable Petsc_Viewer_Socket_keyval is used to indicate an MPI attribute that 424*5c6c1daeSBarry Smith is attached to a communicator, in this case the attribute is a PetscViewer. 425*5c6c1daeSBarry Smith */ 426*5c6c1daeSBarry Smith static PetscMPIInt Petsc_Viewer_Socket_keyval = MPI_KEYVAL_INVALID; 427*5c6c1daeSBarry Smith 428*5c6c1daeSBarry Smith 429*5c6c1daeSBarry Smith #undef __FUNCT__ 430*5c6c1daeSBarry Smith #define __FUNCT__ "PETSC_VIEWER_SOCKET_" 431*5c6c1daeSBarry Smith /*@C 432*5c6c1daeSBarry Smith PETSC_VIEWER_SOCKET_ - Creates a socket viewer shared by all processors in a communicator. 433*5c6c1daeSBarry Smith 434*5c6c1daeSBarry Smith Collective on MPI_Comm 435*5c6c1daeSBarry Smith 436*5c6c1daeSBarry Smith Input Parameter: 437*5c6c1daeSBarry Smith . comm - the MPI communicator to share the socket PetscViewer 438*5c6c1daeSBarry Smith 439*5c6c1daeSBarry Smith Level: intermediate 440*5c6c1daeSBarry Smith 441*5c6c1daeSBarry Smith Options Database Keys: 442*5c6c1daeSBarry Smith For use with the default PETSC_VIEWER_SOCKET_WORLD or if 443*5c6c1daeSBarry Smith PETSC_NULL is passed for machine or PETSC_DEFAULT is passed for port 444*5c6c1daeSBarry Smith $ -viewer_socket_machine <machine> 445*5c6c1daeSBarry Smith $ -viewer_socket_port <port> 446*5c6c1daeSBarry Smith 447*5c6c1daeSBarry Smith Environmental variables: 448*5c6c1daeSBarry Smith + PETSC_VIEWER_SOCKET_PORT portnumber 449*5c6c1daeSBarry Smith - PETSC_VIEWER_SOCKET_MACHINE machine name 450*5c6c1daeSBarry Smith 451*5c6c1daeSBarry Smith Notes: 452*5c6c1daeSBarry Smith Unlike almost all other PETSc routines, PetscViewer_SOCKET_ does not return 453*5c6c1daeSBarry Smith an error code. The socket PetscViewer is usually used in the form 454*5c6c1daeSBarry Smith $ XXXView(XXX object,PETSC_VIEWER_SOCKET_(comm)); 455*5c6c1daeSBarry Smith 456*5c6c1daeSBarry Smith Currently the only socket client available is MATLAB. See 457*5c6c1daeSBarry Smith src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage. 458*5c6c1daeSBarry Smith 459*5c6c1daeSBarry Smith Connects to a waiting socket and stays connected until PetscViewerDestroy() is called. 460*5c6c1daeSBarry Smith 461*5c6c1daeSBarry Smith Use this for communicating with an interactive MATLAB session, see PETSC_VIEWER_MATLAB_() for communicating with the MATLAB engine. 462*5c6c1daeSBarry Smith 463*5c6c1daeSBarry Smith .seealso: PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF, PetscViewerSocketOpen(), PetscViewerCreate(), 464*5c6c1daeSBarry Smith PetscViewerSocketSetConnection(), PetscViewerDestroy(), PETSC_VIEWER_SOCKET_(), PetscViewerBinaryWrite(), PetscViewerBinaryRead(), 465*5c6c1daeSBarry Smith PetscViewerBinaryWriteStringArray(), PetscBinaryViewerGetDescriptor(), PETSC_VIEWER_MATLAB_() 466*5c6c1daeSBarry Smith @*/ 467*5c6c1daeSBarry Smith PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm) 468*5c6c1daeSBarry Smith { 469*5c6c1daeSBarry Smith PetscErrorCode ierr; 470*5c6c1daeSBarry Smith PetscBool flg; 471*5c6c1daeSBarry Smith PetscViewer viewer; 472*5c6c1daeSBarry Smith MPI_Comm ncomm; 473*5c6c1daeSBarry Smith 474*5c6c1daeSBarry Smith PetscFunctionBegin; 475*5c6c1daeSBarry Smith ierr = PetscCommDuplicate(comm,&ncomm,PETSC_NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 476*5c6c1daeSBarry Smith if (Petsc_Viewer_Socket_keyval == MPI_KEYVAL_INVALID) { 477*5c6c1daeSBarry Smith ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Socket_keyval,0); 478*5c6c1daeSBarry Smith if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 479*5c6c1daeSBarry Smith } 480*5c6c1daeSBarry Smith ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Socket_keyval,(void **)&viewer,(int*)&flg); 481*5c6c1daeSBarry Smith if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 482*5c6c1daeSBarry Smith if (!flg) { /* PetscViewer not yet created */ 483*5c6c1daeSBarry Smith ierr = PetscViewerSocketOpen(ncomm,0,0,&viewer); 484*5c6c1daeSBarry Smith if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 485*5c6c1daeSBarry Smith ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 486*5c6c1daeSBarry Smith if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 487*5c6c1daeSBarry Smith ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Socket_keyval,(void*)viewer); 488*5c6c1daeSBarry Smith if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 489*5c6c1daeSBarry Smith } 490*5c6c1daeSBarry Smith ierr = PetscCommDestroy(&ncomm); 491*5c6c1daeSBarry Smith if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,__SDIR__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 492*5c6c1daeSBarry Smith PetscFunctionReturn(viewer); 493*5c6c1daeSBarry Smith } 494*5c6c1daeSBarry Smith 495*5c6c1daeSBarry Smith #if defined(PETSC_USE_SERVER) 496*5c6c1daeSBarry Smith 497*5c6c1daeSBarry Smith #include <pthread.h> 498*5c6c1daeSBarry Smith #include <time.h> 499*5c6c1daeSBarry Smith #define PROTOCOL "HTTP/1.1" 500*5c6c1daeSBarry Smith #define RFC1123FMT "%a, %d %b %Y %H:%M:%S GMT" 501*5c6c1daeSBarry Smith 502*5c6c1daeSBarry Smith #undef __FUNCT__ 503*5c6c1daeSBarry Smith #define __FUNCT__ "PetscWebSendHeader" 504*5c6c1daeSBarry Smith PetscErrorCode PetscWebSendHeader(FILE *f, int status, const char *title, const char *extra, const char *mime, int length) 505*5c6c1daeSBarry Smith { 506*5c6c1daeSBarry Smith time_t now; 507*5c6c1daeSBarry Smith char timebuf[128]; 508*5c6c1daeSBarry Smith 509*5c6c1daeSBarry Smith PetscFunctionBegin; 510*5c6c1daeSBarry Smith fprintf(f, "%s %d %s\r\n", PROTOCOL, status, title); 511*5c6c1daeSBarry Smith fprintf(f, "Server: %s\r\n", "petscserver/1.0"); 512*5c6c1daeSBarry Smith now = time(NULL); 513*5c6c1daeSBarry Smith strftime(timebuf, sizeof(timebuf), RFC1123FMT, gmtime(&now)); 514*5c6c1daeSBarry Smith fprintf(f, "Date: %s\r\n", timebuf); 515*5c6c1daeSBarry Smith if (extra) fprintf(f, "%s\r\n", extra); 516*5c6c1daeSBarry Smith if (mime) fprintf(f, "Content-Type: %s\r\n", mime); 517*5c6c1daeSBarry Smith if (length >= 0) fprintf(f, "Content-Length: %d\r\n", length); 518*5c6c1daeSBarry Smith fprintf(f, "Connection: close\r\n"); 519*5c6c1daeSBarry Smith fprintf(f, "\r\n"); 520*5c6c1daeSBarry Smith PetscFunctionReturn(0); 521*5c6c1daeSBarry Smith } 522*5c6c1daeSBarry Smith 523*5c6c1daeSBarry Smith #undef __FUNCT__ 524*5c6c1daeSBarry Smith #define __FUNCT__ "PetscWebSendFooter" 525*5c6c1daeSBarry Smith PetscErrorCode PetscWebSendFooter(FILE *fd) 526*5c6c1daeSBarry Smith { 527*5c6c1daeSBarry Smith PetscFunctionBegin; 528*5c6c1daeSBarry Smith fprintf(fd, "</BODY></HTML>\r\n"); 529*5c6c1daeSBarry Smith PetscFunctionReturn(0); 530*5c6c1daeSBarry Smith } 531*5c6c1daeSBarry Smith 532*5c6c1daeSBarry Smith #undef __FUNCT__ 533*5c6c1daeSBarry Smith #define __FUNCT__ "PetscWebSendError" 534*5c6c1daeSBarry Smith PetscErrorCode PetscWebSendError(FILE *f, int status, const char *title, const char *extra, const char *text) 535*5c6c1daeSBarry Smith { 536*5c6c1daeSBarry Smith PetscErrorCode ierr; 537*5c6c1daeSBarry Smith 538*5c6c1daeSBarry Smith PetscFunctionBegin; 539*5c6c1daeSBarry Smith ierr = PetscWebSendHeader(f, status, title, extra, "text/html", -1);CHKERRQ(ierr); 540*5c6c1daeSBarry Smith fprintf(f, "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>\r\n", status, title); 541*5c6c1daeSBarry Smith fprintf(f, "<BODY><H4>%d %s</H4>\r\n", status, title); 542*5c6c1daeSBarry Smith fprintf(f, "%s\r\n", text); 543*5c6c1daeSBarry Smith ierr = PetscWebSendFooter(f);CHKERRQ(ierr); 544*5c6c1daeSBarry Smith PetscFunctionReturn(0); 545*5c6c1daeSBarry Smith } 546*5c6c1daeSBarry Smith 547*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_AMS) 548*5c6c1daeSBarry Smith #undef __FUNCT__ 549*5c6c1daeSBarry Smith #define __FUNCT__ "PetscAMSDisplayList" 550*5c6c1daeSBarry Smith PetscErrorCode PetscAMSDisplayList(FILE *fd) 551*5c6c1daeSBarry Smith { 552*5c6c1daeSBarry Smith PetscErrorCode ierr; 553*5c6c1daeSBarry Smith char host[256],**comm_list,**mem_list,**fld_list; 554*5c6c1daeSBarry Smith AMS_Comm ams; 555*5c6c1daeSBarry Smith PetscInt i = 0,j; 556*5c6c1daeSBarry Smith AMS_Memory_type mtype; 557*5c6c1daeSBarry Smith AMS_Data_type dtype; 558*5c6c1daeSBarry Smith AMS_Shared_type stype; 559*5c6c1daeSBarry Smith AMS_Reduction_type rtype; 560*5c6c1daeSBarry Smith AMS_Memory memory; 561*5c6c1daeSBarry Smith int len; 562*5c6c1daeSBarry Smith void *addr; 563*5c6c1daeSBarry Smith 564*5c6c1daeSBarry Smith ierr = PetscGetHostName(host,256);CHKERRQ(ierr); 565*5c6c1daeSBarry Smith ierr = AMS_Connect(host, -1, &comm_list);CHKERRQ(ierr); 566*5c6c1daeSBarry Smith ierr = PetscWebSendHeader(fd, 200, "OK", NULL, "text/html", -1);CHKERRQ(ierr); 567*5c6c1daeSBarry Smith if (!comm_list || !comm_list[0]) { 568*5c6c1daeSBarry Smith fprintf(fd, "AMS Communicator not running</p>\r\n"); 569*5c6c1daeSBarry Smith } else { 570*5c6c1daeSBarry Smith ierr = AMS_Comm_attach(comm_list[0],&ams);CHKERRQ(ierr); 571*5c6c1daeSBarry Smith ierr = AMS_Comm_get_memory_list(ams,&mem_list);CHKERRQ(ierr); 572*5c6c1daeSBarry Smith if (!mem_list[0]) { 573*5c6c1daeSBarry Smith fprintf(fd, "AMS Communicator %s has no published memories</p>\r\n",comm_list[0]); 574*5c6c1daeSBarry Smith } else { 575*5c6c1daeSBarry Smith fprintf(fd, "<HTML><HEAD><TITLE>Petsc Application Server</TITLE></HEAD>\r\n<BODY>"); 576*5c6c1daeSBarry Smith fprintf(fd,"<ul>\r\n"); 577*5c6c1daeSBarry Smith while (mem_list[i]) { 578*5c6c1daeSBarry Smith fprintf(fd,"<li> %s</li>\r\n",mem_list[i]); 579*5c6c1daeSBarry Smith ierr = AMS_Memory_attach(ams,mem_list[i],&memory,NULL);CHKERRQ(ierr); 580*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_list(memory, &fld_list);CHKERRQ(ierr); 581*5c6c1daeSBarry Smith j = 0; 582*5c6c1daeSBarry Smith fprintf(fd,"<ul>\r\n"); 583*5c6c1daeSBarry Smith while (fld_list[j]) { 584*5c6c1daeSBarry Smith fprintf(fd,"<li> %s",fld_list[j]); 585*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_info(memory, fld_list[j], &addr, &len, &dtype, &mtype, &stype, &rtype);CHKERRQ(ierr); 586*5c6c1daeSBarry Smith if (len == 1) { 587*5c6c1daeSBarry Smith if (dtype == AMS_INT) fprintf(fd," %d",*(int*)addr); 588*5c6c1daeSBarry Smith else if (dtype == AMS_STRING) fprintf(fd," %s",*(char**)addr); 589*5c6c1daeSBarry Smith } 590*5c6c1daeSBarry Smith fprintf(fd,"</li>\r\n"); 591*5c6c1daeSBarry Smith j++; 592*5c6c1daeSBarry Smith } 593*5c6c1daeSBarry Smith fprintf(fd,"</ul>\r\n"); 594*5c6c1daeSBarry Smith i++; 595*5c6c1daeSBarry Smith } 596*5c6c1daeSBarry Smith fprintf(fd,"</ul>\r\n"); 597*5c6c1daeSBarry Smith } 598*5c6c1daeSBarry Smith } 599*5c6c1daeSBarry Smith ierr = PetscWebSendFooter(fd);CHKERRQ(ierr); 600*5c6c1daeSBarry Smith ierr = AMS_Disconnect();CHKERRQ(ierr); 601*5c6c1daeSBarry Smith PetscFunctionReturn(0); 602*5c6c1daeSBarry Smith } 603*5c6c1daeSBarry Smith 604*5c6c1daeSBarry Smith #undef __FUNCT__ 605*5c6c1daeSBarry Smith #define __FUNCT__ "PetscAMSDisplayTree" 606*5c6c1daeSBarry Smith PetscErrorCode PetscAMSDisplayTree(FILE *fd) 607*5c6c1daeSBarry Smith { 608*5c6c1daeSBarry Smith PetscErrorCode ierr; 609*5c6c1daeSBarry Smith char host[256],**comm_list,**mem_list,**fld_list; 610*5c6c1daeSBarry Smith AMS_Comm ams; 611*5c6c1daeSBarry Smith PetscInt i = 0,j; 612*5c6c1daeSBarry Smith AMS_Memory_type mtype; 613*5c6c1daeSBarry Smith AMS_Data_type dtype; 614*5c6c1daeSBarry Smith AMS_Shared_type stype; 615*5c6c1daeSBarry Smith AMS_Reduction_type rtype; 616*5c6c1daeSBarry Smith AMS_Memory memory; 617*5c6c1daeSBarry Smith int len; 618*5c6c1daeSBarry Smith void *addr2,*addr3,*addr,*addr4; 619*5c6c1daeSBarry Smith 620*5c6c1daeSBarry Smith ierr = PetscGetHostName(host,256);CHKERRQ(ierr); 621*5c6c1daeSBarry Smith ierr = AMS_Connect(host, -1, &comm_list);CHKERRQ(ierr); 622*5c6c1daeSBarry Smith ierr = PetscWebSendHeader(fd, 200, "OK", NULL, "text/html", -1);CHKERRQ(ierr); 623*5c6c1daeSBarry Smith if (!comm_list || !comm_list[0]) { 624*5c6c1daeSBarry Smith fprintf(fd, "AMS Communicator not running</p>\r\n"); 625*5c6c1daeSBarry Smith } else { 626*5c6c1daeSBarry Smith ierr = AMS_Comm_attach(comm_list[0],&ams);CHKERRQ(ierr); 627*5c6c1daeSBarry Smith ierr = AMS_Comm_get_memory_list(ams,&mem_list);CHKERRQ(ierr); 628*5c6c1daeSBarry Smith if (!mem_list[0]) { 629*5c6c1daeSBarry Smith fprintf(fd, "AMS Communicator %s has no published memories</p>\r\n",comm_list[0]); 630*5c6c1daeSBarry Smith } else { 631*5c6c1daeSBarry Smith PetscInt Nlevels,*Level,*Levelcnt,*Idbylevel,*Column,*parentid,*Id,maxId = 0,maxCol = 0,*parentId,id,cnt,Nlevelcnt = 0; 632*5c6c1daeSBarry Smith PetscBool *mask; 633*5c6c1daeSBarry Smith char **classes,*clas,**subclasses,*sclas; 634*5c6c1daeSBarry Smith 635*5c6c1daeSBarry Smith /* get maximum number of objects */ 636*5c6c1daeSBarry Smith while (mem_list[i]) { 637*5c6c1daeSBarry Smith ierr = AMS_Memory_attach(ams,mem_list[i],&memory,NULL);CHKERRQ(ierr); 638*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_list(memory, &fld_list);CHKERRQ(ierr); 639*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_info(memory, "Id", &addr2, &len, &dtype, &mtype, &stype, &rtype);CHKERRQ(ierr); 640*5c6c1daeSBarry Smith Id = (int*) addr2; 641*5c6c1daeSBarry Smith maxId = PetscMax(maxId,*Id); 642*5c6c1daeSBarry Smith i++; 643*5c6c1daeSBarry Smith } 644*5c6c1daeSBarry Smith maxId++; 645*5c6c1daeSBarry Smith 646*5c6c1daeSBarry Smith /* Gets everyone's parent ID and which nodes are masked */ 647*5c6c1daeSBarry Smith ierr = PetscMalloc4(maxId,PetscInt,&parentid,maxId,PetscBool ,&mask,maxId,char**,&classes,maxId,char**,&subclasses);CHKERRQ(ierr); 648*5c6c1daeSBarry Smith ierr = PetscMemzero(classes,maxId*sizeof(char*));CHKERRQ(ierr); 649*5c6c1daeSBarry Smith ierr = PetscMemzero(subclasses,maxId*sizeof(char*));CHKERRQ(ierr); 650*5c6c1daeSBarry Smith for (i=0; i<maxId; i++) mask[i] = PETSC_TRUE; 651*5c6c1daeSBarry Smith i = 0; 652*5c6c1daeSBarry Smith while (mem_list[i]) { 653*5c6c1daeSBarry Smith ierr = AMS_Memory_attach(ams,mem_list[i],&memory,NULL);CHKERRQ(ierr); 654*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_list(memory, &fld_list);CHKERRQ(ierr); 655*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_info(memory, "Id", &addr2, &len, &dtype, &mtype, &stype, &rtype);CHKERRQ(ierr); 656*5c6c1daeSBarry Smith Id = (int*) addr2; 657*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_info(memory, "ParentId", &addr3, &len, &dtype, &mtype, &stype, &rtype);CHKERRQ(ierr); 658*5c6c1daeSBarry Smith parentId = (int*) addr3; 659*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_info(memory, "Class", &addr, &len, &dtype, &mtype, &stype, &rtype);CHKERRQ(ierr); 660*5c6c1daeSBarry Smith clas = *(char**)addr; 661*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_info(memory, "Type", &addr4, &len, &dtype, &mtype, &stype, &rtype);CHKERRQ(ierr); 662*5c6c1daeSBarry Smith sclas = *(char**)addr4; 663*5c6c1daeSBarry Smith parentid[*Id] = *parentId; 664*5c6c1daeSBarry Smith mask[*Id] = PETSC_FALSE; 665*5c6c1daeSBarry Smith ierr = PetscStrallocpy(clas,classes+*Id);CHKERRQ(ierr); 666*5c6c1daeSBarry Smith ierr = PetscStrallocpy(sclas,subclasses+*Id);CHKERRQ(ierr); 667*5c6c1daeSBarry Smith i++; 668*5c6c1daeSBarry Smith } 669*5c6c1daeSBarry Smith 670*5c6c1daeSBarry Smith /* if the parent is masked then relabel the parent as 0 since the true parent was deleted */ 671*5c6c1daeSBarry Smith for (i=0; i<maxId; i++) { 672*5c6c1daeSBarry Smith if (!mask[i] && parentid[i] > 0 && mask[parentid[i]]) parentid[i] = 0; 673*5c6c1daeSBarry Smith } 674*5c6c1daeSBarry Smith 675*5c6c1daeSBarry Smith ierr = PetscProcessTree(maxId,mask,parentid,&Nlevels,&Level,&Levelcnt,&Idbylevel,&Column);CHKERRQ(ierr); 676*5c6c1daeSBarry Smith 677*5c6c1daeSBarry Smith for (i=0; i<Nlevels; i++) { 678*5c6c1daeSBarry Smith maxCol = PetscMax(maxCol,Levelcnt[i]); 679*5c6c1daeSBarry Smith } 680*5c6c1daeSBarry Smith for (i=0; i<Nlevels; i++) { 681*5c6c1daeSBarry Smith Nlevelcnt = PetscMax(Nlevelcnt,Levelcnt[i]); 682*5c6c1daeSBarry Smith } 683*5c6c1daeSBarry Smith 684*5c6c1daeSBarry Smith /* print all the top-level objects */ 685*5c6c1daeSBarry Smith fprintf(fd, "<HTML><HEAD><TITLE>Petsc Application Server</TITLE>\r\n"); 686*5c6c1daeSBarry Smith fprintf(fd, "<canvas width=800 height=600 id=\"tree\"></canvas>\r\n"); 687*5c6c1daeSBarry Smith fprintf(fd, "<script type=\"text/javascript\">\r\n"); 688*5c6c1daeSBarry Smith fprintf(fd, " function draw(){\r\n"); 689*5c6c1daeSBarry Smith fprintf(fd, " var example = document.getElementById('tree');\r\n"); 690*5c6c1daeSBarry Smith fprintf(fd, " var context = example.getContext('2d');\r\n"); 691*5c6c1daeSBarry Smith /* adjust font size based on how big a tree is printed */ 692*5c6c1daeSBarry Smith if (Nlevels > 5 || Nlevelcnt > 10) { 693*5c6c1daeSBarry Smith fprintf(fd, " context.font = \"normal 12px sans-serif\";\r\n"); 694*5c6c1daeSBarry Smith } else { 695*5c6c1daeSBarry Smith fprintf(fd, " context.font = \"normal 24px sans-serif\";\r\n"); 696*5c6c1daeSBarry Smith } 697*5c6c1daeSBarry Smith fprintf(fd, " context.fillStyle = \"rgb(255,0,0)\";\r\n"); 698*5c6c1daeSBarry Smith fprintf(fd, " context.textBaseline = \"top\";\r\n"); 699*5c6c1daeSBarry Smith fprintf(fd, " var xspacep = 0;\r\n"); 700*5c6c1daeSBarry Smith fprintf(fd, " var yspace = example.height/%d;\r\n",(Nlevels+1)); 701*5c6c1daeSBarry Smith /* estimate the height of a string as twice the width of a character */ 702*5c6c1daeSBarry Smith fprintf(fd, " var wheight = context.measureText(\"K\");\r\n"); 703*5c6c1daeSBarry Smith fprintf(fd, " var height = 1.6*wheight.width;\r\n"); 704*5c6c1daeSBarry Smith 705*5c6c1daeSBarry Smith cnt = 0; 706*5c6c1daeSBarry Smith for (i=0; i<Nlevels; i++) { 707*5c6c1daeSBarry Smith fprintf(fd, " var xspace = example.width/%d;\r\n",Levelcnt[i]+1); 708*5c6c1daeSBarry Smith for (j=0; j<Levelcnt[i]; j++) { 709*5c6c1daeSBarry Smith id = Idbylevel[cnt++]; 710*5c6c1daeSBarry Smith clas = classes[id]; 711*5c6c1daeSBarry Smith sclas = subclasses[id]; 712*5c6c1daeSBarry Smith fprintf(fd, " var width = context.measureText(\"%s\");\r\n",clas); 713*5c6c1daeSBarry Smith fprintf(fd, " var swidth = context.measureText(\"%s\");\r\n",sclas); 714*5c6c1daeSBarry Smith fprintf(fd, " context.fillStyle = \"rgb(255,0,0)\";\r\n"); 715*5c6c1daeSBarry Smith fprintf(fd, " context.fillRect((%d)*xspace-width.width/2, %d*yspace-height/2, width.width, height);\r\n",j+1,i+1); 716*5c6c1daeSBarry Smith fprintf(fd, " context.fillRect((%d)*xspace-swidth.width/2, %d*yspace+height/2, swidth.width, height);\r\n",j+1,i+1); 717*5c6c1daeSBarry Smith fprintf(fd, " context.fillStyle = \"rgb(0,0,0)\";\r\n"); 718*5c6c1daeSBarry Smith fprintf(fd, " context.fillText(\"%s\",(%d)*xspace-width.width/2, %d*yspace-height/2);\r\n",clas,j+1,i+1); 719*5c6c1daeSBarry Smith fprintf(fd, " context.fillText(\"%s\",(%d)*xspace-swidth.width/2, %d*yspace+height/2);\r\n",sclas,j+1,i+1); 720*5c6c1daeSBarry Smith if (parentid[id]) { 721*5c6c1daeSBarry Smith fprintf(fd, " context.moveTo(%d*xspace,%d*yspace-height/2);\r\n",j+1,i+1); 722*5c6c1daeSBarry Smith fprintf(fd, " context.lineTo(%d*xspacep,%d*yspace+3*height/2);\r\n",Column[parentid[id]]+1,i); 723*5c6c1daeSBarry Smith fprintf(fd, " context.stroke();\r\n"); 724*5c6c1daeSBarry Smith } 725*5c6c1daeSBarry Smith } 726*5c6c1daeSBarry Smith fprintf(fd, " xspacep = xspace;\r\n"); 727*5c6c1daeSBarry Smith } 728*5c6c1daeSBarry Smith ierr = PetscFree(Level);CHKERRQ(ierr); 729*5c6c1daeSBarry Smith ierr = PetscFree(Levelcnt);CHKERRQ(ierr); 730*5c6c1daeSBarry Smith ierr = PetscFree(Idbylevel);CHKERRQ(ierr); 731*5c6c1daeSBarry Smith ierr = PetscFree(Column);CHKERRQ(ierr); 732*5c6c1daeSBarry Smith for (i=0; i<maxId; i++) { 733*5c6c1daeSBarry Smith ierr = PetscFree(classes[i]);CHKERRQ(ierr); 734*5c6c1daeSBarry Smith ierr = PetscFree(subclasses[i]);CHKERRQ(ierr); 735*5c6c1daeSBarry Smith } 736*5c6c1daeSBarry Smith ierr = PetscFree4(mask,parentid,classes,subclasses);CHKERRQ(ierr); 737*5c6c1daeSBarry Smith 738*5c6c1daeSBarry Smith ierr = AMS_Disconnect();CHKERRQ(ierr); 739*5c6c1daeSBarry Smith fprintf(fd, "}\r\n"); 740*5c6c1daeSBarry Smith fprintf(fd, "</script>\r\n"); 741*5c6c1daeSBarry Smith fprintf(fd, "<body onload=\"draw();\">\r\n"); 742*5c6c1daeSBarry Smith fprintf(fd, "</body></html>\r\n"); 743*5c6c1daeSBarry Smith } 744*5c6c1daeSBarry Smith } 745*5c6c1daeSBarry Smith ierr = PetscWebSendFooter(fd);CHKERRQ(ierr); 746*5c6c1daeSBarry Smith 747*5c6c1daeSBarry Smith PetscFunctionReturn(0); 748*5c6c1daeSBarry Smith } 749*5c6c1daeSBarry Smith #endif 750*5c6c1daeSBarry Smith 751*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_YAML) 752*5c6c1daeSBarry Smith 753*5c6c1daeSBarry Smith EXTERN_C_BEGIN 754*5c6c1daeSBarry Smith /* 755*5c6c1daeSBarry Smith Toy function that returns all the arguments it is passed 756*5c6c1daeSBarry Smith */ 757*5c6c1daeSBarry Smith #undef __FUNCT__ 758*5c6c1daeSBarry Smith #define __FUNCT__ "YAML_echo" 759*5c6c1daeSBarry Smith PetscErrorCode YAML_echo(PetscInt argc,char **args,PetscInt *argco,char ***argso) 760*5c6c1daeSBarry Smith { 761*5c6c1daeSBarry Smith PetscErrorCode ierr; 762*5c6c1daeSBarry Smith PetscInt i; 763*5c6c1daeSBarry Smith 764*5c6c1daeSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF,"Number of arguments to function %d\n",argc);CHKERRQ(ierr); 765*5c6c1daeSBarry Smith for (i=0; i<argc; i++) { 766*5c6c1daeSBarry Smith ierr = PetscPrintf(PETSC_COMM_SELF," %s\n",args[i]);CHKERRQ(ierr); 767*5c6c1daeSBarry Smith } 768*5c6c1daeSBarry Smith *argco = argc; 769*5c6c1daeSBarry Smith ierr = PetscMalloc(argc*sizeof(char*),argso);CHKERRQ(ierr); 770*5c6c1daeSBarry Smith for (i=0; i<argc; i++) { 771*5c6c1daeSBarry Smith ierr = PetscStrallocpy(args[i],&(*argso)[i]);CHKERRQ(ierr); 772*5c6c1daeSBarry Smith } 773*5c6c1daeSBarry Smith PetscFunctionReturn(0); 774*5c6c1daeSBarry Smith } 775*5c6c1daeSBarry Smith EXTERN_C_END 776*5c6c1daeSBarry Smith 777*5c6c1daeSBarry Smith EXTERN_C_BEGIN 778*5c6c1daeSBarry Smith #undef __FUNCT__ 779*5c6c1daeSBarry Smith #define __FUNCT__ "YAML_AMS_Connect" 780*5c6c1daeSBarry Smith /* 781*5c6c1daeSBarry Smith Connects to the local AMS and gets only the first communication name 782*5c6c1daeSBarry Smith 783*5c6c1daeSBarry Smith Input Parameters: 784*5c6c1daeSBarry Smith . none 785*5c6c1daeSBarry Smith 786*5c6c1daeSBarry Smith Output Parameter: 787*5c6c1daeSBarry Smith . oarg1 - the string name of the first communicator 788*5c6c1daeSBarry Smith 789*5c6c1daeSBarry Smith */ 790*5c6c1daeSBarry Smith PetscErrorCode YAML_AMS_Connect(PetscInt argc,char **args,PetscInt *argco,char ***argso) 791*5c6c1daeSBarry Smith { 792*5c6c1daeSBarry Smith PetscErrorCode ierr; 793*5c6c1daeSBarry Smith char **list = 0; 794*5c6c1daeSBarry Smith 795*5c6c1daeSBarry Smith PetscFunctionBegin; 796*5c6c1daeSBarry Smith ierr = AMS_Connect(0,-1,&list); 797*5c6c1daeSBarry Smith if (ierr) {ierr = PetscInfo1(PETSC_NULL,"AMS_Connect() error %d\n",ierr);CHKERRQ(ierr);} 798*5c6c1daeSBarry Smith else if (!list) {ierr = PetscInfo(PETSC_NULL,"AMS_Connect() list empty, not running AMS server\n");CHKERRQ(ierr);} 799*5c6c1daeSBarry Smith *argco = 1; 800*5c6c1daeSBarry Smith ierr = PetscMalloc(sizeof(char*),argso);CHKERRQ(ierr); 801*5c6c1daeSBarry Smith if (list){ 802*5c6c1daeSBarry Smith ierr = PetscStrallocpy(list[0],&(*argso)[0]);CHKERRQ(ierr); 803*5c6c1daeSBarry Smith } else { 804*5c6c1daeSBarry Smith ierr = PetscStrallocpy("No AMS publisher running",&(*argso)[0]);CHKERRQ(ierr); 805*5c6c1daeSBarry Smith } 806*5c6c1daeSBarry Smith PetscFunctionReturn(0); 807*5c6c1daeSBarry Smith } 808*5c6c1daeSBarry Smith EXTERN_C_END 809*5c6c1daeSBarry Smith 810*5c6c1daeSBarry Smith EXTERN_C_BEGIN 811*5c6c1daeSBarry Smith #undef __FUNCT__ 812*5c6c1daeSBarry Smith #define __FUNCT__ "YAML_AMS_Comm_attach" 813*5c6c1daeSBarry Smith /* 814*5c6c1daeSBarry Smith Attaches to an AMS communicator 815*5c6c1daeSBarry Smith 816*5c6c1daeSBarry Smith Input Parameter: 817*5c6c1daeSBarry Smith . arg1 - string name of the communicator 818*5c6c1daeSBarry Smith 819*5c6c1daeSBarry Smith Output Parameter: 820*5c6c1daeSBarry Smith . oarg1 - the integer name of the communicator 821*5c6c1daeSBarry Smith 822*5c6c1daeSBarry Smith */ 823*5c6c1daeSBarry Smith PetscErrorCode YAML_AMS_Comm_attach(PetscInt argc,char **args,PetscInt *argco,char ***argso) 824*5c6c1daeSBarry Smith { 825*5c6c1daeSBarry Smith PetscErrorCode ierr; 826*5c6c1daeSBarry Smith AMS_Comm comm = -1; 827*5c6c1daeSBarry Smith 828*5c6c1daeSBarry Smith PetscFunctionBegin; 829*5c6c1daeSBarry Smith ierr = AMS_Comm_attach(args[0],&comm); 830*5c6c1daeSBarry Smith if (ierr) {ierr = PetscInfo1(PETSC_NULL,"AMS_Comm_attach() error %d\n",ierr);CHKERRQ(ierr);} 831*5c6c1daeSBarry Smith *argco = 1; 832*5c6c1daeSBarry Smith ierr = PetscMalloc(sizeof(char*),argso);CHKERRQ(ierr); 833*5c6c1daeSBarry Smith ierr = PetscMalloc(3*sizeof(char*),&argso[0][0]);CHKERRQ(ierr); 834*5c6c1daeSBarry Smith sprintf(argso[0][0],"%d",(int)comm); 835*5c6c1daeSBarry Smith PetscFunctionReturn(0); 836*5c6c1daeSBarry Smith } 837*5c6c1daeSBarry Smith EXTERN_C_END 838*5c6c1daeSBarry Smith 839*5c6c1daeSBarry Smith EXTERN_C_BEGIN 840*5c6c1daeSBarry Smith #undef __FUNCT__ 841*5c6c1daeSBarry Smith #define __FUNCT__ "YAML_AMS_Comm_get_memory_list" 842*5c6c1daeSBarry Smith /* 843*5c6c1daeSBarry Smith Gets the list of memories on an AMS Comm 844*5c6c1daeSBarry Smith 845*5c6c1daeSBarry Smith Input Parameter: 846*5c6c1daeSBarry Smith . arg1 - integer name of the communicator 847*5c6c1daeSBarry Smith 848*5c6c1daeSBarry Smith Output Parameter: 849*5c6c1daeSBarry Smith . oarg1 - the list of names 850*5c6c1daeSBarry Smith 851*5c6c1daeSBarry Smith */ 852*5c6c1daeSBarry Smith PetscErrorCode YAML_AMS_Comm_get_memory_list(PetscInt argc,char **args,PetscInt *argco,char ***argso) 853*5c6c1daeSBarry Smith { 854*5c6c1daeSBarry Smith PetscErrorCode ierr; 855*5c6c1daeSBarry Smith char **mem_list; 856*5c6c1daeSBarry Smith AMS_Comm comm; 857*5c6c1daeSBarry Smith PetscInt i,iargco = 0; 858*5c6c1daeSBarry Smith 859*5c6c1daeSBarry Smith PetscFunctionBegin; 860*5c6c1daeSBarry Smith sscanf(args[0],"%d",&comm); 861*5c6c1daeSBarry Smith ierr = AMS_Comm_get_memory_list(comm,&mem_list); 862*5c6c1daeSBarry Smith if (ierr) { 863*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"AMS_Comm_get_memory_list() error %d\n",ierr);CHKERRQ(ierr); 864*5c6c1daeSBarry Smith } else { 865*5c6c1daeSBarry Smith while (mem_list[iargco++]) ; 866*5c6c1daeSBarry Smith iargco--; 867*5c6c1daeSBarry Smith 868*5c6c1daeSBarry Smith ierr = PetscMalloc((iargco)*sizeof(char*),argso);CHKERRQ(ierr); 869*5c6c1daeSBarry Smith for (i=0; i<iargco; i++) { 870*5c6c1daeSBarry Smith ierr = PetscStrallocpy(mem_list[i],(*argso)+i);CHKERRQ(ierr); 871*5c6c1daeSBarry Smith } 872*5c6c1daeSBarry Smith } 873*5c6c1daeSBarry Smith *argco = iargco; 874*5c6c1daeSBarry Smith PetscFunctionReturn(0); 875*5c6c1daeSBarry Smith } 876*5c6c1daeSBarry Smith EXTERN_C_END 877*5c6c1daeSBarry Smith 878*5c6c1daeSBarry Smith EXTERN_C_BEGIN 879*5c6c1daeSBarry Smith #undef __FUNCT__ 880*5c6c1daeSBarry Smith #define __FUNCT__ "YAML_AMS_Memory_attach" 881*5c6c1daeSBarry Smith /* 882*5c6c1daeSBarry Smith Attaches to an AMS memory in a communicator 883*5c6c1daeSBarry Smith 884*5c6c1daeSBarry Smith Input Parameter: 885*5c6c1daeSBarry Smith . arg1 - communicator 886*5c6c1daeSBarry Smith . arg2 - string name of the memory 887*5c6c1daeSBarry Smith 888*5c6c1daeSBarry Smith Output Parameter: 889*5c6c1daeSBarry Smith . oarg1 - the integer name of the memory 890*5c6c1daeSBarry Smith . oarg2 - the integer step of the memory 891*5c6c1daeSBarry Smith 892*5c6c1daeSBarry Smith */ 893*5c6c1daeSBarry Smith PetscErrorCode YAML_AMS_Memory_attach(PetscInt argc,char **args,PetscInt *argco,char ***argso) 894*5c6c1daeSBarry Smith { 895*5c6c1daeSBarry Smith PetscErrorCode ierr; 896*5c6c1daeSBarry Smith AMS_Comm comm; 897*5c6c1daeSBarry Smith AMS_Memory mem; 898*5c6c1daeSBarry Smith unsigned int step; 899*5c6c1daeSBarry Smith 900*5c6c1daeSBarry Smith PetscFunctionBegin; 901*5c6c1daeSBarry Smith sscanf(args[0],"%d",&comm); 902*5c6c1daeSBarry Smith ierr = AMS_Memory_attach(comm,args[1],&mem,&step); 903*5c6c1daeSBarry Smith if (ierr) {ierr = PetscInfo1(PETSC_NULL,"AMS_Memory_attach() error %d\n",ierr);CHKERRQ(ierr);} 904*5c6c1daeSBarry Smith *argco = 2; 905*5c6c1daeSBarry Smith ierr = PetscMalloc(2*sizeof(char*),argso);CHKERRQ(ierr); 906*5c6c1daeSBarry Smith ierr = PetscMalloc(3*sizeof(char*),&argso[0][0]);CHKERRQ(ierr); 907*5c6c1daeSBarry Smith sprintf(argso[0][0],"%d",(int)mem); 908*5c6c1daeSBarry Smith ierr = PetscMalloc(3*sizeof(char*),&argso[0][1]);CHKERRQ(ierr); 909*5c6c1daeSBarry Smith sprintf(argso[0][1],"%d",(int)step); 910*5c6c1daeSBarry Smith PetscFunctionReturn(0); 911*5c6c1daeSBarry Smith } 912*5c6c1daeSBarry Smith EXTERN_C_END 913*5c6c1daeSBarry Smith 914*5c6c1daeSBarry Smith EXTERN_C_BEGIN 915*5c6c1daeSBarry Smith #undef __FUNCT__ 916*5c6c1daeSBarry Smith #define __FUNCT__ "YAML_AMS_Memory_get_field_list" 917*5c6c1daeSBarry Smith /* 918*5c6c1daeSBarry Smith Gets the list of fields on an AMS Memory 919*5c6c1daeSBarry Smith 920*5c6c1daeSBarry Smith Input Parameter: 921*5c6c1daeSBarry Smith . arg1 - integer name of the memory 922*5c6c1daeSBarry Smith 923*5c6c1daeSBarry Smith Output Parameter: 924*5c6c1daeSBarry Smith . oarg1 - the list of names 925*5c6c1daeSBarry Smith 926*5c6c1daeSBarry Smith */ 927*5c6c1daeSBarry Smith PetscErrorCode YAML_AMS_Memory_get_field_list(PetscInt argc,char **args,PetscInt *argco,char ***argso) 928*5c6c1daeSBarry Smith { 929*5c6c1daeSBarry Smith PetscErrorCode ierr; 930*5c6c1daeSBarry Smith char **field_list; 931*5c6c1daeSBarry Smith AMS_Memory mem; 932*5c6c1daeSBarry Smith PetscInt i,iargco = 0; 933*5c6c1daeSBarry Smith 934*5c6c1daeSBarry Smith PetscFunctionBegin; 935*5c6c1daeSBarry Smith sscanf(args[0],"%d",&mem); 936*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_list(mem,&field_list); 937*5c6c1daeSBarry Smith if (ierr) { 938*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"AMS_Memory_get_field_list() error %d\n",ierr);CHKERRQ(ierr); 939*5c6c1daeSBarry Smith } else { 940*5c6c1daeSBarry Smith while (field_list[iargco++]) ; 941*5c6c1daeSBarry Smith iargco--; 942*5c6c1daeSBarry Smith 943*5c6c1daeSBarry Smith ierr = PetscMalloc((iargco)*sizeof(char*),argso);CHKERRQ(ierr); 944*5c6c1daeSBarry Smith for (i=0; i<iargco; i++) { 945*5c6c1daeSBarry Smith ierr = PetscStrallocpy(field_list[i],(*argso)+i);CHKERRQ(ierr); 946*5c6c1daeSBarry Smith } 947*5c6c1daeSBarry Smith } 948*5c6c1daeSBarry Smith *argco = iargco; 949*5c6c1daeSBarry Smith PetscFunctionReturn(0); 950*5c6c1daeSBarry Smith } 951*5c6c1daeSBarry Smith EXTERN_C_END 952*5c6c1daeSBarry Smith 953*5c6c1daeSBarry Smith const char *AMS_Data_types[] = {"AMS_DATA_UNDEF","AMS_BOOLEAN","AMS_INT","AMS_FLOAT","AMS_DOUBLE","AMS_STRING","AMS_Data_type","AMS_",0}; 954*5c6c1daeSBarry Smith const char *AMS_Memory_types[] = {"AMS_MEMORY_UNDEF","AMS_READ","AMS_WRITE","AMS_Memory_type","AMS_",0}; 955*5c6c1daeSBarry Smith const char *AMS_Shared_types[] = {"AMS_SHARED_UNDEF","AMS_COMMON","AMS_REDUCED","AMS_DISTRIBUTED","AMS_Shared_type","AMS_",0}; 956*5c6c1daeSBarry Smith const char *AMS_Reduction_types[] = {"AMS_REDUCTION_WHY_NOT_UNDEF?","AMS_SUM","AMS_MAX","AMS_MIN","AMS_REDUCTION_UNDEF","AMS_Reduction_type","AMS_",0}; 957*5c6c1daeSBarry Smith 958*5c6c1daeSBarry Smith EXTERN_C_BEGIN 959*5c6c1daeSBarry Smith #undef __FUNCT__ 960*5c6c1daeSBarry Smith #define __FUNCT__ "YAML_AMS_Memory_get_field_info" 961*5c6c1daeSBarry Smith /* 962*5c6c1daeSBarry Smith Gets information about a field 963*5c6c1daeSBarry Smith 964*5c6c1daeSBarry Smith Input Parameter: 965*5c6c1daeSBarry Smith . arg1 - memory 966*5c6c1daeSBarry Smith . arg2 - string name of the field 967*5c6c1daeSBarry Smith 968*5c6c1daeSBarry Smith Output Parameter: 969*5c6c1daeSBarry Smith 970*5c6c1daeSBarry Smith */ 971*5c6c1daeSBarry Smith PetscErrorCode YAML_AMS_Memory_get_field_info(PetscInt argc,char **args,PetscInt *argco,char ***argso) 972*5c6c1daeSBarry Smith { 973*5c6c1daeSBarry Smith PetscErrorCode ierr; 974*5c6c1daeSBarry Smith AMS_Memory mem; 975*5c6c1daeSBarry Smith void *addr; 976*5c6c1daeSBarry Smith int len; 977*5c6c1daeSBarry Smith AMS_Data_type dtype; 978*5c6c1daeSBarry Smith AMS_Memory_type mtype; 979*5c6c1daeSBarry Smith AMS_Shared_type stype; 980*5c6c1daeSBarry Smith AMS_Reduction_type rtype; 981*5c6c1daeSBarry Smith PetscInt i; 982*5c6c1daeSBarry Smith 983*5c6c1daeSBarry Smith PetscFunctionBegin; 984*5c6c1daeSBarry Smith sscanf(args[0],"%d",&mem); 985*5c6c1daeSBarry Smith ierr = AMS_Memory_get_field_info(mem,args[1],&addr,&len,&dtype,&mtype,&stype,&rtype); 986*5c6c1daeSBarry Smith if (ierr) {ierr = PetscInfo1(PETSC_NULL,"AMS_Memory_get_field_info() error %d\n",ierr);CHKERRQ(ierr);} 987*5c6c1daeSBarry Smith *argco = 4 + len; 988*5c6c1daeSBarry Smith ierr = PetscMalloc((*argco)*sizeof(char*),argso);CHKERRQ(ierr); 989*5c6c1daeSBarry Smith ierr = PetscStrallocpy(AMS_Data_types[dtype],&argso[0][0]);CHKERRQ(ierr); 990*5c6c1daeSBarry Smith ierr = PetscStrallocpy(AMS_Memory_types[mtype],&argso[0][1]);CHKERRQ(ierr); 991*5c6c1daeSBarry Smith ierr = PetscStrallocpy(AMS_Shared_types[stype],&argso[0][2]);CHKERRQ(ierr); 992*5c6c1daeSBarry Smith ierr = PetscStrallocpy(AMS_Reduction_types[rtype],&argso[0][3]);CHKERRQ(ierr); 993*5c6c1daeSBarry Smith for (i=0; i<len; i++) { 994*5c6c1daeSBarry Smith if (dtype == AMS_STRING) { 995*5c6c1daeSBarry Smith ierr = PetscStrallocpy(*(const char **)addr,&argso[0][4+i]);CHKERRQ(ierr); 996*5c6c1daeSBarry Smith } else if (dtype == AMS_DOUBLE) { 997*5c6c1daeSBarry Smith ierr = PetscMalloc(20*sizeof(char),&argso[0][4+i]);CHKERRQ(ierr); 998*5c6c1daeSBarry Smith sprintf(argso[0][4+i],"%18.16e",*(double*)addr); 999*5c6c1daeSBarry Smith } else if (dtype == AMS_INT) { 1000*5c6c1daeSBarry Smith ierr = PetscMalloc(10*sizeof(char),&argso[0][4+i]);CHKERRQ(ierr); 1001*5c6c1daeSBarry Smith sprintf(argso[0][4+i],"%d",*(int*)addr); 1002*5c6c1daeSBarry Smith } else if (dtype == AMS_BOOLEAN) { 1003*5c6c1daeSBarry Smith if (*(int*)addr) { 1004*5c6c1daeSBarry Smith ierr = PetscStrallocpy("true",&argso[0][4+i]);CHKERRQ(ierr); 1005*5c6c1daeSBarry Smith } else { 1006*5c6c1daeSBarry Smith ierr = PetscStrallocpy("false",&argso[0][4+i]);CHKERRQ(ierr); 1007*5c6c1daeSBarry Smith } 1008*5c6c1daeSBarry Smith } else { 1009*5c6c1daeSBarry Smith ierr = PetscStrallocpy("Not yet done",&argso[0][4+i]);CHKERRQ(ierr); 1010*5c6c1daeSBarry Smith } 1011*5c6c1daeSBarry Smith } 1012*5c6c1daeSBarry Smith PetscFunctionReturn(0); 1013*5c6c1daeSBarry Smith } 1014*5c6c1daeSBarry Smith EXTERN_C_END 1015*5c6c1daeSBarry Smith 1016*5c6c1daeSBarry Smith #include "yaml.h" 1017*5c6c1daeSBarry Smith #undef __FUNCT__ 1018*5c6c1daeSBarry Smith #define __FUNCT__ "PetscProcessYAMLRPC" 1019*5c6c1daeSBarry Smith PetscErrorCode PetscProcessYAMLRPC(const char* request,char **result) 1020*5c6c1daeSBarry Smith { 1021*5c6c1daeSBarry Smith yaml_parser_t parser; 1022*5c6c1daeSBarry Smith yaml_event_t event; 1023*5c6c1daeSBarry Smith int done = 0; 1024*5c6c1daeSBarry Smith int count = 0; 1025*5c6c1daeSBarry Smith size_t len; 1026*5c6c1daeSBarry Smith PetscErrorCode ierr; 1027*5c6c1daeSBarry Smith PetscBool method,params,id; 1028*5c6c1daeSBarry Smith char *methodname,*idname,**args,**argso = 0; 1029*5c6c1daeSBarry Smith PetscInt argc = 0,argco,i; 1030*5c6c1daeSBarry Smith PetscErrorCode (*fun)(PetscInt,char **,PetscInt*,char ***); 1031*5c6c1daeSBarry Smith 1032*5c6c1daeSBarry Smith PetscFunctionBegin; 1033*5c6c1daeSBarry Smith ierr = PetscMalloc(sizeof(char*),&args);CHKERRQ(ierr); 1034*5c6c1daeSBarry Smith yaml_parser_initialize(&parser); 1035*5c6c1daeSBarry Smith PetscStrlen(request,&len); 1036*5c6c1daeSBarry Smith yaml_parser_set_input_string(&parser, (unsigned char *)request, len); 1037*5c6c1daeSBarry Smith 1038*5c6c1daeSBarry Smith /* this is totally bogus; it only handles the simple JSON-RPC messages */ 1039*5c6c1daeSBarry Smith while (!done) { 1040*5c6c1daeSBarry Smith if (!yaml_parser_parse(&parser, &event)) { 1041*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Found error in yaml/json\n");CHKERRQ(ierr); 1042*5c6c1daeSBarry Smith break; 1043*5c6c1daeSBarry Smith } 1044*5c6c1daeSBarry Smith done = (event.type == YAML_STREAM_END_EVENT); 1045*5c6c1daeSBarry Smith switch (event.type) { 1046*5c6c1daeSBarry Smith case YAML_STREAM_START_EVENT: 1047*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Stream start\n");CHKERRQ(ierr); 1048*5c6c1daeSBarry Smith break; 1049*5c6c1daeSBarry Smith case YAML_STREAM_END_EVENT: 1050*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Stream end\n");CHKERRQ(ierr); 1051*5c6c1daeSBarry Smith break; 1052*5c6c1daeSBarry Smith case YAML_DOCUMENT_START_EVENT: 1053*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Document start\n");CHKERRQ(ierr); 1054*5c6c1daeSBarry Smith break; 1055*5c6c1daeSBarry Smith case YAML_DOCUMENT_END_EVENT: 1056*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Document end\n");CHKERRQ(ierr); 1057*5c6c1daeSBarry Smith break; 1058*5c6c1daeSBarry Smith case YAML_MAPPING_START_EVENT: 1059*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Mapping start event\n");CHKERRQ(ierr); 1060*5c6c1daeSBarry Smith break; 1061*5c6c1daeSBarry Smith case YAML_MAPPING_END_EVENT: 1062*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Mapping end event \n");CHKERRQ(ierr); 1063*5c6c1daeSBarry Smith break; 1064*5c6c1daeSBarry Smith case YAML_ALIAS_EVENT: 1065*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Alias event %s\n",event.data.alias.anchor);CHKERRQ(ierr); 1066*5c6c1daeSBarry Smith break; 1067*5c6c1daeSBarry Smith case YAML_SCALAR_EVENT: 1068*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Scalar event %s\n",event.data.scalar.value);CHKERRQ(ierr); 1069*5c6c1daeSBarry Smith ierr = PetscStrcmp((char*)event.data.scalar.value,"method",&method);CHKERRQ(ierr); 1070*5c6c1daeSBarry Smith ierr = PetscStrcmp((char*)event.data.scalar.value,"params",¶ms);CHKERRQ(ierr); 1071*5c6c1daeSBarry Smith ierr = PetscStrcmp((char*)event.data.scalar.value,"id",&id);CHKERRQ(ierr); 1072*5c6c1daeSBarry Smith if (method) { 1073*5c6c1daeSBarry Smith yaml_event_delete(&event); 1074*5c6c1daeSBarry Smith ierr = yaml_parser_parse(&parser, &event);CHKERRQ(!ierr); 1075*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Method %s\n",event.data.scalar.value);CHKERRQ(ierr); 1076*5c6c1daeSBarry Smith ierr = PetscStrallocpy((char*)event.data.scalar.value,&methodname);CHKERRQ(ierr); 1077*5c6c1daeSBarry Smith } else if (id) { 1078*5c6c1daeSBarry Smith yaml_event_delete(&event); 1079*5c6c1daeSBarry Smith ierr = yaml_parser_parse(&parser, &event);CHKERRQ(!ierr); 1080*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Id %s\n",event.data.scalar.value);CHKERRQ(ierr); 1081*5c6c1daeSBarry Smith ierr = PetscStrallocpy((char*)event.data.scalar.value,&idname);CHKERRQ(ierr); 1082*5c6c1daeSBarry Smith } else if (params) { 1083*5c6c1daeSBarry Smith yaml_event_delete(&event); 1084*5c6c1daeSBarry Smith ierr = yaml_parser_parse(&parser, &event);CHKERRQ(!ierr); 1085*5c6c1daeSBarry Smith yaml_event_delete(&event); 1086*5c6c1daeSBarry Smith ierr = yaml_parser_parse(&parser, &event);CHKERRQ(!ierr); 1087*5c6c1daeSBarry Smith while (event.type != YAML_SEQUENCE_END_EVENT) { 1088*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL," Parameter %s\n",event.data.scalar.value);CHKERRQ(ierr); 1089*5c6c1daeSBarry Smith ierr = PetscStrallocpy((char*)event.data.scalar.value,&args[argc++]);CHKERRQ(ierr); 1090*5c6c1daeSBarry Smith yaml_event_delete(&event); 1091*5c6c1daeSBarry Smith ierr = yaml_parser_parse(&parser, &event);CHKERRQ(!ierr); 1092*5c6c1daeSBarry Smith } 1093*5c6c1daeSBarry Smith } else { /* ignore all the other variables in the mapping */ 1094*5c6c1daeSBarry Smith yaml_event_delete(&event); 1095*5c6c1daeSBarry Smith ierr = yaml_parser_parse(&parser, &event);CHKERRQ(!ierr); 1096*5c6c1daeSBarry Smith } 1097*5c6c1daeSBarry Smith break; 1098*5c6c1daeSBarry Smith case YAML_SEQUENCE_START_EVENT: 1099*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Sequence start event \n");CHKERRQ(ierr); 1100*5c6c1daeSBarry Smith break; 1101*5c6c1daeSBarry Smith case YAML_SEQUENCE_END_EVENT: 1102*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Sequence end event \n");CHKERRQ(ierr); 1103*5c6c1daeSBarry Smith break; 1104*5c6c1daeSBarry Smith default: 1105*5c6c1daeSBarry Smith /* It couldn't really happen. */ 1106*5c6c1daeSBarry Smith break; 1107*5c6c1daeSBarry Smith } 1108*5c6c1daeSBarry Smith 1109*5c6c1daeSBarry Smith yaml_event_delete(&event); 1110*5c6c1daeSBarry Smith count ++; 1111*5c6c1daeSBarry Smith } 1112*5c6c1daeSBarry Smith yaml_parser_delete(&parser); 1113*5c6c1daeSBarry Smith 1114*5c6c1daeSBarry Smith ierr = PetscDLLibrarySym(PETSC_COMM_SELF,PETSC_NULL,PETSC_NULL,methodname,(void**)&fun);CHKERRQ(ierr); 1115*5c6c1daeSBarry Smith if (fun) { 1116*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Located function %s and running it\n",methodname);CHKERRQ(ierr); 1117*5c6c1daeSBarry Smith ierr = (*fun)(argc,args,&argco,&argso);CHKERRQ(ierr); 1118*5c6c1daeSBarry Smith } else { 1119*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Did not locate function %s skipping it\n",methodname);CHKERRQ(ierr); 1120*5c6c1daeSBarry Smith } 1121*5c6c1daeSBarry Smith 1122*5c6c1daeSBarry Smith for (i=0; i<argc; i++) { 1123*5c6c1daeSBarry Smith ierr = PetscFree(args[i]);CHKERRQ(ierr); 1124*5c6c1daeSBarry Smith } 1125*5c6c1daeSBarry Smith ierr = PetscFree(args);CHKERRQ(ierr); 1126*5c6c1daeSBarry Smith ierr = PetscFree(methodname);CHKERRQ(ierr); 1127*5c6c1daeSBarry Smith 1128*5c6c1daeSBarry Smith /* convert the result back to YAML; should use YAML encoder, does not handle zero return arguments */ 1129*5c6c1daeSBarry Smith ierr = PetscMalloc(1024,result);CHKERRQ(ierr); 1130*5c6c1daeSBarry Smith ierr = PetscStrcpy(*result,"{\"error\": null, \"id\": \"");CHKERRQ(ierr); 1131*5c6c1daeSBarry Smith ierr = PetscStrcat(*result,idname);CHKERRQ(ierr); 1132*5c6c1daeSBarry Smith ierr = PetscStrcat(*result,"\", \"result\" : ");CHKERRQ(ierr); 1133*5c6c1daeSBarry Smith if (argco > 1) {ierr = PetscStrcat(*result,"[");CHKERRQ(ierr);} 1134*5c6c1daeSBarry Smith for (i=0; i<argco; i++) { 1135*5c6c1daeSBarry Smith ierr = PetscStrcat(*result,"\"");CHKERRQ(ierr); 1136*5c6c1daeSBarry Smith ierr = PetscStrcat(*result,argso[i]);CHKERRQ(ierr); 1137*5c6c1daeSBarry Smith ierr = PetscStrcat(*result,"\"");CHKERRQ(ierr); 1138*5c6c1daeSBarry Smith if (i < argco-1) {ierr = PetscStrcat(*result,",");CHKERRQ(ierr);} 1139*5c6c1daeSBarry Smith } 1140*5c6c1daeSBarry Smith if (argco > 1) {ierr = PetscStrcat(*result,"]");CHKERRQ(ierr);} 1141*5c6c1daeSBarry Smith ierr = PetscStrcat(*result,"}");CHKERRQ(ierr); 1142*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"YAML result of function %s\n",*result);CHKERRQ(ierr); 1143*5c6c1daeSBarry Smith 1144*5c6c1daeSBarry Smith /* free work space */ 1145*5c6c1daeSBarry Smith ierr = PetscFree(idname);CHKERRQ(ierr); 1146*5c6c1daeSBarry Smith for (i=0; i<argco; i++) { 1147*5c6c1daeSBarry Smith ierr = PetscFree(argso[i]);CHKERRQ(ierr); 1148*5c6c1daeSBarry Smith } 1149*5c6c1daeSBarry Smith ierr = PetscFree(argso);CHKERRQ(ierr); 1150*5c6c1daeSBarry Smith PetscFunctionReturn(0); 1151*5c6c1daeSBarry Smith } 1152*5c6c1daeSBarry Smith #endif 1153*5c6c1daeSBarry Smith 1154*5c6c1daeSBarry Smith #undef __FUNCT__ 1155*5c6c1daeSBarry Smith #define __FUNCT__ "PetscWebServeRequest" 1156*5c6c1daeSBarry Smith /*@C 1157*5c6c1daeSBarry Smith PetscWebServeRequest - serves a single web request 1158*5c6c1daeSBarry Smith 1159*5c6c1daeSBarry Smith Not collective 1160*5c6c1daeSBarry Smith 1161*5c6c1daeSBarry Smith Input Parameters: 1162*5c6c1daeSBarry Smith . port - the port 1163*5c6c1daeSBarry Smith 1164*5c6c1daeSBarry Smith Level: developer 1165*5c6c1daeSBarry Smith 1166*5c6c1daeSBarry Smith .seealso: PetscWebServe() 1167*5c6c1daeSBarry Smith @*/ 1168*5c6c1daeSBarry Smith PetscErrorCode PetscWebServeRequest(int port) 1169*5c6c1daeSBarry Smith { 1170*5c6c1daeSBarry Smith PetscErrorCode ierr; 1171*5c6c1daeSBarry Smith FILE *fd,*fdo; 1172*5c6c1daeSBarry Smith char buf[4096],fullpath[PETSC_MAX_PATH_LEN],truefullpath[PETSC_MAX_PATH_LEN]; 1173*5c6c1daeSBarry Smith char *method, *path, *protocol,*result; 1174*5c6c1daeSBarry Smith const char* type; 1175*5c6c1daeSBarry Smith PetscBool flg; 1176*5c6c1daeSBarry Smith PetscToken tok; 1177*5c6c1daeSBarry Smith PetscInt cnt = 8; 1178*5c6c1daeSBarry Smith 1179*5c6c1daeSBarry Smith PetscFunctionBegin; 1180*5c6c1daeSBarry Smith fd = fdopen(port, "r+"); 1181*5c6c1daeSBarry Smith 1182*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Processing web request\n");CHKERRQ(ierr); 1183*5c6c1daeSBarry Smith if (!fgets(buf, sizeof(buf), fd)) { 1184*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Cannot read web request, giving up\n");CHKERRQ(ierr); 1185*5c6c1daeSBarry Smith goto theend; 1186*5c6c1daeSBarry Smith } 1187*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Processing web request %s",buf);CHKERRQ(ierr); 1188*5c6c1daeSBarry Smith 1189*5c6c1daeSBarry Smith ierr = PetscTokenCreate(buf,' ',&tok);CHKERRQ(ierr); 1190*5c6c1daeSBarry Smith ierr = PetscTokenFind(tok,&method);CHKERRQ(ierr); 1191*5c6c1daeSBarry Smith ierr = PetscTokenFind(tok,&path);CHKERRQ(ierr); 1192*5c6c1daeSBarry Smith ierr = PetscTokenFind(tok,&protocol);CHKERRQ(ierr); 1193*5c6c1daeSBarry Smith 1194*5c6c1daeSBarry Smith if (!method || !path || !protocol) { 1195*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Web request not well formatted, giving up\n");CHKERRQ(ierr); 1196*5c6c1daeSBarry Smith goto theend; 1197*5c6c1daeSBarry Smith } 1198*5c6c1daeSBarry Smith 1199*5c6c1daeSBarry Smith ierr = PetscStrcmp(method,"GET",&flg); 1200*5c6c1daeSBarry Smith if (!flg) { 1201*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_YAML) 1202*5c6c1daeSBarry Smith ierr = PetscStrcmp(method,"POST",&flg); 1203*5c6c1daeSBarry Smith /* 1204*5c6c1daeSBarry Smith Start to handle support for POSTs based on json-rpc 1205*5c6c1daeSBarry Smith */ 1206*5c6c1daeSBarry Smith if (flg) { 1207*5c6c1daeSBarry Smith int len; 1208*5c6c1daeSBarry Smith size_t elen; 1209*5c6c1daeSBarry Smith char *fnd; 1210*5c6c1daeSBarry Smith while (cnt--) { 1211*5c6c1daeSBarry Smith 1212*5c6c1daeSBarry Smith if (!fgets(buf, sizeof(buf), fd)) { 1213*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Cannot read POST data, giving up\n");CHKERRQ(ierr); 1214*5c6c1daeSBarry Smith goto theend; 1215*5c6c1daeSBarry Smith } 1216*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"POSTED data %s",buf);CHKERRQ(ierr); 1217*5c6c1daeSBarry Smith ierr = PetscStrstr(buf,"Content-Type:",&fnd);CHKERRQ(ierr); 1218*5c6c1daeSBarry Smith if (fnd) { 1219*5c6c1daeSBarry Smith ierr = PetscStrstr(buf,"application/json-rpc",&fnd);CHKERRQ(ierr); 1220*5c6c1daeSBarry Smith if (!fnd) { 1221*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"POST content is not json-rpc, skipping post\n");CHKERRQ(ierr); 1222*5c6c1daeSBarry Smith goto theend; 1223*5c6c1daeSBarry Smith } 1224*5c6c1daeSBarry Smith } 1225*5c6c1daeSBarry Smith } 1226*5c6c1daeSBarry Smith if (!fgets(buf, sizeof(buf), fd)) { 1227*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Cannot read POST length data, giving up\n");CHKERRQ(ierr); 1228*5c6c1daeSBarry Smith goto theend; 1229*5c6c1daeSBarry Smith } 1230*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"POSTED length data %s",buf);CHKERRQ(ierr); 1231*5c6c1daeSBarry Smith sscanf(buf,"Content-Length: %d\n",&len); 1232*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Length of POSTED data %d\n",len);CHKERRQ(ierr); 1233*5c6c1daeSBarry Smith if (!fgets(buf, sizeof(buf), fd)) { 1234*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Cannot read POST data, giving up\n");CHKERRQ(ierr); 1235*5c6c1daeSBarry Smith goto theend; 1236*5c6c1daeSBarry Smith } 1237*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"POSTED data %s",buf);CHKERRQ(ierr); 1238*5c6c1daeSBarry Smith if (!fgets(buf, sizeof(buf), fd)) { 1239*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Cannot read POST data, giving up\n");CHKERRQ(ierr); 1240*5c6c1daeSBarry Smith goto theend; 1241*5c6c1daeSBarry Smith } 1242*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"POSTED data %s",buf);CHKERRQ(ierr); 1243*5c6c1daeSBarry Smith if (!fgets(buf, len+1, fd)) { /* why is this len + 1? */ 1244*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Cannot read POST data, giving up\n");CHKERRQ(ierr); 1245*5c6c1daeSBarry Smith goto theend; 1246*5c6c1daeSBarry Smith } 1247*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"POSTED data %s\n",buf);CHKERRQ(ierr); 1248*5c6c1daeSBarry Smith fseek(fd, 0, SEEK_CUR); /* Force change of stream direction */ 1249*5c6c1daeSBarry Smith ierr = PetscProcessYAMLRPC(buf,&result);CHKERRQ(ierr); 1250*5c6c1daeSBarry Smith ierr = PetscStrlen(result,&elen);CHKERRQ(ierr); 1251*5c6c1daeSBarry Smith ierr = PetscWebSendHeader(fd, 200, "OK", NULL, "application/json-rpc",(int)elen);CHKERRQ(ierr); 1252*5c6c1daeSBarry Smith fprintf(fd, "%s",result); 1253*5c6c1daeSBarry Smith goto theend; 1254*5c6c1daeSBarry Smith } else { 1255*5c6c1daeSBarry Smith #endif 1256*5c6c1daeSBarry Smith ierr = PetscWebSendError(fd, 501, "Not supported", NULL, "Method is not supported.");CHKERRQ(ierr); 1257*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Web request not a GET or POST, giving up\n");CHKERRQ(ierr); 1258*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_YAML) 1259*5c6c1daeSBarry Smith } 1260*5c6c1daeSBarry Smith #endif 1261*5c6c1daeSBarry Smith } else { 1262*5c6c1daeSBarry Smith fseek(fd, 0, SEEK_CUR); /* Force change of stream direction */ 1263*5c6c1daeSBarry Smith 1264*5c6c1daeSBarry Smith ierr = PetscStrcmp(path,"/favicon.ico",&flg);CHKERRQ(ierr); 1265*5c6c1daeSBarry Smith if (flg) { 1266*5c6c1daeSBarry Smith /* should have cool PETSc icon */; 1267*5c6c1daeSBarry Smith goto theend; 1268*5c6c1daeSBarry Smith } 1269*5c6c1daeSBarry Smith ierr = PetscStrcmp(path,"/",&flg);CHKERRQ(ierr); 1270*5c6c1daeSBarry Smith if (flg) { 1271*5c6c1daeSBarry Smith char program[128]; 1272*5c6c1daeSBarry Smith PetscMPIInt size; 1273*5c6c1daeSBarry Smith PetscViewer viewer; 1274*5c6c1daeSBarry Smith 1275*5c6c1daeSBarry Smith ierr = MPI_Comm_size(PETSC_COMM_WORLD,&size);CHKERRQ(ierr); 1276*5c6c1daeSBarry Smith ierr = PetscGetProgramName(program,128);CHKERRQ(ierr); 1277*5c6c1daeSBarry Smith ierr = PetscWebSendHeader(fd, 200, "OK", NULL, "text/html", -1);CHKERRQ(ierr); 1278*5c6c1daeSBarry Smith fprintf(fd, "<HTML><HEAD><TITLE>Petsc Application Server</TITLE></HEAD>\r\n<BODY>"); 1279*5c6c1daeSBarry Smith fprintf(fd, "<H4>Serving PETSc application code %s </H4>\r\n\n",program); 1280*5c6c1daeSBarry Smith fprintf(fd, "Number of processes %d\r\n\n",size); 1281*5c6c1daeSBarry Smith fprintf(fd, "<HR>\r\n"); 1282*5c6c1daeSBarry Smith ierr = PetscViewerASCIIOpenWithFILE(PETSC_COMM_WORLD,fd,&viewer);CHKERRQ(ierr); 1283*5c6c1daeSBarry Smith ierr = PetscOptionsView(viewer);CHKERRQ(ierr); 1284*5c6c1daeSBarry Smith ierr = PetscViewerDestroy(&viewer);CHKERRQ(ierr); 1285*5c6c1daeSBarry Smith fprintf(fd, "<HR>\r\n"); 1286*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_AMS) 1287*5c6c1daeSBarry Smith if (PetscAMSPublishAll) { 1288*5c6c1daeSBarry Smith fprintf(fd, "<a href=\"./ams-tree\">Connect to Memory Snooper--Tree Display</a></p>\r\n\r\n"); 1289*5c6c1daeSBarry Smith fprintf(fd, "<a href=\"./ams-list\">Connect to Memory Snooper--List Display</a></p>\r\n\r\n"); 1290*5c6c1daeSBarry Smith } 1291*5c6c1daeSBarry Smith #endif 1292*5c6c1daeSBarry Smith fprintf(fd, "<a href=\"./AMSJavascript.html\">Connect to Memory Snooper--Interactive Javascript</a></p>\r\n\r\n"); 1293*5c6c1daeSBarry Smith ierr = PetscWebSendFooter(fd);CHKERRQ(ierr); 1294*5c6c1daeSBarry Smith goto theend; 1295*5c6c1daeSBarry Smith } 1296*5c6c1daeSBarry Smith 1297*5c6c1daeSBarry Smith #if defined(PETSC_HAVE_AMS) 1298*5c6c1daeSBarry Smith ierr = PetscStrcmp(path,"/ams-list",&flg);CHKERRQ(ierr); 1299*5c6c1daeSBarry Smith if (flg) { 1300*5c6c1daeSBarry Smith ierr = PetscAMSDisplayList(fd);CHKERRQ(ierr); 1301*5c6c1daeSBarry Smith goto theend; 1302*5c6c1daeSBarry Smith } 1303*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Browser path %s\n",path); 1304*5c6c1daeSBarry Smith ierr = PetscStrcmp(path,"/ams-tree",&flg);CHKERRQ(ierr); 1305*5c6c1daeSBarry Smith if (flg) { 1306*5c6c1daeSBarry Smith ierr = PetscAMSDisplayTree(fd);CHKERRQ(ierr); 1307*5c6c1daeSBarry Smith goto theend; 1308*5c6c1daeSBarry Smith } 1309*5c6c1daeSBarry Smith #endif 1310*5c6c1daeSBarry Smith ierr = PetscStrcpy(fullpath,"${PETSC_DIR}/include/web");CHKERRQ(ierr); 1311*5c6c1daeSBarry Smith ierr = PetscStrcat(fullpath,path);CHKERRQ(ierr); 1312*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Checking for file %s\n",fullpath);CHKERRQ(ierr); 1313*5c6c1daeSBarry Smith ierr = PetscStrreplace(PETSC_COMM_SELF,fullpath,truefullpath,PETSC_MAX_PATH_LEN);CHKERRQ(ierr); 1314*5c6c1daeSBarry Smith fdo = fopen(truefullpath,"r"); 1315*5c6c1daeSBarry Smith if (fdo) { 1316*5c6c1daeSBarry Smith PetscInt length,index; 1317*5c6c1daeSBarry Smith char data[4096]; 1318*5c6c1daeSBarry Smith struct stat statbuf; 1319*5c6c1daeSBarry Smith int n; 1320*5c6c1daeSBarry Smith const char *suffixes[] = {".html",".js",".gif",0}, *mimes[] = {"text/html","text/javascript","image/gif","text/unknown"}; 1321*5c6c1daeSBarry Smith 1322*5c6c1daeSBarry Smith ierr = PetscStrendswithwhich(fullpath,suffixes,&index);CHKERRQ(ierr); 1323*5c6c1daeSBarry Smith type = mimes[index]; 1324*5c6c1daeSBarry Smith if (!stat(truefullpath, &statbuf)) length = -1; 1325*5c6c1daeSBarry Smith else length = S_ISREG(statbuf.st_mode) ? statbuf.st_size : -1; 1326*5c6c1daeSBarry Smith ierr = PetscWebSendHeader(fd, 200, "OK", NULL, type, length);CHKERRQ(ierr); 1327*5c6c1daeSBarry Smith while ((n = fread(data, 1, sizeof(data), fdo)) > 0) fwrite(data, 1, n, fd); 1328*5c6c1daeSBarry Smith fclose(fdo); 1329*5c6c1daeSBarry Smith ierr = PetscInfo2(PETSC_NULL,"Sent file %s to browser using format %s\n",fullpath,type);CHKERRQ(ierr); 1330*5c6c1daeSBarry Smith goto theend; 1331*5c6c1daeSBarry Smith } 1332*5c6c1daeSBarry Smith ierr = PetscWebSendError(fd, 501, "Not supported", NULL, "Unknown request.");CHKERRQ(ierr); 1333*5c6c1daeSBarry Smith } 1334*5c6c1daeSBarry Smith theend: 1335*5c6c1daeSBarry Smith ierr = PetscTokenDestroy(&tok);CHKERRQ(ierr); 1336*5c6c1daeSBarry Smith fclose(fd); 1337*5c6c1daeSBarry Smith ierr = PetscInfo(PETSC_NULL,"Finished processing request\n");CHKERRQ(ierr); 1338*5c6c1daeSBarry Smith 1339*5c6c1daeSBarry Smith PetscFunctionReturn(0); 1340*5c6c1daeSBarry Smith } 1341*5c6c1daeSBarry Smith 1342*5c6c1daeSBarry Smith #undef __FUNCT__ 1343*5c6c1daeSBarry Smith #define __FUNCT__ "PetscWebServeWait" 1344*5c6c1daeSBarry Smith /*@C 1345*5c6c1daeSBarry Smith PetscWebServeWait - waits for requests on a thread 1346*5c6c1daeSBarry Smith 1347*5c6c1daeSBarry Smith Not collective 1348*5c6c1daeSBarry Smith 1349*5c6c1daeSBarry Smith Input Parameter: 1350*5c6c1daeSBarry Smith . port - port to listen on 1351*5c6c1daeSBarry Smith 1352*5c6c1daeSBarry Smith Level: developer 1353*5c6c1daeSBarry Smith 1354*5c6c1daeSBarry Smith .seealso: PetscViewerSocketOpen(), PetscWebServe() 1355*5c6c1daeSBarry Smith @*/ 1356*5c6c1daeSBarry Smith void *PetscWebServeWait(int *port) 1357*5c6c1daeSBarry Smith { 1358*5c6c1daeSBarry Smith PetscErrorCode ierr; 1359*5c6c1daeSBarry Smith int iport,listenport,tport = *port; 1360*5c6c1daeSBarry Smith 1361*5c6c1daeSBarry Smith ierr = PetscInfo1(PETSC_NULL,"Starting webserver at port %d\n",tport);if (ierr) return 0; 1362*5c6c1daeSBarry Smith ierr = PetscFree(port);if (ierr) return 0; 1363*5c6c1daeSBarry Smith ierr = PetscSocketEstablish(tport,&listenport);if (ierr) return 0; 1364*5c6c1daeSBarry Smith while (1) { 1365*5c6c1daeSBarry Smith ierr = PetscSocketListen(listenport,&iport);if (ierr) return 0; 1366*5c6c1daeSBarry Smith ierr = PetscWebServeRequest(iport);if (ierr) return 0; 1367*5c6c1daeSBarry Smith close(iport); 1368*5c6c1daeSBarry Smith } 1369*5c6c1daeSBarry Smith close(listenport); 1370*5c6c1daeSBarry Smith return 0; 1371*5c6c1daeSBarry Smith } 1372*5c6c1daeSBarry Smith 1373*5c6c1daeSBarry Smith #undef __FUNCT__ 1374*5c6c1daeSBarry Smith #define __FUNCT__ "PetscWebServe" 1375*5c6c1daeSBarry Smith /*@C 1376*5c6c1daeSBarry Smith PetscWebServe - start up the PETSc web server and respond to requests 1377*5c6c1daeSBarry Smith 1378*5c6c1daeSBarry Smith Not collective - only does something on process zero of the communicator 1379*5c6c1daeSBarry Smith 1380*5c6c1daeSBarry Smith Input Parameters: 1381*5c6c1daeSBarry Smith + comm - the MPI communicator 1382*5c6c1daeSBarry Smith - port - port to listen on 1383*5c6c1daeSBarry Smith 1384*5c6c1daeSBarry Smith Options Database Key: 1385*5c6c1daeSBarry Smith + -server <port> - start PETSc webserver (default port is 8080) 1386*5c6c1daeSBarry Smith - -ams_publish_objects 1387*5c6c1daeSBarry Smith 1388*5c6c1daeSBarry Smith 1389*5c6c1daeSBarry Smith Notes: Point your browser to http://hostname:8080 to access the PETSc web server, where hostname is the name of your machine. 1390*5c6c1daeSBarry Smith If you are running PETSc on your local machine you can use http://localhost:8080 1391*5c6c1daeSBarry Smith 1392*5c6c1daeSBarry Smith If the PETSc program completes before you connect with the browser you will not be able to connect to the PETSc webserver. 1393*5c6c1daeSBarry Smith 1394*5c6c1daeSBarry Smith Read the top of $PETSC_DIR/include/web/AMSJavascript.py before running. 1395*5c6c1daeSBarry Smith 1396*5c6c1daeSBarry Smith Level: developer 1397*5c6c1daeSBarry Smith 1398*5c6c1daeSBarry Smith .seealso: PetscViewerSocketOpen() 1399*5c6c1daeSBarry Smith @*/ 1400*5c6c1daeSBarry Smith PetscErrorCode PetscWebServe(MPI_Comm comm,int port) 1401*5c6c1daeSBarry Smith { 1402*5c6c1daeSBarry Smith PetscErrorCode ierr; 1403*5c6c1daeSBarry Smith PetscMPIInt rank; 1404*5c6c1daeSBarry Smith pthread_t thread; 1405*5c6c1daeSBarry Smith int *trueport; 1406*5c6c1daeSBarry Smith 1407*5c6c1daeSBarry Smith PetscFunctionBegin; 1408*5c6c1daeSBarry Smith if (port < 1 && port != PETSC_DEFAULT && port != PETSC_DECIDE) SETERRQ1(PETSC_COMM_WORLD,PETSC_ERR_ARG_WRONG,"Cannot use negative port number %d",port); 1409*5c6c1daeSBarry Smith ierr = MPI_Comm_rank(comm,&rank);CHKERRQ(ierr); 1410*5c6c1daeSBarry Smith if (rank) PetscFunctionReturn(0); 1411*5c6c1daeSBarry Smith 1412*5c6c1daeSBarry Smith if (port == PETSC_DECIDE || port == PETSC_DEFAULT) port = 8080; 1413*5c6c1daeSBarry Smith ierr = PetscMalloc(1*sizeof(int),&trueport);CHKERRQ(ierr); /* malloc this so it still exists in thread */ 1414*5c6c1daeSBarry Smith *trueport = port; 1415*5c6c1daeSBarry Smith ierr = pthread_create(&thread, NULL, (void *(*)(void *))PetscWebServeWait, trueport);CHKERRQ(ierr); 1416*5c6c1daeSBarry Smith PetscFunctionReturn(0); 1417*5c6c1daeSBarry Smith } 1418*5c6c1daeSBarry Smith #endif 1419*5c6c1daeSBarry Smith 1420*5c6c1daeSBarry Smith 1421*5c6c1daeSBarry Smith 1422*5c6c1daeSBarry Smith 1423*5c6c1daeSBarry Smith 1424*5c6c1daeSBarry Smith 1425*5c6c1daeSBarry Smith 1426*5c6c1daeSBarry Smith 1427*5c6c1daeSBarry Smith 1428*5c6c1daeSBarry Smith 1429*5c6c1daeSBarry Smith 1430*5c6c1daeSBarry Smith 1431*5c6c1daeSBarry Smith 1432*5c6c1daeSBarry Smith 1433