コード例 #1
0
ファイル: test_io.py プロジェクト: ChrisCummins/phd
 def test_fatal_status(self):
     out = StringIO()
     with self.assertRaises(SystemExit) as ctx:
         io.fatal("foo", file=out, status=10)
     self.assertEqual(ctx.exception.code, 10)
     self._test("ERROR", re.search("ERROR", out.getvalue()).group(0))
     self._test("fatal", re.search("fatal", out.getvalue()).group(0))
コード例 #2
0
ファイル: io_test.py プロジェクト: 50417/DeepFuzzSL
def test_fatal_status():
    out = StringIO()
    with pytest.raises(SystemExit) as ctx:
        io.fatal("foo", file=out, status=10)
    assert ctx.value.code == 10
    assert "ERROR" == re.search("ERROR", out.getvalue()).group(0)
    assert "fatal" == re.search("fatal", out.getvalue()).group(0)
コード例 #3
0
ファイル: migrate.py プロジェクト: ChrisCummins/msc-thesis
def migrate_3_to_4(old):
    """
    SkelCL database migration script.

    Arguments:

        old (SkelCLDatabase): The database to migrate
    """
    # Create temporary database
    fs.rm("/tmp/omnitune.skelcl.migration.db")
    tmp = _db.Database("/tmp/omnitune.skelcl.migration.db")
    tmp.attach(old.path, "rhs")

    io.info("Migrating database to version 4.")

    backup_path = old.path + ".3"
    io.info("Creating backup of old database at '{0}'".format(backup_path))
    fs.cp(old.path, backup_path)

    tables = [
        "kernels", "kernel_lookup", "kernel_names", "devices", "device_lookup",
        "datasets", "dataset_lookup", "scenarios", "params", "runtimes",
        "runtime_stats", "oracle_params"
    ]

    for table in tables:
        io.info("Copying data from '{}' ...".format(table))
        tmp.execute("INSERT INTO {} SELECT * FROM rhs.{}".format(table, table))

    tmp_path = tmp.path
    old_path = old.path

    tmp.execute("VACUUM")

    # Sanity checks
    bad = False
    for table in tables:
        old_count = tmp.num_rows("rhs." + table)
        tmp_count = tmp.num_rows(table)

        if old_count != tmp_count:
            io.error("Bad rows count:", old_count, tmp_count)
            bad = True

    if bad:
        io.fatal("Failed sanity check, aborting.")
    else:
        io.info("Passed sanity check.")

    # Copy migrated database over the original one.
    fs.cp(tmp_path, old_path)
    fs.rm(tmp_path)

    old.close()
    tmp.close()
    io.info("Migration completed.")
コード例 #4
0
ファイル: migrate.py プロジェクト: vianziro/msc-thesis
def migrate_5_to_6(db):
    """
    SkelCL database migration script.

    Database version 5 adds an additional "param_stats" table.

    Arguments:

        old (SkelCLDatabase): The database to migrate
    """
    io.info("Migrating database to version 6.")

    backup_path = db.path + ".5"
    io.info("Creating backup of old database at '{0}'".format(backup_path))
    fs.cp(db.path, backup_path)

    db.execute("DELETE FROM version")
    db.execute("INSERT INTO version VALUES (6)")

    db.execute("""
CREATE TABLE IF NOT EXISTS scenario_stats (
    scenario                        CHAR(40),     -- Key for scenarios
    num_params                      INTEGER,      -- The number of parameters in W_legal for scenario
    oracle_param                    VARCHAR(255), -- The best parameter
    oracle_runtime                  REAL,         -- The runtime of the best parameter
    worst_param                     VARCHAR(255), -- The worst parameter
    worst_runtime                   REAL,         -- The runtime of the worst parameter
    mean_runtime                    REAL,         -- The mean runtime of all parameters
    PRIMARY KEY (scenario)
)
""")

    db.populate_scenario_stats_table()

    # Sanity checks
    bad = False
    if db.num_rows("scenario_stats") != len(db.scenarios):
        io.error("Bad row count in scenario_stats table! Expected",
                 len(db.scenarios), "Observed:", db.num_rows("scenario_stats"))
        bad = True

    if bad:
        io.fatal("Failed sanity check, aborting.")
    else:
        io.info("Passed sanity check.")

    # Copy migrated database over the original one.
    db.close()
    io.info("Migration completed.")
