Ejemplo n.º 1
0
void write_espresso_conf_indexed(FILE *out, const char *title,
                                 t_atoms *atoms, int nx, int *index,
                                 rvec *x, rvec *v, matrix box)
{
    int i, j;

    fprintf(out, "# %s\n", title);
    if (TRICLINIC(box))
    {
        gmx_warning("The Espresso format does not support triclinic unit-cells");
    }
    fprintf(out, "{variable {box_l %f %f %f}}\n", box[0][0], box[1][1], box[2][2]);

    fprintf(out, "{particles {id pos type q%s}\n", v ? " v" : "");
    for (i = 0; i < nx; i++)
    {
        if (index)
        {
            j = index[i];
        }
        else
        {
            j = i;
        }
        fprintf(out, "\t{%d %f %f %f %u %g",
                j, x[j][XX], x[j][YY], x[j][ZZ],
                atoms->atom[j].type, atoms->atom[j].q);
        if (v)
        {
            fprintf(out, " %f %f %f", v[j][XX], v[j][YY], v[j][ZZ]);
        }
        fprintf(out, "}\n");
    }
    fprintf(out, "}\n");
}
Ejemplo n.º 2
0
int get_strings(const char *db,char ***strings)
{
  FILE *in;
  char **ptr;
  char buf[256];
  int  i,nstr;

  in=libopen(db);
  
  if (fscanf(in,"%d",&nstr) != 1) {
    gmx_warning("File %s is empty",db);
    ffclose(in);
    return 0;
  }
  snew(ptr,nstr);
  for(i=0; (i<nstr); i++) {
    if(1 != fscanf(in,"%s",buf))
    { 
      gmx_fatal(FARGS,"Cannot read string from buffer");
    }
#ifdef DEBUG
    fprintf(stderr,"Have read: %s\n",buf);
#endif
    ptr[i] = strdup(buf);
  }
  ffclose(in);

  *strings=ptr;
  
  return nstr;
}
Ejemplo n.º 3
0
int fget_lines(FILE *in,char ***strings)
{
  char **ptr;
  char buf[256];
  int  i,nstr;
  char *pret;

  pret = fgets(buf,255,in);  
  if ( pret==NULL  || sscanf(buf,"%d",&nstr) != 1) 
  {
    gmx_warning("File is empty");
    ffclose(in);
    
    return 0;
  }
  snew(ptr,nstr);
  for(i=0; (i<nstr); i++) {
    fgets2(buf,255,in);
    ptr[i] = gmx_strdup(buf);
  }
  
  (*strings) = ptr;
  
  return nstr;
}
Ejemplo n.º 4
0
static void enx_warning(const char *msg)
{
    if (getenv("GMX_ENX_NO_FATAL") != NULL)
    {
        gmx_warning(msg);
    }
    else
    {
        gmx_fatal(FARGS,"%s\n%s",
                  msg,
                  "If you want to use the correct frames before the corrupted frame and avoid this fatal error set the env.var. GMX_ENX_NO_FATAL");
    }
}
Ejemplo n.º 5
0
static void
nb_listed_warning_rlimit(const rvec *x, int ai, int aj, int * global_atom_index, real r, real rlimit)
{
    gmx_warning("Listed nonbonded interaction between particles %d and %d\n"
                "at distance %.3f which is larger than the table limit %.3f nm.\n\n"
                "This is likely either a 1,4 interaction, or a listed interaction inside\n"
                "a smaller molecule you are decoupling during a free energy calculation.\n"
                "Since interactions at distances beyond the table cannot be computed,\n"
                "they are skipped until they are inside the table limit again. You will\n"
                "only see this message once, even if it occurs for several interactions.\n\n"
                "IMPORTANT: This should not happen in a stable simulation, so there is\n"
                "probably something wrong with your system. Only change the table-extension\n"
                "distance in the mdp file if you are really sure that is the reason.\n",
                glatnr(global_atom_index, ai), glatnr(global_atom_index, aj), r, rlimit);

    if (debug)
    {
        fprintf(debug,
                "%8f %8f %8f\n%8f %8f %8f\n1-4 (%d,%d) interaction not within cut-off! r=%g. Ignored\n",
                x[ai][XX], x[ai][YY], x[ai][ZZ], x[aj][XX], x[aj][YY], x[aj][ZZ],
                glatnr(global_atom_index, ai), glatnr(global_atom_index, aj), r);
    }
}
Ejemplo n.º 6
0
static void atom_not_found(int fatal_errno, const char *file, int line,
                           const char *atomname, int resind,
                           const char *resname,
                           const char *bondtype, bool bAllowMissing)
{
    char message_buffer[BUFSIZE];
    if (strcmp(bondtype, "check") != 0)
    {
        if (0 != strcmp(bondtype, "atom"))
        {
            snprintf(message_buffer, 1024,
                     "Residue %d named %s of a molecule in the input file was mapped\n"
                     "to an entry in the topology database, but the atom %s used in\n"
                     "an interaction of type %s in that entry is not found in the\n"
                     "input file. Perhaps your atom and/or residue naming needs to be\n"
                     "fixed.\n",
                     resind+1, resname, atomname, bondtype);
        }
        else
        {
            snprintf(message_buffer, 1024,
                     "Residue %d named %s of a molecule in the input file was mapped\n"
                     "to an entry in the topology database, but the atom %s used in\n"
                     "that entry is not found in the input file. Perhaps your atom\n"
                     "and/or residue naming needs to be fixed.\n",
                     resind+1, resname, atomname);
        }
        if (bAllowMissing)
        {
            gmx_warning("WARNING: %s", message_buffer);
        }
        else
        {
            gmx_fatal(fatal_errno, file, line, "%s", message_buffer);
        }
    }
}
Ejemplo n.º 7
0
/*!
 * Thread affinity set by the OpenMP library can conflict with the GROMACS
 * internal affinity setting.
 *
 * While GNU OpenMP does not set affinity by default, the Intel OpenMP library
 * does. This conflicts with the internal affinity (especially thread-MPI)
 * setting, results in incorrectly locked threads, and causes dreadful performance.
 *
 * The KMP_AFFINITY environment variable is used by Intel, GOMP_CPU_AFFINITY
 * by the GNU compilers (Intel also honors it well). If any of the variables
 * is set, we honor it, disable the internal pinning, and warn the user.
 * When using Intel OpenMP, we will disable affinity if the user did not set it
 * anually through one of the aforementioned environment variables.
 *
 * Note that the Intel OpenMP affinity disabling iwll only take effect if this
 * function is called before the OpenMP library gets initialized which happens
 * when the first call is made into a compilation unit that contains OpenMP
 * pragmas.
 */
