Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for aten::remainder.Tensor_out for MPS backend #87582

Closed
wants to merge 1 commit into from

Conversation

yash-dani
Copy link

Fixes #86806

@pytorch-bot pytorch-bot bot added ciflow/mps Run MPS tests (subset of trunk) release notes: mps Release notes category labels Oct 24, 2022
@pytorch-bot
Copy link

pytorch-bot bot commented Oct 24, 2022

🔗 Helpful Links

🧪 See artifacts and rendered test results at hud.pytorch.org/pr/87582

Note: Links to docs will display an error until the docs builds have been completed.

❌ 2 Failures

As of commit 5219485:

The following jobs have failed:

This comment was automatically generated by Dr. CI and updates every 15 minutes.

@linux-foundation-easycla
Copy link

linux-foundation-easycla bot commented Oct 24, 2022

CLA Not Signed

@bdhirsh bdhirsh added the triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module label Oct 27, 2022
@gpomeranz
Copy link

Hi @yash-dani , thanks so much for working on this! I seem to be having this exact issue when running pytorch on my M1, but the build you suggested is failing, same as above. Any chacne you could have a second to look at it?

Thank you so much for doing this :)

Kind regards,
Gideon

@@ -231,5 +231,24 @@ void unary_op(const Tensor& self, const Tensor& output, std::string op_name, Una
});
}


TORCH_IMPL_FUNC(remainder_out_mps) (const Tensor& self, const Tensor& output) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

This function definition is not correct. Infact it should be in BinaryOps.mm.
Please take a look at the formula to implement:
https://pytorch.org/docs/stable/generated/torch.remainder.html

@kulinseth
Copy link
Collaborator

I have attached the patch , which should work.
patch.txt

@kulinseth
Copy link
Collaborator

@yash-dani , can you rebase and apply the patch.

@gpomeranz
Copy link

Hi @kulinseth not sure if it would help but maybe I can take this over? I tried to apply the patch to a git copy of the current pytorch repository but was not able to compile on my M1, but happy to fork my own pytorch and apply this patch?

Kind regards,
Gideon

@gpomeranz
Copy link

I've also send a pull request to @yash-dani where I rebased his repo and added the patch.

@yash-dani
Copy link
Author

I can rebase and merge!

@yash-dani
Copy link
Author

Hey @kulinseth @gpomeranz your patch gives me the following compile error:

error: patch failed: aten/src/ATen/native/mps/operations/BinaryOps.mm:330
error: aten/src/ATen/native/mps/operations/BinaryOps.mm: patch does not apply
error: patch failed: aten/src/ATen/native/native_functions.yaml:8802
error: aten/src/ATen/native/native_functions.yaml: patch does not apply
error: patch failed: test/test_mps.py:8143
error: test/test_mps.py: patch does not apply

What would be the best way to resolve? Thanks!

@kulinseth
Copy link
Collaborator

@yash-dani , seems like the patch and your branch has diverged since I had created that patch.
Can you try manually just applying the changes I suggested in the patch?

--- a/aten/src/ATen/native/mps/operations/BinaryOps.mm
+++ b/aten/src/ATen/native/mps/operations/BinaryOps.mm
@@ -330,5 +330,29 @@ Tensor floor_divide_mps(const Tensor& self, const Tensor& other) {
   mps::binaryOpTensor(self, other, Scalar(1.0), output, "logaddexp2_out_mps", logaddexp2_op_block);
 }
 
+TORCH_IMPL_FUNC(remainder_out_mps) (const Tensor& self, const Tensor& other, const Tensor& output) {
+  // torch.remainder(a, b) == a - a.div(b, rounding_mode="floor") * b
+  mps::BinaryOpBlock remainder_op_block = ^BinaryOpFn(cachedGraph, primaryCastTensor, secondaryCastTensor) {
+    MPSGraph* mpsGraph = cachedGraph->graph();
+    // Rounding is a no-op for integral types, and also a reasonable workaround
+    // For MPSGraph bug on Apple Silicon, that throws `Function floorOp_i64 was not found in the library`
+    // See https://github.com/pytorch/pytorch/issues/84995
+    auto divTensor =  [mpsGraph divisionWithPrimaryTensor:primaryCastTensor
+                                          secondaryTensor:secondaryCastTensor
+                                                     name:nil];
+    //if (([divTensor dataType] & MPSDataTypeFloatBit) != 0) {
+      divTensor =  [mpsGraph floorWithTensor:divTensor name:nil];
+    //}
+    auto mulTensor = [mpsGraph multiplicationWithPrimaryTensor:divTensor
+                                               secondaryTensor:secondaryCastTensor
+                                                          name:nil];
+    return [mpsGraph subtractionWithPrimaryTensor:primaryCastTensor
+                                       secondaryTensor:mulTensor
+                                           name: nil];
+    };
+  mps::binaryOpTensor(self, other, Scalar(1.0), output, "remainder_out_mps", remainder_op_block);
+}
+
+

