15c6c1daeSBarry Smith 25c6c1daeSBarry Smith #include <petscsys.h> 35c6c1daeSBarry Smith 45c6c1daeSBarry Smith #if defined(PETSC_NEEDS_UTYPE_TYPEDEFS) 55c6c1daeSBarry Smith /* Some systems have inconsistent include files that use but do not 65c6c1daeSBarry Smith ensure that the following definitions are made */ 75c6c1daeSBarry Smith typedef unsigned char u_char; 85c6c1daeSBarry Smith typedef unsigned short u_short; 95c6c1daeSBarry Smith typedef unsigned short ushort; 105c6c1daeSBarry Smith typedef unsigned int u_int; 115c6c1daeSBarry Smith typedef unsigned long u_long; 125c6c1daeSBarry Smith #endif 135c6c1daeSBarry Smith 145c6c1daeSBarry Smith #include <errno.h> 155c6c1daeSBarry Smith #include <ctype.h> 165c6c1daeSBarry Smith #if defined(PETSC_HAVE_MACHINE_ENDIAN_H) 175c6c1daeSBarry Smith #include <machine/endian.h> 185c6c1daeSBarry Smith #endif 195c6c1daeSBarry Smith #if defined(PETSC_HAVE_UNISTD_H) 205c6c1daeSBarry Smith #include <unistd.h> 215c6c1daeSBarry Smith #endif 225c6c1daeSBarry Smith #if defined(PETSC_HAVE_SYS_SOCKET_H) 235c6c1daeSBarry Smith #include <sys/socket.h> 245c6c1daeSBarry Smith #endif 255c6c1daeSBarry Smith #if defined(PETSC_HAVE_SYS_WAIT_H) 265c6c1daeSBarry Smith #include <sys/wait.h> 275c6c1daeSBarry Smith #endif 285c6c1daeSBarry Smith #if defined(PETSC_HAVE_NETINET_IN_H) 295c6c1daeSBarry Smith #include <netinet/in.h> 305c6c1daeSBarry Smith #endif 315c6c1daeSBarry Smith #if defined(PETSC_HAVE_NETDB_H) 325c6c1daeSBarry Smith #include <netdb.h> 335c6c1daeSBarry Smith #endif 345c6c1daeSBarry Smith #if defined(PETSC_HAVE_FCNTL_H) 355c6c1daeSBarry Smith #include <fcntl.h> 365c6c1daeSBarry Smith #endif 375c6c1daeSBarry Smith #if defined(PETSC_HAVE_IO_H) 385c6c1daeSBarry Smith #include <io.h> 395c6c1daeSBarry Smith #endif 405c6c1daeSBarry Smith #if defined(PETSC_HAVE_WINSOCK2_H) 415c6c1daeSBarry Smith #include <Winsock2.h> 425c6c1daeSBarry Smith #endif 435c6c1daeSBarry Smith #include <sys/stat.h> 445c6c1daeSBarry Smith #include <../src/sys/classes/viewer/impls/socket/socket.h> 455c6c1daeSBarry Smith 465c6c1daeSBarry Smith #if defined(PETSC_NEED_CLOSE_PROTO) 478cc058d9SJed Brown PETSC_EXTERN int close(int); 485c6c1daeSBarry Smith #endif 495c6c1daeSBarry Smith #if defined(PETSC_NEED_SOCKET_PROTO) 508cc058d9SJed Brown PETSC_EXTERN int socket(int,int,int); 515c6c1daeSBarry Smith #endif 525c6c1daeSBarry Smith #if defined(PETSC_NEED_SLEEP_PROTO) 538cc058d9SJed Brown PETSC_EXTERN int sleep(unsigned); 545c6c1daeSBarry Smith #endif 555c6c1daeSBarry Smith #if defined(PETSC_NEED_CONNECT_PROTO) 568cc058d9SJed Brown PETSC_EXTERN int connect(int,struct sockaddr*,int); 575c6c1daeSBarry Smith #endif 585c6c1daeSBarry Smith 595c6c1daeSBarry Smith /*--------------------------------------------------------------*/ 605c6c1daeSBarry Smith #undef __FUNCT__ 615c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerDestroy_Socket" 625c6c1daeSBarry Smith static PetscErrorCode PetscViewerDestroy_Socket(PetscViewer viewer) 635c6c1daeSBarry Smith { 645c6c1daeSBarry Smith PetscViewer_Socket *vmatlab = (PetscViewer_Socket*)viewer->data; 655c6c1daeSBarry Smith PetscErrorCode ierr; 665c6c1daeSBarry Smith 675c6c1daeSBarry Smith PetscFunctionBegin; 685c6c1daeSBarry Smith if (vmatlab->port) { 695c6c1daeSBarry Smith #if defined(PETSC_HAVE_CLOSESOCKET) 705c6c1daeSBarry Smith ierr = closesocket(vmatlab->port); 715c6c1daeSBarry Smith #else 725c6c1daeSBarry Smith ierr = close(vmatlab->port); 735c6c1daeSBarry Smith #endif 745c6c1daeSBarry Smith if (ierr) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"System error closing socket"); 755c6c1daeSBarry Smith } 765c6c1daeSBarry Smith ierr = PetscFree(vmatlab);CHKERRQ(ierr); 775c6c1daeSBarry Smith PetscFunctionReturn(0); 785c6c1daeSBarry Smith } 795c6c1daeSBarry Smith 805c6c1daeSBarry Smith /*--------------------------------------------------------------*/ 815c6c1daeSBarry Smith #undef __FUNCT__ 825c6c1daeSBarry Smith #define __FUNCT__ "PetscOpenSocket" 835c6c1daeSBarry Smith /* 845c6c1daeSBarry Smith PetscSocketOpen - handles connected to an open port where someone is waiting. 855c6c1daeSBarry Smith 865c6c1daeSBarry Smith .seealso: PetscSocketListen(), PetscSocketEstablish() 875c6c1daeSBarry Smith */ 88e2fc02c1SBarry Smith PetscErrorCode PetscOpenSocket(const char hostname[],int portnum,int *t) 895c6c1daeSBarry Smith { 905c6c1daeSBarry Smith struct sockaddr_in sa; 915c6c1daeSBarry Smith struct hostent *hp; 925c6c1daeSBarry Smith int s = 0; 935c6c1daeSBarry Smith PetscErrorCode ierr; 945c6c1daeSBarry Smith PetscBool flg = PETSC_TRUE; 954a285bdaSBarry Smith static int refcnt = 0; 965c6c1daeSBarry Smith 975c6c1daeSBarry Smith PetscFunctionBegin; 985c6c1daeSBarry Smith if (!(hp=gethostbyname(hostname))) { 995c6c1daeSBarry Smith perror("SEND: error gethostbyname: "); 1005c6c1daeSBarry Smith SETERRQ1(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error open connection to %s",hostname); 1015c6c1daeSBarry Smith } 1025c6c1daeSBarry Smith ierr = PetscMemzero(&sa,sizeof(sa));CHKERRQ(ierr); 1035c6c1daeSBarry Smith ierr = PetscMemcpy(&sa.sin_addr,hp->h_addr_list[0],hp->h_length);CHKERRQ(ierr); 1045c6c1daeSBarry Smith 1055c6c1daeSBarry Smith sa.sin_family = hp->h_addrtype; 1065c6c1daeSBarry Smith sa.sin_port = htons((u_short) portnum); 1075c6c1daeSBarry Smith while (flg) { 1085c6c1daeSBarry Smith if ((s=socket(hp->h_addrtype,SOCK_STREAM,0)) < 0) { 1095c6c1daeSBarry Smith perror("SEND: error socket"); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error"); 1105c6c1daeSBarry Smith } 1115c6c1daeSBarry Smith if (connect(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) { 1125c6c1daeSBarry Smith #if defined(PETSC_HAVE_WSAGETLASTERROR) 1135c6c1daeSBarry Smith ierr = WSAGetLastError(); 114a297a907SKarl Rupp if (ierr == WSAEADDRINUSE) (*PetscErrorPrintf)("SEND: address is in use\n"); 115a297a907SKarl Rupp else if (ierr == WSAEALREADY) (*PetscErrorPrintf)("SEND: socket is non-blocking \n"); 116a297a907SKarl Rupp else if (ierr == WSAEISCONN) { 1175c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: socket already connected\n"); 1185c6c1daeSBarry Smith Sleep((unsigned) 1); 1195c6c1daeSBarry Smith } else if (ierr == WSAECONNREFUSED) { 1205c6c1daeSBarry Smith /* (*PetscErrorPrintf)("SEND: forcefully rejected\n"); */ 1215c6c1daeSBarry Smith Sleep((unsigned) 1); 1225c6c1daeSBarry Smith } else { 1235c6c1daeSBarry Smith perror(NULL); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error"); 1245c6c1daeSBarry Smith } 1255c6c1daeSBarry Smith #else 126a297a907SKarl Rupp if (errno == EADDRINUSE) (*PetscErrorPrintf)("SEND: address is in use\n"); 127a297a907SKarl Rupp else if (errno == EALREADY) (*PetscErrorPrintf)("SEND: socket is non-blocking \n"); 128a297a907SKarl Rupp else if (errno == EISCONN) { 1295c6c1daeSBarry Smith (*PetscErrorPrintf)("SEND: socket already connected\n"); 1305c6c1daeSBarry Smith sleep((unsigned) 1); 1315c6c1daeSBarry Smith } else if (errno == ECONNREFUSED) { 1324a285bdaSBarry Smith refcnt++; 1334a285bdaSBarry Smith if (refcnt > 5) SETERRQ2(PETSC_COMM_SELF,PETSC_ERR_SYS,"Connection refused by remote host %s port %d",hostname,portnum); 134955c1f14SBarry Smith ierr = PetscInfo(0,"Connection refused in attaching socket, trying again\n");CHKERRQ(ierr); 1355c6c1daeSBarry Smith sleep((unsigned) 1); 1365c6c1daeSBarry Smith } else { 1375c6c1daeSBarry Smith perror(NULL); SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"system error"); 1385c6c1daeSBarry Smith } 1395c6c1daeSBarry Smith #endif 1405c6c1daeSBarry Smith flg = PETSC_TRUE; 1415c6c1daeSBarry Smith #if defined(PETSC_HAVE_CLOSESOCKET) 1425c6c1daeSBarry Smith closesocket(s); 1435c6c1daeSBarry Smith #else 1445c6c1daeSBarry Smith close(s); 1455c6c1daeSBarry Smith #endif 146a297a907SKarl Rupp } else flg = PETSC_FALSE; 1475c6c1daeSBarry Smith } 1485c6c1daeSBarry Smith *t = s; 1495c6c1daeSBarry Smith PetscFunctionReturn(0); 1505c6c1daeSBarry Smith } 1515c6c1daeSBarry Smith 1525c6c1daeSBarry Smith #define MAXHOSTNAME 100 1535c6c1daeSBarry Smith #undef __FUNCT__ 1545c6c1daeSBarry Smith #define __FUNCT__ "PetscSocketEstablish" 1555c6c1daeSBarry Smith /* 1565c6c1daeSBarry Smith PetscSocketEstablish - starts a listener on a socket 1575c6c1daeSBarry Smith 1585c6c1daeSBarry Smith .seealso: PetscSocketListen() 1595c6c1daeSBarry Smith */ 1605847ff97SBarry Smith PETSC_INTERN PetscErrorCode PetscSocketEstablish(int portnum,int *ss) 1615c6c1daeSBarry Smith { 1625c6c1daeSBarry Smith char myname[MAXHOSTNAME+1]; 1635c6c1daeSBarry Smith int s; 1645c6c1daeSBarry Smith PetscErrorCode ierr; 1655c6c1daeSBarry Smith struct sockaddr_in sa; 1665c6c1daeSBarry Smith struct hostent *hp; 1675c6c1daeSBarry Smith 1685c6c1daeSBarry Smith PetscFunctionBegin; 1695c6c1daeSBarry Smith ierr = PetscGetHostName(myname,MAXHOSTNAME);CHKERRQ(ierr); 1705c6c1daeSBarry Smith 1715c6c1daeSBarry Smith ierr = PetscMemzero(&sa,sizeof(struct sockaddr_in));CHKERRQ(ierr); 1725c6c1daeSBarry Smith 1735c6c1daeSBarry Smith hp = gethostbyname(myname); 1745c6c1daeSBarry Smith if (!hp) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Unable to get hostent information from system"); 1755c6c1daeSBarry Smith 1765c6c1daeSBarry Smith sa.sin_family = hp->h_addrtype; 1775c6c1daeSBarry Smith sa.sin_port = htons((u_short)portnum); 1785c6c1daeSBarry Smith 1795c6c1daeSBarry Smith if ((s = socket(AF_INET,SOCK_STREAM,0)) < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Error running socket() command"); 1805c6c1daeSBarry Smith #if defined(PETSC_HAVE_SO_REUSEADDR) 1815c6c1daeSBarry Smith { 1825c6c1daeSBarry Smith int optval = 1; /* Turn on the option */ 1835c6c1daeSBarry Smith ierr = setsockopt(s,SOL_SOCKET,SO_REUSEADDR,(char*)&optval,sizeof(optval));CHKERRQ(ierr); 1845c6c1daeSBarry Smith } 1855c6c1daeSBarry Smith #endif 1865c6c1daeSBarry Smith 1875c6c1daeSBarry Smith while (bind(s,(struct sockaddr*)&sa,sizeof(sa)) < 0) { 1885c6c1daeSBarry Smith #if defined(PETSC_HAVE_WSAGETLASTERROR) 1895c6c1daeSBarry Smith ierr = WSAGetLastError(); 1905c6c1daeSBarry Smith if (ierr != WSAEADDRINUSE) { 1915c6c1daeSBarry Smith #else 1925c6c1daeSBarry Smith if (errno != EADDRINUSE) { 1935c6c1daeSBarry Smith #endif 1945c6c1daeSBarry Smith close(s); 1955c6c1daeSBarry Smith SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"Error from bind()"); 1965c6c1daeSBarry Smith } 1975c6c1daeSBarry Smith } 1985c6c1daeSBarry Smith listen(s,0); 1995c6c1daeSBarry Smith *ss = s; 2005c6c1daeSBarry Smith return(0); 2015c6c1daeSBarry Smith } 2025c6c1daeSBarry Smith 2035c6c1daeSBarry Smith #undef __FUNCT__ 2045c6c1daeSBarry Smith #define __FUNCT__ "PetscSocketListen" 2055c6c1daeSBarry Smith /* 2065c6c1daeSBarry Smith PetscSocketListens - Listens at a socket created with PetscSocketEstablish() 2075c6c1daeSBarry Smith 2085c6c1daeSBarry Smith .seealso: PetscSocketEstablish() 2095c6c1daeSBarry Smith */ 2105847ff97SBarry Smith PETSC_INTERN PetscErrorCode PetscSocketListen(int listenport,int *t) 2115c6c1daeSBarry Smith { 2125c6c1daeSBarry Smith struct sockaddr_in isa; 2135c6c1daeSBarry Smith #if defined(PETSC_HAVE_ACCEPT_SIZE_T) 2145c6c1daeSBarry Smith size_t i; 2155c6c1daeSBarry Smith #else 2165c6c1daeSBarry Smith int i; 2175c6c1daeSBarry Smith #endif 2185c6c1daeSBarry Smith 2195c6c1daeSBarry Smith PetscFunctionBegin; 2205c6c1daeSBarry Smith /* wait for someone to try to connect */ 2215c6c1daeSBarry Smith i = sizeof(struct sockaddr_in); 2225c6c1daeSBarry Smith if ((*t = accept(listenport,(struct sockaddr*)&isa,(socklen_t*)&i)) < 0) SETERRQ(PETSC_COMM_SELF,PETSC_ERR_SYS,"error from accept()\n"); 2235c6c1daeSBarry Smith PetscFunctionReturn(0); 2245c6c1daeSBarry Smith } 2255c6c1daeSBarry Smith 2265c6c1daeSBarry Smith #undef __FUNCT__ 2275c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerSocketOpen" 2285c6c1daeSBarry Smith /*@C 2295c6c1daeSBarry Smith PetscViewerSocketOpen - Opens a connection to a MATLAB or other socket 2305c6c1daeSBarry Smith based server. 2315c6c1daeSBarry Smith 2325c6c1daeSBarry Smith Collective on MPI_Comm 2335c6c1daeSBarry Smith 2345c6c1daeSBarry Smith Input Parameters: 2355c6c1daeSBarry Smith + comm - the MPI communicator 2360298fd71SBarry Smith . machine - the machine the server is running on,, use NULL for the local machine, use "server" to passively wait for 2375c6c1daeSBarry Smith a connection from elsewhere 2385c6c1daeSBarry Smith - port - the port to connect to, use PETSC_DEFAULT for the default 2395c6c1daeSBarry Smith 2405c6c1daeSBarry Smith Output Parameter: 2415c6c1daeSBarry Smith . lab - a context to use when communicating with the server 2425c6c1daeSBarry Smith 2435c6c1daeSBarry Smith Level: intermediate 2445c6c1daeSBarry Smith 2455c6c1daeSBarry Smith Notes: 2465c6c1daeSBarry Smith Most users should employ the following commands to access the 2475c6c1daeSBarry Smith MATLAB PetscViewers 2485c6c1daeSBarry Smith $ 2495c6c1daeSBarry Smith $ PetscViewerSocketOpen(MPI_Comm comm, char *machine,int port,PetscViewer &viewer) 2505c6c1daeSBarry Smith $ MatView(Mat matrix,PetscViewer viewer) 2515c6c1daeSBarry Smith $ 2525c6c1daeSBarry Smith $ or 2535c6c1daeSBarry Smith $ 2545c6c1daeSBarry Smith $ PetscViewerSocketOpen(MPI_Comm comm,char *machine,int port,PetscViewer &viewer) 2555c6c1daeSBarry Smith $ VecView(Vec vector,PetscViewer viewer) 2565c6c1daeSBarry Smith 2575c6c1daeSBarry Smith Options Database Keys: 2585c6c1daeSBarry Smith For use with PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF, 2595c6c1daeSBarry Smith PETSC_VIEWER_SOCKET_() or if 2600298fd71SBarry Smith NULL is passed for machine or PETSC_DEFAULT is passed for port 2615c6c1daeSBarry Smith $ -viewer_socket_machine <machine> 2625c6c1daeSBarry Smith $ -viewer_socket_port <port> 2635c6c1daeSBarry Smith 2645c6c1daeSBarry Smith Environmental variables: 2655c6c1daeSBarry Smith + PETSC_VIEWER_SOCKET_PORT portnumber 2665c6c1daeSBarry Smith - PETSC_VIEWER_SOCKET_MACHINE machine name 2675c6c1daeSBarry Smith 2685c6c1daeSBarry Smith Currently the only socket client available is MATLAB. See 2695c6c1daeSBarry Smith src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage. 2705c6c1daeSBarry Smith 2715c6c1daeSBarry Smith Notes: The socket viewer is in some sense a subclass of the binary viewer, to read and write to the socket 2725c6c1daeSBarry Smith use PetscViewerBinaryRead/Write/GetDescriptor(). 2735c6c1daeSBarry Smith 2745c6c1daeSBarry Smith Concepts: MATLAB^sending data 2755c6c1daeSBarry Smith Concepts: sockets^sending data 2765c6c1daeSBarry Smith 2775c6c1daeSBarry Smith .seealso: MatView(), VecView(), PetscViewerDestroy(), PetscViewerCreate(), PetscViewerSetType(), 2785c6c1daeSBarry Smith PetscViewerSocketSetConnection(), PETSC_VIEWER_SOCKET_, PETSC_VIEWER_SOCKET_WORLD, 2795c6c1daeSBarry Smith PETSC_VIEWER_SOCKET_SELF, PetscViewerBinaryWrite(), PetscViewerBinaryRead(), PetscViewerBinaryWriteStringArray(), 2805c6c1daeSBarry Smith PetscBinaryViewerGetDescriptor() 2815c6c1daeSBarry Smith @*/ 2825c6c1daeSBarry Smith PetscErrorCode PetscViewerSocketOpen(MPI_Comm comm,const char machine[],int port,PetscViewer *lab) 2835c6c1daeSBarry Smith { 2845c6c1daeSBarry Smith PetscErrorCode ierr; 2855c6c1daeSBarry Smith 2865c6c1daeSBarry Smith PetscFunctionBegin; 2875c6c1daeSBarry Smith ierr = PetscViewerCreate(comm,lab);CHKERRQ(ierr); 2885c6c1daeSBarry Smith ierr = PetscViewerSetType(*lab,PETSCVIEWERSOCKET);CHKERRQ(ierr); 2895c6c1daeSBarry Smith ierr = PetscViewerSocketSetConnection(*lab,machine,port);CHKERRQ(ierr); 2905c6c1daeSBarry Smith PetscFunctionReturn(0); 2915c6c1daeSBarry Smith } 2925c6c1daeSBarry Smith 2935c6c1daeSBarry Smith #undef __FUNCT__ 2945c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerSetFromOptions_Socket" 2954416b707SBarry Smith static PetscErrorCode PetscViewerSetFromOptions_Socket(PetscOptionItems *PetscOptionsObject,PetscViewer v) 2965c6c1daeSBarry Smith { 2975c6c1daeSBarry Smith PetscErrorCode ierr; 2985c6c1daeSBarry Smith PetscInt def = -1; 2995c6c1daeSBarry Smith char sdef[256]; 3005c6c1daeSBarry Smith PetscBool tflg; 3015c6c1daeSBarry Smith 3025c6c1daeSBarry Smith PetscFunctionBegin; 3035c6c1daeSBarry Smith /* 3045c6c1daeSBarry Smith These options are not processed here, they are processed in PetscViewerSocketSetConnection(), they 3055c6c1daeSBarry Smith are listed here for the GUI to display 3065c6c1daeSBarry Smith */ 307e55864a3SBarry Smith ierr = PetscOptionsHead(PetscOptionsObject,"Socket PetscViewer Options");CHKERRQ(ierr); 308ce94432eSBarry Smith ierr = PetscOptionsGetenv(PetscObjectComm((PetscObject)v),"PETSC_VIEWER_SOCKET_PORT",sdef,16,&tflg);CHKERRQ(ierr); 3095c6c1daeSBarry Smith if (tflg) { 3105c6c1daeSBarry Smith ierr = PetscOptionsStringToInt(sdef,&def);CHKERRQ(ierr); 311a297a907SKarl Rupp } else def = PETSCSOCKETDEFAULTPORT; 3125c6c1daeSBarry Smith ierr = PetscOptionsInt("-viewer_socket_port","Port number to use for socket","PetscViewerSocketSetConnection",def,0,0);CHKERRQ(ierr); 3135c6c1daeSBarry Smith 3145c6c1daeSBarry Smith ierr = PetscOptionsString("-viewer_socket_machine","Machine to use for socket","PetscViewerSocketSetConnection",sdef,0,0,0);CHKERRQ(ierr); 315ce94432eSBarry Smith ierr = PetscOptionsGetenv(PetscObjectComm((PetscObject)v),"PETSC_VIEWER_SOCKET_MACHINE",sdef,256,&tflg);CHKERRQ(ierr); 3165c6c1daeSBarry Smith if (!tflg) { 3175c6c1daeSBarry Smith ierr = PetscGetHostName(sdef,256);CHKERRQ(ierr); 3185c6c1daeSBarry Smith } 3195c6c1daeSBarry Smith ierr = PetscOptionsTail();CHKERRQ(ierr); 3205c6c1daeSBarry Smith PetscFunctionReturn(0); 3215c6c1daeSBarry Smith } 3225c6c1daeSBarry Smith 323*8556b5ebSBarry Smith /*MC 324*8556b5ebSBarry Smith PETSCVIEWERSOCKET - A viewer that writes to a Unix socket 325*8556b5ebSBarry Smith 326*8556b5ebSBarry Smith 327*8556b5ebSBarry Smith .seealso: PetscViewerSocketOpen(), PetscViewerDrawOpen(), PETSC_VIEWER_DRAW_(),PETSC_VIEWER_DRAW_SELF, PETSC_VIEWER_DRAW_WORLD, 328*8556b5ebSBarry Smith PetscViewerCreate(), PetscViewerASCIIOpen(), PetscViewerBinaryOpen(), PETSCVIEWERBINARY, PETSCVIEWERDRAW, 329*8556b5ebSBarry Smith PetscViewerMatlabOpen(), VecView(), DMView(), PetscViewerMatlabPutArray(), PETSCVIEWERASCII, PETSCVIEWERMATLAB, 330*8556b5ebSBarry Smith PetscViewerFileSetName(), PetscViewerFileSetMode(), PetscViewerFormat, PetscViewerType, PetscViewerSetType() 331*8556b5ebSBarry Smith 332*8556b5ebSBarry Smith M*/ 333*8556b5ebSBarry Smith 3345c6c1daeSBarry Smith #undef __FUNCT__ 3355c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerCreate_Socket" 3368cc058d9SJed Brown PETSC_EXTERN PetscErrorCode PetscViewerCreate_Socket(PetscViewer v) 3375c6c1daeSBarry Smith { 3385c6c1daeSBarry Smith PetscViewer_Socket *vmatlab; 3395c6c1daeSBarry Smith PetscErrorCode ierr; 3405c6c1daeSBarry Smith 3415c6c1daeSBarry Smith PetscFunctionBegin; 342b00a9115SJed Brown ierr = PetscNewLog(v,&vmatlab);CHKERRQ(ierr); 3435c6c1daeSBarry Smith vmatlab->port = 0; 3445c6c1daeSBarry Smith v->data = (void*)vmatlab; 3455c6c1daeSBarry Smith v->ops->destroy = PetscViewerDestroy_Socket; 3465c6c1daeSBarry Smith v->ops->flush = 0; 3475c6c1daeSBarry Smith v->ops->setfromoptions = PetscViewerSetFromOptions_Socket; 3485c6c1daeSBarry Smith 3495c6c1daeSBarry Smith /* lie and say this is a binary viewer; then all the XXXView_Binary() methods will work correctly on it */ 3505c6c1daeSBarry Smith ierr = PetscObjectChangeTypeName((PetscObject)v,PETSCVIEWERBINARY);CHKERRQ(ierr); 3515c6c1daeSBarry Smith PetscFunctionReturn(0); 3525c6c1daeSBarry Smith } 3535c6c1daeSBarry Smith 3545c6c1daeSBarry Smith #undef __FUNCT__ 3555c6c1daeSBarry Smith #define __FUNCT__ "PetscViewerSocketSetConnection" 3565c6c1daeSBarry Smith /*@C 3575c6c1daeSBarry Smith PetscViewerSocketSetConnection - Sets the machine and port that a PETSc socket 3585c6c1daeSBarry Smith viewer is to use 3595c6c1daeSBarry Smith 3605c6c1daeSBarry Smith Logically Collective on PetscViewer 3615c6c1daeSBarry Smith 3625c6c1daeSBarry Smith Input Parameters: 3635c6c1daeSBarry Smith + v - viewer to connect 3640298fd71SBarry Smith . machine - host to connect to, use NULL for the local machine,use "server" to passively wait for 3655c6c1daeSBarry Smith a connection from elsewhere 3665c6c1daeSBarry Smith - port - the port on the machine one is connecting to, use PETSC_DEFAULT for default 3675c6c1daeSBarry Smith 3685c6c1daeSBarry Smith Level: advanced 3695c6c1daeSBarry Smith 3705c6c1daeSBarry Smith .seealso: PetscViewerSocketOpen() 3715c6c1daeSBarry Smith @*/ 3725c6c1daeSBarry Smith PetscErrorCode PetscViewerSocketSetConnection(PetscViewer v,const char machine[],int port) 3735c6c1daeSBarry Smith { 3745c6c1daeSBarry Smith PetscErrorCode ierr; 3755c6c1daeSBarry Smith PetscMPIInt rank; 3765c6c1daeSBarry Smith char mach[256]; 3775c6c1daeSBarry Smith PetscBool tflg; 3785c6c1daeSBarry Smith PetscViewer_Socket *vmatlab = (PetscViewer_Socket*)v->data; 3795c6c1daeSBarry Smith 3805c6c1daeSBarry Smith PetscFunctionBegin; 3815c6c1daeSBarry Smith /* PetscValidLogicalCollectiveInt(v,port,3); not a PetscInt */ 3825c6c1daeSBarry Smith if (port <= 0) { 3835c6c1daeSBarry Smith char portn[16]; 384ce94432eSBarry Smith ierr = PetscOptionsGetenv(PetscObjectComm((PetscObject)v),"PETSC_VIEWER_SOCKET_PORT",portn,16,&tflg);CHKERRQ(ierr); 3855c6c1daeSBarry Smith if (tflg) { 3865c6c1daeSBarry Smith PetscInt pport; 3875c6c1daeSBarry Smith ierr = PetscOptionsStringToInt(portn,&pport);CHKERRQ(ierr); 3885c6c1daeSBarry Smith port = (int)pport; 389a297a907SKarl Rupp } else port = PETSCSOCKETDEFAULTPORT; 3905c6c1daeSBarry Smith } 3915c6c1daeSBarry Smith if (!machine) { 392ce94432eSBarry Smith ierr = PetscOptionsGetenv(PetscObjectComm((PetscObject)v),"PETSC_VIEWER_SOCKET_MACHINE",mach,256,&tflg);CHKERRQ(ierr); 3935c6c1daeSBarry Smith if (!tflg) { 3945c6c1daeSBarry Smith ierr = PetscGetHostName(mach,256);CHKERRQ(ierr); 3955c6c1daeSBarry Smith } 3965c6c1daeSBarry Smith } else { 3975c6c1daeSBarry Smith ierr = PetscStrncpy(mach,machine,256);CHKERRQ(ierr); 3985c6c1daeSBarry Smith } 3995c6c1daeSBarry Smith 400ce94432eSBarry Smith ierr = MPI_Comm_rank(PetscObjectComm((PetscObject)v),&rank);CHKERRQ(ierr); 4015c6c1daeSBarry Smith if (!rank) { 4025c6c1daeSBarry Smith ierr = PetscStrcmp(mach,"server",&tflg);CHKERRQ(ierr); 4035c6c1daeSBarry Smith if (tflg) { 4045c6c1daeSBarry Smith int listenport; 4055c6c1daeSBarry Smith ierr = PetscInfo1(v,"Waiting for connection from socket process on port %D\n",port);CHKERRQ(ierr); 4065c6c1daeSBarry Smith ierr = PetscSocketEstablish(port,&listenport);CHKERRQ(ierr); 4075c6c1daeSBarry Smith ierr = PetscSocketListen(listenport,&vmatlab->port);CHKERRQ(ierr); 4085c6c1daeSBarry Smith close(listenport); 4095c6c1daeSBarry Smith } else { 4105c6c1daeSBarry Smith ierr = PetscInfo2(v,"Connecting to socket process on port %D machine %s\n",port,mach);CHKERRQ(ierr); 4115c6c1daeSBarry Smith ierr = PetscOpenSocket(mach,port,&vmatlab->port);CHKERRQ(ierr); 4125c6c1daeSBarry Smith } 4135c6c1daeSBarry Smith } 4145c6c1daeSBarry Smith PetscFunctionReturn(0); 4155c6c1daeSBarry Smith } 4165c6c1daeSBarry Smith 4175c6c1daeSBarry Smith /* ---------------------------------------------------------------------*/ 4185c6c1daeSBarry Smith /* 4195c6c1daeSBarry Smith The variable Petsc_Viewer_Socket_keyval is used to indicate an MPI attribute that 4205c6c1daeSBarry Smith is attached to a communicator, in this case the attribute is a PetscViewer. 4215c6c1daeSBarry Smith */ 4225c6c1daeSBarry Smith static PetscMPIInt Petsc_Viewer_Socket_keyval = MPI_KEYVAL_INVALID; 4235c6c1daeSBarry Smith 4245c6c1daeSBarry Smith 4255c6c1daeSBarry Smith #undef __FUNCT__ 4265c6c1daeSBarry Smith #define __FUNCT__ "PETSC_VIEWER_SOCKET_" 4275c6c1daeSBarry Smith /*@C 4285c6c1daeSBarry Smith PETSC_VIEWER_SOCKET_ - Creates a socket viewer shared by all processors in a communicator. 4295c6c1daeSBarry Smith 4305c6c1daeSBarry Smith Collective on MPI_Comm 4315c6c1daeSBarry Smith 4325c6c1daeSBarry Smith Input Parameter: 4335c6c1daeSBarry Smith . comm - the MPI communicator to share the socket PetscViewer 4345c6c1daeSBarry Smith 4355c6c1daeSBarry Smith Level: intermediate 4365c6c1daeSBarry Smith 4375c6c1daeSBarry Smith Options Database Keys: 4385c6c1daeSBarry Smith For use with the default PETSC_VIEWER_SOCKET_WORLD or if 4390298fd71SBarry Smith NULL is passed for machine or PETSC_DEFAULT is passed for port 4405c6c1daeSBarry Smith $ -viewer_socket_machine <machine> 4415c6c1daeSBarry Smith $ -viewer_socket_port <port> 4425c6c1daeSBarry Smith 4435c6c1daeSBarry Smith Environmental variables: 4445c6c1daeSBarry Smith + PETSC_VIEWER_SOCKET_PORT portnumber 4455c6c1daeSBarry Smith - PETSC_VIEWER_SOCKET_MACHINE machine name 4465c6c1daeSBarry Smith 4475c6c1daeSBarry Smith Notes: 4485c6c1daeSBarry Smith Unlike almost all other PETSc routines, PetscViewer_SOCKET_ does not return 4495c6c1daeSBarry Smith an error code. The socket PetscViewer is usually used in the form 4505c6c1daeSBarry Smith $ XXXView(XXX object,PETSC_VIEWER_SOCKET_(comm)); 4515c6c1daeSBarry Smith 4525c6c1daeSBarry Smith Currently the only socket client available is MATLAB. See 4535c6c1daeSBarry Smith src/dm/da/examples/tests/ex12.c and ex12.m for an example of usage. 4545c6c1daeSBarry Smith 4555c6c1daeSBarry Smith Connects to a waiting socket and stays connected until PetscViewerDestroy() is called. 4565c6c1daeSBarry Smith 4575c6c1daeSBarry Smith Use this for communicating with an interactive MATLAB session, see PETSC_VIEWER_MATLAB_() for communicating with the MATLAB engine. 4585c6c1daeSBarry Smith 4595c6c1daeSBarry Smith .seealso: PETSC_VIEWER_SOCKET_WORLD, PETSC_VIEWER_SOCKET_SELF, PetscViewerSocketOpen(), PetscViewerCreate(), 4605c6c1daeSBarry Smith PetscViewerSocketSetConnection(), PetscViewerDestroy(), PETSC_VIEWER_SOCKET_(), PetscViewerBinaryWrite(), PetscViewerBinaryRead(), 4615c6c1daeSBarry Smith PetscViewerBinaryWriteStringArray(), PetscBinaryViewerGetDescriptor(), PETSC_VIEWER_MATLAB_() 4625c6c1daeSBarry Smith @*/ 4635c6c1daeSBarry Smith PetscViewer PETSC_VIEWER_SOCKET_(MPI_Comm comm) 4645c6c1daeSBarry Smith { 4655c6c1daeSBarry Smith PetscErrorCode ierr; 4665c6c1daeSBarry Smith PetscBool flg; 4675c6c1daeSBarry Smith PetscViewer viewer; 4685c6c1daeSBarry Smith MPI_Comm ncomm; 4695c6c1daeSBarry Smith 4705c6c1daeSBarry Smith PetscFunctionBegin; 471efca3c55SSatish Balay ierr = PetscCommDuplicate(comm,&ncomm,NULL);if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 4725c6c1daeSBarry Smith if (Petsc_Viewer_Socket_keyval == MPI_KEYVAL_INVALID) { 4735c6c1daeSBarry Smith ierr = MPI_Keyval_create(MPI_NULL_COPY_FN,MPI_NULL_DELETE_FN,&Petsc_Viewer_Socket_keyval,0); 474efca3c55SSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 4755c6c1daeSBarry Smith } 4765c6c1daeSBarry Smith ierr = MPI_Attr_get(ncomm,Petsc_Viewer_Socket_keyval,(void**)&viewer,(int*)&flg); 477efca3c55SSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 4785c6c1daeSBarry Smith if (!flg) { /* PetscViewer not yet created */ 4795c6c1daeSBarry Smith ierr = PetscViewerSocketOpen(ncomm,0,0,&viewer); 480efca3c55SSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 4815c6c1daeSBarry Smith ierr = PetscObjectRegisterDestroy((PetscObject)viewer); 482efca3c55SSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 4835c6c1daeSBarry Smith ierr = MPI_Attr_put(ncomm,Petsc_Viewer_Socket_keyval,(void*)viewer); 484efca3c55SSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 4855c6c1daeSBarry Smith } 4865c6c1daeSBarry Smith ierr = PetscCommDestroy(&ncomm); 487efca3c55SSatish Balay if (ierr) {PetscError(PETSC_COMM_SELF,__LINE__,"PETSC_VIEWER_SOCKET_",__FILE__,PETSC_ERR_PLIB,PETSC_ERROR_INITIAL," ");PetscFunctionReturn(0);} 4885c6c1daeSBarry Smith PetscFunctionReturn(viewer); 4895c6c1daeSBarry Smith } 4905c6c1daeSBarry Smith 491