summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Dreslinski <rdreslin@umich.edu>2005-02-17 12:14:04 -0500
committerRon Dreslinski <rdreslin@umich.edu>2005-02-17 12:14:04 -0500
commit45ef238e3f54bd7e2b602def187085bd0b99aab5 (patch)
treeea4057df1dac0768ebf36201468af632cdefedf1
parentb8d65408c810ba490243fc32c7d5e6817c32c70b (diff)
parentcfe6ed7c484b62d07bae23c528f0e2e568cf0d65 (diff)
downloadgem5-45ef238e3f54bd7e2b602def187085bd0b99aab5.tar.xz
Merge zizzer:/z/m5/Bitkeeper/m5
into zizzer.eecs.umich.edu:/.automount/zazzer/z/rdreslin/m5bk/timing_L1 --HG-- extra : convert_revision : 88afcacc41f5b0fae0ed1ac1821b7ca88c407e85
-rw-r--r--SConscript1
-rw-r--r--arch/alpha/alpha_memory.cc2
-rw-r--r--base/misc.cc5
-rw-r--r--base/output.cc129
-rw-r--r--base/output.hh61
-rw-r--r--base/statistics.cc7
-rw-r--r--base/statistics.hh2
-rw-r--r--base/stats/text.cc2
-rw-r--r--cpu/base_cpu.cc9
-rw-r--r--dev/etherdump.cc19
-rw-r--r--dev/etherdump.hh4
-rw-r--r--dev/simconsole.cc21
-rw-r--r--dev/tsunami_cchip.cc2
-rw-r--r--objects/Root.mpy10
-rw-r--r--sim/main.cc266
-rw-r--r--sim/param.cc5
-rw-r--r--sim/process.cc23
-rw-r--r--sim/process.hh2
-rw-r--r--sim/pyconfig/SConscript2
-rw-r--r--sim/pyconfig/m5config.py7
-rw-r--r--sim/serialize.cc7
-rw-r--r--sim/universe.cc98
-rw-r--r--test/genini.py17
-rwxr-xr-xutil/pbs/pbs.py134
-rwxr-xr-xutil/pbs/send.py46
25 files changed, 538 insertions, 343 deletions
diff --git a/SConscript b/SConscript
index 187edadff..19f84f913 100644
--- a/SConscript
+++ b/SConscript
@@ -63,6 +63,7 @@ base_sources = Split('''
base/intmath.cc
base/match.cc
base/misc.cc
+ base/output.cc
base/pollevent.cc
base/python.cc
base/range.cc
diff --git a/arch/alpha/alpha_memory.cc b/arch/alpha/alpha_memory.cc
index 81a1902a0..639abbeb8 100644
--- a/arch/alpha/alpha_memory.cc
+++ b/arch/alpha/alpha_memory.cc
@@ -501,6 +501,8 @@ AlphaDTB::translate(MemReqPtr &req, bool write) const
*/
if (req->vaddr & (req->size - 1)) {
fault(req, write ? MM_STAT_WR_MASK : 0);
+ DPRINTF(TLB, "Alignment Fault on %#x, size = %d", req->vaddr,
+ req->size);
return Alignment_Fault;
}
diff --git a/base/misc.cc b/base/misc.cc
index 0c459352f..4b7c3632a 100644
--- a/base/misc.cc
+++ b/base/misc.cc
@@ -30,10 +30,11 @@
#include <string>
#include "base/cprintf.hh"
-#include "sim/host.hh"
#include "base/hostinfo.hh"
#include "base/misc.hh"
+#include "base/output.hh"
#include "base/trace.hh"
+#include "sim/host.hh"
#include "sim/universe.hh"
using namespace std;
@@ -116,7 +117,7 @@ __warn(const string &format, cp::ArgList &args, const char *func,
#endif
args.dump(cerr, fmt);
- if (outputStream != &cerr && outputStream != &cout)
+ if (simout.isFile(*outputStream))
args.dump(*outputStream, fmt);
delete &args;
diff --git a/base/output.cc b/base/output.cc
new file mode 100644
index 000000000..2b1733f21
--- /dev/null
+++ b/base/output.cc
@@ -0,0 +1,129 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <fstream>
+
+#include "base/misc.hh"
+#include "base/output.hh"
+
+using namespace std;
+
+OutputDirectory simout;
+
+/**
+ *
+ */
+OutputDirectory::OutputDirectory()
+{}
+
+OutputDirectory::~OutputDirectory()
+{}
+
+void
+OutputDirectory::setDirectory(const string &d)
+{
+ if (!dir.empty())
+ panic("Output directory already set!\n");
+
+ dir = d;
+
+ if (dir != ".") {
+ if (mkdir(dir.c_str(), 0777) < 0 && errno != EEXIST)
+ panic("couldn't make output dir %s: %s\n",
+ dir, strerror(errno));
+ }
+
+ // guarantee that directory ends with a '/'
+ if (dir[dir.size() - 1] != '/')
+ dir += "/";
+}
+
+const string &
+OutputDirectory::directory()
+{
+ if (dir.empty())
+ panic("Output directory not set!");
+
+ return dir;
+}
+
+string
+OutputDirectory::resolve(const string &name)
+{
+ return (name[0] != '/') ? dir + name : name;
+}
+
+ostream *
+OutputDirectory::create(const string &name)
+{
+ if (name == "cerr" || name == "stderr")
+ return &cerr;
+
+ if (name == "cout" || name == "stdout")
+ return &cout;
+
+ ofstream *file = new ofstream(resolve(name).c_str(), ios::trunc);
+ if (!file->is_open())
+ panic("Cannot open file %s", name);
+
+ return file;
+}
+
+ostream *
+OutputDirectory::find(const string &name)
+{
+ if (name == "cerr" || name == "stderr")
+ return &cerr;
+
+ if (name == "cout" || name == "stdout")
+ return &cout;
+
+ string filename = resolve(name);
+ map_t::iterator i = files.find(filename);
+ if (i != files.end())
+ return (*i).second;
+
+ ofstream *file = new ofstream(filename.c_str(), ios::trunc);
+ if (!file->is_open())
+ panic("Cannot open file %s", filename);
+
+ files[filename] = file;
+ return file;
+}
+
+bool
+OutputDirectory::isFile(const std::ostream *os)
+{
+ return os && os != &cerr && os != &cout;
+}
diff --git a/base/output.hh b/base/output.hh
new file mode 100644
index 000000000..3bbe73e3b
--- /dev/null
+++ b/base/output.hh
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2005 The Regents of The University of Michigan
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met: redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer;
+ * redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution;
+ * neither the name of the copyright holders nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef __BASE_OUTPUT_HH__
+#define __BASE_OUTPUT_HH__
+
+#include <iosfwd>
+#include <map>
+#include <string>
+
+class OutputDirectory
+{
+ private:
+ typedef std::map<std::string, std::ostream *> map_t;
+
+ map_t files;
+ std::string dir;
+
+ public:
+ OutputDirectory();
+ ~OutputDirectory();
+
+ void setDirectory(const std::string &dir);
+ const std::string &directory();
+
+ std::string resolve(const std::string &name);
+ std::ostream *create(const std::string &name);
+ std::ostream *find(const std::string &name);
+
+ static bool isFile(const std::ostream *os);
+ static inline bool isFile(const std::ostream &os) { return isFile(&os); }
+};
+
+extern OutputDirectory simout;
+
+#endif // __BASE_OUTPUT_HH__
diff --git a/base/statistics.cc b/base/statistics.cc
index 6e3dae1ef..6f5caf1fe 100644
--- a/base/statistics.cc
+++ b/base/statistics.cc
@@ -286,6 +286,13 @@ check()
Database::stats().sort(StatData::less);
+#if defined(STATS_BINNING)
+ if (MainBin::curBin() == NULL) {
+ static MainBin mainBin("main bin");
+ mainBin.activate();
+ }
+#endif
+
if (i == end)
return;
diff --git a/base/statistics.hh b/base/statistics.hh
index 9ec26eb4d..667a0ed48 100644
--- a/base/statistics.hh
+++ b/base/statistics.hh
@@ -2184,7 +2184,7 @@ class SumNode : public Node
* binned. If the typedef is NoBin, nothing is binned. If it is
* MainBin, then all stats are binned under that Bin.
*/
-#if defined(FS_MEASURE) || defined(STATS_BINNING)
+#if defined(STATS_BINNING)
typedef MainBin DefaultBin;
#else
typedef NoBin DefaultBin;
diff --git a/base/stats/text.cc b/base/stats/text.cc
index f7e82a30f..8cc5ff65e 100644
--- a/base/stats/text.cc
+++ b/base/stats/text.cc
@@ -126,7 +126,7 @@ Text::output()
using namespace Database;
ccprintf(*stream, "\n---------- Begin Simulation Statistics ----------\n");
- if (bins().empty()) {
+ if (bins().empty() || bins().size() == 1) {
stat_list_t::const_iterator i, end = stats().end();
for (i = stats().begin(); i != end; ++i)
(*i)->visit(*this);
diff --git a/cpu/base_cpu.cc b/cpu/base_cpu.cc
index 4325bfc17..59804c7d5 100644
--- a/cpu/base_cpu.cc
+++ b/cpu/base_cpu.cc
@@ -26,13 +26,14 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include <iostream>
#include <string>
#include <sstream>
-#include <iostream>
#include "base/cprintf.hh"
#include "base/loader/symtab.hh"
#include "base/misc.hh"
+#include "base/output.hh"
#include "cpu/base_cpu.hh"
#include "cpu/exec_context.hh"
#include "cpu/sampling_cpu/sampling_cpu.hh"
@@ -133,8 +134,7 @@ BaseCPU::BaseCPU(const string &_name, int _number_of_threads, bool _def_reg,
functionTracingEnabled = false;
if (_function_trace) {
- std::string filename = csprintf("ftrace.%s", name());
- functionTraceStream = makeOutputStream(filename);
+ functionTraceStream = simout.find(csprintf("ftrace.%s", name()));
currentFunctionStart = currentFunctionEnd = 0;
functionEntryTick = _function_trace_start;
@@ -158,11 +158,8 @@ BaseCPU::enableFunctionTrace()
BaseCPU::~BaseCPU()
{
- if (functionTracingEnabled)
- closeOutputStream(functionTraceStream);
}
-
void
BaseCPU::init()
{
diff --git a/dev/etherdump.cc b/dev/etherdump.cc
index 485d5599c..3de417bdc 100644
--- a/dev/etherdump.cc
+++ b/dev/etherdump.cc
@@ -36,14 +36,15 @@
#include <string>
#include "base/misc.hh"
+#include "base/output.hh"
#include "dev/etherdump.hh"
#include "sim/builder.hh"
#include "sim/universe.hh"
using std::string;
-EtherDump::EtherDump(const string &name, std::ostream *_stream, int max)
- : SimObject(name), stream(_stream), maxlen(max)
+EtherDump::EtherDump(const string &name, const string &file, int max)
+ : SimObject(name), stream(file.c_str()), maxlen(max)
{
}
@@ -86,7 +87,7 @@ EtherDump::init()
hdr.sigfigs = 0;
hdr.linktype = DLT_EN10MB;
- stream->write(reinterpret_cast<char *>(&hdr), sizeof(hdr));
+ stream.write(reinterpret_cast<char *>(&hdr), sizeof(hdr));
/*
* output an empty packet with the current time so that we know
@@ -98,9 +99,9 @@ EtherDump::init()
pkthdr.microseconds = 0;
pkthdr.caplen = 0;
pkthdr.len = 0;
- stream->write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
+ stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
- stream->flush();
+ stream.flush();
}
void
@@ -111,9 +112,9 @@ EtherDump::dumpPacket(PacketPtr &packet)
pkthdr.microseconds = (curTick / us_freq) % ULL(1000000);
pkthdr.caplen = std::min(packet->length, maxlen);
pkthdr.len = packet->length;
- stream->write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
- stream->write(reinterpret_cast<char *>(packet->data), pkthdr.caplen);
- stream->flush();
+ stream.write(reinterpret_cast<char *>(&pkthdr), sizeof(pkthdr));
+ stream.write(reinterpret_cast<char *>(packet->data), pkthdr.caplen);
+ stream.flush();
}
BEGIN_DECLARE_SIM_OBJECT_PARAMS(EtherDump)
@@ -132,7 +133,7 @@ END_INIT_SIM_OBJECT_PARAMS(EtherDump)
CREATE_SIM_OBJECT(EtherDump)
{
- return new EtherDump(getInstanceName(), makeOutputStream(file), maxlen);
+ return new EtherDump(getInstanceName(), simout.resolve(file), maxlen);
}
REGISTER_SIM_OBJECT("EtherDump", EtherDump)
diff --git a/dev/etherdump.hh b/dev/etherdump.hh
index b127d05e2..ba15796c8 100644
--- a/dev/etherdump.hh
+++ b/dev/etherdump.hh
@@ -43,7 +43,7 @@
class EtherDump : public SimObject
{
private:
- std::ostream *stream;
+ std::ofstream stream;
const int maxlen;
void dumpPacket(PacketPtr &packet);
void init();
@@ -53,7 +53,7 @@ class EtherDump : public SimObject
Tick us_freq;
public:
- EtherDump(const std::string &name, std::ostream *_stream, int max);
+ EtherDump(const std::string &name, const std::string &file, int max);
inline void dump(PacketPtr &pkt) { dumpPacket(pkt); }
};
diff --git a/dev/simconsole.cc b/dev/simconsole.cc
index 48e5d0201..94fd9ec1f 100644
--- a/dev/simconsole.cc
+++ b/dev/simconsole.cc
@@ -43,6 +43,7 @@
#include <string>
#include "base/misc.hh"
+#include "base/output.hh"
#include "base/socket.hh"
#include "base/trace.hh"
#include "dev/platform.hh"
@@ -71,7 +72,7 @@ SimConsole::Event::process(int revent)
cons->detach();
}
-SimConsole::SimConsole(const string &name, std::ostream *os, int num)
+SimConsole::SimConsole(const string &name, ostream *os, int num)
: SimObject(name), event(NULL), number(num), in_fd(-1), out_fd(-1),
listener(NULL), txbuf(16384), rxbuf(16384), outfile(os)
#if TRACING_ON == 1
@@ -85,8 +86,6 @@ SimConsole::SimConsole(const string &name, std::ostream *os, int num)
SimConsole::~SimConsole()
{
close();
- if (outfile)
- closeOutputStream(outfile);
}
void
@@ -313,18 +312,16 @@ END_INIT_SIM_OBJECT_PARAMS(SimConsole)
CREATE_SIM_OBJECT(SimConsole)
{
- string filename;
+ string filename = output;
+ ostream *stream = NULL;
- if (filename.empty()) {
- filename = getInstanceName();
- } else if (append_name) {
- filename = (string)output + "." + getInstanceName();
- } else {
- filename = output;
+ if (!filename.empty()) {
+ if (append_name)
+ filename += "." + getInstanceName();
+ stream = simout.find(filename);
}
- SimConsole *console = new SimConsole(getInstanceName(),
- makeOutputStream(filename), number);
+ SimConsole *console = new SimConsole(getInstanceName(), stream, number);
((ConsoleListener *)listener)->add(console);
return console;
diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc
index 6bf4d8b57..2fb293fbf 100644
--- a/dev/tsunami_cchip.cc
+++ b/dev/tsunami_cchip.cc
@@ -176,7 +176,7 @@ TsunamiCChip::read(MemReqPtr &req, uint8_t *data)
if (regnum == TSDEV_CC_DRIR) {
warn("accessing DRIR with 32 bit read, "
"hopefully your just reading this for timing");
- *(uint64_t*)data = drir;
+ *(uint32_t*)data = drir;
} else
panic("invalid access size(?) for tsunami register!\n");
return No_Fault;
diff --git a/objects/Root.mpy b/objects/Root.mpy
index b21396e36..0e531054b 100644
--- a/objects/Root.mpy
+++ b/objects/Root.mpy
@@ -1,11 +1,15 @@
from HierParams import HierParams
+from Serialize import Serialize
+from Statistics import Statistics
+from Trace import Trace
+
simobj Root(SimObject):
type = 'Root'
frequency = Param.Tick(200000000, "tick frequency")
- output_dir = Param.String('.', "directory to output data to")
output_file = Param.String('cout', "file to dump simulator output to")
- config_output_file = Param.String('m5config.out',
- "file to dump simulator config to")
full_system = Param.Bool("Full system simulation?")
hier = HierParams(do_data = False, do_events = True)
checkpoint = Param.String('', "Checkpoint file")
+ stats = Statistics()
+ trace = Trace()
+ serialize = Serialize()
diff --git a/sim/main.cc b/sim/main.cc
index 163c835ee..891931c2b 100644
--- a/sim/main.cc
+++ b/sim/main.cc
@@ -31,6 +31,7 @@
///
#include <sys/types.h>
#include <sys/stat.h>
+#include <libgen.h>
#include <stdlib.h>
#include <signal.h>
@@ -42,6 +43,7 @@
#include "base/embedfile.hh"
#include "base/inifile.hh"
#include "base/misc.hh"
+#include "base/output.hh"
#include "base/pollevent.hh"
#include "base/statistics.hh"
#include "base/str.hh"
@@ -106,28 +108,35 @@ abortHandler(int sigtype)
}
/// Simulator executable name
-const char *myProgName = "";
+char *myProgName = "";
/// Show brief help message.
-static void
+void
showBriefHelp(ostream &out)
{
- out << "Usage: " << myProgName
- << " [-hnu] [-Dname[=def]] [-Uname] [-I[dir]] "
- << "<config-spec> [<config-spec> ...]\n"
- << "[] [<config file> ...]\n"
- << " -h: print long help (including parameter listing)\n"
- << " -u: don't quit on unreferenced parameters\n"
- << " -D,-U,-I: passed to cpp for preprocessing .ini files\n"
- << " <config-spec>: config file name (.ini or .py) or\n"
- << " single param (--<section>:<param>=<value>)"
- << endl;
+ char *prog = basename(myProgName);
+
+ ccprintf(out, "Usage:\n");
+ ccprintf(out,
+"%s [-d <dir>] [-E <var>[=<val>]] [-I <dir>] [-P <python>]\n"
+" [--<var>=<val>] <config file>\n"
+"\n"
+" -d set the output directory to <dir>\n"
+" -E set the environment variable <var> to <val> (or 'True')\n"
+" -I add the directory <dir> to python's path\n"
+" -P execute <python> directly in the configuration\n"
+" --var=val set the python variable <var> to '<val>'\n"
+" <configfile> config file name (.py or .mpy)\n",
+ prog);
+
+ ccprintf(out, "%s -X\n -X extract embedded files\n", prog);
+ ccprintf(out, "%s -h\n -h print long help\n", prog);
}
/// Show verbose help message. Includes parameter listing from
/// showBriefHelp(), plus an exhaustive list of ini-file parameters
/// and SimObjects (with their parameters).
-static void
+void
showLongHelp(ostream &out)
{
showBriefHelp(out);
@@ -152,7 +161,7 @@ showLongHelp(ostream &out)
}
/// Print welcome message.
-static void
+void
sayHello(ostream &out)
{
extern const char *compileDate; // from date.cc
@@ -176,7 +185,7 @@ sayHello(ostream &out)
/// Echo the command line for posterity in such a way that it can be
/// used to rerun the same simulation (given the same .ini files).
///
-static void
+void
echoCommandLine(int argc, char **argv, ostream &out)
{
out << "command line: " << argv[0];
@@ -208,16 +217,20 @@ echoCommandLine(int argc, char **argv, ostream &out)
out << endl << endl;
}
+char *
+getOptionString(int &index, int argc, char **argv)
+{
+ char *option = argv[index] + 2;
+ if (*option != '\0')
+ return option;
-///
-/// The simulator configuration database. This is the union of all
-/// specified .ini files. This shouldn't need to be visible outside
-/// this file, as it is passed as a parameter to all the param-parsing
-/// routines.
-///
-static IniFile simConfigDB;
+ // We didn't find an argument, it must be in the next variable.
+ if (++index >= argc)
+ panic("option string for option '%s' not found", argv[index - 1]);
+
+ return argv[index];
+}
-/// M5 entry point.
int
main(int argc, char **argv)
{
@@ -233,18 +246,9 @@ main(int argc, char **argv)
sayHello(cerr);
- // Initialize statistics database
- Stats::InitSimStats();
-
- vector<char *> cppArgs;
-
- // Should we quit if there are unreferenced parameters? By
- // default, yes... it's a good way of catching typos in
- // section/parameter names (which otherwise go by silently). Use
- // -u to override.
- bool quitOnUnreferenced = true;
-
- bool python_initialized = false;
+ bool configfile_found = false;
+ PythonConfig pyconfig;
+ string outdir;
// Parse command-line options.
// Since most of the complex options are handled through the
@@ -253,12 +257,53 @@ main(int argc, char **argv)
for (int i = 1; i < argc; ++i) {
char *arg_str = argv[i];
- // if arg starts with '-', parse as option,
- // else treat it as a configuration file name and load it
- if (arg_str[0] == '-') {
+ // if arg starts with '--', parse as a special python option
+ // of the format --<python var>=<string value>, if the arg
+ // starts with '-', it should be a simulator option with a
+ // format similar to getopt. In any other case, treat the
+ // option as a configuration file name and load it.
+ if (arg_str[0] == '-' && arg_str[1] == '-') {
+ string str = &arg_str[2];
+ string var, val;
+
+ if (!split_first(str, var, val, '='))
+ panic("Could not parse configuration argument '%s'\n"
+ "Expecting --<variable>=<value>\n", arg_str);
+
+ pyconfig.setVariable(var, val);
+ } else if (arg_str[0] == '-') {
+ char *option;
+ string var, val;
// switch on second char
switch (arg_str[1]) {
+ case 'd':
+ outdir = getOptionString(i, argc, argv);
+ break;
+
+ case 'h':
+ showLongHelp(cerr);
+ exit(1);
+
+ case 'E':
+ option = getOptionString(i, argc, argv);
+ if (!split_first(option, var, val, '='))
+ val = "True";
+
+ if (setenv(var.c_str(), val.c_str(), true) == -1)
+ panic("setenv: %s\n", strerror(errno));
+ break;
+
+ case 'I':
+ option = getOptionString(i, argc, argv);
+ pyconfig.addPath(option);
+ break;
+
+ case 'P':
+ option = getOptionString(i, argc, argv);
+ pyconfig.writeLine(option);
+ break;
+
case 'X': {
list<EmbedFile> lst;
EmbedMap::all(lst);
@@ -274,124 +319,58 @@ main(int argc, char **argv)
return 0;
}
- case 'h':
- // -h: show help
- showLongHelp(cerr);
- exit(1);
-
- case 'u':
- // -u: don't quit on unreferenced parameters
- quitOnUnreferenced = false;
- break;
-
- case 'D':
- case 'U':
- // cpp options: record & pass to cpp. Note that these
- // cannot have spaces, i.e., '-Dname=val' is OK, but
- // '-D name=val' is not. I don't consider this a
- // problem, since even though gnu cpp accepts the
- // latter, other cpp implementations do not (Tru64,
- // for one).
- cppArgs.push_back(arg_str);
- break;
-
- case 'I': {
- // We push -I as an argument to cpp
- cppArgs.push_back(arg_str);
-
- string arg = arg_str + 2;
- eat_white(arg);
-
- // Send this as the python path
- addPythonPath(arg);
- } break;
-
- case 'P':
- if (!python_initialized) {
- initPythonConfig();
- python_initialized = true;
- }
- writePythonString(arg_str + 2);
- writePythonString("\n");
-
- case 'E':
- if (putenv(arg_str + 2) == -1)
- panic("putenv: %s\n", strerror(errno));
- break;
-
- case '-':
- // command-line configuration parameter:
- // '--<section>:<parameter>=<value>'
- if (!simConfigDB.add(arg_str + 2)) {
- // parse error
- ccprintf(cerr,
- "Could not parse configuration argument '%s'\n"
- "Expecting --<section>:<parameter>=<value>\n",
- arg_str);
- exit(0);
- }
- break;
-
default:
showBriefHelp(cerr);
- ccprintf(cerr, "Fatal: invalid argument '%s'\n", arg_str);
- exit(0);
- }
- }
- else {
- // no '-', treat as config file name
-
- // make STL string out of file name
- string filename(arg_str);
-
- int ext_loc = filename.rfind(".");
-
- string ext =
- (ext_loc != string::npos) ? filename.substr(ext_loc) : "";
-
- if (ext == ".ini") {
- if (!simConfigDB.loadCPP(filename, cppArgs)) {
- cprintf("Error processing file %s\n", filename);
- exit(1);
- }
- } else if (ext == ".py" || ext == ".mpy") {
- if (!python_initialized) {
- initPythonConfig();
- python_initialized = true;
- }
- loadPythonConfig(filename);
- }
- else {
- cprintf("Config file name '%s' must end in '.py' or '.ini'.\n",
- filename);
- exit(1);
+ panic("invalid argument '%s'\n", arg_str);
}
+ } else {
+ string file(arg_str);
+ string base, ext;
+
+ if (!split_last(file, base, ext, '.') ||
+ ext != "py" && ext != "mpy")
+ panic("Config file '%s' must end in '.py' or '.mpy'\n", file);
+
+ pyconfig.load(file);
+ configfile_found = true;
}
}
- if (python_initialized && !finishPythonConfig(simConfigDB)) {
- cprintf("Error processing python code\n");
- exit(1);
+ if (outdir.empty()) {
+ char *env = getenv("OUTPUT_DIR");
+ outdir = env ? env : ".";
}
- // The configuration database is now complete; start processing it.
+ simout.setDirectory(outdir);
- // Parse and check all non-config-hierarchy parameters.
- ParamContext::parseAllContexts(simConfigDB);
- ParamContext::checkAllContexts();
+ char *env = getenv("CONFIG_OUTPUT");
+ if (!env)
+ env = "config.out";
+ configStream = simout.find(env);
- // Print header info into stats file. Can't do this sooner since
- // the stat file name is set via a .ini param... thus it just got
- // opened above during ParamContext::checkAllContexts().
+ if (!configfile_found)
+ panic("no configuration file specified!");
+
+ // The configuration database is now complete; start processing it.
+ IniFile inifile;
+ if (!pyconfig.output(inifile))
+ panic("Error processing python code");
+
+ // Initialize statistics database
+ Stats::InitSimStats();
// Now process the configuration hierarchy and create the SimObjects.
- ConfigHierarchy configHierarchy(simConfigDB);
+ ConfigHierarchy configHierarchy(inifile);
configHierarchy.build();
configHierarchy.createSimObjects();
+ // Parse and check all non-config-hierarchy parameters.
+ ParamContext::parseAllContexts(inifile);
+ ParamContext::checkAllContexts();
+
// Print hello message to stats file if it's actually a file. If
// it's not (i.e. it's cout or cerr) then we already did it above.
- if (outputStream != &cout && outputStream != &cerr)
+ if (simout.isFile(*outputStream))
sayHello(*outputStream);
// Echo command line and all parameter settings to stats file as well.
@@ -406,13 +385,8 @@ main(int argc, char **argv)
// Done processing the configuration database.
// Check for unreferenced entries.
- if (simConfigDB.printUnreferenced() && quitOnUnreferenced) {
- cerr << "Fatal: unreferenced .ini sections/entries." << endl
- << "If this is not an error, add 'unref_section_ok=y' or "
- << "'unref_entries_ok=y' to the appropriate sections "
- << "to suppress this message." << endl;
- exit(1);
- }
+ if (inifile.printUnreferenced())
+ panic("unreferenced sections/entries in the intermediate ini file");
SimObject::regAllStats();
diff --git a/sim/param.cc b/sim/param.cc
index d16578a2d..ff023ce85 100644
--- a/sim/param.cc
+++ b/sim/param.cc
@@ -441,6 +441,11 @@ EnumVectorParam<Map>::parse(const string &s)
{
vector<string> tokens;
+ if (s.empty()) {
+ wasSet = true;
+ return;
+ }
+
tokenize(tokens, s, ' ');
value.resize(tokens.size());
diff --git a/sim/process.cc b/sim/process.cc
index c725d3b1c..4d860c51d 100644
--- a/sim/process.cc
+++ b/sim/process.cc
@@ -88,8 +88,6 @@ Process::Process(const string &name,
fd_map[i] = -1;
}
- num_syscalls = 0;
-
// other parameters will be initialized when the program is loaded
}
@@ -145,21 +143,28 @@ Process::registerExecContext(ExecContext *xc)
execContexts.push_back(xc);
if (myIndex == 0) {
- // first exec context for this process... initialize & enable
-
// copy process's initial regs struct
xc->regs = *init_regs;
-
- // mark this context as active.
- // activate with zero delay so that we start ticking right
- // away on cycle 0
- xc->activate(0);
}
// return CPU number to caller and increment available CPU count
return myIndex;
}
+void
+Process::startup()
+{
+ if (execContexts.empty())
+ return;
+
+ // first exec context for this process... initialize & enable
+ ExecContext *xc = execContexts[0];
+
+ // mark this context as active.
+ // activate with zero delay so that we start ticking right
+ // away on cycle 0
+ xc->activate(0);
+}
void
Process::replaceExecContext(ExecContext *xc, int xcIndex)
diff --git a/sim/process.hh b/sim/process.hh
index bb4829875..817ab656c 100644
--- a/sim/process.hh
+++ b/sim/process.hh
@@ -108,6 +108,8 @@ class Process : public SimObject
int stdout_fd,
int stderr_fd);
+ // post initialization startup
+ virtual void startup();
protected:
FunctionalMemory *memory;
diff --git a/sim/pyconfig/SConscript b/sim/pyconfig/SConscript
index 5708ac9a8..9154d3b99 100644
--- a/sim/pyconfig/SConscript
+++ b/sim/pyconfig/SConscript
@@ -170,7 +170,7 @@ EmbedMap %(name)s("%(fname)s",
/* namespace */ }
'''
-embedded_py_files = ['m5config.py']
+embedded_py_files = ['m5config.py', '../../util/pbs/jobfile.py']
objpath = os.path.join(env['SRCDIR'], 'objects')
for root, dirs, files in os.walk(objpath, topdown=True):
for i,dir in enumerate(dirs):
diff --git a/sim/pyconfig/m5config.py b/sim/pyconfig/m5config.py
index bbd437b30..9a48e2fa4 100644
--- a/sim/pyconfig/m5config.py
+++ b/sim/pyconfig/m5config.py
@@ -350,6 +350,13 @@ class MetaConfigNode(type):
for p,v in c._values.iteritems():
if not values.has_key(p):
values[p] = v
+ for p,v in c._params.iteritems():
+ if not values.has_key(p) and hasattr(v, 'default'):
+ v.valid(v.default)
+ v = v.default
+ cls._setvalue(p, v)
+ values[p] = v
+
return values
def _getvalue(cls, name, default = AttributeError):
diff --git a/sim/serialize.cc b/sim/serialize.cc
index 3a073f68d..846d191e0 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -38,6 +38,7 @@
#include "base/inifile.hh"
#include "base/misc.hh"
+#include "base/output.hh"
#include "base/str.hh"
#include "base/trace.hh"
#include "sim/config_node.hh"
@@ -333,11 +334,7 @@ SerializeParamContext::~SerializeParamContext()
void
SerializeParamContext::checkParams()
{
- if (serialize_dir.isValid()) {
- checkpointDirBase = serialize_dir;
- } else {
- checkpointDirBase = outputDirectory + "cpt.%012d";
- }
+ checkpointDirBase = simout.resolve(serialize_dir);
// guarantee that directory ends with a '/'
if (checkpointDirBase[checkpointDirBase.size() - 1] != '/')
diff --git a/sim/universe.cc b/sim/universe.cc
index 115f6f790..9137baaf0 100644
--- a/sim/universe.cc
+++ b/sim/universe.cc
@@ -26,10 +26,6 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <errno.h>
-
#include <cstring>
#include <fstream>
#include <list>
@@ -37,6 +33,7 @@
#include <vector>
#include "base/misc.hh"
+#include "base/output.hh"
#include "sim/builder.hh"
#include "sim/host.hh"
#include "sim/sim_object.hh"
@@ -51,7 +48,7 @@ double __ticksPerUS;
double __ticksPerNS;
double __ticksPerPS;
-string outputDirectory;
+bool fullSystem;
ostream *outputStream;
ostream *configStream;
@@ -61,81 +58,40 @@ class Root : public SimObject
public:
Root(const std::string &name) : SimObject(name) {}
};
-Root *root = NULL;
-
-std::ostream *
-makeOutputStream(std::string &name)
-{
- if (name == "cerr" || name == "stderr")
- return &std::cerr;
-
- if (name == "cout" || name == "stdout")
- return &std::cout;
-
- string path = (name[0] != '/') ? outputDirectory + name : name;
-
- // have to dynamically allocate a stream since we're going to
- // return it... though the caller can't easily free it since it
- // may be cerr or cout. need GC!
- ofstream *s = new ofstream(path.c_str(), ios::trunc);
-
- if (!s->is_open())
- fatal("Cannot open file %s", path);
-
- return s;
-}
-
-
-void
-closeOutputStream(std::ostream *os)
-{
- // can't close cerr or cout
- if (os == &std::cerr || os == &std::cout)
- return;
-
- // can only close ofstreams, not generic ostreams, so try to
- // downcast and close only if the downcast succeeds
- std::ofstream *ofs = dynamic_cast<std::ofstream *>(os);
- if (ofs)
- ofs->close();
-}
-
BEGIN_DECLARE_SIM_OBJECT_PARAMS(Root)
Param<bool> full_system;
Param<Tick> frequency;
- Param<string> output_dir;
Param<string> output_file;
- Param<string> config_output_file;
END_DECLARE_SIM_OBJECT_PARAMS(Root)
BEGIN_INIT_SIM_OBJECT_PARAMS(Root)
- INIT_PARAM_DFLT(full_system, "full system simulation", true),
- INIT_PARAM_DFLT(frequency, "tick frequency", 200000000),
- INIT_PARAM_DFLT(output_dir, "directory to output data to", "."),
- INIT_PARAM_DFLT(output_file, "file to dump simulator output to", "cout"),
- INIT_PARAM_DFLT(config_output_file, "file to dump simulator config to",
- "m5config.out")
+ INIT_PARAM(full_system, "full system simulation"),
+ INIT_PARAM(frequency, "tick frequency"),
+ INIT_PARAM(output_file, "file to dump simulator output to")
END_INIT_SIM_OBJECT_PARAMS(Root)
CREATE_SIM_OBJECT(Root)
{
+ static bool created = false;
+ if (created)
+ panic("only one root object allowed!");
+
+ created = true;
+ fullSystem = full_system;
+
#ifdef FULL_SYSTEM
- if (!bool(full_system))
+ if (!fullSystem)
panic("FULL_SYSTEM compiled and configuration not full_system");
#else
- if (bool(full_system))
+ if (fullSystem)
panic("FULL_SYSTEM not compiled but configuration is full_system");
#endif
- if (root)
- panic("only one root object allowed!");
- root = new Root(getInstanceName());
-
ticksPerSecond = frequency;
double freq = double(ticksPerSecond);
__ticksPerMS = freq / 1.0e3;
@@ -143,29 +99,9 @@ CREATE_SIM_OBJECT(Root)
__ticksPerNS = freq / 1.0e9;
__ticksPerPS = freq / 1.0e12;
- outputDirectory = output_dir;
- if (!outputDirectory.empty()) {
- outputDirectory = output_dir;
-
- // guarantee that directory ends with a '/'
- if (outputDirectory[outputDirectory.size() - 1] != '/')
- outputDirectory += "/";
-
- if (mkdir(outputDirectory.c_str(), 0777) < 0) {
- if (errno != EEXIST) {
- panic("%s\ncould not make output directory: %s\n",
- strerror(errno), outputDirectory);
- }
- }
- }
-
- outputStream = makeOutputStream(output_file);
- configStream = outputStream;
- string cof = config_output_file;
- if (!cof.empty())
- configStream = makeOutputStream(cof);
-
- return root;
+ outputStream = simout.find(output_file);
+
+ return new Root(getInstanceName());
}
REGISTER_SIM_OBJECT("Root", Root)
diff --git a/test/genini.py b/test/genini.py
index 0dac0d409..73e7012f6 100644
--- a/test/genini.py
+++ b/test/genini.py
@@ -31,23 +31,26 @@ from os.path import join as joinpath, realpath
mypath = sys.path[0]
sys.path.append(joinpath(mypath, '..'))
sys.path.append(joinpath(mypath, '../configs/kernel'))
+sys.path.append(joinpath(mypath, '../util/pbs'))
sys.path.append(joinpath(mypath, '../sim/pyconfig'))
from importer import mpy_exec, mpy_execfile, AddToPath
from m5config import *
try:
- opts, args = getopt.getopt(sys.argv[1:], '-E:')
- for o,a in opts:
- if o == '-E':
- offset = a.find('=')
+ opts, args = getopt.getopt(sys.argv[1:], '-E:I:')
+ for opt,arg in opts:
+ if opt == '-E':
+ offset = arg.find('=')
if offset == -1:
- name = a
+ name = arg
value = True
else:
- name = a[:offset]
- value = a[offset+1:]
+ name = arg[:offset]
+ value = arg[offset+1:]
env[name] = value
+ if opt == '-I':
+ AddToPath(arg)
except getopt.GetoptError:
sys.exit('Improper Usage')
diff --git a/util/pbs/pbs.py b/util/pbs/pbs.py
index a71dbbf8e..ecacbeba2 100755
--- a/util/pbs/pbs.py
+++ b/util/pbs/pbs.py
@@ -26,18 +26,68 @@
#
# Authors: Nathan Binkert
-import os, re, sys
+import os, popen2, re, sys
-def ssh(host, script, tty = False, user = ''):
- args = [ 'ssh', '-x' ]
- if user:
- args.append('-l' + user)
- if tty:
- args.append('-t')
- args.append(host)
- args.append(script)
+class MyPOpen(object):
+ def __init__(self, cmd, input = None, output = None, bufsize = -1):
+ self.status = -1
- return os.spawnvp(os.P_WAIT, args[0], args)
+ if input is None:
+ p2c_read, p2c_write = os.pipe()
+ self.tochild = os.fdopen(p2c_write, 'w', bufsize)
+ else:
+ p2c_write = None
+ if isinstance(input, file):
+ p2c_read = input.fileno()
+ elif isinstance(input, str):
+ input = file(input, 'r')
+ p2c_read = input.fileno()
+ elif isinstance(input, int):
+ p2c_read = input
+ else:
+ raise AttributeError
+
+ if output is None:
+ c2p_read, c2p_write = os.pipe()
+ self.fromchild = os.fdopen(c2p_read, 'r', bufsize)
+ else:
+ c2p_read = None
+ if isinstance(output, file):
+ c2p_write = output.fileno()
+ elif isinstance(output, str):
+ output = file(output, 'w')
+ c2p_write = output.fileno()
+ elif isinstance(output, int):
+ c2p_write = output
+ else:
+ raise AttributeError
+
+ self.pid = os.fork()
+ if self.pid == 0:
+ os.dup2(p2c_read, sys.stdin.fileno())
+ os.dup2(c2p_write, sys.stdout.fileno())
+ os.dup2(c2p_write, sys.stderr.fileno())
+ try:
+ os.execvp(cmd[0], cmd)
+ finally:
+ os._exit(1)
+
+ os.close(p2c_read)
+ os.close(c2p_write)
+
+ def poll(self):
+ if self.status < 0:
+ pid, status = os.waitpid(self.pid, os.WNOHANG)
+ if pid == self.pid:
+ self.status = status
+ return self.status
+
+ def wait(self):
+ if self.status < 0:
+ pid, status = os.waitpid(self.pid, 0)
+ if pid == self.pid:
+ self.status = status
+ return self.status
class qsub:
def __init__(self):
@@ -56,37 +106,35 @@ class qsub:
self.pbshost = ''
self.qsub = 'qsub'
self.env = {}
- self.onlyecho = False
- self.verbose = False
- def do(self, script, ):
- args = [self.qsub]
+ def build(self, script, args = []):
+ self.cmd = [ self.qsub ]
if self.env:
arg = '-v'
arg += ','.join([ '%s=%s' % i for i in self.env.iteritems() ])
- args.append(arg)
+ self.cmd.append(arg)
if self.hold:
- args.append('-h')
+ self.cmd.append('-h')
if len(self.stdout):
- args.append('-olocalhost:' + self.stdout)
+ self.cmd.append('-olocalhost:' + self.stdout)
if self.keep_stdout and self.keep_stderr:
- args.append('-koe')
+ self.cmd.append('-koe')
elif self.keep_stdout:
- args.append('-ko')
+ self.cmd.append('-ko')
elif self.keep_stderr:
- args.append('-ke')
+ self.cmd.append('-ke')
else:
- args.append('-kn')
+ self.cmd.append('-kn')
if self.join:
- args.append('-joe')
+ self.cmd.append('-joe')
if len(self.node_type):
- args.append('-lnodes=' + self.node_type)
+ self.cmd.append('-lnodes=' + self.node_type)
if self.mail_abort or self.mail_begin or self.mail_end:
flags = ''
@@ -97,30 +145,32 @@ class qsub:
if self.mail_end:
flags.append('e')
if len(flags):
- args.append('-m ' + flags)
+ self.cmd.append('-m ' + flags)
if len(self.name):
- args.append("-N%s" % self.name)
+ self.cmd.append("-N%s" % self.name)
if self.priority != 0:
- args.append('-p' + self.priority)
+ self.cmd.append('-p' + self.priority)
if len(self.queue):
- args.append('-q' + self.queue)
-
- args.append(script)
-
- if self.verbose or self.onlyecho:
- print >>sys.stderr, 'PBS Command: ', ' '.join(args)
-
- if self.onlyecho:
- return 0
-
- print >>sys.stderr, 'PBS Jobid: ',
-
- ec = os.spawnvp(os.P_WAIT, args[0], args)
-
- if ec != 0 and len(self.pbshost):
- ec = ssh(self.pbshost, ' '.join(args))
+ self.cmd.append('-q' + self.queue)
+
+ self.cmd.extend(args)
+ self.script = script
+ self.command = ' '.join(self.cmd + [ self.script ])
+
+ def do(self):
+ pbs = MyPOpen(self.cmd + [ self.script ])
+ self.result = pbs.fromchild.read()
+ ec = pbs.wait()
+
+ if ec != 0 and self.pbshost:
+ cmd = ' '.join(self.cmd + [ '-' ])
+ cmd = [ 'ssh', '-x', self.pbshost, cmd ]
+ self.command = ' '.join(cmd)
+ ssh = MyPOpen(cmd, input = self.script)
+ self.result = ssh.fromchild.read()
+ ec = ssh.wait()
return ec
diff --git a/util/pbs/send.py b/util/pbs/send.py
index 1f174b1f8..b796cadbd 100755
--- a/util/pbs/send.py
+++ b/util/pbs/send.py
@@ -28,12 +28,20 @@
# Authors: Ali Saidi
# Nathan Binkert
-import os, os.path, re, sys
+import os, os.path, re, socket, sys
from os import environ as env, listdir
from os.path import basename, isdir, isfile, islink, join as joinpath
from filecmp import cmp as filecmp
from shutil import copyfile
+def nfspath(dir):
+ if dir.startswith('/.automount/'):
+ dir = '/n/%s' % dir[12:]
+ elif not dir.startswith('/n/'):
+ dir = '/n/%s%s' % (socket.gethostname().split('.')[0], dir)
+ return dir
+
+progpath = nfspath(sys.path[0])
progname = basename(sys.argv[0])
usage = """\
Usage:
@@ -65,7 +73,7 @@ force = False
listonly = False
queue = ''
verbose = False
-rootdir = re.sub(r'^/\.automount/', r'/n/', os.getcwd())
+rootdir = nfspath(os.getcwd())
for opt,arg in opts:
if opt == '-c':
clean = True
@@ -92,7 +100,8 @@ for arg in args:
exprs.append(re.compile(arg))
if not listonly and not onlyecho and isdir(linkdir):
- print 'Checking for outdated files in Link directory'
+ if verbose:
+ print 'Checking for outdated files in Link directory'
entries = listdir(linkdir)
for entry in entries:
link = joinpath(linkdir, entry)
@@ -131,22 +140,23 @@ if listonly:
if not onlyecho:
jl = []
for jobname in joblist:
+ jobdir = joinpath(rootdir, jobname)
if os.path.exists(jobname):
if not force:
- if os.path.isfile(joinpath(jobname, '.success')):
+ if os.path.isfile(joinpath(jobdir, '.success')):
continue
- if os.path.isfile(joinpath(jobname, '.start')) and \
- not os.path.isfile(joinpath(jobname, '.stop')):
+ if os.path.isfile(joinpath(jobdir, '.start')) and \
+ not os.path.isfile(joinpath(jobdir, '.stop')):
continue
if not clean:
sys.exit('job directory not clean!')
- job.cleandir(jobname)
+ job.cleandir(jobdir)
else:
- os.mkdir(jobname)
- jl.append(jobname)
+ os.mkdir(jobdir)
+ jl.append(jobname)
joblist = jl
for jobname in joblist:
@@ -155,8 +165,8 @@ for jobname in joblist:
if not onlyecho and not os.path.isdir(jobdir):
sys.exit('%s is not a directory. Cannot build job' % jobdir)
- print >>sys.stderr, 'Job name: %s' % jobname
- print >>sys.stderr, 'Job directory: %s' % jobdir
+ print 'Job name: %s' % jobname
+ print 'Job directory: %s' % jobdir
qsub = pbs.qsub()
qsub.pbshost = 'simpool.eecs.umich.edu'
@@ -164,11 +174,17 @@ for jobname in joblist:
qsub.name = jobname
qsub.join = True
qsub.node_type = 'FAST'
- qsub.onlyecho = onlyecho
qsub.env['ROOTDIR'] = rootdir
- qsub.verbose = verbose
if len(queue):
qsub.queue = queue
+ qsub.build(joinpath(progpath, 'job.py'))
- qsub.do(joinpath(basedir, 'job.py'))
- print >>sys.stderr, ''
+ if verbose:
+ print 'PBS Command: %s' % qsub.command
+
+ if not onlyecho:
+ ec = qsub.do()
+ if ec == 0:
+ print 'PBS Jobid: %s' % qsub.result
+ else:
+ print 'PBS Failed'