hdiff output

r29015/amber12_interface.F90 2015-11-17 23:33:09.136627281 +0000 r29014/amber12_interface.F90 2015-11-17 23:33:14.712702061 +0000
250: #ifdef CUDA250: #ifdef CUDA
251:   call gpu_setup_system(natom, imin, tol, ntf, ntb, ips, ntp, ntt, vrand)251:   call gpu_setup_system(natom, imin, tol, ntf, ntb, ips, ntp, ntt, vrand)
252:   call gpu_upload_crd(atm_crd)252:   call gpu_upload_crd(atm_crd)
253:   call gpu_upload_charges(atm_qterm)253:   call gpu_upload_charges(atm_qterm)
254:   call gpu_upload_masses(atm_mass)254:   call gpu_upload_masses(atm_mass)
255:   call gpu_upload_frc(atm_frc)255:   call gpu_upload_frc(atm_frc)
256:   call gpu_upload_vel(atm_vel)256:   call gpu_upload_vel(atm_vel)
257:   call gpu_upload_last_vel(atm_last_vel)257:   call gpu_upload_last_vel(atm_last_vel)
258:   call gpu_init_extra_pnts_nb14(gbl_frame_cnt, ep_frames, ep_lcl_crd)258:   call gpu_init_extra_pnts_nb14(gbl_frame_cnt, ep_frames, ep_lcl_crd)
259:   call gpu_constraints_setup(natc, atm_jrc, atm_weight, atm_xc)259:   call gpu_constraints_setup(natc, atm_jrc, atm_weight, atm_xc)
260:   call gminoptim_copy_const()260:   call gmin_copy_const()
261: #endif261: #endif
262: 262: 
263: ! The following call does more uniprocessor setup and mpi master/slave setup.263: ! The following call does more uniprocessor setup and mpi master/slave setup.
264: 264: 
265:   if (using_pme_potential) then265:   if (using_pme_potential) then
266:     call pme_alltasks_setup(num_ints, num_reals)266:     call pme_alltasks_setup(num_ints, num_reals)
267:   else if (using_gb_potential) then267:   else if (using_gb_potential) then
268:     call gb_alltasks_setup(num_ints, num_reals)268:     call gb_alltasks_setup(num_ints, num_reals)
269:   end if269:   end if
270: 270: 


r29015/amber_potential.cu 2015-11-17 23:33:11.600660325 +0000 r29014/amber_potential.cu 2015-11-17 23:33:17.176735110 +0000
 11: AmberPotential::AmberPotential(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas,  11: AmberPotential::AmberPotential(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas, 
 12:                 size_t numDimensions, int nDegFreedom, int nRigidBody, int rigidMaxSite,  12:                 size_t numDimensions, int nDegFreedom, int nRigidBody, int rigidMaxSite, 
 13:                 int *nRigidSitesPerBody, int *rigidGroups, double *sitesRigidBody, int *rigidSingles,  13:                 int *nRigidSitesPerBody, int *rigidGroups, double *sitesRigidBody, int *rigidSingles, 
 14:                 double *rigidInverse, double *x, int nSecDiag, bool isAtomisticNotRigid,  14:                 double *rigidInverse, double *x, int nSecDiag, bool isAtomisticNotRigid, 
 15:                 double aaConvThreshold, double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen,  15:                 double aaConvThreshold, double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen, 
 16:                 int nFreeze) 16:                 int nFreeze)
 17:         : CostFunction(debugPrinting, timer_potential, cublas, numDimensions, nDegFreedom, nRigidBody, rigidMaxSite,  17:         : CostFunction(debugPrinting, timer_potential, cublas, numDimensions, nDegFreedom, nRigidBody, rigidMaxSite, 
 18:                         nRigidSitesPerBody, rigidGroups, sitesRigidBody, rigidSingles, rigidInverse, x, nSecDiag,  18:                         nRigidSitesPerBody, rigidGroups, sitesRigidBody, rigidSingles, rigidInverse, x, nSecDiag, 
 19:                         isAtomisticNotRigid, aaConvThreshold, coldFusionLim, shouldFreeze, isAtomFrozen, nFreeze) {} 19:                         isAtomisticNotRigid, aaConvThreshold, coldFusionLim, shouldFreeze, isAtomFrozen, nFreeze) {}
 20:  20: 
 21:  
 22:  
 23: void AmberPotential::computeEnergyAndGradient(const double *d_x, double *d_f, double *d_gradf) 21: void AmberPotential::computeEnergyAndGradient(const double *d_x, double *d_f, double *d_gradf)
 24: { 22: {
 25:         double testEnergy; 23:         double testEnergy;
 26:  24: 
 27:         // Copy coordinates to correct location in device memory.  25:         // Copy coordinates to correct location in device memory. 
 28:         gminoptim_copy_crd(d_x); 26:         gmin_copy_crd(d_x);
 29:         CudaCheckError(); 27:         CudaCheckError();
 30:         cudaDeviceSynchronize(); 28:         cudaDeviceSynchronize();
 31:  29: 
 32:         // Energy calculation.  30:         // Energy calculation. 
 33:         gminoptim_gpu_energy(d_f); 31:         gmin_gpu_energy(d_f);
 34:         CudaCheckError(); 32:         CudaCheckError();
 35:         cudaDeviceSynchronize(); 33:         cudaDeviceSynchronize();
 36:  34: 
 37:         // Copy forces back.  35:         // Copy forces back. 
 38:         gminoptim_copy_frc(d_gradf); 36:         gmin_copy_frc(d_gradf);
 39:         CudaCheckError(); 37:         CudaCheckError();
 40:         cudaDeviceSynchronize(); 38:         cudaDeviceSynchronize();
 41:  39: 
 42:         CudaSafeCall( cudaMemcpy(&testEnergy, d_f, sizeof(double), cudaMemcpyDeviceToHost) ); 40:         CudaSafeCall( cudaMemcpy(&testEnergy, d_f, sizeof(double), cudaMemcpyDeviceToHost) );
 43:         // Test for cold fusion.  41:         // Test for cold fusion. 
 44:         if (testEnergy < m_coldFusionLim) { 42:         if (testEnergy < m_coldFusionLim) {
 45:                 m_isColdFusion = true; 43:                 m_isColdFusion = true;
 46:         } 44:         }
 47: } 45: }


