Skip to content

LinearOp IR node#2240

Merged
Priya2698 merged 30 commits intomainfrom
pm/linearop
May 17, 2024
Merged

LinearOp IR node#2240
Priya2698 merged 30 commits intomainfrom
pm/linearop

Conversation

@Priya2698
Copy link
Collaborator

@Priya2698 Priya2698 commented May 14, 2024

  1. Add a LinearOp node that has the same functionality as F.linear.
  2. Update linear_op_generator to cover all cases allowed in thunder / F.linear.

Issue #2149, #2132.

if opinfo.symbolic_parameter_list is None:
opinfo.symbolic_parameter_list = [ArgumentType.Symbolic] * len(args)
num_symbolic_parameters = len(opinfo.symbolic_parameter_list)
symbolic_parameter_list = (
Copy link
Collaborator Author

@Priya2698 Priya2698 May 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Avoid updating opinfo.symbolic_parameter_list directly since ops like linear can have variable number of parameters which throws an error for the linear input generator which can have 2 /3 arguments.

@Priya2698 Priya2698 marked this pull request as ready for review May 14, 2024 05:37
@Priya2698
Copy link
Collaborator Author

!build

Comment on lines +605 to +607
testing::Values(Sizes({k}), Sizes({m, k}), Sizes({b, m, k})),
testing::Values(Sizes({n, k})),
testing::Values(Sizes({n}))));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add broadcast dims here?

Comment on lines +1533 to +1534
shapes_input = ((K), (M, K), (B, M, K))
shapes_weight = ((K), (N, K))
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we test with broadcasts? What about more than one batch dim?

Copy link
Collaborator

@jacobhinkle jacobhinkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking good. I had a few minor questions but the only thing I think is missing is a test for IterDomain mapping like in #2246.

std::vector<IterDomain*> out_domain = ops::newOutputDomain({mapping_a, mapping_b});
for (auto idx : c10::irange(ndims_out)) {
std::vector<IterDomain*> input_ids;
input_ids.reserve(2);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: if input_ids.size() is not always 2 then just skip reserving.

Comment on lines +203 to +235
// Check if the producer is A, B or bias.
std::optional<MatmulRole> input_role = std::nullopt;
if (producer->sameAs(op->inA()->as<TensorView>()->domain())) {
input_role = MatmulRole::INPUT_A;
} else if (producer->sameAs(op->inB()->as<TensorView>()->domain())) {
input_role = MatmulRole::INPUT_B;
} else if (producer->sameAs(op->bias()->as<TensorView>()->domain())){
input_role = MatmulRole::INPUT_C;
} else {
NVF_ERROR(false, "Producer did not match any LinearOp input.")
}

// LinearOp:
// inputs (INPUT_A) = {*, in_features}
// weight (INPUT_B) = {out_features, in_features} / {in_features}
// bias (INPUT_C) = {out_features} / {}
// output = {*, out_features} / {*}

const std::vector<IterDomain*>& aligned_producer_ids =
ops::mapLinearOpIterDomains(producer_root, input_role.value(), out_size);

for (auto inx : c10::irange(out_size)) {
IterDomain* producer_id = aligned_producer_ids.at(inx);
IterDomain* consumer_id = consumer_root.at(inx);
if (producer_id == nullptr) {
continue;
}
updatePairwiseRootDomainMap(producer_id, consumer_id);
}

return dom_map;
}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth reusing some of this code between matmul and linear? I am not sure if anything but the last loop can be re-used but it seems like there might be a way since the patterns are so similar.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll put the last loop in a separate fn atleast. Will see if combining the rest of the snippet is clean enough or not since we will still need to distinguish between matmul/linear

@Priya2698
Copy link
Collaborator Author

!build

Sizes({1, 1}),
Sizes({b, 1, n}))));

INSTANTIATE_TEST_SUITE_P(
Copy link
Collaborator Author

@Priya2698 Priya2698 May 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I still need to think about a good naming scheme: Underscore separated shapes looked too verbose and for filtering we will need the exact shapes in that case.

Copy link
Collaborator

@jacobhinkle jacobhinkle left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for adding the ID mapping checks.

@Priya2698 Priya2698 merged commit 7fd7bce into main May 17, 2024
@Priya2698 Priya2698 deleted the pm/linearop branch May 17, 2024 18:08
Priya2698 added a commit that referenced this pull request May 18, 2024
1. Add a `LinearOp` node that has the same functionality as `F.linear`.
2. Update `linear_op_generator` to cover all cases allowed in thunder /
`F.linear`.

Issue #2149, #2132.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants