| 685 | } |
| 686 | |
| 687 | std::unique_ptr<ConvertF32ToF16Pass> ConvertF32ToF16Pass::make(bool use_f32_comp) { |
| 688 | #if MEGDNN_DISABLE_FLOAT16 |
| 689 | mgb_throw(SystemError, "float16 disabled at compile time."); |
| 690 | #else |
| 691 | auto replace_h2d_opr = [](OperatorNodeBase* opr, const VarNodeArray& new_inp) { |
| 692 | mgb_assert(opr->input().size() == new_inp.size()); |
| 693 | auto& h2d_opr = opr->cast_final_safe<opr::Host2DeviceCopy>(); |
| 694 | if (h2d_opr.output(0)->dtype() == dtype::Float32()) { |
| 695 | auto cvt_var = opr::TypeCvt::make(h2d_opr.output(0), dtype::Float16(), {}); |
| 696 | return cvt_var.node()->owner_opr(); |
| 697 | } |
| 698 | return opr; |
| 699 | }; |
| 700 | |
| 701 | auto replace_sdt_opr = [](OperatorNodeBase* opr, const VarNodeArray& new_inp) { |
| 702 | mgb_assert(opr->input().size() == new_inp.size()); |
| 703 | auto& sdt_opr = opr->cast_final_safe<opr::SharedDeviceTensor>(); |
| 704 | if (sdt_opr.output(0)->dtype() == dtype::Float32()) { |
| 705 | auto cvt_var = opr::TypeCvt::make(sdt_opr.output(0), dtype::Float16(), {}); |
| 706 | return cvt_var.node()->owner_opr(); |
| 707 | } |
| 708 | return opr; |
| 709 | }; |
| 710 | |
| 711 | auto replace_multi_sdt_opr = [](OperatorNodeBase* opr, |
| 712 | const VarNodeArray& new_inp) { |
| 713 | mgb_assert(opr->input().size() == new_inp.size()); |
| 714 | auto& multi_sdt_opr = opr->cast_final_safe<opr::MultipleDeviceTensorHolder>(); |
| 715 | |
| 716 | VarNodeArray cvt_vars; |
| 717 | cvt_vars.reserve(multi_sdt_opr.output().size()); |
| 718 | |
| 719 | for (size_t i = 0; i < multi_sdt_opr.output().size(); ++i) { |
| 720 | if (multi_sdt_opr.output(i)->dtype() == dtype::Float32()) { |
| 721 | cvt_vars.append({opr::TypeCvt::make( |
| 722 | multi_sdt_opr.output(i), dtype::Float16(), {}) |
| 723 | .node()}); |
| 724 | } else { |
| 725 | cvt_vars.append({multi_sdt_opr.output(i)}); |
| 726 | } |
| 727 | } |
| 728 | return cvt_vars; |
| 729 | }; |
| 730 | |
| 731 | auto replace_multi_sdt_with_format_opr = [](OperatorNodeBase* opr, |
| 732 | const VarNodeArray& new_inp) { |
| 733 | mgb_assert(opr->input().size() == new_inp.size()); |
| 734 | auto& multi_sdt_with_format_opr = |
| 735 | opr->cast_final_safe<opr::MultipleDeviceTensorWithFormatHolder>(); |
| 736 | |
| 737 | VarNodeArray cvt_vars; |
| 738 | cvt_vars.reserve(multi_sdt_with_format_opr.output().size()); |
| 739 | |
| 740 | for (size_t i = 0; i < multi_sdt_with_format_opr.output().size(); ++i) { |
| 741 | if (multi_sdt_with_format_opr.output(i)->dtype() == dtype::Float32()) { |
| 742 | cvt_vars.append({opr::TypeCvt::make( |
| 743 | multi_sdt_with_format_opr.output(i), |
| 744 | dtype::Float16(), {}) |
nothing calls this directly
no test coverage detected