📄 mpqc.cc
字号:
//// mpqc.cc//// Copyright (C) 1996 Limit Point Systems, Inc.//// Author: Edward Seidl <seidl@janed.com>// Maintainer: LPS//// This file is part of MPQC.//// MPQC is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2, or (at your option)// any later version.//// MPQC is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with the MPQC; see the file COPYING. If not, write to// the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.//// The U.S. Government is granted a limited license as per AL 91-7.//// This is needed to make GNU extensions available, such as// feenableexcept and fedisableexcept.#ifndef _GNU_SOURCE# define _GNU_SOURCE#endif#ifdef HAVE_CONFIG_H#include <scconfig.h>#endif#ifdef HAVE_TIME_H#include <time.h>#endif#include <scdirlist.h>#include <new>#include <stdexcept>#include <string.h>#include <unistd.h>#include <sys/stat.h>#include <fstream>#include <scconfig.h>#ifdef HAVE_SSTREAM# include <sstream>#else# include <strstream.h>#endif#ifdef HAVE_SYS_RESOURCE_H# include <sys/resource.h>#endif#ifdef HAVE_SYS_TIME_H# include <sys/time.h>#endif#include <util/options/GetLongOpt.h>#include <util/misc/newstring.h>#include <util/keyval/keyval.h>#include <util/state/state_bin.h>#include <util/group/message.h>#include <util/group/memory.h>#include <util/group/mstate.h>#include <util/group/thread.h>#include <util/group/pregtime.h>#include <util/misc/bug.h>#include <util/misc/formio.h>#include <util/misc/exenv.h>#include <util/render/render.h>#include <math/optimize/opt.h>#include <chemistry/molecule/coor.h>#include <chemistry/molecule/energy.h>#include <chemistry/molecule/molfreq.h>#include <chemistry/molecule/fdhess.h>#include <chemistry/molecule/formula.h>#include <chemistry/qc/wfn/wfn.h>// Force linkages:#include <chemistry/qc/wfn/linkage.h>#include <chemistry/qc/scf/linkage.h>#include <chemistry/qc/dft/linkage.h>#include <chemistry/qc/mbpt/linkage.h>#ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_MBPTR12# include <chemistry/qc/mbptr12/linkage.h>#endif#ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_CINTS# include <chemistry/qc/cints/linkage.h>#endif//#include <chemistry/qc/psi/linkage.h>#include <util/state/linkage.h>#ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_CC# include <chemistry/qc/cc/linkage.h>#endif#ifdef HAVE_SC_SRC_LIB_CHEMISTRY_QC_PSI# include <chemistry/qc/psi/linkage.h>#endif#ifdef HAVE_MPI#include <mpi.h>#include <util/group/messmpi.h>#endifusing namespace std;using namespace sc;#include "mpqcin.h"//////////////////////////////////////////////////////////////////////////static voidtrash_stack_b(int &i, char *&ichar){ char stack; ichar = &stack; ichar -= 10; for (i=0; i<1000; i++) { *ichar-- = 0xfe; }}static voidtrash_stack(){ int i; char *ichar; trash_stack_b(i,ichar);}static voidclean_up(void){ MemoryGrp::set_default_memorygrp(0); MessageGrp::set_default_messagegrp(0); ThreadGrp::set_default_threadgrp(0); SCMatrixKit::set_default_matrixkit(0); Integral::set_default_integral(0); RegionTimer::set_default_regiontimer(0);}#include <signal.h>#ifdef HAVE_FENV_H# include <fenv.h>#endifinttry_main(int argc, char *argv[]){ //trash_stack(); KeyValValueboolean truevalue(1), falsevalue(0); int i; const char *devnull = "/dev/null"; atexit(clean_up);#ifdef HAVE_FEENABLEEXCEPT // this uses a glibc extension to trap on individual exceptions# ifdef FE_DIVBYZERO feenableexcept(FE_DIVBYZERO);# endif# ifdef FE_INVALID feenableexcept(FE_INVALID);# endif# ifdef FE_OVERFLOW feenableexcept(FE_OVERFLOW);# endif#endif#ifdef HAVE_FEDISABLEEXCEPT // this uses a glibc extension to not trap on individual exceptions# ifdef FE_UNDERFLOW fedisableexcept(FE_UNDERFLOW);# endif# ifdef FE_INEXACT fedisableexcept(FE_INEXACT);# endif#endif#if defined(HAVE_SETRLIMIT) struct rlimit rlim; rlim.rlim_cur = 0; rlim.rlim_max = 0; setrlimit(RLIMIT_CORE,&rlim);#endif ExEnv::init(argc, argv); Ref<MessageGrp> grp;#if defined(HAVE_MPI) && defined(ALWAYS_USE_MPI) grp = new MPIMessageGrp(&argc, &argv);#endif // parse commandline options GetLongOpt options; options.usage("[options] [filename]"); options.enroll("f", GetLongOpt::MandatoryValue, "the name of an object format input file", 0); options.enroll("o", GetLongOpt::MandatoryValue, "the name of the output file", 0); options.enroll("messagegrp", GetLongOpt::MandatoryValue, "which message group to use", 0); options.enroll("threadgrp", GetLongOpt::MandatoryValue, "which thread group to use", 0); options.enroll("memorygrp", GetLongOpt::MandatoryValue, "which memory group to use", 0); options.enroll("integral", GetLongOpt::MandatoryValue, "which integral evaluator to use", 0); options.enroll("l", GetLongOpt::MandatoryValue, "basis set limit", "0"); options.enroll("W", GetLongOpt::MandatoryValue, "set the working directory", "."); options.enroll("c", GetLongOpt::NoValue, "check input then exit", 0); options.enroll("v", GetLongOpt::NoValue, "print the version number", 0); options.enroll("w", GetLongOpt::NoValue, "print the warranty", 0); options.enroll("L", GetLongOpt::NoValue, "print the license", 0); options.enroll("k", GetLongOpt::NoValue, "print key/value assignments", 0); options.enroll("i", GetLongOpt::NoValue, "convert simple to OO input", 0); options.enroll("d", GetLongOpt::NoValue, "debug", 0); options.enroll("h", GetLongOpt::NoValue, "print this message", 0); int optind = options.parse(argc, argv); const char *output = options.retrieve("o"); ostream *outstream = 0; if (output != 0) { outstream = new ofstream(output); ExEnv::set_out(outstream); } if (options.retrieve("h")) { ExEnv::out0() << indent << "MPQC version " << SC_VERSION << endl << indent << "compiled for " << TARGET_ARCH << endl << SCFormIO::copyright << endl; options.usage(ExEnv::out0()); exit(0); } if (options.retrieve("v")) { ExEnv::out0() << indent << "MPQC version " << SC_VERSION << endl << indent << "compiled for " << TARGET_ARCH << endl << SCFormIO::copyright; exit(0); } if (options.retrieve("w")) { ExEnv::out0() << indent << "MPQC version " << SC_VERSION << endl << indent << "compiled for " << TARGET_ARCH << endl << SCFormIO::copyright << endl << SCFormIO::warranty; exit(0); } if (options.retrieve("L")) { ExEnv::out0() << indent << "MPQC version " << SC_VERSION << endl << indent << "compiled for " << TARGET_ARCH << endl << SCFormIO::copyright << endl << SCFormIO::license; exit(0); } // set the working dir if (strcmp(options.retrieve("W"),".")) chdir(options.retrieve("W")); // initialize keyval input const char *object_input = options.retrieve("f"); const char *generic_input; if (argc - optind == 0) { generic_input = 0; } else if (argc - optind == 1) { generic_input = argv[optind]; } else { options.usage(); throw invalid_argument("extra arguments given"); } // get the message group. first try the commandline and environment if (grp.null()) grp = MessageGrp::initial_messagegrp(argc, argv); if (grp.nonnull()) MessageGrp::set_default_messagegrp(grp); else grp = MessageGrp::get_default_messagegrp(); if (object_input == 0 && generic_input == 0) { generic_input = "mpqc.in"; } else if (object_input && generic_input) { options.usage(); throw invalid_argument("only one of -f and a file argument can be given"); } const char *input; if (object_input) input = object_input; if (generic_input) input = generic_input; Ref<ParsedKeyVal> parsedkv; // read the input file on only node 0 char *in_char_array; if (grp->me() == 0) { ifstream is(input);#ifdef HAVE_SSTREAM ostringstream ostrs; is >> ostrs.rdbuf(); int n = 1 + strlen(ostrs.str().c_str()); in_char_array = strcpy(new char[n],ostrs.str().c_str());#else ostrstream ostrs; is >> ostrs.rdbuf(); ostrs << ends; in_char_array = ostrs.str(); int n = ostrs.pcount();#endif grp->bcast(n); grp->bcast(in_char_array, n); } else { int n; grp->bcast(n); in_char_array = new char[n]; grp->bcast(in_char_array, n); } int use_simple_input; if (generic_input && grp->me() == 0) { MPQCIn mpqcin; use_simple_input = mpqcin.check_string(in_char_array); } else { use_simple_input = 0; } grp->bcast(use_simple_input); if (use_simple_input) { MPQCIn mpqcin; char *simple_input_text = mpqcin.parse_string(in_char_array); if (options.retrieve("i")) { ExEnv::out0() << "Generated object-oriented input file:" << endl << simple_input_text << endl; exit(0); } parsedkv = new ParsedKeyVal(); parsedkv->parse_string(simple_input_text); delete[] simple_input_text; } else { parsedkv = new ParsedKeyVal(); parsedkv->parse_string(in_char_array); } delete[] in_char_array; if (options.retrieve("k")) parsedkv->verbose(1); Ref<KeyVal> keyval = new PrefixKeyVal(parsedkv.pointer(),"mpqc"); // get the basename for output files int nfilebase = (int) (::strrchr(input, '.') - input); char *basename = new char[nfilebase + 1]; strncpy(basename, input, nfilebase); basename[nfilebase] = '\0'; SCFormIO::set_default_basename(basename); // set up output classes SCFormIO::setindent(ExEnv::outn(), 2); SCFormIO::setindent(ExEnv::errn(), 2); SCFormIO::setindent(cout, 2); SCFormIO::setindent(cerr, 2); SCFormIO::set_printnode(0); if (grp->n() > 1) SCFormIO::init_mp(grp->me()); if (options.retrieve("d")) SCFormIO::set_debug(1); // initialize timing for mpqc grp->sync(); // make sure nodes are sync'ed before starting timings Ref<RegionTimer> tim; if (keyval->exists("timer")) tim << keyval->describedclassvalue("timer"); else tim = new ParallelRegionTimer(grp,"mpqc",1,1); RegionTimer::set_default_regiontimer(tim); if (tim.nonnull()) tim->enter("input"); // announce ourselves const char title1[] = "MPQC: Massively Parallel Quantum Chemistry"; int ntitle1 = sizeof(title1); const char title2[] = "Version " SC_VERSION; int ntitle2 = sizeof(title2); ExEnv::out0() << endl; ExEnv::out0() << indent; for (i=0; i<(80-ntitle1)/2; i++) ExEnv::out0() << ' '; ExEnv::out0() << title1 << endl; ExEnv::out0() << indent; for (i=0; i<(80-ntitle2)/2; i++) ExEnv::out0() << ' '; ExEnv::out0() << title2 << endl << endl; const char *tstr = 0;#if defined(HAVE_TIME) && defined(HAVE_CTIME) time_t t; time(&t); tstr = ctime(&t);#endif if (!tstr) { tstr = "UNKNOWN"; } ExEnv::out0() << indent << scprintf("Machine: %s", TARGET_ARCH) << endl << indent << scprintf("User: %s@%s", ExEnv::username(), ExEnv::hostname()) << endl << indent << scprintf("Start Time: %s", tstr) << endl; // get the thread group. first try the commandline and environment Ref<ThreadGrp> thread = ThreadGrp::initial_threadgrp(argc, argv); // if we still don't have a group, try reading the thread group // from the input if (thread.null()) { thread << keyval->describedclassvalue("thread"); } if (thread.nonnull()) ThreadGrp::set_default_threadgrp(thread); else thread = ThreadGrp::get_default_threadgrp(); // get the memory group. first try the commandline and environment Ref<MemoryGrp> memory = MemoryGrp::initial_memorygrp(argc, argv); // if we still don't have a group, try reading the memory group // from the input if (memory.null()) { memory << keyval->describedclassvalue("memory"); } if (memory.nonnull()) MemoryGrp::set_default_memorygrp(memory); else memory = MemoryGrp::get_default_memorygrp(); ExEnv::out0() << indent << "Using " << grp->class_name() << " for message passing (number of nodes = " << grp->n() << ")." << endl << indent << "Using " << thread->class_name() << " for threading (number of threads = " << thread->nthread() << ")." << endl << indent << "Using " << memory->class_name() << " for distributed shared memory." << endl << indent << "Total number of processors = " << grp->n() * thread->nthread() << endl; // now set up the debugger Ref<Debugger> debugger; debugger << keyval->describedclassvalue("debug"); if (debugger.nonnull()) { Debugger::set_default_debugger(debugger);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -