Exemple #1
0
int tclcommand_imd_print_check_connect(Tcl_Interp *interp)
{
  /* handshaking */
  if (vmdsock_selread(initsock, 0) > 0) {
    int32_t length;

    sock = vmdsock_accept(initsock);
    if (imd_handshake(sock)) {
      Tcl_AppendResult(interp, "IMD handshake failed. Wrong VMD version ?",
		       (char *) NULL);
      vmdsock_destroy(sock);
      sock = 0;
      return (TCL_ERROR);
    }

    sleep(1);
    if ((vmdsock_selread(sock, 0) != 1) ||
	(imd_recv_header(sock, &length) != IMD_GO)) {
      Tcl_AppendResult(interp, "No go from VMD. Wrong VMD version ?",
		       (char *) NULL);
      vmdsock_destroy(sock);
      sock = 0;
      return (TCL_ERROR);
    }

    sleep(1);
  }

  return (TCL_OK);
}
int VMDCollab::connect(const char *host, int port) {
  if (clientsock) {
    msgErr << "Already connected to another vmdcollab server" << sendmsg;
    return FALSE;
  }
  if (!(clientsock = vmdsock_create())) {
    msgErr << "Could not create socket." << sendmsg;
    return FALSE;
  }
  int numTries = 3;
  for (int i=0; i<numTries; i++) {
    if (vmdsock_connect(clientsock, host, port)) {
      msgErr << "Could not connect to vmdcollab server at " << host << ":" << port << sendmsg;
      msgErr << "Error: " << strerror(errno) << sendmsg;
    } else {
      // success
      return TRUE;
    }
    // sleep for a second; maybe the server just hasn't started yet
    vmd_sleep(1);
  }
  // failed
  msgErr << "VMDCollab giving up after " << numTries << " seconds." << sendmsg;
  vmdsock_destroy(clientsock);
  clientsock = NULL;
  return FALSE;
}
int VMDCollab::startserver(int port) {
  if (serversock) {
    msgErr << "Already running a server on port " <<  port << sendmsg;
    return FALSE;
  }
  void *serversock = vmdsock_create();
  if (!serversock) {
    msgErr << "Could not create socket." << sendmsg;
    return FALSE;
  }
  if (vmdsock_bind(serversock, port)) {
    msgErr << "Could not bind vmdcollab server to port " << port 
           << sendmsg;
    vmdsock_destroy(serversock);
    return FALSE;
  }
  vmdsock_listen(serversock);

  wkf_thread_t serverthread;
  if (wkf_thread_create(&serverthread,
                        serverproc,    // my thread routine
                        serversock     // context for thread
  )) {
    msgErr << "VMDCollab: unable to create server thread" << sendmsg;
  } else {
    msgInfo << "Starting VMDCollab bounce server." << sendmsg;
  }
  return TRUE;
}
int VMDCollab::check_event() {
  if (!clientsock) return FALSE;
  eval_in_progress = TRUE;
  char buf[VMDCOLLAB_MSGSIZE];
  while (vmdsock_selread(clientsock, 0) > 0) {
    if (imd_readn(clientsock, buf, VMDCOLLAB_MSGSIZE) != VMDCOLLAB_MSGSIZE) {
      vmdsock_shutdown(clientsock);
      vmdsock_destroy(clientsock);
      clientsock = NULL;
      break;
    }
    runcommand(new TclEvalEvent(buf));
  }
  eval_in_progress = FALSE;
  return TRUE;
}
Exemple #5
0
int tclcommand_imd_print_drain_socket(Tcl_Interp *interp)
{
  while (vmdsock_selread(sock,0) > 0)  {
    int32_t length;
    IMDType type = imd_recv_header(sock, &length);
    switch (type) {
    case IMD_MDCOMM:
      /* ignore forces for now */
      Tcl_AppendResult(interp, "IMD force feedback not yet implemented",
		       (char *) NULL);
      return (TCL_ERROR);
      /* Expect the msglength to give number of indicies, and the data
	 message to consist of first the indicies, then the coordinates
	 in xyz1 xyz2... format.
	 int32_t *addindices = new int32_t[length];
	 float *addforces = new float[3*length];

	 if (imd_recv_mdcomm(sock, length, addindices, addforces))
	 throw Error(IOERROR);
	 oversized tmp buffer
	 int32_t *tmpindices = new int32_t[n_atoms + length];
	 float *tmpforces = new float[3*(n_atoms + length)];
	 int32_t tmpatoms = n_atoms;
	 for (int i = 0; i < tmpatoms; i++) {
	 tmpindices[i]      = indices[i];
	 tmpforces[3*i    ] = forces[3*i];
	 tmpforces[3*i + 1] = forces[3*i + 1];
	 tmpforces[3*i + 2] = forces[3*i + 2];
	 }

	 for (int i = 0; i < length; i++) {
	 int32_t index = addindices[i];
	 check if there is a force for this atom already
	 int j;
	 for (j = 0; j < tmpatoms; j++)
	 if (tmpindices[j] == index)
	 break;
	 if (j == tmpatoms) {
	 tmpindices[j] = index;
	 tmpatoms++;
	 }
	 tmpforces[3*j    ] = addforces[3*i    ];
	 tmpforces[3*j + 1] = addforces[3*i + 1];
	 tmpforces[3*j + 2] = addforces[3*i + 2];
	 }
	 if (n_atoms > 0) {
	 delete[] indices;
	 delete[] forces;
	 }
	 n_atoms = tmpatoms;
	 indices = new int32_t[n_atoms];
	 forces  = new float[3*n_atoms];
	 cout << "now forces are" << endl;
	 for (int i = 0; i < n_atoms; i++) {
	 indices[i] = tmpindices[i];
	 forces[3*i    ] = tmpforces[3*i];
	 forces[3*i + 1] = tmpforces[3*i + 1];
	 forces[3*i + 2] = tmpforces[3*i + 2];
	 
	 cout << indices[i] << " force "
	 << forces[3*i    ] << " "
	 << forces[3*i + 1] << " "
	 << forces[3*i + 2] << endl;
	 
	 }
	 cout << "end" << endl;
	 */
      break;
    case IMD_TRATE:
      transfer_rate = length;
      break;
    case IMD_IOERROR:
      vmdsock_destroy(sock);
      sock = 0;
      Tcl_AppendResult(interp, "IMD reports IO error",
		       (char *) NULL);
      return (TCL_ERROR);
    case IMD_DISCONNECT:
    case IMD_KILL:
      vmdsock_destroy(sock);
      sock = 0;
      Tcl_AppendResult(interp, "no connection",
		       (char *) NULL);
      return (TCL_OK);
    case IMD_ENERGIES:
    case IMD_FCOORDS:
      Tcl_AppendResult(interp, "IMD protocol failure: unexpected token.",
		       (char *) NULL);
      return (TCL_ERROR);
      break;
    default: ;
    }
  }
  return (TCL_OK);
}
Exemple #6
0
int tclcommand_imd(ClientData data, Tcl_Interp *interp,
	int argc, char **argv)
{
  if (argc < 2) {
    Tcl_AppendResult(interp, "wrong # args:  should be \"",
		     argv[0], " connect|disconnect|listen|positions|energies ?values?\"",
		     (char *) NULL);
    return (TCL_ERROR);
  }

  if (ARG1_IS_S("connect")) {
    /* connect to vmd */
    int port = 12346;

    if (argc > 3) {
      Tcl_AppendResult(interp, "wrong # args:  should be \"",
		       argv[0], " connect ?port?\"",
		       (char *) NULL);
      return (TCL_ERROR);
    }
    if (argc == 3)
      if (!ARG_IS_I(2, port))
	return (TCL_ERROR);

    if (sock)
      vmdsock_destroy(sock);
    if (initsock)
      vmdsock_destroy(initsock);
    sock = 0;
    initsock = 0;

    vmdsock_init();
    initsock = vmdsock_create();
    if (vmdsock_bind(initsock, port) != 0) {
      Tcl_AppendResult(interp, "IMD bind failed. Port already in use ?",
		       (char *) NULL);
      vmdsock_destroy(initsock);
      initsock = 0;
      return (TCL_ERROR);
    }

    if (vmdsock_listen(initsock)) {
      Tcl_AppendResult(interp, "IMD listen failed. Port already in use ?",
		       (char *) NULL);
      vmdsock_destroy(initsock);
      initsock = 0;
      return (TCL_ERROR);
    }

    return (TCL_OK);
  }
  if (ARG1_IS_S("disconnect")) {
    if (argc > 2) {
      Tcl_AppendResult(interp, "wrong # args:  should be \"",
		       argv[0], " disconnect\"",
		       (char *) NULL);
      return (TCL_ERROR);
    }

    if (sock)
      vmdsock_destroy(sock);
    if (initsock)
      vmdsock_destroy(initsock);
    sock = 0;
    initsock = 0;

    Tcl_AppendResult(interp, "no connection",
		     (char *) NULL);
    return (TCL_OK);
  }

  if (ARG1_IS_S("listen")) {
    /* wait until vmd connects */
    int cnt = 3600;
    
    if (argc != 3) {
      Tcl_AppendResult(interp, "wrong # args:  should be \"",
		       argv[0], " listen <secs>\"",
		       (char *) NULL);
      return (TCL_ERROR);
    } 
   
    if (!ARG_IS_I(2, cnt))
      return (TCL_ERROR);

    while (initsock && !sock && cnt--) {
      if (tclcommand_imd_print_check_connect(interp) == TCL_ERROR)
	return (TCL_ERROR);
      sleep(1);
    }

    if (!sock)
      Tcl_AppendResult(interp, "no connection",
		       (char *) NULL);
    else {
      if (tclcommand_imd_print_drain_socket(interp) == TCL_ERROR)
	return (TCL_ERROR);
      Tcl_AppendResult(interp, "connected",
		       (char *) NULL);
    }
    return (TCL_OK);
  }

  if (ARG1_IS_S("positions")) 
    return tclcommand_imd_parse_pos(interp, argc, argv);
  
  if (ARG1_IS_S("energies")) {
    Tcl_AppendResult(interp, "Sorry. imd energies not yet implemented",
		     (char *) NULL);
    return (TCL_ERROR);      
  }

  Tcl_AppendResult(interp, "imd: unkown job.",
		   (char *) NULL);
  return (TCL_ERROR);      
}
void *VMDCollab::serverproc(void *serversock) {

  ResizeArray<void *>clients;
  char buf[VMDCOLLAB_MSGSIZE];
  int i, j;
  
  while (1) {
    // if we have no clients, hang until someone connects
    // otherwise, just check for pending connections
    if (vmdsock_selread(serversock, 0) > 0) {
      msgInfo << "serversock became readable" << sendmsg;
      void *clientsock = vmdsock_accept(serversock);
      if (clientsock) {
        msgInfo << "VMDCollab accepting connection" << sendmsg;
        clients.append(clientsock);
      }
    } else if (vmdsock_selwrite(serversock, 0)) {
      msgInfo << "serversock became writable; exiting..." << sendmsg;
      break;
    }

    // Loop through one socket at a time.  If incoming data is found,
    // drain it before moving on, on the assumption that we only want
    // commands from one VMD at a time to be propagated to the other
    // clients.
    for (i=0; i<clients.num(); i++) {
      void *client = clients[i];
      while (vmdsock_selread(client, 0) > 0) {
        memset(buf, 0, VMDCOLLAB_MSGSIZE);
        if (imd_readn(client, buf, VMDCOLLAB_MSGSIZE) != VMDCOLLAB_MSGSIZE) {
          msgInfo << "client sent incomplete message, shutting it down"
                  << sendmsg;
          vmdsock_shutdown(client);
          vmdsock_destroy(client);
          clients.remove(clients.find(client));
          break;
        }
        // send to all other clients
        for (j=0; j<clients.num(); j++) {
          void *dest = clients[j];
          if (dest != client) {
            imd_writen(clients[j], buf, VMDCOLLAB_MSGSIZE);
          }
        } // loop over clients other than sender
      } // while client is readable
    } // loop over clients
    vmd_msleep(10);
  }
  // if here, then the serversock got shut down, indicating that it's
  // time to die.
  msgInfo << "VMDCollab shutting down server" << sendmsg;
  for (i=0; i<clients.num(); i++) {
    void *client = clients[i];
    strcpy(buf, "exit");
    imd_writen(client, buf, VMDCOLLAB_MSGSIZE);
    vmdsock_shutdown(client);
    vmdsock_destroy(client);
  }
  vmdsock_destroy(serversock);
  return NULL;
}
void VMDCollab::disconnect() {
  if (!clientsock) return;
  vmdsock_shutdown(clientsock);
  vmdsock_destroy(clientsock);
  clientsock = NULL;
}
Exemple #9
0
void IMD::receive(){

  if(!connected) return;

  if(clientsock){
    IMDType type;
    int length;
    int itype;
    while (vmdsock_selread(clientsock,0) > 0) {
      type = imd_recv_header(clientsock, &length);
      if(type==IMD_MDCOMM){
        int32* vmd_atoms = new int32[length];
        float* vmd_forces = new float[3*length];
        imd_recv_mdcomm(clientsock, length, vmd_atoms, vmd_forces);
        for(int i=0;i<length;i++){
          forces[3*vmd_atoms[i]+0]=vmd_forces[3*i+0];
          forces[3*vmd_atoms[i]+1]=vmd_forces[3*i+1];
          forces[3*vmd_atoms[i]+2]=vmd_forces[3*i+2];
        }
        delete [] vmd_atoms;
        delete [] vmd_forces;
        itype=0;
        comm.Bcast(&itype,1,0);
        comm.Bcast(&forces[0],forces.size(),0);
      }else if(type==IMD_DISCONNECT){
        vmdsock_destroy(clientsock);
        clientsock=NULL;
        for(unsigned i=0;i<forces.size();i++) forces[i]=0.0;
        connected=false;
        itype=1;
        comm.Bcast(&itype,1,0);
        break;
      }else if(type==IMD_TRATE){
        if(length<1) length=1;
        itype=2;
        log.printf("IMD: setting transfer rate to %d\n",length);
        transferRate=length;
        comm.Bcast(&itype,1,0);
        comm.Bcast(&transferRate,1,0);
      }else if(type==IMD_KILL){
        log.printf("IMD: killing simulation\n");
        itype=3;
        comm.Bcast(&itype,1,0);
        plumed.exit();
      }
    }
    itype=-1;
    comm.Bcast(&itype,1,0);
  }

  if(comm.Get_rank()!=0){
    int itype;
    while(true){
      comm.Bcast(&itype,1,0);
      if(itype==-1)break;
      else if(itype==0) comm.Bcast(&forces[0],forces.size(),0);
      else if(itype==1) {
        for(unsigned i=0;i<forces.size();i++) forces[i]=0.0;
        connected=false;
      }
      else if(itype==2) comm.Bcast(&transferRate,1,0);
      else if(itype==3) plumed.exit();
      else plumed_error();
    }
  }

}