* Makes all the shapes in the dynamic_dimension range. Probably won't work for `if` * and `loop` instructions, depending on how the submodules for those * work. Inserts select_module instruction to the top. Replaces return, bypassing other * instructions. Skips if the dynamic parameter outputs to a select_module operator. */
| 116 | * instructions. Skips if the dynamic parameter outputs to a select_module operator. |
| 117 | */ |
| 118 | void split_single_dyn_dim::apply(module_pass_manager& mpm) const |
| 119 | { |
| 120 | module_ref mm = &mpm.get_module(); |
| 121 | auto param_names = mm->get_parameter_names(); |
| 122 | auto param_shapes = mm->get_parameter_shapes(); |
| 123 | optional<std::vector<dynamic_dimensions_check>> dd_check_vec = |
| 124 | has_one_unique_dyn_dim(param_shapes); |
| 125 | if(dd_check_vec.has_value() and not any_sm_next(mm, dd_check_vec.value())) |
| 126 | { |
| 127 | // all dynamic dimension objects should be the same for all parameters in dd_check_vec |
| 128 | auto dyn_dim = dd_check_vec->at(0).dd; |
| 129 | // create submodules for each dimension size |
| 130 | std::vector<module_ref> submodules; |
| 131 | for(size_t dim_size : migraphx::range(dyn_dim.min, dyn_dim.max + 1)) |
| 132 | { |
| 133 | auto* submod = mpm.create_module("dim_" + std::to_string(dim_size)); |
| 134 | // instruction map for new static shaped submodule parameters |
| 135 | std::unordered_map<instruction_ref, instruction_ref> map_ins; |
| 136 | for(const auto& dd_check : dd_check_vec.value()) |
| 137 | { |
| 138 | // create static shape using dim_size |
| 139 | const auto& dyn_param = mm->get_parameter(dd_check.dyn_param_str); |
| 140 | auto dyn_param_shape = mm->get_parameter_shape(dd_check.dyn_param_str); |
| 141 | auto static_shape = dyn_param_shape.to_static(dim_size); |
| 142 | map_ins[dyn_param] = submod->add_parameter(dd_check.dyn_param_str, static_shape); |
| 143 | } |
| 144 | auto outputs = submod->add_instructions(mm, &map_ins); |
| 145 | submod->add_return({outputs}); |
| 146 | submodules.push_back(submod); |
| 147 | } |
| 148 | // sort parameters by name for consistency (vs. parameter order attr) |
| 149 | std::sort(param_names.begin(), param_names.end()); |
| 150 | // redirect to select_module operator and return |
| 151 | std::vector<instruction_ref> sm_inputs; |
| 152 | std::transform(param_names.cbegin(), |
| 153 | param_names.cend(), |
| 154 | std::back_inserter(sm_inputs), |
| 155 | [&](auto pn) { return mm->get_parameter(std::move(pn)); }); |
| 156 | auto output_shapes = mm->get_output_shapes(); |
| 157 | migraphx::shape out_attr = migraphx::shape{output_shapes}; |
| 158 | auto sm_ins = mm->add_instruction( |
| 159 | migraphx::make_op("select_module", |
| 160 | {{"output_dyn_shapes", migraphx::to_value(out_attr)}}), |
| 161 | sm_inputs, |
| 162 | submodules); |
| 163 | std::vector<instruction_ref> outputs(output_shapes.size()); |
| 164 | for(size_t i = 0; i < output_shapes.size(); ++i) |
| 165 | { |
| 166 | outputs.at(i) = |
| 167 | mm->add_instruction(migraphx::make_op("get_tuple_elem", {{"index", i}}), sm_ins); |
| 168 | } |
| 169 | mm->replace_return(outputs); |
| 170 | } |
| 171 | } |
| 172 | |
| 173 | } // namespace MIGRAPHX_INLINE_NS |
| 174 | } // namespace migraphx |
nothing calls this directly
no test coverage detected