| 836 | |
| 837 | template <typename Trait, typename dtype> |
| 838 | void TestRunner<Trait, dtype, true>::run() { |
| 839 | { |
| 840 | Mode mode = Trait::MODE; |
| 841 | // copy to temporary var to avoid undefined reference when linking |
| 842 | tested_mode.insert(mode); |
| 843 | } |
| 844 | |
| 845 | using ctype = typename DTypeTrait<dtype>::ctype; |
| 846 | |
| 847 | HostTensorGenerator<> gen; |
| 848 | using Config = CheckerConfig<Trait>; |
| 849 | |
| 850 | static constexpr bool TEST_REV_INP = |
| 851 | Trait::ARITY == 2 && |
| 852 | Config::allow_inp_grad(0) == Config::allow_inp_grad(1) && |
| 853 | Config::enable_binary_inp_swap(); |
| 854 | using Checker = AutoOprChecker<Trait::ARITY, TEST_REV_INP + 1, dtype>; |
| 855 | auto make_graph = [&](const typename Checker::SymInpArray& inputs) { |
| 856 | typename Checker::SymOutArray out; |
| 857 | SymbolVarArray vinp(inputs.begin(), inputs.end()); |
| 858 | out[0] = opr::Elemwise::make(vinp, Trait::MODE); |
| 859 | if (TEST_REV_INP) { |
| 860 | std::swap(vinp[0], vinp[1]); |
| 861 | out[1] = opr::Elemwise::make(vinp, Trait::MODE); |
| 862 | } |
| 863 | return out; |
| 864 | }; |
| 865 | |
| 866 | auto fwd = [&](typename Checker::NumOutArray& dest, |
| 867 | typename Checker::NumInpArray inp) { |
| 868 | dest[0].resize(inp[0]->shape()); |
| 869 | if (TEST_REV_INP) |
| 870 | dest[1].resize(inp[0]->shape()); |
| 871 | |
| 872 | std::array<const ctype*, Trait::ARITY> iptr; |
| 873 | for (size_t i = 0; i < Trait::ARITY; ++i) |
| 874 | iptr[i] = inp[i]->template ptr<ctype>(); |
| 875 | |
| 876 | size_t sz = dest[0].shape().total_nr_elems(); |
| 877 | |
| 878 | ctype* optr = dest[0].template ptr<ctype>(); |
| 879 | for (size_t i = 0; i < sz; ++i) |
| 880 | optr[i] = Trait::apply(iptr, i); |
| 881 | |
| 882 | if (TEST_REV_INP) { |
| 883 | std::swap(iptr[0], iptr[1]); |
| 884 | ctype* optr = dest[1].template ptr<ctype>(); |
| 885 | for (size_t i = 0; i < sz; ++i) |
| 886 | optr[i] = Trait::apply(iptr, i); |
| 887 | } |
| 888 | }; |
| 889 | |
| 890 | Checker checker{make_graph, fwd}; |
| 891 | checker.set_extra_err_msg(ssprintf("mode=%s", Trait::NAME)); |
| 892 | for (size_t i = 0; i < Trait::ARITY; ++i) { |
| 893 | auto func = Config::template get_inp_gen<ctype>(i); |
| 894 | if (func.valid()) |
| 895 | checker.set_input_generator(i, func.val()); |
no test coverage detected