Basically it need to be added to the BinaryOps.mm

@kulinseth
Copy link
Collaborator

Thanks @gpomeranz for giving it a try? What issue did you run into ?

@gpomeranz
Copy link

@kulinseth I tried to manually apply the patches in the latest branch of pytorch, as I've never applied a patch to a github repo before. I unfortunately was not able to compile pytorch, so it stopped for me there. I don't remember what the error was but I believe it has something to do with my clang compiler (even though I use the latest brew one). I will try to redownload pytorch and apply the patch and will post here what my error was.

I think if @yash-dani, who has more experience, manually adds the patch and tries to compile it will succeed.

@gpomeranz
Copy link

This is the error that I get when manually adding the patch and compiling pytorch:

/opt/homebrew/opt/llvm/bin/../include/c++/v1/__algorithm/iterator_operations.h:131:12: error: calling a private constructor of class 'c10::impl::ListElementReference<at::Tensor, std::__wrap_iter<c10::IValue *>>'
return *std::forward<_Iter>(__i);

@jinsu35
Copy link
Contributor

jinsu35 commented Jan 13, 2023

@yash-dani , seems like the patch and your branch has diverged since I had created that patch. Can you try manually just applying the changes I suggested in the patch?

--- a/aten/src/ATen/native/mps/operations/BinaryOps.mm
+++ b/aten/src/ATen/native/mps/operations/BinaryOps.mm
@@ -330,5 +330,29 @@ Tensor floor_divide_mps(const Tensor& self, const Tensor& other) {
   mps::binaryOpTensor(self, other, Scalar(1.0), output, "logaddexp2_out_mps", logaddexp2_op_block);
 }
 
+TORCH_IMPL_FUNC(remainder_out_mps) (const Tensor& self, const Tensor& other, const Tensor& output) {
+  // torch.remainder(a, b) == a - a.div(b, rounding_mode="floor") * b
+  mps::BinaryOpBlock remainder_op_block = ^BinaryOpFn(cachedGraph, primaryCastTensor, secondaryCastTensor) {
+    MPSGraph* mpsGraph = cachedGraph->graph();
+    // Rounding is a no-op for integral types, and also a reasonable workaround
+    // For MPSGraph bug on Apple Silicon, that throws `Function floorOp_i64 was not found in the library`
+    // See https://github.com/pytorch/pytorch/issues/84995
+    auto divTensor =  [mpsGraph divisionWithPrimaryTensor:primaryCastTensor
+                                          secondaryTensor:secondaryCastTensor
+                                                     name:nil];
+    //if (([divTensor dataType] & MPSDataTypeFloatBit) != 0) {
+      divTensor =  [mpsGraph floorWithTensor:divTensor name:nil];
+    //}
+    auto mulTensor = [mpsGraph multiplicationWithPrimaryTensor:divTensor
+                                               secondaryTensor:secondaryCastTensor
+                                                          name:nil];
+    return [mpsGraph subtractionWithPrimaryTensor:primaryCastTensor
+                                       secondaryTensor:mulTensor
+                                           name: nil];
+    };
+  mps::binaryOpTensor(self, other, Scalar(1.0), output, "remainder_out_mps", remainder_op_block);
+}
+
+

Basically it need to be added to the BinaryOps.mm

You do need this conditional block to handle a MPS bug.

if (([divTensor dataType] & MPSDataTypeFloatBit) != 0) {
    divTensor =  [mpsGraph floorWithTensor:divTensor name:nil];
}

I applied the patch to the latest of master in PR #92139

@gpomeranz
Copy link

I can confirm that the above change indeed fixes the build problems and I was able to build pytorch from source using this code addition to the latest release.

Looking forward to have this incorporated so that I can run my gpu accelerated code in R!

@vishank97
Copy link

Hi,
Any update on the fix? I'm still getting the error and I don't if there's a fix available yet. @yash-dani @gpomeranz @kulinseth

@kulinseth
Copy link
Collaborator

We have pulled in the remainder PR.

@kulinseth
Copy link
Collaborator

@yash-dani , please re-open if you think we missed something.

@kulinseth kulinseth closed this Mar 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
ciflow/mps Run MPS tests (subset of trunk) open source release notes: mps Release notes category triaged This issue has been looked at a team member, and triaged and prioritized into an appropriate module
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[MPS] Add support for aten::remainder.Tensor_out for MPS backend
7 participants