| 359 | |
| 360 | template <typename ctype> |
| 361 | Maybe<std::string> do_compare_tensor_value( |
| 362 | const char* expr0, const char* expr1, const HostTensorND& v0, |
| 363 | const HostTensorND& v1, float maxerr) { |
| 364 | auto it0 = megdnn::tensor_iter<ctype>(v0.as_megdnn()).begin(), |
| 365 | it1 = megdnn::tensor_iter<ctype>(v1.as_megdnn()).begin(); |
| 366 | for (size_t i = 0, it = v0.shape().total_nr_elems(); i < it; ++i) { |
| 367 | typename RealCtype<ctype>::ctype iv0 = RealCtype<ctype>::trans(*it0), |
| 368 | iv1 = RealCtype<ctype>::trans(*it1); |
| 369 | double err = std::abs(iv0 - iv1) / |
| 370 | std::max<double>( |
| 371 | 1, std::min( |
| 372 | std::abs(static_cast<double>(iv0)), |
| 373 | std::abs((static_cast<double>(iv1))))); |
| 374 | if (!good_float(iv0) || !good_float(iv1) || err >= maxerr) { |
| 375 | TensorShape idx_shp; |
| 376 | idx_shp.ndim = v0.shape().ndim; |
| 377 | std::copy(it0.idx(), it0.idx() + idx_shp.ndim, idx_shp.shape); |
| 378 | return mgb_ssprintf_log( |
| 379 | "Unequal value\n" |
| 380 | "Value of: %s\n" |
| 381 | " Actual: %s\n" |
| 382 | "Expected: %s\n" |
| 383 | "Which is: %s\n" |
| 384 | "At index: %s/%s\n" |
| 385 | " error: %.6g", |
| 386 | expr1, num2str(iv1).c_str(), expr0, num2str(iv0).c_str(), |
| 387 | idx_shp.to_string().c_str(), v0.shape().to_string().c_str(), err); |
| 388 | } |
| 389 | |
| 390 | ++it0; |
| 391 | ++it1; |
| 392 | } |
| 393 | return None; |
| 394 | } |
| 395 | |
| 396 | } // anonymous namespace |
| 397 |
nothing calls this directly
no test coverage detected