#!/bin/bash
set -u

function print_usage()
{
    cat << EOF
$(basename "$0") -- OpenMP Event Summary

    No arguments.

    Output: All time values given in nanoseconds
        Time(%) : Percentage of "Total Time"
        Total Time : The total time used by all executions of event type
        Count: The number of event type
        Average : The average execution time of event type
        Minimum : The smallest execution time of event type
        Maximum : The largest execution time of event type
        Name : The name of the event

    This report provides a summary of OpenMP events and their
    execution times. Note that the "Time(%)" column is calculated
    using a summation of the "Total Time" column, and represents that
    event type's percent of the execution time of the events listed,
    and not a percentage of the application wall or CPU execution time.
EOF
}

### BEGIN include inc_setup ###

EXIT_HELP=25
EXIT_DB=26
EXIT_NODATA=27

# Verify number of params
if [ $# -lt 1 ]
then
    print_usage ${BASH_SOURCE[0]}
    exit ${EXIT_HELP}
fi

# Set DB file
DATABASE="$1"

# Verify DB file exists
if [ ! -f "${DATABASE}" ]
then
    exit ${EXIT_DB}
fi

# Verify DB file contents
# The sqlite3 file format is defined at https://sqlite.org/fileformat.html
DB_FILE_HEADER=$(head -c 16 "$DATABASE" | tr '\0' '\n')
if [ "${DB_FILE_HEADER}" != "SQLite format 3" ]
then
    exit ${EXIT_DB}
fi

# Helper function for error messages
function echoerr() # accepts multiple args
{
    echo "$@" >&2
}

# Setup standard vars

# If we were run by nsys, the path to the preferred sqlite3 should have been
# passed as an env-var.  If not, hope the user has it in their path.
SQLITE3="${NSYS_STATS_SCRIPTS_SQLITE:-sqlite3}"
SQLITE3OPTS="-header -csv -readonly"

RUN_SQLITE="eval \"${SQLITE3}\" ${SQLITE3OPTS} \"${DATABASE}\""

### END include inc_setup ###

### BEGIN: include from inc_table_exists ###

TABLE_EXISTS_TABLES=( )

function table_exists()
{
    local TABLE_NAME=$1

    if [ "${#TABLE_EXISTS_TABLES[@]}" -eq 0 ]
    then
        TABLE_EXISTS_TABLES=( $("${SQLITE3}" ${SQLITE3OPTS} "${DATABASE}" \
                "SELECT name FROM sqlite_master WHERE type = 'table' OR type = 'view'") )
    fi

    for TABLE in "${TABLE_EXISTS_TABLES[@]}"
    do
        if [ "${TABLE}" = "${TABLE_NAME}" ]
        then
            echo "true"
            return 1
        fi
    done
    echo "false"
    return 0
}

### END: include from inc_table_exists ###


OPENMP_TABLES=( $("${SQLITE3}" ${SQLITE3OPTS} "${DATABASE}" ".tables OPENMP_EVENT_KIND_%") )

if [ ${#OPENMP_TABLES[@]} -eq 0 ]
then
    echoerr "${DATABASE} does not contain OpenMP event data."
    exit ${EXIT_NODATA}
fi

QUERY=()

for T in "${OPENMP_TABLES[@]}"
do
    if [ ${#QUERY[@]} -gt 0 ]
    then
        QUERY+=("UNION ALL")
    fi

    Q="""
        SELECT
            nameId AS nameId,
            count(*) AS num,
            min(end - start) AS min,
            max(end - start) AS max,
            avg(end - start) AS avg,
            sum(end - start) AS total
        FROM ${T}
        GROUP BY 1
    """
    QUERY+=("$Q")
done

${RUN_SQLITE} << EOF

WITH
    summary AS (
        ${QUERY[@]}
    ),
    totals AS (
        SELECT sum(total) AS total
        FROM summary
    )
SELECT
    round(summary.total * 100.0 / totals.total, 1) AS "Time(%)",
    summary.total AS "Total Time (ns)",
    summary.num AS "Count",
    round(summary.avg, 1) AS "Average",
    summary.min AS "Minimum",
    summary.max AS "Maximum",
    ids.value AS "Name"
FROM
    summary
JOIN
    totals
LEFT JOIN
    StringIds AS ids
    ON ids.id = summary.nameId
ORDER BY 2 DESC
;

EOF