r29015/bfgsts.cu 2015-11-17 23:33:10.088640047 +0000 r29014/bfgsts.cu 2015-11-17 23:33:15.668714882 +0000
 24:         , m_maxEvecStep(maxEvecStep) 24:         , m_maxEvecStep(maxEvecStep)
 25:         , m_maxMaxStep(maxMaxStep) 25:         , m_maxMaxStep(maxMaxStep)
 26:         , m_minMaxStep(minMaxStep) 26:         , m_minMaxStep(minMaxStep)
 27:         , m_trustRadius(trustRadius) 27:         , m_trustRadius(trustRadius)
 28:         , m_pMaxIter1(pMaxIter1) 28:         , m_pMaxIter1(pMaxIter1)
 29:         , m_pMaxIter2(pMaxIter2) 29:         , m_pMaxIter2(pMaxIter2)
 30:         , m_bItMax(bItMax) 30:         , m_bItMax(bItMax)
 31:           , m_evecOverlapTol(evecOverlapTol) 31:           , m_evecOverlapTol(evecOverlapTol)
 32:           , m_evStepMagTol(evStepMagTol) {} 32:           , m_evStepMagTol(evStepMagTol) {}
 33:  33: 
 34:  
 35:  
 36: std::string Bfgsts::statusToString(Bfgsts::bStatus bfgstsStatus) 34: std::string Bfgsts::statusToString(Bfgsts::bStatus bfgstsStatus)
 37: { 35: {
 38:         switch (bfgstsStatus) { 36:         switch (bfgstsStatus) {
 39:                 case BFGSTS_CONVERGED_TO_TS : 37:                 case BFGSTS_CONVERGED_TO_TS :
 40:                         return "Converged to a transition state of Hessian index 1"; 38:                         return "Converged to a transition state of Hessian index 1";
 41:                 case BFGSTS_REACHED_MAX_ITER : 39:                 case BFGSTS_REACHED_MAX_ITER :
 42:                         return "Reached maximum number of iterations"; 40:                         return "Reached maximum number of iterations";
 43:                 case BFGSTS_COLD_FUSION_DIAGNOSED : 41:                 case BFGSTS_COLD_FUSION_DIAGNOSED :
 44:                         return "Cold fusion diagnosed"; 42:                         return "Cold fusion diagnosed";
 45:                 default : 43:                 default :
 46:                         return "Unknown status"; 44:                         return "Unknown status";
 47:         } 45:         }
 48: } 46: }
 49:  47: 
 50:  
 51:  
 52: Bfgsts::bStatus Bfgsts::findTs(double *d_coords, double *d_evec, double *energy, double *evalMin, double *outRms, int *itDone) 48: Bfgsts::bStatus Bfgsts::findTs(double *d_coords, double *d_evec, double *energy, double *evalMin, double *outRms, int *itDone)
 53: { 49: {
 54:         bool printingOn = m_debugPrinting.getPrintingOn(); 50:         bool printingOn = m_debugPrinting.getPrintingOn();
 55:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle(); 51:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();
 56:  52: 
 57:         bool isTimingTotal = m_timer_total.getTimingOn(); 53:         bool isTimingTotal = m_timer_total.getTimingOn();
 58:         bool isTimingSteps = m_timer_eFolSteps.getTimingOn(); 54:         bool isTimingSteps = m_timer_eFolSteps.getTimingOn();
 59:  55: 
 60:         if (isTimingTotal) { 56:         if (isTimingTotal) {
 61:                 m_timer_total.start(); 57:                 m_timer_total.start();
 83:         double *xRms = new double; 79:         double *xRms = new double;
 84:         int *xItDone = new int; 80:         int *xItDone = new int;
 85:         int *pItDone = new int; 81:         int *pItDone = new int;
 86:  82: 
 87:         double efStepMag   = 0.0; 83:         double efStepMag   = 0.0;
 88:         double evecOverlap = 0.0; 84:         double evecOverlap = 0.0;
 89:         bool isNegativeEv  = false; 85:         bool isNegativeEv  = false;
 90:  86: 
 91:         m_costFunction.setIsRayleighRitz(false); 87:         m_costFunction.setIsRayleighRitz(false);
 92:         m_costFunction.basePotential(d_coords, d_energy, d_gradient); 88:         m_costFunction.basePotential(d_coords, d_energy, d_gradient);
  89:         CudaCheckError();
  90:         cudaDeviceSynchronize();
 93:  91: 
 94:         m_costFunction.calculateRms(d_gradient, outRms); 92:         m_costFunction.calculateRms(d_gradient, outRms);
 95:  93: 
 96:         m_costFunction.setDevEnergy(d_energy); 94:         m_costFunction.setDevEnergy(d_energy);
 97:         m_costFunction.setDevGradient(d_gradient); 95:         m_costFunction.setDevGradient(d_gradient);
 98:  96: 
 99:         m_costFunction.freeze(d_evec); 97:         m_costFunction.freeze(d_evec);
100:  98: 
101:         *xItDone = 0; 99:         *xItDone = 0;
102:         *pItDone = 0;100:         *pItDone = 0;
103: 101: 
104:         size_t it = 1;102:         size_t it = 1;
105:         for (it = 1; it <= m_bItMax; ++it) {103:         for (it = 1; it <= m_bItMax; ++it) {
106: 104:                 if (printingOn) {
107:                 fileHandle << std::endl;105:                         fileHandle << std::endl;
108:                 fileHandle << " Beginning of optimization cycle " << it << "." << std::endl;106:                         fileHandle << " Beginning of optimization cycle " << it << "." << std::endl;
109:                 fileHandle << " -------------------------------" << std::endl;107:                         fileHandle << " -------------------------------" << std::endl;
 108:                 }
110: 109: 
111:                 bool isFirstIter = (it == 1);110:                 bool isFirstIter = (it == 1);
112: 111: 
113:                 CudaSafeCall( cudaMemcpy(d_evecOld, d_evec, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );112:                 CudaSafeCall( cudaMemcpy(d_evecOld, d_evec, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );
114: 113: 
115:                 // True if we are minimizing Rayleigh-Ritz ratio and want to calculate secdiag. 114:                 // True if we are minimizing Rayleigh-Ritz ratio and want to calculate secdiag. 
116:                 m_costFunction.setIsRayleighRitz(true);115:                 m_costFunction.setIsRayleighRitz(true);
117:                 fileHandle << " Lowest eigenvector search (Rayleigh-Ritz):" << std::endl;116:                 if (printingOn) {
 117:                         fileHandle << " Lowest eigenvector search (Rayleigh-Ritz):" << std::endl;
 118:                 }
118:                 // Perform the minimization. 119:                 // Perform the minimization. 
119:                 xLbfgsStatus = m_xLbfgs.minimize(d_evec, d_evalMin, d_xGrad, xRms, xItDone);120:                 xLbfgsStatus = m_xLbfgs.minimize(d_evec, d_evalMin, d_xGrad, xRms, xItDone);
120: 121: 
121:                 CudaSafeCall( cudaMemcpy(evalMin, d_evalMin, sizeof(double), cudaMemcpyDeviceToHost) );122:                 CudaSafeCall( cudaMemcpy(evalMin, d_evalMin, sizeof(double), cudaMemcpyDeviceToHost) );
122: 123: 
123:                 bool isEvTooSmall = (abs(*evalMin) < 1.0e-100);124:                 bool isEvTooSmall = (abs(*evalMin) < 1.0e-100);
124:                 if (isEvTooSmall) {125:                 if (isEvTooSmall) {
125:                         if (*evalMin >= 0) {126:                         if (*evalMin >= 0) {
126:                                 *evalMin = 1.0e-20;127:                                 *evalMin = 1.0e-20;
127:                         }128:                         }
128:                         else {129:                         else {
129:                                 *evalMin = -1.0e-20;130:                                 *evalMin = -1.0e-20;
130:                         }131:                         }
131:                 }132:                 }
132: 133: 
133:                 isNegativeEv = (*evalMin < 0.0);134:                 isNegativeEv = (*evalMin < 0.0);
134: 135: 
135:                 if (isFirstIter && !isNegativeEv) {136:                 if (isFirstIter && !isNegativeEv && printingOn) {
136:                         fileHandle << " Warning: initial eigenvalue is positive - increase NEBK?" << std::endl;137:                         fileHandle << " Warning: initial eigenvalue is positive - increase NEBK?" << std::endl;
137:                 }138:                 }
138: 139: 
139:                 bool isxLbfgsConverged = (xLbfgsStatus == Lbfgs::LBFGS_CONVERGED);140:                 bool isxLbfgsConverged = (xLbfgsStatus == Lbfgs::LBFGS_CONVERGED);
140: 141: 
141:                 m_cublas.dispatchDot(numDimensions, &evecOverlap, d_evec, d_evecOld, false); // evecOverlap = evec Dot evecOld142:                 m_cublas.dispatchDot(numDimensions, &evecOverlap, d_evec, d_evecOld, false);
142:                 if (isxLbfgsConverged) {143:                 if (printingOn) {
143:                         fileHandle << " Smallest eigenvalue converged in " << std::setw(7) << *xItDone << " steps" 144:                         if (isxLbfgsConverged) {
144:                                 << std::endl; 145:                                 fileHandle << " Smallest eigenvalue converged in " << std::setw(7) << *xItDone << " steps" 
145:                 }146:                                         << std::endl; 
146:                 else {147:                         }
147:                         fileHandle << " Warning: smallest eigenvalue did not converge" << std::endl;148:                         else {
 149:                                 fileHandle << " Warning: smallest eigenvalue did not converge" << std::endl;
 150:                         }
148:                 }151:                 }
149: 152: 
150:                 m_costFunction.freeze(d_evec);153:                 m_costFunction.freeze(d_evec);
151: 154: 
152:                 if (isTimingSteps) {155:                 if (isTimingSteps) {
153:                         m_timer_eFolSteps.start();156:                         m_timer_eFolSteps.start();
154:                 }157:                 }
155: 158: 
156:                 m_pLbfgs.setDevzWork(d_evec, numDimensions);159:                 m_pLbfgs.setDevzWork(d_evec, numDimensions);
157: 160: 
164: 167: 
165:                 bool isOverlap = ((1.0 - abs(evecOverlap)) <= m_evecOverlapTol);168:                 bool isOverlap = ((1.0 - abs(evecOverlap)) <= m_evecOverlapTol);
166:                 if (!isFirstIter && isOverlap && isNegativeEv) {169:                 if (!isFirstIter && isOverlap && isNegativeEv) {
167:                         m_pLbfgs.setMaxIterations(m_pMaxIter2);170:                         m_pLbfgs.setMaxIterations(m_pMaxIter2);
168:                 }171:                 }
169:                 else {172:                 else {
170:                         m_pLbfgs.setMaxIterations(m_pMaxIter1);173:                         m_pLbfgs.setMaxIterations(m_pMaxIter1);
171:                 }174:                 }
172: 175: 
173:                 m_costFunction.setIsRayleighRitz(false);176:                 m_costFunction.setIsRayleighRitz(false);
174:                 fileHandle << " Minimization perpendicular to lowest eigenvector:" << std::endl;177:                 if (printingOn) {
 178:                         fileHandle << " Minimization perpendicular to lowest eigenvector:" << std::endl;
 179:                 }
175:                 bool shouldReset = false;180:                 bool shouldReset = false;
176:                 // Perform minimization, projecting out uphill components of gradient along eigenvector.181:                 // Perform minimization, projecting out uphill components of gradient along eigenvector.
177:                 pLbfgsStatus = m_pLbfgs.minimize(d_coords, d_energy, d_gradient, outRms, pItDone, shouldReset);182:                 pLbfgsStatus = m_pLbfgs.minimize(d_coords, d_energy, d_gradient, outRms, pItDone, shouldReset);
178: 183: 
179:                 fileHandle << " True RMS grad = " << std::setw(15) << std::setprecision(7) << *outRms << std::endl;184:                 if (printingOn) {
 185:                         fileHandle << " True RMS grad = " << std::setw(15) << std::setprecision(7) << *outRms << std::endl;
 186:                 }
180: 187: 
181:                 bool ispLbfgsConverged  = (pLbfgsStatus == Lbfgs::LBFGS_CONVERGED);188:                 bool ispLbfgsConverged  = (pLbfgsStatus == Lbfgs::LBFGS_CONVERGED);
182:                 bool ispLbfgsColdFusion = (pLbfgsStatus == Lbfgs::LBFGS_COLD_FUSION_DIAGNOSED);189:                 bool ispLbfgsColdFusion = (pLbfgsStatus == Lbfgs::LBFGS_COLD_FUSION_DIAGNOSED);
183:                 bool isEfStepConverged  = (efStepMag <= m_evStepMagTol);190:                 bool isEfStepConverged  = (efStepMag <= m_evStepMagTol);
184:                 if (ispLbfgsConverged && isNegativeEv && isEfStepConverged) {191:                 if (ispLbfgsConverged && isNegativeEv && isEfStepConverged) {
185:                         bfgstsStatus = BFGSTS_CONVERGED_TO_TS;192:                         bfgstsStatus = BFGSTS_CONVERGED_TO_TS;
186:                         break;193:                         break;
187:                 }194:                 }
188:                 else if (ispLbfgsColdFusion) {195:                 else if (ispLbfgsColdFusion) {
189:                         bfgstsStatus = BFGSTS_COLD_FUSION_DIAGNOSED;196:                         bfgstsStatus = BFGSTS_COLD_FUSION_DIAGNOSED;
190:                         break;197:                         break;
191:                 }198:                 }
192:         }199:         }
193: 200: 
194:         *itDone = it;201:         *itDone = it;
195: 202: 
196:         CudaSafeCall( cudaMemcpy(energy, d_energy, sizeof(double), cudaMemcpyDeviceToHost) );203:         CudaSafeCall( cudaMemcpy(energy, d_energy, sizeof(double), cudaMemcpyDeviceToHost) );
197: 204: 
198:         fileHandle << std::endl; 
199:         fileHandle << " Reason for termination: " << statusToString(bfgstsStatus) << std::endl;205:         fileHandle << " Reason for termination: " << statusToString(bfgstsStatus) << std::endl;
200:         fileHandle << std::endl;206:         fileHandle << std::endl;
201: 207: 
202:         delete xItDone;208:         delete xItDone;
203:         delete pItDone;209:         delete pItDone;
204:         delete xRms;210:         delete xRms;
205: 211: 
206:         CudaSafeCall( cudaFree(d_evecOld) );212:         CudaSafeCall( cudaFree(d_evecOld) );
207:         CudaSafeCall( cudaFree(d_energy) );213:         CudaSafeCall( cudaFree(d_energy) );
208:         CudaSafeCall( cudaFree(d_evalMin) );214:         CudaSafeCall( cudaFree(d_evalMin) );
209:         CudaSafeCall( cudaFree(d_gradient) );215:         CudaSafeCall( cudaFree(d_gradient) );
210:         CudaSafeCall( cudaFree(d_xGrad) );216:         CudaSafeCall( cudaFree(d_xGrad) );
211: 217: 
212:         if (isTimingTotal) {218:         if (isTimingTotal) {
213:                 m_timer_total.stop();219:                 m_timer_total.stop();
214:         }220:         }
215: 221: 
216:         return bfgstsStatus;222:         return bfgstsStatus;
217: }223: }
218: 224: 
219:  
220:  
221: void Bfgsts::stepUphill(double *d_coords, const double *d_evec, const double *evalMin, double *d_energy, double *d_gradient, 225: void Bfgsts::stepUphill(double *d_coords, const double *d_evec, const double *evalMin, double *d_energy, double *d_gradient, 
222:                 const bool isxLbfgsConverged, const bool &isNegativeEv, double &efStepMag, double *outRms, size_t it)226:                 const bool isxLbfgsConverged, const bool &isNegativeEv, double &efStepMag, double *outRms, size_t it)
223: {227: {
224:         bool printingOn = m_debugPrinting.getPrintingOn();228:         bool printingOn = m_debugPrinting.getPrintingOn();
225:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();229:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();
226: 230: 
227:         const size_t numDimensions = m_costFunction.getNumDimensions();231:         const size_t numDimensions = m_costFunction.getNumDimensions();
228: 232: 
229:         double fob;233:         double fob;
230:         double efStep;234:         double efStep;
231:         double trustRatio;235:         double trustRatio;
232: 236: 
233:         m_cublas.dispatchDot(numDimensions, &fob, d_evec, d_gradient, false); // fob = evec Dot gradient237:         m_cublas.dispatchDot(numDimensions, &fob, d_evec, d_gradient, false);
234: 238: 
235:         bool shouldStepAway = false;239:         bool shouldStepAway = false;
236:         bool couldPushoff = (*outRms < m_pushOffCut);240:         bool couldPushoff = (*outRms < m_pushOffCut);
237:         if (couldPushoff && !isNegativeEv && isxLbfgsConverged) {241:         if (couldPushoff && !isNegativeEv && isxLbfgsConverged) {
238:                 bool isFirstIter = (it == 1);242:                 bool isFirstIter = (it == 1);
239:                 bool isIterMultipleOfFour = ((it - 1) % 4 == 0);243:                 bool isIterMultipleOfFour = ((it - 1) % 4 == 0);
240:                 if (isFirstIter) {244:                 if (isFirstIter) {
241:                         fileHandle << " Stepping away from minimum along softest mode + direction" << std::endl;245:                         if (printingOn) {
 246:                                 fileHandle << " Stepping away from minimum along softest mode + direction" << std::endl;
 247:                         }
242:                         shouldStepAway = true;248:                         shouldStepAway = true;
243:                 }249:                 }
244:                 else if (isIterMultipleOfFour) {250:                 else if (isIterMultipleOfFour) {
245:                         fileHandle << " Stepping away from solution of wrong index" << std::endl;251:                         if (printingOn) {
 252:                                 fileHandle << " Stepping away from solution of wrong index" << std::endl;
 253:                         }
246:                         if (m_pushOffMag != 0.0) {254:                         if (m_pushOffMag != 0.0) {
247:                                 fob = m_pushOffMag;255:                                 fob = m_pushOffMag;
248:                         }256:                         }
249:                         else {257:                         else {
250:                                 fob = m_maxEvecStep;258:                                 fob = m_maxEvecStep;
251:                         }259:                         }
252:                 }260:                 }
253:         }261:         }
254: 262: 
255:         double xp1 = abs(*evalMin)/2.0;263:         double xp1 = abs(*evalMin)/2.0;
270: 278: 
271:         if (!shouldStepAway) {279:         if (!shouldStepAway) {
272:                 double scale = std::min(m_maxEvecStep/std::max(abs(efStep),1.0e-10),1.0);280:                 double scale = std::min(m_maxEvecStep/std::max(abs(efStep),1.0e-10),1.0);
273:                 efStep = scale*efStep;281:                 efStep = scale*efStep;
274:         }282:         }
275: 283: 
276:         if (isxLbfgsConverged && !isNegativeEv) {284:         if (isxLbfgsConverged && !isNegativeEv) {
277:                 efStep = fob*m_maxMaxStep/abs(fob);285:                 efStep = fob*m_maxMaxStep/abs(fob);
278:         }286:         }
279: 287: 
280:         fileHandle << " EF step uphill of magnitude " << efStepMag << " is taken" << std::endl;288:         if (printingOn) {
 289:                 fileHandle << " EF step uphill of magnitude " << efStepMag << " is taken" << std::endl;
 290:         }
281:         // Take step uphill along the lowest eigenvector. 291:         // Take step uphill along the lowest eigenvector. 
282:         m_cublas.dispatchAxpy(numDimensions, d_coords, d_coords, d_evec, &efStep, false); // coords += evec*efStep292:         m_cublas.dispatchAxpy(numDimensions, d_coords, d_coords, d_evec, &efStep, false);
283: 293: 
284:         double eOld;294:         double eOld;
285:         CudaSafeCall( cudaMemcpy(&eOld, d_energy, sizeof(double), cudaMemcpyDeviceToHost) );295:         CudaSafeCall( cudaMemcpy(&eOld, d_energy, sizeof(double), cudaMemcpyDeviceToHost) );
286: 296: 
287:         m_costFunction.setIsRayleighRitz(false);297:         m_costFunction.setIsRayleighRitz(false);
288:         m_costFunction.basePotential(d_coords, d_energy, d_gradient);298:         m_costFunction.basePotential(d_coords, d_energy, d_gradient);
 299:         CudaCheckError();
 300:         cudaDeviceSynchronize();
289: 301: 
290:         m_costFunction.calculateRms(d_gradient, outRms);302:         m_costFunction.calculateRms(d_gradient, outRms);
291: 303: 
292:         double fobNew;304:         double fobNew;
293:         m_cublas.dispatchDot(numDimensions, &fobNew, d_evec, d_gradient, false); // fobNew = evec Dot gradient305:         m_cublas.dispatchDot(numDimensions, &fobNew, d_evec, d_gradient, false);
294: 306: 
295:         bool isZeroEnergy = (eOld == 0.0);307:         bool isZeroEnergy = (eOld == 0.0);
296:         if (!isZeroEnergy && isNegativeEv) {308:         if (!isZeroEnergy && isNegativeEv) {
297:                 double predictedEv = fobNew - fob;309:                 double predictedEv = fobNew - fob;
298:                 double actualEv = (efStep*(*evalMin));310:                 double actualEv = (efStep*(*evalMin));
299:                 trustRatio = abs(1.0 - predictedEv/actualEv) ;311:                 trustRatio = abs(1.0 - predictedEv/actualEv) ;
300:                 if (trustRatio > m_trustRadius) {312:                 if (trustRatio > m_trustRadius) {
301:                         m_maxEvecStep = std::max(m_maxEvecStep/1.1, m_minMaxStep);313:                         m_maxEvecStep = std::max(m_maxEvecStep/1.1, m_minMaxStep);
302:                 }314:                 }
303:                 else {315:                 else {
304:                         m_maxEvecStep = std::min(m_maxEvecStep*1.1, m_maxMaxStep);316:                         m_maxEvecStep = std::min(m_maxEvecStep*1.1, m_maxMaxStep);
305:                 }317:                 }
306:         }318:         }
307: 319: 
308:         fileHandle << std::endl;320:         if (printingOn) {
309:         fileHandle << " ----------------------------------------------------------------------------------------" 321:                 fileHandle << " ----------------------------------------------------------------------------------------" 
310:                 << std::endl;322:                         << std::endl;
311:         fileHandle << "  Vector        Gradient          Secder            Step        Max step     Trust ratio " 323:                 fileHandle << "  Vector        Gradient          Secder            Step        Max step     Trust ratio " 
312:                 << std::endl;324:                         << std::endl;
313:         fileHandle << " ----------------------------------------------------------------------------------------" 325:                 fileHandle << " ----------------------------------------------------------------------------------------" 
314:                 << std::endl;326:                         << std::endl;
315:         fileHandle << "     1   " << std::setw(15) << std::setprecision(6) << fob << " " 327:                 fileHandle << "     1   " << std::setw(15) << std::setprecision(6) << fob << " " 
316:                 << std::setw(15) << std::setprecision(6) << *evalMin << " " 328:                         << std::setw(15) << std::setprecision(6) << *evalMin << " " 
317:                 << std::setw(15) << std::setprecision(6) << efStep << " " 329:                         << std::setw(15) << std::setprecision(6) << efStep << " " 
318:                 << std::setw(15) << std::setprecision(6) << m_maxEvecStep << " " 330:                         << std::setw(15) << std::setprecision(6) << m_maxEvecStep << " " 
319:                 << std::setw(15) << std::setprecision(6) << trustRatio << " " << std::endl;331:                         << std::setw(15) << std::setprecision(6) << trustRatio << " " << std::endl;
320:         fileHandle << " ----------------------------------------------------------------------------------------" 332:                 fileHandle << " ----------------------------------------------------------------------------------------" 
321:                 << std::endl;333:                         << std::endl;
322:         fileHandle << std::endl;334:                 fileHandle << std::endl;
 335:         }
323: }336: }


r29015/cost_function.cu 2015-11-17 23:33:10.464645090 +0000 r29014/cost_function.cu 2015-11-17 23:33:16.044719925 +0000
  5:  **/  5:  **/
  6:   6: 
  7: #include<iomanip>  7: #include<iomanip>
  8:   8: 
  9: #include "cost_function.h"  9: #include "cost_function.h"
 10:  10: 
 11: CostFunction::CostFunction(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas, size_t numDimensions, int nDegFreedom,  11: CostFunction::CostFunction(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas, size_t numDimensions, int nDegFreedom, 
 12:                 int nRigidBody, int rigidMaxSite, int *nRigidSitesPerBody, int *rigidGroups, double *sitesRigidBody,  12:                 int nRigidBody, int rigidMaxSite, int *nRigidSitesPerBody, int *rigidGroups, double *sitesRigidBody, 
 13:                 int *rigidSingles, double *rigidInverse, double *coords, int nSecDiag, bool isAtomisticNotRigid,  13:                 int *rigidSingles, double *rigidInverse, double *coords, int nSecDiag, bool isAtomisticNotRigid, 
 14:                 double aaConvThreshold, double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen, int nFreeze) 14:                 double aaConvThreshold, double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen, int nFreeze)
 15:         : m_timer_potential(timer_potential) 15: : m_timer_potential(timer_potential)
 16:         , m_numDimensions(numDimensions) 16:         , m_numDimensions(numDimensions)
 17:         , m_nDegFreedom(nDegFreedom) 17:         , m_nDegFreedom(nDegFreedom)
 18:         , m_nRigidBody(nRigidBody) 18:         , m_nRigidBody(nRigidBody)
 19:         , m_rigidMaxSite(rigidMaxSite) 19:         , m_rigidMaxSite(rigidMaxSite)
 20:         , m_nRigidSitesPerBody(nRigidSitesPerBody) 20:         , m_nRigidSitesPerBody(nRigidSitesPerBody)
 21:         , m_rigidGroups(rigidGroups) 21:         , m_rigidGroups(rigidGroups)
 22:         , m_sitesRigidBody(sitesRigidBody) 22:         , m_sitesRigidBody(sitesRigidBody)
 23:         , m_rigidSingles(rigidSingles) 23:         , m_rigidSingles(rigidSingles)
 24:         , m_rigidInverse(rigidInverse) 24:         , m_rigidInverse(rigidInverse)
 25:         , m_isColdFusion(false) 25:         , m_isColdFusion(false)
 37:         , m_nSecDiag(nSecDiag) 37:         , m_nSecDiag(nSecDiag)
 38:         , m_isAtomisticNotRigid(isAtomisticNotRigid) 38:         , m_isAtomisticNotRigid(isAtomisticNotRigid)
 39:         , m_aaConvThreshold(aaConvThreshold) 39:         , m_aaConvThreshold(aaConvThreshold)
 40:         , m_nCalls(0) 40:         , m_nCalls(0)
 41:         , m_coldFusionLim(coldFusionLim) 41:         , m_coldFusionLim(coldFusionLim)
 42:         , m_shouldFreeze(shouldFreeze) 42:         , m_shouldFreeze(shouldFreeze)
 43:         , m_isAtomFrozen(isAtomFrozen) 43:         , m_isAtomFrozen(isAtomFrozen)
 44:         , m_nFreeze(nFreeze) 44:         , m_nFreeze(nFreeze)
 45:         , m_debugPrinting(debugPrinting) 45:         , m_debugPrinting(debugPrinting)
 46:         , m_cublas(cublas) 46:         , m_cublas(cublas)
 47:           , m_isBfgsts(false) 47:         , m_isBfgsts(false)
 48: { 48: {
 49:         double *zerosx; 
 50:         double *zerosy; 
 51:         double *zerosz; 
 52:  
 53:         zerosx = new double[numDimensions]; 
 54:         zerosy = new double[numDimensions]; 
 55:         zerosz = new double[numDimensions]; 
 56:  
 57:         CudaSafeCall( cudaMalloc(&m_d_zerosx, m_numDimensions * sizeof(double)) ); 
 58:         CudaSafeCall( cudaMalloc(&m_d_zerosy, m_numDimensions * sizeof(double)) ); 
 59:         CudaSafeCall( cudaMalloc(&m_d_zerosz, m_numDimensions * sizeof(double)) ); 
 60:  
 61:         if (m_rigidInverse != NULL) { 49:         if (m_rigidInverse != NULL) {
 62:                 CudaSafeCall( cudaMalloc(&m_d_gkAtoms, numDimensions * sizeof(double)) ); 50:                 CudaSafeCall( cudaMalloc(&m_d_gkAtoms, numDimensions * sizeof(double)) );
 63:         } 51:         }
 64:  52: 
 65:         CudaSafeCall( cudaMalloc(&m_d_nRigidSitesPerBody, m_nRigidBody * sizeof(int)) ); 53:         CudaSafeCall( cudaMalloc(&m_d_nRigidSitesPerBody, m_nRigidBody * sizeof(int)) );
 66:         CudaSafeCall( cudaMalloc(&m_d_sitesRigidBody, m_nRigidBody * 3 * m_rigidMaxSite * sizeof(double)) ); 54:         CudaSafeCall( cudaMalloc(&m_d_sitesRigidBody, m_nRigidBody * 3 * m_rigidMaxSite * sizeof(double)) );
 67:         CudaSafeCall( cudaMalloc(&m_d_rigidGroups, m_nRigidBody * m_rigidMaxSite * sizeof(int)) ); 55:         CudaSafeCall( cudaMalloc(&m_d_rigidGroups, m_nRigidBody * m_rigidMaxSite * sizeof(int)) );
 68:         CudaSafeCall( cudaMalloc(&m_d_rigidSingles, (m_nDegFreedom/3 - 2*m_nRigidBody) * sizeof(int)) ); 56:         CudaSafeCall( cudaMalloc(&m_d_rigidSingles, (m_nDegFreedom/3 - 2*m_nRigidBody) * sizeof(int)) );
 69:         CudaSafeCall( cudaMalloc(&m_d_rigidInverse, m_nRigidBody * 3 * 3 * sizeof(double)) ); 57:         CudaSafeCall( cudaMalloc(&m_d_rigidInverse, m_nRigidBody * 3 * 3 * sizeof(double)) );
 70:  58: 
 75:         CudaSafeCall( cudaMalloc(&m_d_gkRigid, m_nDegFreedom * sizeof(double)) ); 63:         CudaSafeCall( cudaMalloc(&m_d_gkRigid, m_nDegFreedom * sizeof(double)) );
 76:  64: 
 77:         if (m_coords != NULL) { 65:         if (m_coords != NULL) {
 78:                 CudaSafeCall( cudaMalloc(&m_d_coords,   numDimensions * sizeof(double)) ); 66:                 CudaSafeCall( cudaMalloc(&m_d_coords,   numDimensions * sizeof(double)) );
 79:                 CudaSafeCall( cudaMalloc(&m_d_energy, sizeof(double)) ); 67:                 CudaSafeCall( cudaMalloc(&m_d_energy, sizeof(double)) );
 80:                 CudaSafeCall( cudaMalloc(&m_d_gradient, numDimensions * sizeof(double)) ); 68:                 CudaSafeCall( cudaMalloc(&m_d_gradient, numDimensions * sizeof(double)) );
 81:         } 69:         }
 82:  70: 
 83:         CudaSafeCall( cudaMalloc(&m_d_isAtomFrozen, numDimensions/3 * sizeof(bool)) ); 71:         CudaSafeCall( cudaMalloc(&m_d_isAtomFrozen, numDimensions/3 * sizeof(bool)) );
 84:  72: 
 85:         for (size_t i = 1; i < (numDimensions + 1); ++i) { 
 86:                 if ((i + 2)%3 == 0) { 
 87:                         zerosx[i-1] = 1.0; 
 88:                 } 
 89:                 else { 
 90:                         zerosx[i-1] = 0.0; 
 91:                 } 
 92:         } 
 93:  
 94:         for (size_t i = 1; i < (numDimensions + 1); ++i) { 
 95:                 if ((i + 1)%3 == 0) { 
 96:                         zerosy[i-1] = 1.0; 
 97:                 } 
 98:                 else { 
 99:                         zerosy[i-1] = 0.0; 
100:                 } 
101:         } 
102:  
103:         for (size_t i = 1; i < (numDimensions + 1); ++i) { 
104:                 if (i%3 == 0) { 
105:                         zerosz[i-1] = 1.0; 
106:                 } 
107:                 else { 
108:                         zerosz[i-1] = 0.0; 
109:                 } 
110:         } 
111:  
112:         CudaSafeCall( cudaMemcpy(m_d_nRigidSitesPerBody, m_nRigidSitesPerBody, m_nRigidBody * sizeof(int), cudaMemcpyHostToDevice) ); 73:         CudaSafeCall( cudaMemcpy(m_d_nRigidSitesPerBody, m_nRigidSitesPerBody, m_nRigidBody * sizeof(int), cudaMemcpyHostToDevice) );
113:         CudaSafeCall( cudaMemcpy(m_d_sitesRigidBody, m_sitesRigidBody, m_nRigidBody * 3 * m_rigidMaxSite * sizeof(double), cudaMemcpyHostToDevice) ); 74:         CudaSafeCall( cudaMemcpy(m_d_sitesRigidBody, m_sitesRigidBody, m_nRigidBody * 3 * m_rigidMaxSite * sizeof(double), cudaMemcpyHostToDevice) );
114:         CudaSafeCall( cudaMemcpy(m_d_rigidGroups, m_rigidGroups, m_nRigidBody * m_rigidMaxSite * sizeof(int), cudaMemcpyHostToDevice) ); 75:         CudaSafeCall( cudaMemcpy(m_d_rigidGroups, m_rigidGroups, m_nRigidBody * m_rigidMaxSite * sizeof(int), cudaMemcpyHostToDevice) );
115:         CudaSafeCall( cudaMemcpy(m_d_rigidSingles, m_rigidSingles, (m_nDegFreedom/3 - 2*m_nRigidBody) * sizeof(int), cudaMemcpyHostToDevice) ); 76:         CudaSafeCall( cudaMemcpy(m_d_rigidSingles, m_rigidSingles, (m_nDegFreedom/3 - 2*m_nRigidBody) * sizeof(int), cudaMemcpyHostToDevice) );
116:         CudaSafeCall( cudaMemcpy(m_d_rigidInverse, m_rigidInverse, m_nRigidBody * 3 * 3 * sizeof(double), cudaMemcpyHostToDevice) ); 77:         CudaSafeCall( cudaMemcpy(m_d_rigidInverse, m_rigidInverse, m_nRigidBody * 3 * 3 * sizeof(double), cudaMemcpyHostToDevice) );
117:  78: 
118:         CudaSafeCall( cudaMemcpy(m_d_nRigidBody, &m_nRigidBody, sizeof(int), cudaMemcpyHostToDevice) ); 79:         CudaSafeCall( cudaMemcpy(m_d_nRigidBody, &m_nRigidBody, sizeof(int), cudaMemcpyHostToDevice) );
119:         CudaSafeCall( cudaMemcpy(m_d_rigidMaxSite, &m_rigidMaxSite, sizeof(int), cudaMemcpyHostToDevice) ); 80:         CudaSafeCall( cudaMemcpy(m_d_rigidMaxSite, &m_rigidMaxSite, sizeof(int), cudaMemcpyHostToDevice) );
120:  81: 
121:         if (m_coords != NULL) { 82:         if (m_coords != NULL) {
122:                 CudaSafeCall( cudaMemcpy(m_d_coords, m_coords, numDimensions * sizeof(double), cudaMemcpyHostToDevice) ); 83:                 CudaSafeCall( cudaMemcpy(m_d_coords, m_coords, numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
123:         } 84:         }
124:  85: 
125:         CudaSafeCall( cudaMemcpy(m_d_isAtomFrozen, m_isAtomFrozen, numDimensions/3 * sizeof(bool), cudaMemcpyHostToDevice) ); 86:         CudaSafeCall( cudaMemcpy(m_d_isAtomFrozen, m_isAtomFrozen, numDimensions/3 * sizeof(bool), cudaMemcpyHostToDevice) );
126:  
127:         CudaSafeCall( cudaMemcpy(m_d_zerosx, zerosx, numDimensions * sizeof(double), cudaMemcpyHostToDevice) ); 
128:         CudaSafeCall( cudaMemcpy(m_d_zerosy, zerosy, numDimensions * sizeof(double), cudaMemcpyHostToDevice) ); 
129:         CudaSafeCall( cudaMemcpy(m_d_zerosz, zerosz, numDimensions * sizeof(double), cudaMemcpyHostToDevice) ); 
130:  
131:         delete [] zerosx; 
132:         delete [] zerosy; 
133:         delete [] zerosz; 
134:  
135: } 87: }
136:  88: 
137:  
138:  
139: CostFunction::~CostFunction()  89: CostFunction::~CostFunction() 
140: { 90: {
141:         CudaSafeCall( cudaFree(m_d_zerosx) ); 
142:         CudaSafeCall( cudaFree(m_d_zerosy) ); 
143:         CudaSafeCall( cudaFree(m_d_zerosz) ); 
144:  
145:         if (m_rigidInverse != NULL) { 91:         if (m_rigidInverse != NULL) {
146:                 CudaSafeCall( cudaFree(m_d_gkAtoms)); 92:                 CudaSafeCall( cudaFree(m_d_gkAtoms));
147:         } 93:         }
148:  94: 
149:         CudaSafeCall( cudaFree(m_d_nRigidSitesPerBody)); 95:         CudaSafeCall( cudaFree(m_d_nRigidSitesPerBody));
150:         CudaSafeCall( cudaFree(m_d_sitesRigidBody)); 96:         CudaSafeCall( cudaFree(m_d_sitesRigidBody));
151:         CudaSafeCall( cudaFree(m_d_rigidGroups)); 97:         CudaSafeCall( cudaFree(m_d_rigidGroups));
152:         CudaSafeCall( cudaFree(m_d_rigidSingles)); 98:         CudaSafeCall( cudaFree(m_d_rigidSingles));
153:         CudaSafeCall( cudaFree(m_d_rigidInverse)); 99:         CudaSafeCall( cudaFree(m_d_rigidInverse));
154: 100: 
160: 106: 
161:         if (m_coords != NULL) {107:         if (m_coords != NULL) {
162:                 CudaSafeCall( cudaFree(m_d_coords) );108:                 CudaSafeCall( cudaFree(m_d_coords) );
163:                 CudaSafeCall( cudaFree(m_d_energy) );109:                 CudaSafeCall( cudaFree(m_d_energy) );
164:                 CudaSafeCall( cudaFree(m_d_gradient) );110:                 CudaSafeCall( cudaFree(m_d_gradient) );
165:         }111:         }
166: 112: 
167:         CudaSafeCall( cudaFree(m_d_isAtomFrozen) );113:         CudaSafeCall( cudaFree(m_d_isAtomFrozen) );
168: }114: }
169: 115: 
170:  
171:  
172: // Get/set functions. 116: // Get/set functions. 
173: 117: 
174: size_t CostFunction::getNumDimensions() const118: size_t CostFunction::getNumDimensions() const
175: {119: {
176:         return m_numDimensions;120:         return m_numDimensions;
177: }121: }
178: 122: 
179: int CostFunction::getnCalls() const123: int CostFunction::getnCalls() const
180: {124: {
181:         return m_nCalls;125:         return m_nCalls;
209: void CostFunction::setDevGradient(double *d_gradient)153: void CostFunction::setDevGradient(double *d_gradient)
210: {154: {
211:         CudaSafeCall( cudaMemcpy(m_d_gradient, d_gradient, m_numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );155:         CudaSafeCall( cudaMemcpy(m_d_gradient, d_gradient, m_numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );
212: }156: }
213: 157: 
214: void CostFunction::setIsBfgsts(bool isBfgsts)158: void CostFunction::setIsBfgsts(bool isBfgsts)
215: {159: {
216:         m_isBfgsts = isBfgsts;160:         m_isBfgsts = isBfgsts;
217: }161: }
218: 162: 
219:  
220:  
221: namespace gpu_secdiag163: namespace gpu_secdiag
222: {164: {
223:         // Variables on the GPU. 165:         // Variables on the GPU. 
224:         __constant__ double zeta;166:         __constant__ double zeta;
225:         __constant__ double minusZeta;167:         __constant__ double minusZeta;
226: 168: 
227:         // Kernels. 169:         // Kernels. 
228:         __global__ void updateDiag(const double *d_fPlus, const double *d_fMinus, const double *m_d_energy, double *d_f, 170:         __global__ void updateDiag(const double *d_fPlus, const double *d_fMinus, const double *m_d_energy, double *d_f, 
229:                         double *d_eigen2, double *d_eigen3, double *d_twoEigen, double *d_twoEigen2);171:                         double *d_eigen2, double *d_eigen3, double *d_twoEigen, double *d_twoEigen2);
230:         __global__ void updateDiag4(double *d_eigen4, double *d_twoEigen4);172:         __global__ void updateDiag4(double *d_eigen4, double *d_twoEigen4);
231:         __global__ void calculateDebug(const double *d_fPlus, const double *d_fMinus, double *d_temp);173:         __global__ void calculateDebug(const double *d_fPlus, const double *d_fMinus, double *d_temp);
232: }174: }
233: 175: 
234:  
235:  
236: namespace gpu_freeze176: namespace gpu_freeze
237: {177: {
238:         // Variables on the GPU. 178:         // Variables on the GPU. 
239:         __constant__ int numDimensions;179:         __constant__ int numDimensions;
240: 180: 
241:         //Kernels. 181:         //Kernels. 
242:         __global__ void freezeGrad(double *d_gradf, const bool *m_d_isAtomFrozen);182:         __global__ void freezeGrad(double *d_gradf, const bool *m_d_isAtomFrozen);
243: }183: }
244: 184: 
245:  
246:  
247: namespace gpu_orthogopt185: namespace gpu_orthogopt
248: {186: {
249:         // Variables on the GPU. 187:         // Variables on the GPU. 
250:         __constant__ int numDimensions;188:         __constant__ int numDimensions;
251: 189: 
252:         // Kernels. 190:         // Kernels. 
253:         __global__ void updateCm(double *d_cmx, double *d_cmy, double *d_cmz);191:         __global__ void updateCm(double *d_cmx, double *d_cmy, double *d_cmz);
254:         __global__ void updatevDotTrans(double *d_tmp, double *d_vDot);192:         __global__ void updatevDotTrans(double *d_tmp, double *d_vDot);
255:         __global__ void updateTmp(double *d_tmp);193:         __global__ void updateTmp(double *d_tmp);
256:         __global__ void updatevDotRot(const double *d_tmp, double *d_tmp2, double *d_vDot);194:         __global__ void updatevDotRot(const double *d_tmp, double *d_tmp2, double *d_vDot);
262:         __global__ void rotationaly1(const double *d_x, const double *m_d_coords, double *d_tempArray, const double *d_cmx, 200:         __global__ void rotationaly1(const double *d_x, const double *m_d_coords, double *d_tempArray, const double *d_cmx, 
263:                         const double *d_cmz);201:                         const double *d_cmz);
264:         __global__ void rotationaly2(double *d_x, const double *m_d_coords, const double *d_cmx, const double *d_cmz, 202:         __global__ void rotationaly2(double *d_x, const double *m_d_coords, const double *d_cmx, const double *d_cmz, 
265:                         const double *d_tmp2);203:                         const double *d_tmp2);
266:         __global__ void rotationalz1(const double *d_x, const double *m_d_coords, double *d_tempArray, const double *d_cmx, 204:         __global__ void rotationalz1(const double *d_x, const double *m_d_coords, double *d_tempArray, const double *d_cmx, 
267:                         const double *d_cmz);205:                         const double *d_cmz);
268:         __global__ void rotationalz2(double *d_x, const double *m_d_coords, const double *d_cmx, const double *d_cmy, 206:         __global__ void rotationalz2(double *d_x, const double *m_d_coords, const double *d_cmx, const double *d_cmy, 
269:                         const double *d_tmp2);207:                         const double *d_tmp2);
270: }208: }
271: 209: 
272:  
273:  
274: // d_x is the estimated eigenvalue and direction along which to compute the curvature. 210: // d_x is the estimated eigenvalue and direction along which to compute the curvature. 
275: // d_f is the curvature. 211: // d_f is the curvature. 
276: // d_gradf is the gradient of the curvature. 212: // d_gradf is the gradient of the curvature. 
277: void CostFunction::basePotential(double *d_x, double *d_f, double *d_gradf)213: void CostFunction::basePotential(double *d_x, double *d_f, double *d_gradf)
278: {214: {
279:         bool printingOn = m_debugPrinting.getPrintingOn();215:         bool printingOn = m_debugPrinting.getPrintingOn();
280:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();216:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();
281: 217: 
282:         bool isTiming = m_timer_potential.getTimingOn();218:         bool isTiming = m_timer_potential.getTimingOn();
283:         if (isTiming) {219:         if (isTiming) {
336:                         std::cerr << "This method for calculating secdiag is not recognised. " << std::endl;272:                         std::cerr << "This method for calculating secdiag is not recognised. " << std::endl;
337:                         exit(EXIT_FAILURE);273:                         exit(EXIT_FAILURE);
338:                 }274:                 }
339: 275: 
340:                 bool shouldNormalise = true;276:                 bool shouldNormalise = true;
341:                 orthogopt(d_xCopy, shouldNormalise);277:                 orthogopt(d_xCopy, shouldNormalise);
342: 278: 
343:                 freeze(d_xCopy);279:                 freeze(d_xCopy);
344: 280: 
345:                 // Compute the energy and gradient at coords + zeta*xCopy. 281:                 // Compute the energy and gradient at coords + zeta*xCopy. 
346:                 m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, m_d_coords, d_xCopy, d_zeta); // nDimTmp = coords + zeta*xCopy282:                 m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, m_d_coords, d_xCopy, d_zeta); // nt = c + z*xc
347:                 rigidTransforms(d_nDimTmp, d_fPlus, d_grad1);283:                 rigidTransforms(d_nDimTmp, d_fPlus, d_grad1);
348: 284: 
349:                 // Second order central differences expansion.285:                 // Second order central differences expansion.
350:                 if (m_nSecDiag <= 2) {286:                 if (m_nSecDiag <= 2) {
351:                         // Compute the energy and gradient at coords - zeta*xCopy. 287:                         // Compute the energy and gradient at coords - zeta*xCopy. 
352:                         m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, m_d_coords, d_xCopy, d_minusZeta); // nDimTmp = coords - zeta*xCopy288:                         m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, m_d_coords, d_xCopy, d_minusZeta); // nt = c - z*xc
353:                         rigidTransforms(d_nDimTmp, d_fMinus, d_grad2);289:                         rigidTransforms(d_nDimTmp, d_fMinus, d_grad2);
354: 290: 
355:                         m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, d_grad1, d_grad2, &minusOne, false); // nDimTmp = grad1 - grad2291:                         m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, d_grad1, d_grad2, &minusOne, false); // nt = g1 - g2
356:                         m_cublas.dispatchDot(m_numDimensions, d_eigen2, d_nDimTmp, d_xCopy); // eigen2 = nDimTmp Dot xCopy 292:                         m_cublas.dispatchDot(m_numDimensions, d_eigen2, d_nDimTmp, d_xCopy); // e2 = ntDotX
357: 293: 
358:                         gpu_secdiag::updateDiag<<<1,1>>>(d_fPlus, d_fMinus, m_d_energy, d_f, d_eigen2, d_eigen3, d_twoEigen, 294:                         gpu_secdiag::updateDiag<<<1,1>>>(d_fPlus, d_fMinus, m_d_energy, d_f, d_eigen2, d_eigen3, d_twoEigen, 
359:                                         d_twoEigen2);295:                                         d_twoEigen2);
360:                         CudaCheckError();296:                         CudaCheckError();
361:                         cudaDeviceSynchronize();297:                         cudaDeviceSynchronize();
362: 298: 
363:                         if (printingOn) {299:                         if (printingOn) {
364:                                 gpu_secdiag::calculateDebug<<<1,1>>>(d_fPlus, d_fMinus, d_tmp);300:                                 gpu_secdiag::calculateDebug<<<1,1>>>(d_fPlus, d_fMinus, d_tmp);
365:                                 CudaCheckError();301:                                 CudaCheckError();
366:                                 cudaDeviceSynchronize();302:                                 cudaDeviceSynchronize();
367:                         }303:                         }
368: 304: 
369:                         m_cublas.dispatchScale(m_numDimensions, d_nDimTmp, d_nDimTmp, &oneOverZeta, false); // nDimTmp = (1/zeta)*nDimTmp305:                         m_cublas.dispatchScale(m_numDimensions, d_nDimTmp, d_nDimTmp, &oneOverZeta, false); // nt = (1/zeta)*nt
370:                         if (m_nSecDiag == 2) {306:                         if (m_nSecDiag == 2) {
371:                                 m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_nDimTmp, d_xCopy, d_twoEigen2); // gradf = nDimTmp + twoEigen2*xCopy307:                                 m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_nDimTmp, d_xCopy, d_twoEigen2); // g = nt + mte*xc
372:                         }308:                         }
373:                         else {309:                         else {
374:                                 m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_nDimTmp, d_xCopy, d_twoEigen); // gradf = nDimTmp + twoEigen*xCopy310:                                 m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_nDimTmp, d_xCopy, d_twoEigen); // g = nt + mte*xc
375:                         }311:                         }
376:                 }312:                 }
377:                 // First order forward finite differences (m_nSecDiag == 3). 313:                 // First order forward finite differences (m_nSecDiag == 3). 
378:                 else {314:                 else {
379:                         m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, d_grad1, m_d_gradient, &minusOne, false); // nDimTmp = grad1 - gradient315:                         m_cublas.dispatchAxpy(m_numDimensions, d_nDimTmp, d_grad1, m_d_gradient, &minusOne, false); // nt = g1 - gg
380:                         m_cublas.dispatchDot(m_numDimensions, d_eigen4, d_nDimTmp, d_xCopy); // eigen4 = nDimTmp Dot xCopy316:                         m_cublas.dispatchDot(m_numDimensions, d_eigen4, d_nDimTmp, d_xCopy); // e4 = ntDotX
381:                         gpu_secdiag::updateDiag4<<<1,1>>>(d_eigen4, d_twoEigen4);317:                         gpu_secdiag::updateDiag4<<<1,1>>>(d_eigen4, d_twoEigen4);
382:                         CudaCheckError();318:                         CudaCheckError();
383:                         cudaDeviceSynchronize();319:                         cudaDeviceSynchronize();
384: 320: 
385:                         m_cublas.dispatchScale(m_numDimensions, d_nDimTmp, d_nDimTmp, &twoOverZeta, false); // nDimTmp = (2/zeta)*nDimTmp321:                         m_cublas.dispatchScale(m_numDimensions, d_nDimTmp, d_nDimTmp, &twoOverZeta, false); // nt = (2/zeta)*nt
386:                         m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_nDimTmp, d_xCopy, d_twoEigen4); // gradf = nDimTmp + twoEigen4*xCopy322:                         m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_nDimTmp, d_xCopy, d_twoEigen4); // g = nt + mte*xc
387:                 }323:                 }
388: 324: 
389:                 shouldNormalise = false;325:                 shouldNormalise = false;
390:                 orthogopt(d_gradf, shouldNormalise);326:                 orthogopt(d_gradf, shouldNormalise);
391: 327: 
392:                 m_cublas.dispatchDot(m_numDimensions, &proj, d_gradf, d_xCopy, false); // proj = gradf Dot xCopy328:                 m_cublas.dispatchDot(m_numDimensions, &proj, d_gradf, d_xCopy, false); // p = gDotX
393:                 proj = -proj;329:                 proj = -proj;
394:                 m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_gradf, d_xCopy, &proj, false); // gradf += proj*xCopy330:                 m_cublas.dispatchAxpy(m_numDimensions, d_gradf, d_gradf, d_xCopy, &proj, false); // g = g + p*x
395: 331: 
396:                 if (printingOn) {332:                 if (printingOn) {
397:                         double printDiag, printDiag2, printDiag3, printEnePlus, printEneMinus, printEnergy;333:                         double printDiag, printDiag2, printDiag3, printEnePlus, printEneMinus, printEnergy;
398: 334: 
399:                         CudaSafeCall( cudaMemcpy(&printDiag,     d_f,        sizeof(double), cudaMemcpyDeviceToHost) );335:                         CudaSafeCall( cudaMemcpy(&printDiag,     d_f,        sizeof(double), cudaMemcpyDeviceToHost) );
400:                         CudaSafeCall( cudaMemcpy(&printDiag2,    d_eigen2,   sizeof(double), cudaMemcpyDeviceToHost) );336:                         CudaSafeCall( cudaMemcpy(&printDiag2,    d_eigen2,   sizeof(double), cudaMemcpyDeviceToHost) );
401:                         CudaSafeCall( cudaMemcpy(&printDiag3,    d_eigen3,   sizeof(double), cudaMemcpyDeviceToHost) );337:                         CudaSafeCall( cudaMemcpy(&printDiag3,    d_eigen3,   sizeof(double), cudaMemcpyDeviceToHost) );
402:                         CudaSafeCall( cudaMemcpy(&printEnePlus,  d_fPlus,    sizeof(double), cudaMemcpyDeviceToHost) );338:                         CudaSafeCall( cudaMemcpy(&printEnePlus,  d_fPlus,    sizeof(double), cudaMemcpyDeviceToHost) );
403:                         CudaSafeCall( cudaMemcpy(&printEneMinus, d_fMinus,   sizeof(double), cudaMemcpyDeviceToHost) );339:                         CudaSafeCall( cudaMemcpy(&printEneMinus, d_fMinus,   sizeof(double), cudaMemcpyDeviceToHost) );
404:                         CudaSafeCall( cudaMemcpy(&printEnergy,   m_d_energy, sizeof(double), cudaMemcpyDeviceToHost) );340:                         CudaSafeCall( cudaMemcpy(&printEnergy,   m_d_energy, sizeof(double), cudaMemcpyDeviceToHost) );
443:         else {379:         else {
444:                 rigidTransforms(d_x, d_f, d_gradf);380:                 rigidTransforms(d_x, d_f, d_gradf);
445:         }381:         }
446: 382: 
447:         if (isTiming) {383:         if (isTiming) {
448:                 m_timer_potential.stop();384:                 m_timer_potential.stop();
449:         }385:         }
450: 386: 
451: }387: }
452: 388: 
453:  
454:  
455: void CostFunction::rigidTransforms(double *d_x, double *d_f, double *d_gradf)389: void CostFunction::rigidTransforms(double *d_x, double *d_f, double *d_gradf)
456: {390: {
457:         if (!m_isAtomisticNotRigid) {391:         if (!m_isAtomisticNotRigid) {
458:                 // Rigid bodies coordinate transformation. 392:                 // Rigid bodies coordinate transformation. 
459:                 transformRigidToC(d_x);393:                 transformRigidToC(d_x);
 394:                 CudaCheckError();
 395:                 cudaDeviceSynchronize();
460:         }396:         }
461: 397: 
462:         computeEnergyAndGradient(d_x, d_f, d_gradf);398:         computeEnergyAndGradient(d_x, d_f, d_gradf);
463: 399: 
464:         if (!m_isAtomisticNotRigid) {400:         if (!m_isAtomisticNotRigid) {
465:                 CudaSafeCall( cudaMemcpy(m_d_gkAtoms, d_gradf, m_numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );401:                 CudaSafeCall( cudaMemcpy(m_d_gkAtoms, d_gradf, m_numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );
466:                 // Rigid bodies gradient transformation. 402:                 // Rigid bodies gradient transformation. 
467:                 transformGrad(d_gradf, d_x);403:                 transformGrad(d_gradf, d_x);
 404: 
 405:                 CudaCheckError();
 406:                 cudaDeviceSynchronize();
468:         }407:         }
469: 408: 
470:         freeze(d_gradf);409:         freeze(d_gradf);
471: 410: 
472:         m_nCalls += 1;411:         m_nCalls += 1;
473: }412: }
474: 413: 
475:  
476:  
477: void CostFunction::calculateRms(const double *d_gradf, double *outRms)414: void CostFunction::calculateRms(const double *d_gradf, double *outRms)
478: {415: {
479:         double gkNormSquared;416:         double gkNormSquared;
480:         m_cublas.dispatchDot(m_numDimensions, &gkNormSquared, d_gradf, d_gradf, false); // gkNormSquared = gradf Dot gradf417:         m_cublas.dispatchDot(m_numDimensions, &gkNormSquared, d_gradf, d_gradf, false);
481:         if (!m_isAtomisticNotRigid) {418:         if (!m_isAtomisticNotRigid) {
482:                 *outRms = fmax(sqrt(gkNormSquared/m_nDegFreedom), 1.0e-100);419:                 *outRms = fmax(sqrt(gkNormSquared/m_nDegFreedom), 1.0e-100);
483:                 if ((*outRms < m_aaConvThreshold) && !m_isBfgsts) {420:                 if ((*outRms < m_aaConvThreshold) && !m_isBfgsts) {
484:                         aaConvergence(m_d_gkAtoms, outRms);421:                         aaConvergence(m_d_gkAtoms, outRms);
485:                         *outRms = fmax(sqrt(*outRms/m_numDimensions), 1.0e-100);422:                         *outRms = fmax(sqrt(*outRms/m_numDimensions), 1.0e-100);
486:                 }423:                 }
487:         }424:         }
488:         else {425:         else {
489:                 *outRms = fmax(sqrt(gkNormSquared/m_numDimensions), 1.0e-100);426:                 *outRms = fmax(sqrt(gkNormSquared/m_numDimensions), 1.0e-100);
490:         }427:         }
491: }428: }
492: 429: 
493:  
494:  
495: void CostFunction::freeze(double *d_gradf)430: void CostFunction::freeze(double *d_gradf)
496: {431: {
497:         if (m_shouldFreeze) {432:         if (m_shouldFreeze) {
498:                 CudaSafeCall( cudaMemcpyToSymbol(gpu_freeze::numDimensions, &m_numDimensions,  sizeof(int)) );433:                 CudaSafeCall( cudaMemcpyToSymbol(gpu_freeze::numDimensions, &m_numDimensions,  sizeof(int)) );
499: 434: 
500:                 dim3 blockDim;435:                 dim3 blockDim;
501:                 dim3 gridDim;436:                 dim3 gridDim;
502: 437: 
503:                 blockDim.x = 1024;438:                 blockDim.x = 1024;
504:                 gridDim.x = ((m_numDimensions/3) + blockDim.x - 1)/blockDim.x;439:                 gridDim.x = ((m_numDimensions/3) + blockDim.x - 1)/blockDim.x;
505: 440: 
506:                 gpu_freeze::freezeGrad<<<gridDim, blockDim>>>(d_gradf, m_d_isAtomFrozen);441:                 gpu_freeze::freezeGrad<<<gridDim, blockDim>>>(d_gradf, m_d_isAtomFrozen);
507:                 CudaCheckError();442:                 CudaCheckError();
508:                 cudaDeviceSynchronize();443:                 cudaDeviceSynchronize();
509: 444: 
510:         }445:         }
511: }446: }
512: 447: 
513:  
514:  
515: void CostFunction::orthogopt(double *d_x, const bool shouldNormalise)448: void CostFunction::orthogopt(double *d_x, const bool shouldNormalise)
516: {449: {
517:         bool printingOn = m_debugPrinting.getPrintingOn();450:         bool printingOn = m_debugPrinting.getPrintingOn();
518:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();451:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();
519: 452: 
520:         CudaSafeCall( cudaMemcpyToSymbol(gpu_orthogopt::numDimensions, &m_numDimensions,  sizeof(int)) );453:         CudaSafeCall( cudaMemcpyToSymbol(gpu_orthogopt::numDimensions, &m_numDimensions,  sizeof(int)) );
521:         double *d_tmp;454:         double *d_tmp;
522:         CudaSafeCall( cudaMalloc(&d_tmp, sizeof(double)) );455:         CudaSafeCall( cudaMalloc(&d_tmp, sizeof(double)) );
523:         if (m_nFreeze < 3) {456:         if (m_nFreeze < 3) {
524:                 dim3 blockDim;457:                 dim3 blockDim;
525:                 dim3 gridDim;458:                 dim3 gridDim;
526: 459: 
 460:                 double *zerosx;
 461:                 double *zerosy;
 462:                 double *zerosz;
 463: 
 464:                 double *d_zerosx;
 465:                 double *d_zerosy;
 466:                 double *d_zerosz;
 467: 
527:                 double *d_tempArray;468:                 double *d_tempArray;
528: 469: 
529:                 double *d_cmx;470:                 double *d_cmx;
530:                 double *d_cmy;471:                 double *d_cmy;
531:                 double *d_cmz;472:                 double *d_cmz;
532: 473: 
533:                 double *d_tmp2;474:                 double *d_tmp2;
534:                 double *d_vDot;475:                 double *d_vDot;
535: 476: 
 477:                 zerosx = new double[m_numDimensions];
 478:                 zerosy = new double[m_numDimensions];
 479:                 zerosz = new double[m_numDimensions];
 480: 
 481:                 CudaSafeCall( cudaMalloc(&d_zerosx, m_numDimensions * sizeof(double)) );
 482:                 CudaSafeCall( cudaMalloc(&d_zerosy, m_numDimensions * sizeof(double)) );
 483:                 CudaSafeCall( cudaMalloc(&d_zerosz, m_numDimensions * sizeof(double)) );
 484: 
536:                 CudaSafeCall( cudaMalloc(&d_cmx, sizeof(double)) );485:                 CudaSafeCall( cudaMalloc(&d_cmx, sizeof(double)) );
537:                 CudaSafeCall( cudaMalloc(&d_cmy, sizeof(double)) );486:                 CudaSafeCall( cudaMalloc(&d_cmy, sizeof(double)) );
538:                 CudaSafeCall( cudaMalloc(&d_cmz, sizeof(double)) );487:                 CudaSafeCall( cudaMalloc(&d_cmz, sizeof(double)) );
539: 488: 
540:                 CudaSafeCall( cudaMalloc(&d_tmp2, sizeof(double)) );489:                 CudaSafeCall( cudaMalloc(&d_tmp2, sizeof(double)) );
541:                 CudaSafeCall( cudaMalloc(&d_vDot, sizeof(double)) );490:                 CudaSafeCall( cudaMalloc(&d_vDot, sizeof(double)) );
542: 491: 
543: 492: 
544:                 CudaSafeCall( cudaMalloc(&d_tempArray, m_numDimensions * sizeof(double)) );493:                 CudaSafeCall( cudaMalloc(&d_tempArray, m_numDimensions * sizeof(double)) );
545: 494: 
546:                 CudaSafeCall( cudaMemcpy(d_tempArray, m_d_zerosx, m_numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );495:                 for (size_t i = 1; i < (m_numDimensions + 1); ++i) {
 496:                         if ((i + 2)%3 == 0) {
 497:                                 zerosx[i-1] = 1.0;
 498:                         }
 499:                         else {
 500:                                 zerosx[i-1] = 0.0;
 501:                         }
 502:                 }
 503: 
 504:                 for (size_t i = 1; i < (m_numDimensions + 1); ++i) {
 505:                         if ((i + 1)%3 == 0) {
 506:                                 zerosy[i-1] = 1.0;
 507:                         }
 508:                         else {
 509:                                 zerosy[i-1] = 0.0;
 510:                         }
 511:                 }
 512: 
 513:                 for (size_t i = 1; i < (m_numDimensions + 1); ++i) {
 514:                         if (i%3 == 0) {
 515:                                 zerosz[i-1] = 1.0;
 516:                         }
 517:                         else {
 518:                                 zerosz[i-1] = 0.0;
 519:                         }
 520:                 }
 521: 
 522:                 CudaSafeCall( cudaMemcpy(d_zerosx, zerosx, m_numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
 523:                 CudaSafeCall( cudaMemcpy(d_zerosy, zerosy, m_numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
 524:                 CudaSafeCall( cudaMemcpy(d_zerosz, zerosz, m_numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
 525: 
 526:                 CudaSafeCall( cudaMemcpy(d_tempArray, d_zerosx, m_numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );
547: 527: 
548:                 double vDot;528:                 double vDot;
549: 529: 
550:                 m_cublas.dispatchDot(m_numDimensions, d_cmx, m_d_zerosx, m_d_coords); // cmx = zerosx Dot coords530:                 m_cublas.dispatchDot(m_numDimensions, d_cmx, d_zerosx, m_d_coords);
551:                 m_cublas.dispatchDot(m_numDimensions, d_cmy, m_d_zerosy, m_d_coords); // cmy = zerosy Dot coords531:                 m_cublas.dispatchDot(m_numDimensions, d_cmy, d_zerosy, m_d_coords);
552:                 m_cublas.dispatchDot(m_numDimensions, d_cmz, m_d_zerosz, m_d_coords); // cmz = zerosz Dot coords532:                 m_cublas.dispatchDot(m_numDimensions, d_cmz, d_zerosz, m_d_coords);
553: 533: 
554:                 gpu_orthogopt::updateCm<<<1,1>>>(d_cmx, d_cmy, d_cmz);534:                 gpu_orthogopt::updateCm<<<1,1>>>(d_cmx, d_cmy, d_cmz);
555:                 CudaCheckError();535:                 CudaCheckError();
556:                 cudaDeviceSynchronize();536:                 cudaDeviceSynchronize();
557: 537: 
558:                 size_t nCheck = 0;538:                 size_t nCheck = 0;
559:                 for (nCheck =0; nCheck < 100; ++nCheck) {539:                 for (nCheck =0; nCheck < 100; ++nCheck) {
560:                         vDot = 0.0;540:                         vDot = 0.0;
561:                         CudaSafeCall( cudaMemcpy(d_vDot, &vDot, sizeof(double), cudaMemcpyHostToDevice) );541:                         CudaSafeCall( cudaMemcpy(d_vDot, &vDot, sizeof(double), cudaMemcpyHostToDevice) );
562: 542: 
563:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, m_d_zerosx, d_x); // tmp = zerosx Dot x543:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, d_zerosx, d_x);
564: 544: 
565:                         gpu_orthogopt::updatevDotTrans<<<1,1>>>(d_tmp, d_vDot);545:                         gpu_orthogopt::updatevDotTrans<<<1,1>>>(d_tmp, d_vDot);
566:                         CudaCheckError();546:                         CudaCheckError();
567:                         cudaDeviceSynchronize();547:                         cudaDeviceSynchronize();
568: 548: 
569:                         m_cublas.dispatchAxpy (m_numDimensions, d_x, d_x, m_d_zerosx, d_tmp); // x += zerosx * tmp549:                         m_cublas.dispatchAxpy (m_numDimensions, d_x, d_x, d_zerosx, d_tmp);
570: 550: 
571:                         if (shouldNormalise) {551:                         if (shouldNormalise) {
572:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x); // tmp = sqrt(x Dot x)552:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x);
573: 553: 
574:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);554:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);
575:                                 CudaCheckError();555:                                 CudaCheckError();
576:                                 cudaDeviceSynchronize();556:                                 cudaDeviceSynchronize();
577: 557: 
578:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);  // x = tmp*x558:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);
579:                         }559:                         }
580: 560: 
581:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, m_d_zerosy, d_x); // tmp = zerosy Dot x561:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, d_zerosy, d_x);
582: 562: 
583:                         gpu_orthogopt::updatevDotTrans<<<1,1>>>(d_tmp, d_vDot);563:                         gpu_orthogopt::updatevDotTrans<<<1,1>>>(d_tmp, d_vDot);
584:                         CudaCheckError();564:                         CudaCheckError();
585:                         cudaDeviceSynchronize();565:                         cudaDeviceSynchronize();
586: 566: 
587:                         m_cublas.dispatchAxpy (m_numDimensions, d_x, d_x, m_d_zerosy, d_tmp); // x += zerosy * tmp567:                         m_cublas.dispatchAxpy (m_numDimensions, d_x, d_x, d_zerosy, d_tmp);
588: 568: 
589:                         if (shouldNormalise) {569:                         if (shouldNormalise) {
590:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x); // tmp = sqrt(x Dot x)570:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x);
591: 571: 
592:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);572:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);
593:                                 CudaCheckError();573:                                 CudaCheckError();
594:                                 cudaDeviceSynchronize();574:                                 cudaDeviceSynchronize();
595: 575: 
596:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp); // x = tmp*x576:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);
597:                         }577:                         }
598: 578: 
599:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, m_d_zerosz, d_x); // tmp = zerosz Dot x579:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, d_zerosz, d_x);
600: 580: 
601:                         gpu_orthogopt::updatevDotTrans<<<1,1>>>(d_tmp, d_vDot);581:                         gpu_orthogopt::updatevDotTrans<<<1,1>>>(d_tmp, d_vDot);
602:                         CudaCheckError();582:                         CudaCheckError();
603:                         cudaDeviceSynchronize();583:                         cudaDeviceSynchronize();
604: 584: 
605:                         m_cublas.dispatchAxpy (m_numDimensions, d_x, d_x, m_d_zerosz, d_tmp); // x += zerosz * tmp585:                         m_cublas.dispatchAxpy (m_numDimensions, d_x, d_x, d_zerosz, d_tmp);
606: 586: 
607:                         if (shouldNormalise) {587:                         if (shouldNormalise) {
608:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x); // tmp = sqrt(x Dot x)588:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x);
609: 589: 
610:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);590:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);
611:                                 CudaCheckError();591:                                 CudaCheckError();
612:                                 cudaDeviceSynchronize();592:                                 cudaDeviceSynchronize();
613: 593: 
614:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp); // x = tmp*x594:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);
615:                         }595:                         }
616: 596: 
617: 597: 
618:                         blockDim.x = 1024;598:                         blockDim.x = 1024;
619:                         gridDim.x = ((m_numDimensions) + blockDim.x - 1)/blockDim.x;599:                         gridDim.x = ((m_numDimensions) + blockDim.x - 1)/blockDim.x;
620: 600: 
621:                         gpu_orthogopt::rotationalx1<<<gridDim, blockDim>>>(d_x, m_d_coords, d_tempArray, d_cmy, d_cmz);601:                         gpu_orthogopt::rotationalx1<<<gridDim, blockDim>>>(d_x, m_d_coords, d_tempArray, d_cmy, d_cmz);
622:                         CudaCheckError();602:                         CudaCheckError();
623:                         cudaDeviceSynchronize();603:                         cudaDeviceSynchronize();
624: 604: 
625:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, m_d_zerosy, d_tempArray); // tmp = zerosy Dot tempArray605:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, d_zerosy, d_tempArray);
626:                         m_cublas.dispatchDot(m_numDimensions, d_tmp2, m_d_zerosz, d_tempArray); // tmp2 = zerosz Dot tempArray606:                         m_cublas.dispatchDot(m_numDimensions, d_tmp2, d_zerosz, d_tempArray);
627: 607: 
628:                         gpu_orthogopt::updatevDotRot<<<1,1>>>(d_tmp, d_tmp2, d_vDot);608:                         gpu_orthogopt::updatevDotRot<<<1,1>>>(d_tmp, d_tmp2, d_vDot);
629:                         CudaCheckError();609:                         CudaCheckError();
630:                         cudaDeviceSynchronize();610:                         cudaDeviceSynchronize();
631: 611: 
632:                         gpu_orthogopt::rotationalx2<<<gridDim, blockDim>>>(d_x, m_d_coords, d_cmy, d_cmz, d_tmp2);612:                         gpu_orthogopt::rotationalx2<<<gridDim, blockDim>>>(d_x, m_d_coords, d_cmy, d_cmz, d_tmp2);
633:                         CudaCheckError();613:                         CudaCheckError();
634:                         cudaDeviceSynchronize();614:                         cudaDeviceSynchronize();
635: 615: 
636:                         if (shouldNormalise) {616:                         if (shouldNormalise) {
637:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x); // tmp = sqrt(x Dot x)617:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x);
638: 618: 
639:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);619:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);
640:                                 CudaCheckError();620:                                 CudaCheckError();
641:                                 cudaDeviceSynchronize();621:                                 cudaDeviceSynchronize();
642: 622: 
643:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp); // x = tmp*x623:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);
644:                         }624:                         }
645: 625: 
646:                         gpu_orthogopt::rotationaly1<<<gridDim, blockDim>>>(d_x, m_d_coords, d_tempArray, d_cmx, d_cmz);626:                         gpu_orthogopt::rotationaly1<<<gridDim, blockDim>>>(d_x, m_d_coords, d_tempArray, d_cmx, d_cmz);
647:                         CudaCheckError();627:                         CudaCheckError();
648:                         cudaDeviceSynchronize();628:                         cudaDeviceSynchronize();
649: 629: 
650:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, m_d_zerosx, d_tempArray); // tmp = zerosx Dot tempArray630:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, d_zerosx, d_tempArray);
651:                         m_cublas.dispatchDot(m_numDimensions, d_tmp2, m_d_zerosz, d_tempArray); // tmp2 = zerosz Dot tempArray631:                         m_cublas.dispatchDot(m_numDimensions, d_tmp2, d_zerosz, d_tempArray);
652: 632: 
653:                         gpu_orthogopt::updatevDotRot<<<1,1>>>(d_tmp, d_tmp2, d_vDot);633:                         gpu_orthogopt::updatevDotRot<<<1,1>>>(d_tmp, d_tmp2, d_vDot);
654:                         CudaCheckError();634:                         CudaCheckError();
655:                         cudaDeviceSynchronize();635:                         cudaDeviceSynchronize();
656: 636: 
657:                         gpu_orthogopt::rotationaly2<<<gridDim, blockDim>>>(d_x, m_d_coords, d_cmx, d_cmz, d_tmp2);637:                         gpu_orthogopt::rotationaly2<<<gridDim, blockDim>>>(d_x, m_d_coords, d_cmx, d_cmz, d_tmp2);
658:                         CudaCheckError();638:                         CudaCheckError();
659:                         cudaDeviceSynchronize();639:                         cudaDeviceSynchronize();
660: 640: 
661:                         if (shouldNormalise) {641:                         if (shouldNormalise) {
662:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x); // tmp = sqrt(x Dot x)642:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x);
663: 643: 
664:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);644:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);
665:                                 CudaCheckError();645:                                 CudaCheckError();
666:                                 cudaDeviceSynchronize();646:                                 cudaDeviceSynchronize();
667: 647: 
668:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);  // x = tmp*x648:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);
669:                         }649:                         }
670: 650: 
671:                         gpu_orthogopt::rotationalz1<<<gridDim, blockDim>>>(d_x, m_d_coords, d_tempArray, d_cmx, d_cmy);651:                         gpu_orthogopt::rotationalz1<<<gridDim, blockDim>>>(d_x, m_d_coords, d_tempArray, d_cmx, d_cmy);
672:                         CudaCheckError();652:                         CudaCheckError();
673:                         cudaDeviceSynchronize();653:                         cudaDeviceSynchronize();
674: 654: 
675:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, m_d_zerosx, d_tempArray); // tmp = zerosx Dot tempArray655:                         m_cublas.dispatchDot(m_numDimensions, d_tmp, d_zerosx, d_tempArray);
676:                         m_cublas.dispatchDot(m_numDimensions, d_tmp2, m_d_zerosy, d_tempArray); // tmp2 = zerosz Dot tempArray656:                         m_cublas.dispatchDot(m_numDimensions, d_tmp2, d_zerosy, d_tempArray);
677: 657: 
678:                         gpu_orthogopt::updatevDotRot<<<1,1>>>(d_tmp, d_tmp2, d_vDot);658:                         gpu_orthogopt::updatevDotRot<<<1,1>>>(d_tmp, d_tmp2, d_vDot);
679:                         CudaCheckError();659:                         CudaCheckError();
680:                         cudaDeviceSynchronize();660:                         cudaDeviceSynchronize();
681: 661: 
682:                         gpu_orthogopt::rotationalz2<<<gridDim, blockDim>>>(d_x, m_d_coords, d_cmx, d_cmy, d_tmp2);662:                         gpu_orthogopt::rotationalz2<<<gridDim, blockDim>>>(d_x, m_d_coords, d_cmx, d_cmy, d_tmp2);
683:                         CudaCheckError();663:                         CudaCheckError();
684:                         cudaDeviceSynchronize();664:                         cudaDeviceSynchronize();
685: 665: 
686:                         if (shouldNormalise) {666:                         if (shouldNormalise) {
687:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x); // tmp = sqrt(x Dot x)667:                                 m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x);
688: 668: 
689:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);669:                                 gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);
690:                                 CudaCheckError();670:                                 CudaCheckError();
691:                                 cudaDeviceSynchronize();671:                                 cudaDeviceSynchronize();
692: 672: 
693:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp); // x = tmp*x673:                                 m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);
694:                         }674:                         }
695: 675: 
696:                         CudaSafeCall( cudaMemcpy(&vDot, d_vDot, sizeof(double), cudaMemcpyDeviceToHost) );676:                         CudaSafeCall( cudaMemcpy(&vDot, d_vDot, sizeof(double), cudaMemcpyDeviceToHost) );
697:                         if (vDot <= 1.0e-6) {677:                         if (vDot <= 1.0e-6) {
698:                                 break;678:                                 break;
699:                         }679:                         }
700:                 }680:                 }
701: 681: 
702:                 if (nCheck==100) {682:                 if (printingOn && (nCheck==100)) {
703:                         fileHandle << " Warning: cannot orthogonalise to known eigenvectors using orthogopt" << std::endl;683:                         fileHandle << " Warning: cannot orthogonalise to known eigenvectors using orthogopt" << std::endl;
704:                 }684:                 }
705: 685: 
 686:                 delete [] zerosx;
 687:                 delete [] zerosy;
 688:                 delete [] zerosz;
 689: 
 690:                 CudaSafeCall( cudaFree(d_zerosx) );
 691:                 CudaSafeCall( cudaFree(d_zerosy) );
 692:                 CudaSafeCall( cudaFree(d_zerosz) );
 693: 