void gmx_omp_check_thread_affinity(FILE *fplog, const t_commrec *cr,
                                   gmx_hw_opt_t *hw_opt)
{
    gmx_bool bKmpAffinitySet, bGompCpuAffinitySet;
    char *kmp_env, *gomp_env;

    /* no need to worry if internal thread pinning is turned off */
    if (!hw_opt->bThreadPinning)
    {
        return;
    }

#if defined(GMX_OPENMP)

    /* We assume that the affinity setting is available on all platforms
     * gcc supports. Even if this is not the case (e.g. Mac OS) the user
     * will only get a warning.*/
    bGompCpuAffinitySet = FALSE;
    gomp_env = NULL;
#if defined(__GNUC__)
    gomp_env = getenv("GOMP_CPU_AFFINITY");
    bGompCpuAffinitySet = (gomp_env != NULL);
#endif /* __GNUC__ */

    bKmpAffinitySet = FALSE;
#if defined(__INTEL_COMPILER)
    kmp_env = getenv("KMP_AFFINITY");
    bKmpAffinitySet = (kmp_env != NULL);

    /* disable Intel OpenMP affinity if neither KMP_AFFINITY nor
     * GOMP_CPU_AFFINITY is set (Intel uses the GNU env. var as well) */
    if (!bKmpAffinitySet && !bGompCpuAffinitySet)
    {
        int retval;

#ifdef _MSC_VER
        /* Windows not POSIX */
        retval = _putenv_s("KMP_AFFINITY", "disabled");
#else
        /* POSIX */
        retval = setenv("KMP_AFFINITY", "disabled", 0);
#endif /* _MSC_VER */

        if (debug)
        {
            fprintf(debug, "Disabling Intel OpenMP affinity by setting the KMP_AFFINITY=disabled env. var.\n");
        }

        if (retval != 0)
        {
            gmx_warning("Disabling Intel OpenMp affinity setting failed!");
        }
    }

    /* turn off internal pinning KMP_AFFINITY != "disabled" */
    if (bKmpAffinitySet && (gmx_strncasecmp(kmp_env, "disabled", 8) != 0))
    {
        md_print_warn(cr, fplog, "WARNING: KMP_AFFINITY set, will turn off %s internal affinity\n"
                      "         setting as the two can conflict and cause performance degradation.\n"
                      "         To keep using the %s internal affinity setting, set the\n"
                      "         KMP_AFFINITY=disabled environment variable.",
                      ShortProgram(), ShortProgram());

        hw_opt->bThreadPinning = FALSE;
    }
#endif /* __INTEL_COMPILER */

#if defined(__INTEL_COMPILER) || defined(__GNUC__)
    /* turn off internal pinning f GOMP_CPU_AFFINITY is set & non-empty */
    if (bGompCpuAffinitySet && gomp_env != NULL && gomp_env != '\0')
    {
        md_print_warn(cr, fplog,
                      "WARNING: GOMP_CPU_AFFINITY set, will turn off %s internal affinity\n"
                      "         setting as the two can conflict and cause performance degradation.\n"
                      "         To keep using the %s internal affinity setting, unset the\n"
                      "         GOMP_CPU_AFFINITY environment variable.",
                      ShortProgram(), ShortProgram());

        hw_opt->bThreadPinning = FALSE;
    }
#endif /* __INTEL_COMPILER || __GNUC__ */

#endif /* GMX_OPENMP */
}
Ejemplo n.º 8
0
/* Try to increase nstlist when using the Verlet cut-off scheme */
static void increase_nstlist(FILE *fp, t_commrec *cr,
                             t_inputrec *ir, int nstlist_cmdline,
                             const gmx_mtop_t *mtop, matrix box,
                             gmx_bool bGPU)
{
    float                  listfac_ok, listfac_max;
    int                    nstlist_orig, nstlist_prev;
    verletbuf_list_setup_t ls;
    real                   rlistWithReferenceNstlist, rlist_inc, rlist_ok, rlist_max;
    real                   rlist_new, rlist_prev;
    size_t                 nstlist_ind = 0;
    t_state                state_tmp;
    gmx_bool               bBox, bDD, bCont;
    const char            *nstl_gpu = "\nFor optimal performance with a GPU nstlist (now %d) should be larger.\nThe optimum depends on your CPU and GPU resources.\nYou might want to try several nstlist values.\n";
    const char            *nve_err  = "Can not increase nstlist because an NVE ensemble is used";
    const char            *vbd_err  = "Can not increase nstlist because verlet-buffer-tolerance is not set or used";
    const char            *box_err  = "Can not increase nstlist because the box is too small";
    const char            *dd_err   = "Can not increase nstlist because of domain decomposition limitations";
    char                   buf[STRLEN];
    const float            oneThird = 1.0f / 3.0f;

    if (nstlist_cmdline <= 0)
    {
        if (ir->nstlist == 1)
        {
            /* The user probably set nstlist=1 for a reason,
             * don't mess with the settings.
             */
            return;
        }

        if (fp != NULL && bGPU && ir->nstlist < nstlist_try[0])
        {
            fprintf(fp, nstl_gpu, ir->nstlist);
        }
        nstlist_ind = 0;
        while (nstlist_ind < NNSTL && ir->nstlist >= nstlist_try[nstlist_ind])
        {
            nstlist_ind++;
        }
        if (nstlist_ind == NNSTL)
        {
            /* There are no larger nstlist value to try */
            return;
        }
    }

    if (EI_MD(ir->eI) && ir->etc == etcNO)
    {
        if (MASTER(cr))
        {
            fprintf(stderr, "%s\n", nve_err);
        }
        if (fp != NULL)
        {
            fprintf(fp, "%s\n", nve_err);
        }

        return;
    }

    if (ir->verletbuf_tol == 0 && bGPU)
    {
        gmx_fatal(FARGS, "You are using an old tpr file with a GPU, please generate a new tpr file with an up to date version of grompp");
    }

    if (ir->verletbuf_tol < 0)
    {
        if (MASTER(cr))
        {
            fprintf(stderr, "%s\n", vbd_err);
        }
        if (fp != NULL)
        {
            fprintf(fp, "%s\n", vbd_err);
        }

        return;
    }

    if (bGPU)
    {
        listfac_ok  = nbnxn_gpu_listfac_ok;
        listfac_max = nbnxn_gpu_listfac_max;
    }
    else
    {
        listfac_ok  = nbnxn_cpu_listfac_ok;
        listfac_max = nbnxn_cpu_listfac_max;
    }

    nstlist_orig = ir->nstlist;
    if (nstlist_cmdline > 0)
    {
        if (fp)
        {
            sprintf(buf, "Getting nstlist=%d from command line option",
                    nstlist_cmdline);
        }
        ir->nstlist = nstlist_cmdline;
    }

    verletbuf_get_list_setup(TRUE, bGPU, &ls);

    /* Allow rlist to make the list a given factor larger than the list
     * would be with the reference value for nstlist (10).
     */
    nstlist_prev = ir->nstlist;
    ir->nstlist  = nbnxnReferenceNstlist;
    calc_verlet_buffer_size(mtop, det(box), ir, -1, &ls, NULL,
                            &rlistWithReferenceNstlist);
    ir->nstlist  = nstlist_prev;

    /* Determine the pair list size increase due to zero interactions */
    rlist_inc = nbnxn_get_rlist_effective_inc(ls.cluster_size_j,
                                              mtop->natoms/det(box));
    rlist_ok  = (rlistWithReferenceNstlist + rlist_inc)*pow(listfac_ok, oneThird) - rlist_inc;
    rlist_max = (rlistWithReferenceNstlist + rlist_inc)*pow(listfac_max, oneThird) - rlist_inc;
    if (debug)
    {
        fprintf(debug, "nstlist tuning: rlist_inc %.3f rlist_ok %.3f rlist_max %.3f\n",
                rlist_inc, rlist_ok, rlist_max);
    }

    nstlist_prev = nstlist_orig;
    rlist_prev   = ir->rlist;
    do
    {
        if (nstlist_cmdline <= 0)
        {
            ir->nstlist = nstlist_try[nstlist_ind];
        }

        /* Set the pair-list buffer size in ir */
        calc_verlet_buffer_size(mtop, det(box), ir, -1, &ls, NULL, &rlist_new);

        /* Does rlist fit in the box? */
        bBox = (sqr(rlist_new) < max_cutoff2(ir->ePBC, box));
        bDD  = TRUE;
        if (bBox && DOMAINDECOMP(cr))
        {
            /* Check if rlist fits in the domain decomposition */
            if (inputrec2nboundeddim(ir) < DIM)
            {
                gmx_incons("Changing nstlist with domain decomposition and unbounded dimensions is not implemented yet");
            }
            copy_mat(box, state_tmp.box);
            bDD = change_dd_cutoff(cr, &state_tmp, ir, rlist_new);
        }

        if (debug)
        {
            fprintf(debug, "nstlist %d rlist %.3f bBox %d bDD %d\n",
                    ir->nstlist, rlist_new, bBox, bDD);
        }

        bCont = FALSE;

        if (nstlist_cmdline <= 0)
        {
            if (bBox && bDD && rlist_new <= rlist_max)
            {
                /* Increase nstlist */
                nstlist_prev = ir->nstlist;
                rlist_prev   = rlist_new;
                bCont        = (nstlist_ind+1 < NNSTL && rlist_new < rlist_ok);
            }
            else
            {
                /* Stick with the previous nstlist */
                ir->nstlist = nstlist_prev;
                rlist_new   = rlist_prev;
                bBox        = TRUE;
                bDD         = TRUE;
            }
        }

        nstlist_ind++;
    }
    while (bCont);

    if (!bBox || !bDD)
    {
        gmx_warning(!bBox ? box_err : dd_err);
        if (fp != NULL)
        {
            fprintf(fp, "\n%s\n", bBox ? box_err : dd_err);
        }
        ir->nstlist = nstlist_orig;
    }
    else if (ir->nstlist != nstlist_orig || rlist_new != ir->rlist)
    {
        sprintf(buf, "Changing nstlist from %d to %d, rlist from %g to %g",
                nstlist_orig, ir->nstlist,
                ir->rlist, rlist_new);
        if (MASTER(cr))
        {
            fprintf(stderr, "%s\n\n", buf);
        }
        if (fp != NULL)
        {
            fprintf(fp, "%s\n\n", buf);
        }
        ir->rlist     = rlist_new;
        ir->rlistlong = rlist_new;
    }
}
Ejemplo n.º 9
0
static void process_multiprot_output(const char *fn, real *rmsd, int *nres, rvec rotangles, 
				     rvec translation, bool bCountres, t_countres *countres)
{
    FILE       *mpoutput;
    char       line[256];
    char       *string;
    int        i=0,j=0,res;
    
    (*rmsd)=-1;
    (*nres)=0;
    mpoutput=gmx_ffopen (fn,"r");
    
    if (bCountres) {
	do {
	    fgets(line, 256, mpoutput);
	} while (strstr(line,"Match List") == NULL);
	fgets(line, 256, mpoutput);
	do {
	    string = strtok (line,".");
	    while (i<2 && string != NULL) {
		string = strtok (NULL,". ");
		i++;
	    }
	    i=0;
	    res=atoi(string);
	    if (res > 0) {
		while (countres[j].resnr!=res)
		    j++;
		countres[j].count++;
	    }
	    fgets(line, 256, mpoutput);
	} while (strstr(line,"End of Match List") == NULL);
	rewind(mpoutput);
    }
    do {
	fgets(line, 256, mpoutput);
    } while (strstr(line,"Trans : ") == NULL);
    
    string = strtok (line," :");
    string = strtok (NULL," ");
    while (i<3 && string != NULL) {
	string = strtok (NULL," ");
	rotangles[i]=atof(string);
	i++;
    }
    i=0;
    while (i<3 && string != NULL) {
	string = strtok (NULL," ");
	translation[i]=atof(string)/10;
	i++;
    }
    if (i!=3) {
	gmx_warning("Not enough values for rotation and translation vectors in the output of multiprot");
    }
    
    rotangles[YY]=rotangles[YY]*(-1); 
    
    while ((*rmsd) <0) {
	fgets(line, 256, mpoutput);
	if (strstr(line,"RMSD : ") != NULL) {
	    string = strtok (line,":");
	    string = strtok (NULL,":");
	    (*rmsd)=atof(string)/10;
	}
    }
    while (!(*nres)) {
	fgets(line,256, mpoutput);
	if (strstr(line,"Match List") != NULL) {
	    string = strtok (line,":");
	    string = strtok (NULL,":");
	    (*nres) = atoi(string);
	}
    }
    gmx_ffclose(mpoutput);
}
Ejemplo n.º 10
0
static gmx_bool get_w_conf(FILE *in, const char *infile, char *title,
                           t_symtab *symtab, t_atoms *atoms, int *ndec,
                           rvec x[], rvec *v, matrix box)
{
    char       name[6];
    char       line[STRLEN+1], *ptr;
    char       buf[256];
    double     x1, y1, z1, x2, y2, z2;
    rvec       xmin, xmax;
    int        natoms, i, m, resnr, newres, oldres, ddist, c;
    gmx_bool   bFirst, bVel;
    char      *p1, *p2, *p3;

    newres  = -1;
    oldres  = NOTSET; /* Unlikely number for the first residue! */
    ddist   = 0;

    /* Read the title and number of atoms */
    get_coordnum_fp(in, title, &natoms);

    if (natoms > atoms->nr)
    {
        gmx_fatal(FARGS, "gro file contains more atoms (%d) than expected (%d)",
                  natoms, atoms->nr);
    }
    else if (natoms <  atoms->nr)
    {
        fprintf(stderr, "Warning: gro file contains less atoms (%d) than expected"
                " (%d)\n", natoms, atoms->nr);
    }

    bFirst = TRUE;

    bVel = FALSE;

    /* just pray the arrays are big enough */
    for (i = 0; (i < natoms); i++)
    {
        if ((fgets2 (line, STRLEN, in)) == NULL)
        {
            gmx_fatal(FARGS, "Unexpected end of file in file %s at line %d",
                      infile, i+2);
        }
        if (strlen(line) < 39)
        {
            gmx_fatal(FARGS, "Invalid line in %s for atom %d:\n%s", infile, i+1, line);
        }

        /* determine read precision from distance between periods
           (decimal points) */
        if (bFirst)
        {
            bFirst = FALSE;
            p1     = strchr(line, '.');
            if (p1 == NULL)
            {
                gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
            }
            p2 = strchr(&p1[1], '.');
            if (p2 == NULL)
            {
                gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
            }
            ddist = p2 - p1;
            *ndec = ddist - 5;

            p3 = strchr(&p2[1], '.');
            if (p3 == NULL)
            {
                gmx_fatal(FARGS, "A coordinate in file %s does not contain a '.'", infile);
            }

            if (p3 - p2 != ddist)
            {
                gmx_fatal(FARGS, "The spacing of the decimal points in file %s is not consistent for x, y and z", infile);
            }
        }

        /* residue number*/
        memcpy(name, line, 5);
        name[5] = '\0';
        sscanf(name, "%d", &resnr);
        memcpy(name, line+5, 5);
        name[5] = '\0';
        if (resnr != oldres)
        {
            oldres = resnr;
            newres++;
            if (newres >= natoms)
            {
                gmx_fatal(FARGS, "More residues than atoms in %s (natoms = %d)",
                          infile, natoms);
            }
            atoms->atom[i].resind = newres;
            t_atoms_set_resinfo(atoms, i, symtab, name, resnr, ' ', 0, ' ');
        }
        else
        {
            atoms->atom[i].resind = newres;
        }

        /* atomname */
        memcpy(name, line+10, 5);
        atoms->atomname[i] = put_symtab(symtab, name);

        /* eventueel controle atomnumber met i+1 */

        /* coordinates (start after residue data) */
        ptr = line + 20;
        /* Read fixed format */
        for (m = 0; m < DIM; m++)
        {
            for (c = 0; (c < ddist && ptr[0]); c++)
            {
                buf[c] = ptr[0];
                ptr++;
            }
            buf[c] = '\0';
            if (sscanf (buf, "%lf %lf", &x1, &x2) != 1)
            {
                gmx_fatal(FARGS, "Something is wrong in the coordinate formatting of file %s. Note that gro is fixed format (see the manual)", infile);
            }
            else
            {
                x[i][m] = x1;
            }
        }

        /* velocities (start after residues and coordinates) */
        if (v)
        {
            /* Read fixed format */
            for (m = 0; m < DIM; m++)
            {
                for (c = 0; (c < ddist && ptr[0]); c++)
                {
                    buf[c] = ptr[0];
                    ptr++;
                }
                buf[c] = '\0';
                if (sscanf (buf, "%lf", &x1) != 1)
                {
                    v[i][m] = 0;
                }
                else
                {
                    v[i][m] = x1;
                    bVel    = TRUE;
                }
            }
        }
    }
    atoms->nres = newres + 1;

    /* box */
    fgets2 (line, STRLEN, in);
    if (sscanf (line, "%lf%lf%lf", &x1, &y1, &z1) != 3)
    {
        gmx_warning("Bad box in file %s", infile);

        /* Generate a cubic box */
        for (m = 0; (m < DIM); m++)
        {
            xmin[m] = xmax[m] = x[0][m];
        }
        for (i = 1; (i < atoms->nr); i++)
        {
            for (m = 0; (m < DIM); m++)
            {
                xmin[m] = min(xmin[m], x[i][m]);
                xmax[m] = max(xmax[m], x[i][m]);
            }
        }
        for (i = 0; i < DIM; i++)
        {
            for (m = 0; m < DIM; m++)
            {
                box[i][m] = 0.0;
            }
        }
        for (m = 0; (m < DIM); m++)
        {
            box[m][m] = (xmax[m]-xmin[m]);
        }
        fprintf(stderr, "Generated a cubic box %8.3f x %8.3f x %8.3f\n",
                box[XX][XX], box[YY][YY], box[ZZ][ZZ]);
    }
    else
    {
        /* We found the first three values, the diagonal elements */
        box[XX][XX] = x1;
        box[YY][YY] = y1;
        box[ZZ][ZZ] = z1;
        if (sscanf (line, "%*f%*f%*f%lf%lf%lf%lf%lf%lf",
                    &x1, &y1, &z1, &x2, &y2, &z2) != 6)
        {
            x1 = y1 = z1 = x2 = y2 = z2 = 0.0;
        }
        box[XX][YY] = x1;
        box[XX][ZZ] = y1;
        box[YY][XX] = z1;
        box[YY][ZZ] = x2;
        box[ZZ][XX] = y2;
        box[ZZ][YY] = z2;
    }

    return bVel;
}
Ejemplo n.º 11
0
void set_pdb_conf_bfac(int natoms, int nres, t_atoms *atoms, int n_bfac,
                       double *bfac, int *bfac_nr, gmx_bool peratom)
{
    FILE *out;
    real bfac_min, bfac_max;
    int i, n;
    gmx_bool found;

    bfac_max = -1e10;
    bfac_min = 1e10;
    for (i = 0; (i < n_bfac); i++)
    {
        if (bfac_nr[i] - 1 >= atoms->nres)
            peratom = TRUE;
        /*    if ((bfac_nr[i]-1<0) || (bfac_nr[i]-1>=atoms->nr))
         gmx_fatal(FARGS,"Index of B-Factor %d is out of range: %d (%g)",
         i+1,bfac_nr[i],bfac[i]); */
        if (bfac[i] > bfac_max)
            bfac_max = bfac[i];
        if (bfac[i] < bfac_min)
            bfac_min = bfac[i];
    }
    while ((bfac_max > 99.99) || (bfac_min < -99.99))
    {
        fprintf(stderr,
                "Range of values for B-factors too large (min %g, max %g) "
                    "will scale down a factor 10\n", bfac_min, bfac_max);
        for (i = 0; (i < n_bfac); i++)
            bfac[i] /= 10;
        bfac_max /= 10;
        bfac_min /= 10;
    }
    while ((fabs(bfac_max) < 0.5) && (fabs(bfac_min) < 0.5))
    {
        fprintf(stderr,
                "Range of values for B-factors too small (min %g, max %g) "
                    "will scale up a factor 10\n", bfac_min, bfac_max);
        for (i = 0; (i < n_bfac); i++)
            bfac[i] *= 10;
        bfac_max *= 10;
        bfac_min *= 10;
    }

    for (i = 0; (i < natoms); i++)
        atoms->pdbinfo[i].bfac = 0;

    if (!peratom)
    {
        fprintf(stderr, "Will attach %d B-factors to %d residues\n", n_bfac,
                nres);
        for (i = 0; (i < n_bfac); i++)
        {
            found = FALSE;
            for (n = 0; (n < natoms); n++)
                if (bfac_nr[i] == atoms->resinfo[atoms->atom[n].resind].nr)
                {
                    atoms->pdbinfo[n].bfac = bfac[i];
                    found = TRUE;
                }
            if (!found)
            {
                gmx_warning("Residue nr %d not found\n", bfac_nr[i]);
            }
        }
    }
    else
    {
        fprintf(stderr, "Will attach %d B-factors to %d atoms\n", n_bfac,
                natoms);
        for (i = 0; (i < n_bfac); i++)
        {
            atoms->pdbinfo[bfac_nr[i] - 1].bfac = bfac[i];
        }
    }
}
Ejemplo n.º 12
0
static void do_sham(const char *fn, const char *ndx,
                    const char *xpmP, const char *xpm, const char *xpm2,
                    const char *xpm3, const char *pdb,
                    const char *logf,
                    int n, int neig, real **eig,
                    gmx_bool bGE, int nenerT, real **enerT,
                    real Tref,
                    real pmax, real gmax,
                    real *emin, real *emax, int nlevels, real pmin,
                    int *idim, int *ibox,
                    gmx_bool bXmin, real *xmin, gmx_bool bXmax, real *xmax)
{
    FILE        *fp;
    real        *min_eig, *max_eig;
    real        *axis_x, *axis_y, *axis_z, *axis = NULL;
    double      *P;
    real       **PP, *W, *E, **WW, **EE, *S, **SS, *M, *bE;
    rvec         xxx;
    char        *buf;
    double      *bfac, efac, bref, Pmax, Wmin, Wmax, Winf, Emin, Emax, Einf, Smin, Smax, Sinf, Mmin, Mmax;
    real        *delta;
    int          i, j, k, imin, len, index, d, *nbin, *bindex, bi;
    int         *nxyz, maxbox;
    t_blocka    *b;
    gmx_bool     bOutside;
    unsigned int flags;
    t_rgb        rlo  = { 0, 0, 0 };
    t_rgb        rhi  = { 1, 1, 1 };

    /* Determine extremes for the eigenvectors */
    snew(min_eig, neig);
    snew(max_eig, neig);
    snew(nxyz, neig);
    snew(bfac, neig);
    snew(delta, neig);

    for (i = 0; (i < neig); i++)
    {
        /* Check for input constraints */
        min_eig[i] = max_eig[i] = eig[i][0];
        for (j = 0; (j < n); j++)
        {
            min_eig[i] = min(min_eig[i], eig[i][j]);
            max_eig[i] = max(max_eig[i], eig[i][j]);
            delta[i]   = (max_eig[i]-min_eig[i])/(2.0*ibox[i]);
        }
        /* Add some extra space, half a bin on each side, unless the
         * user has set the limits.
         */
        if (bXmax)
        {
            if (max_eig[i] > xmax[i])
            {
                gmx_warning("Your xmax[%d] value %f is smaller than the largest data point %f", i, xmax[i], max_eig[i]);
            }
            max_eig[i] = xmax[i];
        }
        else
        {
            max_eig[i] += delta[i];
        }

        if (bXmin)
        {
            if (min_eig[i] < xmin[i])
            {
                gmx_warning("Your xmin[%d] value %f is larger than the smallest data point %f", i, xmin[i], min_eig[i]);
            }
            min_eig[i] = xmin[i];
        }
        else
        {
            min_eig[i] -= delta[i];
        }
        bfac[i]     = ibox[i]/(max_eig[i]-min_eig[i]);
    }
    /* Do the binning */
    bref = 1/(BOLTZ*Tref);
    snew(bE, n);
    if (bGE || nenerT == 2)
    {
        Emin = 1e8;
        for (j = 0; (j < n); j++)
        {
            if (bGE)
            {
                bE[j] = bref*enerT[0][j];
            }
            else
            {
                bE[j] = (bref - 1/(BOLTZ*enerT[1][j]))*enerT[0][j];
            }
            Emin  = min(Emin, bE[j]);
        }
    }
    else
    {
        Emin = 0;
    }
    len = 1;
    for (i = 0; (i < neig); i++)
    {
        len = len*ibox[i];
    }
    printf("There are %d bins in the %d-dimensional histogram. Beta-Emin = %g\n",
           len, neig, Emin);
    snew(P, len);
    snew(W, len);
    snew(E, len);
    snew(S, len);
    snew(M, len);
    snew(nbin, len);
    snew(bindex, n);


    /* Loop over projections */
    for (j = 0; (j < n); j++)
    {
        /* Loop over dimensions */
        bOutside = FALSE;
        for (i = 0; (i < neig); i++)
        {
            nxyz[i] = bfac[i]*(eig[i][j]-min_eig[i]);
            if (nxyz[i] < 0 || nxyz[i] >= ibox[i])
            {
                bOutside = TRUE;
            }
        }
        if (!bOutside)
        {
            index = indexn(neig, ibox, nxyz);
            range_check(index, 0, len);
            /* Compute the exponential factor */
            if (enerT)
            {
                efac = exp(-bE[j]+Emin);
            }
            else
            {
                efac = 1;
            }
            /* Apply the bin volume correction for a multi-dimensional distance */
            for (i = 0; i < neig; i++)
            {
                if (idim[i] == 2)
                {
                    efac /= eig[i][j];
                }
                else if (idim[i] == 3)
                {
                    efac /= sqr(eig[i][j]);
                }
                else if (idim[i] == -1)
                {
                    efac /= sin(DEG2RAD*eig[i][j]);
                }
            }
            /* Update the probability */
            P[index] += efac;
            /* Update the energy */
            if (enerT)
            {
                E[index] += enerT[0][j];
            }
            /* Statistics: which "structure" in which bin */
            nbin[index]++;
            bindex[j] = index;
        }
    }
    /* Normalize probability */
    normalize_p_e(len, P, nbin, E, pmin);
    Pmax = 0;
    /* Compute boundaries for the Free energy */
    Wmin = 1e8;
    imin = -1;
    Wmax = -1e8;
    /* Recompute Emin: it may have changed due to averaging */
    Emin = 1e8;
    Emax = -1e8;
    for (i = 0; (i < len); i++)
    {
        if (P[i] != 0)
        {
            Pmax = max(P[i], Pmax);
            W[i] = -BOLTZ*Tref*log(P[i]);
            if (W[i] < Wmin)
            {
                Wmin = W[i];
                imin = i;
            }
            Emin = min(E[i], Emin);
            Emax = max(E[i], Emax);
            Wmax = max(W[i], Wmax);
        }
    }
    if (pmax > 0)
    {
        Pmax = pmax;
    }
    if (gmax > 0)
    {
        Wmax = gmax;
    }
    else
    {
        Wmax -= Wmin;
    }
    Winf = Wmax+1;
    Einf = Emax+1;
    Smin = Emin-Wmax;
    Smax = Emax-Smin;
    Sinf = Smax+1;
    /* Write out the free energy as a function of bin index */
    fp = gmx_ffopen(fn, "w");
    for (i = 0; (i < len); i++)
    {
        if (P[i] != 0)
        {
            W[i] -= Wmin;
            S[i]  = E[i]-W[i]-Smin;
            fprintf(fp, "%5d  %10.5e  %10.5e  %10.5e\n", i, W[i], E[i], S[i]);
        }
        else
        {
            W[i] = Winf;
            E[i] = Einf;
            S[i] = Sinf;
        }
    }
    gmx_ffclose(fp);
    /* Organize the structures in the bins */
    snew(b, 1);
    snew(b->index, len+1);
    snew(b->a, n);
    b->index[0] = 0;
    for (i = 0; (i < len); i++)
    {
        b->index[i+1] = b->index[i]+nbin[i];
        nbin[i]       = 0;
    }
    for (i = 0; (i < n); i++)
    {
        bi = bindex[i];
        b->a[b->index[bi]+nbin[bi]] = i;
        nbin[bi]++;
    }
    /* Consistency check */
    /* This no longer applies when we allow the plot to be smaller
       than the sampled space.
       for(i=0; (i<len); i++) {
       if (nbin[i] != (b->index[i+1] - b->index[i]))
        gmx_fatal(FARGS,"nbin[%d] = %d, should be %d",i,nbin[i],
          b->index[i+1] - b->index[i]);
       }
     */
    /* Write the index file */
    fp = gmx_ffopen(ndx, "w");
    for (i = 0; (i < len); i++)
    {
        if (nbin[i] > 0)
        {
            fprintf(fp, "[ %d ]\n", i);
            for (j = b->index[i]; (j < b->index[i+1]); j++)
            {
                fprintf(fp, "%d\n", b->a[j]+1);
            }
        }
    }
    gmx_ffclose(fp);
    snew(axis_x, ibox[0]+1);
    snew(axis_y, ibox[1]+1);
    snew(axis_z, ibox[2]+1);
    maxbox = max(ibox[0], max(ibox[1], ibox[2]));
    snew(PP, maxbox*maxbox);
    snew(WW, maxbox*maxbox);
    snew(EE, maxbox*maxbox);
    snew(SS, maxbox*maxbox);
    for (i = 0; (i < min(neig, 3)); i++)
    {
        switch (i)
        {
            case 0: axis = axis_x; break;
            case 1: axis = axis_y; break;
            case 2: axis = axis_z; break;
            default: break;
        }
        for (j = 0; j <= ibox[i]; j++)
        {
            axis[j] = min_eig[i] + j/bfac[i];
        }
    }

    pick_minima(logf, ibox, neig, len, W);
    if (gmax <= 0)
    {
        gmax = Winf;
    }
    flags = MAT_SPATIAL_X | MAT_SPATIAL_Y;
    if (neig == 2)
    {
        /* Dump to XPM file */
        snew(PP, ibox[0]);
        for (i = 0; (i < ibox[0]); i++)
        {
            snew(PP[i], ibox[1]);
            for (j = 0; j < ibox[1]; j++)
            {
                PP[i][j] = P[i*ibox[1]+j];
            }
            WW[i] = &(W[i*ibox[1]]);
            EE[i] = &(E[i*ibox[1]]);
            SS[i] = &(S[i*ibox[1]]);
        }
        fp = gmx_ffopen(xpmP, "w");
        write_xpm(fp, flags, "Probability Distribution", "", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, PP, 0, Pmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        fp = gmx_ffopen(xpm, "w");
        write_xpm(fp, flags, "Gibbs Energy Landscape", "G (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        fp = gmx_ffopen(xpm2, "w");
        write_xpm(fp, flags, "Enthalpy Landscape", "H (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, EE,
                  emin ? *emin : Emin, emax ? *emax : Einf, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        fp = gmx_ffopen(xpm3, "w");
        write_xpm(fp, flags, "Entropy Landscape", "TDS (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, SS, 0, Sinf, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
    }
    else if (neig == 3)
    {
        /* Dump to PDB file */
        fp = gmx_ffopen(pdb, "w");
        for (i = 0; (i < ibox[0]); i++)
        {
            xxx[XX] = 3*(i+0.5-ibox[0]/2);
            for (j = 0; (j < ibox[1]); j++)
            {
                xxx[YY] = 3*(j+0.5-ibox[1]/2);
                for (k = 0; (k < ibox[2]); k++)
                {
                    xxx[ZZ] = 3*(k+0.5-ibox[2]/2);
                    index   = index3(ibox, i, j, k);
                    if (P[index] > 0)
                    {
                        fprintf(fp, "%-6s%5u  %-4.4s%3.3s  %4d    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
                                "ATOM", (index+1) %10000, "H", "H", (index+1)%10000,
                                xxx[XX], xxx[YY], xxx[ZZ], 1.0, W[index]);
                    }
                }
            }
        }
        gmx_ffclose(fp);
        write_xplor("out.xplor", W, ibox, min_eig, max_eig);
        nxyz[XX] = imin/(ibox[1]*ibox[2]);
        nxyz[YY] = (imin-nxyz[XX]*ibox[1]*ibox[2])/ibox[2];
        nxyz[ZZ] = imin % ibox[2];
        for (i = 0; (i < ibox[0]); i++)
        {
            snew(WW[i], maxbox);
            for (j = 0; (j < ibox[1]); j++)
            {
                WW[i][j] = W[index3(ibox, i, j, nxyz[ZZ])];
            }
        }
        snew(buf, strlen(xpm)+4);
        sprintf(buf, "%s", xpm);
        sprintf(&buf[strlen(xpm)-4], "12.xpm");
        fp = gmx_ffopen(buf, "w");
        write_xpm(fp, flags, "Gibbs Energy Landscape", "W (kJ/mol)", "PC1", "PC2",
                  ibox[0], ibox[1], axis_x, axis_y, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        for (i = 0; (i < ibox[0]); i++)
        {
            for (j = 0; (j < ibox[2]); j++)
            {
                WW[i][j] = W[index3(ibox, i, nxyz[YY], j)];
            }
        }
        sprintf(&buf[strlen(xpm)-4], "13.xpm");
        fp = gmx_ffopen(buf, "w");
        write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC1", "PC3",
                  ibox[0], ibox[2], axis_x, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        for (i = 0; (i < ibox[1]); i++)
        {
            for (j = 0; (j < ibox[2]); j++)
            {
                WW[i][j] = W[index3(ibox, nxyz[XX], i, j)];
            }
        }
        sprintf(&buf[strlen(xpm)-4], "23.xpm");
        fp = gmx_ffopen(buf, "w");
        write_xpm(fp, flags, "SHAM Energy Landscape", "kJ/mol", "PC2", "PC3",
                  ibox[1], ibox[2], axis_y, axis_z, WW, 0, gmax, rlo, rhi, &nlevels);
        gmx_ffclose(fp);
        sfree(buf);
    }
}
Ejemplo n.º 13
0
/** Determine the number of threads for module \p mod.
 *
 *  \p m takes values form the module_nth_t enum and maps these to the
 *  corresponding value in modth_env_var.
 *
 *  Each number of threads per module takes the default value unless
 *  GMX_*_NUM_THERADS env var is set, case in which its value overrides
 *  the deafult.
 *
 *  The "group" scheme supports OpenMP only in PME and in thise case all but
 *  the PME nthread values default to 1.
 */
static void pick_module_nthreads(FILE *fplog, int m,
                                 gmx_bool bSimMaster,
                                 gmx_bool bFullOmpSupport,
                                 gmx_bool bSepPME)
{
    char    *env;
    int      nth;
    char     sbuf[STRLEN];
    gmx_bool bOMP;

#ifdef GMX_OPENMP
    bOMP = TRUE;
#else
    bOMP = FALSE;
#endif /* GMX_OPENMP */

    /* The default should never be set through a GMX_*_NUM_THREADS env var
     * as it's always equal with gnth. */
    if (m == emntDefault)
    {
        return;
    }

    /* check the environment variable */
    if ((env = getenv(modth_env_var[m])) != NULL)
    {
        sscanf(env, "%d", &nth);

        if (!bOMP)
        {
            gmx_warning("%s=%d is set, but %s is compiled without OpenMP!",
                        modth_env_var[m], nth, ShortProgram());
        }

        /* with the verlet codepath, when any GMX_*_NUM_THREADS env var is set,
         * OMP_NUM_THREADS also has to be set */
        if (bFullOmpSupport && getenv("OMP_NUM_THREADS") == NULL)
        {
            gmx_fatal(FARGS, "%s=%d is set, the default number of threads also "
                      "needs to be set with OMP_NUM_THREADS!",
                      modth_env_var[m], nth);
        }

        /* with the group scheme warn if any env var except PME is set */
        if (!bFullOmpSupport)
        {
            if (m != emntPME)
            {
                gmx_warning("%s=%d is set, but OpenMP multithreading is not "
                            "supported in %s!",
                            modth_env_var[m], nth, mod_name[m]);
                nth = 1;
            }
        }

        /* only babble if we are really overriding with a different value */
        if ((bSepPME && m == emntPME && nth != modth.gnth_pme) || (nth != modth.gnth))
        {
            sprintf(sbuf, "%s=%d set, overriding the default number of %s threads",
                    modth_env_var[m], nth, mod_name[m]);
            if (bSimMaster)
            {
                fprintf(stderr, "\n%s\n", sbuf);
            }
            if (fplog)
            {
                fprintf(fplog, "%s\n", sbuf);
            }
        }
    }
    else
    {
        /* pick the global PME node nthreads if we are setting the number
         * of threads in separate PME nodes  */
        nth = (bSepPME && m == emntPME) ? modth.gnth_pme : modth.gnth;
    }

    gmx_omp_nthreads_set(m, nth);
}
Ejemplo n.º 14
0
gmx_bool gmx_omp_check_thread_affinity(char **message)
{
    bool shouldSetAffinity = true;

    *message = NULL;
#ifdef GMX_OPENMP
    /* We assume that the affinity setting is available on all platforms
     * gcc supports. Even if this is not the case (e.g. Mac OS) the user
     * will only get a warning. */
#if defined(__GNUC__) || defined(__INTEL_COMPILER)
    const char *programName;
    try
    {
        programName = gmx::getProgramContext().displayName();
    }
    GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;

    const char *const gomp_env            = getenv("GOMP_CPU_AFFINITY");
    const bool        bGompCpuAffinitySet = (gomp_env != NULL);

    /* turn off internal pinning if GOMP_CPU_AFFINITY is set & non-empty */
    if (bGompCpuAffinitySet && *gomp_env != '\0')
    {
        try
        {
            std::string buf = gmx::formatString(
                        "NOTE: GOMP_CPU_AFFINITY set, will turn off %s internal affinity\n"
                        "      setting as the two can conflict and cause performance degradation.\n"
                        "      To keep using the %s internal affinity setting, unset the\n"
                        "      GOMP_CPU_AFFINITY environment variable.",
                        programName, programName);
            *message = gmx_strdup(buf.c_str());
        }
        GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
        shouldSetAffinity = false;
    }
#endif /* __GNUC__ || __INTEL_COMPILER */

#if defined(__INTEL_COMPILER)
    const char *const kmp_env         = getenv("KMP_AFFINITY");
    const bool        bKmpAffinitySet = (kmp_env != NULL);

    /* disable Intel OpenMP affinity if neither KMP_AFFINITY nor
     * GOMP_CPU_AFFINITY is set (Intel uses the GNU env. var as well) */
    if (!bKmpAffinitySet && !bGompCpuAffinitySet)
    {
        int retval;

#ifdef _MSC_VER
        /* Windows not POSIX */
        retval = _putenv_s("KMP_AFFINITY", "disabled");
#else
        /* POSIX */
        retval = setenv("KMP_AFFINITY", "disabled", 0);
#endif  /* _MSC_VER */

        if (debug)
        {
            fprintf(debug, "Disabling Intel OpenMP affinity by setting the KMP_AFFINITY=disabled env. var.\n");
        }

        if (retval != 0)
        {
            gmx_warning("Disabling Intel OpenMp affinity setting failed!");
        }
    }

    /* turn off internal pinning KMP_AFFINITY != "disabled" */
    if (bKmpAffinitySet && (gmx_strncasecmp(kmp_env, "disabled", 8) != 0))
    {
        try
        {
            std::string buf = gmx::formatString(
                        "NOTE: KMP_AFFINITY set, will turn off %s internal affinity\n"
                        "      setting as the two can conflict and cause performance degradation.\n"
                        "      To keep using the %s internal affinity setting, set the\n"
                        "      KMP_AFFINITY=disabled environment variable.",
                        programName, programName);
            *message = gmx_strdup(buf.c_str());
        }
        GMX_CATCH_ALL_AND_EXIT_WITH_FATAL_ERROR;
        shouldSetAffinity = false;
    }
#endif /* __INTEL_COMPILER */

#endif /* GMX_OPENMP */
    return shouldSetAffinity;
}
Ejemplo n.º 15
0
/* TODO: If/when TNG acquires the ability to copy data blocks without
 * uncompressing them, then this implemenation should be reconsidered.
 * Ideally, gmx trjconv -f a.tng -o b.tng -b 10 -e 20 would be fast
 * and lose no information. */
gmx_bool gmx_read_next_tng_frame(tng_trajectory_t            input,
                                 t_trxframe                 *fr,
                                 gmx_int64_t                *requestedIds,
                                 int                         numRequestedIds)
{
#if GMX_USE_TNG
    gmx_bool                bOK = TRUE;
    tng_function_status     stat;
    gmx_int64_t             numberOfAtoms = -1, frameNumber = -1;
    gmx_int64_t             nBlocks, blockId, *blockIds = NULL, codecId;
    char                    datatype      = -1;
    void                   *values        = NULL;
    double                  frameTime     = -1.0;
    int                     size, blockDependency;
    double                  prec;
    const int               defaultNumIds = 5;
    static gmx_int64_t      fallbackRequestedIds[defaultNumIds] =
    {
        TNG_TRAJ_BOX_SHAPE, TNG_TRAJ_POSITIONS,
        TNG_TRAJ_VELOCITIES, TNG_TRAJ_FORCES,
        TNG_GMX_LAMBDA
    };


    fr->bStep     = FALSE;
    fr->bTime     = FALSE;
    fr->bLambda   = FALSE;
    fr->bAtoms    = FALSE;
    fr->bPrec     = FALSE;
    fr->bX        = FALSE;
    fr->bV        = FALSE;
    fr->bF        = FALSE;
    fr->bBox      = FALSE;

    /* If no specific IDs were requested read all block types that can
     * currently be interpreted */
    if (!requestedIds || numRequestedIds == 0)
    {
        numRequestedIds = defaultNumIds;
        requestedIds    = fallbackRequestedIds;
    }

    stat = tng_num_particles_get(input, &numberOfAtoms);
    if (stat != TNG_SUCCESS)
    {
        gmx_file("Cannot determine number of atoms from TNG file.");
    }
    fr->natoms = numberOfAtoms;

    if (!gmx_get_tng_data_block_types_of_next_frame(input,
                                                    fr->step,
                                                    numRequestedIds,
                                                    requestedIds,
                                                    &frameNumber,
                                                    &nBlocks,
                                                    &blockIds))
    {
        return FALSE;
    }

    if (nBlocks == 0)
    {
        return FALSE;
    }

    for (gmx_int64_t i = 0; i < nBlocks; i++)
    {
        blockId = blockIds[i];
        tng_data_block_dependency_get(input, blockId, &blockDependency);
        if (blockDependency & TNG_PARTICLE_DEPENDENT)
        {
            stat = tng_util_particle_data_next_frame_read(input,
                                                          blockId,
                                                          &values,
                                                          &datatype,
                                                          &frameNumber,
                                                          &frameTime);
        }
        else
        {
            stat = tng_util_non_particle_data_next_frame_read(input,
                                                              blockId,
                                                              &values,
                                                              &datatype,
                                                              &frameNumber,
                                                              &frameTime);
        }
        if (stat == TNG_CRITICAL)
        {
            gmx_file("Cannot read positions from TNG file.");
            return FALSE;
        }
        else if (stat == TNG_FAILURE)
        {
            continue;
        }
        switch (blockId)
        {
            case TNG_TRAJ_BOX_SHAPE:
                switch (datatype)
                {
                    case TNG_INT_DATA:
                        size = sizeof(gmx_int64_t);
                        break;
                    case TNG_FLOAT_DATA:
                        size = sizeof(float);
                        break;
                    case TNG_DOUBLE_DATA:
                        size = sizeof(double);
                        break;
                    default:
                        gmx_incons("Illegal datatype of box shape values!");
                }
                for (int i = 0; i < DIM; i++)
                {
                    convert_array_to_real_array(reinterpret_cast<char *>(values) + size * i * DIM,
                                                reinterpret_cast<real *>(fr->box[i]),
                                                getDistanceScaleFactor(input),
                                                1,
                                                DIM,
                                                datatype);
                }
                fr->bBox = TRUE;
                break;
            case TNG_TRAJ_POSITIONS:
                srenew(fr->x, fr->natoms);
                convert_array_to_real_array(values,
                                            reinterpret_cast<real *>(fr->x),
                                            getDistanceScaleFactor(input),
                                            fr->natoms,
                                            DIM,
                                            datatype);
                fr->bX = TRUE;
                tng_util_frame_current_compression_get(input, blockId, &codecId, &prec);
                /* This must be updated if/when more lossy compression methods are added */
                if (codecId == TNG_TNG_COMPRESSION)
                {
                    fr->prec  = prec;
                    fr->bPrec = TRUE;
                }
                break;
            case TNG_TRAJ_VELOCITIES:
                srenew(fr->v, fr->natoms);
                convert_array_to_real_array(values,
                                            (real *) fr->v,
                                            getDistanceScaleFactor(input),
                                            fr->natoms,
                                            DIM,
                                            datatype);
                fr->bV = TRUE;
                tng_util_frame_current_compression_get(input, blockId, &codecId, &prec);
                /* This must be updated if/when more lossy compression methods are added */
                if (codecId == TNG_TNG_COMPRESSION)
                {
                    fr->prec  = prec;
                    fr->bPrec = TRUE;
                }
                break;
            case TNG_TRAJ_FORCES:
                srenew(fr->f, fr->natoms);
                convert_array_to_real_array(values,
                                            reinterpret_cast<real *>(fr->f),
                                            getDistanceScaleFactor(input),
                                            fr->natoms,
                                            DIM,
                                            datatype);
                fr->bF = TRUE;
                break;
            case TNG_GMX_LAMBDA:
                switch (datatype)
                {
                    case TNG_FLOAT_DATA:
                        fr->lambda = *(reinterpret_cast<float *>(values));
                        break;
                    case TNG_DOUBLE_DATA:
                        fr->lambda = *(reinterpret_cast<double *>(values));
                        break;
                    default:
                        gmx_incons("Illegal datatype lambda value!");
                }
                fr->bLambda = TRUE;
                break;
            default:
                gmx_warning("Illegal block type! Currently GROMACS tools can only handle certain data types. Skipping block.");
        }
        /* values does not have to be freed before reading next frame. It will
         * be reallocated if it is not NULL. */
    }

    fr->step  = static_cast<int>(frameNumber);
    fr->bStep = TRUE;
    // Convert the time to ps
    fr->time  = frameTime / PICO;
    fr->bTime = TRUE;

    /* values must be freed before leaving this function */
    sfree(values);

    return bOK;
#else
    GMX_UNUSED_VALUE(input);
    GMX_UNUSED_VALUE(fr);
    GMX_UNUSED_VALUE(requestedIds);
    GMX_UNUSED_VALUE(numRequestedIds);
    return FALSE;
#endif
}
Ejemplo n.º 16
0
/*! \brief Helper function for parsing various input about the number
    of OpenMP threads to use in various modules and deciding what to
    do about it. */
static void manage_number_of_openmp_threads(const gmx::MDLogger &mdlog,
                                            const t_commrec     *cr,
                                            bool                 bOMP,
                                            int                  nthreads_hw_avail,
                                            int                  omp_nthreads_req,
                                            int                  omp_nthreads_pme_req,
                                            gmx_bool gmx_unused  bThisNodePMEOnly,
                                            gmx_bool             bFullOmpSupport,
                                            int                  numRanksOnThisNode,
                                            gmx_bool             bSepPME)
{
    int      nth;
    char    *env;

#if GMX_THREAD_MPI
    /* modth is shared among tMPI threads, so for thread safety, the
     * detection is done on the master only. It is not thread-safe
     * with multiple simulations, but that's anyway not supported by
     * tMPI. */
    if (!SIMMASTER(cr))
    {
        return;
    }
#else
    GMX_UNUSED_VALUE(cr);
#endif

    if (modth.initialized)
    {
        /* Just return if the initialization has already been
           done. This could only happen if gmx_omp_nthreads_init() has
           already been called. */
        return;
    }

    /* With full OpenMP support (verlet scheme) set the number of threads
     * per process / default:
     * - 1 if not compiled with OpenMP or
     * - OMP_NUM_THREADS if the env. var is set, or
     * - omp_nthreads_req = #of threads requested by the user on the mdrun
     *   command line, otherwise
     * - take the max number of available threads and distribute them
     *   on the processes/tMPI threads.
     * ~ The GMX_*_NUM_THREADS env var overrides the number of threads of
     *   the respective module and it has to be used in conjunction with
     *   OMP_NUM_THREADS.
     *
     * With the group scheme OpenMP multithreading is only supported in PME,
     * for all other modules nthreads is set to 1.
     * The number of PME threads is equal to:
     * - 1 if not compiled with OpenMP or
     * - GMX_PME_NUM_THREADS if defined, otherwise
     * - OMP_NUM_THREADS if defined, otherwise
     * - 1
     */
    nth = 1;
    if ((env = getenv("OMP_NUM_THREADS")) != nullptr)
    {
        if (!bOMP && (std::strncmp(env, "1", 1) != 0))
        {
            gmx_warning("OMP_NUM_THREADS is set, but %s was compiled without OpenMP support!",
                        gmx::getProgramContext().displayName());
        }
        else
        {
            nth = gmx_omp_get_max_threads();
        }
    }
    else if (omp_nthreads_req > 0)
    {
        nth = omp_nthreads_req;
    }
    else if (bFullOmpSupport && bOMP)
    {
        /* max available threads per node */
        nth = nthreads_hw_avail;

        /* divide the threads among the MPI ranks */
        if (nth >= numRanksOnThisNode)
        {
            nth /= numRanksOnThisNode;
        }
        else
        {
            nth = 1;
        }
    }

    /* now we have the global values, set them:
     * - 1 if not compiled with OpenMP and for the group scheme
     * - nth for the verlet scheme when compiled with OpenMP
     */
    if (bFullOmpSupport && bOMP)
    {
        modth.gnth = nth;
    }
    else
    {
        modth.gnth = 1;
    }

    if (bSepPME)
    {
        if (omp_nthreads_pme_req > 0)
        {
            modth.gnth_pme = omp_nthreads_pme_req;
        }
        else
        {
            modth.gnth_pme = nth;
        }
    }
    else
    {
        modth.gnth_pme = 0;
    }

    /* now set the per-module values */
    modth.nth[emntDefault] = modth.gnth;
    pick_module_nthreads(mdlog, emntDomdec, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntPairsearch, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntNonbonded, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntBonded, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntPME, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntUpdate, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntVSITE, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntLINCS, bFullOmpSupport, bSepPME);
    pick_module_nthreads(mdlog, emntSETTLE, bFullOmpSupport, bSepPME);

    /* set the number of threads globally */
    if (bOMP)
    {
#if !GMX_THREAD_MPI
        if (bThisNodePMEOnly)
        {
            gmx_omp_set_num_threads(modth.gnth_pme);
        }
        else
#endif      /* GMX_THREAD_MPI */
        {
            if (bFullOmpSupport)
            {
                gmx_omp_set_num_threads(nth);
            }
            else
            {
                gmx_omp_set_num_threads(1);
            }
        }
    }

    modth.initialized = TRUE;
}
Ejemplo n.º 17
0
/** Determine the number of threads for module \p mod.
 *
 *  \p m takes values form the module_nth_t enum and maps these to the
 *  corresponding value in modth_env_var.
 *
 *  Each number of threads per module takes the default value unless
 *  GMX_*_NUM_THERADS env var is set, case in which its value overrides
 *  the deafult.
 *
 *  The "group" scheme supports OpenMP only in PME and in thise case all but
 *  the PME nthread values default to 1.
 */
static void pick_module_nthreads(const gmx::MDLogger &mdlog, int m,
                                 gmx_bool bFullOmpSupport,
                                 gmx_bool bSepPME)
{
    char      *env;
    int        nth;

    const bool bOMP = GMX_OPENMP;

    /* The default should never be set through a GMX_*_NUM_THREADS env var
     * as it's always equal with gnth. */
    if (m == emntDefault)
    {
        return;
    }

    /* check the environment variable */
    if ((env = getenv(modth_env_var[m])) != nullptr)
    {
        sscanf(env, "%d", &nth);

        if (!bOMP)
        {
            gmx_warning("%s=%d is set, but %s is compiled without OpenMP!",
                        modth_env_var[m], nth,
                        gmx::getProgramContext().displayName());
        }

        /* with the verlet codepath, when any GMX_*_NUM_THREADS env var is set,
         * OMP_NUM_THREADS also has to be set */
        if (bFullOmpSupport && getenv("OMP_NUM_THREADS") == nullptr)
        {
            gmx_warning("%s=%d is set, the default number of threads also "
                        "needs to be set with OMP_NUM_THREADS!",
                        modth_env_var[m], nth);
        }

        /* with the group scheme warn if any env var except PME is set */
        if (!bFullOmpSupport)
        {
            if (m != emntPME)
            {
                gmx_warning("%s=%d is set, but OpenMP multithreading is not "
                            "supported in %s!",
                            modth_env_var[m], nth, mod_name[m]);
                nth = 1;
            }
        }

        /* only babble if we are really overriding with a different value */
        if ((bSepPME && m == emntPME && nth != modth.gnth_pme) || (nth != modth.gnth))
        {
            GMX_LOG(mdlog.warning).asParagraph().appendTextFormatted(
                    "%s=%d set, overriding the default number of %s threads",
                    modth_env_var[m], nth, mod_name[m]);
        }
    }
    else
    {
        /* pick the global PME node nthreads if we are setting the number
         * of threads in separate PME nodes  */
        nth = (bSepPME && m == emntPME) ? modth.gnth_pme : modth.gnth;
    }

    gmx_omp_nthreads_set(m, nth);
}
Ejemplo n.º 18
0
void gmx_omp_nthreads_init(FILE *fplog, t_commrec *cr,
                           int nthreads_hw_avail,
                           int omp_nthreads_req,
                           int omp_nthreads_pme_req,
                           gmx_bool gmx_unused bThisNodePMEOnly,
                           gmx_bool bFullOmpSupport)
{
    int      nth, nth_pmeonly, gmx_maxth, nppn;
    char    *env;
    gmx_bool bSepPME, bOMP;

#ifdef GMX_OPENMP
    bOMP = TRUE;
#else
    bOMP = FALSE;
#endif /* GMX_OPENMP */

    /* number of MPI processes/threads per physical node */
    nppn = cr->nrank_intranode;

    bSepPME = ( (cr->duty & DUTY_PP) && !(cr->duty & DUTY_PME)) ||
        (!(cr->duty & DUTY_PP) &&  (cr->duty & DUTY_PME));

#ifdef GMX_THREAD_MPI
    /* modth is shared among tMPI threads, so for thread safety do the
     * detection is done on the master only. It is not thread-safe with
     * multiple simulations, but that's anyway not supported by tMPI. */
    if (SIMMASTER(cr))
#endif
    {
        /* just return if the initialization has already been done */
        if (modth.initialized)
        {
            return;
        }

        /* With full OpenMP support (verlet scheme) set the number of threads
         * per process / default:
         * - 1 if not compiled with OpenMP or
         * - OMP_NUM_THREADS if the env. var is set, or
         * - omp_nthreads_req = #of threads requested by the user on the mdrun
         *   command line, otherwise
         * - take the max number of available threads and distribute them
         *   on the processes/tMPI threads.
         * ~ The GMX_*_NUM_THREADS env var overrides the number of threads of
         *   the respective module and it has to be used in conjunction with
         *   OMP_NUM_THREADS.
         *
         * With the group scheme OpenMP multithreading is only supported in PME,
         * for all other modules nthreads is set to 1.
         * The number of PME threads is equal to:
         * - 1 if not compiled with OpenMP or
         * - GMX_PME_NUM_THREADS if defined, otherwise
         * - OMP_NUM_THREADS if defined, otherwise
         * - 1
         */
        nth = 1;
        if ((env = getenv("OMP_NUM_THREADS")) != NULL)
        {
            if (!bOMP && (strncmp(env, "1", 1) != 0))
            {
                gmx_warning("OMP_NUM_THREADS is set, but %s was compiled without OpenMP support!",
                            ShortProgram());
            }
            else
            {
                nth = gmx_omp_get_max_threads();
            }
        }
        else if (omp_nthreads_req > 0)
        {
            nth = omp_nthreads_req;
        }
        else if (bFullOmpSupport && bOMP)
        {
            /* max available threads per node */
            nth = nthreads_hw_avail;

            /* divide the threads among the MPI processes/tMPI threads */
            if (nth >= nppn)
            {
                nth /= nppn;
            }
            else
            {
                nth = 1;
            }
        }

        /* now we have the global values, set them:
         * - 1 if not compiled with OpenMP and for the group scheme
         * - nth for the verlet scheme when compiled with OpenMP
         */
        if (bFullOmpSupport && bOMP)
        {
            modth.gnth = nth;
        }
        else
        {
            modth.gnth = 1;
        }

        if (bSepPME)
        {
            if (omp_nthreads_pme_req > 0)
            {
                modth.gnth_pme = omp_nthreads_pme_req;
            }
            else
            {
                modth.gnth_pme = nth;
            }
        }
        else
        {
            modth.gnth_pme = 0;
        }

        /* now set the per-module values */
        modth.nth[emntDefault] = modth.gnth;
        pick_module_nthreads(fplog, emntDomdec, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntPairsearch, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntNonbonded, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntBonded, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntPME, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntUpdate, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntVSITE, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntLINCS, SIMMASTER(cr), bFullOmpSupport, bSepPME);
        pick_module_nthreads(fplog, emntSETTLE, SIMMASTER(cr), bFullOmpSupport, bSepPME);

        /* set the number of threads globally */
        if (bOMP)
        {
#ifndef GMX_THREAD_MPI
            if (bThisNodePMEOnly)
            {
                gmx_omp_set_num_threads(modth.gnth_pme);
            }
            else
#endif      /* GMX_THREAD_MPI */
            {
                if (bFullOmpSupport)
                {
                    gmx_omp_set_num_threads(nth);
                }
                else
                {
                    gmx_omp_set_num_threads(1);
                }
            }
        }

        modth.initialized = TRUE;
    }
#ifdef GMX_THREAD_MPI
    /* Non-master threads have to wait for the detection to be done. */
    if (PAR(cr))
    {
        MPI_Barrier(cr->mpi_comm_mysim);
    }
#endif

    /* inform the user about the settings */
    if (bOMP)
    {
#ifdef GMX_THREAD_MPI
        const char *mpi_str = "per tMPI thread";
#else
        const char *mpi_str = "per MPI process";
#endif

        /* for group scheme we print PME threads info only */
        if (bFullOmpSupport)
        {
            md_print_info(cr, fplog, "Using %d OpenMP thread%s %s\n",
                          modth.gnth, modth.gnth > 1 ? "s" : "",
                          cr->nnodes > 1 ? mpi_str : "");
        }
        if (bSepPME && modth.gnth_pme != modth.gnth)
        {
            md_print_info(cr, fplog, "Using %d OpenMP thread%s %s for PME\n",
                          modth.gnth_pme, modth.gnth_pme > 1 ? "s" : "",
                          cr->nnodes > 1 ? mpi_str : "");
        }
    }

    /* detect and warn about oversubscription
     * TODO: enable this for separate PME nodes as well! */
    if (!bSepPME && cr->rank_pp_intranode == 0)
    {
        char sbuf[STRLEN], sbuf1[STRLEN], sbuf2[STRLEN];

        if (modth.gnth*nppn > nthreads_hw_avail)
        {
            sprintf(sbuf, "threads");
            sbuf1[0] = '\0';
            sprintf(sbuf2, "O");
#ifdef GMX_MPI
            if (modth.gnth == 1)
            {
#ifdef GMX_THREAD_MPI
                sprintf(sbuf, "thread-MPI threads");
#else
                sprintf(sbuf, "MPI processes");
                sprintf(sbuf1, " per node");
                sprintf(sbuf2, "On node %d: o", cr->sim_nodeid);
#endif
            }
#endif
            md_print_warn(cr, fplog,
                          "WARNING: %sversubscribing the available %d logical CPU cores%s with %d %s.\n"
                          "         This will cause considerable performance loss!",
                          sbuf2, nthreads_hw_avail, sbuf1, nppn*modth.gnth, sbuf);
        }
    }
}