コード例 #5
0
def migrate_5_to_6(db):
  """
  SkelCL database migration script.

  Database version 5 adds an additional "param_stats" table.

  Arguments:

      old (SkelCLDatabase): The database to migrate
  """
  io.info("Migrating database to version 6.")

  backup_path = db.path + ".5"
  io.info("Creating backup of old database at '{0}'".format(backup_path))
  fs.cp(db.path, backup_path)

  db.execute("DELETE FROM version")
  db.execute("INSERT INTO version VALUES (6)")

  db.execute("""
CREATE TABLE IF NOT EXISTS scenario_stats (
    scenario                        CHAR(40),     -- Key for scenarios
    num_params                      INTEGER,      -- The number of parameters in W_legal for scenario
    oracle_param                    VARCHAR(255), -- The best parameter
    oracle_runtime                  REAL,         -- The runtime of the best parameter
    worst_param                     VARCHAR(255), -- The worst parameter
    worst_runtime                   REAL,         -- The runtime of the worst parameter
    mean_runtime                    REAL,         -- The mean runtime of all parameters
    PRIMARY KEY (scenario)
)
""")

  db.populate_scenario_stats_table()

  # Sanity checks
  bad = False
  if db.num_rows("scenario_stats") != len(db.scenarios):
    io.error("Bad row count in scenario_stats table! Expected",
             len(db.scenarios), "Observed:", db.num_rows("scenario_stats"))
    bad = True

  if bad:
    io.fatal("Failed sanity check, aborting.")
  else:
    io.info("Passed sanity check.")

  # Copy migrated database over the original one.
  db.close()
  io.info("Migration completed.")
コード例 #6
0
ファイル: migrate.py プロジェクト: vianziro/msc-thesis
def migrate_4_to_5(db):
    """
    SkelCL database migration script.

    Database version 5 adds an additional "param_stats" table.

    Arguments:

        old (SkelCLDatabase): The database to migrate
    """
    io.info("Migrating database to version 5.")

    backup_path = db.path + ".4"
    io.info("Creating backup of old database at '{0}'".format(backup_path))
    fs.cp(db.path, backup_path)

    db.execute("DELETE FROM version")
    db.execute("INSERT INTO version VALUES (5)")

    db.execute("""
-- Parameter stats table
CREATE TABLE IF NOT EXISTS param_stats (
    params                          VARCHAR(255), -- Key for params
    num_scenarios                   INTEGER,      -- Number of scenarios for which param is legal, 0 < num_scenarios
    coverage                        REAL,         -- num_scenarios / total number of scenarios, 0 < coverage <= 1
    performance                     REAL,         -- Geometric mean of performance relative to the oracle for all scenarios for which param was legal, 0 < performance <= 1
    PRIMARY KEY (params)
)
""")

    db.populate_param_stats_table()

    # Sanity checks
    bad = False
    if db.num_rows("param_stats") != len(db.params):
        io.error("Bad row count in params table! Expected", len(db.params),
                 "Observed:", db.num_rows("param_stats"))
        bad = True

    if bad:
        io.fatal("Failed sanity check, aborting.")
    else:
        io.info("Passed sanity check.")

    # Copy migrated database over the original one.
    db.close()
    io.info("Migration completed.")
コード例 #7
0
def migrate_4_to_5(db):
  """
  SkelCL database migration script.

  Database version 5 adds an additional "param_stats" table.

  Arguments:

      old (SkelCLDatabase): The database to migrate
  """
  io.info("Migrating database to version 5.")

  backup_path = db.path + ".4"
  io.info("Creating backup of old database at '{0}'".format(backup_path))
  fs.cp(db.path, backup_path)

  db.execute("DELETE FROM version")
  db.execute("INSERT INTO version VALUES (5)")

  db.execute("""
-- Parameter stats table
CREATE TABLE IF NOT EXISTS param_stats (
    params                          VARCHAR(255), -- Key for params
    num_scenarios                   INTEGER,      -- Number of scenarios for which param is legal, 0 < num_scenarios
    coverage                        REAL,         -- num_scenarios / total number of scenarios, 0 < coverage <= 1
    performance                     REAL,         -- Geometric mean of performance relative to the oracle for all scenarios for which param was legal, 0 < performance <= 1
    PRIMARY KEY (params)
)
""")

  db.populate_param_stats_table()

  # Sanity checks
  bad = False
  if db.num_rows("param_stats") != len(db.params):
    io.error("Bad row count in params table! Expected", len(db.params),
             "Observed:", db.num_rows("param_stats"))
    bad = True

  if bad:
    io.fatal("Failed sanity check, aborting.")
  else:
    io.info("Passed sanity check.")

  # Copy migrated database over the original one.
  db.close()
  io.info("Migration completed.")
コード例 #8
0
ファイル: reduce.py プロジェクト: vianziro/msc-thesis
def merge(old_oracle, dbs, path):
    """
    Merge databases into one.

    Arguments:

        dbs (list of Database): Databases to merge.
        path (str): Path to merged database.

    Returns:

        Database: merged database instance.
    """
    print("Merging {n} databases:".format(n=len(dbs) + 1))
    print("   ", old_oracle)
    for db in dbs:
        print("   ", db)
    print()

    # Make a copy of the old oracle database to work from.
    io.info("Coping", old_oracle, "->", fs.basename(path))
    fs.cp(old_oracle, path)

    target = migrate(_db.Database(path=path))

    for db in dbs + [target]:
        try:
            db.num_rows("runtimes")
        except sqlite3.DatabaseError as e:
            io.error("Broken db:", db.path)
            io.fatal(e)

    num_runtimes = [db.num_rows("runtimes") for db in dbs]
    expected_total = target.num_rows("runtimes") + sum(num_runtimes)

    target.merge(dbs)

    total = target.num_rows("runtimes")

    if total != expected_total:
        io.fatal("Expected total", expected_total,
                 "!= actual total", total)

    io.info(("Merged {num_db} databases, {n} rows"
             .format(num_db=len(dbs), n=total)))

    return target
コード例 #9
0
    def __init__(self, *args, **kwargs):
        """
        Construct a SkelCL server.
        """
        # Fail if we can't find the path
        if not fs.isdir(self.LLVM_PATH):
            io.fatal("Could not find llvm path '{0}'".format(self.LLVM_PATH))

        super(Server, self).__init__(*args, **kwargs)
        io.info("Registered server %s/SkelCLServer ..." % SESSION_NAME)

        # Setup persistent database.
        self.db = migrate(Database())
        self.db.status_report()

        # Create an in-memory sample strategy cache.
        self.strategies = cache.TransientCache()
コード例 #10
0
def main():
    """
    Gather databases from experimental setups.
    """
    fs.mkdir(experiment.DATA_ROOT)
    fs.mkdir(experiment.DB_DEST)

    if system.HOSTNAME != "cec":
        io.fatal("script must be ran on machine `cec'")

    # TODO: Perform integrity checks. If they fail, transfer again.
    cp_loc("~/.omnitune/skelcl.db", "cec")
    cp_rmt("brendel.inf.ed.ac.uk", path="~/florence.db", name="florence")
    cp_rmt("dhcp-90-060")
    cp_rmt("monza")
    cp_rmt("tim")
    cp_rmt("whz5")
コード例 #11
0
ファイル: reduce.py プロジェクト: ChrisCummins/msc-thesis
def merge(old_oracle, dbs, path):
    """
    Merge databases into one.

    Arguments:

        dbs (list of Database): Databases to merge.
        path (str): Path to merged database.

    Returns:

        Database: merged database instance.
    """
    print("Merging {n} databases:".format(n=len(dbs) + 1))
    print("   ", old_oracle)
    for db in dbs:
        print("   ", db)
    print()

    # Make a copy of the old oracle database to work from.
    io.info("Coping", old_oracle, "->", fs.basename(path))
    fs.cp(old_oracle, path)

    target = migrate(_db.Database(path=path))

    for db in dbs + [target]:
        try:
            db.num_rows("runtimes")
        except sqlite3.DatabaseError as e:
            io.error("Broken db:", db.path)
            io.fatal(e)

    num_runtimes = [db.num_rows("runtimes") for db in dbs]
    expected_total = target.num_rows("runtimes") + sum(num_runtimes)

    target.merge(dbs)

    total = target.num_rows("runtimes")

    if total != expected_total:
        io.fatal("Expected total", expected_total, "!= actual total", total)

    io.info(("Merged {num_db} databases, {n} rows".format(num_db=len(dbs),
                                                          n=total)))

    return target
コード例 #12
0
ファイル: experiment.py プロジェクト: vianziro/msc-thesis
]

