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

并行计算

开发平台:

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 <cstdio>
  19. #include <cstdlib>
  20. #include <cstring>
  21. #include "ProgramParameters.h"
  22. #include "Utils.h"
  23. #include "Exceptions.h"
  24. #if !defined(_WIN32)
  25.     #include "UnixSignals.h"
  26.     #include <sys/wait.h>
  27. #endif
  28. #define ST_ENABLED "enabled"
  29. #define ST_DISABLED "disabled (related options ignored)"
  30. #if defined(AG_OPENMP)
  31.     #define OMP_STATUS ST_ENABLED
  32. #else
  33.     #define OMP_STATUS ST_DISABLED
  34.     #define omp_set_num_threads(n) (n)
  35. #endif
  36. #if defined(AG_CUDA)
  37.     #include "electrostatics/cuda_internal/Interface.h"
  38.     #define CUDA_STATUS ST_ENABLED
  39. #else
  40.     #define CUDA_STATUS ST_DISABLED
  41. #endif
  42. ProgramParameters::ProgramParameters(int argc, char **argv): debug(0), deviceID(0), cutoffGridMem(512), benchmark(false), nns(true),
  43.     cutoffGrid(true), cuda(true), cudaThread(true), calcSlicesSeparately(false), v4(false), cudaUnroll(Unassigned),
  44.     cudaDDDKind(Diel_Unassigned)
  45. {
  46.     programName[0] = 0;
  47.     gridParameterFilename[0] = 0;
  48.     logFilename[0] = 0;
  49.     parse(argc, argv);
  50. }
  51. void ProgramParameters::parse(int argc, char **argv)
  52. {
  53.     strncpy(programName, argv[0], MAX_CHARS);
  54.     // Loop over arguments
  55.     while (argc > 1)
  56.     {
  57.         if (0);
  58.         // Stream control:
  59.         else if (cmp2(argv[1], "-l", "--log"))    readParamString(&argc, &argv, logFilename);
  60.         else if (cmp2(argv[1], "-p", "--gpf"))    readParamString(&argc, &argv, gridParameterFilename);
  61.         // Miscellaneous:
  62.         else if (cmp(argv[1], "--benchmark"))     benchmark = true;
  63.         else if (cmp(argv[1], "--cogrid-mem"))    cutoffGridMem = readParamInt(&argc, &argv);
  64.         else if (cmp(argv[1], "--cuda-enum"))     cudaEnumDevicesAndExit();
  65.         else if (cmp(argv[1], "--cuda-dev"))      deviceID = readParamInt(&argc, &argv);
  66.         else if (cmp2(argv[1], "-d", "--debug"))  ++debug;
  67.         else if (cmp2(argv[1], "-u", "--help"))   printHelpAndExit();
  68.         else if (cmp(argv[1], "--no-cuda"))       cuda = false;
  69.         else if (cmp(argv[1], "--omp"))           omp_set_num_threads(readParamInt(&argc, &argv));
  70.         else if (cmp(argv[1], "--timeout"))       setTimeout(readParamInt(&argc, &argv));
  71.         else if (cmp(argv[1], "--v4"))            v4 = true;
  72.         // Advanced:
  73.         else if (cmp(argv[1], "--cuda-ddd=g"))    cudaDDDKind = DistanceDependentDiel_GlobalMem;
  74.         else if (cmp(argv[1], "--cuda-ddd=c"))    cudaDDDKind = DistanceDependentDiel_ConstMem;
  75.         else if (cmp(argv[1], "--cuda-ddd=t"))    cudaDDDKind = DistanceDependentDiel_TextureMem;
  76.         else if (cmp(argv[1], "--cuda-ddd=i"))    cudaDDDKind = DistanceDependentDiel_InPlace;
  77.         else if (cmp(argv[1], "--cuda-unroll=y")) cudaUnroll = True;
  78.         else if (cmp(argv[1], "--cuda-unroll=n")) cudaUnroll = False;
  79.         else if (cmp(argv[1], "--cuda-thread=y")) cudaThread = true;
  80.         else if (cmp(argv[1], "--cuda-thread=n")) cudaThread = false;
  81.         else if (cmp(argv[1], "--cuda-slices=y")) calcSlicesSeparately = true;
  82.         else if (cmp(argv[1], "--cuda-slices=n")) calcSlicesSeparately = false;
  83.         else if (cmp(argv[1], "--no-cogrid"))     cutoffGrid = false;
  84.         else if (cmp(argv[1], "--no-nns"))        nns = false;
  85.         // Error:
  86.         else
  87.         {
  88.             fprintf(stderr, "%s: unknown switch '%s'n", programName, argv[1]);
  89.             throw ExitProgram(1);
  90.         }
  91.         --argc;
  92.         ++argv;
  93.     }
  94. }
  95. void ProgramParameters::cudaEnumDevicesAndExit()
  96. {
  97. #if defined(AG_CUDA)
  98.     // Get a device count
  99.     int deviceCount;
  100.     CUDA_SAFE_CALL(cudaGetDeviceCount(&deviceCount));
  101.     // Print a list of devices
  102.     cudaDeviceProp prop;
  103.     fprintf(stderr, "Found %i CUDA devices:nn"
  104.                     " # | Name                           | MPs | Cap | GlobalMem | ConstMemn"
  105.                     "-----------------------------------------------------------------------n", deviceCount);
  106.     for (int i = 0; i < deviceCount; i++)
  107.     {
  108.         memset(&prop, 0, sizeof(prop));
  109.         CUDA_SAFE_CALL(cudaGetDeviceProperties(&prop, i));
  110.         fprintf(stderr, "%2i | %-31s|%4i |%2i.%-2i|%6lu MiB |%5lu KiBn", i,
  111.                         prop.name, prop.multiProcessorCount, prop.major, prop.minor,
  112.                         prop.totalGlobalMem >> 20, prop.totalConstMem >> 10);
  113.     }
  114. #endif
  115.     throw ExitProgram(0);
  116. }
  117. void ProgramParameters::readParamString(int *argc, char ***argv, char *out)
  118. {
  119.     strncpy(out, (*argv)[2], MAX_CHARS);
  120.     ++*argv;
  121.     --*argc;
  122. }
  123. int ProgramParameters::readParamInt(int *argc, char ***argv)
  124. {
  125.     int n;
  126.     if (sscanf((*argv)[2], "%i", &n) != 1)
  127.     {
  128.         fprintf(stderr, "%s: '%s' is not a numbern", programName, (*argv)[2]);
  129.         throw ExitProgram(1);
  130.     }
  131.     ++*argv;
  132.     --*argc;
  133.     return n;
  134. }
  135. void ProgramParameters::printHelpAndExit()
  136. {
  137.     fprintf(stderr, "Usage: %s [OPTIONS]n"
  138.                     "n"
  139.                     "Stream control:n"
  140.                     "  -l, --log FILE    log to FILE, default: standard outputn"
  141.                     "  -p, --gpf FILE    read grid parameters from FILE, default: standard inputn"
  142.                     "n"
  143.                     "Miscellaneous:n"
  144.                     "      --benchmark   print execution times to standard error outputn"
  145.                     "      --cogrid-mem N  reserve at most N megabytes of memory for the cutoff grid,n"
  146.                     "                      default: 512n"
  147.                     "      --cuda-enum   enumerate all CUDA devices and exitn"
  148.                     "      --cuda-dev N  use a CUDA device number N, default: 0n"
  149.                     "  -d, --debug       increment debug leveln"
  150.                     "  -u, --help        display this help and exitn"
  151.                     "      --no-cuda     disable CUDA, use the CPU codepath insteadn"
  152.                     "      --omp N       set OpenMP to use N threads at mostn"
  153.                     "      --timeout N   terminate if calculations does not finish in N secondsn"
  154.                     "                    (POSIX only), this must be the first parameter if usedn"
  155.                     "      --v4          set the AutoGrid 4.0 default parameter libraryn"
  156.                     "n"
  157.                     "Advanced:n"
  158.                     "      --cuda-ddd=g|c|t|i  set a way of calculating distance-dependent dielectricn"
  159.                     "                          to one of the following: g=global memory, c=constantn"
  160.                     "                          memory, t=texture memory, i=in-placen"
  161.                     "                          default: either t or i based on grid dimensionsn"
  162.                     "      --cuda-slices=y|n  calculate gridmap slices separately i.e. only onen"
  163.                     "                         gridmap slice per CUDA kernel call, default: nn"
  164.                     "      --cuda-thread=y|n  use a separate thread for CUDA, default: yn"
  165.                     "      --cuda-unroll=y|n  increase performance for large gridmaps,n"
  166.                     "                         default: based on grid dimensionsn"
  167.                     "      --no-cogrid   disable the cutoff-grid optimizationn"
  168.                     "      --no-nns      disable the nearest-neighbor-search optimizationn"
  169.                     "n"
  170.                     "Compiled with OpenMP " OMP_STATUS ".n"
  171.                     "Compiled with CUDA " CUDA_STATUS ".n"
  172.                     "n", programName);
  173.     throw ExitProgram(0);
  174. }
  175. void ProgramParameters::setTimeout(int seconds)
  176. {
  177. #if !defined(_WIN32)
  178.     pid_t pid = fork();
  179.     if (pid)
  180.     {
  181.         int status;
  182.         alarm(seconds);
  183.         UNIX_SIGNAL_TRY(SIGALRM)
  184.         {
  185.             waitpid(pid, &status, 0);
  186.         }
  187.         UNIX_SIGNAL_CATCH()
  188.         {
  189.             kill(pid, SIGKILL);
  190.             fprintf(stderr, "Timeout! Process terminated.n");
  191.         }
  192.         UNIX_SIGNAL_END()
  193.         throw ExitProgram(0);
  194.     }
  195. #endif
  196. }
  197. bool ProgramParameters::cmp(const char *s1, const char *s2)
  198. {
  199.     return strcmp(s1, s2) == 0;
  200. }
  201. bool ProgramParameters::cmp2(const char *s1, const char *s2, const char *s3)
  202. {
  203.     return cmp(s1, s2) || cmp(s1, s3);
  204. }