vector_matmul_run.py 5.8 KB
Newer Older
C
ckey_Dou 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
# Copyright 2019 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

import os
import logging
from gen_random import random_gaussian
import numpy as np
from akg.utils import kernel_exec as utils
from test_op import vector_matmul


logging.basicConfig(level=logging.DEBUG)


def np_matmul(matrix_a, matrix_b, trans_a=False, trans_b=False):
    if trans_a:
        matrix_a = matrix_a.transpose(1, 0)
    if trans_b:
        matrix_b = matrix_b.transpose(1, 0)
    m, k_a = matrix_a.shape
    k_b, n = matrix_b.shape
    if k_a != k_b:
        raise RuntimeError("matrix_a: %d %d vs matrix_b: %d %d" % (m, k_a, k_b, n))
    result = np.dot(matrix_a, matrix_b)
    return result


def gen_data(m, n, k, trans_a, trans_b, dtype):
    shape_x, shape_y = vector_matmul.get_shape(m, n, k, trans_a, trans_b)
    matrix_a = random_gaussian(shape_x, miu=0.5, sigma=0.01).astype(dtype)
    # matrix_b = random_gaussian(shape_y, miu=0.5, sigma=0.01).astype(dtype)
    # matrix_a = np.ones(shape_x, dtype=dtype)
    matrix_b = np.ones(shape_y, dtype=dtype)
    res = np_matmul(matrix_a, matrix_b, trans_a, trans_b)
    return matrix_a, matrix_b, res


def get_name(caseIndex=1, name="leftMatrix", m=0, n=0, k=0, trans_a=False, trans_b=False):
    res = "{}_{}_{}_{}_{}_{}_{}.bin".format(caseIndex, name, m, n, k, trans_a, trans_b)
    return res


def read_from_file(case_index, m, n, k, trans_a, trans_b, dtype):
    cur_path = os.path.abspath('.')
    benchmark_path, tmp = cur_path.split("ci_test")
    benchmark_path += "ci_test/AT-Benchmark/poly_benchmark/vector_matmul_benchmark/"

    # print benchmark_path
    left_matrix_name = get_name(case_index, "leftMatrix", m, n, k, trans_a, trans_b)
    right_matrix_name = get_name(case_index, "rightMatrix", m, n, k, trans_a, trans_b)
    result_name = get_name(case_index, "result", m, n, k, trans_a, trans_b)

    m_a_shape, m_b_shape = vector_matmul.get_shape(m, n, k, trans_a, trans_b)
    m_a = np.fromfile(benchmark_path + left_matrix_name, dtype=dtype).reshape(m_a_shape)
    m_b = np.fromfile(benchmark_path + right_matrix_name, dtype=dtype).reshape(m_b_shape)
    res_shape = (m, n)
    res = np.fromfile(benchmark_path + result_name, dtype=dtype).reshape(res_shape)
    return m_a, m_b, res


def vector_matmul_data(case_index, m, n, k, trans_a, trans_b, read_data, dump_data, dtype, debug_logging=False):
    m_a = ()
    m_b = ()
    bench_mark = ()

    if read_data:
        logging.debug("read from file!")
        m_a, m_b, bench_mark = read_from_file(case_index, m, n, k, trans_a, trans_b, dtype)
    else:
        m_a, m_b, bench_mark = gen_data(m, n, k, trans_a, trans_b, dtype)

    if dump_data:
        left_matrix_name = get_name(case_index, "leftMatrix", m, n, k, trans_a, trans_b)
        right_matrix_name = get_name(case_index, "rightMatrix", m, n, k, trans_a, trans_b)
        result_name = get_name(case_index, "result", m, n, k, trans_a, trans_b)
        m_a.tofile(left_matrix_name)
        m_b.tofile(right_matrix_name)
        bench_mark.tofile(result_name)

    if debug_logging:
        logging.debug("m_a shape:{}".format(m_a.shape))
        logging.debug("m_b shape:{}".format(m_b.shape))
        logging.debug(type(m_a))

    return m_a, m_b, bench_mark


def result_compare(actual, bench_mark, batch_tuple, M, N, K, r_tol=5e-3):
    output_shape = (M, N)

    error = 0
    count = 0
    lastErr = -2
    continueErr = 0
    maxContinue = -1
    maxEnd = 0
    logging.debug(actual.shape)
    logging.debug(bench_mark.shape)

    for m in range(output_shape[0]):
        for n in range(output_shape[1]):
            a = actual[m, n]
            b = bench_mark[m, n]
            if(abs(a - b) > abs(b) * r_tol):
                error += 1

                if lastErr + 1 == count:
                    continueErr += 1
                else:
                    if continueErr > maxContinue:
                        maxContinue = continueErr
                        maxEnd = lastErr
                    continueErr = 1
                lastErr = count

                # if a != 0.0:
                logging.debug("count: %6d expect: %20f actual: %20f %20.2f%%" % (count, b, a, abs(b - a) / b * 100))
            count += 1
    if continueErr > maxContinue:
        maxContinue = continueErr
        maxEnd = lastErr
    logging.debug("error num: %d/%d (%.2f%%)" % (error, count, 100.0 * error / count))
    logging.debug("longest error range: [%d, %d]" % (maxEnd - maxContinue + 1, maxEnd))
    if maxContinue >= 16:
        return False
    logging.debug("\n\n******************** test ok *****************\n\n")
    return True


def vector_matmul_run(case_index, m, n, k, trans_a, trans_b, read_data, dump_data, dtype, kernel_name, attrs):
    batch_tuple = (1, )
    # m = (m+15)//16*16
    # n = (n+15)//16*16
    # k = (k+15)//16*16

    mod, out_shape = vector_matmul.vector_matmul(m, n, k, trans_a, trans_b, dtype, kernel_name, attrs)
148
    utils.create_code(kernel_name, "./", mod.imported_modules[0].get_source())
C
ckey_Dou 已提交
149 150 151 152 153 154 155 156 157 158 159

    # Generate data
    m_a, m_b, bench_mark = vector_matmul_data(case_index, m, n, k, trans_a, trans_b, read_data, dump_data, dtype)

    # mod launch
    output = np.full(out_shape, np.nan, dtype=dtype)
    output = utils.mod_launch(mod, (m_a, m_b, output), expect=batch_tuple)

    # compare result
    compare_result = result_compare(output, bench_mark, batch_tuple, m, n, k, r_tol=1e-2)
    return (m_a, m_b), output, bench_mark, compare_result