DATASIZES = [
    ["--width",  "512", "--height",  "512"],
    ["--width", "1024", "--height", "1024"],
    ["--width", "2048", "--height", "2048"]
]

if system.HOSTNAME == "cec":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"]]
elif system.HOSTNAME == "dhcp-90-060":
    DEVARGS = [["--device-type", "GPU", "--device-count", "1"]]
elif system.HOSTNAME == "florence":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"]]
elif system.HOSTNAME == "monza":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "2"]]
elif system.HOSTNAME == "tim":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "2"],
               ["--device-type", "GPU", "--device-count", "3"],
               ["--device-type", "GPU", "--device-count", "4"]]
elif system.HOSTNAME == "whz5":
    DEVARGS = [["--device-type", "GPU", "--device-count", "1"]]
else:
    io.fatal("Unrecognised hostname!")

ARGS = list(itertools.product(COMPLEXITIES, DATASIZES, BORDERS, DEVARGS))
コード例 #13
0
ファイル: migrate.py プロジェクト: vianziro/msc-thesis
def migrate_3_to_4(old):
    """
    SkelCL database migration script.

    Arguments:

        old (SkelCLDatabase): The database to migrate
    """
    # Create temporary database
    fs.rm("/tmp/omnitune.skelcl.migration.db")
    tmp = _db.Database("/tmp/omnitune.skelcl.migration.db")
    tmp.attach(old.path, "rhs")

    io.info("Migrating database to version 4.")

    backup_path = old.path + ".3"
    io.info("Creating backup of old database at '{0}'".format(backup_path))
    fs.cp(old.path, backup_path)

    tables = [
        "kernels",
        "kernel_lookup",
        "kernel_names",
        "devices",
        "device_lookup",
        "datasets",
        "dataset_lookup",
        "scenarios",
        "params",
        "runtimes",
        "runtime_stats",
        "oracle_params"
    ]

    for table in tables:
        io.info("Copying data from '{}' ...".format(table))
        tmp.execute("INSERT INTO {} SELECT * FROM rhs.{}".format(table, table))

    tmp_path = tmp.path
    old_path = old.path

    tmp.execute("VACUUM")

    # Sanity checks
    bad = False
    for table in tables:
        old_count = tmp.num_rows("rhs." + table)
        tmp_count = tmp.num_rows(table)

        if old_count != tmp_count:
            io.error("Bad rows count:", old_count, tmp_count)
            bad = True

    if bad:
        io.fatal("Failed sanity check, aborting.")
    else:
        io.info("Passed sanity check.")

    # Copy migrated database over the original one.
    fs.cp(tmp_path, old_path)
    fs.rm(tmp_path)

    old.close()
    tmp.close()
    io.info("Migration completed.")
