Add test generator using python mako templates. * Adds templates for OPIVV, OPIVX and OPIVI instruction tests. * Adds cmake targets for generating test source code. * Convert vsub and vadd to autogenerated tests. * Remove vand test. Change-Id: I1a197894e83e7ae23841e5164eac6e13186f9c09
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index b6c65e8..73fbeef 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt
@@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.10) - +include(vec_cc_generated_test.cmake) enable_language(ASM) file(COPY ${CMAKE_CURRENT_SOURCE_DIR}/test_runner.py @@ -15,6 +15,27 @@ ${VEC_DEFAULT_COPTS} ) +vec_cc_generated_test( + NAME + vsub + OPFMT + OPIVV + OPIVX + LINKOPTS + -Xlinker --defsym=__itcm_length__=128K +) + +vec_cc_generated_test( + NAME + vadd + OPFMT + OPIVV + OPIVX + OPIVI + LINKOPTS + -Xlinker --defsym=__itcm_length__=256K +) + vec_cc_test( NAME vsetvl_test @@ -48,19 +69,6 @@ vec_cc_test( NAME - vadd_test - SRCS - vadd_vi_test.cpp - vadd_vx_test.cpp - vadd_vv_test.cpp - LINKOPTS - -Xlinker --defsym=__itcm_length__=256K - TIMEOUT - 40 -) - -vec_cc_test( - NAME vmax_test SRCS vmax_vx_test.cpp @@ -71,13 +79,3 @@ 40 ) -vec_cc_test( - NAME - vand_test - SRCS - vand_vi_test.cpp - LINKOPTS - -Xlinker --defsym=__itcm_length__=256K - TIMEOUT - 40 -)
diff --git a/tests/scripts/generate_vector_tests.py b/tests/scripts/generate_vector_tests.py new file mode 100644 index 0000000..b3e002d --- /dev/null +++ b/tests/scripts/generate_vector_tests.py
@@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +""" +Generate tests for Vector Instructions +""" +import os +import logging +import argparse +from collections import namedtuple +from pathlib import Path + +from mako.lookup import TemplateLookup +import mako.exceptions + +parser = argparse.ArgumentParser( + description='Generate tests for vector instructions.') + +parser.add_argument('--template-path', dest='template_path', + help='path to templates', required=True) +parser.add_argument('-v', '--verbose', help='increase output verbosity', + action='store_true') +parser.add_argument('--op-code', dest='op_code', + help='Op-code', required=True) +parser.add_argument('--out-path', dest='out_path', + help='Path to output files', default='.') + +template_name_lookup = { + 'OPIVV':'opivv_test.tpl.cpp', + 'OPIVI':'opivi_test.tpl.cpp', + 'OPIVX':'opivx_test.tpl.cpp', +} + +parser.add_argument('--instruction-format', + action='append', choices=template_name_lookup.keys(), required=True) +args = parser.parse_args() + +if args.verbose: + logging.basicConfig(level=logging.DEBUG) + +def main(): + """ Main routine for generating tests from templates.""" + mylookup = TemplateLookup(directories=[args.template_path, "."]) + template_names = [template_name_lookup.get(fmt, None) for fmt in args.instruction_format] + template_names = [template for template in template_names if template is not None] + template_jobs = [] + TemplateJob = namedtuple("TemplateJob", "template outfile") + Path(args.out_path).mkdir(parents=True, exist_ok=True) + for opfmt, template_name in template_name_lookup.items(): + if not opfmt in args.instruction_format: + continue + try: + template = mylookup.get_template(template_name) + except mako.exceptions.TopLevelLookupException: + parser.error("Template does not exist %s" % template_name) + outfile_name = "%s_%s" % (args.op_code, template_name.replace(".tpl", "")) + template_jobs.append(TemplateJob(template, outfile_name)) + + for template_job in template_jobs: + full_outfile_path = os.path.join(args.out_path, template_job.outfile) + with open(full_outfile_path, "w+") as outfile: + outfile.write(template_job.template.render(op_code=args.op_code)) + +if __name__ == "__main__": + main()
diff --git a/tests/templates/opivi_test.tpl.cpp b/tests/templates/opivi_test.tpl.cpp new file mode 100644 index 0000000..40a5d26 --- /dev/null +++ b/tests/templates/opivi_test.tpl.cpp
@@ -0,0 +1,78 @@ +/* Automatically generated file */ +#include <limits.h> +#include <riscv_vector.h> +#include <softrvv.h> +#include <springbok.h> +#include <stdio.h> +#include <stdlib.h> + +#include <bit> +#include <tuple> + +#include "pw_unit_test/framework.h" +#include "test_v_helpers.h" + +namespace ${op_code}_vi_test { +namespace { + +using namespace test_v_helpers; + +uint8_t src_vector_1[MAXVL_BYTES]; +uint8_t dest_vector[MAXVL_BYTES]; +uint8_t ref_dest_vector[MAXVL_BYTES]; + +class ${op_code.capitalize()}Test : public ::testing::Test { + protected: + void SetUp() override { zero_vector_registers(); } + void TearDown() override { zero_vector_registers(); } +}; +% for test_val in [-16, -15, -4, 1, 5, 12, 15]: +% for sew in [8, 16, 32]: +% for lmul in [1, 2, 4, 8]: +<% +var_type = "int%d_t" % sew +%>\ + +TEST_F(${op_code.capitalize()}Test, ${op_code.lower()}_vi${sew}m${lmul}simm5_${("%s" % test_val).replace('-','n')}) { + for (int i = 0; i < AVL_COUNT; i++) { + int32_t avl = AVLS[i]; + int vlmax; + int vl; + const ${var_type} test_val = ${test_val}; + + std::tie(vlmax, vl) = vector_test_setup<${var_type}>( + VLMUL::LMUL_M${lmul}, avl, + {src_vector_1, dest_vector, ref_dest_vector}); + if (avl > vlmax) { + continue; + } + ${var_type} *ptr_vec_1 = reinterpret_cast<${var_type} *>(src_vector_1); + ${var_type} *ptr_dest_vec = reinterpret_cast<${var_type} *>(dest_vector); + ${var_type} *ptr_ref_dest_vec = reinterpret_cast<${var_type} *>(ref_dest_vector); + // set up values to test up to index of the AVL + fill_random_vector<${var_type}>(ptr_vec_1, avl); + memset(dest_vector, 0, MAXVL_BYTES); + memset(ref_dest_vector, 0, MAXVL_BYTES); + + // Generate reference vector + softrvv::${op_code}_vx<${var_type}>(ptr_ref_dest_vec, ptr_vec_1, &test_val, avl); + + // Load vector registers + __asm__ volatile("vle${sew}.v v8, (%0)" : : "r"(ptr_vec_1)); + + // Run target instruction + __asm__ volatile("${op_code}.vi v24, v8, %[SIMM5]" ::[SIMM5] "n"(test_val)); + + // Store result vector register + __asm__ volatile("vse${sew}.v v24, (%0)" : : "r"(ptr_dest_vec)); + + // Check vector elements + assert_vec_elem_eq<${var_type}>(vlmax, dest_vector, ref_dest_vector); + } +} +%endfor +%endfor +%endfor + +} // namespace +} // namespace ${op_code}_vi_test
diff --git a/tests/templates/opivv_test.tpl.cpp b/tests/templates/opivv_test.tpl.cpp new file mode 100644 index 0000000..1df0448 --- /dev/null +++ b/tests/templates/opivv_test.tpl.cpp
@@ -0,0 +1,79 @@ +/* Automatically generated file */ +#include <limits.h> +#include <riscv_vector.h> +#include <softrvv.h> +#include <springbok.h> +#include <stdio.h> +#include <stdlib.h> + +#include <bit> +#include <tuple> + +#include "pw_unit_test/framework.h" +#include "test_v_helpers.h" + +namespace ${op_code}_vv_test { +namespace { + +using namespace test_v_helpers; + +uint8_t src_vector_1[MAXVL_BYTES]; +uint8_t src_vector_2[MAXVL_BYTES]; +uint8_t dest_vector[MAXVL_BYTES]; +uint8_t ref_dest_vector[MAXVL_BYTES]; + +class ${op_code.capitalize()}Test : public ::testing::Test { + protected: + void SetUp() override { zero_vector_registers(); } + void TearDown() override { zero_vector_registers(); } +}; +% for sew in [8, 16, 32]: +% for lmul in [1, 2, 4, 8]: +<% +var_type = "int%d_t" % sew +%>\ + +TEST_F(${op_code.capitalize()}Test, ${op_code.lower()}_vv${sew}m${lmul}) { + for (int i = 0; i < AVL_COUNT; i++) { + int32_t avl = AVLS[i]; + int vlmax; + int vl; + std::tie(vlmax, vl) = vector_test_setup<${var_type}>( + VLMUL::LMUL_M${lmul}, avl, + {src_vector_1, src_vector_2, dest_vector, ref_dest_vector}); + if (avl > vlmax) { + continue; + } + ${var_type} *ptr_vec_1 = reinterpret_cast<${var_type} *>(src_vector_1); + ${var_type} *ptr_vec_2 = reinterpret_cast<${var_type} *>(src_vector_2); + ${var_type} *ptr_dest_vec = reinterpret_cast<${var_type} *>(dest_vector); + ${var_type} *ptr_ref_dest_vec = reinterpret_cast<${var_type} *>(ref_dest_vector); + + // set up values to test up to index of the AVL + fill_random_vector<${var_type}>(ptr_vec_1, avl); + fill_random_vector<${var_type}>(ptr_vec_2, avl); + memset(dest_vector, 0, MAXVL_BYTES); + memset(ref_dest_vector, 0, MAXVL_BYTES); + + // Generate reference vector + softrvv::${op_code}_vv<${var_type}>(ptr_ref_dest_vec, ptr_vec_2, ptr_vec_1, avl); + + // Load vector registers + __asm__ volatile("vle${sew}.v v8, (%0)" : : "r"(ptr_vec_1)); + __asm__ volatile("vle${sew}.v v16, (%0)" : : "r"(ptr_vec_2)); + + // Run target instruction + __asm__ volatile("${op_code}.vv v24, v16, v8"); + + // Store result vector register + __asm__ volatile("vse${sew}.v v24, (%0)" : : "r"(ptr_dest_vec)); + + // Check vector elements + assert_vec_elem_eq<${var_type}>(vlmax, dest_vector, ref_dest_vector); + } +} +%endfor +%endfor + +} // namespace +} // namespace ${op_code}_vv_test
diff --git a/tests/templates/opivx_test.tpl.cpp b/tests/templates/opivx_test.tpl.cpp new file mode 100644 index 0000000..2476708 --- /dev/null +++ b/tests/templates/opivx_test.tpl.cpp
@@ -0,0 +1,75 @@ +/* Automatically generated file */ +#include <limits.h> +#include <riscv_vector.h> +#include <softrvv.h> +#include <springbok.h> +#include <stdio.h> +#include <stdlib.h> + +#include <bit> +#include <tuple> + +#include "pw_unit_test/framework.h" +#include "test_v_helpers.h" + +namespace ${op_code}_vx_test { +namespace { + +using namespace test_v_helpers; + +uint8_t src_vector_1[MAXVL_BYTES]; +uint8_t dest_vector[MAXVL_BYTES]; +uint8_t ref_dest_vector[MAXVL_BYTES]; + +class ${op_code.capitalize()}Test : public ::testing::Test { + protected: + void SetUp() override { zero_vector_registers(); } + void TearDown() override { zero_vector_registers(); } +}; +% for sew in [8, 16, 32]: +% for lmul in [1, 2, 4, 8]: +<% +var_type = "int%d_t" % sew +%>\ + +TEST_F(${op_code.capitalize()}Test, ${op_code.lower()}_vx${sew}m${lmul}) { + for (int i = 0; i < AVL_COUNT; i++) { + int32_t avl = AVLS[i]; + int vlmax; + int vl; + std::tie(vlmax, vl) = vector_test_setup<${var_type}>( + VLMUL::LMUL_M${lmul}, avl, + {src_vector_1, dest_vector, ref_dest_vector}); + if (avl > vlmax) { + continue; + } + ${var_type} *ptr_vec_1 = reinterpret_cast<${var_type} *>(src_vector_1); + ${var_type} *ptr_dest_vec = reinterpret_cast<${var_type} *>(dest_vector); + ${var_type} *ptr_ref_dest_vec = reinterpret_cast<${var_type} *>(ref_dest_vector); + ${var_type} test_val = static_cast<${var_type}>(rand()); + // set up values to test up to index of the AVL + fill_random_vector<${var_type}>(ptr_vec_1, avl); + memset(dest_vector, 0, MAXVL_BYTES); + memset(ref_dest_vector, 0, MAXVL_BYTES); + + // Generate reference vector + softrvv::${op_code}_vx<${var_type}>(ptr_ref_dest_vec, ptr_vec_1, &test_val, avl); + + // Load vector registers + __asm__ volatile("vle${sew}.v v8, (%0)" : : "r"(ptr_vec_1)); + + // Run target instruction + __asm__ volatile("${op_code}.vx v24, v8, %[RS1]" ::[RS1] "r"(test_val)); + + // Store result vector register + __asm__ volatile("vse${sew}.v v24, (%0)" : : "r"(ptr_dest_vec)); + + // Check vector elements + assert_vec_elem_eq<${var_type}>(vlmax, dest_vector, ref_dest_vector); + } +} +%endfor +%endfor + +} // namespace +} // namespace ${op_code}_vx_test
diff --git a/tests/vadd_vi_test.cpp b/tests/vadd_vi_test.cpp deleted file mode 100644 index 389d862..0000000 --- a/tests/vadd_vi_test.cpp +++ /dev/null
@@ -1,98 +0,0 @@ -#include <riscv_vector.h> -#include <softrvv.h> -#include <springbok.h> -#include <stdio.h> -#include <stdlib.h> - -#include <bit> -#include <tuple> - -#include "pw_unit_test/framework.h" -#include "test_v_helpers.h" - -namespace vadd_vi_test { -namespace { - -using namespace test_v_helpers; - -uint8_t test_vector_1[MAXVL_BYTES]; -uint8_t reference_vector_1[MAXVL_BYTES]; - -class VaddViTest : public ::testing::Test { - protected: - void SetUp() override { zero_vector_registers(); } - void TearDown() override { zero_vector_registers(); } -}; - -// Below is a non-macro version of the test for more convenient debugging. -// Remove the "DISABLED_" prefix to enable this test for debugging. -TEST_F(VaddViTest, DISABLED_vadd_vi_demo) { - for (int i = 0; i < AVL_COUNT; i++) { - int32_t avl = AVLS[i]; - int vlmax; - int vl; - std::tie(vlmax, vl) = vector_test_setup<int8_t>( - VLMUL::LMUL_M1, avl, {test_vector_1, reference_vector_1}); - if (avl > vlmax) { - continue; - } - int8_t *ptr_vec_1 = reinterpret_cast<int8_t *>(test_vector_1); - int8_t *ptr_ref_vec_1 = reinterpret_cast<int8_t *>(reference_vector_1); - const int8_t test_val_1 = 1; - const int8_t test_val_2 = -3; - __asm__ volatile("vadd.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_1)); - __asm__ volatile("vadd.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_2)); - softrvv::vadd_vi<int8_t>(ptr_ref_vec_1, ptr_ref_vec_1, test_val_1, avl); - softrvv::vadd_vi<int8_t>(ptr_ref_vec_1, ptr_ref_vec_1, test_val_2, avl); - __asm__ volatile("vse8.v v8, (%0)" : : "r"(ptr_vec_1)); - assert_vec_elem_eq<int8_t>(vlmax, test_vector_1, reference_vector_1); - } -} - -#define DEFINE_TEST_VADD_VI(_SEW_, _LMUL_, TEST_VAL_1, TEST_VAL_2) \ - TEST_F(VaddViTest, vadd_vi##_SEW_##m##_LMUL_) { \ - for (int i = 0; i < AVL_COUNT; i++) { \ - int32_t avl = AVLS[i]; \ - int vlmax; \ - int vl; \ - std::tie(vlmax, vl) = vector_test_setup<int##_SEW_##_t>( \ - VLMUL::LMUL_M##_LMUL_, avl, {test_vector_1, reference_vector_1}); \ - if (avl > vlmax) { \ - continue; \ - } \ - int##_SEW_##_t *ptr_vec_1 = \ - reinterpret_cast<int##_SEW_##_t *>(test_vector_1); \ - int##_SEW_##_t *ptr_ref_vec_1 = \ - reinterpret_cast<int##_SEW_##_t *>(reference_vector_1); \ - const int##_SEW_##_t test_val_1 = TEST_VAL_1; \ - const int##_SEW_##_t test_val_2 = TEST_VAL_2; \ - __asm__ volatile("vadd.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_1)); \ - __asm__ volatile("vadd.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_2)); \ - softrvv::vadd_vi<int##_SEW_##_t>(ptr_ref_vec_1, ptr_ref_vec_1, \ - test_val_1, avl); \ - softrvv::vadd_vi<int##_SEW_##_t>(ptr_ref_vec_1, ptr_ref_vec_1, \ - test_val_2, avl); \ - __asm__ volatile("vse" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_1)); \ - assert_vec_elem_eq<int##_SEW_##_t>(vlmax, test_vector_1, \ - reference_vector_1); \ - } \ - } - -// TODO(gkielian): modify macro to permit more than one test per sew/lmul pair -DEFINE_TEST_VADD_VI(8, 1, -16, 15) -DEFINE_TEST_VADD_VI(8, 2, -2, 3) -DEFINE_TEST_VADD_VI(8, 4, 15, 15) -DEFINE_TEST_VADD_VI(8, 8, -15, -15) - -DEFINE_TEST_VADD_VI(16, 1, -16, 15) -DEFINE_TEST_VADD_VI(16, 2, -2, 3) -DEFINE_TEST_VADD_VI(16, 4, 15, 15) -DEFINE_TEST_VADD_VI(16, 8, -15, -15) - -DEFINE_TEST_VADD_VI(32, 1, -16, 15) -DEFINE_TEST_VADD_VI(32, 2, -2, 3) -DEFINE_TEST_VADD_VI(32, 4, 15, 15) -DEFINE_TEST_VADD_VI(32, 8, -15, -15) - -} // namespace -} // namespace vadd_vi_test
diff --git a/tests/vadd_vv_test.cpp b/tests/vadd_vv_test.cpp deleted file mode 100644 index f1b7a00..0000000 --- a/tests/vadd_vv_test.cpp +++ /dev/null
@@ -1,105 +0,0 @@ -#include <limits.h> -#include <riscv_vector.h> -#include <softrvv.h> -#include <springbok.h> -#include <stdio.h> -#include <stdlib.h> - -#include <bit> -#include <tuple> - -#include "pw_unit_test/framework.h" -#include "test_v_helpers.h" - -namespace vadd_vv_test { -namespace { - -using namespace test_v_helpers; - -uint8_t test_vector_1[MAXVL_BYTES]; -uint8_t reference_vector_1[MAXVL_BYTES]; - -class VaddVxTest : public ::testing::Test { - protected: - void SetUp() override { zero_vector_registers(); } - void TearDown() override { zero_vector_registers(); } -}; - -// Below is a demo Test for convenient debugging -// Currently disabled, so remove "DISABLED_" prefix to enable this test -TEST_F(VaddVxTest, DISABLED_vadd_vv_demo) { - for (int i = 0; i < AVL_COUNT; i++) { - int32_t avl = AVLS[i]; - int vlmax; - int vl; - std::tie(vlmax, vl) = vector_test_setup<int8_t>( - VLMUL::LMUL_M1, avl, {test_vector_1, reference_vector_1}); - if (avl > vlmax) { - continue; - } - int8_t *ptr_vec_1 = reinterpret_cast<int8_t *>(test_vector_1); - int8_t *ptr_ref_vec_1 = reinterpret_cast<int8_t *>(reference_vector_1); - - // set up values to test up to index of the AVL - for (int idx = 0; idx < vl; idx++) { - // restrict values to valid int8_t range - ptr_vec_1[idx] = idx % (INT8_MAX) + (INT8_MIN); - reference_vector_1[idx] = ptr_vec_1[idx]; - } - __asm__ volatile("vle8.v v8, (%0)" : : "r"(ptr_vec_1)); - __asm__ volatile("vadd.vv v8, v8, v8"); - softrvv::vadd_vv<int8_t>(ptr_ref_vec_1, ptr_ref_vec_1, ptr_ref_vec_1, avl); - __asm__ volatile("vse8.v v8, (%0)" : : "r"(ptr_vec_1)); - assert_vec_elem_eq<int8_t>(vlmax, test_vector_1, reference_vector_1); - } -} - -#define DEFINE_TEST_VADD_VV(_SEW_, _LMUL_) \ - TEST_F(VaddVxTest, vadd_vv##_SEW_##m##_LMUL_) { \ - for (int i = 0; i < AVL_COUNT; i++) { \ - int32_t avl = AVLS[i]; \ - int vlmax; \ - int vl; \ - std::tie(vlmax, vl) = vector_test_setup<int##_SEW_##_t>( \ - VLMUL::LMUL_M##_LMUL_, avl, {test_vector_1, reference_vector_1}); \ - if (avl > vlmax) { \ - continue; \ - } \ - int##_SEW_##_t *ptr_vec_1 = \ - reinterpret_cast<int##_SEW_##_t *>(test_vector_1); \ - int##_SEW_##_t *ptr_ref_vec_1 = \ - reinterpret_cast<int##_SEW_##_t *>(reference_vector_1); \ - \ - for (long long idx = 0; idx < avl; idx++) { \ - ptr_vec_1[idx] = idx % INT##_SEW_##_MAX + INT##_SEW_##_MIN; \ - ptr_ref_vec_1[idx] = ptr_vec_1[idx]; \ - } \ - \ - __asm__ volatile("vle" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_1)); \ - __asm__ volatile("vadd.vv v8, v8, v8"); \ - softrvv::vadd_vv<int##_SEW_##_t>(ptr_ref_vec_1, ptr_ref_vec_1, \ - ptr_ref_vec_1, avl); \ - __asm__ volatile("vse" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_1)); \ - assert_vec_elem_eq<int##_SEW_##_t>(vlmax, test_vector_1, \ - reference_vector_1); \ - } \ - } // namespace - -// TODO(gkielian): modify macro to permit more than one test per sew/lmul pair -DEFINE_TEST_VADD_VV(8, 1) -DEFINE_TEST_VADD_VV(8, 2) -DEFINE_TEST_VADD_VV(8, 4) -DEFINE_TEST_VADD_VV(8, 8) - -DEFINE_TEST_VADD_VV(16, 1) -DEFINE_TEST_VADD_VV(16, 2) -DEFINE_TEST_VADD_VV(16, 4) -DEFINE_TEST_VADD_VV(16, 8) - -DEFINE_TEST_VADD_VV(32, 1) -DEFINE_TEST_VADD_VV(32, 2) -DEFINE_TEST_VADD_VV(32, 4) -DEFINE_TEST_VADD_VV(32, 8) - -} // namespace -} // namespace vadd_vv_test
diff --git a/tests/vadd_vx_test.cpp b/tests/vadd_vx_test.cpp deleted file mode 100644 index 88ae686..0000000 --- a/tests/vadd_vx_test.cpp +++ /dev/null
@@ -1,92 +0,0 @@ -#include <limits.h> -#include <riscv_vector.h> -#include <softrvv.h> -#include <springbok.h> -#include <stdio.h> -#include <stdlib.h> - -#include <bit> -#include <tuple> - -#include "pw_unit_test/framework.h" -#include "test_v_helpers.h" - -namespace vadd_vx_test { -namespace { - -using namespace test_v_helpers; - -uint8_t test_vector_1[MAXVL_BYTES]; -uint8_t reference_vector_1[MAXVL_BYTES]; - -class VaddVxTest : public ::testing::Test { - protected: - void SetUp() override { zero_vector_registers(); } - void TearDown() override { zero_vector_registers(); } -}; - -// Below is a non-macro version of the test for more convenient debugging. -// Remove the "DISABLED_" prefix to enable this test for debugging. -TEST_F(VaddVxTest, DISABLED_vadd_vx_demo) { - for (int i = 0; i < AVL_COUNT; i++) { - int32_t avl = AVLS[i]; - int vlmax; - int vl; - std::tie(vlmax, vl) = vector_test_setup<int8_t>( - VLMUL::LMUL_M1, avl, {test_vector_1, reference_vector_1}); - if (avl > vlmax) { - continue; - } - int8_t *ptr_vec_1 = reinterpret_cast<int8_t *>(test_vector_1); - int8_t *ptr_ref_vec_1 = reinterpret_cast<int8_t *>(reference_vector_1); - int8_t test_val = 8; - __asm__ volatile("vadd.vx v8, v8, %[RS1]" ::[RS1] "r"(test_val)); - softrvv::vadd_vx<int8_t>(ptr_ref_vec_1, ptr_ref_vec_1, &test_val, avl); - __asm__ volatile("vse8.v v8, (%0)" : : "r"(ptr_vec_1)); - assert_vec_elem_eq<int8_t>(vlmax, test_vector_1, reference_vector_1); - } -} - -#define DEFINE_TEST_VADD_VX(_SEW_, _LMUL_, TEST_VAL) \ - TEST_F(VaddVxTest, vadd_vx##_SEW_##m##_LMUL_) { \ - for (int i = 0; i < AVL_COUNT; i++) { \ - int32_t avl = AVLS[i]; \ - int vlmax; \ - int vl; \ - std::tie(vlmax, vl) = vector_test_setup<int##_SEW_##_t>( \ - VLMUL::LMUL_M##_LMUL_, avl, {test_vector_1, reference_vector_1}); \ - if (avl > vlmax) { \ - continue; \ - } \ - int##_SEW_##_t *ptr_vec_1 = \ - reinterpret_cast<int##_SEW_##_t *>(test_vector_1); \ - int##_SEW_##_t *ptr_ref_vec_1 = \ - reinterpret_cast<int##_SEW_##_t *>(reference_vector_1); \ - const int##_SEW_##_t test_val = TEST_VAL; \ - __asm__ volatile("vadd.vx v8, v8, %[RS1]" ::[RS1] "r"(test_val)); \ - softrvv::vadd_vx<int##_SEW_##_t>(ptr_ref_vec_1, ptr_ref_vec_1, \ - &test_val, avl); \ - __asm__ volatile("vse" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_1)); \ - assert_vec_elem_eq<int##_SEW_##_t>(vlmax, test_vector_1, \ - reference_vector_1); \ - } \ - } - -// TODO(gkielian): modify macro to permit more than one test per sew/lmul pair -DEFINE_TEST_VADD_VX(8, 1, INT8_MIN) -DEFINE_TEST_VADD_VX(8, 2, INT8_MAX) -DEFINE_TEST_VADD_VX(8, 4, -1) -DEFINE_TEST_VADD_VX(8, 8, 2) - -DEFINE_TEST_VADD_VX(16, 1, INT16_MIN) -DEFINE_TEST_VADD_VX(16, 2, INT16_MAX) -DEFINE_TEST_VADD_VX(16, 4, -1) -DEFINE_TEST_VADD_VX(16, 8, 2) - -DEFINE_TEST_VADD_VX(32, 1, INT32_MIN) -DEFINE_TEST_VADD_VX(32, 2, INT32_MAX) -DEFINE_TEST_VADD_VX(32, 4, -1) -DEFINE_TEST_VADD_VX(32, 8, 2) - -} // namespace -} // namespace vadd_vx_test
diff --git a/tests/vand_vi_test.cpp b/tests/vand_vi_test.cpp deleted file mode 100644 index 9d53f97..0000000 --- a/tests/vand_vi_test.cpp +++ /dev/null
@@ -1,108 +0,0 @@ -#include <limits.h> -#include <riscv_vector.h> -#include <springbok.h> -#include <stdio.h> -#include <stdlib.h> - -#include <bit> -#include <tuple> - -#include "pw_unit_test/framework.h" -#include "test_v_helpers.h" - -namespace vand_vi_test { -namespace { - -using namespace test_v_helpers; - -uint8_t test_vector_1[MAXVL_BYTES]; -uint8_t test_vector_2[MAXVL_BYTES]; - -class VandViTest : public ::testing::Test { - protected: - void SetUp() override { zero_vector_registers(); } - void TearDown() override { zero_vector_registers(); } -}; - -// Below is a non-macro version of the test for more convenient debugging. -// Remove the "DISABLED_" prefix to enable this test for debugging. -TEST_F(VandViTest, DISABLED_vand_vi_demo) { - for (int i = 0; i < AVL_COUNT; i++) { - int32_t avl = AVLS[i]; - int vlmax; - int vl; - std::tie(vlmax, vl) = vector_test_setup<int8_t>( - VLMUL::LMUL_M1, avl, test_vector_1, test_vector_2); - if (avl > vlmax) { - continue; - } - int8_t *ptr_vec_1 = reinterpret_cast<int8_t *>(test_vector_1); - int8_t *ptr_vec_2 = reinterpret_cast<int8_t *>(test_vector_2); - const int8_t test_val_1 = INT8_MIN; - const int8_t test_val_2 = 15; // range of SIMM5 is [-16, 15] - for (int i = 0; i < vl; i++) { - ptr_vec_1[i] = test_val_1; - } - __asm__ volatile("vle8.v v8, (%0)" : : "r"(ptr_vec_1)); - __asm__ volatile("vand.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_2)); - for (int i = 0; i < vl; i++) { - ptr_vec_1[i] = test_val_1 & test_val_2; - } - __asm__ volatile("vse8.v v8, (%0)" : : "r"(ptr_vec_2)); - assert_vec_elem_eq<int8_t>(vlmax, test_vector_1, test_vector_2); - } -} - -#define DEFINE_TEST_VAND_VI(_SEW_, _LMUL_, TEST_VAL_1, TEST_VAL_2) \ - TEST_F(VandViTest, vand_vi##_SEW_##m##_LMUL_) { \ - for (int i = 0; i < AVL_COUNT; i++) { \ - int32_t avl = AVLS[i]; \ - int vlmax; \ - int vl; \ - std::tie(vlmax, vl) = vector_test_setup<int##_SEW_##_t>( \ - VLMUL::LMUL_M##_LMUL_, avl, test_vector_1, test_vector_2); \ - if (avl > vlmax) { \ - continue; \ - } \ - int##_SEW_##_t *ptr_vec_1 = \ - reinterpret_cast<int##_SEW_##_t *>(test_vector_1); \ - int##_SEW_##_t *ptr_vec_2 = \ - reinterpret_cast<int##_SEW_##_t *>(test_vector_2); \ - const int##_SEW_##_t test_val_1 = TEST_VAL_1; \ - const int##_SEW_##_t test_val_2 = TEST_VAL_2; \ - for (int i = 0; i < vl; i++) { \ - ptr_vec_1[i] = test_val_1; \ - } \ - __asm__ volatile("vle" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_1)); \ - __asm__ volatile("vand.vi v8, v8, %[SIMM5]" ::[SIMM5] "n"(test_val_2)); \ - for (int i = 0; i < vl; i++) { \ - ptr_vec_1[i] = test_val_1 & test_val_2; \ - } \ - __asm__ volatile("vse" #_SEW_ ".v v8, (%0)" : : "r"(ptr_vec_2)); \ - assert_vec_elem_eq<int##_SEW_##_t>(vlmax, test_vector_1, test_vector_2); \ - } \ - } - -// TODO(gkielian): modify macro to permit more than one test per sew/lmul pair - -// Macro Usage Note: -// First value just needs to be within SEW range -// Second value needs to be within range [-16, 15] (SIMM5 range) -DEFINE_TEST_VAND_VI(8, 1, INT8_MIN, 15) -DEFINE_TEST_VAND_VI(8, 2, INT8_MAX, 3) -DEFINE_TEST_VAND_VI(8, 4, -1, 15) -DEFINE_TEST_VAND_VI(8, 8, 0, -16) - -DEFINE_TEST_VAND_VI(16, 1, INT16_MIN, 15) -DEFINE_TEST_VAND_VI(16, 2, INT16_MAX, 3) -DEFINE_TEST_VAND_VI(16, 4, -1, 15) -DEFINE_TEST_VAND_VI(16, 8, 0, -16) - -DEFINE_TEST_VAND_VI(32, 1, INT32_MIN, 15) -DEFINE_TEST_VAND_VI(32, 2, INT32_MAX, 3) -DEFINE_TEST_VAND_VI(32, 4, -1, 15) -DEFINE_TEST_VAND_VI(32, 8, 0, -16) - -} // namespace -} // namespace vand_vi_test -
diff --git a/tests/vec_cc_generated_test.cmake b/tests/vec_cc_generated_test.cmake new file mode 100644 index 0000000..43a10ff --- /dev/null +++ b/tests/vec_cc_generated_test.cmake
@@ -0,0 +1,39 @@ +function(vec_cc_generated_test) + cmake_parse_arguments( + _RULE + "" + "NAME" + "OPFMT;LINKOPTS;TIMEOUT" + ${ARGN} + ) + +set(_OPCODE "${_RULE_NAME}") + +foreach(_OPFMT ${_RULE_OPFMT}) +string(TOLOWER ${_OPFMT} _LOWER_OPFMT) +set(_TEST_SRC ${CMAKE_CURRENT_BINARY_DIR}/generated/${_OPCODE}/${_OPCODE}_${_LOWER_OPFMT}_test.cpp) +add_custom_command( + OUTPUT + ${_TEST_SRC} + DEPENDS + ${CMAKE_CURRENT_SOURCE_DIR}/templates/${_LOWER_OPFMT}_test.tpl.cpp + COMMAND python3 ${CMAKE_CURRENT_SOURCE_DIR}/scripts/generate_vector_tests.py + --template-path=${CMAKE_CURRENT_SOURCE_DIR}/templates/ + --instruction-format ${_OPFMT} + --op-code ${_OPCODE} + --out-path=${CMAKE_CURRENT_BINARY_DIR}/generated/${_OPCODE} +) +list (APPEND _TEST_SRCS "${_TEST_SRC}") +endforeach() + +vec_cc_test( + NAME + ${_OPCODE}_test + SRCS + ${_TEST_SRCS} + LINKOPTS + ${_RULE_LINKOPTS} + TIMEOUT + ${_RULE_TIMEOUT} +) +endfunction()