#!/usr/bin/env python

# Copyright (C) 2009 Anders Logg
#
# This file is part of DOLFIN.
#
# DOLFIN is free software: you can redistribute it and/or modify
# it under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# DOLFIN 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 Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public License
# along with DOLFIN. If not, see <http://www.gnu.org/licenses/>.
#
# Modified by Johan Hake, 2009.
#
# First added:  2009-09-15
# Last changed: 2011-01-04

# FIXME: Not checked if working!

from dolfin import *
from glob import glob
from numpy import arange

# Size of mesh
size = 128

# Number of processes to use
# NOTE: Largest number of processors to run is 2^EXP
EXP = 6
num_processes = list(2**arange(EXP+1))

# Function for extracting log file
def get_filename(pattern):
    filenames = glob(pattern)
    if len(filenames) == 0:
        raise IOError, "Unable to open file: %s" % pattern
    elif len(filenames) > 1:
        raise RuntimeError, "More than one data file, don't know which one to pick: " + ", ".join(filenames)
    filename = filenames[0]
    print "Reading data from %s..." % filename
    return filename

# Iterate over process range
assemble_time = []
assemble_second_time = []
solve_time = []

# Remove run with one processor
if 1 in num_processes:
    num_processes.remove(1)

for np in num_processes:

    # Read timings for assemble benchmark
    lines = open(get_filename(\
        "assemble-poisson_np_%d_size_%d.log*" % (np, size))).readlines()
    assemble_time.append(float([line for line in lines \
                                if "TIME (first assembly):" in \
                                line][0].split("TIME (first assembly): ")[-1]))

    assemble_second_time.append(float([line for line in lines \
                                       if "TIME (second assembly):" in \
                                       line][0].split("TIME (second assembly): ")[-1]))

    # Read timings for solve benchmark
    filename = get_filename("solve-poisson_np_%d_size_%d.log*" % (np, size))
    solve_time.append(float([line for line in open(filename).readlines()\
                             if "TIME:" in line][0].split("TIME: ")[-1]))

# Compute speedups
scale_assemble = [assemble_time[0] / t for t in assemble_time]
scale_second_assemble = [assemble_second_time[0] / t for t in assemble_second_time]
scale_solve = [solve_time[0] / t for t in solve_time]

# Print results
table = Table("Speedup")
for i, np in enumerate(num_processes):
    table.set(str(np), "Assemble (first)", scale_assemble[i])
    table.set(str(np), "Assemble (second)", scale_second_assemble[i])
    table.set(str(np), "Solve", scale_solve[i])

print ""
info(table, True)