コード例 #14
0
ファイル: migrate.py プロジェクト: vianziro/msc-thesis
def migrate_2_to_3(old):
    """
    SkelCL database migration script.

    Arguments:

        old (SkelCLDatabase): The database to migrate
    """
    def _old_kernel2new(old_id):
        kernel = old.execute("SELECT north,south,east,west,max_wg_size,source "
                             "FROM kernels WHERE id=?",
                             (old_id,)).fetchone()
        if kernel:
            return tmp.kernel_id(*kernel)

    def _old_scenario2new(old_id):
        device, old_kernel, dataset = old.execute("SELECT device,kernel,dataset "
                                                  "FROM scenarios WHERE id=?",
                                                  (old_id,)).fetchone()
        kernel = _old_kernel2new(old_kernel)
        return tmp.scenario_id(device, kernel, dataset)

    # TODO: Un-comment out code!

    # Create temporary database
    fs.rm("/tmp/omnitune.skelcl.migration.db")
    tmp = _db.Database("/tmp/omnitune.skelcl.migration.db")
    tmp.attach(old.path, "rhs")

    io.info("Migrating database to version 3.")

    backup_path = old.path + ".2"
    io.info("Creating backup of old database at '{0}'".format(backup_path))
    fs.cp(old.path, backup_path)

    tmp_path = tmp.path
    old_path = old.path

    tmp.run("create_tables")

    # Populate feature and lookup tables.
    for row in old.execute("SELECT * FROM devices"):
        features = row[1:]
        id = hash_device(*features)
        io.debug("Features extracted for device", id)
        row = (id,) + features
        tmp.execute("INSERT INTO devices VALUES " +
                    placeholders(*row), row)

        row = (features[0], features[1], id)
        tmp.execute("INSERT INTO device_lookup VALUES " +
                    placeholders(*row), row)
        tmp.commit()

    for row in old.execute("SELECT * FROM kernels"):
        args = row[1:]
        tmp.kernel_id(*args)

    for row in old.execute("SELECT * FROM datasets"):
        features = row[1:]
        id = hash_dataset(*features)
        io.debug("Features extracted for dataset", id)
        row = (id,) + features
        tmp.execute("INSERT INTO datasets VALUES " +
                    placeholders(*row), row)

        row = features + (id,)
        tmp.execute("INSERT INTO dataset_lookup VALUES " +
                    placeholders(*row), row)
        tmp.commit()

    # Populate kernel_names table.
    for row in old.execute("SELECT * FROM kernel_names"):
        old_id = row[0]
        synthetic, name = row[1:]

        kernel = _old_kernel2new(old_id)
        if kernel:
            row = (kernel, synthetic, name)
            tmp.execute("INSERT OR IGNORE INTO kernel_names VALUES " +
                        placeholders(*row), row)
    tmp.commit()

    # Populate scenarios table.
    for row in old.execute("SELECT * FROM scenarios"):
        old_id, _, device, old_kernel, dataset = row
        kernel = _old_kernel2new(old_kernel)
        new_id = hash_scenario(device, kernel, dataset)

        row = (new_id, device, kernel, dataset)
        tmp.execute("INSERT OR IGNORE INTO scenarios VALUES " +
                    placeholders(*row), row)
    tmp.commit()

    # Populate params table.
    tmp.execute("INSERT INTO params SELECT * from rhs.params")
    tmp.commit()

    scenario_replacements = {
        row[0]: _old_scenario2new(row[0])
        for row in old.execute("SELECT * FROM scenarios")
    }

    tmp.execute("INSERT INTO runtimes SELECT * from rhs.runtimes")
    for old_id, new_id in scenario_replacements.iteritems():
        io.info("Runtimes", old_id, "->", new_id)
        tmp.execute("UPDATE runtimes SET scenario=? WHERE scenario=?",
                    (new_id, old_id))
    tmp.commit()

    # Sanity checks
    bad = False
    for row in tmp.execute("SELECT DISTINCT scenario FROM runtimes"):
        count = tmp.execute("SELECT Count(*) FROM scenarios WHERE id=?",
                            (row[0],)).fetchone()[0]
        if count != 1:
            io.error("Bad scenario count:", row[0], count)
            bad = True

    if bad:
        io.fatal("Failed sanity check, aborting.")
    else:
        io.info("Passed sanity check.")

    # Copy migrated database over the original one.
    fs.cp(tmp_path, old_path)
    fs.rm(tmp_path)

    old.close()
    tmp.close()
    io.info("Migration completed.")
コード例 #15
0
ファイル: experiment.py プロジェクト: ChrisCummins/msc-thesis
           ["--north", "30", "--south", "30", "--east", "30", "--west", "30"],
           ["--north", "1", "--south", "10", "--east", "30", "--west", "30"],
           ["--north", "20", "--south", "10", "--east", "20", "--west", "10"]]

DATASIZES = [["--width", "512", "--height", "512"],
             ["--width", "1024", "--height", "1024"],
             ["--width", "2048", "--height", "2048"]]

if system.HOSTNAME == "cec":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"]]
elif system.HOSTNAME == "dhcp-90-060":
    DEVARGS = [["--device-type", "GPU", "--device-count", "1"]]
