We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Implement Default Absolute Value Functions in Base Tensor Type
**User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing the elementwise absolute value of a Tensor of arbitrary type. abs() should return a new tensor and abs_ should perform the operation inline. For a great reference on how 

**Acceptance Criteria:**
- If the Base Tensor type's attribute "encrypted" is set to True, it should return a NotImplemented error.
- a unit test demonstrating the correct operation of abs() and abs_() on the Base Tensor type implemented over int and float Tensors.
- inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.
Implement Default addmm Functionality in Base Tensor Type
**User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing each operation on a Tensor of arbitrary type. addmm_() should return a new tensor and addmm_() should perform the operation inline. For a reference on the operation this performs check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation.

**Acceptance Criteria:**
- If the Base Tensor type's attribute "encrypted" is set to True, it should return a NotImplemented error.
- a unit test demonstrating the correct operation of addmm() and addmm_() on the Base Tensor type implemented over int and float Tensors.
- inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `syft/tensor.py`
Content:
```
1 import numpy as np
2 
3 def _ensure_ndarray(arr):
4     if not isinstance(arr, np.ndarray):
5         arr = np.array(arr)
6 
7     return arr
8 
9 class TensorBase(object):
10     """
11     A base tensor class that perform basic element-wise operation such as
12     addition, subtraction, multiplication and division
13     """
14 
15     def __init__(self, arr_like, encrypted=False):
16         self.data = _ensure_ndarray(arr_like)
17         self.encrypted = encrypted
18 
19     def __add__(self, arr_like):
20         """Performs element-wise addition between two array like objects"""
21         if self.encrypted:
22             return NotImplemented
23 
24         arr_like = _ensure_ndarray(arr_like)
25         return self.data + arr_like
26 
27     def __iadd__(self, arr_like):
28         """Performs in place element-wise addition between two array like objects"""
29         if self.encrypted:
30             return NotImplemented
31 
32         arr_like = _ensure_ndarray(arr_like)
33         self.data = self.data + arr_like
34         return self.data
35 
36     def __sub__(self, arr_like):
37         """Performs element-wise subtraction between two array like objects"""
38         if self.encrypted:
39             return NotImplemented
40 
41         arr_like = _ensure_ndarray(arr_like)
42         return self.data - arr_like
43 
44     def __isub__(self, arr_like):
45         """Performs in place element-wise subtraction between two array like objects"""
46         if self.encrypted:
47             return NotImplemented
48 
49         arr_like = _ensure_ndarray(arr_like)
50         self.data = self.data - arr_like
51         return self.data
52 
53     def __mul__(self, arr_like):
54         """Performs element-wise multiplication between two array like objects"""
55         if self.encrypted:
56             return NotImplemented
57 
58         arr_like = _ensure_ndarray(arr_like)
59         return self.data * arr_like
60 
61     def __imul__(self, arr_like):
62         """Performs in place element-wise multiplication between two array like objects"""
63         if self.encrypted:
64             return NotImplemented
65 
66         arr_like = _ensure_ndarray(arr_like)
67         self.data = self.data * arr_like
68         return self.data
69 
70     def __truediv__(self, arr_like):
71         """Performs element-wise division between two array like objects"""
72         if self.encrypted:
73             return NotImplemented
74 
75         arr_like = _ensure_ndarray(arr_like)
76         return self.data / arr_like
77 
78     def __itruediv__(self, arr_like):
79         """Performs in place element-wise subtraction between two array like objects"""
80         if self.encrypted:
81             return NotImplemented
82 
83         arr_like = _ensure_ndarray(arr_like)
84         self.data = self.data / arr_like
85         return self.data
86 
87     def shape(self):
88         """Returns a tuple of input array dimensions."""
89         if self.encrypted:
90             return NotImplemented
91 
92         return self.data.shape
93 
94     def sum(self, dim=None):
95         """Returns the sum of all elements in the input array."""
96         if self.encrypted:
97             return NotImplemented
98 
99         if dim is None:
100             return self.data.sum()
101         else:
102             return self.data.sum(axis=dim)
103
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/syft/tensor.py b/syft/tensor.py
--- a/syft/tensor.py
+++ b/syft/tensor.py
@@ -84,6 +84,19 @@
         self.data = self.data / arr_like
         return self.data
 
+    def abs(self):
+        """Returns absolute value of tensor as a new tensor"""
+        if self.encrypted:
+            return NotImplemented
+        return np.absolute(self.data)
+    
+    def abs_(self):
+        """Replaces tensor values with its absolute value"""
+        if self.encrypted:
+            return NotImplemented
+        self.data=np.absolute(self.data)
+        return self.data
+
     def shape(self):
         """Returns a tuple of input array dimensions."""
         if self.encrypted:
@@ -100,3 +113,33 @@
             return self.data.sum()
         else:
             return self.data.sum(axis=dim)
+     
+     def addmm(self,tensor2,mat,beta=1,alpha=1):
+        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor
+            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
+            *If both tensors are 1-dimensional, their dot product is returned.
+            *If both arguments are 2-D they are multiplied like conventional matrices.
+            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
+            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
+            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
+            """
+        if self.encrypted or tensor2.encrypted or mat.encrypted:
+            return NotImplemented
+        else:
+            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))
+
+    def addmm_(self,tensor2,mat,beta=1,alpha=1):
+        """Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it
+            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.
+            *If both tensors are 1-dimensional, their dot product is returned.
+            *If both arguments are 2-D they are multiplied like conventional matrices.
+            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.
+            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.
+            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.
+            """
+        if self.encrypted is True or tensor2.encrypted is True or mat.encrypted is True:
+            return NotImplemented
+        else:
+            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))
+            return self
+

{"golden_diff": "diff --git a/syft/tensor.py b/syft/tensor.py\n--- a/syft/tensor.py\n+++ b/syft/tensor.py\n@@ -84,6 +84,19 @@\n         self.data = self.data / arr_like\n         return self.data\n \n+    def abs(self):\n+        \"\"\"Returns absolute value of tensor as a new tensor\"\"\"\n+        if self.encrypted:\n+            return NotImplemented\n+        return np.absolute(self.data)\n+    \n+    def abs_(self):\n+        \"\"\"Replaces tensor values with its absolute value\"\"\"\n+        if self.encrypted:\n+            return NotImplemented\n+        self.data=np.absolute(self.data)\n+        return self.data\n+\n     def shape(self):\n         \"\"\"Returns a tuple of input array dimensions.\"\"\"\n         if self.encrypted:\n@@ -100,3 +113,33 @@\n             return self.data.sum()\n         else:\n             return self.data.sum(axis=dim)\n+     \n+     def addmm(self,tensor2,mat,beta=1,alpha=1):\n+        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor\n+            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n+            *If both tensors are 1-dimensional, their dot product is returned.\n+            *If both arguments are 2-D they are multiplied like conventional matrices.\n+            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n+            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n+            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n+            \"\"\"\n+        if self.encrypted or tensor2.encrypted or mat.encrypted:\n+            return NotImplemented\n+        else:\n+            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))\n+\n+    def addmm_(self,tensor2,mat,beta=1,alpha=1):\n+        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it\n+            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n+            *If both tensors are 1-dimensional, their dot product is returned.\n+            *If both arguments are 2-D they are multiplied like conventional matrices.\n+            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n+            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n+            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n+            \"\"\"\n+        if self.encrypted is True or tensor2.encrypted is True or mat.encrypted is True:\n+            return NotImplemented\n+        else:\n+            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))\n+            return self\n+\n", "issue": "Implement Default Absolute Value Functions in Base Tensor Type\n**User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing the elementwise absolute value of a Tensor of arbitrary type. abs() should return a new tensor and abs_ should perform the operation inline. For a great reference on how \r\n\r\n**Acceptance Criteria:**\r\n- If the Base Tensor type's attribute \"encrypted\" is set to True, it should return a NotImplemented error.\r\n- a unit test demonstrating the correct operation of abs() and abs_() on the Base Tensor type implemented over int and float Tensors.\r\n- inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.\nImplement Default addmm Functionality in Base Tensor Type\n**User Story A:** As a Data Scientist using Syft's Base Tensor type, we want to implement a default method for computing each operation on a Tensor of arbitrary type. addmm_() should return a new tensor and addmm_() should perform the operation inline. For a reference on the operation this performs check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation.\r\n\r\n**Acceptance Criteria:**\r\n- If the Base Tensor type's attribute \"encrypted\" is set to True, it should return a NotImplemented error.\r\n- a unit test demonstrating the correct operation of addmm() and addmm_() on the Base Tensor type implemented over int and float Tensors.\r\n- inline documentation in the python code. For inspiration on inline documentation, please check out [PyTorch](http://pytorch.org/docs/master/tensors.html)'s documentation for this operator.\n", "before_files": [{"content": "import numpy as np\n\ndef _ensure_ndarray(arr):\n    if not isinstance(arr, np.ndarray):\n        arr = np.array(arr)\n\n    return arr\n\nclass TensorBase(object):\n    \"\"\"\n    A base tensor class that perform basic element-wise operation such as\n    addition, subtraction, multiplication and division\n    \"\"\"\n\n    def __init__(self, arr_like, encrypted=False):\n        self.data = _ensure_ndarray(arr_like)\n        self.encrypted = encrypted\n\n    def __add__(self, arr_like):\n        \"\"\"Performs element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data + arr_like\n\n    def __iadd__(self, arr_like):\n        \"\"\"Performs in place element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data + arr_like\n        return self.data\n\n    def __sub__(self, arr_like):\n        \"\"\"Performs element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data - arr_like\n\n    def __isub__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data - arr_like\n        return self.data\n\n    def __mul__(self, arr_like):\n        \"\"\"Performs element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data * arr_like\n\n    def __imul__(self, arr_like):\n        \"\"\"Performs in place element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data * arr_like\n        return self.data\n\n    def __truediv__(self, arr_like):\n        \"\"\"Performs element-wise division between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data / arr_like\n\n    def __itruediv__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data / arr_like\n        return self.data\n\n    def shape(self):\n        \"\"\"Returns a tuple of input array dimensions.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        return self.data.shape\n\n    def sum(self, dim=None):\n        \"\"\"Returns the sum of all elements in the input array.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        if dim is None:\n            return self.data.sum()\n        else:\n            return self.data.sum(axis=dim)\n", "path": "syft/tensor.py"}], "after_files": [{"content": "import numpy as np\n\ndef _ensure_ndarray(arr):\n    if not isinstance(arr, np.ndarray):\n        arr = np.array(arr)\n\n    return arr\n\nclass TensorBase(object):\n    \"\"\"\n    A base tensor class that perform basic element-wise operation such as\n    addition, subtraction, multiplication and division\n    \"\"\"\n\n    def __init__(self, arr_like, encrypted=False):\n        self.data = _ensure_ndarray(arr_like)\n        self.encrypted = encrypted\n\n    def __add__(self, arr_like):\n        \"\"\"Performs element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data + arr_like\n\n    def __iadd__(self, arr_like):\n        \"\"\"Performs in place element-wise addition between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data + arr_like\n        return self.data\n\n    def __sub__(self, arr_like):\n        \"\"\"Performs element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data - arr_like\n\n    def __isub__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data - arr_like\n        return self.data\n\n    def __mul__(self, arr_like):\n        \"\"\"Performs element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data * arr_like\n\n    def __imul__(self, arr_like):\n        \"\"\"Performs in place element-wise multiplication between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data * arr_like\n        return self.data\n\n    def __truediv__(self, arr_like):\n        \"\"\"Performs element-wise division between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        return self.data / arr_like\n\n    def __itruediv__(self, arr_like):\n        \"\"\"Performs in place element-wise subtraction between two array like objects\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        arr_like = _ensure_ndarray(arr_like)\n        self.data = self.data / arr_like\n        return self.data\n\n    def abs(self):\n        \"\"\"Returns absolute value of tensor as a new tensor\"\"\"\n        if self.encrypted:\n            return NotImplemented\n        return np.absolute(self.data)\n    \n    def abs_(self):\n        \"\"\"Replaces tensor values with its absolute value\"\"\"\n        if self.encrypted:\n            return NotImplemented\n        self.data=np.absolute(self.data)\n        return self.data\n\n    def shape(self):\n        \"\"\"Returns a tuple of input array dimensions.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        return self.data.shape\n\n    def sum(self, dim=None):\n        \"\"\"Returns the sum of all elements in the input array.\"\"\"\n        if self.encrypted:\n            return NotImplemented\n\n        if dim is None:\n            return self.data.sum()\n        else:\n            return self.data.sum(axis=dim)\n     \n     def addmm(self,tensor2,mat,beta=1,alpha=1):\n        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and  returns the result as a Tensor\n            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n            *If both tensors are 1-dimensional, their dot product is returned.\n            *If both arguments are 2-D they are multiplied like conventional matrices.\n            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n            \"\"\"\n        if self.encrypted or tensor2.encrypted or mat.encrypted:\n            return NotImplemented\n        else:\n            return TensorBase(np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha)))\n\n    def addmm_(self,tensor2,mat,beta=1,alpha=1):\n        \"\"\"Performs ((Mat*Beta)+((Tensor1.Tensor2)*Alpha)) and updates Tensor1 with result and reurns it\n            Tensor1.Tensor2 is performed as Matrix product of two array The behavior depends on the arguments in the following way.\n            *If both tensors are 1-dimensional, their dot product is returned.\n            *If both arguments are 2-D they are multiplied like conventional matrices.\n            *If either argument is N-D, N > 2, it is treated as a stack of matrices residing in the last two indexes and broadcast accordingly.\n            *If the first argument is 1-D, it is promoted to a matrix by prepending a 1 to its dimensions. After matrix multiplication the prepended 1 is removed.\n            *If the second argument is 1-D, it is promoted to a matrix by appending a 1 to its dimensions. After matrix multiplication the appended 1 is removed.\n            \"\"\"\n        if self.encrypted is True or tensor2.encrypted is True or mat.encrypted is True:\n            return NotImplemented\n        else:\n            self.data=np.array((mat*beta)+((np.matmul(self.data,tensor2.data))*alpha))\n            return self\n\n", "path": "syft/tensor.py"}]}