| 43 | /* ================== FancyIndexingHelper ================== */ |
| 44 | |
| 45 | FancyIndexingHelper::FancyIndexingHelper( |
| 46 | const OperatorNodeBaseCtorParam& opr, VarNode* data, VarNode* value, |
| 47 | const IndexDesc& index_desc, bool require_scalar_index, |
| 48 | const InputTensorReplacer& input_tensor_replacer) |
| 49 | : Super(opr), |
| 50 | m_idx_inp_start{1u + (value != nullptr)}, |
| 51 | m_require_scalar_index{require_scalar_index}, |
| 52 | m_is_assign_opr{value != nullptr}, |
| 53 | m_input_tensor_replacer{input_tensor_replacer} { |
| 54 | add_input({data}); |
| 55 | if (value) { |
| 56 | add_input({value}); |
| 57 | mgb_assert( |
| 58 | data->dtype() == value->dtype(), |
| 59 | "subtensor modifier dest and value must have same dtype; got " |
| 60 | "dest=%s value=%s", |
| 61 | data->dtype().name(), value->dtype().name()); |
| 62 | } |
| 63 | add_output(None)->dtype(data->dtype()); |
| 64 | if (!require_scalar_index) { |
| 65 | cg::add_workspace_output(this); |
| 66 | } |
| 67 | init(index_desc); |
| 68 | |
| 69 | if (has_input_tensor_replacer()) { |
| 70 | mgb_assert(value); |
| 71 | output(0) |
| 72 | ->add_flag(VarNode::Flag::ALLOW_EMPTY_SHAPE) |
| 73 | .add_flag(VarNode::Flag::VOLATILE_CONTENT); |
| 74 | |
| 75 | // do not dedup |
| 76 | add_equivalence_component<ScalarHash<void*>>(this); |
| 77 | } |
| 78 | } |
| 79 | |
| 80 | void FancyIndexingHelper::init(const IndexDesc& index_desc) { |
| 81 | mgb_assert(input().size() == m_idx_inp_start); |
nothing calls this directly
no test coverage detected