706:                 CudaSafeCall( cudaFree(d_cmx) );694:                 CudaSafeCall( cudaFree(d_cmx) );
707:                 CudaSafeCall( cudaFree(d_cmy) );695:                 CudaSafeCall( cudaFree(d_cmy) );
708:                 CudaSafeCall( cudaFree(d_cmz) );696:                 CudaSafeCall( cudaFree(d_cmz) );
709: 697: 
710:                 CudaSafeCall( cudaFree(d_tmp2) );698:                 CudaSafeCall( cudaFree(d_tmp2) );
711:                 CudaSafeCall( cudaFree(d_vDot) );699:                 CudaSafeCall( cudaFree(d_vDot) );
712: 700: 
713:                 CudaSafeCall( cudaFree(d_tempArray) );701:                 CudaSafeCall( cudaFree(d_tempArray) );
714:         }702:         }
715:         else {703:         else {
716:                 // Simply normalise. 704:                 // Simply normalise. 
717:                 if (shouldNormalise) {705:                 if (shouldNormalise) {
718:                         m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x); // tmp = sqrt(x Dot x)706:                         m_cublas.dispatchNrm2(m_numDimensions, d_tmp, d_x);
719: 707: 
720:                         gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);708:                         gpu_orthogopt::updateTmp<<<1,1>>>(d_tmp);
721:                         CudaCheckError();709:                         CudaCheckError();
722:                         cudaDeviceSynchronize();710:                         cudaDeviceSynchronize();
723: 711: 
724:                         m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp); // x = tmp*x712:                         m_cublas.dispatchScale(m_numDimensions, d_x, d_x, d_tmp);
725:                 }713:                 }
726:         }714:         }
727: 715: 
728:         CudaSafeCall( cudaFree(d_tmp) );716:         CudaSafeCall( cudaFree(d_tmp) );
729: }717: }
730: 718: 
731:  
732:  
733: namespace gpu_secdiag719: namespace gpu_secdiag
734: {720: {
735:         __global__ void updateDiag(const double *d_fPlus, const double *d_fMinus, const double *m_d_energy, double *d_f, 721:         __global__ void updateDiag(const double *d_fPlus, const double *d_fMinus, const double *m_d_energy, double *d_f, 
736:                         double *d_eigen2, double *d_eigen3, double *d_twoEigen, double *d_twoEigen2)722:                         double *d_eigen2, double *d_eigen3, double *d_twoEigen, double *d_twoEigen2)
737:         {723:         {
738:                 // d_f is a second order central differences expansion of the curvature using energies. 724:                 // d_f is a second order central differences expansion of the curvature using energies. 
739:                 *d_f = (*d_fPlus + *d_fMinus - 2.0*(*m_d_energy))/(zeta*zeta);725:                 *d_f = (*d_fPlus + *d_fMinus - 2.0*(*m_d_energy))/(zeta*zeta);
740:                 // d_eigen2 is a second order central differences expansion of the curvature using gradients. 726:                 // d_eigen2 is a second order central differences expansion of the curvature using gradients. 
741:                 *d_eigen2 = *d_eigen2 / (2.0*zeta);727:                 *d_eigen2 = *d_eigen2 / (2.0*zeta);
742:                 // d_eigen3 is a more accurate estimate of the diagonal second derivative, 728:                 // d_eigen3 is a more accurate estimate of the diagonal second derivative, 
752:                 *d_eigen4 = *d_eigen4/zeta;738:                 *d_eigen4 = *d_eigen4/zeta;
753:                 *d_twoEigen4 = -2.0*(*d_eigen4);739:                 *d_twoEigen4 = -2.0*(*d_eigen4);
754:         }740:         }
755: 741: 
756:         __global__ void calculateDebug(const double *d_fPlus, const double *d_fMinus, double *d_tmp)742:         __global__ void calculateDebug(const double *d_fPlus, const double *d_fMinus, double *d_tmp)
757:         {743:         {
758:                 *d_tmp = (*d_fPlus - *d_fMinus)/(2*zeta);744:                 *d_tmp = (*d_fPlus - *d_fMinus)/(2*zeta);
759:         }745:         }
760: }746: }
761: 747: 
762:  
763:  
764: namespace gpu_freeze748: namespace gpu_freeze
765: {749: {
766: 750: 
767:         __global__ void freezeGrad(double *d_gradient, const bool *m_d_isAtomFrozen)751:         __global__ void freezeGrad(double *d_gradient, const bool *m_d_isAtomFrozen)
768:         {752:         {
769:                 int tid = blockIdx.x * blockDim.x + threadIdx.x;753:                 int tid = blockIdx.x * blockDim.x + threadIdx.x;
 754: 
770:                 while (tid < (numDimensions/3)) {755:                 while (tid < (numDimensions/3)) {
771:                         if (m_d_isAtomFrozen[tid]) {756:                         if (m_d_isAtomFrozen[tid]) {
772:                                 d_gradient[3*tid+0] = 0.0;757:                                 d_gradient[3*tid+0] = 0.0;
773:                                 d_gradient[3*tid+1] = 0.0;758:                                 d_gradient[3*tid+1] = 0.0;
774:                                 d_gradient[3*tid+2] = 0.0;759:                                 d_gradient[3*tid+2] = 0.0;
775:                         }760:                         }
776: 761: 
777:                         tid += blockDim.x * gridDim.x;762:                         tid += blockDim.x * gridDim.x;
778:                 }763:                 }
779:         }764:         }
780: }765: }
781: 766: 
782:  
783:  
784: namespace gpu_orthogopt767: namespace gpu_orthogopt
785: {768: {
786: 769: 
787:         __global__ void rotationalx1(const double *d_x, const double *m_d_coords, double *d_tempArray, const double *d_cmy, 770:         __global__ void rotationalx1(const double *d_x, const double *m_d_coords, double *d_tempArray, const double *d_cmy, 
788:                         const double *d_cmz)771:                         const double *d_cmz)
789:         {772:         {
790:                 int tid = blockIdx.x * blockDim.x + threadIdx.x;773:                 int tid = blockIdx.x * blockDim.x + threadIdx.x;
791: 774: 
792:                 while (tid < (numDimensions/3)) {775:                 while (tid < (numDimensions/3)) {
793:                         d_tempArray[3*tid+1] = d_x[3*tid+1]*(m_d_coords[3*tid+2] - *d_cmz) - 776:                         d_tempArray[3*tid+1] = d_x[3*tid+1]*(m_d_coords[3*tid+2] - *d_cmz) - 


r29015/cost_function.h 2015-11-17 23:33:10.840650135 +0000 r29014/cost_function.h 2015-11-17 23:33:16.420724968 +0000
 30:                 CostFunction(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas, size_t numDimensions, int nDegFreedom,  30:                 CostFunction(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas, size_t numDimensions, int nDegFreedom, 
 31:                                 int nRigidBody, int rigidMaxSite, int *nRigidSitesPerBody, int *rigidGroups, double *sitesRigidBody,  31:                                 int nRigidBody, int rigidMaxSite, int *nRigidSitesPerBody, int *rigidGroups, double *sitesRigidBody, 
 32:                                 int *rigidSingles, double *rigidInverse, double *coords, int nSecDiag, bool isAtomisticNotRigid,  32:                                 int *rigidSingles, double *rigidInverse, double *coords, int nSecDiag, bool isAtomisticNotRigid, 
 33:                                 double aaConvThreshold, double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen, int nFreeze); 33:                                 double aaConvThreshold, double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen, int nFreeze);
 34:  34: 
 35:                 ~CostFunction(); 35:                 ~CostFunction();
 36:  36: 
 37:                 // Calculates secdiag if R-R minimization and calls rigid body transformations and computeEnergyAndGradient.  37:                 // Calculates secdiag if R-R minimization and calls rigid body transformations and computeEnergyAndGradient. 
 38:                 void basePotential(double *d_x, double *d_f, double *d_gradf); 38:                 void basePotential(double *d_x, double *d_f, double *d_gradf);
 39:  39: 
 40:                 // Implement this method computing both function value d_f 
 41:                 // and gradient d_gradf of your cost function at point d_x. 
 42:                 virtual void computeEnergyAndGradient(const double *d_x, double *d_f, double *d_gradf) = 0; 
 43:  
 44:                 void calculateRms(const double *d_gradf, double *outRms); 40:                 void calculateRms(const double *d_gradf, double *outRms);
 45:  41: 
 46:                 size_t getNumDimensions() const; 42:                 size_t getNumDimensions() const;
 47:  43: 
 48:                 int  getnCalls() const; 44:                 int  getnCalls() const;
 49:  45: 
 50:                 bool getIsColdFusion() const; 46:                 bool getIsColdFusion() const;
 51:                 bool getIsRayleighRitz() const; 47:                 bool getIsRayleighRitz() const;
 52:  48: 
 53:                 void setIsRayleighRitz(bool isRayleighRitz); 49:                 void setIsRayleighRitz(bool isRayleighRitz);
 65:                 // More accurate calculation of RMS force for rigid body framework (RBF).  61:                 // More accurate calculation of RMS force for rigid body framework (RBF). 
 66:                 void aaConvergence(const double *d_gradf, double *outRms); 62:                 void aaConvergence(const double *d_gradf, double *outRms);
 67:  63: 
 68:                 // Orthogonalise eigenvector to overall rotations and translations.  64:                 // Orthogonalise eigenvector to overall rotations and translations. 
 69:                 void orthogopt(double *d_x, const bool shouldNormalise); 65:                 void orthogopt(double *d_x, const bool shouldNormalise);
 70:  66: 
 71:                 // Freeze specified atoms by setting gradient components to zero.  67:                 // Freeze specified atoms by setting gradient components to zero. 
 72:                 void freeze(double *d_gradf); 68:                 void freeze(double *d_gradf);
 73:  69: 
 74:         protected: 70:         protected:
  71:                 // Implement this method computing both function value d_f
  72:                 // and gradient d_gradf of your cost function at point d_x.
  73:                 virtual void computeEnergyAndGradient(const double *d_x, double *d_f, double *d_gradf) = 0;
  74: 
 75:                 const size_t m_numDimensions; // Number of dimensions of function - usually 3*natoms.  75:                 const size_t m_numDimensions; // Number of dimensions of function - usually 3*natoms. 
 76:                 bool m_isColdFusion; // True if cold fusion has occurred.  76:                 bool m_isColdFusion; // True if cold fusion has occurred. 
  77:                 bool m_isRayleighRitz; // If true, curvature of PES calculated along direction vec at point coords (R-R min). 
 77:                 const double m_coldFusionLim; // Energy limit below which we say cold fusion has occurred.  78:                 const double m_coldFusionLim; // Energy limit below which we say cold fusion has occurred. 
 78:  79: 
 79:         private: 80:         private:
 80:                 Printing &m_debugPrinting; 81:                 Printing &m_debugPrinting;
 81:  82: 
 82:                 Timer &m_timer_potential; 83:                 Timer &m_timer_potential;
 83:  84: 
 84:                 Cublas &m_cublas; 85:                 Cublas &m_cublas;
 85:  86: 
 86:                 const double  m_aaConvThreshold;      // Threshold under which aaConvergence function is called in RMS force calc. 87:                 const double  m_aaConvThreshold;      // Threshold under which aaConvergence function is called in RMS force calc.
 90:                 const int     m_nSecDiag;             // Method used to approximate eigenvalue in R-R LBFGS. 91:                 const int     m_nSecDiag;             // Method used to approximate eigenvalue in R-R LBFGS.
 91:                 const int     m_nFreeze;              // No. of frozen atoms. 92:                 const int     m_nFreeze;              // No. of frozen atoms.
 92:  93: 
 93:                 int           m_nCalls;               // No. of potential calls made during this invocation of the CUDA code. 94:                 int           m_nCalls;               // No. of potential calls made during this invocation of the CUDA code.
 94:  95: 
 95:                 const bool    m_shouldFreeze;         // If true, freeze some specified coordinates. 96:                 const bool    m_shouldFreeze;         // If true, freeze some specified coordinates.
 96:  97: 
 97:                 const bool   *m_isAtomFrozen;         // Logical array specifying frozen atoms. 98:                 const bool   *m_isAtomFrozen;         // Logical array specifying frozen atoms.
 98:  99: 
 99:                 bool          m_isBfgsts;             // True if costFunction is being used in a Bfgsts calculation - stops aaConvergence call.100:                 bool          m_isBfgsts;             // True if costFunction is being used in a Bfgsts calculation - stops aaConvergence call.
100:                 bool          m_isRayleighRitz;       // If true, curvature of PES calculated along direction vec at point coords (R-R min). 
101: 101: 
102:                 const bool    m_isAtomisticNotRigid;  // If false, use rigid body coordinates.102:                 const bool    m_isAtomisticNotRigid;  // If false, use rigid body coordinates.
103: 103: 
104:                 const double *m_sitesRigidBody;       // RBF: coordinates of the rigid body sites.104:                 const double *m_sitesRigidBody;       // RBF: coordinates of the rigid body sites.
105:                 const double *m_rigidInverse;         // RBF: IINVERSE from genrigid, used in aaConvergence subroutine.105:                 const double *m_rigidInverse;         // RBF: IINVERSE from genrigid, used in aaConvergence subroutine.
106: 106: 
107:                 const int     m_nDegFreedom;          // RBF: no. of degrees of freedom.107:                 const int     m_nDegFreedom;          // RBF: no. of degrees of freedom.
108:                 const int     m_nRigidBody;           // RBF: no. of rigid bodies108:                 const int     m_nRigidBody;           // RBF: no. of rigid bodies
109:                 const int     m_rigidMaxSite;         // RBF: max. no. of sites in a rigid body.109:                 const int     m_rigidMaxSite;         // RBF: max. no. of sites in a rigid body.
110: 110: 
111:                 const int    *m_nRigidSitesPerBody;   // RBF: no. of rigid body sites.111:                 const int    *m_nRigidSitesPerBody;   // RBF: no. of rigid body sites.
112:                 const int    *m_rigidGroups;          // RBF: list of atoms in rigid bodies.112:                 const int    *m_rigidGroups;          // RBF: list of atoms in rigid bodies.
113:                 const int    *m_rigidSingles;         // RBF: list of atoms not in rigid bodies.113:                 const int    *m_rigidSingles;         // RBF: list of atoms not in rigid bodies.
114: 114: 
115: 115: 
116:                 double       *m_d_coords;             // The current coordinates in Bfgsts on GPU, used in R-R minimization. 116:                 double       *m_d_coords;             // The current coordinates in Bfgsts on GPU, used in R-R minimization. 
117:                 double       *m_d_energy;             // The energy at the current coordinates in Bfgsts on GPU, used in R-R minimization. 117:                 double       *m_d_energy;             // The energy at the current coordinates in Bfgsts on GPU, used in R-R minimization. 
118:                 double       *m_d_gradient;           // The gradient at the current coordinates in Bfgsts on GPU, used in R-R minimization. 118:                 double       *m_d_gradient;           // The gradient at the current coordinates in Bfgsts on GPU, used in R-R minimization. 
119:                 double       *m_d_zerosx;             // Array used in cuBLAS operations with ones at all the x positions.  
120:                 double       *m_d_zerosy;             // Array used in cuBLAS operations with ones at all the y positions. 
121:                 double       *m_d_zerosz;             // Array used in cuBLAS operations with ones at all the z positions. 
122: 119: 
123:                 bool         *m_d_isAtomFrozen;       // Logical array specifying frozen atoms, on GPU.120:                 bool         *m_d_isAtomFrozen;       // Logical array specifying frozen atoms, on GPU.
124: 121: 
125:                 double       *m_d_sitesRigidBody;     // RBF: coordinates of the rigid body sites, on GPU.122:                 double       *m_d_sitesRigidBody;     // RBF: coordinates of the rigid body sites, on GPU.
126:                 double       *m_d_rigidInverse;       // RBF: IINVERSE from genrigid, used in aaconvergence subroutine, on GPU.123:                 double       *m_d_rigidInverse;       // RBF: IINVERSE from genrigid, used in aaconvergence subroutine, on GPU.
127:                 double       *m_d_xRigid;             // RBF: rigid body coordinates, on GPU.124:                 double       *m_d_xRigid;             // RBF: rigid body coordinates, on GPU.
128:                 double       *m_d_gkRigid;            // RBF: rigid body gradient, on GPU.125:                 double       *m_d_gkRigid;            // RBF: rigid body gradient, on GPU.
129:                 double       *m_d_gkAtoms;            // RBF: copy of atomistic gradient for use with aaConvergence, on GPU.126:                 double       *m_d_gkAtoms;            // RBF: copy of atomistic gradient for use with aaConvergence, on GPU.
130: 127: 
131:                 int          *m_d_nRigidSitesPerBody; // RBF: no. of rigid body sites, on GPU. 128:                 int          *m_d_nRigidSitesPerBody; // RBF: no. of rigid body sites, on GPU. 
132:                 int          *m_d_rigidGroups;        // RBF: list of atoms in rigid bodies, on GPU. 129:                 int          *m_d_rigidGroups;        // RBF: list of atoms in rigid bodies, on GPU. 
133:                 int          *m_d_rigidSingles;       // RBF: list of atoms not in rigid bodies, on GPU. 130:                 int          *m_d_rigidSingles;       // RBF: list of atoms not in rigid bodies, on GPU. 
134:                 int          *m_d_nRigidBody;         // RBF: no. of rigid bodies, on GPU. 131:                 int          *m_d_nRigidBody;         // RBF: no. of rigid bodies, on GPU. 
135:                 int          *m_d_rigidMaxSite;       // RBF: maximum number of sites in a rigid body, on GPU. 132:                 int          *m_d_rigidMaxSite;       // RBF: maximum number of sites in a rigid body, on GPU. 
136: 133: 
137: 134: 
138:                 // Rigid body gradient transformations either side of energy/gradient call.135:                 // Rigid body gradient transformations either side of energy/gradient call.
139:                 void rigidTransforms(double *d_x, double *d_f, double *d_gradf);136:                 void rigidTransforms(double *d_x, double *d_f, double *d_gradf);
140: };137: };
141: 138: 
142: #endif /* end of include guard: COST_FUNCTION_H */139: #endif /* end of include guard: COST_FUNCTION_H */


r29015/CUDAGMINOPTIM.cu 2015-11-17 23:33:09.320629750 +0000 r29014/CUDAGMINOPTIM.cu 2015-11-17 23:33:14.900704583 +0000
  1: #include <cuda.h>  1: svn: E195012: Unable to find repository location for 'svn+ssh://svn.ch.private.cam.ac.uk/groups/wales/trunk/AMBER12/cuda/CUDAGMINOPTIM.cu' in revision 29014
  2: #include <cuda_runtime.h> 
  3: #include <cuda_runtime_api.h> 
  4: #include <device_launch_parameters.h> 
  5: #include <device_functions.h> 
  6:  
  7: #include "gpu.h" 
  8:  
  9: __constant__ int numatoms; 
 10: __constant__ int simstride1; 
 11: __constant__ int simstride2; 
 12:  
 13: void gminoptim_copy_constants(gpuContext gpu) 
 14: { 
 15:         // Copy gpu->sim.atoms, gpu->sim.stride and gpu->sim.stride2 to GPU for use in later kernels         
 16:  
 17:         cudaError_t status; 
 18:  
 19:         int* natoms; 
 20:         natoms = &(gpu->sim.atoms); 
 21:         status = cudaMemcpyToSymbol(numatoms, natoms, sizeof(int)); 
 22:         RTERROR(status, "cudaMemcpyToSymbol: natoms copy to numatoms failed"); 
 23:  
 24:         int* stride1; 
 25:         stride1 = &(gpu->sim.stride); 
 26:         status = cudaMemcpyToSymbol(simstride1, stride1, sizeof(int)); 
 27:         RTERROR(status, "cudaMemcpyToSymbol: stride1 copy to simstride1 failed"); 
 28:  
 29:         int* stride2; 
 30:         stride2 = &(gpu->sim.stride2); 
 31:         status = cudaMemcpyToSymbol(simstride2, stride2, sizeof(int)); 
 32:         RTERROR(status, "cudaMemcpyToSymbol: stride2 copy to simstride2 failed"); 
 33: } 
 34:  
 35: __global__ void atm_crd_to_devdata(PMEDouble* pbatomdev, PMEFloat2* pbatomxyspdev, PMEFloat* pbatomzspdev, const double* atm_crd) 
 36: { 
 37:         int tid = blockIdx.x * blockDim.x + threadIdx.x; 
 38:  
 39:         while (tid < (numatoms)) 
 40:         { 
 41:                 pbatomdev[tid] = atm_crd[3*tid];                        // x crd copied to double precision locations 
 42:                 pbatomdev[tid + simstride1] = atm_crd[3*tid+1];                // y crd copied to double precision locations 
 43:                 pbatomdev[tid + simstride2] = atm_crd[3*tid+2];                // z crd copied to double precision locations 
 44:                 pbatomxyspdev[tid].x = atm_crd[3*tid];                        // x crd copied to single precision locations 
 45:                 pbatomxyspdev[tid].y = atm_crd[3*tid+1];                // y crd copied to single precision locations 
 46:                 pbatomzspdev[tid] = atm_crd[3*tid+2];                        // z crd copied to single precision locations 
 47:  
 48:                 tid += blockDim.x * gridDim.x; 
 49:         } 
 50:  
 51:         while (tid < (simstride1 - numatoms)) 
 52:         { 
 53:                 pbatomdev[tid+numatoms] = 9999990000.0 + (tid+numatoms) * 2000.0; 
 54:                 pbatomdev[tid+numatoms+simstride1] = 9999990000.0 + (tid+numatoms) * 2000.0; 
 55:                 pbatomdev[tid+numatoms+simstride2] = 9999990000.0 + (tid+numatoms) * 2000.0; 
 56:                 pbatomxyspdev[tid+numatoms].x = 9999990000.0f + (tid+numatoms) * 2000.0; 
 57:                 pbatomxyspdev[tid+numatoms].y = 9999990000.0f + (tid+numatoms) * 2000.0; 
 58:                 pbatomzspdev[tid+numatoms] = 9999990000.0f + (tid+numatoms) * 2000.0; 
 59:  
 60:                 tid += blockDim.x * gridDim.x; 
 61:         } 
 62: } 
 63:  
 64: void gminoptim_copy_atoms(gpuContext& gpu, const double* atm_crd)  
 65: { 
 66:         dim3 blockDim; 
 67:         blockDim.x = 1024; 
 68:         dim3 gridDim; 
 69:         gridDim.x = ((gpu->sim.atoms)+ blockDim.x - 1)/blockDim.x; 
 70:         atm_crd_to_devdata<<<gridDim, blockDim>>>(gpu->pbAtom->_pDevData, gpu->pbAtomXYSP->_pDevData, gpu->pbAtomZSP->_pDevData, atm_crd); 
 71: } 
 72:  
 73: __global__ void get_ene(unsigned long long int* energybuffer, double* energy) 
 74: { 
 75:         extern __shared__ PMEDouble shared_ene[]; 
 76:         int tid = blockIdx.x * blockDim.x + threadIdx.x; 
 77:         shared_ene[tid] = 0.0; 
 78:  
 79:         if (tid < VIRIALOFFSET){ 
 80:                 unsigned long long int val  = energybuffer[tid]; 
 81:                 if (val >= 0x8000000000000000ull) 
 82:                 { 
 83:                         shared_ene[tid]               = -(PMEDouble)(val ^ 0xffffffffffffffffull) / ENERGYSCALE; 
 84:                 } 
 85:                 else 
 86:                 { 
 87:                         shared_ene[tid]               = (PMEDouble)val / ENERGYSCALE; 
 88:                 } 
 89:         } 
 90:         // Shared memory reduction to add up all energy contributions to get a total energy 
 91:         int i = blockDim.x/2; 
 92:         while (i != 0) { 
 93:                 if (tid < i){ 
 94:                         shared_ene[tid] += shared_ene[tid + i]; 
 95:                 } 
 96:                 __syncthreads(); 
 97:                 i /= 2; 
 98:         } 
 99:  
100:         if (tid == 0){ 
101:                 *energy = shared_ene[0];   // Write total energy back to global memory 
102:         } 
103:  
104: } 
105:  
106: extern "C" void gminoptim_copy_ene(gpuContext gpu, double* energy) 
107: { 
108:         dim3 blockDim; 
109:         blockDim.x = 32;        // Power of 2 greater than VIRIALOFFSET for easy reduction 
110:         dim3 gridDim; 
111:         gridDim.x = 1; 
112:         int shared_size = sizeof(PMEDouble) * (blockDim.x); 
113:         get_ene<<<gridDim, blockDim, shared_size>>>(gpu->pbEnergyBuffer->_pDevData, energy); 
114: } 
115:  
116: __global__ void get_frc(PMEDouble* pbforcedev, double* grad) 
117: { 
118:         int tid = blockIdx.x * blockDim.x + threadIdx.x; 
119:  
120:         while (tid < (numatoms)) 
121:         { 
122:                 grad[3*tid] = -1.0 * pbforcedev[tid]; 
123:                 grad[3*tid+1] = -1.0 * pbforcedev[tid+simstride1];  
124:                 grad[3*tid+2] = -1.0 * pbforcedev[tid+simstride2]; 
125:  
126:                 tid += blockDim.x * gridDim.x; 
127:         } 
128: } 
129:  
130: extern "C" void gminoptim_copy_forces(gpuContext gpu, double* gradient) 
131: { 
132:         dim3 blockDim; 
133:         blockDim.x = 1024; 
134:         dim3 gridDim; 
135:         gridDim.x = ((gpu->sim.atoms)+ blockDim.x - 1)/blockDim.x; 
136:         get_frc<<<gridDim, blockDim>>>(gpu->pbForce->_pDevData, gradient);         
137: } 
138:  
139: extern "C" void gminoptim_coords_cputogpu(gpuContext gpu, int *natoms, double *coords) 
140: { 
141:         double *d_coords; 
142:         cudaMalloc(&d_coords, 3 * (*natoms) * sizeof(double)); 
143:         cudaMemcpy(d_coords, coords, 3 * (*natoms) * sizeof(double), cudaMemcpyHostToDevice); 
144:         gminoptim_copy_atoms(gpu, d_coords); 
145:         cudaFree(d_coords); 
146: } 
147:  
148: extern "C" void gminoptim_ene_gputocpu(gpuContext gpu, double *energy) 
149: { 
150:         double *d_energy; 
151:         cudaMalloc(&d_energy, sizeof(double)); 
152:         gminoptim_copy_ene(gpu, d_energy); 
153:         cudaMemcpy(energy, d_energy, sizeof(double), cudaMemcpyDeviceToHost); 
154:         cudaFree(d_energy); 
155: } 
156:  
157: extern "C" void gminoptim_gradients_gputocpu(gpuContext gpu, int *natoms, double *gradients) 
158: { 
159:         double *d_gradients; 
160:         cudaMalloc(&d_gradients, 3 * (*natoms) * sizeof(double)); 
161:         gminoptim_copy_forces(gpu, d_gradients); 
162:         cudaMemcpy(gradients, d_gradients, 3 * (*natoms) * sizeof(double), cudaMemcpyDeviceToHost); 
163:         cudaFree(d_gradients); 
164: } 


r29015/fetchz.f 2015-11-17 23:33:12.972678726 +0000 r29014/fetchz.f 2015-11-17 23:33:18.508752971 +0000
1917:        IF (PGRAD) WRITE(*,'(A,I3,A)') ' fetchz> Gradients along Hessian eigenvectors will be printed every ',NGRADIENTS,' steps'1917:        IF (PGRAD) WRITE(*,'(A,I3,A)') ' fetchz> Gradients along Hessian eigenvectors will be printed every ',NGRADIENTS,' steps'
1918:        IF (EFSTEPST) WRITE(*,'(A,I4,A)') ' fetchz> Maximum unscaled steps for each mode will be printed every ',EFSTEPS,' steps'1918:        IF (EFSTEPST) WRITE(*,'(A,I4,A)') ' fetchz> Maximum unscaled steps for each mode will be printed every ',EFSTEPS,' steps'
1919:        IF (VALUEST) WRITE(*,'(A,I4,A)') ' fetchz> Hessian eigenvalues will be printed every ',NVALUES,' steps'1919:        IF (VALUEST) WRITE(*,'(A,I4,A)') ' fetchz> Hessian eigenvalues will be printed every ',NVALUES,' steps'
1920:        IF (VECTORST) WRITE(*,'(A,I4,A)') ' fetchz> Hessian eigenvectors will be printed every ',NVECTORS,' steps'1920:        IF (VECTORST) WRITE(*,'(A,I4,A)') ' fetchz> Hessian eigenvectors will be printed every ',NVECTORS,' steps'
1921:        WRITE(*,'(A,I3,A)') ' fetchz> Summary of steps and derivatives will be printed every ',NSUMMARY,' steps'1921:        WRITE(*,'(A,I3,A)') ' fetchz> Summary of steps and derivatives will be printed every ',NSUMMARY,' steps'
1922:       ENDIF1922:       ENDIF
1923: 1923: 
1924:       IF (CUDAT) THEN1924:       IF (CUDAT) THEN
1925:          WRITE(*,'(A)') ' fetchz> This calculation will take place on the GPU. '1925:          WRITE(*,'(A)') ' fetchz> This calculation will take place on the GPU. '
1926:          ! Open and close all output files that might be used - ensures output *replaced* when rerunning CUDAOPTIM1926:          ! Open and close all output files that might be used - ensures output *replaced* when rerunning CUDAOPTIM
1927:          CUDAFILENAME1 ="GPU_debug_out"1927:          IF (DEBUG) THEN
1928:          OPEN(UNIT=325, FILE=CUDAFILENAME1, STATUS="REPLACE")1928:             CUDAFILENAME1 ="GPU_debug_out"
1929:          CLOSE(325)1929:             OPEN(UNIT=325, FILE=CUDAFILENAME1, STATUS="REPLACE")
 1930:             CLOSE(325)
 1931:          END IF
1930:          IF (CUDATIMET) THEN1932:          IF (CUDATIMET) THEN
1931:             CUDAFILENAME2 ="GPU_BFGSTS_Rayleigh_Ritz_total.txt"1933:             CUDAFILENAME2 ="GPU_BFGSTS_Rayleigh_Ritz_total.txt"
1932:             CUDAFILENAME3 ="GPU_BFGSTS_subspace_min_total.txt"1934:             CUDAFILENAME3 ="GPU_BFGSTS_subspace_min_total.txt"
1933:             CUDAFILENAME4 ="GPU_BFGSTS_total.txt"1935:             CUDAFILENAME4 ="GPU_BFGSTS_total.txt"
1934:             CUDAFILENAME5 ="GPU_BFGSTS_EF_steps.txt"1936:             CUDAFILENAME5 ="GPU_BFGSTS_EF_steps.txt"
1935:             CUDAFILENAME6 ="GPU_potential.txt"1937:             CUDAFILENAME6 ="GPU_potential.txt"
1936:             OPEN(UNIT=326, FILE=CUDAFILENAME2, STATUS="REPLACE")1938:             OPEN(UNIT=326, FILE=CUDAFILENAME2, STATUS="REPLACE")
1937:             CLOSE(326)1939:             CLOSE(326)
1938:             OPEN(UNIT=327, FILE=CUDAFILENAME3, STATUS="REPLACE")1940:             OPEN(UNIT=327, FILE=CUDAFILENAME3, STATUS="REPLACE")
1939:             CLOSE(327)1941:             CLOSE(327)


r29015/gpu.cpp 2015-11-17 23:33:09.712635005 +0000 r29014/gpu.cpp 2015-11-17 23:33:15.296709894 +0000
821: // Add additional force output for PME reciprocal forces821: // Add additional force output for PME reciprocal forces
822: if (gpu->bNeighborList)822: if (gpu->bNeighborList)
823: {823: {
824:         int buffers = 1;824:         int buffers = 1;
825:         for (int i = 0; i < gpu->sim.atoms; i++)825:         for (int i = 0; i < gpu->sim.atoms; i++)
826:                 gpu->pbOutputBufferCounter->_pSysData[i] = buffers;826:                 gpu->pbOutputBufferCounter->_pSysData[i] = buffers;
827: }827: }
828: gpuCopyConstants();828: gpuCopyConstants();
829: }829: }
830: 830: 
831: // Function below added for CUDAGMIN/CUDAOPTIM831: // Function below added for CUDAGMIN
832: extern "C" void gminoptim_copy_const_()832: extern "C" void gmin_copy_const_()
833: {833: {
834:         gminoptim_copy_constants(gpu);834:         gmin_copy_constants(gpu);
835: }835: }
836: 836: 
837: //Function below added for CUDAGMIN/CUDAOPTIM837: //Function below added for CUDAGMIN
838: extern "C" void gminoptim_enegrad_cputogpu(int *natoms, double *coords, double *energy, double *gradients)838: extern "C" void gmin_enegrad_cputogpu(int *natoms, double *coords, double *energy, double *gradients)
839: {839: {
840:         gminoptim_coords_cputogpu(gpu, natoms, coords);840:         gmin_coords_cputogpu(gpu, natoms, coords);
841:         gminoptim_gpu_gb_ene();841:         gmin_gpu_gb_ene();
842:         gminoptim_ene_gputocpu(gpu, energy);842:         gmin_ene_gputocpu(gpu, energy);
843:         gminoptim_gradients_gputocpu(gpu, natoms, gradients);843:         gmin_gradients_gputocpu(gpu, natoms, gradients);
844: }844: }
845: 845: 
846: // Function below added for CUDAGMIN/CUDAOPTIM846: // Function below added for CUDAGMIN
847: extern "C" void gminoptim_copy_crd(const double* atm_crd)847: extern "C" void gmin_copy_crd(const double* atm_crd)
848: {848: {
849:         gminoptim_copy_atoms(gpu, atm_crd);849:         gmin_copy_atoms(gpu, atm_crd);
850: }850: }
851: 851: 
852: extern "C" void gpu_upload_crd_(double atm_crd[][3])852: extern "C" void gpu_upload_crd_(double atm_crd[][3])
853: {853: {
854:         PRINTMETHOD("gpu_upload_crd");854:         PRINTMETHOD("gpu_upload_crd");
855:         if (gpu->bNeighborList && (gpu->pbImageIndex != NULL))855:         if (gpu->bNeighborList && (gpu->pbImageIndex != NULL))
856:         {856:         {
857:                 if (gpu->bNewNeighborList)857:                 if (gpu->bNewNeighborList)
858:                 {858:                 {
859:                         gpu->pbImageIndex->Download();859:                         gpu->pbImageIndex->Download();
1293:                 for (int i = 0; i < gpu->sim.atoms; i++)1293:                 for (int i = 0; i < gpu->sim.atoms; i++)
1294:                 {1294:                 {
1295:                         atm_frc[i][0]                               = gpu->pbForce->_pSysData[i];1295:                         atm_frc[i][0]                               = gpu->pbForce->_pSysData[i];
1296:                         atm_frc[i][1]                               = gpu->pbForce->_pSysData[i + gpu->sim.stride];1296:                         atm_frc[i][1]                               = gpu->pbForce->_pSysData[i + gpu->sim.stride];
1297:                         atm_frc[i][2]                               = gpu->pbForce->_pSysData[i + gpu->sim.stride2];1297:                         atm_frc[i][2]                               = gpu->pbForce->_pSysData[i + gpu->sim.stride2];
1298:                 } 1298:                 } 
1299:         }1299:         }
1300: #endif1300: #endif
1301: }1301: }
1302: 1302: 
1303: // Function below added for CUDAGMIN/CUDAOPTIM1303: // Function below added for CUDAGMIN
1304: extern "C" void gminoptim_copy_frc(double* atm_grad)1304: extern "C" void gmin_copy_frc(double* atm_grad)
1305: {1305: {
1306:         gminoptim_copy_forces(gpu, atm_grad);1306:         gmin_copy_forces(gpu, atm_grad);
1307: }1307: }
1308: 1308: 
1309: 1309: 
1310: extern "C" void gpu_upload_vel_(double atm_vel[][3])1310: extern "C" void gpu_upload_vel_(double atm_vel[][3])
1311: {1311: {
1312:         PRINTMETHOD("gpu_upload_vel");1312:         PRINTMETHOD("gpu_upload_vel");
1313:         if (gpu->bNeighborList && (gpu->pbImageIndex != NULL))1313:         if (gpu->bNeighborList && (gpu->pbImageIndex != NULL))
1314:         {1314:         {
1315:                 if (gpu->bNewNeighborList)1315:                 if (gpu->bNewNeighborList)
1316:                 {1316:                 {
8614:                 printf("%5d: %32.15f %32.15f %32.15f\n", i, gpu->pbForce->_pSysData[i], gpu->pbForce->_pSysData[i + gpu->sim.stride], gpu->pbForce->_pSysData[i + gpu->sim.stride2]);8614:                 printf("%5d: %32.15f %32.15f %32.15f\n", i, gpu->pbForce->_pSysData[i], gpu->pbForce->_pSysData[i + gpu->sim.stride], gpu->pbForce->_pSysData[i + gpu->sim.stride2]);
8615:                 xsum += gpu->pbForce->_pSysData[i];8615:                 xsum += gpu->pbForce->_pSysData[i];
8616:                 ysum += gpu->pbForce->_pSysData[i + gpu->sim.stride];8616:                 ysum += gpu->pbForce->_pSysData[i + gpu->sim.stride];
8617:                 zsum += gpu->pbForce->_pSysData[i + gpu->sim.stride2];8617:                 zsum += gpu->pbForce->_pSysData[i + gpu->sim.stride2];
8618:         } 8618:         } 
8619:         printf("Sum: %32.15f %32.15f %32.15f\n", xsum, ysum, zsum);8619:         printf("Sum: %32.15f %32.15f %32.15f\n", xsum, ysum, zsum);
8620:         exit(-1);8620:         exit(-1);
8621: #endif  8621: #endif  
8622: }8622: }
8623: 8623: 
8624: // Function below added for CUDAGMIN/CUDAOPTIM8624: // Function below added for CUDAGMIN
8625: extern "C" void gminoptim_gpu_energy(double *totenergy)8625: extern "C" void gmin_gpu_energy(double *totenergy)
8626: {8626: {
8627:         gminoptim_gpu_gb_ene();8627:         gmin_gpu_gb_ene();
8628:         gminoptim_copy_ene(gpu, totenergy);8628:         gmin_copy_ene(gpu, totenergy);
8629: }8629: }
8630: 8630: 
8631: // Function below added for CUDAGMIN/CUDAOPTIM8631: // Function below added for CUDAGMIN
8632: extern "C" void gminoptim_gpu_gb_ene()8632: extern "C" void gmin_gpu_gb_ene()
8633: {8633: {
8634:         kClearForces(gpu);8634:         kClearForces(gpu);
8635: #ifdef use_SPFP8635: #ifdef use_SPFP
8636:         kClearGBBuffers(gpu);8636:         kClearGBBuffers(gpu);
8637: #endif8637: #endif
8638:         if (gpu->ntf != 8)8638:         if (gpu->ntf != 8)
8639:         {8639:         {
8640:                 kCalculateGBBornRadii(gpu);8640:                 kCalculateGBBornRadii(gpu);
8641:                 kReduceGBBornRadii(gpu);8641:                 kReduceGBBornRadii(gpu);
8642: #ifdef MPI       8642: #ifdef MPI       


r29015/gpu.h 2015-11-17 23:33:09.900637526 +0000 r29014/gpu.h 2015-11-17 23:33:15.480712364 +0000
167: extern "C" void kCalculateIPSNonbondEnergy(gpuContext gpu);167: extern "C" void kCalculateIPSNonbondEnergy(gpuContext gpu);
168: extern "C" void kCalculateIPSNonbondForces(gpuContext gpu);168: extern "C" void kCalculateIPSNonbondForces(gpuContext gpu);
169: extern "C" void kNLSkinTest(gpuContext gpu);169: extern "C" void kNLSkinTest(gpuContext gpu);
170: extern "C" void kCalculateAMDWeights(gpuContext gpu);170: extern "C" void kCalculateAMDWeights(gpuContext gpu);
171: extern "C" void kAMDCalcWeightAndScaleForces(gpuContext gpu, PMEDouble pot_ene_tot, PMEDouble dih_ene_tot, PMEDouble fwgt);171: extern "C" void kAMDCalcWeightAndScaleForces(gpuContext gpu, PMEDouble pot_ene_tot, PMEDouble dih_ene_tot, PMEDouble fwgt);
172: extern "C" void kCalculateAmdDihedralEnergy(gpuContext gpu);172: extern "C" void kCalculateAmdDihedralEnergy(gpuContext gpu);
173: #ifdef MPI173: #ifdef MPI
174: extern "C" void kTransposeForces(gpuContext gpu);174: extern "C" void kTransposeForces(gpuContext gpu);
175: #endif175: #endif
176: 176: 
177: // Added for CUDAGMIN/CUDAOPTIM usage177: // Added for CUDAGMIN usage
178: extern "C" void gminoptim_copy_const_();178: extern "C" void gmin_copy_const_();
179: extern "C" void gminoptim_copy_constants(gpuContext gpu);179: extern "C" void gmin_copy_constants(gpuContext gpu);
180: extern "C" void gminoptim_gpu_gb_ene();180: extern "C" void gmin_gpu_gb_ene();
181: extern "C" void gminoptim_gpu_energy(double* totenergy);181: extern "C" void gmin_gpu_energy(double* totenergy);
182: extern "C" void gminoptim_copy_ene(gpuContext gpu, double* energy);182: extern "C" void gmin_copy_ene(gpuContext gpu, double* energy);
183: extern "C" void gminoptim_copy_crd(const double* atm_crd);183: extern "C" void gmin_copy_crd(const double* atm_crd);
184: extern "C" void gminoptim_copy_atoms(gpuContext& gpu, const double* atm_crd);184: extern "C" void gmin_copy_atoms(gpuContext& gpu, const double* atm_crd);
185: extern "C" void gminoptim_copy_frc(double* atm_grad);185: extern "C" void gmin_copy_frc(double* atm_grad);
186: extern "C" void gminoptim_copy_forces(gpuContext gpu, double* gradient);186: extern "C" void gmin_copy_forces(gpuContext gpu, double* gradient);
187: extern "C" void gminoptim_coords_cputogpu(gpuContext gpu, int *natoms, double *coords);187: extern "C" void gmin_coords_cputogpu(gpuContext gpu, int *natoms, double *coords);
188: extern "C" void gminoptim_ene_gputocpu(gpuContext gpu, double *energy);188: extern "C" void gmin_ene_gputocpu(gpuContext gpu, double *energy);
189: extern "C" void gminoptim_gradients_gputocpu(gpuContext gpu, int *natoms, double *gradients);189: extern "C" void gmin_gradients_gputocpu(gpuContext gpu, int *natoms, double *gradients);
190: 190: 
191: #endif191: #endif
192: 192: 
193: 193: 


r29015/keywords.f 2015-11-17 23:33:13.168681354 +0000 r29014/keywords.f 2015-11-17 23:33:18.796756832 +0000
5112:             CALL READF(RESIZE)5112:             CALL READF(RESIZE)
5113: ! 5113: ! 
5114: ! REVERSEUPHILL reverses the gradient component in the uphill direction for5114: ! REVERSEUPHILL reverses the gradient component in the uphill direction for
5115: ! BFGSTS and turns off projection in MYLBFGS.5115: ! BFGSTS and turns off projection in MYLBFGS.
5116: ! 5116: ! 
5117:          ELSE IF (WORD.EQ.'REVERSEUPHILL') THEN5117:          ELSE IF (WORD.EQ.'REVERSEUPHILL') THEN
5118:             REVERSEUPHILLT=.TRUE.5118:             REVERSEUPHILLT=.TRUE.
5119: 5119: 
5120:          ELSE IF (WORD .EQ. 'CUDA') THEN5120:          ELSE IF (WORD .EQ. 'CUDA') THEN
5121:             CUDAT=.TRUE.5121:             CUDAT=.TRUE.
5122:             IF (NITEMS .EQ. 1) THEN5122:             IF(NITEMS .EQ. 2) THEN
5123:                WRITE(*,'(A)') " keywords> You must specify a potential with keyword CUDA. " 
5124:                STOP 
5125:             END IF 
5126:             IF (NITEMS .GT. 1) THEN 
5127:                CALL READA(CUDAPOT)5123:                CALL READA(CUDAPOT)
5128:             END IF5124:                IF (CUDAPOT .EQ. 'A') THEN
5129:             IF (NITEMS .GT. 2) THEN5125:                    WRITE(MYUNIT,'(A)') "keywords> CUDAOPTIM has not yet been optimised for use with AMBER12. "
5130:                WRITE(*,'(A)') " keywords> Too many arguments specified with keyword CUDA. "5126:                    STOP
 5127:                END IF
 5128:             ELSE IF (NITEMS .EQ. 1) THEN
 5129:                WRITE(MYUNIT,'(A)') "keywords> You must specify a potential with keyword CUDA. "
5131:                STOP5130:                STOP
5132:             ENDIF5131:             ELSE
5133:             IF ((CUDAPOT .EQ. 'A') .AND. (.NOT. AMBER12T)) THEN5132:                WRITE(MYUNIT,'(A)') "keywords> The keyword CUDA only takes one argument. "
5134:                WRITE(*,'(A)') " keywords> The AMBER12 keyword must be used with 'CUDA A'. " 
5135:                STOP5133:                STOP
5136:             END IF5134:             ENDIF
5137: 5135: 
5138:       ELSE IF (WORD .EQ. 'CUDATIME') THEN5136:       ELSE IF (WORD .EQ. 'CUDATIME') THEN
5139:          CUDATIMET=.TRUE.5137:          CUDATIMET=.TRUE.
5140: 5138: 
5141: ! ----------------------------------!5139: ! ----------------------------------!
5142: ! hk286 > Generalised rigid body   !5140: ! hk286 > Generalised rigid body   !
5143: ! ----------------------------------!5141: ! ----------------------------------!
5144: 5142: 
5145:          ELSE IF (WORD.EQ.'RIGIDINIT') THEN5143:          ELSE IF (WORD.EQ.'RIGIDINIT') THEN
5146: 5144: 


r29015/lbfgs.cu 2015-11-17 23:33:11.028652654 +0000 r29014/lbfgs.cu 2015-11-17 23:33:16.612727545 +0000
 29:         // Kernels.  29:         // Kernels. 
 30:  30: 
 31:         // Small helper kernels for scalar operations in device memory needed during updates. *** Use with a single thread only! *** 31:         // Small helper kernels for scalar operations in device memory needed during updates. *** Use with a single thread only! ***
 32:         __global__ void update1   (double *alphaOut, const double *sDotZ, const double *rho, double *minusAlphaOut); // First update loop.  32:         __global__ void update1   (double *alphaOut, const double *sDotZ, const double *rho, double *minusAlphaOut); // First update loop. 
 33:         __global__ void update2   (double *alphaMinusBetaOut, const double *rho, const double *yDotZ, const double *alpha); // Second update loop.  33:         __global__ void update2   (double *alphaMinusBetaOut, const double *rho, const double *yDotZ, const double *alpha); // Second update loop. 
 34:         __global__ void update3   (double *rhoOut, double *H0Out, double *yDotS, double *yDotY); // After linesearch. 34:         __global__ void update3   (double *rhoOut, double *H0Out, double *yDotS, double *yDotY); // After linesearch.
 35:  35: 
 36:         __global__ void updateNegative(double *tmpOut); 36:         __global__ void updateNegative(double *tmpOut);
 37: } 37: }
 38:  38: 
 39:  
 40:  
 41: // File linesearch.h is no real header, it contains 39: // File linesearch.h is no real header, it contains
 42: // part of the implementation and must be included 40: // part of the implementation and must be included
 43: // after the variables above have been declared. 41: // after the variables above have been declared.
 44: #include "linesearch.h"  42: #include "linesearch.h" 
 45:  43: 
 46: Lbfgs::Lbfgs(CostFunction &costFunc, Printing &debugPrinting, Timer &timer_total, Timer &timer_updates,  44: Lbfgs::Lbfgs(CostFunction &costFunc, Printing &debugPrinting, Timer &timer_total, Timer &timer_updates, 
 47:                 Timer &timer_linesearch, Cublas &cublas, size_t numDimensions, double H0, int updates, int maxIter,  45:                 Timer &timer_linesearch, Cublas &cublas, size_t numDimensions, double H0, int updates, int maxIter, 
 48:                 double gradEps, double maxStep, double maxFkRise, int nRedMax) 46:                 double gradEps, double maxStep, double maxFkRise, int nRedMax)
 49:         : m_costFunction(costFunc) 47:         : m_costFunction(costFunc)
 50:         , m_debugPrinting(debugPrinting) 48:         , m_debugPrinting(debugPrinting)
 69:         CudaSafeCall( cudaMalloc(&m_d_alpha, m_updates * sizeof(double)) ); 67:         CudaSafeCall( cudaMalloc(&m_d_alpha, m_updates * sizeof(double)) );
 70:         CudaSafeCall( cudaMalloc(&m_d_rho, m_updates * sizeof(double)) ); 68:         CudaSafeCall( cudaMalloc(&m_d_rho, m_updates * sizeof(double)) );
 71:         CudaSafeCall( cudaMalloc(&m_d_zWork, numDimensions * sizeof(double)) ); 69:         CudaSafeCall( cudaMalloc(&m_d_zWork, numDimensions * sizeof(double)) );
 72:  70: 
 73:         CudaSafeCall( cudaMemcpy(m_d_H0, &m_H0, sizeof(double), cudaMemcpyHostToDevice) ); 71:         CudaSafeCall( cudaMemcpy(m_d_H0, &m_H0, sizeof(double), cudaMemcpyHostToDevice) );
 74:  72: 
 75:         CudaSafeCall( cudaMemcpyToSymbol(gpu_lbfgs::maxStep, &m_maxStep,  sizeof(double)) ); 73:         CudaSafeCall( cudaMemcpyToSymbol(gpu_lbfgs::maxStep, &m_maxStep,  sizeof(double)) );
 76:         CudaSafeCall( cudaMemcpyToSymbol(gpu_lbfgs::maxFkRise, &m_maxFkRise,  sizeof(double)) ); 74:         CudaSafeCall( cudaMemcpyToSymbol(gpu_lbfgs::maxFkRise, &m_maxFkRise,  sizeof(double)) );
 77: } 75: }
 78:  76: 
 79:  
 80:  
 81: Lbfgs::~Lbfgs() 77: Lbfgs::~Lbfgs()
 82: { 78: {
 83:         CudaSafeCall( cudaFree(m_d_H0) ); 79:         CudaSafeCall( cudaFree(m_d_H0) );
 84:         CudaSafeCall( cudaFree(m_d_s) ); 80:         CudaSafeCall( cudaFree(m_d_s) );
 85:         CudaSafeCall( cudaFree(m_d_y) ); 81:         CudaSafeCall( cudaFree(m_d_y) );
 86:         CudaSafeCall( cudaFree(m_d_alpha)); 82:         CudaSafeCall( cudaFree(m_d_alpha));
 87:         CudaSafeCall( cudaFree(m_d_rho) ); 83:         CudaSafeCall( cudaFree(m_d_rho) );
 88:         CudaSafeCall( cudaFree(m_d_zWork) ); 84:         CudaSafeCall( cudaFree(m_d_zWork) );
 89: } 85: }
 90:  86: 
 91:  
 92:  
 93: // Get/set functions.  87: // Get/set functions. 
 94:  88: 
 95: void   Lbfgs::setMaxIterations(size_t maxIter) 89: void   Lbfgs::setMaxIterations(size_t maxIter)
 96: { 90: {
 97:         m_maxIter = maxIter; 91:         m_maxIter = maxIter;
 98: } 92: }
 99:  93: 
100: void   Lbfgs::setEvalPercentEps(double evalPercentEps) 94: void   Lbfgs::setEvalPercentEps(double evalPercentEps)
101: { 95: {
102:         m_evalPercentEps = evalPercentEps; 96:         m_evalPercentEps = evalPercentEps;
106: {100: {
107:         m_projectGrad = projectGrad;101:         m_projectGrad = projectGrad;
108: }102: }
109: 103: 
110: void Lbfgs::setDevzWork(double *d_zWork, const size_t arraySize)104: void Lbfgs::setDevzWork(double *d_zWork, const size_t arraySize)
111: {105: {
112:         CudaSafeCall( cudaMemcpy(m_d_zWork, d_zWork, arraySize * sizeof(double), cudaMemcpyDeviceToDevice) );106:         CudaSafeCall( cudaMemcpy(m_d_zWork, d_zWork, arraySize * sizeof(double), cudaMemcpyDeviceToDevice) );
113: }107: }
114: 108: 
115: 109: 
116:  
117: std::string Lbfgs::statusToString(Lbfgs::lStatus lbfgsStatus)110: std::string Lbfgs::statusToString(Lbfgs::lStatus lbfgsStatus)
118: {111: {
119:         switch (lbfgsStatus) {112:         switch (lbfgsStatus) {
120:                 case LBFGS_CONVERGED :113:                 case LBFGS_CONVERGED :
121:                         return "Convergence achieved";114:                         return "Convergence achieved";
122:                 case LBFGS_REACHED_MAX_ITER :115:                 case LBFGS_REACHED_MAX_ITER :
123:                         return "Reached maximum number of iterations";116:                         return "Reached maximum number of iterations";
124:                 case LBFGS_COLD_FUSION_DIAGNOSED :117:                 case LBFGS_COLD_FUSION_DIAGNOSED :
125:                         return "Cold fusion diagnosed";118:                         return "Cold fusion diagnosed";
126:                 case LBFGS_RMS_IS_NAN :119:                 case LBFGS_RMS_IS_NAN :
127:                         return "RMS force was NaN - now reset to 1.0e-100 - if using AMBER igb=1 this can be due to negative Born radii";120:                         return "RMS force was NaN - now reset to 1.0e-100 - if using AMBER igb=1 this can be due to negative Born radii";
128:                 default :121:                 default :
129:                         return "Unknown status";122:                         return "Unknown status";
130:         }123:         }
131: }124: }
132: 125: 
133:  
134:  
135: Lbfgs::lStatus Lbfgs::minimize(double *d_x, double *d_fk, double *d_gk, double *outRms, int *itDone, bool resetHistory)126: Lbfgs::lStatus Lbfgs::minimize(double *d_x, double *d_fk, double *d_gk, double *outRms, int *itDone, bool resetHistory)
136: {127: {
137:         bool printingOn = m_debugPrinting.getPrintingOn();128:         bool printingOn = m_debugPrinting.getPrintingOn();
138:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();129:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();
139: 130: 
140:         if (resetHistory) {131:         if (resetHistory) {
141:                 m_cumulativeIter = 0;132:                 m_cumulativeIter = 0;
142:                 CudaSafeCall( cudaMemcpy(m_d_H0, &m_H0, sizeof(double), cudaMemcpyHostToDevice) );133:                 CudaSafeCall( cudaMemcpy(m_d_H0, &m_H0, sizeof(double), cudaMemcpyHostToDevice) );
143:         }134:         }
144: 135: 
190: 181: 
191:         if (isRayleighRitz) {182:         if (isRayleighRitz) {
192:                 bool shouldNormalise = true;183:                 bool shouldNormalise = true;
193:                 m_costFunction.orthogopt(d_x, shouldNormalise);184:                 m_costFunction.orthogopt(d_x, shouldNormalise);
194:         }185:         }
195: 186: 
196:         // Initialize. 187:         // Initialize. 
197: 188: 
198:         m_costFunction.basePotential(d_x, d_fk, d_gk);189:         m_costFunction.basePotential(d_x, d_fk, d_gk);
199: 190: 
 191:         CudaCheckError();
 192:         cudaDeviceSynchronize();
 193: 
200:         if (m_projectGrad) {194:         if (m_projectGrad) {
201:                 // Save the true gradient. 195:                 // Save the true gradient. 
202:                 CudaSafeCall( cudaMemcpy(d_gkSave, d_gk, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );196:                 CudaSafeCall( cudaMemcpy(d_gkSave, d_gk, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );
203: 197: 
204:                 double thisDot;198:                 double thisDot;
205:                 m_cublas.dispatchDot(numDimensions, &thisDot, m_d_zWork, m_d_zWork, false); // thisDot = zWork Dot zWork199:                 m_cublas.dispatchDot(numDimensions, &thisDot, m_d_zWork, m_d_zWork, false); // thisDot = zWorkDotZwork
206:                 bool iszWorkTooLarge = (abs(thisDot - 1.0) > 1.0e-10); 200:                 bool iszWorkTooLarge = (abs(thisDot - 1.0) > 1.0e-10); 
207:                 if (iszWorkTooLarge) {201:                 if (iszWorkTooLarge) {
208:                         thisDot = 1.0/sqrt(thisDot);202:                         thisDot = 1.0/sqrt(thisDot);
209:                         if (printingOn) {203:                         if (printingOn) {
210:                                 fileHandle << " Renormalising uphill vector by factor of " << thisDot << std::endl;204:                                 fileHandle << " Renormalising uphill vector by factor of " << thisDot << std::endl;
211:                         }205:                         }
212:                         m_cublas.dispatchScale(numDimensions, m_d_zWork, m_d_zWork, &thisDot, false); // zWork = zWork*thisDot206:                         m_cublas.dispatchScale(numDimensions, m_d_zWork, m_d_zWork, &thisDot, false); // zWork = zWork * thisDot
213:                 }207:                 }
214:                 m_cublas.dispatchDot(numDimensions, d_tmp, m_d_zWork, d_gk); // tmp = zWork Dot gk208:                 m_cublas.dispatchDot(numDimensions, d_tmp, m_d_zWork, d_gk); // tmp = zWorkDotGk
215: 209: 
216:                 // tmp = -tmp210:                 // tmp = -tmp
217:                 updateNegative<<<1, 1>>>(d_tmp);211:                 updateNegative<<<1, 1>>>(d_tmp);
218:                 CudaCheckError();212:                 CudaCheckError();
219:                 cudaDeviceSynchronize();213:                 cudaDeviceSynchronize();
220: 214: 
221:                 m_cublas.dispatchAxpy(numDimensions, d_gk, d_gk, m_d_zWork, d_tmp); // gk += zWork*tmp215:                 m_cublas.dispatchAxpy(numDimensions, d_gk, d_gk, m_d_zWork, d_tmp); // gk += zWork * tmp
222:         }        216:         }        
223: 217: 
224:         m_costFunction.calculateRms(d_gk, outRms);218:         m_costFunction.calculateRms(d_gk, outRms);
225: 219: 
226:         double evPercent = 0.0;220:         double evPercent = 0.0;
227: 221: 
228:         lStatus lbfgsStatus = LBFGS_REACHED_MAX_ITER;222:         lStatus lbfgsStatus = LBFGS_REACHED_MAX_ITER;
229:         size_t it = 0;223:         size_t it = 0;
230: 224: 
231:         if (printingOn) {225:         if (printingOn) {
265:                 }259:                 }
266: 260: 
267:                 const double minusOne = -1.0;261:                 const double minusOne = -1.0;
268:                 m_cublas.dispatchScale(numDimensions, d_z, d_gk, &minusOne, false); // z = -gk262:                 m_cublas.dispatchScale(numDimensions, d_z, d_gk, &minusOne, false); // z = -gk
269: 263: 
270:                 const size_t MAX_IDX = std::min<size_t>(m_cumulativeIter, m_updates);264:                 const size_t MAX_IDX = std::min<size_t>(m_cumulativeIter, m_updates);
271: 265: 
272:                 for (size_t i = 1; i <= MAX_IDX; ++i) {266:                 for (size_t i = 1; i <= MAX_IDX; ++i) {
273:                         size_t idx = ((m_cumulativeIter - i) % m_updates);267:                         size_t idx = ((m_cumulativeIter - i) % m_updates);
274: 268: 
275:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_s + idx * numDimensions, d_z); // tmp = s Dot z269:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_s + idx * numDimensions, d_z); // tmp = sDotZ
276: 270: 
277:                         // alpha = tmp * rho271:                         // alpha = tmp * rho
278:                         // tmp = -alpha272:                         // tmp = -alpha
279:                         update1<<<1, 1>>>(m_d_alpha + idx, d_tmp, m_d_rho + idx, d_tmp);273:                         update1<<<1, 1>>>(m_d_alpha + idx, d_tmp, m_d_rho + idx, d_tmp);
280:                         CudaCheckError();274:                         CudaCheckError();
281:                         cudaDeviceSynchronize();275:                         cudaDeviceSynchronize();
282: 276: 
283:                         m_cublas.dispatchAxpy(numDimensions, d_z, d_z, m_d_y + idx * numDimensions, d_tmp); // z += tmp*y277:                         m_cublas.dispatchAxpy(numDimensions, d_z, d_z, m_d_y + idx * numDimensions, d_tmp); // z += tmp * y
284:                 }278:                 }
285: 279: 
286:                 m_cublas.dispatchScale(numDimensions, d_z, d_z, m_d_H0); // z = H0*z280:                 m_cublas.dispatchScale(numDimensions, d_z, d_z, m_d_H0); // z = H0 * z
287: 281: 
288:                 for (size_t i = MAX_IDX; i > 0; --i) {282:                 for (size_t i = MAX_IDX; i > 0; --i) {
289:                         size_t idx = ((m_cumulativeIter - i) % m_updates);283:                         size_t idx = ((m_cumulativeIter - i) % m_updates);
290: 284: 
291:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_y + idx * numDimensions, d_z); // tmp = y Dot z285:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_y + idx * numDimensions, d_z); // tmp = yDotZ
292: 286: 
293:                         // beta = rho * tmp287:                         // beta = rho * tmp
294:                         // tmp = alpha - beta288:                         // tmp = alpha - beta
295:                         update2<<<1, 1>>>(d_tmp, m_d_rho + idx, d_tmp, m_d_alpha + idx);289:                         update2<<<1, 1>>>(d_tmp, m_d_rho + idx, d_tmp, m_d_alpha + idx);
296:                         CudaCheckError();290:                         CudaCheckError();
297:                         cudaDeviceSynchronize();291:                         cudaDeviceSynchronize();
298: 292: 
299:                         m_cublas.dispatchAxpy(numDimensions, d_z, d_z, m_d_s + idx * numDimensions, d_tmp); // z += tmp*s293:                         m_cublas.dispatchAxpy(numDimensions, d_z, d_z, m_d_s + idx * numDimensions, d_tmp); // z += tmp * s
300:                 }294:                 }
301: 295: 
302:                 if (isTimingUpdates) {296:                 if (isTimingUpdates) {
303:                         m_timer_updates.stop();297:                         m_timer_updates.stop();
304:                 }298:                 }
305: 299: 
306:                 if (m_projectGrad) {300:                 if (m_projectGrad) {
307:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_zWork, d_z); // tmp = zWork Dot z301:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_zWork, d_z); // tmp = zWorkDotZ
308: 302: 
309:                         // tmp = -tmp303:                         // tmp = -tmp
310:                         updateNegative<<<1, 1>>>(d_tmp);304:                         updateNegative<<<1, 1>>>(d_tmp);
311:                         CudaCheckError();305:                         CudaCheckError();
312:                         cudaDeviceSynchronize();306:                         cudaDeviceSynchronize();
313: 307: 
314:                         m_cublas.dispatchAxpy(numDimensions, d_z, d_z, m_d_zWork, d_tmp); // z += zWork*tmp308:                         m_cublas.dispatchAxpy(numDimensions, d_z, d_z, m_d_zWork, d_tmp); // z += zWork * tmp
315:                 }309:                 }
316: 310: 
317:                 CudaSafeCall( cudaMemcpy(d_fkm1, d_fk,                 sizeof(double), cudaMemcpyDeviceToDevice) ); // fkm1 = fk;311:                 CudaSafeCall( cudaMemcpy(d_fkm1, d_fk,                 sizeof(double), cudaMemcpyDeviceToDevice) ); // fkm1 = fk;
318:                 CudaSafeCall( cudaMemcpy(d_gkm1, d_gk, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) ); // gkm1 = gk;312:                 CudaSafeCall( cudaMemcpy(d_gkm1, d_gk, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) ); // gkm1 = gk;
319: 313: 
320:                 if (isTimingLinesearch) {314:                 if (isTimingLinesearch) {
321:                         m_timer_linesearch.start();315:                         m_timer_linesearch.start();
322:                 }316:                 }
323: 317: 
324:                 // The linesearch is defined in linesearch.h. 318:                 // The linesearch is defined in linesearch.h. 
337:                 // Update s, y, rho and H_0. 331:                 // Update s, y, rho and H_0. 
338: 332: 
339:                 // s   = x_k - x_{k-1} = step * z333:                 // s   = x_k - x_{k-1} = step * z
340:                 // y   = g_k - g_{k-1}334:                 // y   = g_k - g_{k-1}
341:                 // rho = 1 / (y^T s)335:                 // rho = 1 / (y^T s)
342:                 // H_0 = (y^T s) / (y^T y)336:                 // H_0 = (y^T s) / (y^T y)
343: 337: 
344:                 double *d_curS = m_d_s + (m_cumulativeIter % m_updates) * numDimensions;338:                 double *d_curS = m_d_s + (m_cumulativeIter % m_updates) * numDimensions;
345:                 double *d_curY = m_d_y + (m_cumulativeIter % m_updates) * numDimensions;339:                 double *d_curY = m_d_y + (m_cumulativeIter % m_updates) * numDimensions;
346: 340: 
347:                 m_cublas.dispatchScale(numDimensions, d_curS, d_z,  d_step); // s = step*z341:                 m_cublas.dispatchScale(numDimensions, d_curS, d_z,  d_step); // s = step * z
348:                 m_cublas.dispatchAxpy (numDimensions, d_curY, d_gk, d_gkm1, &minusOne, false); // y = gk - gkm1342:                 m_cublas.dispatchAxpy (numDimensions, d_curY, d_gk, d_gkm1, &minusOne, false); // y = gk - gkm1
349: 343: 
350:                 if (isRayleighRitz) {344:                 if (isRayleighRitz) {
351:                         bool shouldNormalise = true;345:                         bool shouldNormalise = true;
352:                         m_costFunction.orthogopt(d_x, shouldNormalise);346:                         m_costFunction.orthogopt(d_x, shouldNormalise);
353:                 }347:                 }
354: 348: 
355:                 m_cublas.dispatchDot(numDimensions, d_tmp,  d_curY, d_curS); // tmp  = y Dot s349:                 m_cublas.dispatchDot(numDimensions, d_tmp,  d_curY, d_curS); // tmp  = yDotS
356:                 m_cublas.dispatchDot(numDimensions, d_tmp2, d_curY, d_curY); // tmp2 = y Dot y350:                 m_cublas.dispatchDot(numDimensions, d_tmp2, d_curY, d_curY); // tmp2 = yDotY
357: 351: 
358:                 // rho = 1 / tmp352:                 // rho = 1 / tmp
359:                 // H0 = tmp / tmp2353:                 // H0 = tmp / tmp2
360:                 update3<<<1, 1>>>(m_d_rho + (m_cumulativeIter % m_updates), m_d_H0, d_tmp, d_tmp2);354:                 update3<<<1, 1>>>(m_d_rho + (m_cumulativeIter % m_updates), m_d_H0, d_tmp, d_tmp2);
361:                 CudaCheckError();355:                 CudaCheckError();
362:                 cudaDeviceSynchronize();356:                 cudaDeviceSynchronize();
363: 357: 
364:                 if (isTimingUpdates) {358:                 if (isTimingUpdates) {
365:                         m_timer_updates.stop();359:                         m_timer_updates.stop();
366:                 }360:                 }
367: 361: 
368:                 ++m_cumulativeIter;362:                 ++m_cumulativeIter;
369:         }363:         }
370:         //        CudaSafeCall( cudaMemcpy(&printEne, d_fk, sizeof(double), cudaMemcpyDeviceToHost) );364:         //        CudaSafeCall( cudaMemcpy(&printEne, d_fk, sizeof(double), cudaMemcpyDeviceToHost) );
371: 365: 
372:         *itDone = it;366:         *itDone = it;
373: 367: 
374:         if (isRayleighRitz) {368:         if (isRayleighRitz) {
375:                 // Normalise. 369:                 // Normalise. 
376:                 double thisFactor;370:                 double thisFactor;
377:                 m_cublas.dispatchNrm2(numDimensions, &thisFactor, d_x, false); // thisFactor = sqrt(x Dot x)371:                 m_cublas.dispatchNrm2(numDimensions, &thisFactor, d_x, false);
378:                 thisFactor = 1.0/thisFactor;372:                 thisFactor = 1.0/thisFactor;
379:                 m_cublas.dispatchScale(numDimensions, d_x, d_x, &thisFactor, false); // x = thisfactor*x373:                 m_cublas.dispatchScale(numDimensions, d_x, d_x, &thisFactor, false);
380:         }374:         }
381: 375: 
382:         if (printingOn) {376:         if (printingOn) {
383:                 double diagOut;377:                 double diagOut;
384:                 CudaSafeCall( cudaMemcpy(&diagOut, m_d_H0, sizeof(double), cudaMemcpyDeviceToHost) );378:                 CudaSafeCall( cudaMemcpy(&diagOut, m_d_H0, sizeof(double), cudaMemcpyDeviceToHost) );
385:                 fileHandle << " Diagonal inverse Hessian elements = " << std::setw(20) << std::setprecision(10) << diagOut 379:                 fileHandle << " Diagonal inverse Hessian elements = " << std::setw(20) << std::setprecision(10) << diagOut 
386:                         << std::endl;380:                         << std::endl;
387:                 fileHandle << " Reason for termination: " << statusToString(lbfgsStatus) << std::endl;381:                 fileHandle << " Reason for termination: " << statusToString(lbfgsStatus) << std::endl;
388: 382: 
389:                 fileHandle << std::endl;383:                 fileHandle << std::endl;
402:         CudaSafeCall( cudaFree(d_gkSave) );396:         CudaSafeCall( cudaFree(d_gkSave) );
403:         CudaSafeCall( cudaFree(d_z) );397:         CudaSafeCall( cudaFree(d_z) );
404: 398: 
405:         if (isTimingTotal) {399:         if (isTimingTotal) {
406:                 m_timer_total.stop();400:                 m_timer_total.stop();
407:         }401:         }
408: 402: 
409:         return lbfgsStatus;403:         return lbfgsStatus;
410: }404: }
411: 405: 
412:  
413:  
414: // Device / kernel functions406: // Device / kernel functions
415: namespace gpu_lbfgs407: namespace gpu_lbfgs
416: {408: {
417:         __global__ void update1(double *alphaOut, const double *sDotZ, const double *rho, double *minusAlphaOut)409:         __global__ void update1(double *alphaOut, const double *sDotZ, const double *rho, double *minusAlphaOut)
418:         {410:         {
419:                 *alphaOut      = *sDotZ * (*rho);411:                 *alphaOut      = *sDotZ * (*rho);
420:                 *minusAlphaOut = -*alphaOut;412:                 *minusAlphaOut = -*alphaOut;
421:         }413:         }
422: 414: 
423:         __global__ void update2(double *alphaMinusBetaOut, const double *rho, const double *yDotZ, const double *alpha)415:         __global__ void update2(double *alphaMinusBetaOut, const double *rho, const double *yDotZ, const double *alpha)


r29015/linesearch.h 2015-11-17 23:33:11.224655282 +0000 r29014/linesearch.h 2015-11-17 23:33:16.800730065 +0000
 15:  15: 
 16: namespace gpu_lbfgs 16: namespace gpu_lbfgs
 17: { 17: {
 18:         // Variables on the GPU.  18:         // Variables on the GPU. 
 19:  19: 
 20:         __device__ double fNew; 20:         __device__ double fNew;
 21:         __device__ double factor; 21:         __device__ double factor;
 22:         __device__ double stepSize; 22:         __device__ double stepSize;
 23:         __device__ double evPercent; 23:         __device__ double evPercent;
 24:  24: 
 25:         __device__ bool status; 25:         __device__ int status;
 26:  26: 
 27:         __constant__ double maxStep; 27:         __constant__ double maxStep;
 28:         __constant__ double maxFkRise; 28:         __constant__ double maxFkRise;
 29:  29: 
 30:         //Kernels. 30:         //Kernels.
 31:  31: 
 32:         __global__ void adjustStepSize(); 32:         __global__ void adjustStepSize();
 33:         __global__ void checkMaxFkRiseAndEvPc(const double *d_fk, const bool isRayleighRitz); 33:         __global__ void checkMaxFkRiseAndEvPc(const double *d_fk, const bool isRayleighRitz);
 34:         __global__ void reduceStepSize(); 34:         __global__ void reduceStepSize();
 35: } 35: }
 36:  36: 
 37:  
 38:  
 39: bool Lbfgs::linesearch(double *d_x, double *d_z, double *d_fk, double *d_gk, size_t it, Lbfgs::lStatus &lbfgsStatus, double *d_step, 37: bool Lbfgs::linesearch(double *d_x, double *d_z, double *d_fk, double *d_gk, size_t it, Lbfgs::lStatus &lbfgsStatus, double *d_step,
 40:                 double *d_tmp, const double *m_d_zWork, double &evPercent, double *outRms, double *d_gkSave) 38:                 double *d_tmp, const double *m_d_zWork, double &evPercent, double *outRms, double *d_gkSave)
 41: { 39: {
 42:         using namespace gpu_lbfgs; 40:         using namespace gpu_lbfgs;
 43:  41: 
 44:         bool printingOn = m_debugPrinting.getPrintingOn(); 42:         bool printingOn = m_debugPrinting.getPrintingOn();
 45:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle(); 43:         std::ofstream &fileHandle = m_debugPrinting.getFileHandle();
 46:  44: 
 47:         bool isTimingLinesearch = m_timer_linesearch.getTimingOn(); 45:         bool isTimingLinesearch = m_timer_linesearch.getTimingOn();
 48:  46: 
 60:         CudaSafeCall( cudaMalloc((void**)&d_xNew, numDimensions * sizeof(double)) ); 58:         CudaSafeCall( cudaMalloc((void**)&d_xNew, numDimensions * sizeof(double)) );
 61:         CudaSafeCall( cudaMalloc((void**)&d_gNew, numDimensions * sizeof(double)) ); 59:         CudaSafeCall( cudaMalloc((void**)&d_gNew, numDimensions * sizeof(double)) );
 62:  60: 
 63:         CudaSafeCall( cudaGetSymbolAddress((void**)&d_fNew,     gpu_lbfgs::fNew) ); 61:         CudaSafeCall( cudaGetSymbolAddress((void**)&d_fNew,     gpu_lbfgs::fNew) );
 64:         CudaSafeCall( cudaGetSymbolAddress((void**)&d_factor,   gpu_lbfgs::factor) ); 62:         CudaSafeCall( cudaGetSymbolAddress((void**)&d_factor,   gpu_lbfgs::factor) );
 65:         CudaSafeCall( cudaGetSymbolAddress((void**)&d_stepSize, gpu_lbfgs::stepSize) ); 63:         CudaSafeCall( cudaGetSymbolAddress((void**)&d_stepSize, gpu_lbfgs::stepSize) );
 66:  64: 
 67:         bool isFirstStep = (m_cumulativeIter == 0); 65:         bool isFirstStep = (m_cumulativeIter == 0);
 68:         if (isFirstStep) { 66:         if (isFirstStep) {
 69:                 // Make the first guess for the step length cautious.  67:                 // Make the first guess for the step length cautious. 
 70:                 m_cublas.dispatchNrm2(numDimensions, &gNorm, d_gk, false); // gNorm = sqrt(gk Dot gk)         68:                 m_cublas.dispatchNrm2(numDimensions, &gNorm, d_gk, false); // gNorm = sqrt(gkDotgk)        
 71:                 double firstFactor = std::min(1/gNorm, gNorm); 69:                 double firstFactor = std::min(1/gNorm, gNorm);
 72:                 CudaSafeCall( cudaMemcpy(d_factor, &firstFactor, sizeof(double), cudaMemcpyHostToDevice) ); 70:                 CudaSafeCall( cudaMemcpy(d_factor, &firstFactor, sizeof(double), cudaMemcpyHostToDevice) );
 73:         } 71:         }
 74:         else { 72:         else {
 75:                 CudaSafeCall( cudaMemcpy(d_factor, &one, sizeof(double), cudaMemcpyHostToDevice) ); 73:                 CudaSafeCall( cudaMemcpy(d_factor, &one, sizeof(double), cudaMemcpyHostToDevice) );
 76:         } 74:         }
 77:  75: 
 78:         // If the step is pointing uphill, invert it.  76:         // If the step is pointing uphill, invert it. 
 79:         m_cublas.dispatchDot(numDimensions, &dotted, d_z, d_gk, false); // dotted = z Dot gk 77:         m_cublas.dispatchDot(numDimensions, &dotted, d_z, d_gk, false); // dotted = zDotgk
 80:         bool isStepUphill = (dotted > 0.0); 78:         bool isStepUphill = (dotted > 0.0);
 81:         if (isStepUphill) { 79:         if (isStepUphill) {
 82:                 if (printingOn) { 80:                 if (printingOn) {
 83:                         fileHandle << " Warning: step direction was uphill (positive projection onto gradient) - reversing"  81:                         fileHandle << " Warning: step direction was uphill (positive projection onto gradient) - reversing" 
 84:                                 << std::endl; 82:                                 << std::endl;
 85:                 } 83:                 }
 86:                 m_cublas.dispatchScale(numDimensions, d_z, d_z, &minusOne, false); // z = -z 84:                 m_cublas.dispatchScale(numDimensions, d_z, d_z, &minusOne, false); // z = -1 * z
 87:         } 85:         }
 88:  86: 
 89:         m_cublas.dispatchNrm2(numDimensions, d_stepSize, d_z); // stepSize = sqrt(z Dot z) 87:         m_cublas.dispatchNrm2(numDimensions, d_stepSize, d_z); // stepSize = sqrt(zDotZ)
 90:         // Make sure the step is no larger than maxStep.  88:         // Make sure the step is no larger than maxStep. 
 91:         adjustStepSize<<<1,1>>>();                 89:         adjustStepSize<<<1,1>>>();                
 92:         CudaCheckError(); 90:         CudaCheckError();
 93:         cudaDeviceSynchronize(); 91:         cudaDeviceSynchronize();
 94:  92: 
 95:         int nRed = 0; 93:         int nRed = 0;
 96:         for (nRed = 0; nRed < m_nRedMax; ++nRed) { 94:         for (nRed = 0; nRed < m_nRedMax; ++nRed) {
 97:                 m_cublas.dispatchAxpy(numDimensions, d_xNew, d_x, d_z, d_factor); // xNew = x + z*factor 95:                 m_cublas.dispatchAxpy(numDimensions, d_xNew, d_x, d_z, d_factor); // xNew = x + z*factor
 98:  96: 
 99:                 if (isTimingLinesearch) { 97:                 if (isTimingLinesearch) {
100:                         m_timer_linesearch.stop(); 98:                         m_timer_linesearch.stop();
101:                 } 99:                 }
102: 100: 
103:                 // Calculate energy and gradient for proposed step. 101:                 // Calculate energy and gradient for proposed step. 
104:                 m_costFunction.basePotential(d_xNew, d_fNew, d_gNew);102:                 m_costFunction.basePotential(d_xNew, d_fNew, d_gNew);
 103:                 CudaCheckError();
 104:                 cudaDeviceSynchronize();
105: 105: 
106:                 bool isColdFusion = m_costFunction.getIsColdFusion();106:                 bool isColdFusion = m_costFunction.getIsColdFusion();
107:                 if (isColdFusion) {107:                 if (isColdFusion) {
108:                         lbfgsStatus = LBFGS_COLD_FUSION_DIAGNOSED;108:                         lbfgsStatus = LBFGS_COLD_FUSION_DIAGNOSED;
109:                         return false;109:                         return false;
110:                 }110:                 }
111: 111: 
112:                 if (isTimingLinesearch) {112:                 if (isTimingLinesearch) {
113:                         m_timer_linesearch.start();113:                         m_timer_linesearch.start();
114:                 }114:                 }
115: 115: 
116:                 if (m_projectGrad) {116:                 if (m_projectGrad) {
117:                         // Save the true gradient. 117:                         // Save the true gradient. 
118:                         CudaSafeCall( cudaMemcpy(d_gkSave, d_gNew, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );118:                         CudaSafeCall( cudaMemcpy(d_gkSave, d_gNew, numDimensions * sizeof(double), cudaMemcpyDeviceToDevice) );
119: 119: 
120:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_zWork, d_gNew); // tmp = zWork Dot gNew120:                         m_cublas.dispatchDot(numDimensions, d_tmp, m_d_zWork, d_gNew); // tmp = zWorkDotGnew
121: 121: 
122:                         // tmp = -tmp122:                         // tmp = -tmp
123:                         updateNegative<<<1, 1>>>(d_tmp);123:                         updateNegative<<<1, 1>>>(d_tmp);
124:                         CudaCheckError();124:                         CudaCheckError();
125:                         cudaDeviceSynchronize();125:                         cudaDeviceSynchronize();
126: 126: 
127:                         m_cublas.dispatchAxpy(numDimensions, d_gNew, d_gNew, m_d_zWork, d_tmp); // gNew += zWork*tmp127:                         m_cublas.dispatchAxpy(numDimensions, d_gNew, d_gNew, m_d_zWork, d_tmp); // gNew += zWork * tmp
128:                 }128:                 }
129:                 m_costFunction.calculateRms(d_gNew, outRms);129:                 m_costFunction.calculateRms(d_gNew, outRms);
130: 130: 
131:                 // Check whether energy has risen too much and % change in eigenvalue if R-R minimization. 131:                 // Check whether energy has risen too much and % change in eigenvalue if R-R minimization. 
132:                 checkMaxFkRiseAndEvPc<<<1,1>>>(d_fk, isRayleighRitz);132:                 checkMaxFkRiseAndEvPc<<<1,1>>>(d_fk, isRayleighRitz);
133:                 CudaCheckError();133:                 CudaCheckError();
134:                 cudaDeviceSynchronize();134:                 cudaDeviceSynchronize();
135: 135: 
136:                 if (isRayleighRitz) {136:                 if (isRayleighRitz) {
137:                         CudaSafeCall( cudaMemcpyFromSymbol(&evPercent, gpu_lbfgs::evPercent, sizeof(double)) );137:                         CudaSafeCall( cudaMemcpyFromSymbol(&evPercent, gpu_lbfgs::evPercent, sizeof(double)) );
138:                 }138:                 }
139: 139: 
140:                 int isBelowMaxFkRise=false;140:                 int ret=0;
141:                 CudaSafeCall( cudaMemcpyFromSymbol(&isBelowMaxFkRise, gpu_lbfgs::status, sizeof(bool)) );141:                 CudaSafeCall( cudaMemcpyFromSymbol(&ret, gpu_lbfgs::status, sizeof(int)) );
142: 142: 
143:                 double b, testFactor, testStepSize;143:                 double b, testFactor, testStepSize;
 144:                 bool isBelowMaxFkRise = (ret == 1);
144:                 if (isBelowMaxFkRise) {145:                 if (isBelowMaxFkRise) {
145:                         if (printingOn) {146:                         if (printingOn) {
146:                                 CudaSafeCall( cudaMemcpy(&testFactor,   d_factor,   sizeof(double), cudaMemcpyDeviceToHost) );147:                                 CudaSafeCall( cudaMemcpy(&testFactor,   d_factor,   sizeof(double), cudaMemcpyDeviceToHost) );
147:                                 CudaSafeCall( cudaMemcpy(&testStepSize, d_stepSize, sizeof(double), cudaMemcpyDeviceToHost) );148:                                 CudaSafeCall( cudaMemcpy(&testStepSize, d_stepSize, sizeof(double), cudaMemcpyDeviceToHost) );
148:                                 b = testFactor * testStepSize;149:                                 b = testFactor * testStepSize;
149:                                 fileHandle << " LBFGS step = " << std::setw(13) << std::fixed << std::setprecision(9) << b 150:                                 fileHandle << " LBFGS step = " << std::setw(13) << std::fixed << std::setprecision(9) << b 
150:                                         << std::endl;151:                                         << std::endl;
151:                         }152:                         }
152:                         break;153:                         break;
153:                 }154:                 }
194:                         fileHandle << " Eigenvalue % change = " << std::setw(13) << std::fixed << std::setprecision(9) << evPercent 195:                         fileHandle << " Eigenvalue % change = " << std::setw(13) << std::fixed << std::setprecision(9) << evPercent 
195:                                 << std::endl;196:                                 << std::endl;
196:                 }197:                 }
197:         }198:         }
198: 199: 
199:         CudaSafeCall( cudaFree(d_xNew) );200:         CudaSafeCall( cudaFree(d_xNew) );
200:         CudaSafeCall( cudaFree(d_gNew) );201:         CudaSafeCall( cudaFree(d_gNew) );
201:         return true;202:         return true;
202: }203: }
203: 204: 
204:  
205:  
206: namespace gpu_lbfgs205: namespace gpu_lbfgs
207: {206: {
208:         __global__ void adjustStepSize()207:         __global__ void adjustStepSize()
209:         {208:         {
210:                 double a = factor * stepSize;209:                 double a = factor * stepSize;
211:                 if (a > maxStep) {210:                 if (a > maxStep) {
212:                         factor = maxStep / stepSize;211:                         factor = maxStep / stepSize;
213:                 }212:                 }
214:         }213:         }
215: 214: 
216:         __global__ void checkMaxFkRiseAndEvPc(const double *d_fk, const bool isRayleighRitz)215:         __global__ void checkMaxFkRiseAndEvPc(const double *d_fk, const bool isRayleighRitz)
217:         {216:         {
218:                 double df;217:                 double df;
219:                 df = fNew - *d_fk;218:                 df = fNew - *d_fk;
220:                 if (isRayleighRitz) {219:                 if (isRayleighRitz) {
221:                         df = df/fmax(abs(fNew), 1.0e-100);220:                         df = df/fmax(abs(fNew), 1.0e-100);
222:                         evPercent = 100.0*abs(df);221:                         evPercent = 100.0*abs(df);
223:                 }222:                 }
224: 223: 
225:                 if (df < maxFkRise) {224:                 if (df < maxFkRise) {
226:                         status = true;225:                         status = 1;
227:                 }226:                 }
228:                 else {227:                 else {
229:                         status = false;228:                         status = 0;
230:                 }229:                 }
231:         }230:         }
232: 231: 
233:         __global__ void reduceStepSize()232:         __global__ void reduceStepSize()
234:         {233:         {
235:                 factor /= 10.0;234:                 factor /= 10.0;
236:         }235:         }
237: }236: }
238: 237: 
239: #endif // LBFGS_LINESEARCH_H238: #endif // LBFGS_LINESEARCH_H


r29015/lj_potential.cu 2015-11-17 23:33:11.788662850 +0000 r29014/lj_potential.cu 2015-11-17 23:33:17.364737630 +0000
109:                         i /= 2;109:                         i /= 2;
110:                 }110:                 }
111: 111: 
112:                 if (tid==0) {112:                 if (tid==0) {
113:                         // Write total energy back to global memory. 113:                         // Write total energy back to global memory. 
114:                         *d_y = shared_r[0].w;114:                         *d_y = shared_r[0].w;
115:                 }115:                 }
116:         }116:         }
117: }117: }
118: 118: 
119:  
120:  
121: LjPotential::LjPotential(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas, size_t numDimensions, 119: LjPotential::LjPotential(Printing &debugPrinting, Timer &timer_potential, Cublas &cublas, size_t numDimensions, 
122:                 int nDegFreedom, int nRigidBody, int rigidMaxSite, int *nRigidSitesPerBody, 120:                 int nDegFreedom, int nRigidBody, int rigidMaxSite, int *nRigidSitesPerBody, 
123:                 int *rigidGroups, double *sitesRigidBody, int *rigidSingles, double *rigidInverse, 121:                 int *rigidGroups, double *sitesRigidBody, int *rigidSingles, double *rigidInverse, 
124:                 double *coords, int nSecDiag, bool isAtomisticNotRigid, double aaConvThreshold, 122:                 double *coords, int nSecDiag, bool isAtomisticNotRigid, double aaConvThreshold, 
125:                 double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen, int nFreeze)123:                 double coldFusionLim, bool shouldFreeze, bool *isAtomFrozen, int nFreeze)
126: : CostFunction(debugPrinting, timer_potential, cublas, numDimensions, nDegFreedom, nRigidBody, rigidMaxSite, 124: : CostFunction(debugPrinting, timer_potential, cublas, numDimensions, nDegFreedom, nRigidBody, rigidMaxSite, 
127:                 nRigidSitesPerBody, rigidGroups, sitesRigidBody, rigidSingles, rigidInverse, coords, 125:                 nRigidSitesPerBody, rigidGroups, sitesRigidBody, rigidSingles, rigidInverse, coords, 
128:                 nSecDiag, isAtomisticNotRigid, aaConvThreshold, coldFusionLim, shouldFreeze, isAtomFrozen, 126:                 nSecDiag, isAtomisticNotRigid, aaConvThreshold, coldFusionLim, shouldFreeze, isAtomFrozen, 
129:                 nFreeze)127:                 nFreeze)
130: {128: {
131:         // Copy 3*natoms to GPU129:         // Copy 3*natoms to GPU
132:         CudaSafeCall( cudaMemcpyToSymbol(gpu_lj::m_d_numDimensions, &m_numDimensions, sizeof(size_t)) );130:         CudaSafeCall( cudaMemcpyToSymbol(gpu_lj::m_d_numDimensions, &m_numDimensions, sizeof(size_t)) );
133: }131: }
134: 132: 
135:  
136:  
137: void LjPotential::computeEnergyAndGradient(const double *d_x, double *d_f, double *d_gradf)133: void LjPotential::computeEnergyAndGradient(const double *d_x, double *d_f, double *d_gradf)
138: {134: {
139:         dim3 blockDim;135:         dim3 blockDim;
140:         dim3 gridDim;136:         dim3 gridDim;
141: 137: 
142:         // Set launch parameters for main potential kernel. 138:         // Set launch parameters for main potential kernel. 
143:         // No. of threads (1024 is max. per block). 139:         // No. of threads (1024 is max. per block). 
144:         blockDim.x = 1024;140:         blockDim.x = 1024;
145:         int numBlocks = ((m_numDimensions/3) + blockDim.x - 1)/blockDim.x;141:         int numBlocks = ((m_numDimensions/3) + blockDim.x - 1)/blockDim.x;
146:         // Number of blocks (one). 142:         // Number of blocks (one). 


r29015/main.F 2015-11-17 23:33:12.176668050 +0000 r29014/main.F 2015-11-17 23:33:17.752742833 +0000
162: !              END DO162: !              END DO
163: !        END IF163: !        END IF
164: 164: 
165:       IF (RIGIDINIT) THEN165:       IF (RIGIDINIT) THEN
166:           CALL GENRIGID_READ_FROM_FILE ()166:           CALL GENRIGID_READ_FROM_FILE ()
167: ! csw34> Tell the user how many degrees of freedom there are in the system167: ! csw34> Tell the user how many degrees of freedom there are in the system
168:           WRITE(MYUNIT, '(A,I15)') " genrigid> rbodyconfig used to specifiy rigid bodies, degrees of freedom now ", DEGFREEDOMS168:           WRITE(MYUNIT, '(A,I15)') " genrigid> rbodyconfig used to specifiy rigid bodies, degrees of freedom now ", DEGFREEDOMS
169:       END IF169:       END IF
170: 170: 
171:       IF (CUDAT) THEN171:       IF (CUDAT) THEN
172:          IF ((CUDAPOT .EQ. 'A') .AND. (.NOT. AMBER12T)) THEN 
173:             WRITE(MYUNIT,'(A)') " main> The AMBER12 keyword must be used with 'CUDA A'. " 
174:             STOP 
175:          END IF 
176:          IF (DEBUG) THEN172:          IF (DEBUG) THEN
177:             CUDAFILENAME1 ="GPU_debug_out"173:             CUDAFILENAME1 ="GPU_debug_out"
178:             OPEN(UNIT=325, FILE=CUDAFILENAME1, STATUS="REPLACE")174:             OPEN(UNIT=325, FILE=CUDAFILENAME1, STATUS="REPLACE")
179:             CLOSE(325)175:             CLOSE(325)
180:          END IF176:          END IF
181:          IF (CUDATIMET) THEN177:          IF (CUDATIMET) THEN
182:             CUDAFILENAME2 ="GPU_LBFGS_total.txt"178:             CUDAFILENAME2 ="GPU_LBFGS_total.txt"
183:             CUDAFILENAME3 ="GPU_LBFGS_updates.txt"179:             CUDAFILENAME3 ="GPU_LBFGS_updates.txt"
184:             CUDAFILENAME4 ="GPU_LBFGS_linesearch.txt"180:             CUDAFILENAME4 ="GPU_LBFGS_linesearch.txt"
185:             CUDAFILENAME5 ="GPU_potential.txt"181:             CUDAFILENAME5 ="GPU_potential.txt"


r29015/modcudabfgsts.f90 2015-11-17 23:33:13.356683876 +0000 r29014/modcudabfgsts.f90 2015-11-17 23:33:18.984759357 +0000
  1: MODULE MODCUDABFGSTS  1: MODULE MODCUDABFGSTS
  2:   2: 
  3: USE COMMONS, ONLY : NATOMS, DEBUG, NOPT, STPMAX, REDOPATH, IVEC  3: USE COMMONS, ONLY : NATOMS, DEBUG, NOPT, STPMAX, REDOPATH, IVEC
  4:   4: 
  5: USE KEY, ONLY : CUDAPOT, GMAX, CONVU, CONVR, MINMAX, MXSTP, MAXXBFGS, XMAXERISE, CUDATIMET, CFUSIONT, COLDFUSIONLIMIT, XDGUESS, &   5: USE KEY, ONLY : CUDAPOT, GMAX, CONVU, CONVR, MINMAX, MXSTP, MAXXBFGS, XMAXERISE, CUDATIMET, CFUSIONT, COLDFUSIONLIMIT, XDGUESS, & 
  6:                 XMUPDATE, MYUNIT, HINDEX, MASST, SHIFTED, CHECKINDEX, REVERSEUPHILLT, GRADSQ, FREEZE, READV, DUMPV, FIXD, &  6:                 XMUPDATE, MYUNIT, HINDEX, MASST, SHIFTED, CHECKINDEX, REVERSEUPHILLT, GRADSQ, FREEZE, READV, DUMPV, FIXD, &
  7:                 EIGENONLY, NSECDIAG, EVPC, CEIG, NEVS, CHECKOVERLAPT, CHECKNEGATIVET, REOPT, BFGSSTEP, PUSHCUT, PUSHOFF, MAXMAX, &  7:                 EIGENONLY, NSECDIAG, EVPC, CEIG, NEVS, CHECKOVERLAPT, CHECKNEGATIVET, REOPT, BFGSSTEP, PUSHCUT, PUSHOFF, MAXMAX, &
  8:                 TRAD, NBFGSMAX1, NBFGSMAX2, BFGSTSTOL, REPELTST, MUPDATE, MAXBFGS, MAXERISE, DGUESS, NOIT, VARIABLES, NOHESS, &   8:                 TRAD, NBFGSMAX1, NBFGSMAX2, BFGSTSTOL, REPELTST, MUPDATE, MAXBFGS, MAXERISE, DGUESS, NOIT, VARIABLES, NOHESS, & 
  9:                 FROZEN, NFREEZE, PV, FIXAFTER, CPMD, PRINTPTS, TWOENDS, DUMPMAG, NSTEPMIN, AMBER12T  9:                 FROZEN, NFREEZE, PV, FIXAFTER, CPMD, PRINTPTS, TWOENDS, DUMPMAG, NSTEPMIN
 10:  10: 
 11: USE GENRIGID, ONLY : RIGIDINIT, ATOMRIGIDCOORDT, DEGFREEDOMS, NRIGIDBODY, NSITEPERBODY, RIGIDGROUPS, MAXSITE, SITESRIGIDBODY, & 11: USE GENRIGID, ONLY : RIGIDINIT, ATOMRIGIDCOORDT, DEGFREEDOMS, NRIGIDBODY, NSITEPERBODY, RIGIDGROUPS, MAXSITE, SITESRIGIDBODY, &
 12:                      RIGIDSINGLES, IINVERSE 12:                      RIGIDSINGLES, IINVERSE
 13:  13: 
 14: USE ZWK, ONLY : NUP, ZWORK 14: USE ZWK, ONLY : NUP, ZWORK
 15:  15: 
 16: USE MODNEB, ONLY : NEWCONNECTT, NEWNEBT 16: USE MODNEB, ONLY : NEWCONNECTT, NEWNEBT
 17:  17: 
 18: USE INTCOMMONS, ONLY : BONDSFROMFILE 18: USE INTCOMMONS, ONLY : BONDSFROMFILE
 19:  19: 
 20: USE INTERNALS_WRAPPER, ONLY : INTWRAP_USEINTERNALS 20: USE INTERNALS_WRAPPER, ONLY : INTWRAP_USEINTERNALS
 21:  21: 
 22: USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT, C_DOUBLE, C_BOOL, C_CHAR 22: USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT, C_DOUBLE, C_BOOL, C_CHAR
 23:  23: 
 24: IMPLICIT NONE 24: IMPLICIT NONE
 25:  25: 
 26: INTERFACE 26: INTERFACE
 27:     SUBROUTINE CUDA_BFGSTS(C_NATOMS, C_COORDS, C_CEIG, C_MFLAG, C_ENERGY, C_NEVS, ITMAX, C_ITER, C_MAXXBFGS, C_XMAXERISE, C_RMS, & 27:     SUBROUTINE CUDA_BFGSTS(C_NATOMS, C_COORDS, C_CEIG, C_MFLAG, C_ENERGY, C_NEVS, ITMAX, C_ITER, C_MAXXBFGS, C_XMAXERISE, C_RMS, &
 28:                           C_CUDAPOT, C_DEBUG, C_CUDATIMET, NCALLS, C_CFUSIONT, C_COLDFUSIONLIMIT, C_XDGUESS, C_XMUPDATE, & 28:                           C_CUDAPOT, C_DEBUG, C_CUDATIMET, ECALLS, C_CFUSIONT, C_COLDFUSIONLIMIT, C_XDGUESS, C_XMUPDATE, &
 29:                           C_EVALMIN, C_VECS, C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, & 29:                           C_EVALMIN, C_VECS, C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, &
 30:                           C_MAXSITE, C_SITESRIGIDBODY, C_RIGIDSINGLES, C_IINVERSE, C_NSECDIAG, C_EVPC, & 30:                           C_MAXSITE, C_SITESRIGIDBODY, C_RIGIDSINGLES, C_IINVERSE, C_NSECDIAG, C_EVPC, &
 31:                           C_PUSHCUT, C_PUSHOFF, C_STPMAX, C_MAXMAX, C_MINMAX, C_TRAD, C_NBFGSMAX1, C_NBFGSMAX2, C_BFGSTSTOL, & 31:                           C_PUSHCUT, C_PUSHOFF, C_STPMAX, C_MAXMAX, C_MINMAX, C_TRAD, C_NBFGSMAX1, C_NBFGSMAX2, C_BFGSTSTOL, &
 32:                           C_MUPDATE, C_GMAX, C_MAXBFGS, C_MAXERISE, C_DGUESS, C_CONVU, C_FREEZE, C_FROZEN, &  32:                           C_MUPDATE, C_GMAX, C_MAXBFGS, C_MAXERISE, C_DGUESS, C_CONVU, C_FREEZE, C_FROZEN, & 
 33:                           C_NFREEZE, POTENTIALTIME)BIND(C,NAME="setup_bfgsts") 33:                           C_NFREEZE)BIND(C,NAME="setup_bfgsts")
 34:  34: 
 35:         IMPORT :: C_INT, C_DOUBLE, C_BOOL, C_CHAR 35:         IMPORT :: C_INT, C_DOUBLE, C_BOOL, C_CHAR
 36:  36: 
 37:         INTEGER(KIND=C_INT), INTENT(IN) :: C_NATOMS, & ! No. of atoms 37:         INTEGER(KIND=C_INT), INTENT(IN) :: C_NATOMS, & ! No. of atoms
 38:                                            ITMAX, & ! Max. no. of BFGSTS iterations allowed 38:                                            ITMAX, & ! Max. no. of BFGSTS iterations allowed
 39:                                            C_DEGFREEDOMS, & ! Rigid Body Framework (RBF): no. of degrees of freedom 39:                                            C_DEGFREEDOMS, & ! Rigid Body Framework (RBF): no. of degrees of freedom
 40:                                            C_NRIGIDBODY, & ! RBF: no. of rigid bodies 40:                                            C_NRIGIDBODY, & ! RBF: no. of rigid bodies
 41:                                            C_MAXSITE, & ! RBF: max. no. of sites in a rigid body 41:                                            C_MAXSITE, & ! RBF: max. no. of sites in a rigid body
 42:                                            C_XMUPDATE, & ! History size for Rayleigh-Ritz (R-R) LBFGS minimization 42:                                            C_XMUPDATE, & ! History size for Rayleigh-Ritz (R-R) LBFGS minimization
 43:                                            C_NSECDIAG, & ! Method used to approximate eigenvalue in R-R LBFGS 43:                                            C_NSECDIAG, & ! Method used to approximate eigenvalue in R-R LBFGS
 47:                                            C_MUPDATE, & ! History size for restricted LBFGS minimization 47:                                            C_MUPDATE, & ! History size for restricted LBFGS minimization
 48:                                            C_NFREEZE ! No. of frozen atoms 48:                                            C_NFREEZE ! No. of frozen atoms
 49:  49: 
 50:         INTEGER(KIND=C_INT), DIMENSION(C_NRIGIDBODY), INTENT(IN) :: C_NSITEPERBODY ! RBF: no. of rigid body sites 50:         INTEGER(KIND=C_INT), DIMENSION(C_NRIGIDBODY), INTENT(IN) :: C_NSITEPERBODY ! RBF: no. of rigid body sites
 51:  51: 
 52:         INTEGER(KIND=C_INT), DIMENSION(C_MAXSITE*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDGROUPS ! RBF: list of atoms in rigid bodies 52:         INTEGER(KIND=C_INT), DIMENSION(C_MAXSITE*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDGROUPS ! RBF: list of atoms in rigid bodies
 53:  53: 
 54:         INTEGER(KIND=C_INT), DIMENSION(C_DEGFREEDOMS/3 - 2*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDSINGLES ! RBF: list of atoms not in rigid bodies 54:         INTEGER(KIND=C_INT), DIMENSION(C_DEGFREEDOMS/3 - 2*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDSINGLES ! RBF: list of atoms not in rigid bodies
 55:  55: 
 56:         INTEGER(KIND=C_INT), INTENT(OUT) :: C_ITER, & ! No. of BFGSTS iterations done 56:         INTEGER(KIND=C_INT), INTENT(OUT) :: C_ITER, & ! No. of BFGSTS iterations done
 57:                                             NCALLS ! No. of potential calls made during this call to BFGSTS  57:                                             ECALLS ! No. of potential calls made during this call to BFGSTS 
 58:  58: 
 59:         REAL(KIND=C_DOUBLE), INTENT(IN) :: C_CEIG, & ! Convergence tolerance for RMS force for R-R LBFGS 59:         REAL(KIND=C_DOUBLE), INTENT(IN) :: C_CEIG, & ! Convergence tolerance for RMS force for R-R LBFGS
 60:                                            C_MAXXBFGS, & ! Max. step size allowed for R-R LBFGS 60:                                            C_MAXXBFGS, & ! Max. step size allowed for R-R LBFGS
 61:                                            C_XMAXERISE, & ! Max. energy rise allowed for R-R LBFGS 61:                                            C_XMAXERISE, & ! Max. energy rise allowed for R-R LBFGS
 62:                                            C_COLDFUSIONLIMIT, & ! Limit below which cold fusion is diagnosed and BFGSTS terminated 62:                                            C_COLDFUSIONLIMIT, & ! Limit below which cold fusion is diagnosed and BFGSTS terminated
 63:                                            C_XDGUESS, & ! Initial guess for R-R inverse Hessian diagonal elements 63:                                            C_XDGUESS, & ! Initial guess for R-R inverse Hessian diagonal elements
 64:                                            C_EVPC, & ! Convergence condition for abs(% change) in eigenvalue for R-R LBFGS 64:                                            C_EVPC, & ! Convergence condition for abs(% change) in eigenvalue for R-R LBFGS
 65:                                            C_PUSHCUT, & ! RMS threshold under which a pushoff will be applied 65:                                            C_PUSHCUT, & ! RMS threshold under which a pushoff will be applied
 66:                                            C_PUSHOFF, & ! Magnitude of step away from transition state 66:                                            C_PUSHOFF, & ! Magnitude of step away from transition state
 67:                                            C_STPMAX, & ! Max. step along the eigenvector 67:                                            C_STPMAX, & ! Max. step along the eigenvector
 77:  77: 
 78:         REAL(KIND=C_DOUBLE), DIMENSION(C_MAXSITE*3*C_NRIGIDBODY), INTENT(IN) :: C_SITESRIGIDBODY ! RBF: coordinates of the rigid body sites 78:         REAL(KIND=C_DOUBLE), DIMENSION(C_MAXSITE*3*C_NRIGIDBODY), INTENT(IN) :: C_SITESRIGIDBODY ! RBF: coordinates of the rigid body sites
 79:  79: 
 80:         REAL(KIND=C_DOUBLE), DIMENSION(C_NRIGIDBODY*3*3), INTENT(IN) :: C_IINVERSE ! RBF: from genrigid, used in aaconvergence subroutine 80:         REAL(KIND=C_DOUBLE), DIMENSION(C_NRIGIDBODY*3*3), INTENT(IN) :: C_IINVERSE ! RBF: from genrigid, used in aaconvergence subroutine
 81:  81: 
 82:         REAL(KIND=C_DOUBLE), DIMENSION(3*C_NATOMS), INTENT(INOUT) :: C_COORDS, & ! Coordinates 82:         REAL(KIND=C_DOUBLE), DIMENSION(3*C_NATOMS), INTENT(INOUT) :: C_COORDS, & ! Coordinates
 83:                                                                      C_VECS ! Lowest eigenvector 83:                                                                      C_VECS ! Lowest eigenvector
 84:  84: 
 85:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_ENERGY, & ! Energy at coordinates C_COORDS 85:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_ENERGY, & ! Energy at coordinates C_COORDS
 86:                                             C_RMS, & ! RMS force 86:                                             C_RMS, & ! RMS force
 87:                                             C_EVALMIN, & ! Smallest eigenvalue 87:                                             C_EVALMIN ! Smallest eigenvalue
 88:                                             POTENTIALTIME ! Time taken in calculating potential 
 89:  88: 
 90:         LOGICAL(KIND=C_BOOL), INTENT(IN) :: C_DEBUG, & ! If true, print debug info. 89:         LOGICAL(KIND=C_BOOL), INTENT(IN) :: C_DEBUG, & ! If true, print debug info.
 91:                                             C_CUDATIMET, & ! If true, print timing info. 90:                                             C_CUDATIMET, & ! If true, print timing info.
 92:                                             C_ATOMRIGIDCOORDT, & ! If false, use rigid body coordinates 91:                                             C_ATOMRIGIDCOORDT, & ! If false, use rigid body coordinates
 93:                                             C_FREEZE ! If true, freeze some specified coordinates 92:                                             C_FREEZE ! If true, freeze some specified coordinates
 94:  93: 
 95:         LOGICAL(KIND=C_BOOL), DIMENSION(C_NATOMS), INTENT(IN) :: C_FROZEN ! Logical array specifying frozen atoms 94:         LOGICAL(KIND=C_BOOL), DIMENSION(C_NATOMS), INTENT(IN) :: C_FROZEN ! Logical array specifying frozen atoms
 96:  95: 
 97:         LOGICAL(KIND=C_BOOL), INTENT(OUT) :: C_MFLAG, & ! True if converged to a transition state 96:         LOGICAL(KIND=C_BOOL), INTENT(OUT) :: C_MFLAG, & ! True if converged to a transition state
 98:                                              C_CFUSIONT ! Set to true during BFGSTS if cold fusion diagnosed 97:                                              C_CFUSIONT ! Set to true during BFGSTS if cold fusion diagnosed
100:         CHARACTER(LEN=1, KIND=C_CHAR), INTENT(IN) :: C_CUDAPOT ! Character specifying the CUDA potential to be used 99:         CHARACTER(LEN=1, KIND=C_CHAR), INTENT(IN) :: C_CUDAPOT ! Character specifying the CUDA potential to be used
101: 100: 
102:     END SUBROUTINE CUDA_BFGSTS101:     END SUBROUTINE CUDA_BFGSTS
103: END INTERFACE102: END INTERFACE
104:  103:  
105: CONTAINS104: CONTAINS
106: 105: 
107:     SUBROUTINE CUDA_BFGSTS_WRAPPER(ITMAX,COORDS,ENERGY,MFLAG,RMS,EVALMIN,VECS,ITER)106:     SUBROUTINE CUDA_BFGSTS_WRAPPER(ITMAX,COORDS,ENERGY,MFLAG,RMS,EVALMIN,VECS,ITER)
108: 107: 
109:         ! Variables passed as *arguments through this wrapper* (not common) with intent in for CUDA_BFGSTS are converted directly108:         ! Variables passed as *arguments through this wrapper* (not common) with intent in for CUDA_BFGSTS are converted directly
110:         INTEGER(KIND=C_INT) :: C_NATOMS, ITMAX, C_ITER, NCALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, C_XMUPDATE, &109:         INTEGER(KIND=C_INT) :: C_NATOMS, ITMAX, C_ITER, ECALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, C_XMUPDATE, &
111:                                C_NSECDIAG, C_NEVS, C_NBFGSMAX1, C_NBFGSMAX2, C_MUPDATE, C_NFREEZE110:                                C_NSECDIAG, C_NEVS, C_NBFGSMAX1, C_NBFGSMAX2, C_MUPDATE, C_NFREEZE
112:         INTEGER(KIND=C_INT), DIMENSION(NRIGIDBODY) :: C_NSITEPERBODY111:         INTEGER(KIND=C_INT), DIMENSION(NRIGIDBODY) :: C_NSITEPERBODY
113:         INTEGER(KIND=C_INT), DIMENSION(MAXSITE*NRIGIDBODY) :: C_RIGIDGROUPS112:         INTEGER(KIND=C_INT), DIMENSION(MAXSITE*NRIGIDBODY) :: C_RIGIDGROUPS
114:         INTEGER(KIND=C_INT), DIMENSION(DEGFREEDOMS/3 - 2*NRIGIDBODY) :: C_RIGIDSINGLES113:         INTEGER(KIND=C_INT), DIMENSION(DEGFREEDOMS/3 - 2*NRIGIDBODY) :: C_RIGIDSINGLES
115: 114: 
116:         REAL(KIND=C_DOUBLE) :: C_CEIG, C_ENERGY, C_RMS, C_XDGUESS, C_EVALMIN, C_MAXXBFGS, C_XMAXERISE, C_COLDFUSIONLIMIT, &115:         REAL(KIND=C_DOUBLE) :: C_CEIG, C_ENERGY, C_RMS, C_XDGUESS, C_EVALMIN, C_MAXXBFGS, C_XMAXERISE, C_COLDFUSIONLIMIT, &
117:                                C_EVPC, C_PUSHCUT, C_PUSHOFF, C_STPMAX, C_MAXMAX, C_MINMAX, C_TRAD, C_BFGSTSTOL, C_GMAX, &116:                                C_EVPC, C_PUSHCUT, C_PUSHOFF, C_STPMAX, C_MAXMAX, C_MINMAX, C_TRAD, C_BFGSTSTOL, C_GMAX, &
118:                                C_MAXBFGS, C_MAXERISE, C_DGUESS, C_CONVU, POTENTIALTIME117:                                C_MAXBFGS, C_MAXERISE, C_DGUESS, C_CONVU
119:         REAL(KIND=C_DOUBLE), DIMENSION(MAXSITE*3*NRIGIDBODY) :: C_SITESRIGIDBODY 118:         REAL(KIND=C_DOUBLE), DIMENSION(MAXSITE*3*NRIGIDBODY) :: C_SITESRIGIDBODY 
120:         REAL(KIND=C_DOUBLE), DIMENSION(NRIGIDBODY*3*3) :: C_IINVERSE119:         REAL(KIND=C_DOUBLE), DIMENSION(NRIGIDBODY*3*3) :: C_IINVERSE
121:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS) :: C_COORDS, C_VECS120:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS) :: C_COORDS, C_VECS
122: 121: 
123:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_CFUSIONT, C_ATOMRIGIDCOORDT, C_FREEZE122:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_CFUSIONT, C_ATOMRIGIDCOORDT, C_FREEZE
124:         LOGICAL(KIND=C_BOOL), DIMENSION(NATOMS) :: C_FROZEN123:         LOGICAL(KIND=C_BOOL), DIMENSION(NATOMS) :: C_FROZEN
125: 124: 
126:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT125:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT
127: 126: 
128:         ! Variables passed as *arguments through this wrapper* (not common) with intent out for CUDA_BFGSTS are not passed into it127:         ! Variables passed as *arguments through this wrapper* (not common) with intent out for CUDA_BFGSTS are not passed into it
129:         ! Therefore uninitialised C types are passed in and converted types are copied back after the call128:         ! Therefore uninitialised C types are passed in and converted types are copied back after the call
130: 129: 
131:         INTEGER :: I, J, K, ITER, FCALL, NPCALL, ECALL, SCALL130:         INTEGER :: I, J, K, ITER, FCALL
132:         DOUBLE PRECISION :: ENERGY, RMS, EVALMIN, FTIME, ETIME, STIME131:         DOUBLE PRECISION :: ENERGY, RMS, EVALMIN 
133:         DOUBLE PRECISION, DIMENSION(3*NATOMS) :: COORDS, VECS132:         DOUBLE PRECISION, DIMENSION(3*NATOMS) :: COORDS, VECS
134:         LOGICAL :: MFLAG, KNOWE, KNOWG, KNOWH, DRAGT, DOINTERNALSTRANSFORM133:         LOGICAL :: MFLAG, KNOWE, KNOWG, KNOWH, DRAGT, DOINTERNALSTRANSFORM
135:         COMMON /PCALL/ NPCALL, ECALL, FCALL, SCALL, ETIME, FTIME, STIME134:         COMMON /PCALL/ FCALL
136:         COMMON /KNOWN/ KNOWE, KNOWG, KNOWH135:         COMMON /KNOWN/ KNOWE, KNOWG, KNOWH
137:         COMMON /RUNTYPE/ DRAGT136:         COMMON /RUNTYPE/ DRAGT
138: 137: 
139:         IF (.NOT. NOHESS) THEN138:         IF (.NOT. NOHESS) THEN
140:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Keyword NOHESS must be used. "139:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Keyword NOHESS must be used. "
141:             STOP140:             STOP
142:         END IF141:         END IF
143: 142: 
144:         DOINTERNALSTRANSFORM = INTWRAP_USEINTERNALS()143:         DOINTERNALSTRANSFORM = INTWRAP_USEINTERNALS()
145: 144: 
150:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Keywords MASS, CHECKINDEX, REVERSEUPHILLT, GRADSQ, READVEC, &149:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Keywords MASS, CHECKINDEX, REVERSEUPHILLT, GRADSQ, READVEC, &
151:                                  DUMPVECTOR, FIXD, EIGENONLY, CHECKOVERLAPT, CHECKNEGATIVET, REDOPATH, REOPT, BFGSSTEP, REPELTST, &150:                                  DUMPVECTOR, FIXD, EIGENONLY, CHECKOVERLAPT, CHECKNEGATIVET, REDOPATH, REOPT, BFGSSTEP, REPELTST, &
152:                                  NOIT, VARIABLES, FIXAFTER, PV, MODE, MODEDOWN, CPMD, DRAG, TWOENDS, INTMIN, BONDSFROMFILE, & 151:                                  NOIT, VARIABLES, FIXAFTER, PV, MODE, MODEDOWN, CPMD, DRAG, TWOENDS, INTMIN, BONDSFROMFILE, & 
153:                                  DUMPMAG, STEPMIN are not yet supported. & 152:                                  DUMPMAG, STEPMIN are not yet supported. & 
154:                                  Contact rgm38 if you would like a feature to be added. "153:                                  Contact rgm38 if you would like a feature to be added. "
155:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Disclaimer: this list might not be exhaustive! "154:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Disclaimer: this list might not be exhaustive! "
156:             STOP155:             STOP
157:         END IF156:         END IF
158: 157: 
159:         IF (PRINTPTS) THEN158:         IF (PRINTPTS) THEN
160:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Keyword NOPOINTS must be used. & 159:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Keyword NOPOINTS must be used. Functionality to print coordinates/energies is coming soon! "
161:                                  Functionality to print coordinates/energies will be added at some point in the future. " 
162:             STOP160:             STOP
163:         END IF161:         END IF
164: 162: 
165:         IF (SHIFTED) THEN163:         IF (SHIFTED) THEN
166:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Zeros are shifted in lowest eigenvector. "164:             WRITE(MYUNIT,'(A)') "modcudabfgsts> Zeros are shifted in lowest eigenvector. "
167:             STOP165:             STOP
168:         END IF166:         END IF
169: 167: 
170:         ! Check for consistent convergence criteria on RMS gradient in LBFGS and EF part168:         ! Check for consistent convergence criteria on RMS gradient in LBFGS and EF part
171:         IF (GMAX.NE.CONVR) THEN169:         IF (GMAX.NE.CONVR) THEN
269:         C_GMAX = GMAX267:         C_GMAX = GMAX
270:         C_MAXBFGS = MAXBFGS268:         C_MAXBFGS = MAXBFGS
271:         C_MAXERISE = MAXERISE269:         C_MAXERISE = MAXERISE
272:         C_DGUESS = DGUESS270:         C_DGUESS = DGUESS
273:         C_CONVU = CONVU271:         C_CONVU = CONVU
274:         C_FREEZE = FREEZE272:         C_FREEZE = FREEZE
275:         C_NFREEZE = NFREEZE273:         C_NFREEZE = NFREEZE
276: 274: 
277:         ! 'C_' prefix denotes those variables which have intent out or inout or are copies of those from common blocks/modules275:         ! 'C_' prefix denotes those variables which have intent out or inout or are copies of those from common blocks/modules
278:         CALL CUDA_BFGSTS(C_NATOMS, C_COORDS, C_CEIG, C_MFLAG, C_ENERGY, C_NEVS, ITMAX, C_ITER, C_MAXXBFGS, C_XMAXERISE, C_RMS, &276:         CALL CUDA_BFGSTS(C_NATOMS, C_COORDS, C_CEIG, C_MFLAG, C_ENERGY, C_NEVS, ITMAX, C_ITER, C_MAXXBFGS, C_XMAXERISE, C_RMS, &
279:                         C_CUDAPOT, C_DEBUG, C_CUDATIMET, NCALLS, C_CFUSIONT, C_COLDFUSIONLIMIT, C_XDGUESS, C_XMUPDATE, C_EVALMIN, &277:                         C_CUDAPOT, C_DEBUG, C_CUDATIMET, ECALLS, C_CFUSIONT, C_COLDFUSIONLIMIT, C_XDGUESS, C_XMUPDATE, C_EVALMIN, &
280:                         C_VECS, C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, &278:                         C_VECS, C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, &
281:                         C_SITESRIGIDBODY, C_RIGIDSINGLES, C_IINVERSE, C_NSECDIAG, C_EVPC, C_PUSHCUT, C_PUSHOFF, &279:                         C_SITESRIGIDBODY, C_RIGIDSINGLES, C_IINVERSE, C_NSECDIAG, C_EVPC, C_PUSHCUT, C_PUSHOFF, &
282:                         C_STPMAX, C_MAXMAX, C_MINMAX, C_TRAD, C_NBFGSMAX1, C_NBFGSMAX2, C_BFGSTSTOL, C_MUPDATE, C_GMAX, &280:                         C_STPMAX, C_MAXMAX, C_MINMAX, C_TRAD, C_NBFGSMAX1, C_NBFGSMAX2, C_BFGSTSTOL, C_MUPDATE, C_GMAX, &
283:                         C_MAXBFGS, C_MAXERISE, C_DGUESS, C_CONVU, C_FREEZE, C_FROZEN, C_NFREEZE, POTENTIALTIME)281:                         C_MAXBFGS, C_MAXERISE, C_DGUESS, C_CONVU, C_FREEZE, C_FROZEN, C_NFREEZE)
284: 282: 
285:         ! Make sure C types with intent out or inout are coverted back to Fortran ones283:         ! Make sure C types with intent out or inout are coverted back to Fortran ones
286: 284: 
287:         DO I = 1,3*NATOMS285:         DO I = 1,3*NATOMS
288:             COORDS(I) = DBLE(C_COORDS(I))286:             COORDS(I) = DBLE(C_COORDS(I))
289:         END DO287:         END DO
290: 288: 
291:         DO I = 1,3*NATOMS289:         DO I = 1,3*NATOMS
292:             VECS(I) = DBLE(C_VECS(I))290:             VECS(I) = DBLE(C_VECS(I))
293:         END DO291:         END DO
296:             ZWORK(I,1) = DBLE(C_VECS(I))294:             ZWORK(I,1) = DBLE(C_VECS(I))
297:         END DO295:         END DO
298: 296: 
299:         ENERGY = DBLE(C_ENERGY)297:         ENERGY = DBLE(C_ENERGY)
300:         MFLAG = LOGICAL(C_MFLAG)298:         MFLAG = LOGICAL(C_MFLAG)
301:         RMS = DBLE(C_RMS)299:         RMS = DBLE(C_RMS)
302:         CFUSIONT = LOGICAL(C_CFUSIONT)300:         CFUSIONT = LOGICAL(C_CFUSIONT)
303:         EVALMIN = DBLE(C_EVALMIN)301:         EVALMIN = DBLE(C_EVALMIN)
304:         ITER = INT(C_ITER)302:         ITER = INT(C_ITER)
305: 303: 
306:         FCALL = FCALL + INT(NCALLS)304:         FCALL = FCALL + INT(ECALLS)
307:         FTIME = FTIME + DBLE(POTENTIALTIME) 
308: 305: 
309:         KNOWE=.FALSE.306:         KNOWE=.FALSE.
310:         KNOWG=.FALSE.307:         KNOWG=.FALSE.
311:         KNOWH=.FALSE.308:         KNOWH=.FALSE.
312: 309: 
313:     END SUBROUTINE CUDA_BFGSTS_WRAPPER310:     END SUBROUTINE CUDA_BFGSTS_WRAPPER
314: 311: 
315: END MODULE MODCUDABFGSTS312: END MODULE MODCUDABFGSTS


r29015/modcudadummylbfgs.f90 2015-11-17 23:33:13.544686397 +0000 r29014/modcudadummylbfgs.f90 2015-11-17 23:33:19.168761824 +0000
  6:   6: 
  7:         INTEGER :: N, MUPDATE, ITDONE, ITMAX  7:         INTEGER :: N, MUPDATE, ITDONE, ITMAX
  8:         DOUBLE PRECISION, DIMENSION(1) :: XCOORDS  8:         DOUBLE PRECISION, DIMENSION(1) :: XCOORDS
  9:         DOUBLE PRECISION :: ENERGY, RMS  9:         DOUBLE PRECISION :: ENERGY, RMS
 10:         LOGICAL :: MFLAG, PROJECT 10:         LOGICAL :: MFLAG, PROJECT
 11:  11: 
 12:         RETURN 12:         RETURN
 13:  13: 
 14:     END SUBROUTINE CUDA_LBFGS_WRAPPER 14:     END SUBROUTINE CUDA_LBFGS_WRAPPER
 15:  15: 
 16:     SUBROUTINE CUDA_ENEGRAD_WRAPPER(NATOMS, COORDS, TOTENERGY, GRADIENTS) 
 17:  
 18:         INTEGER :: NATOMS 
 19:         DOUBLE PRECISION :: TOTENERGY 
 20:         DOUBLE PRECISION, DIMENSION(1) :: COORDS, GRADIENTS 
 21:  
 22:         RETURN 
 23:  
 24:     END SUBROUTINE CUDA_ENEGRAD_WRAPPER 
 25:  
 26: END MODULE MODCUDALBFGS 16: END MODULE MODCUDALBFGS


r29015/modcudalbfgs.f90 2015-11-17 23:33:14.308696643 +0000 r29014/modcudalbfgs.f90 2015-11-17 23:33:19.360764400 +0000
  1: MODULE MODCUDALBFGS  1: MODULE MODCUDALBFGS
  2:   2: 
  3: USE KEY, ONLY : GMAX, CUDATIMET, CUDAPOT, MAXBFGS, MAXERISE, CFUSIONT, COLDFUSIONLIMIT, DGUESS, MYUNIT, GRADSQ, FREEZE, &   3: USE KEY, ONLY : GMAX, CUDATIMET, CUDAPOT, MAXBFGS, MAXERISE, CFUSIONT, COLDFUSIONLIMIT, DGUESS, MYUNIT, GRADSQ, FREEZE, & 
  4:                 REVERSEUPHILLT, FREEZE, FROZEN, NFREEZE, PRINTPTS, TWOENDS, PV, DUMPMAG, NSTEPMIN, FIXAFTER, AMBER12T  4:                 REVERSEUPHILLT, FREEZE, FROZEN, NFREEZE, PRINTPTS, TWOENDS, PV, DUMPMAG, NSTEPMIN, FIXAFTER
  5:   5: 
  6: USE COMMONS, ONLY : DEBUG  6: USE COMMONS, ONLY : DEBUG
  7:   7: 
  8: USE GENRIGID, ONLY : ATOMRIGIDCOORDT, DEGFREEDOMS, NRIGIDBODY, NSITEPERBODY, RIGIDGROUPS, MAXSITE, SITESRIGIDBODY, &   8: USE GENRIGID, ONLY : ATOMRIGIDCOORDT, DEGFREEDOMS, NRIGIDBODY, NSITEPERBODY, RIGIDGROUPS, MAXSITE, SITESRIGIDBODY, & 
  9:                      RIGIDSINGLES, IINVERSE  9:                      RIGIDSINGLES, IINVERSE
 10:  10: 
 11: USE INTCOMMONS, ONLY : BONDSFROMFILE 11: USE INTCOMMONS, ONLY : BONDSFROMFILE
 12:  12: 
 13: USE INTERNALS_WRAPPER, ONLY : INTWRAP_USEINTERNALS 13: USE INTERNALS_WRAPPER, ONLY : INTWRAP_USEINTERNALS
 14:  14: 
 15: USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT, C_DOUBLE, C_BOOL, C_CHAR 15: USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT, C_DOUBLE, C_BOOL, C_CHAR
 16:  16: 
 17: IMPLICIT NONE 17: IMPLICIT NONE
 18:  18: 
 19: INTERFACE 19: INTERFACE
 20:     SUBROUTINE CUDA_LBFGS(N, C_XCOORDS, C_GMAX, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, &  20:     SUBROUTINE CUDA_LBFGS(N, C_XCOORDS, C_GMAX, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, & 
 21:                          C_DEBUG, C_CUDATIMET, NCALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, C_DGUESS, MUPDATE, C_ATOMRIGIDCOORDT, &  21:                          C_DEBUG, C_CUDATIMET, ECALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, C_DGUESS, MUPDATE, C_ATOMRIGIDCOORDT, & 
 22:                          C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, C_SITESRIGIDBODY, C_RIGIDSINGLES, &  22:                          C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, C_SITESRIGIDBODY, C_RIGIDSINGLES, & 
 23:                          C_BQMAX, C_IINVERSE, PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE, POTENTIALTIME) BIND(C,NAME="setup_lbfgs") 23:                          C_BQMAX, C_IINVERSE, PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE) BIND(C,NAME="setup_lbfgs")
 24:  24: 
 25:         IMPORT :: C_INT, C_DOUBLE, C_BOOL, C_CHAR 25:         IMPORT :: C_INT, C_DOUBLE, C_BOOL, C_CHAR
 26:  26: 
 27:         INTEGER(KIND=C_INT), INTENT(IN) :: N, & ! No. of atoms 27:         INTEGER(KIND=C_INT), INTENT(IN) :: N, & ! No. of atoms
 28:                                            ITMAX, & ! Max. no. of steps allowed in minmization 28:                                            ITMAX, & ! Max. no. of steps allowed in minmization
 29:                                            C_DEGFREEDOMS, & ! Rigid Body Framework (RBF): no. of degrees of freedom 29:                                            C_DEGFREEDOMS, & ! Rigid Body Framework (RBF): no. of degrees of freedom
 30:                                            C_NRIGIDBODY, & ! RBF: no. of rigid bodies 30:                                            C_NRIGIDBODY, & ! RBF: no. of rigid bodies
 31:                                            C_MAXSITE, & ! RBF: max. no. of sites in a rigid body 31:                                            C_MAXSITE, & ! RBF: max. no. of sites in a rigid body
 32:                                            MUPDATE, & ! History size 32:                                            MUPDATE, & ! History size
 33:                                            C_NFREEZE ! No. of frozen atoms 33:                                            C_NFREEZE ! No. of frozen atoms
 34:  34: 
 35:         INTEGER(KIND=C_INT), DIMENSION(C_NRIGIDBODY), INTENT(IN) :: C_NSITEPERBODY ! RBF: no. of rigid body sites 35:         INTEGER(KIND=C_INT), DIMENSION(C_NRIGIDBODY), INTENT(IN) :: C_NSITEPERBODY ! RBF: no. of rigid body sites
 36:  36: 
 37:         INTEGER(KIND=C_INT), DIMENSION(C_MAXSITE*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDGROUPS ! RBF: list of atoms in rigid bodies 37:         INTEGER(KIND=C_INT), DIMENSION(C_MAXSITE*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDGROUPS ! RBF: list of atoms in rigid bodies
 38:  38: 
 39:  39: 
 40:         INTEGER(KIND=C_INT), DIMENSION(C_DEGFREEDOMS/3 - 2*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDSINGLES ! RBF: list of atoms not in rigid bodies 40:         INTEGER(KIND=C_INT), DIMENSION(C_DEGFREEDOMS/3 - 2*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDSINGLES ! RBF: list of atoms not in rigid bodies
 41:  41: 
 42:         INTEGER(KIND=C_INT), INTENT(OUT) :: C_ITDONE, & ! No. of LBFGS iterations done 42:         INTEGER(KIND=C_INT), INTENT(OUT) :: C_ITDONE, & ! No. of LBFGS iterations done
 43:                                             NCALLS ! No. of potential calls made during this call to LBFGS 43:                                             ECALLS ! No. of potential calls made during this call to LBFGS
 44:  44: 
 45:         REAL(KIND=C_DOUBLE), INTENT(IN) :: C_GMAX, & ! Convergence tolerance for RMS force  45:         REAL(KIND=C_DOUBLE), INTENT(IN) :: C_GMAX, & ! Convergence tolerance for RMS force 
 46:                                            C_MAXBFGS, & ! Max. step size allowed  46:                                            C_MAXBFGS, & ! Max. step size allowed 
 47:                                            C_MAXERISE, & ! Max. energy rise allowed  47:                                            C_MAXERISE, & ! Max. energy rise allowed 
 48:                                            C_COLDFUSIONLIMIT, & ! Limit below which cold fusion is diagnosed and minimization terminated 48:                                            C_COLDFUSIONLIMIT, & ! Limit below which cold fusion is diagnosed and minimization terminated
 49:                                            C_DGUESS, & ! Initial guess for inverse Hessian diagonal elements 49:                                            C_DGUESS, & ! Initial guess for inverse Hessian diagonal elements
 50:                                            C_BQMAX ! (1/5) of threshold under which aaconvergence is used, equivalent to C_GMAX 50:                                            C_BQMAX ! (1/5) of threshold under which aaconvergence is used, equivalent to C_GMAX
 51:  51: 
 52:         REAL(KIND=C_DOUBLE), DIMENSION(C_MAXSITE*3*C_NRIGIDBODY), INTENT(IN) :: C_SITESRIGIDBODY ! RBF: coordinates of the rigid body sites 52:         REAL(KIND=C_DOUBLE), DIMENSION(C_MAXSITE*3*C_NRIGIDBODY), INTENT(IN) :: C_SITESRIGIDBODY ! RBF: coordinates of the rigid body sites
 53:  53: 
 54:         REAL(KIND=C_DOUBLE), DIMENSION(C_NRIGIDBODY*3*3), INTENT(IN) :: C_IINVERSE ! RBF: from genrigid, used in aaconvergence subroutine 54:         REAL(KIND=C_DOUBLE), DIMENSION(C_NRIGIDBODY*3*3), INTENT(IN) :: C_IINVERSE ! RBF: from genrigid, used in aaconvergence subroutine
 55:  55: 
 56:         REAL(KIND=C_DOUBLE), DIMENSION(N), INTENT(INOUT) :: C_XCOORDS ! Coordinates 56:         REAL(KIND=C_DOUBLE), DIMENSION(N), INTENT(INOUT) :: C_XCOORDS ! Coordinates
 57:  57: 
 58:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_ENERGY, & ! Energy 58:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_ENERGY, & ! Energy
 59:                                             C_RMS, & ! RMS force 59:                                             C_RMS ! RMS force
 60:                                             POTENTIALTIME ! Time taken in calculating potential 
 61:  60: 
 62:         LOGICAL(KIND=C_BOOL), INTENT(IN) :: C_DEBUG, & ! If true, print debug info. 61:         LOGICAL(KIND=C_BOOL), INTENT(IN) :: C_DEBUG, & ! If true, print debug info.
 63:                                             C_CUDATIMET, & ! If true, print timing info. 62:                                             C_CUDATIMET, & ! If true, print timing info.
 64:                                             C_ATOMRIGIDCOORDT, & ! If false, use rigid body coordinates 63:                                             C_ATOMRIGIDCOORDT, & ! If false, use rigid body coordinates
 65:                                             PROJECT, & ! If true, project out the components of the gradient along the eigenvector 64:                                             PROJECT, & ! If true, project out the components of the gradient along the eigenvector
 66:                                             C_FREEZE ! If true, freeze some specified atoms 65:                                             C_FREEZE ! If true, freeze some specified atoms
 67:  66: 
 68:         LOGICAL(KIND=C_BOOL), DIMENSION(N), INTENT(IN) :: C_FROZEN ! Logical array specifying frozen atoms 67:         LOGICAL(KIND=C_BOOL), DIMENSION(N), INTENT(IN) :: C_FROZEN ! Logical array specifying frozen atoms
 69:  68: 
 70:         LOGICAL(KIND=C_BOOL), INTENT(OUT) :: C_MFLAG, & ! True if quench converged 69:         LOGICAL(KIND=C_BOOL), INTENT(INOUT) :: C_COLDFUSION ! Set to true during minimization if cold fusion diagnosed
 71:                                              C_COLDFUSION ! Set to true during minimization if cold fusion diagnosed 70: 
  71:         LOGICAL(KIND=C_BOOL), INTENT(OUT) :: C_MFLAG ! True if quench converged
 72:  72: 
 73:         CHARACTER(LEN=1, KIND=C_CHAR), INTENT(IN) :: C_CUDAPOT ! Character specifying the CUDA potential to be used 73:         CHARACTER(LEN=1, KIND=C_CHAR), INTENT(IN) :: C_CUDAPOT ! Character specifying the CUDA potential to be used
 74:  74: 
 75:     END SUBROUTINE CUDA_LBFGS 75:     END SUBROUTINE CUDA_LBFGS
 76: END INTERFACE 76: END INTERFACE
 77:  77: 
 78: INTERFACE 
 79:     SUBROUTINE CUDA_ENEGRAD_CPUTOGPU(NATOMS, COORDS, C_TOTENERGY, C_GRADIENTS) BIND(C,NAME="gminoptim_enegrad_cputogpu") 
 80:  
 81:         IMPORT :: C_INT, C_DOUBLE 
 82:  
 83:         INTEGER(KIND=C_INT), INTENT(IN) :: NATOMS ! No. of atoms 
 84:  
 85:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS), INTENT(IN) :: COORDS ! Atomic coordinates 
 86:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_TOTENERGY ! Total energy of the system 
 87:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS), INTENT(OUT) :: C_GRADIENTS ! Gradient of the energy w.r.t. each atomic coordinate 
 88:  
 89:     END SUBROUTINE CUDA_ENEGRAD_CPUTOGPU 
 90: END INTERFACE 
 91:  
 92: CONTAINS 78: CONTAINS
 93:  79: 
 94:     SUBROUTINE CUDA_LBFGS_WRAPPER(N, MUPDATE, XCOORDS, MFLAG, ENERGY, RMS, ITMAX, ITDONE, PROJECT) 80:     SUBROUTINE CUDA_LBFGS_WRAPPER(N, MUPDATE, XCOORDS, MFLAG, ENERGY, RMS, ITMAX, ITDONE, PROJECT)
 95:  81: 
 96:         ! Variables passed as *arguments through this wrapper* (not common) with intent in for CUDA_LBFGS are converted directly 82:         ! Variables passed as *arguments through this wrapper* (not common) with intent in for CUDA_LBFGS are converted directly
 97:         INTEGER(KIND=C_INT) :: N, ITMAX, C_ITDONE, NCALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, MUPDATE, C_NFREEZE 83:         INTEGER(KIND=C_INT) :: N, ITMAX, C_ITDONE, ECALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, MUPDATE, C_NFREEZE
 98:         INTEGER(KIND=C_INT), DIMENSION(NRIGIDBODY) :: C_NSITEPERBODY 84:         INTEGER(KIND=C_INT), DIMENSION(NRIGIDBODY) :: C_NSITEPERBODY
 99:         INTEGER(KIND=C_INT), DIMENSION(MAXSITE*NRIGIDBODY) :: C_RIGIDGROUPS 85:         INTEGER(KIND=C_INT), DIMENSION(MAXSITE*NRIGIDBODY) :: C_RIGIDGROUPS
100:         INTEGER(KIND=C_INT), DIMENSION(DEGFREEDOMS/3 - 2*NRIGIDBODY) :: C_RIGIDSINGLES 86:         INTEGER(KIND=C_INT), DIMENSION(DEGFREEDOMS/3 - 2*NRIGIDBODY) :: C_RIGIDSINGLES
101:  87: 
102:         REAL(KIND=C_DOUBLE) :: C_MAXBFGS, C_MAXERISE, C_ENERGY, C_RMS, C_COLDFUSIONLIMIT, C_DGUESS, C_BQMAX, C_GMAX, POTENTIALTIME 88:         REAL(KIND=C_DOUBLE) :: C_MAXBFGS, C_MAXERISE, C_ENERGY, C_RMS, C_COLDFUSIONLIMIT, C_DGUESS, C_BQMAX, C_GMAX
103:         REAL(KIND=C_DOUBLE), DIMENSION(MAXSITE*3*NRIGIDBODY) :: C_SITESRIGIDBODY 89:         REAL(KIND=C_DOUBLE), DIMENSION(MAXSITE*3*NRIGIDBODY) :: C_SITESRIGIDBODY
104:         REAL(KIND=C_DOUBLE), DIMENSION(NRIGIDBODY*3*3) :: C_IINVERSE 90:         REAL(KIND=C_DOUBLE), DIMENSION(NRIGIDBODY*3*3) :: C_IINVERSE
105:         REAL(KIND=C_DOUBLE), DIMENSION(N) :: C_XCOORDS 91:         REAL(KIND=C_DOUBLE), DIMENSION(N) :: C_XCOORDS
106:  92: 
107:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_ATOMRIGIDCOORDT, C_COLDFUSION, PROJECT, C_FREEZE 93:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_ATOMRIGIDCOORDT, C_COLDFUSION, PROJECT, C_FREEZE
108:         LOGICAL(KIND=C_BOOL), DIMENSION(N) :: C_FROZEN 94:         LOGICAL(KIND=C_BOOL), DIMENSION(N) :: C_FROZEN
109:  95: 
110:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT 96:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT
111:  97: 
112:         ! Variables passed as *arguments through this wrapper* (not common) with intent out for CUDA_LBFGS are not passed into it 98:         ! Variables passed as *arguments through this wrapper* (not common) with intent out for CUDA_LBFGS are not passed into it
113:         ! Therefore uninitialised C types are passed in and converted types are copied back after the call 99:         ! Therefore uninitialised C types are passed in and converted types are copied back after the call
114: 100: 
115:         INTEGER :: I, J, K, ITDONE, FCALL, NPCALL, ECALL, SCALL101:         INTEGER :: I, J, K, ITDONE, FCALL
116:         DOUBLE PRECISION :: ENERGY, RMS, FTIME, ETIME, STIME102:         DOUBLE PRECISION :: ENERGY, RMS
117:         DOUBLE PRECISION, DIMENSION(N) :: XCOORDS103:         DOUBLE PRECISION, DIMENSION(N) :: XCOORDS
118:         LOGICAL :: MFLAG, KNOWE, KNOWG, KNOWH, DRAGT, DOINTERNALSTRANSFORM104:         LOGICAL :: MFLAG, KNOWE, KNOWG, KNOWH, DRAGT, DOINTERNALSTRANSFORM
119:         COMMON /PCALL/ NPCALL, ECALL, FCALL, SCALL, ETIME, FTIME, STIME105:         COMMON /PCALL/ FCALL
120:         COMMON /KNOWN/ KNOWE, KNOWG, KNOWH106:         COMMON /KNOWN/ KNOWE, KNOWG, KNOWH
121:         COMMON /RUNTYPE/ DRAGT107:         COMMON /RUNTYPE/ DRAGT
122: 108: 
123:         DOINTERNALSTRANSFORM = INTWRAP_USEINTERNALS()109:         DOINTERNALSTRANSFORM = INTWRAP_USEINTERNALS()
124: 110: 
125:         IF (PRINTPTS) THEN111:         IF (PRINTPTS) THEN
126:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Keyword NOPOINTS must be used. &112:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Keyword NOPOINTS must be used. Functionality to print coordinates/energies is coming soon! "
127:                                  Functionality to print coordinates/energies will be added at some point in the future. " 
128:             STOP113:             STOP
129:         END IF114:         END IF
130: 115: 
131:         IF (REVERSEUPHILLT .OR. GRADSQ .OR. DRAGT .OR. TWOENDS .OR. DOINTERNALSTRANSFORM .OR. BONDSFROMFILE .OR. PV .OR. & 116:         IF (REVERSEUPHILLT .OR. GRADSQ .OR. DRAGT .OR. TWOENDS .OR. DOINTERNALSTRANSFORM .OR. BONDSFROMFILE .OR. PV .OR. & 
132:             DUMPMAG .OR. (NSTEPMIN .GT. 0) .OR. (FIXAFTER .GT. 0)) THEN117:             DUMPMAG .OR. (NSTEPMIN .GT. 0) .OR. (FIXAFTER .GT. 0)) THEN
133:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Keywords REVERSEUPHILLT, GRADSQ, DRAG, TWOENDS, INTMIN, BONDSFROMFILE, PV, & 118:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Keywords REVERSEUPHILLT, GRADSQ, DRAG, TWOENDS, INTMIN, BONDSFROMFILE, PV, & 
134:                                  DUMPMAG, STEPMIN, FIXAFTER are not yet supported. Contact rgm38 if you would like a feature to be added. "119:                                  DUMPMAG, STEPMIN, FIXAFTER are not yet supported. Contact rgm38 if you would like a feature to be added. "
135:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Disclaimer: this list might not be exhaustive! "120:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Disclaimer: this list might not be exhaustive! "
136:             STOP121:             STOP
137:         END IF122:         END IF
178: 163: 
179:         C_CUDAPOT = CUDAPOT164:         C_CUDAPOT = CUDAPOT
180:         C_DEBUG = DEBUG165:         C_DEBUG = DEBUG
181:         C_CUDATIMET = CUDATIMET166:         C_CUDATIMET = CUDATIMET
182:         C_MAXBFGS = MAXBFGS167:         C_MAXBFGS = MAXBFGS
183:         C_MAXERISE = MAXERISE168:         C_MAXERISE = MAXERISE
184:         C_ATOMRIGIDCOORDT = ATOMRIGIDCOORDT169:         C_ATOMRIGIDCOORDT = ATOMRIGIDCOORDT
185:         C_DEGFREEDOMS = DEGFREEDOMS170:         C_DEGFREEDOMS = DEGFREEDOMS
186:         C_NRIGIDBODY = NRIGIDBODY171:         C_NRIGIDBODY = NRIGIDBODY
187:         C_MAXSITE = MAXSITE172:         C_MAXSITE = MAXSITE
 173:         C_COLDFUSION = .FALSE. ! Set to false here rather than COLDFUSION as it should definitely be false at this point
188:         C_COLDFUSIONLIMIT = COLDFUSIONLIMIT174:         C_COLDFUSIONLIMIT = COLDFUSIONLIMIT
189:         C_DGUESS = DGUESS175:         C_DGUESS = DGUESS
190:         C_BQMAX = GMAX176:         C_BQMAX = GMAX
191:         C_GMAX = GMAX177:         C_GMAX = GMAX
192:         C_FREEZE = FREEZE178:         C_FREEZE = FREEZE
193:         C_NFREEZE = NFREEZE179:         C_NFREEZE = NFREEZE
194: 180: 
195:         ! 'C_' prefix denotes those variables which have intent out or inout or are copies of those from common blocks/modules 181:         ! 'C_' prefix denotes those variables which have intent out or inout or are copies of those from common blocks/modules 
196:         CALL CUDA_LBFGS(N, C_XCOORDS, C_GMAX, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, & 182:         CALL CUDA_LBFGS(N, C_XCOORDS, C_GMAX, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, & 
197:                        C_DEBUG, C_CUDATIMET, NCALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, C_DGUESS, MUPDATE, & 183:                        C_DEBUG, C_CUDATIMET, ECALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, C_DGUESS, MUPDATE, & 
198:                        C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, & 184:                        C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, & 
199:                        C_SITESRIGIDBODY, C_RIGIDSINGLES, C_BQMAX, C_IINVERSE, PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE, & 185:                        C_SITESRIGIDBODY, C_RIGIDSINGLES, C_BQMAX, C_IINVERSE, PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE)
200:                        POTENTIALTIME) 
201: 186: 
202:         ! Make sure C types with intent out or inout are coverted back to Fortran ones187:         ! Make sure C types with intent out or inout are coverted back to Fortran ones
203: 188: 
204:         DO I = 1,N189:         DO I = 1,N
205:             XCOORDS(I) = DBLE(C_XCOORDS(I))190:             XCOORDS(I) = DBLE(C_XCOORDS(I))
206:         END DO191:         END DO
207: 192: 
208:         ENERGY = DBLE(C_ENERGY)193:         ENERGY = DBLE(C_ENERGY)
209:         RMS = DBLE(C_RMS)194:         RMS = DBLE(C_RMS)
210:         MFLAG = LOGICAL(C_MFLAG)195:         MFLAG = LOGICAL(C_MFLAG)
211:         ITDONE = INT(C_ITDONE)196:         ITDONE = INT(C_ITDONE)
212:         CFUSIONT = LOGICAL(C_COLDFUSION)197:         CFUSIONT = LOGICAL(C_COLDFUSION)
213: 198: 
214:         IF (CFUSIONT) THEN199:         IF (CFUSIONT) THEN
215:             WRITE(MYUNIT,'(A,2G20.10)') ' modcudalbfgs> Cold fusion diagnosed - step discarded, energy, limit=',ENERGY,COLDFUSIONLIMIT200:             WRITE(MYUNIT,'(A,2G20.10)') ' modcudalbfgs> Cold fusion diagnosed - step discarded, energy, limit=',ENERGY,COLDFUSIONLIMIT
216:             ENERGY = 1.0D60201:             ENERGY = 1.0D60
217:             RMS = 1.0D1202:             RMS = 1.0D1
218:         END IF203:         END IF
219: 204: 
220:         FCALL = FCALL + INT(NCALLS)205:         FCALL = FCALL + INT(ECALLS)
221:         FTIME = FTIME + DBLE(POTENTIALTIME) 
222: 206: 
223:         KNOWE=.FALSE.207:         KNOWE=.FALSE.
224:         KNOWG=.FALSE.208:         KNOWG=.FALSE.
225:         KNOWH=.FALSE.209:         KNOWH=.FALSE.
226: 210: 
227:     END SUBROUTINE CUDA_LBFGS_WRAPPER211:     END SUBROUTINE CUDA_LBFGS_WRAPPER
228: 212: 
229:  
230:     SUBROUTINE CUDA_ENEGRAD_WRAPPER(NATOMS, COORDS, TOTENERGY, GRADIENTS) 
231:  
232:         INTEGER(KIND=C_INT) :: NATOMS 
233:  
234:         REAL(KIND=C_DOUBLE) :: C_TOTENERGY 
235:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS) :: COORDS, C_GRADIENTS 
236:  
237:         INTEGER :: X 
238:  
239:         DOUBLE PRECISION :: TOTENERGY 
240:         DOUBLE PRECISION, DIMENSION(3*NATOMS) :: GRADIENTS 
241:  
242:         ! Calculates the energy and gradients on the GPU using the GB potential 
243:         CALL CUDA_ENEGRAD_CPUTOGPU(NATOMS, COORDS, C_TOTENERGY, C_GRADIENTS) 
244:  
245:         TOTENERGY = DBLE(C_TOTENERGY) 
246:  
247:         DO X = 1,(3*NATOMS) 
248:             GRADIENTS(X) = DBLE(C_GRADIENTS(X)) 
249:         END DO 
250:  
251:     END SUBROUTINE CUDA_ENEGRAD_WRAPPER 
252:  
253: END MODULE MODCUDALBFGS213: END MODULE MODCUDALBFGS


r29015/modcudalbfgs.F90 2015-11-17 23:33:12.364670573 +0000 r29014/modcudalbfgs.F90 2015-11-17 23:33:17.940745353 +0000
  1: MODULE MODCUDALBFGS  1: MODULE MODCUDALBFGS
  2:   2: 
  3: #ifndef DUMMY_CUDA  3: #ifndef DUMMY_CUDA
  4:   4: 
  5: USE COMMONS, ONLY : RMS, DEBUG, CUDATIMET, MAXBFGS, MAXERISE, CUDAPOT, NPCALL, COLDFUSION, COLDFUSIONLIMIT, MYUNIT, DGUESS, &  5: USE COMMONS, ONLY : RMS, DEBUG, CUDATIMET, MAXBFGS, MAXERISE, CUDAPOT, NPCALL, COLDFUSION, COLDFUSIONLIMIT, MYUNIT, DGUESS, &
  6:                     BQMAX, FREEZE, SEEDT, FREEZECORE, FROZEN, NFREEZE, QUENCHDOS, CENT, CALCQT, INTMINT, DUMPT, COMPRESSRIGIDT, &   6:                     MUPDATE, BQMAX, FREEZE, SEEDT, FREEZECORE, FROZEN, NFREEZE, QUENCHDOS, CENT, CALCQT, INTMINT, DUMPT, & 
  7:                     AMBER12T  7:                     COMPRESSRIGIDT
  8:   8: 
  9: USE GENRIGID, ONLY : ATOMRIGIDCOORDT, DEGFREEDOMS, NRIGIDBODY, NSITEPERBODY, RIGIDGROUPS, MAXSITE, SITESRIGIDBODY, &   9: USE GENRIGID, ONLY : ATOMRIGIDCOORDT, DEGFREEDOMS, NRIGIDBODY, NSITEPERBODY, RIGIDGROUPS, MAXSITE, SITESRIGIDBODY, & 
 10:                      RIGIDSINGLES, IINVERSE 10:                      RIGIDSINGLES, IINVERSE
 11:  11: 
 12: USE MODAMBER9, ONLY : STEEREDMINT 12: USE MODAMBER9, ONLY : STEEREDMINT
 13:  13: 
 14: #endif 14: #endif
 15:  15: 
 16: USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT, C_DOUBLE, C_BOOL, C_CHAR 16: USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_INT, C_DOUBLE, C_BOOL, C_CHAR
 17:  17: 
 18: IMPLICIT NONE 18: IMPLICIT NONE
 19:  19: 
 20: #ifndef DUMMY_CUDA 20: #ifndef DUMMY_CUDA
 21: INTERFACE 21: INTERFACE
 22:     SUBROUTINE CUDA_LBFGS(N, C_XCOORDS, EPS, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, &  22:     SUBROUTINE CUDA_LBFGS(N, C_XCOORDS, EPS, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, & 
 23:                          C_DEBUG, C_CUDATIMET, ECALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, & 23:                          C_DEBUG, C_CUDATIMET, ECALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, &
 24:                          C_DGUESS, MUPDATE, C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, & 24:                          C_DGUESS, C_MUPDATE, C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, &
 25:                          C_RIGIDGROUPS, C_MAXSITE, C_SITESRIGIDBODY, C_RIGIDSINGLES, C_BQMAX, C_IINVERSE, & 25:                          C_RIGIDGROUPS, C_MAXSITE, C_SITESRIGIDBODY, C_RIGIDSINGLES, C_BQMAX, C_IINVERSE, &
 26:                          PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE, POTENTIALTIME) BIND(C,NAME="setup_lbfgs") 26:                          PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE) BIND(C,NAME="setup_lbfgs")
 27:  27: 
 28:         IMPORT :: C_INT, C_DOUBLE, C_BOOL, C_CHAR 28:         IMPORT :: C_INT, C_DOUBLE, C_BOOL, C_CHAR
 29:  29: 
 30:         INTEGER(KIND=C_INT), INTENT(IN) :: N, & ! No. of atoms 30:         INTEGER(KIND=C_INT), INTENT(IN) :: N, & ! No. of atoms
 31:                                            ITMAX, & ! Max. no. of steps allowed in minmization 31:                                            ITMAX, & ! Max. no. of steps allowed in minmization
 32:                                            C_DEGFREEDOMS, & ! Rigid Body Framework (RBF): no. of degrees of freedom 32:                                            C_DEGFREEDOMS, & ! Rigid Body Framework (RBF): no. of degrees of freedom
 33:                                            C_NRIGIDBODY, & ! RBF: no. of rigid bodies 33:                                            C_NRIGIDBODY, & ! RBF: no. of rigid bodies
 34:                                            C_MAXSITE, & ! RBF: max. no. of sites in a rigid body 34:                                            C_MAXSITE, & ! RBF: max. no. of sites in a rigid body
 35:                                            MUPDATE, & ! History size 35:                                            C_MUPDATE, & ! History size
 36:                                            C_NFREEZE ! No. of frozen atoms 36:                                            C_NFREEZE ! No. of frozen atoms
 37:  37: 
 38:         INTEGER(KIND=C_INT), DIMENSION(C_NRIGIDBODY), INTENT(IN) :: C_NSITEPERBODY ! RBF: no. of rigid body sites 38:         INTEGER(KIND=C_INT), DIMENSION(C_NRIGIDBODY), INTENT(IN) :: C_NSITEPERBODY ! RBF: no. of rigid body sites
 39:  39: 
 40:         INTEGER(KIND=C_INT), DIMENSION(C_MAXSITE*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDGROUPS ! RBF: list of atoms in rigid bodies 40:         INTEGER(KIND=C_INT), DIMENSION(C_MAXSITE*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDGROUPS ! RBF: list of atoms in rigid bodies
 41:  41: 
 42:         INTEGER(KIND=C_INT), DIMENSION(C_DEGFREEDOMS/3 - 2*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDSINGLES ! RBF: list of atoms not in rigid bodies 42:         INTEGER(KIND=C_INT), DIMENSION(C_DEGFREEDOMS/3 - 2*C_NRIGIDBODY), INTENT(IN) :: C_RIGIDSINGLES ! RBF: list of atoms not in rigid bodies
 43:  43: 
 44:         INTEGER(KIND=C_INT), INTENT(OUT) :: C_ITDONE, & ! No. of LBFGS iterations done 44:         INTEGER(KIND=C_INT), INTENT(OUT) :: C_ITDONE, & ! No. of LBFGS iterations done
 45:                                             ECALLS ! Number of potential calls made during this call to LBFGS 45:                                             ECALLS ! Number of potential calls made during this call to LBFGS
 51:                                            C_DGUESS, & ! Initial guess for inverse Hessian diagonal elements 51:                                            C_DGUESS, & ! Initial guess for inverse Hessian diagonal elements
 52:                                            C_BQMAX ! Sloppy quench tolerance for RMS gradient 52:                                            C_BQMAX ! Sloppy quench tolerance for RMS gradient
 53:  53: 
 54:         REAL(KIND=C_DOUBLE), DIMENSION(C_MAXSITE*3*C_NRIGIDBODY), INTENT(IN) :: C_SITESRIGIDBODY ! RBF: coordinates of the rigid body sites 54:         REAL(KIND=C_DOUBLE), DIMENSION(C_MAXSITE*3*C_NRIGIDBODY), INTENT(IN) :: C_SITESRIGIDBODY ! RBF: coordinates of the rigid body sites
 55:  55: 
 56:         REAL(KIND=C_DOUBLE), DIMENSION(C_NRIGIDBODY*3*3), INTENT(IN) :: C_IINVERSE ! RBF: from genrigid, used in aaconvergence subroutine 56:         REAL(KIND=C_DOUBLE), DIMENSION(C_NRIGIDBODY*3*3), INTENT(IN) :: C_IINVERSE ! RBF: from genrigid, used in aaconvergence subroutine
 57:  57: 
 58:         REAL(KIND=C_DOUBLE), DIMENSION(N), INTENT(INOUT) :: C_XCOORDS ! Coordinates 58:         REAL(KIND=C_DOUBLE), DIMENSION(N), INTENT(INOUT) :: C_XCOORDS ! Coordinates
 59:  59: 
 60:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_ENERGY, & ! Energy 60:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_ENERGY, & ! Energy
 61:                                             C_RMS, & ! RMS force 61:                                             C_RMS ! RMS force
 62:                                             POTENTIALTIME ! Time taken in calculating potential - not used in GMIN 
 63:  62: 
 64:         LOGICAL(KIND=C_BOOL), INTENT(IN) :: C_DEBUG, & ! If true, print debug info. 63:         LOGICAL(KIND=C_BOOL), INTENT(IN) :: C_DEBUG, & ! If true, print debug info.
 65:                                             C_CUDATIMET, & ! If true, print timing info.  64:                                             C_CUDATIMET, & ! If true, print timing info. 
 66:                                             C_ATOMRIGIDCOORDT, & ! If false, use rigid body coordinates 65:                                             C_ATOMRIGIDCOORDT, & ! If false, use rigid body coordinates
 67:                                             C_FREEZE, & ! If true, freeze some specified atoms 66:                                             C_FREEZE, & ! If true, freeze some specified atoms
 68:                                             PROJECT ! PROJECT is OPTIM only, always false 67:                                             PROJECT ! PROJECT is OPTIM only, always false
 69:  68: 
 70:         LOGICAL(KIND=C_BOOL), DIMENSION(N), INTENT(IN) :: C_FROZEN ! Logical array specifying frozen atoms 69:         LOGICAL(KIND=C_BOOL), DIMENSION(N), INTENT(IN) :: C_FROZEN ! Logical array specifying frozen atoms
 71:  70: 
 72:         LOGICAL(KIND=C_BOOL), INTENT(OUT) :: C_MFLAG, & ! True if quench converged 71:         LOGICAL(KIND=C_BOOL), INTENT(INOUT) :: C_COLDFUSION ! Set to true during minimization if cold fusion diagnosed
 73:                                              C_COLDFUSION ! Set to true during minimization if cold fusion diagnosed 72: 
  73:         LOGICAL(KIND=C_BOOL), INTENT(OUT) :: C_MFLAG ! True if quench converged
 74:  74: 
 75:         CHARACTER(LEN=1, KIND=C_CHAR), INTENT(IN) :: C_CUDAPOT ! Character specifying the CUDA potential to be used 75:         CHARACTER(LEN=1, KIND=C_CHAR), INTENT(IN) :: C_CUDAPOT ! Character specifying the CUDA potential to be used
 76:  76: 
 77:     END SUBROUTINE CUDA_LBFGS 77:     END SUBROUTINE CUDA_LBFGS
 78: END INTERFACE 78: END INTERFACE
 79:  79: 
 80: INTERFACE 80: INTERFACE
 81:     SUBROUTINE CUDA_ENEGRAD_CPUTOGPU(NATOMS, COORDS, C_TOTENERGY, C_GRADIENTS) BIND(C,NAME="gminoptim_enegrad_cputogpu") 81:     SUBROUTINE ENEGRAD_CPUTOGPU(NATOMS, COORDS, C_TOTENERGY, C_GRADIENTS) BIND(C,NAME="gmin_enegrad_cputogpu")
 82:  82: 
 83:         IMPORT :: C_INT, C_DOUBLE 83:         IMPORT :: C_INT, C_DOUBLE
 84:  84: 
 85:         INTEGER(KIND=C_INT), INTENT(IN) :: NATOMS ! No. of atoms 85:         INTEGER(KIND=C_INT), INTENT(IN) :: NATOMS ! No. of atoms
 86:  86: 
 87:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS), INTENT(IN) :: COORDS ! Atomic coordinates 87:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS), INTENT(IN) :: COORDS ! Atomic coordinates
 88:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_TOTENERGY ! Total energy of the system 88:         REAL(KIND=C_DOUBLE), INTENT(OUT) :: C_TOTENERGY ! Total energy of the system
 89:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS), INTENT(OUT) :: C_GRADIENTS ! Gradient of the energy w.r.t. each atomic coordinate 89:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS), INTENT(OUT) :: C_GRADIENTS ! Gradient of the energy w.r.t. each atomic coordinate
 90:  90: 
 91:     END SUBROUTINE CUDA_ENEGRAD_CPUTOGPU     91:     END SUBROUTINE ENEGRAD_CPUTOGPU    
 92: END INTERFACE 92: END INTERFACE
 93: #endif /* DUMMY_CUDA */ 93: #endif /* DUMMY_CUDA */
 94:  94: 
 95: CONTAINS 95: CONTAINS
 96:  96: 
 97:     SUBROUTINE CUDA_LBFGS_WRAPPER(N, MUPDATE, XCOORDS, EPS, MFLAG, ENERGY, ITMAX, ITDONE, RESET) 97:     SUBROUTINE CUDA_LBFGS_WRAPPER(N,XCOORDS,EPS,MFLAG,ENERGY,ITMAX,ITDONE,RESET)
 98:  98: 
 99:         ! Variables passed as *arguments through this wrapper* (not common) with intent in for CUDA_LBFGS are converted directly 99:         ! Variables passed as *arguments through this wrapper* (not common) with intent in for CUDA_LBFGS are converted directly
100: #ifndef DUMMY_CUDA100: #ifndef DUMMY_CUDA
101:         INTEGER(KIND=C_INT) :: N, MUPDATE, ITMAX, C_ITDONE, ECALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, C_NFREEZE101:         INTEGER(KIND=C_INT) :: N, ITMAX, C_ITDONE, ECALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, C_MUPDATE, C_NFREEZE
102:         INTEGER(KIND=C_INT), DIMENSION(NRIGIDBODY) :: C_NSITEPERBODY102:         INTEGER(KIND=C_INT), DIMENSION(NRIGIDBODY) :: C_NSITEPERBODY
103:         INTEGER(KIND=C_INT), DIMENSION(MAXSITE*NRIGIDBODY) :: C_RIGIDGROUPS103:         INTEGER(KIND=C_INT), DIMENSION(MAXSITE*NRIGIDBODY) :: C_RIGIDGROUPS
104:         INTEGER(KIND=C_INT), DIMENSION(DEGFREEDOMS/3 - 2*NRIGIDBODY) :: C_RIGIDSINGLES104:         INTEGER(KIND=C_INT), DIMENSION(DEGFREEDOMS/3 - 2*NRIGIDBODY) :: C_RIGIDSINGLES
105: 105: 
106:         REAL(KIND=C_DOUBLE) :: EPS, C_MAXBFGS, C_MAXERISE, C_ENERGY, C_RMS, C_COLDFUSIONLIMIT, C_DGUESS, C_BQMAX, POTENTIALTIME106:         REAL(KIND=C_DOUBLE) :: EPS, C_MAXBFGS, C_MAXERISE, C_ENERGY, C_RMS, C_COLDFUSIONLIMIT, C_DGUESS, C_BQMAX
107:         REAL(KIND=C_DOUBLE), DIMENSION(MAXSITE*3*NRIGIDBODY) :: C_SITESRIGIDBODY107:         REAL(KIND=C_DOUBLE), DIMENSION(MAXSITE*3*NRIGIDBODY) :: C_SITESRIGIDBODY
108:         REAL(KIND=C_DOUBLE), DIMENSION(NRIGIDBODY*3*3) :: C_IINVERSE108:         REAL(KIND=C_DOUBLE), DIMENSION(NRIGIDBODY*3*3) :: C_IINVERSE
109:         REAL(KIND=C_DOUBLE), DIMENSION(N) :: C_XCOORDS109:         REAL(KIND=C_DOUBLE), DIMENSION(N) :: C_XCOORDS
110: 110: 
111:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_ATOMRIGIDCOORDT, C_COLDFUSION, C_FREEZE, PROJECT111:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_ATOMRIGIDCOORDT, C_COLDFUSION, C_FREEZE, PROJECT
112:         LOGICAL(KIND=C_BOOL), DIMENSION(N) :: C_FROZEN112:         LOGICAL(KIND=C_BOOL), DIMENSION(N) :: C_FROZEN
113: 113: 
114:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT114:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT
115: #endif115: #endif
116:         ! Same as above, but now dimension(1).116:         ! Same as above, but now dimension(1).
117: #ifdef DUMMY_CUDA117: #ifdef DUMMY_CUDA
118:         INTEGER(KIND=C_INT) :: N, MUPDATE, ITMAX, C_ITDONE, ECALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, C_NFREEZE118:         INTEGER(KIND=C_INT) :: N, ITMAX, C_ITDONE, ECALLS, C_DEGFREEDOMS, C_NRIGIDBODY, C_MAXSITE, C_MUPDATE, C_NFREEZE
119:         INTEGER(KIND=C_INT), DIMENSION(1) :: C_NSITEPERBODY119:         INTEGER(KIND=C_INT), DIMENSION(1) :: C_NSITEPERBODY
120:         INTEGER(KIND=C_INT), DIMENSION(1) :: C_RIGIDGROUPS120:         INTEGER(KIND=C_INT), DIMENSION(1) :: C_RIGIDGROUPS
121:         INTEGER(KIND=C_INT), DIMENSION(1) :: C_RIGIDSINGLES121:         INTEGER(KIND=C_INT), DIMENSION(1) :: C_RIGIDSINGLES
122: 122: 
123:         REAL(KIND=C_DOUBLE) :: EPS, C_MAXBFGS, C_MAXERISE, C_ENERGY, C_RMS, C_COLDFUSIONLIMIT, C_DGUESS, C_BQMAX, POTENTIALTIME123:         REAL(KIND=C_DOUBLE) :: EPS, C_MAXBFGS, C_MAXERISE, C_ENERGY, C_RMS, C_COLDFUSIONLIMIT, C_DGUESS, C_BQMAX
124:         REAL(KIND=C_DOUBLE), DIMENSION(1) :: C_SITESRIGIDBODY124:         REAL(KIND=C_DOUBLE), DIMENSION(1) :: C_SITESRIGIDBODY
125:         REAL(KIND=C_DOUBLE), DIMENSION(1) :: C_IINVERSE125:         REAL(KIND=C_DOUBLE), DIMENSION(1) :: C_IINVERSE
126:         REAL(KIND=C_DOUBLE), DIMENSION(1) :: C_XCOORDS126:         REAL(KIND=C_DOUBLE), DIMENSION(1) :: C_XCOORDS
127: 127: 
128:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_ATOMRIGIDCOORDT, C_COLDFUSION, C_FREEZE, PROJECT128:         LOGICAL(KIND=C_BOOL) :: C_MFLAG, C_DEBUG, C_CUDATIMET, C_ATOMRIGIDCOORDT, C_COLDFUSION, C_FREEZE, PROJECT
129:         LOGICAL(KIND=C_BOOL), DIMENSION(N) :: C_FROZEN129:         LOGICAL(KIND=C_BOOL), DIMENSION(N) :: C_FROZEN
130: 130: 
131:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT131:         CHARACTER(LEN=1, KIND=C_CHAR) :: C_CUDAPOT
132: #endif132: #endif
133: 133: 
135:         ! Therefore uninitialised C types are passed in and converted types are copied back after the call135:         ! Therefore uninitialised C types are passed in and converted types are copied back after the call
136: 136: 
137:         INTEGER :: I, J, K, ITDONE137:         INTEGER :: I, J, K, ITDONE
138:         DOUBLE PRECISION :: ENERGY, POTEL138:         DOUBLE PRECISION :: ENERGY, POTEL
139:         DOUBLE PRECISION, DIMENSION(N) :: XCOORDS139:         DOUBLE PRECISION, DIMENSION(N) :: XCOORDS
140:         LOGICAL :: MFLAG, RESET140:         LOGICAL :: MFLAG, RESET
141: #ifndef DUMMY_CUDA141: #ifndef DUMMY_CUDA
142:         COMMON /MYPOT/ POTEL142:         COMMON /MYPOT/ POTEL
143: 143: 
144:         IF (.NOT. RESET) THEN144:         IF (.NOT. RESET) THEN
145:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Warning: LBFGS resetting, though RESET is false. "145:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Warning: LBFGS resetting. "
146:         END IF146:         END IF
147: 147: 
148:         IF (DUMPT .AND. DEBUG) THEN148:         IF (DUMPT .AND. DEBUG) THEN
149:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Warning: printing behaviour of DUMP and DEBUG during minimization is not implemented. "149:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Warning: printing behaviour of DUMP and DEBUG during minimization is not implemented. "
150:         END IF150:         END IF
151: 151: 
152:         IF ((SEEDT.AND.FREEZECORE) .OR. STEEREDMINT .OR. QUENCHDOS .OR. CENT .OR. CALCQT .OR. INTMINT .OR. COMPRESSRIGIDT) THEN152:         IF ((SEEDT.AND.FREEZECORE) .OR. STEEREDMINT .OR. QUENCHDOS .OR. CENT .OR. CALCQT .OR. INTMINT .OR. COMPRESSRIGIDT) THEN
153:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Keyword SEED with FREEZECORE is not yet supported. SEED can be used with NOFREEZE. &153:             WRITE(MYUNIT,'(A)') "modcudalbfgs> Keyword SEED with FREEZECORE is not yet supported. SEED can be used with NOFREEZE. &
154:                                  Keywords STEEREDMIN, QUENCHDOS, CENTRE, CALCQ, INTMIN, COMPRESSRIGID are not yet supported. & 154:                                  Keywords STEEREDMIN, QUENCHDOS, CENTRE, CALCQ, INTMIN, COMPRESSRIGID are not yet supported. & 
155:                                  Contact rgm38 if you would like a feature to be added. "155:                                  Contact rgm38 if you would like a feature to be added. "
199: 199: 
200:         C_CUDAPOT = CUDAPOT200:         C_CUDAPOT = CUDAPOT
201:         C_DEBUG = DEBUG201:         C_DEBUG = DEBUG
202:         C_CUDATIMET = CUDATIMET202:         C_CUDATIMET = CUDATIMET
203:         C_MAXBFGS = MAXBFGS203:         C_MAXBFGS = MAXBFGS
204:         C_MAXERISE = MAXERISE204:         C_MAXERISE = MAXERISE
205:         C_ATOMRIGIDCOORDT = ATOMRIGIDCOORDT205:         C_ATOMRIGIDCOORDT = ATOMRIGIDCOORDT
206:         C_DEGFREEDOMS = DEGFREEDOMS206:         C_DEGFREEDOMS = DEGFREEDOMS
207:         C_NRIGIDBODY = NRIGIDBODY207:         C_NRIGIDBODY = NRIGIDBODY
208:         C_MAXSITE = MAXSITE208:         C_MAXSITE = MAXSITE
 209:         C_COLDFUSION = .FALSE. ! Set to false here rather than COLDFUSION as it should definitely be false at this point
209:         C_COLDFUSIONLIMIT = COLDFUSIONLIMIT210:         C_COLDFUSIONLIMIT = COLDFUSIONLIMIT
210:         C_DGUESS = DGUESS211:         C_DGUESS = DGUESS
 212:         C_MUPDATE = MUPDATE
211:         C_BQMAX = BQMAX213:         C_BQMAX = BQMAX
212:         C_FREEZE = FREEZE214:         C_FREEZE = FREEZE
213:         C_NFREEZE = NFREEZE215:         C_NFREEZE = NFREEZE
214:         PROJECT = .FALSE.216:         PROJECT = .FALSE.
215: 217: 
216:         ! 'C_' prefix denotes those variables which have intent out or inout or are copies of those from common blocks/modules 218:         ! 'C_' prefix denotes those variables which have intent out or inout or are copies of those from common blocks/modules 
217:         CALL CUDA_LBFGS(N, C_XCOORDS, EPS, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, & 219:         CALL CUDA_LBFGS(N, C_XCOORDS, EPS, C_MFLAG, C_ENERGY, ITMAX, C_ITDONE, C_MAXBFGS, C_MAXERISE, C_RMS, C_CUDAPOT, & 
218:                        C_DEBUG, C_CUDATIMET, ECALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, C_DGUESS, MUPDATE, & 220:                        C_DEBUG, C_CUDATIMET, ECALLS, C_COLDFUSION, C_COLDFUSIONLIMIT, C_DGUESS, C_MUPDATE, & 
219:                        C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, & 221:                        C_ATOMRIGIDCOORDT, C_DEGFREEDOMS, C_NRIGIDBODY, C_NSITEPERBODY, C_RIGIDGROUPS, C_MAXSITE, & 
220:                        C_SITESRIGIDBODY, C_RIGIDSINGLES, C_BQMAX, C_IINVERSE, PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE, & 222:                        C_SITESRIGIDBODY, C_RIGIDSINGLES, C_BQMAX, C_IINVERSE, PROJECT, C_FREEZE, C_FROZEN, C_NFREEZE)
221:                        POTENTIALTIME) 
222: 223: 
223:         ! Make sure C types with intent out or inout are coverted back to Fortran ones224:         ! Make sure C types with intent out or inout are coverted back to Fortran ones
224: 225: 
225:         DO I = 1,N226:         DO I = 1,N
226:             XCOORDS(I) = DBLE(C_XCOORDS(I))227:             XCOORDS(I) = DBLE(C_XCOORDS(I))
227:         END DO228:         END DO
228: 229: 
229:         ENERGY = DBLE(C_ENERGY)230:         ENERGY = DBLE(C_ENERGY)
230:         RMS = DBLE(C_RMS)231:         RMS = DBLE(C_RMS)
231:         MFLAG = LOGICAL(C_MFLAG)232:         MFLAG = LOGICAL(C_MFLAG)
252:         REAL(KIND=C_DOUBLE) :: C_TOTENERGY253:         REAL(KIND=C_DOUBLE) :: C_TOTENERGY
253:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS) :: COORDS, C_GRADIENTS254:         REAL(KIND=C_DOUBLE), DIMENSION(3*NATOMS) :: COORDS, C_GRADIENTS
254: 255: 
255:         INTEGER :: X256:         INTEGER :: X
256: 257: 
257:         DOUBLE PRECISION :: TOTENERGY258:         DOUBLE PRECISION :: TOTENERGY
258:         DOUBLE PRECISION, DIMENSION(3*NATOMS) :: GRADIENTS259:         DOUBLE PRECISION, DIMENSION(3*NATOMS) :: GRADIENTS
259: 260: 
260: #ifndef DUMMY_CUDA261: #ifndef DUMMY_CUDA
261:         ! Calculates the energy and gradients on the GPU using the GB potential262:         ! Calculates the energy and gradients on the GPU using the GB potential
262:         CALL CUDA_ENEGRAD_CPUTOGPU(NATOMS, COORDS, C_TOTENERGY, C_GRADIENTS)263:         CALL ENEGRAD_CPUTOGPU(NATOMS, COORDS, C_TOTENERGY, C_GRADIENTS)
263: 264: 
264:         TOTENERGY = DBLE(C_TOTENERGY)265:         TOTENERGY = DBLE(C_TOTENERGY)
265:         266:         
266:         DO X = 1,(3*NATOMS)267:         DO X = 1,(3*NATOMS)
267:             GRADIENTS(X) = DBLE(C_GRADIENTS(X))268:             GRADIENTS(X) = DBLE(C_GRADIENTS(X))
268:         END DO269:         END DO
269: #endif270: #endif
270:     END SUBROUTINE CUDA_ENEGRAD_WRAPPER271:     END SUBROUTINE CUDA_ENEGRAD_WRAPPER
271: 272: 
272: END MODULE MODCUDALBFGS273: END MODULE MODCUDALBFGS


r29015/mylbfgs.f90 2015-11-17 23:33:12.580673470 +0000 r29014/mylbfgs.f90 2015-11-17 23:33:18.124747824 +0000
 52:       IF (HYBRIDMINT) THEN 52:       IF (HYBRIDMINT) THEN
 53:          EPS_TEMP = EPSRIGID 53:          EPS_TEMP = EPSRIGID
 54:       ELSE 54:       ELSE
 55:          EPS_TEMP = EPS 55:          EPS_TEMP = EPS
 56:       END IF 56:       END IF
 57: ! Call to CUDA LBFGS for rigid minimisation to tolerance epsrigid before the atomistic minimisation 57: ! Call to CUDA LBFGS for rigid minimisation to tolerance epsrigid before the atomistic minimisation
 58:       IF (CUDAT) THEN 58:       IF (CUDAT) THEN
 59:          IF (.NOT. (AMBER12T)) THEN 59:          IF (.NOT. (AMBER12T)) THEN
 60:             CALL RADCOM(XCOORDS, .TRUE.) ! Evaporated atoms moved back in 60:             CALL RADCOM(XCOORDS, .TRUE.) ! Evaporated atoms moved back in
 61:          END IF 61:          END IF
 62:          CALL CUDA_LBFGS_WRAPPER(N, M, XCOORDS, EPS_TEMP, MFLAG, ENERGY, ITMAX, ITDONE, RESET) 62:          CALL CUDA_LBFGS_WRAPPER(N, XCOORDS, EPS_TEMP, MFLAG, ENERGY, ITMAX, ITDONE, RESET)
 63:          IF (.NOT. (AMBER12T)) THEN 63:          IF (.NOT. (AMBER12T)) THEN
 64:             EVAP = .FALSE. 64:             EVAP = .FALSE.
 65:             CALL RADCOM(XCOORDS, .FALSE.) ! Evaporated atoms NOT moved back in 65:             CALL RADCOM(XCOORDS, .FALSE.) ! Evaporated atoms NOT moved back in
 66:             MFLAG = (.NOT. EVAP) 66:             MFLAG = (.NOT. EVAP)
 67:          END IF 67:          END IF
 68:       ELSE 68:       ELSE
 69:          CALL MYMYLBFGS(N, M, XCOORDS, DIAGCO, EPS_TEMP, MFLAG, ENERGY, ITMAX, ITDONE, RESET, NP) 69:          CALL MYMYLBFGS(N, M, XCOORDS, DIAGCO, EPS_TEMP, MFLAG, ENERGY, ITMAX, ITDONE, RESET, NP)
 70:       END IF 70:       END IF
 71:       IF (DEBUG.AND.HYBRIDMINT) WRITE(MYUNIT, '(A)') ' HYBRIDMIN> Rigid body minimisation converged, switching to all-atom' 71:       IF (DEBUG.AND.HYBRIDMINT) WRITE(MYUNIT, '(A)') ' HYBRIDMIN> Rigid body minimisation converged, switching to all-atom'
 72: ! Convert back to atomistic coordinates.  72: ! Convert back to atomistic coordinates. 
 76:    END IF 76:    END IF
 77:  77: 
 78: ! If we're not using rigid bodies, or we've already completed a rigid body minimisation and we're using 78: ! If we're not using rigid bodies, or we've already completed a rigid body minimisation and we're using
 79: ! hybrid minimisation, then perform a minimisation in atomistic coordinates. 79: ! hybrid minimisation, then perform a minimisation in atomistic coordinates.
 80:    IF ((.NOT. RIGIDINIT) .OR. HYBRIDMINT) THEN 80:    IF ((.NOT. RIGIDINIT) .OR. HYBRIDMINT) THEN
 81:       IF (CUDAT) THEN 81:       IF (CUDAT) THEN
 82: ! Call to CUDA LBFGS for rigid minimisation 82: ! Call to CUDA LBFGS for rigid minimisation
 83:          IF (.NOT. (AMBER12T)) THEN 83:          IF (.NOT. (AMBER12T)) THEN
 84:             CALL RADCOM(XCOORDS, .TRUE.) ! Evaporated atoms moved back in 84:             CALL RADCOM(XCOORDS, .TRUE.) ! Evaporated atoms moved back in
 85:          END IF 85:          END IF
 86:          CALL CUDA_LBFGS_WRAPPER(N, M, XCOORDS, EPS, MFLAG, ENERGY, ITMAX, ITDONE, RESET) 86:          CALL CUDA_LBFGS_WRAPPER(N, XCOORDS, EPS, MFLAG, ENERGY, ITMAX, ITDONE, RESET)
 87:          IF (.NOT. (AMBER12T)) THEN 87:          IF (.NOT. (AMBER12T)) THEN
 88:             EVAP = .FALSE. 88:             EVAP = .FALSE.
 89:             CALL RADCOM(XCOORDS, .FALSE.) ! Evaporated atoms NOT moved back in 89:             CALL RADCOM(XCOORDS, .FALSE.) ! Evaporated atoms NOT moved back in
 90:             MFLAG = (.NOT. EVAP) 90:             MFLAG = (.NOT. EVAP)
 91:          END IF 91:          END IF
 92:       ELSE 92:       ELSE
 93:          CALL MYMYLBFGS(N, M, XCOORDS, DIAGCO, EPS, MFLAG, ENERGY, ITMAX, ITDONE, RESET, NP) 93:          CALL MYMYLBFGS(N, M, XCOORDS, DIAGCO, EPS, MFLAG, ENERGY, ITMAX, ITDONE, RESET, NP)
 94:       END IF 94:       END IF
 95:    END IF 95:    END IF
 96:  96: 


r29015/potential.f 2015-11-17 23:33:14.508699325 +0000 r29014/potential.f 2015-11-17 23:33:19.552766972 +0000
 27:          use SDWATER, ONLY : SDPOTENTIAL, SDGRAD, SDHESS 27:          use SDWATER, ONLY : SDPOTENTIAL, SDGRAD, SDHESS
 28:          USE MCY, ONLY : MCYPOT=>POTENTIAL 28:          USE MCY, ONLY : MCYPOT=>POTENTIAL
 29:          USE BOWMANWATER, ONLY : BOWMANPOT 29:          USE BOWMANWATER, ONLY : BOWMANPOT
 30:          USE FINITE_DIFFERENCES 30:          USE FINITE_DIFFERENCES
 31:          USE MODAMBER9,only : ifswitch,goodstructure1,irespa,cisarray1,checkcistransalways,checkcistransalwaysdna, 31:          USE MODAMBER9,only : ifswitch,goodstructure1,irespa,cisarray1,checkcistransalways,checkcistransalwaysdna,
 32:      1   checkcistransalwaysrna 32:      1   checkcistransalwaysrna
 33:          ! hk286 33:          ! hk286
 34:          USE GENRIGID 34:          USE GENRIGID
 35:          USE CHIRALITY, ONLY: CIS_TRANS_CHECK, CHIRALITY_CHECK 35:          USE CHIRALITY, ONLY: CIS_TRANS_CHECK, CHIRALITY_CHECK
 36:          USE AMBER12_INTERFACE_MOD, ONLY: AMBER12_ENERGY_AND_GRADIENT, POT_ENE_REC_C, AMBER12_NUM_HESS 36:          USE AMBER12_INTERFACE_MOD, ONLY: AMBER12_ENERGY_AND_GRADIENT, POT_ENE_REC_C, AMBER12_NUM_HESS
 37:          USE MODCUDALBFGS, ONLY: CUDA_ENEGRAD_WRAPPER 
 38:          ! use AMHGLOBALS 37:          ! use AMHGLOBALS
 39:  38: 
 40:          IMPLICIT NONE 39:          IMPLICIT NONE
 41:  40: 
 42:          DOUBLE PRECISION, DIMENSION(3*NATOMS) :: COORDS 41:          DOUBLE PRECISION, DIMENSION(3*NATOMS) :: COORDS
 43:          DOUBLE PRECISION ENERGY 42:          DOUBLE PRECISION ENERGY
 44:          DOUBLE PRECISION, DIMENSION(3*NATOMS) :: VNEW 43:          DOUBLE PRECISION, DIMENSION(3*NATOMS) :: VNEW
 45:          LOGICAL GTEST, STEST 44:          LOGICAL GTEST, STEST
 46:          DOUBLE PRECISION RMS 45:          DOUBLE PRECISION RMS
 47:          LOGICAL PTEST, BOXTEST, file_exists 46:          LOGICAL PTEST, BOXTEST, file_exists
2926:                CALL TRANSFORMRIGIDTOC(1, NRIGIDBODY, COORDS, XRIGIDCOORDS)2925:                CALL TRANSFORMRIGIDTOC(1, NRIGIDBODY, COORDS, XRIGIDCOORDS)
2927:             ENDIF2926:             ENDIF
2928: ! Check cis/trans isomerisation - actually, chirality of sugar ring carbons for nucleic acids2927: ! Check cis/trans isomerisation - actually, chirality of sugar ring carbons for nucleic acids
2929:             IF (CHECKCISTRANSALWAYSDNA .OR. CHECKCISTRANSALWAYSRNA) THEN2928:             IF (CHECKCISTRANSALWAYSDNA .OR. CHECKCISTRANSALWAYSRNA) THEN
2930:                CALL CHIRALITY_CHECK(COORDS, GOODSTRUCTURE1)2929:                CALL CHIRALITY_CHECK(COORDS, GOODSTRUCTURE1)
2931:             END IF2930:             END IF
2932: ! Check cis/trans isomerisation for proteins2931: ! Check cis/trans isomerisation for proteins
2933:             IF (CHECKCISTRANSALWAYS) THEN2932:             IF (CHECKCISTRANSALWAYS) THEN
2934:                CALL CIS_TRANS_CHECK(COORDS, GOODSTRUCTURE1)2933:                CALL CIS_TRANS_CHECK(COORDS, GOODSTRUCTURE1)
2935:             END IF2934:             END IF
2936:             IF (CUDAT) THEN2935:             CALL AMBER12_ENERGY_AND_GRADIENT(NATOMS,
2937:                ! This call copies CPU coordinates to GPU, calculates energy/gradient and copies energy/gradient back to CPU2936:      &                                       COORDS,
2938:                CALL CUDA_ENEGRAD_WRAPPER(NATOMS, COORDS, ENERGY, VNEW(1:3*NATOMS))2937:      &                                       ENERGY,
2939:             ELSE2938:      &                                       VNEW(1:3*NATOMS),
2940:                CALL AMBER12_ENERGY_AND_GRADIENT(NATOMS,2939:      &                                       ENERGY_DECOMP)
2941:      &                                          COORDS, 
2942:      &                                          ENERGY, 
2943:      &                                          VNEW(1:3*NATOMS), 
2944:      &                                          ENERGY_DECOMP) 
2945:             END IF 
2946: ! Calculate the numerical hessian2940: ! Calculate the numerical hessian
2947:             IF (STEST) THEN2941:             IF (STEST) THEN
2948:                IF (.NOT. ALLOCATED(HESS)) ALLOCATE(HESS(3*NATOMS, 3*NATOMS))2942:                IF (.NOT. ALLOCATED(HESS)) ALLOCATE(HESS(3*NATOMS, 3*NATOMS))
2949:                CALL AMBER12_NUM_HESS(NATOMS, COORDS, DELTA=1.0D-5, HESSIAN=HESS(:, :))2943:                CALL AMBER12_NUM_HESS(NATOMS, COORDS, DELTA=1.0D-5, HESSIAN=HESS(:, :))
2950:             END IF2944:             END IF
2951:             IF (PTEST) THEN2945:             IF (PTEST) THEN
2952:                WRITE(*,10) ' potential> Energy for last cycle=',ENERGY,' kcal/mol'2946:                WRITE(*,10) ' potential> Energy for last cycle=',ENERGY,' kcal/mol'
2953:                WRITE(ESTRING,10) 'Energy for last cycle=',ENERGY,' kcal/mol'2947:                WRITE(ESTRING,10) 'Energy for last cycle=',ENERGY,' kcal/mol'
2954:             ENDIF2948:             ENDIF
2955:             IF (RIGIDINIT .AND. (.NOT. ATOMRIGIDCOORDT) ) THEN2949:             IF (RIGIDINIT .AND. (.NOT. ATOMRIGIDCOORDT) ) THEN


r29015/potential.f90 2015-11-17 23:33:12.768675990 +0000 r29014/potential.f90 2015-11-17 23:33:18.316750396 +0000
362:          ELSE362:          ELSE
363:             CALL AMBER12_ENERGY_AND_GRADIENT(NATOMS, X, EREAL, GRADATOMS, AMBER12_ENERGY_DECOMP)363:             CALL AMBER12_ENERGY_AND_GRADIENT(NATOMS, X, EREAL, GRADATOMS, AMBER12_ENERGY_DECOMP)
364:             GRAD(1:3*NATOMS)=GRADATOMS(:)364:             GRAD(1:3*NATOMS)=GRADATOMS(:)
365:          END IF365:          END IF
366: ! If the coordinates include rigid bodies, transform them back to being atomistic first366: ! If the coordinates include rigid bodies, transform them back to being atomistic first
367:       ELSE367:       ELSE
368:          XRIGIDCOORDS(1:DEGFREEDOMS)=X(1:DEGFREEDOMS)368:          XRIGIDCOORDS(1:DEGFREEDOMS)=X(1:DEGFREEDOMS)
369:          CALL TRANSFORMRIGIDTOC(1, NRIGIDBODY, XCOORDS, XRIGIDCOORDS)369:          CALL TRANSFORMRIGIDTOC(1, NRIGIDBODY, XCOORDS, XRIGIDCOORDS)
370: ! Now call the AMBER 12 energy and gradient370: ! Now call the AMBER 12 energy and gradient
371:          IF (CUDAT) THEN371:          IF (CUDAT) THEN
372:             CALL CUDA_ENEGRAD_WRAPPER(NATOMS, XCOORDS, EREAL, GRADATOMS)372:             CALL CUDA_ENEGRAD_WRAPPER(NATOMS, X, EREAL, GRADATOMS)
373:             GRAD(1:3*NATOMS)=GRADATOMS(:)373:             GRAD(1:3*NATOMS)=GRADATOMS(:)
374:          ELSE374:          ELSE
375:             CALL AMBER12_ENERGY_AND_GRADIENT(NATOMS, XCOORDS, EREAL, GRADATOMS, AMBER12_ENERGY_DECOMP)375:             CALL AMBER12_ENERGY_AND_GRADIENT(NATOMS, XCOORDS, EREAL, GRADATOMS, AMBER12_ENERGY_DECOMP)
376:             GRAD(1:3*NATOMS)=GRADATOMS(:)376:             GRAD(1:3*NATOMS)=GRADATOMS(:)
377:          END IF377:          END IF
378: ! Transform the gradient and coordinates back to the rigid body representation 378: ! Transform the gradient and coordinates back to the rigid body representation 
379:          CALL TRANSFORMGRAD(GRADATOMS, XRIGIDCOORDS, XRIGIDGRAD)379:          CALL TRANSFORMGRAD(GRADATOMS, XRIGIDCOORDS, XRIGIDGRAD)
380:          X(1:DEGFREEDOMS)=XRIGIDCOORDS(1:DEGFREEDOMS)380:          X(1:DEGFREEDOMS)=XRIGIDCOORDS(1:DEGFREEDOMS)
381:          X(DEGFREEDOMS+1:3*NATOMS)=0.0D0381:          X(DEGFREEDOMS+1:3*NATOMS)=0.0D0
382:          GRAD(1:DEGFREEDOMS)=XRIGIDGRAD(1:DEGFREEDOMS)382:          GRAD(1:DEGFREEDOMS)=XRIGIDGRAD(1:DEGFREEDOMS)


r29015/rigid_bodies.cu 2015-11-17 23:33:10.656647665 +0000 r29014/rigid_bodies.cu 2015-11-17 23:33:16.236722500 +0000
 58:                         const double *m_d_sitesRigidBody, const int *m_d_rigidGroups, double *d_tempArray,  58:                         const double *m_d_sitesRigidBody, const int *m_d_rigidGroups, double *d_tempArray, 
 59:                         const int *m_d_nRigidBody, const int *m_d_rigidMaxSite); 59:                         const int *m_d_nRigidBody, const int *m_d_rigidMaxSite);
 60:  60: 
 61:         __global__ void aaConvTorque(const double *d_torques, const double *m_d_gkRigid, const double *d_grmi0,  61:         __global__ void aaConvTorque(const double *d_torques, const double *m_d_gkRigid, const double *d_grmi0, 
 62:                         const int *m_d_nRigidSitesPerBody, const double *m_d_rigidInverse, double *d_rmsArray,  62:                         const int *m_d_nRigidSitesPerBody, const double *m_d_rigidInverse, double *d_rmsArray, 
 63:                         const int *m_d_nRigidBody); 63:                         const int *m_d_nRigidBody);
 64:  64: 
 65:         __global__ void ones4(const int *m_d_nRigidBody, double *d_nRigidBodyOnes); 65:         __global__ void ones4(const int *m_d_nRigidBody, double *d_nRigidBodyOnes);
 66: } 66: }
 67:  67: 
 68:  
 69:  
 70: void CostFunction::transformRigidToC(double *d_x) 68: void CostFunction::transformRigidToC(double *d_x)
 71: { 69: {
 72:         using namespace gpu_rigid_bodies; 70:         using namespace gpu_rigid_bodies;
 73:  71: 
 74:         // Copy atomistic coordinates to rigid coordinates.  72:         // Copy atomistic coordinates to rigid coordinates. 
 75:         CudaSafeCall( cudaMemcpy(m_d_xRigid, d_x, m_nDegFreedom * sizeof(double), cudaMemcpyDeviceToDevice) ); 73:         CudaSafeCall( cudaMemcpy(m_d_xRigid, d_x, m_nDegFreedom * sizeof(double), cudaMemcpyDeviceToDevice) );
 76:  74: 
 77:         // Temporary global memory storage for rotation matrices.  75:         // Temporary global memory storage for rotation matrices. 
 78:         double *d_grmi; 76:         double *d_grmi;
 79:         CudaSafeCall( cudaMalloc(&d_grmi, 9 * m_nRigidBody * sizeof(double)) ); 77:         CudaSafeCall( cudaMalloc(&d_grmi, 9 * m_nRigidBody * sizeof(double)) );
112:                 blockDim.x = 1024;110:                 blockDim.x = 1024;
113:                 gridDim.x = (hostSinglesThreads + blockDim.x - 1)/blockDim.x;111:                 gridDim.x = (hostSinglesThreads + blockDim.x - 1)/blockDim.x;
114: 112: 
115:                 // Treatment of single atoms not in rigid bodies. 113:                 // Treatment of single atoms not in rigid bodies. 
116:                 gpu_rigid_bodies::singleAtoms<<<gridDim, blockDim>>>(d_x, m_d_xRigid, m_d_rigidSingles, m_d_nRigidBody);114:                 gpu_rigid_bodies::singleAtoms<<<gridDim, blockDim>>>(d_x, m_d_xRigid, m_d_rigidSingles, m_d_nRigidBody);
117:                 CudaCheckError();115:                 CudaCheckError();
118:                 cudaDeviceSynchronize();116:                 cudaDeviceSynchronize();
119:         }117:         }
120: }118: }
121: 119: 
122:  
123:  
124: void CostFunction::transformGrad(double *d_gk, double *d_x)120: void CostFunction::transformGrad(double *d_gk, double *d_x)
125: {121: {
126:         using namespace gpu_rigid_bodies;122:         using namespace gpu_rigid_bodies;
127: 123: 
128:         const size_t numDimensions = m_numDimensions;124:         const size_t numDimensions = m_numDimensions;
129: 125: 
130:         double *zeros;126:         double *zeros;
131:         zeros = new double[numDimensions];127:         zeros = new double[numDimensions];
132:         for (size_t i = 0; i < numDimensions; ++i) {128:         for (size_t i = 0; i < numDimensions; ++i) {
133:                 zeros[i] = 0.0;129:                 zeros[i] = 0.0;
180:                 CudaCheckError();176:                 CudaCheckError();
181:                 cudaDeviceSynchronize();177:                 cudaDeviceSynchronize();
182: 178: 
183:                 // Change zeros to ones up to appropriate number of rigid sites. 179:                 // Change zeros to ones up to appropriate number of rigid sites. 
184:                 gpu_rigid_bodies::ones1<<<gridDim, blockDim>>>(m_d_nRigidSitesPerBody, m_d_rigidGroups, d_xZeroOne, 180:                 gpu_rigid_bodies::ones1<<<gridDim, blockDim>>>(m_d_nRigidSitesPerBody, m_d_rigidGroups, d_xZeroOne, 
185:                                 d_yZeroOne, d_zZeroOne, m_d_rigidMaxSite);181:                                 d_yZeroOne, d_zZeroOne, m_d_rigidMaxSite);
186:                 CudaCheckError();182:                 CudaCheckError();
187:                 cudaDeviceSynchronize();183:                 cudaDeviceSynchronize();
188: 184: 
189:                 // Reduction - library dot product is fastest way for subsections of arrays. 185:                 // Reduction - library dot product is fastest way for subsections of arrays. 
190:                 m_cublas.dispatchDot(numDimensions, (m_d_gkRigid + 3*hostThisBody), d_xZeroOne, d_gk); // gkRigid = xZeroOne Dot gk186:                 m_cublas.dispatchDot(numDimensions, (m_d_gkRigid + 3*hostThisBody), d_xZeroOne, d_gk);
191:                 m_cublas.dispatchDot(numDimensions, (m_d_gkRigid + 3*hostThisBody + 1), d_yZeroOne, d_gk); // gkRigid = yZeroOne Dot gk187:                 m_cublas.dispatchDot(numDimensions, (m_d_gkRigid + 3*hostThisBody + 1), d_yZeroOne, d_gk);
192:                 m_cublas.dispatchDot(numDimensions, (m_d_gkRigid + 3*hostThisBody + 2), d_zZeroOne, d_gk); // gkRigid = zZeroOne Dot gk188:                 m_cublas.dispatchDot(numDimensions, (m_d_gkRigid + 3*hostThisBody + 2), d_zZeroOne, d_gk);
193: 189: 
194:         }190:         }
195: 191: 
196:         CudaSafeCall( cudaFree(d_xZeroOne) );192:         CudaSafeCall( cudaFree(d_xZeroOne) );
197:         CudaSafeCall( cudaFree(d_yZeroOne) );193:         CudaSafeCall( cudaFree(d_yZeroOne) );
198:         CudaSafeCall( cudaFree(d_zZeroOne) );194:         CudaSafeCall( cudaFree(d_zZeroOne) );
199: 195: 
200:         // Temporary global memory storage for atomistic components of rigid body forces. 196:         // Temporary global memory storage for atomistic components of rigid body forces. 
201:         double *d_tempArray;197:         double *d_tempArray;
202:         int tempArraySize = 3 * m_nRigidBody * m_rigidMaxSite;198:         int tempArraySize = 3 * m_nRigidBody * m_rigidMaxSite;
241:                 CudaCheckError();237:                 CudaCheckError();
242:                 cudaDeviceSynchronize();238:                 cudaDeviceSynchronize();
243: 239: 
244:                 // Change zeros to ones up to appropriate number of rigid sites. 240:                 // Change zeros to ones up to appropriate number of rigid sites. 
245:                 gpu_rigid_bodies::ones2<<<gridDim, blockDim>>>(m_d_nRigidSitesPerBody, d_xZeroOne2, d_yZeroOne2, 241:                 gpu_rigid_bodies::ones2<<<gridDim, blockDim>>>(m_d_nRigidSitesPerBody, d_xZeroOne2, d_yZeroOne2, 
246:                                 d_zZeroOne2, m_d_rigidMaxSite);242:                                 d_zZeroOne2, m_d_rigidMaxSite);
247:                 CudaCheckError();243:                 CudaCheckError();
248:                 cudaDeviceSynchronize();244:                 cudaDeviceSynchronize();
249: 245: 
250:                 // Reduction - library dot product is fastest way for subsections of arrays. 246:                 // Reduction - library dot product is fastest way for subsections of arrays. 
251:                 m_cublas.dispatchDot(tempArraySize, (m_d_gkRigid + 3*m_nRigidBody + 3*hostThisBody),     d_xZeroOne2, d_tempArray); // gkRigid = xZeroOne2 Dot tempArray247:                 m_cublas.dispatchDot(tempArraySize, (m_d_gkRigid + 3*m_nRigidBody + 3*hostThisBody),     d_xZeroOne2, d_tempArray);
252:                 m_cublas.dispatchDot(tempArraySize, (m_d_gkRigid + 3*m_nRigidBody + 3*hostThisBody + 1), d_yZeroOne2, d_tempArray); // gkRigid = yZeroOne2 Dot tempArray248:                 m_cublas.dispatchDot(tempArraySize, (m_d_gkRigid + 3*m_nRigidBody + 3*hostThisBody + 1), d_yZeroOne2, d_tempArray);
253:                 m_cublas.dispatchDot(tempArraySize, (m_d_gkRigid + 3*m_nRigidBody + 3*hostThisBody + 2), d_zZeroOne2, d_tempArray); // gkRigid = zZeroOne2 Dot tempArray249:                 m_cublas.dispatchDot(tempArraySize, (m_d_gkRigid + 3*m_nRigidBody + 3*hostThisBody + 2), d_zZeroOne2, d_tempArray);
254:         }250:         }
255: 251: 
256:         CudaSafeCall( cudaFree(d_xZeroOne2) );252:         CudaSafeCall( cudaFree(d_xZeroOne2) );
257:         CudaSafeCall( cudaFree(d_yZeroOne2) );253:         CudaSafeCall( cudaFree(d_yZeroOne2) );
258:         CudaSafeCall( cudaFree(d_zZeroOne2) );254:         CudaSafeCall( cudaFree(d_zZeroOne2) );
259:         CudaSafeCall( cudaFree(d_tempArray) );255:         CudaSafeCall( cudaFree(d_tempArray) );
260: 256: 
261:         if (m_nDegFreedom > 6*m_nRigidBody) {257:         if (m_nDegFreedom > 6*m_nRigidBody) {
262:                 int hostSinglesThreads = (m_nDegFreedom - 6*m_nRigidBody)/3;258:                 int hostSinglesThreads = (m_nDegFreedom - 6*m_nRigidBody)/3;
263:                 CudaSafeCall( cudaMemcpyToSymbol(gpu_rigid_bodies::singlesThreads, &hostSinglesThreads, sizeof(int)) );259:                 CudaSafeCall( cudaMemcpyToSymbol(gpu_rigid_bodies::singlesThreads, &hostSinglesThreads, sizeof(int)) );
275:         // Copy rigid coordinates/gradient to atomistic coordinates/gradient and pad with zeros. 271:         // Copy rigid coordinates/gradient to atomistic coordinates/gradient and pad with zeros. 
276:         CudaSafeCall( cudaMemcpy(d_x,  zeros, numDimensions * sizeof(double), cudaMemcpyHostToDevice) );272:         CudaSafeCall( cudaMemcpy(d_x,  zeros, numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
277:         CudaSafeCall( cudaMemcpy(d_gk, zeros, numDimensions * sizeof(double), cudaMemcpyHostToDevice) );273:         CudaSafeCall( cudaMemcpy(d_gk, zeros, numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
278: 274: 
279:         CudaSafeCall( cudaMemcpy(d_x,  m_d_xRigid,  m_nDegFreedom * sizeof(double), cudaMemcpyDeviceToDevice) );275:         CudaSafeCall( cudaMemcpy(d_x,  m_d_xRigid,  m_nDegFreedom * sizeof(double), cudaMemcpyDeviceToDevice) );
280:         CudaSafeCall( cudaMemcpy(d_gk, m_d_gkRigid, m_nDegFreedom * sizeof(double), cudaMemcpyDeviceToDevice) );276:         CudaSafeCall( cudaMemcpy(d_gk, m_d_gkRigid, m_nDegFreedom * sizeof(double), cudaMemcpyDeviceToDevice) );
281: 277: 
282:         delete [] zeros;278:         delete [] zeros;
283: }279: }
284: 280: 
285:  
286:  
287: void CostFunction::aaConvergence(const double *d_gk, double *outRms)281: void CostFunction::aaConvergence(const double *d_gk, double *outRms)
288: {282: {
289:         using namespace gpu_rigid_bodies;283:         using namespace gpu_rigid_bodies;
290: 284: 
291:         *outRms = 0.0;285:         *outRms = 0.0;
292: 286: 
293:         double *d_rmi10;287:         double *d_rmi10;
294:         double *d_rmi20;288:         double *d_rmi20;
295:         double *d_rmi30;289:         double *d_rmi30;
296: 290: 
357:                 gridDim.x = (tempArraySize + blockDim.x - 1)/blockDim.x;351:                 gridDim.x = (tempArraySize + blockDim.x - 1)/blockDim.x;
358: 352: 
359:                 gpu_rigid_bodies::zeros2<<<gridDim, blockDim>>>(d_xZeroOne2, d_yZeroOne2, d_zZeroOne2);353:                 gpu_rigid_bodies::zeros2<<<gridDim, blockDim>>>(d_xZeroOne2, d_yZeroOne2, d_zZeroOne2);
360:                 CudaCheckError();354:                 CudaCheckError();
361:                 cudaDeviceSynchronize();355:                 cudaDeviceSynchronize();
362: 356: 
363:                 gpu_rigid_bodies::ones3<<<gridDim, blockDim>>>(d_xZeroOne2, d_yZeroOne2, d_zZeroOne2, m_d_rigidMaxSite);357:                 gpu_rigid_bodies::ones3<<<gridDim, blockDim>>>(d_xZeroOne2, d_yZeroOne2, d_zZeroOne2, m_d_rigidMaxSite);
364:                 CudaCheckError();358:                 CudaCheckError();
365:                 cudaDeviceSynchronize();359:                 cudaDeviceSynchronize();
366: 360: 
367:                 m_cublas.dispatchDot(tempArraySize, d_torques + 3*hostThisBody,     d_xZeroOne2, d_tempArray); // torques =  xZeroOne2 Dot tempArray361:                 m_cublas.dispatchDot(tempArraySize, d_torques + 3*hostThisBody,     d_xZeroOne2, d_tempArray);
368:                 m_cublas.dispatchDot(tempArraySize, d_torques + 3*hostThisBody + 1, d_yZeroOne2, d_tempArray); // torques =  yZeroOne2 Dot tempArray362:                 m_cublas.dispatchDot(tempArraySize, d_torques + 3*hostThisBody + 1, d_yZeroOne2, d_tempArray);
369:                 m_cublas.dispatchDot(tempArraySize, d_torques + 3*hostThisBody + 2, d_zZeroOne2, d_tempArray); // torques =  zZeroOne2 Dot twmpArray363:                 m_cublas.dispatchDot(tempArraySize, d_torques + 3*hostThisBody + 2, d_zZeroOne2, d_tempArray);
370:         }364:         }
371: 365: 
372:         CudaSafeCall( cudaFree(d_tempArray) );366:         CudaSafeCall( cudaFree(d_tempArray) );
373:         CudaSafeCall( cudaFree(d_xZeroOne2) );367:         CudaSafeCall( cudaFree(d_xZeroOne2) );
374:         CudaSafeCall( cudaFree(d_yZeroOne2) );368:         CudaSafeCall( cudaFree(d_yZeroOne2) );
375:         CudaSafeCall( cudaFree(d_zZeroOne2) );369:         CudaSafeCall( cudaFree(d_zZeroOne2) );
376: 370: 
377:         double *d_rmsArray;371:         double *d_rmsArray;
378:         double *d_nRigidBodyOnes;372:         double *d_nRigidBodyOnes;
379: 373: 
391:         CudaSafeCall( cudaFree(d_grmi0) );385:         CudaSafeCall( cudaFree(d_grmi0) );
392:         CudaSafeCall( cudaFree(d_torques) );386:         CudaSafeCall( cudaFree(d_torques) );
393: 387: 
394:         gpu_rigid_bodies::ones4<<<gridDim, blockDim>>>(m_d_nRigidBody, d_nRigidBodyOnes);388:         gpu_rigid_bodies::ones4<<<gridDim, blockDim>>>(m_d_nRigidBody, d_nRigidBodyOnes);
395:         CudaCheckError();389:         CudaCheckError();
396:         cudaDeviceSynchronize();390:         cudaDeviceSynchronize();
397: 391: 
398:         double temp1 = 0.0;392:         double temp1 = 0.0;
399:         double temp2 = 0.0;393:         double temp2 = 0.0;
400: 394: 
401:         m_cublas.dispatchDot(m_nRigidBody, &temp1, d_rmsArray, d_nRigidBodyOnes, false); // temp1 =  rmsArray Dot nRigidBodyOnes395:         m_cublas.dispatchDot(m_nRigidBody, &temp1, d_rmsArray, d_nRigidBodyOnes, false);
402: 396: 
403:         CudaSafeCall( cudaFree(d_rmsArray) );397:         CudaSafeCall( cudaFree(d_rmsArray) );
404:         CudaSafeCall( cudaFree(d_nRigidBodyOnes) );398:         CudaSafeCall( cudaFree(d_nRigidBodyOnes) );
405: 399: 
406:         if (m_nDegFreedom > 6*m_nRigidBody) {400:         if (m_nDegFreedom > 6*m_nRigidBody) {
407:                 int arraysize = m_nDegFreedom - 6*m_nRigidBody;401:                 int arraysize = m_nDegFreedom - 6*m_nRigidBody;
408: 402: 
409:                 m_cublas.dispatchDot(arraysize, &temp2, (m_d_gkRigid + 6*m_nRigidBody), (m_d_gkRigid + 6*m_nRigidBody), false); // temp2 =  gkRigid Dot gkRigid403:                 m_cublas.dispatchDot(arraysize, &temp2, (m_d_gkRigid + 6*m_nRigidBody), (m_d_gkRigid + 6*m_nRigidBody), false);
410:         }404:         }
411: 405: 
412:         *outRms = temp1 + temp2;406:         *outRms = temp1 + temp2;
413: }407: }
414: 408: 
415:  
416:  
417: namespace gpu_rigid_bodies409: namespace gpu_rigid_bodies
418: {410: {
419:         __device__ void rmdrvt(double3 p, double rmi[9], double drmi1[9], double drmi2[9], double drmi3[9], 411:         __device__ void rmdrvt(double3 p, double rmi[9], double drmi1[9], double drmi2[9], double drmi3[9], 
420:                         bool shouldFindDeriv)412:                         bool shouldFindDeriv)
421:         {413:         {
422:                 double theta2 = p.x*p.x + p.y*p.y + p.z*p.z;414:                 double theta2 = p.x*p.x + p.y*p.y + p.z*p.z;
423:                 if (theta2 < 1.0e-12) {415:                 if (theta2 < 1.0e-12) {
424:                         // Rotation matrix if magnitude of rotation is zero. 416:                         // Rotation matrix if magnitude of rotation is zero. 
425:                         rmi[0] =  1.0; // RM(1,1)417:                         rmi[0] =  1.0; // RM(1,1)
426:                         rmi[1] =  p.z; // RM(2,1)418:                         rmi[1] =  p.z; // RM(2,1)


r29015/setup_bfgsts.cu 2015-11-17 23:33:10.276642571 +0000 r29014/setup_bfgsts.cu 2015-11-17 23:33:15.860717457 +0000
 19:                 double *pushOffMag, double *maxEvecStep, double *maxMaxStep, double *minMaxStep, double *trustRadius, int *pMaxIter1,  19:                 double *pushOffMag, double *maxEvecStep, double *maxMaxStep, double *minMaxStep, double *trustRadius, int *pMaxIter1, 
 20:                 int *pMaxIter2, int *bItMax, double *evecOverlapTol, int *pUpdates, double *gradEps, double *pMaxStep,  20:                 int *pMaxIter2, int *bItMax, double *evecOverlapTol, int *pUpdates, double *gradEps, double *pMaxStep, 
 21:                 double *pMaxFkRise, double *pH0, double *evStepMagTol) 21:                 double *pMaxFkRise, double *pH0, double *evStepMagTol)
 22: { 22: {
 23:         bool isBfgsts = true; 23:         bool isBfgsts = true;
 24:         potential.setIsBfgsts(isBfgsts); 24:         potential.setIsBfgsts(isBfgsts);
 25:  25: 
 26:         bool printingOn = debugPrinting.getPrintingOn(); 26:         bool printingOn = debugPrinting.getPrintingOn();
 27:         std::ofstream &fileHandle = debugPrinting.getFileHandle(); 27:         std::ofstream &fileHandle = debugPrinting.getFileHandle();
 28:  28: 
 29:         fileHandle << "CUDA BFGSTS" << std::endl; 29:         if (printingOn) {
  30:                 fileHandle << "CUDA BFGSTS" << std::endl;
  31:         }
 30:  32: 
 31:         Timer timer_xLbfgsTotal     ("GPU_BFGSTS_Rayleigh_Ritz_total"     ); 33:         Timer timer_xLbfgsTotal     ("GPU_BFGSTS_Rayleigh_Ritz_total"     );
 32:         // Timing always turned off for updates and linesearch - setTimingOn() to turn on.  34:         // Timing always turned off for updates and linesearch - setTimingOn() to turn on. 
 33:         Timer timer_xLbfgsUpdates   ("GPU_BFGSTS_Rayleigh_Ritz_updates"   ); 35:         Timer timer_xLbfgsUpdates   ("GPU_BFGSTS_Rayleigh_Ritz_updates"   );
 34:         Timer timer_xLbfgsLinesearch("GPU_BFGSTS_Rayleigh_Ritz_linesearch"); 36:         Timer timer_xLbfgsLinesearch("GPU_BFGSTS_Rayleigh_Ritz_linesearch");
 35:  37: 
 36:         Timer timer_pLbfgsTotal     ("GPU_BFGSTS_subspace_min_total"      ); 38:         Timer timer_pLbfgsTotal     ("GPU_BFGSTS_subspace_min_total"      );
 37:         // Timing always turned off for updates and linesearch - setTimingOn() to turn on.  39:         // Timing always turned off for updates and linesearch - setTimingOn() to turn on. 
 38:         Timer timer_pLbfgsUpdates   ("GPU_BFGSTS_subspace_min_updates"    ); 40:         Timer timer_pLbfgsUpdates   ("GPU_BFGSTS_subspace_min_updates"    );
 39:         Timer timer_pLbfgsLinesearch("GPU_BFGSTS_subspace_min_linesearch" ); 41:         Timer timer_pLbfgsLinesearch("GPU_BFGSTS_subspace_min_linesearch" );
 75:         CudaSafeCall( cudaMalloc(&d_coords, numDimensions * sizeof(double)) ); 77:         CudaSafeCall( cudaMalloc(&d_coords, numDimensions * sizeof(double)) );
 76:  78: 
 77:         CudaSafeCall( cudaMemcpy(d_evec,   evec,   numDimensions * sizeof(double), cudaMemcpyHostToDevice) ); 79:         CudaSafeCall( cudaMemcpy(d_evec,   evec,   numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
 78:         CudaSafeCall( cudaMemcpy(d_coords, coords, numDimensions * sizeof(double), cudaMemcpyHostToDevice) ); 80:         CudaSafeCall( cudaMemcpy(d_coords, coords, numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
 79:  81: 
 80:         // Main BFGSTS calculation.  82:         // Main BFGSTS calculation. 
 81:         bfgstsStatus = bfgsts.findTs(d_coords, d_evec, energy, evalMin, outRms, bIter); 83:         bfgstsStatus = bfgsts.findTs(d_coords, d_evec, energy, evalMin, outRms, bIter);
 82:  84: 
 83:         if (bfgstsStatus == Bfgsts::BFGSTS_CONVERGED_TO_TS) { 85:         if (bfgstsStatus == Bfgsts::BFGSTS_CONVERGED_TO_TS) {
 84:                 *isConverged = 1; 86:                 *isConverged = 1;
 85:                 *isColdFusion = 0; 
 86:         } 87:         }
 87:         else { 88:         else {
 88:                 *isConverged = 0; 89:                 *isConverged = 0;
 89:                 if (bfgstsStatus == Bfgsts::BFGSTS_COLD_FUSION_DIAGNOSED) { 90:                 if (bfgstsStatus == Bfgsts::BFGSTS_COLD_FUSION_DIAGNOSED) {
 90:                         *isColdFusion = 1; 91:                         *isColdFusion = 1;
 91:                 } 92:                 }
 92:         } 93:         }
 93:  94: 
 94:         CudaSafeCall( cudaMemcpy(evec,   d_evec,   numDimensions * sizeof(double), cudaMemcpyDeviceToHost) ); 95:         CudaSafeCall( cudaMemcpy(evec,   d_evec,   numDimensions * sizeof(double), cudaMemcpyDeviceToHost) );
 95:         CudaSafeCall( cudaMemcpy(coords, d_coords, numDimensions * sizeof(double), cudaMemcpyDeviceToHost) ); 96:         CudaSafeCall( cudaMemcpy(coords, d_coords, numDimensions * sizeof(double), cudaMemcpyDeviceToHost) );
101: 102: 
102:         if (timeCuda) {103:         if (timeCuda) {
103:                 timer_xLbfgsTotal.saveMeasurement();104:                 timer_xLbfgsTotal.saveMeasurement();
104:                 timer_pLbfgsTotal.saveMeasurement();105:                 timer_pLbfgsTotal.saveMeasurement();
105:                 timer_total.saveMeasurement();106:                 timer_total.saveMeasurement();
106:                 timer_eFolSteps.saveMeasurement();107:                 timer_eFolSteps.saveMeasurement();
107:         }108:         }
108: }109: }
109: 110: 
110: 111: 
111:  
112: extern "C" void setup_bfgsts(int *nAtoms, double *coords, double *xGradEps, _Bool *isConverged, double *energy, int *xMaxIter, 112: extern "C" void setup_bfgsts(int *nAtoms, double *coords, double *xGradEps, _Bool *isConverged, double *energy, int *xMaxIter, 
113:                 int *bItMax, int *bIter, double *xMaxStep, double *xMaxFkRise, double *outRms, char *cudaPotential, 113:                 int *bItMax, int *bIter, double *xMaxStep, double *xMaxFkRise, double *outRms, char *cudaPotential, 
114:                 _Bool *printDebug, _Bool *timeCuda, int *nPotCalls, _Bool *isColdFusion, double *coldFusionLim, double *xH0, 114:                 _Bool *printDebug, _Bool *timeCuda, int *nPotCalls, _Bool *isColdFusion, double *coldFusionLim, double *xH0, 
115:                 int *xUpdates, double *evalMin, double *evec, _Bool *isAtomisticNotRigid, int *nDegFreedomF, int *nRigidBodyF, 115:                 int *xUpdates, double *evalMin, double *evec, _Bool *isAtomisticNotRigid, int *nDegFreedomF, int *nRigidBodyF, 
116:                 int *nRigidSitesPerBodyF, int *rigidGroupsF, int *rigidMaxSiteF, double *sitesRigidBodyF, int *rigidSinglesF, 116:                 int *nRigidSitesPerBodyF, int *rigidGroupsF, int *rigidMaxSiteF, double *sitesRigidBodyF, int *rigidSinglesF, 
117:                 double *rigidInverseF, int *nSecDiag, double *evalPercentEps, double *pushOffCut, double *pushOffMag, 117:                 double *rigidInverseF, int *nSecDiag, double *evalPercentEps, double *pushOffCut, double *pushOffMag, 
118:                 double *maxEvecStep, double *maxMaxStep, double *minMaxStep, double *trustRadius, int *pMaxIter1, int *pMaxIter2, 118:                 double *maxEvecStep, double *maxMaxStep, double *minMaxStep, double *trustRadius, int *pMaxIter1, int *pMaxIter2, 
119:                 double *evecOverlapTol, int *pUpdates, double *gradEps, double *pMaxStep, double *pMaxFkRise, double *pH0, 119:                 double *evecOverlapTol, int *pUpdates, double *gradEps, double *pMaxStep, double *pMaxFkRise, double *pH0, 
120:                 double *evStepMagTol, _Bool *shouldFreeze, _Bool *isAtomFrozen, int *nFreeze, double *potTimeElapsed)120:                 double *evStepMagTol, _Bool *shouldFreeze, _Bool *isAtomFrozen, int *nFreeze)
121: {121: {
122:         const size_t numDimensions = 3*(*nAtoms);122:         const size_t numDimensions = 3*(*nAtoms);
123:         const double aaConvThreshold = 5*(*gradEps);123:         const double aaConvThreshold = 5*(*gradEps);
124: 124: 
125:         // Rigid body parameters may not be intialised in Fortran code if rigid body framework not being used. 125:         // Rigid body parameters may not be intialised in Fortran code if rigid body framework not being used. 
126:         int nDegFreedom  = 0;126:         int nDegFreedom  = 0;
127:         int nRigidBody   = 0;127:         int nRigidBody   = 0;
128:         int rigidMaxSite = 0;128:         int rigidMaxSite = 0;
129: 129: 
130:         int *nRigidSitesPerBody = NULL;130:         int *nRigidSitesPerBody = NULL;
145:                 rigidInverse       = rigidInverseF;145:                 rigidInverse       = rigidInverseF;
146:         }146:         }
147: 147: 
148:         // This is first opened in OPTIM fetchz to ensure file contents overwritten only at beginning of new run. 148:         // This is first opened in OPTIM fetchz to ensure file contents overwritten only at beginning of new run. 
149:         Printing debugPrinting("GPU_debug_out");149:         Printing debugPrinting("GPU_debug_out");
150:         if (*printDebug) {150:         if (*printDebug) {
151:                 debugPrinting.setPrintingOn();151:                 debugPrinting.setPrintingOn();
152:         }152:         }
153: 153: 
154:         Timer timer_potential     ("GPU_potential");154:         Timer timer_potential     ("GPU_potential");
155:         timer_potential.setTimingOn();155:         if (timeCuda) {
 156:                 timer_potential.setTimingOn();
 157:         }
156: 158: 
157:         // Set up cuBLAS. 159:         // Set up cuBLAS. 
158:         Cublas cublas;160:         Cublas cublas;
159: 161: 
160:         // L specifies the Lennard-Jones potential for up to 1024 atoms. 162:         // L specifies the Lennard-Jones potential for up to 1024 atoms. 
161:         if (*cudaPotential == 'L') {163:         if (*cudaPotential == 'L') {
162:                 const size_t atomMax = 1024;164:                 const size_t atomMax = 1024;
163:                 if (numDimensions > 3*atomMax) {165:                 if (numDimensions > 3*atomMax) {
164:                         std::cerr << "Lennard-Jones is currently only supported for a maximum of 1024 atoms. " << std::endl;166:                         std::cerr << "Lennard-Jones is currently only supported for a maximum of 1024 atoms. " << std::endl;
165:                         exit(EXIT_FAILURE);167:                         exit(EXIT_FAILURE);
190:         }192:         }
191:         else {193:         else {
192:                 std::cerr << "The specified potential has not been recognised. " << std::endl;194:                 std::cerr << "The specified potential has not been recognised. " << std::endl;
193:                 exit(EXIT_FAILURE);195:                 exit(EXIT_FAILURE);
194:         }196:         }
195: 197: 
196:         if (timeCuda) {198:         if (timeCuda) {
197:                 timer_potential.saveMeasurement();199:                 timer_potential.saveMeasurement();
198:         }200:         }
199: 201: 
200:         *potTimeElapsed = timer_potential.elapsed()/1000.0; 
201:  
202: }202: }
203: 203: 


r29015/setup_lbfgs.cu 2015-11-17 23:33:11.412657804 +0000 r29014/setup_lbfgs.cu 2015-11-17 23:33:16.984732532 +0000
 44:         CudaSafeCall( cudaMemcpy(d_x, x, numDimensions * sizeof(double), cudaMemcpyHostToDevice) ); 44:         CudaSafeCall( cudaMemcpy(d_x, x, numDimensions * sizeof(double), cudaMemcpyHostToDevice) );
 45:  45: 
 46:         // Perform the minimization.  46:         // Perform the minimization. 
 47:         lbfgsStatus = lbfgs.minimize(d_x, d_fk, d_gk, outRms, itDone); 47:         lbfgsStatus = lbfgs.minimize(d_x, d_fk, d_gk, outRms, itDone);
 48:  48: 
 49:         CudaSafeCall( cudaMemcpy(x, d_x, numDimensions * sizeof(double), cudaMemcpyDeviceToHost) ); 49:         CudaSafeCall( cudaMemcpy(x, d_x, numDimensions * sizeof(double), cudaMemcpyDeviceToHost) );
 50:         CudaSafeCall( cudaMemcpy(energy, d_fk, sizeof(double), cudaMemcpyDeviceToHost) ); 50:         CudaSafeCall( cudaMemcpy(energy, d_fk, sizeof(double), cudaMemcpyDeviceToHost) );
 51:  51: 
 52:         if (lbfgsStatus == Lbfgs::LBFGS_CONVERGED) { 52:         if (lbfgsStatus == Lbfgs::LBFGS_CONVERGED) {
 53:                 *isConverged = 1; 53:                 *isConverged = 1;
 54:                 *isColdFusion = 0; 
 55:         } 54:         }
 56:         else { 55:         else {
 57:                 *isConverged = 0; 56:                 *isConverged = 0;
 58:                 if (lbfgsStatus == Lbfgs::LBFGS_COLD_FUSION_DIAGNOSED) { 57:                 if (lbfgsStatus == Lbfgs::LBFGS_COLD_FUSION_DIAGNOSED) {
 59:                         *isColdFusion = 1; 58:                         *isColdFusion = 1;
 60:                 } 59:                 }
 61:         } 60:         }
 62:  61: 
 63:         CudaSafeCall( cudaFree(d_x) );         62:         CudaSafeCall( cudaFree(d_x) );        
 64:         CudaSafeCall( cudaFree(d_fk) ); 63:         CudaSafeCall( cudaFree(d_fk) );
 66:  65: 
 67:         *nPotCalls = potential.getnCalls(); 66:         *nPotCalls = potential.getnCalls();
 68:  67: 
 69:         if (timeCuda) { 68:         if (timeCuda) {
 70:                 timer_total.saveMeasurement(); 69:                 timer_total.saveMeasurement();
 71:                 timer_updates.saveMeasurement(); 70:                 timer_updates.saveMeasurement();
 72:                 timer_linesearch.saveMeasurement(); 71:                 timer_linesearch.saveMeasurement();
 73:         } 72:         }
 74: } 73: }
 75:  74: 
 76:  75: extern "C" void setup_lbfgs(int *n, double *x, double *gradEps, _Bool *isConverged, double *energy, int *maxIter, int *itDone, double *maxStep, double *maxFkRise, double *outRms, char *cudaPot, _Bool *printDebug, _Bool *timeCuda, int *nPotCalls, _Bool *isColdFusion, double *coldFusionLim, double *H0, int *updates, _Bool *isAtomisticNotRigid, int *nDegFreedomF, int *nRigidBodyF, int *nRigidSitesPerBodyF, int *rigidGroupsF, int *rigidMaxSiteF, double *sitesRigidBodyF, int *rigidSinglesF, double *aaConvThresholdF, double *rigidInverseF, _Bool *projectGrad, _Bool *shouldFreeze, _Bool *isAtomFrozen, int *nFreeze)
 77:  
 78: extern "C" void setup_lbfgs(int *n, double *x, double *gradEps, _Bool *isConverged, double *energy, int *maxIter, int *itDone,  
 79:                 double *maxStep, double *maxFkRise, double *outRms, char *cudaPot, _Bool *printDebug, _Bool *timeCuda,  
 80:                 int *nPotCalls, _Bool *isColdFusion, double *coldFusionLim, double *H0, int *updates,  
 81:                 _Bool *isAtomisticNotRigid, int *nDegFreedomF, int *nRigidBodyF, int *nRigidSitesPerBodyF,  
 82:                 int *rigidGroupsF, int *rigidMaxSiteF, double *sitesRigidBodyF, int *rigidSinglesF,  
 83:                 double *aaConvThresholdF, double *rigidInverseF, _Bool *projectGrad, _Bool *shouldFreeze,  
 84:                 _Bool *isAtomFrozen, int *nFreeze, double *potTimeElapsed) 
 85: { 76: {
 86:         const size_t numDimensions = *n; 77:         const size_t numDimensions = *n;
 87:  78: 
 88:         const int nSecDiag = 0; 79:         const int nSecDiag = 0;
 89:  80: 
 90:         const double aaConvThreshold = 5*(*aaConvThresholdF); 81:         const double aaConvThreshold = 5*(*aaConvThresholdF);
 91:  82: 
 92:         // Rigid body parameters may not be intialised if rigid body framework not being used. 83:         // Rigid body parameters may not be intialised if rigid body framework not being used.
 93:         int nDegFreedom  = 0; 84:         int nDegFreedom  = 0;
 94:         int nRigidBody   = 0; 85:         int nRigidBody   = 0;
114:                 rigidInverse       = rigidInverseF;105:                 rigidInverse       = rigidInverseF;
115:         }106:         }
116: 107: 
117:         // This is first opened in GMIN main to ensure file contents overwritten only at beginning of new run.108:         // This is first opened in GMIN main to ensure file contents overwritten only at beginning of new run.
118:         Printing debugPrinting("GPU_debug_out");109:         Printing debugPrinting("GPU_debug_out");
119:         if (*printDebug) {110:         if (*printDebug) {
120:                 debugPrinting.setPrintingOn();111:                 debugPrinting.setPrintingOn();
121:         }112:         }
122: 113: 
123:         Timer timer_potential     ("GPU_potential");114:         Timer timer_potential     ("GPU_potential");
124:         timer_potential.setTimingOn();115:         if (timeCuda) {
 116:                 timer_potential.setTimingOn();
 117:         }
125: 118: 
126:         // Set up cuBLAS. 119:         // Set up cuBLAS. 
127:         Cublas cublas;120:         Cublas cublas;
128: 121: 
129:         // L specifies the Lennard-Jones potential for up to 1024 atoms.122:         // L specifies the Lennard-Jones potential for up to 1024 atoms.
130:         if (*cudaPot == 'L') {123:         if (*cudaPot == 'L') {
131:                 const size_t atom_max = 1024;124:                 const size_t atom_max = 1024;
132:                 if (numDimensions > 3*atom_max) {125:                 if (numDimensions > 3*atom_max) {
133:                         std::cerr << "Lennard-Jones is currently only supported for a maximum of 1024 atoms. " << std::endl;126:                         std::cerr << "Lennard-Jones is currently only supported for a maximum of 1024 atoms. " << std::endl;
134:                         exit(EXIT_FAILURE);127:                         exit(EXIT_FAILURE);
144:                 setup<AmberPotential>(debugPrinting, cublas, numDimensions, x, gradEps, isConverged, energy, maxIter, itDone, maxStep, maxFkRise, outRms, potential, printDebug, timeCuda, nPotCalls, H0, updates, isColdFusion, projectGrad); 137:                 setup<AmberPotential>(debugPrinting, cublas, numDimensions, x, gradEps, isConverged, energy, maxIter, itDone, maxStep, maxFkRise, outRms, potential, printDebug, timeCuda, nPotCalls, H0, updates, isColdFusion, projectGrad); 
145:         }138:         }
146:         else {139:         else {
147:                 std::cerr << "The specified potential has not been recognised" << std::endl;140:                 std::cerr << "The specified potential has not been recognised" << std::endl;
148:                 exit(EXIT_FAILURE);141:                 exit(EXIT_FAILURE);
149:         }142:         }
150: 143: 
151:         if (timeCuda) {144:         if (timeCuda) {
152:                 timer_potential.saveMeasurement();145:                 timer_potential.saveMeasurement();
153:         }146:         }
154:  
155:         *potTimeElapsed = timer_potential.elapsed()/1000.0; 
156: }147: }


legend
Lines Added 
Lines changed
 Lines Removed

hdiff - version: 2.1.0