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

并行计算

开发平台:

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 <algorithm>
  19. #include "CudaGridMap.h"
  20. #include "../Exceptions.h"
  21. CudaGridMap::CudaGridMap(const Vec3i &numGridPoints, const Vec3i &numGridPointsPadded, const double *inputEnergies, cudaStream_t stream)
  22.     : stream(stream), numGridPoints(numGridPoints), numGridPointsPadded(numGridPointsPadded)
  23. {
  24.     // Allocate the padded grid in global memory
  25.     CUDA_SAFE_CALL(cudaMalloc((void**)&energiesDevice, sizeof(float) * numGridPointsPadded.Cube()));
  26.     // Convert doubles to floats and save them in page-locked memory
  27.     int numGridPointsPerMap = numGridPoints.Cube();
  28.     CUDA_SAFE_CALL(cudaMallocHost((void**)&energiesHost, sizeof(float) * numGridPointsPerMap));
  29.     std::transform(inputEnergies, inputEnergies + numGridPointsPerMap, energiesHost, typecast<float, double>);
  30.     // Copy the initial energies from the original grid to the padded one in global memory
  31.     // Elements in the area of padding will stay uninitialized
  32.     copyGridMapPadded(energiesDevice, numGridPointsPadded, energiesHost, numGridPoints, cudaMemcpyHostToDevice);
  33. }
  34. CudaGridMap::~CudaGridMap()
  35. {
  36.     CUDA_SAFE_CALL(cudaFree(energiesDevice));
  37.     CUDA_SAFE_CALL(cudaFreeHost(energiesHost));
  38. }
  39. void CudaGridMap::copyFromDeviceToHost()
  40. {
  41.     copyGridMapPadded(energiesHost, numGridPoints, energiesDevice, numGridPointsPadded, cudaMemcpyDeviceToHost);
  42. }
  43. void CudaGridMap::readFromHost(double *outputEnergies)
  44. {
  45.     std::transform(energiesHost, energiesHost + numGridPoints.Cube(), outputEnergies, typecast<double, float>);
  46. }
  47. void CudaGridMap::copyGridMapPadded(float *dst,       const Vec3i &numGridPointsDst,
  48.                                     const float *src, const Vec3i &numGridPointsSrc,
  49.                                     cudaMemcpyKind kind)
  50. {
  51.     Vec3i numGridPointsMin = Vec3i(Mathi::Min(numGridPointsDst.x, numGridPointsSrc.x),
  52.                                    Mathi::Min(numGridPointsDst.y, numGridPointsSrc.y),
  53.                                    Mathi::Min(numGridPointsDst.z, numGridPointsSrc.z));
  54.     int numGridPointsDstXMulY = numGridPointsDst.x * numGridPointsDst.y;
  55.     int numGridPointsSrcXMulY = numGridPointsSrc.x * numGridPointsSrc.y;
  56.     for (int z = 0; z < numGridPointsMin.z; z++)
  57.     {
  58.         // Set the base of output indices from z
  59.         int outputIndexZBaseDst = z * numGridPointsDstXMulY;
  60.         int outputIndexZBaseSrc = z * numGridPointsSrcXMulY;
  61.         for (int y = 0; y < numGridPointsMin.y; y++)
  62.         {
  63.             // Set the base of output indices from (z,y)
  64.             int outputIndexZYBaseDst = outputIndexZBaseDst + y * numGridPointsDst.x;
  65.             int outputIndexZYBaseSrc = outputIndexZBaseSrc + y * numGridPointsSrc.x;
  66.             // Copy one row in axis X
  67.             CUDA_SAFE_CALL(cudaMemcpyAsync(dst + outputIndexZYBaseDst, src + outputIndexZYBaseSrc, sizeof(float) * numGridPointsMin.x, kind, stream));
  68.         }
  69.     }
  70. }