| 41 | |
| 42 | template <typename ctype> |
| 43 | void do_print_host_val( |
| 44 | FILE* fout, size_t max_nr_print, const megdnn::TensorND& val, bool print_stat) { |
| 45 | bool first = true; |
| 46 | fprintf(fout, "["); |
| 47 | size_t nr_print = 0; |
| 48 | for (ctype i : megdnn::tensor_iter_valonly<ctype>(val)) { |
| 49 | if (first) { |
| 50 | first = false; |
| 51 | } else |
| 52 | fprintf(fout, ", "); |
| 53 | if (++nr_print > max_nr_print) { |
| 54 | fprintf(fout, "..."); |
| 55 | break; |
| 56 | } |
| 57 | fprintf(fout, "%.4g", as_double(i)); |
| 58 | } |
| 59 | fprintf(fout, "]"); |
| 60 | |
| 61 | if (!print_stat) |
| 62 | return; |
| 63 | |
| 64 | ctype min(megdnn::DTypeTrait<ctype>::max()), max(megdnn::DTypeTrait<ctype>::min()); |
| 65 | double sum1 = 0, sum2 = 0; |
| 66 | auto update = [&](ctype i) { |
| 67 | min = std::min(i, min); |
| 68 | max = std::max(i, max); |
| 69 | sum1 += as_double(i); |
| 70 | sum2 += as_double(i) * as_double(i); |
| 71 | }; |
| 72 | size_t nr = val.layout.total_nr_elems(); |
| 73 | bool normal_contig = !val.layout.dtype.is_low_bit() && val.layout.is_contiguous(); |
| 74 | bool lowbit_contig = |
| 75 | val.layout.dtype.is_low_bit() && val.layout.is_physical_contiguous(); |
| 76 | if (normal_contig || lowbit_contig) { |
| 77 | ctype* ptr = val.ptr<ctype>(); |
| 78 | for (size_t i = 0; i < nr; ++i) { |
| 79 | update(ptr[i]); |
| 80 | } |
| 81 | } else { |
| 82 | for (ctype i : megdnn::tensor_iter_valonly<ctype>(val)) { |
| 83 | update(i); |
| 84 | } |
| 85 | } |
| 86 | fprintf(fout, "min=%.3g max=%.3g mean=%.3g l2=%.3g", as_double(min), as_double(max), |
| 87 | sum1 / nr, std::sqrt(sum2 / nr)); |
| 88 | if (nr > 1) { |
| 89 | fprintf(fout, " sd=%.3g", |
| 90 | std::sqrt((sum2 * nr - sum1 * sum1) / (nr * (nr - 1)))); |
| 91 | } else { |
| 92 | fprintf(fout, " sd=N/A"); |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | void print_host_val( |
| 97 | FILE* fout, size_t max_nr_print, const megdnn::TensorND& val, |
nothing calls this directly
no test coverage detected