Main Page Namespace List Class Hierarchy Alphabetical List Compound List File List Namespace Members Compound Members File Members Related Pages

IMDSimThread.C

Go to the documentation of this file.
00001 /***************************************************************************
00002 *cr
00003 *cr (C) Copyright 1995-2019 The Board of Trustees of the
00004 *cr University of Illinois
00005 *cr All Rights Reserved
00006 *cr
00007 ***************************************************************************/
00008 
00009 /***************************************************************************
00010 * RCS INFORMATION:
00011 *
00012 * $RCSfile: IMDSimThread.C,v $
00013 * $Author: johns $ $Locker: $ $State: Exp $
00014 * $Revision: 1.18 $ $Date: 2019年01月17日 21:20:59 $
00015 *
00016 ***************************************************************************
00017 * DESCRIPTION:
00018 * A multithreaded implementation of the interactive MD 
00019 * coordinate/force communication update loop.
00020 ***************************************************************************/
00021 
00022 #include <string.h>
00023 #include <stdio.h>
00024 #include "vmdsock.h"
00025 #include "IMDMgr.h"
00026 #include "IMDSimThread.h"
00027 #include "Inform.h"
00028 #include "utilities.h"
00029 
00030 extern "C" void * imdreaderthread(void *v) {
00031 IMDSimThread *st = (IMDSimThread *)v;
00032 return st->reader(v);
00033 }
00034 
00035 IMDSimThread::IMDSimThread(const char *host, int port) : IMDSim(host, port) { 
00036 curpos = curbuf = posbuf1 = posbuf2 = NULL; 
00037 time2die = 0;
00038 
00039 if (!isConnected())
00040 return;
00041 
00042 deadsocket = 0;
00043 
00044 wkf_mutex_init(&sockmutex);
00045 wkf_mutex_init(&coordmutex);
00046 
00047 if (wkf_thread_create(&readerthread,
00048 imdreaderthread, // my thread routine
00049 this // context for thread
00050 )) {
00051 msgErr << "IMDSimThread: unable to create thread" << sendmsg;
00052 } else {
00053 msgInfo << "Using multithreaded IMD implementation." << sendmsg;
00054 }
00055 }
00056 
00057 IMDSimThread::~IMDSimThread() {
00058 time2die = 1; // time2die is modified here only!!!
00059 void *status;
00060 
00061 if (isConnected()) {
00062 if (wkf_thread_join(readerthread, &status)) {
00063 msgErr << "IMDSimThread: unable to join thread" << sendmsg;
00064 } 
00065 }
00066 delete [] posbuf1;
00067 delete [] posbuf2;
00068 disconnect();
00069 }
00070 
00071 void *IMDSimThread::reader(void *) {
00072 IMDType type;
00073 int32 length;
00074 while (!deadsocket && !time2die) {
00075 if (!vmdsock_selread(sock, 0)) {
00076 vmd_msleep(1);
00077 continue;
00078 }
00079 type = imd_recv_header(sock, &length);
00080 
00081 switch (type) {
00082 case IMD_FCOORDS: process_coordinates(length); break;
00083 case IMD_ENERGIES: process_energies(length); break; 
00084 case IMD_MDCOMM: process_mdcomm(length); break;
00085 case IMD_IOERROR: deadsocket = 1; break;
00086 default: break; // Don't need to read data 
00087 }
00088 }
00089 wkf_mutex_lock(&sockmutex);
00090 disconnect();
00091 wkf_mutex_unlock(&sockmutex);
00092 return NULL;
00093 }
00094 
00095 void IMDSimThread::process_coordinates(int32 length) {
00096 if (numcoords < length) { // Need to resize
00097 delete [] posbuf1;
00098 delete [] posbuf2;
00099 posbuf1 = new float[3L*length];
00100 posbuf2 = new float[3L*length];
00101 curbuf = posbuf1;
00102 curpos = posbuf2; // should I lock?
00103 }
00104 numcoords = length; // should I lock?
00105 
00106 int errcode = imd_recv_fcoords(sock, numcoords, curbuf);
00107 
00108 if (errcode) {
00109 msgErr << "Error reading remote coordinates!" << sendmsg;
00110 deadsocket = 1;
00111 } else {
00112 // swap the buffers and announce that new coordinates are ready
00113 wkf_mutex_lock(&coordmutex);
00114 float *tmp = curpos;
00115 curpos = curbuf;
00116 curbuf = tmp;
00117 new_coords_ready = 1;
00118 wkf_mutex_unlock(&coordmutex);
00119 }
00120 }
00121 
00122 void IMDSimThread::process_energies(int32 /* length */) {
00123 wkf_mutex_lock(&coordmutex);
00124 
00125 int errcode = imd_recv_energies(sock, &imdEnergies);
00126 
00127 if (errcode) { 
00128 msgErr << "Error reading energies!" << sendmsg;
00129 deadsocket = 1;
00130 } else {
00131 if (need2flip) swap4_aligned(&imdEnergies, sizeof(imdEnergies) / 4);
00132 }
00133 
00134 wkf_mutex_unlock(&coordmutex);
00135 }
00136 
00137 // This should never happen, but I'll handle it in case it does
00138 void IMDSimThread::process_mdcomm(int32 length) {
00139 int32 *ind = new int32[length];
00140 float *f = new float[3L*length];
00141 
00142 int errcode = imd_recv_mdcomm(sock, length, ind, f);
00143 
00144 if (errcode) {
00145 msgErr << "Error reading MDComm-style forces!" << sendmsg;
00146 deadsocket = 1;
00147 }
00148 delete [] ind;
00149 delete [] f;
00150 }
00151 
00152 void IMDSimThread::get_next_ts(float *pos, IMDEnergies *buf) {
00153 wkf_mutex_lock(&coordmutex);
00154 memcpy(pos, curpos, 3L*numcoords*sizeof(float));
00155 memcpy(buf, &imdEnergies, sizeof(IMDEnergies));
00156 new_coords_ready = 0;
00157 wkf_mutex_unlock(&coordmutex);
00158 // swap outside of the mutex - yeah baby!
00159 if (need2flip) swap4_aligned(pos, 3L*numcoords);
00160 }
00161 
00162 void IMDSimThread::send_forces(int num, int *ind, float *forces) {
00163 // Total data sent will be one int and three floats for each atom 
00164 if (need2flip) {
00165 swap4_aligned(ind, num);
00166 swap4_aligned(forces, 3L*num);
00167 }
00168 
00169 wkf_mutex_lock(&sockmutex); 
00170 if (isConnected()) {
00171 if (imd_send_mdcomm(sock, num, ind, forces)) {
00172 msgErr << "Error sending MDComm indices+forces" << sendmsg;
00173 deadsocket = 1;
00174 }
00175 }
00176 wkf_mutex_unlock(&sockmutex); 
00177 }
00178 
00179 void IMDSimThread::pause() {
00180 wkf_mutex_lock(&sockmutex); 
00181 if (isConnected() && (getSimState() == IMDRUNNING)) {
00182 simstate = IMDPAUSED;
00183 imd_pause(sock);
00184 }
00185 wkf_mutex_unlock(&sockmutex); 
00186 }
00187 
00188 void IMDSimThread::unpause() {
00189 wkf_mutex_lock(&sockmutex); 
00190 if (isConnected() && (getSimState() == IMDPAUSED)) {
00191 simstate = IMDRUNNING;
00192 imd_pause(sock);
00193 }
00194 wkf_mutex_unlock(&sockmutex);
00195 }
00196 
00197 void IMDSimThread::detach() {
00198 wkf_mutex_lock(&sockmutex); 
00199 if (isConnected()) {
00200 simstate = IMDOFFLINE;
00201 imd_disconnect(sock);
00202 deadsocket = 1;
00203 }
00204 wkf_mutex_unlock(&sockmutex); 
00205 }
00206 
00207 void IMDSimThread::kill() {
00208 wkf_mutex_lock(&sockmutex); 
00209 if (isConnected()) {
00210 simstate = IMDOFFLINE;
00211 imd_kill(sock);
00212 deadsocket = 1;
00213 }
00214 wkf_mutex_unlock(&sockmutex); 
00215 }
00216 
00217 void IMDSimThread::set_transrate(int rate) {
00218 wkf_mutex_lock(&sockmutex); 
00219 if (isConnected()) {
00220 imd_trate(sock, rate);
00221 }
00222 wkf_mutex_unlock(&sockmutex); 
00223 }
00224 

Generated on Mon Nov 17 02:46:18 2025 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002

AltStyle によって変換されたページ (->オリジナル) /