Cpu.cpp
上传用户:chinafayin
上传日期:2022-04-05
资源大小:153k
文件大小:5k
源码类别:

并行计算

开发平台:

Visual C++

  1. /*
  2.     FastGrid (formerly AutoGrid)
  3.     Copyright (C) 2009 The Scripps Research Institute. All rights reserved.
  4.     Copyright (C) 2009 Masaryk University. All rights reserved.
  5.     AutoGrid is a Trade Mark of The Scripps Research Institute.
  6.     This program is free software; you can redistribute it and/or
  7.     modify it under the terms of the GNU General Public License
  8.     as published by the Free Software Foundation; either version 2
  9.     of the License, or (at your option) any later version.
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.     You should have received a copy of the GNU General Public License
  15.     along with this program; if not, write to the Free Software
  16.     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  17. */
  18. #include "Electrostatics.h"
  19. #include "../Utils.h"
  20. template<int DistanceDependentDielectric>
  21. static void calculateElectrostaticMapGeneric(const InputData *input, GridMap &elecMap)
  22. {
  23.     #if defined(AG_OPENMP)
  24.         #pragma omp parallel for schedule(dynamic, 1)
  25.     #endif
  26.     // Z axis
  27.     for (int z = 0; z < input->numGridPoints.z; z++)
  28.     {
  29.         // gridPos contains the current grid point
  30.         Vec3d gridPos;
  31.         gridPos.z = (z - input->numGridPointsDiv2.z) * input->gridSpacing;
  32.         int outputOffsetZBase = z * input->numGridPoints.x*input->numGridPoints.y;
  33.         // Precalculate dz^2
  34.         double *dzSq = new double[input->numReceptorAtoms*2];
  35.         for (int ia = 0; ia < input->numReceptorAtoms; ia++)
  36.             dzSq[ia] = Mathd::Sqr(input->receptorAtom[ia].z - gridPos.z);
  37.         double *dydzSq = dzSq + input->numReceptorAtoms;
  38.         // Y axis
  39.         for (int y = 0; y < input->numGridPoints.y; y++)
  40.         {
  41.             gridPos.y = (y - input->numGridPointsDiv2.y) * input->gridSpacing;
  42.             int outputOffsetZYBase = outputOffsetZBase + y * input->numGridPoints.x;
  43.             // Precalculate dy^2 + dz^2
  44.             for (int ia = 0; ia < input->numReceptorAtoms; ia++)
  45.                 dydzSq[ia] = Mathd::Sqr(input->receptorAtom[ia].y - gridPos.y) + dzSq[ia];
  46.             // X axis
  47.             for (int x = 0; x < input->numGridPoints.x; x++)
  48.             {
  49.                 gridPos.x = (x - input->numGridPointsDiv2.x) * input->gridSpacing;
  50.                 int outputIndex = outputOffsetZYBase + x;
  51.                 double energy = elecMap.energies[outputIndex];
  52.                 //  Do all Receptor (protein, DNA, etc.) atoms...
  53.                 for (int ia = 0; ia < input->numReceptorAtoms; ia++)
  54.                 {
  55.                     // Get reciprocal of the distance from current grid point to this receptor atom (1 / |receptorAtom - gridPos|)
  56.                     double r = sqrt(Mathd::Sqr(input->receptorAtom[ia].x - gridPos.x) + dydzSq[ia]);
  57.                     double invR = 1 / r;
  58.                     if (DistanceDependentDielectric)
  59.                         // The estat forcefield coefficient/weight is premultiplied
  60.                         energy += input->receptorAtom[ia].w * Mathd::Min(invR, 2) * input->epsilon[angstromToIndex<int>(r)];
  61.                     else
  62.                         // Both the constant dielectric and the estat forcefield coefficient/weight are premultiplied
  63.                         energy += input->receptorAtom[ia].w * Mathd::Min(invR, 2);
  64.                 }
  65.                 // Round to 3 decimal places
  66.                 elecMap.energies[outputIndex] = roundOutput(energy);
  67.             }
  68.         }
  69.         delete [] dzSq;
  70.     }
  71. }
  72. void calculateElectrostaticMapCPU(const InputData *input, const ProgramParameters &programParams, GridMapList &gridmaps)
  73. {
  74.     Timer *t2 = 0;
  75.     if (programParams.benchmarkEnabled())
  76.         t2 = Timer::startNew("Electrostatic map      ");
  77.     if (input->distDepDiel)
  78.         calculateElectrostaticMapGeneric<1>(input, gridmaps.getElectrostaticMap());
  79.     else
  80.         calculateElectrostaticMapGeneric<0>(input, gridmaps.getElectrostaticMap());
  81.     if (programParams.benchmarkEnabled())
  82.     {
  83.         t2->stopAndLog(stderr, false);
  84.         double seconds = t2->getReal() / double(getClocksPerSec());
  85.         double atoms = input->numReceptorAtoms * double(input->numGridPointsPerMap);
  86.         double atomsPerSec = atoms / seconds;
  87.         fprintf(stderr, "Electrostatics performance: %i million atoms/sn", int(atomsPerSec / 1000000));
  88.     }
  89.     gridmaps.saveElectrostaticMap();
  90. }
  91. #if !defined(AG_CUDA)
  92. void *calculateElectrostaticMapAsync(const InputData *input, const ProgramParameters &programParams, GridMapList &gridmaps)
  93. {
  94.     calculateElectrostaticMapCPU(input, programParams, gridmaps);
  95.     return 0;
  96. }
  97. void synchronizeCalculation(void *)
  98. {
  99.     // no-op
  100. }
  101. #endif