elif system.HOSTNAME == "florence":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"]]
elif system.HOSTNAME == "monza":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "2"]]
elif system.HOSTNAME == "tim":
    DEVARGS = [["--device-type", "CPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "1"],
               ["--device-type", "GPU", "--device-count", "2"],
               ["--device-type", "GPU", "--device-count", "3"],
               ["--device-type", "GPU", "--device-count", "4"]]
elif system.HOSTNAME == "whz5":
    DEVARGS = [["--device-type", "GPU", "--device-count", "1"]]
else:
    io.fatal("Unrecognised hostname!")

ARGS = list(itertools.product(COMPLEXITIES, DATASIZES, BORDERS, DEVARGS))
コード例 #16
0
def migrate_2_to_3(old):
  """
  SkelCL database migration script.

  Arguments:

      old (SkelCLDatabase): The database to migrate
  """

  def _old_kernel2new(old_id):
    kernel = old.execute("SELECT north,south,east,west,max_wg_size,source "
                         "FROM kernels WHERE id=?",
                         (old_id,)).fetchone()
    if kernel:
      return tmp.kernel_id(*kernel)

  def _old_scenario2new(old_id):
    device, old_kernel, dataset = old.execute("SELECT device,kernel,dataset "
                                              "FROM scenarios WHERE id=?",
                                              (old_id,)).fetchone()
    kernel = _old_kernel2new(old_kernel)
    return tmp.scenario_id(device, kernel, dataset)

  # TODO: Un-comment out code!

  # Create temporary database
  fs.rm("/tmp/omnitune.skelcl.migration.db")
  tmp = _db.Database("/tmp/omnitune.skelcl.migration.db")
  tmp.attach(old.path, "rhs")

  io.info("Migrating database to version 3.")

  backup_path = old.path + ".2"
  io.info("Creating backup of old database at '{0}'".format(backup_path))
  fs.cp(old.path, backup_path)

  tmp_path = tmp.path
  old_path = old.path

  tmp.run("create_tables")

  # Populate feature and lookup tables.
  for row in old.execute("SELECT * FROM devices"):
    features = row[1:]
    id = hash_device(*features)
    io.debug("Features extracted for device", id)
    row = (id,) + features
    tmp.execute("INSERT INTO devices VALUES " +
                placeholders(*row), row)

    row = (features[0], features[1], id)
    tmp.execute("INSERT INTO device_lookup VALUES " +
                placeholders(*row), row)
    tmp.commit()

  for row in old.execute("SELECT * FROM kernels"):
    args = row[1:]
    tmp.kernel_id(*args)

  for row in old.execute("SELECT * FROM datasets"):
    features = row[1:]
    id = hash_dataset(*features)
    io.debug("Features extracted for dataset", id)
    row = (id,) + features
    tmp.execute("INSERT INTO datasets VALUES " +
                placeholders(*row), row)

    row = features + (id,)
    tmp.execute("INSERT INTO dataset_lookup VALUES " +
                placeholders(*row), row)
    tmp.commit()

  # Populate kernel_names table.
  for row in old.execute("SELECT * FROM kernel_names"):
    old_id = row[0]
    synthetic, name = row[1:]

    kernel = _old_kernel2new(old_id)
    if kernel:
      row = (kernel, synthetic, name)
      tmp.execute("INSERT OR IGNORE INTO kernel_names VALUES " +
                  placeholders(*row), row)
  tmp.commit()

  # Populate scenarios table.
  for row in old.execute("SELECT * FROM scenarios"):
    old_id, _, device, old_kernel, dataset = row
    kernel = _old_kernel2new(old_kernel)
    new_id = hash_scenario(device, kernel, dataset)

    row = (new_id, device, kernel, dataset)
    tmp.execute("INSERT OR IGNORE INTO scenarios VALUES " +
                placeholders(*row), row)
  tmp.commit()

  # Populate params table.
  tmp.execute("INSERT INTO params SELECT * from rhs.params")
  tmp.commit()

  scenario_replacements = {
    row[0]: _old_scenario2new(row[0])
    for row in old.execute("SELECT * FROM scenarios")
  }

  tmp.execute("INSERT INTO runtimes SELECT * from rhs.runtimes")
  for old_id, new_id in scenario_replacements.iteritems():
    io.info("Runtimes", old_id, "->", new_id)
    tmp.execute("UPDATE runtimes SET scenario=? WHERE scenario=?",
                (new_id, old_id))
  tmp.commit()

  # Sanity checks
  bad = False
  for row in tmp.execute("SELECT DISTINCT scenario FROM runtimes"):
    count = tmp.execute("SELECT Count(*) FROM scenarios WHERE id=?",
                        (row[0],)).fetchone()[0]
    if count != 1:
      io.error("Bad scenario count:", row[0], count)
      bad = True

  if bad:
    io.fatal("Failed sanity check, aborting.")
  else:
    io.info("Passed sanity check.")

  # Copy migrated database over the original one.
  fs.cp(tmp_path, old_path)
  fs.rm(tmp_path)

  old.close()
  tmp.close()
  io.info("Migration completed.")