Repository: OpenMined/PySyft

Issue:
Fix parameter serialization
In some situations, parameters are not serialized properly. I suspect this is due to our implementation of parameter.data

Here is one example:
```python
class Net(sy.Plan):
    def __init__(self):
        super(Net, self).__init__()
        self.fc1 = nn.Linear(1, 1)

    def forward(self, x):
        return self.fc1(x)

plan = Net()
plan.build(th.tensor([1.2]))

x = th.tensor([-1.0])
expected = plan(x)

plan.fix_precision().share(alice, bob, crypto_provider=charlie)
print(plan.state.tensors())
ptr_plan = plan.send(james)

# Fetch plan
fetched_plan = plan.owner.fetch_plan(ptr_plan.id_at_location, james)
print('***')
print(fetched_plan.state.tensors())
```
Output
```
[Parameter containing:
(Wrapper)>FixedPrecisionTensor>[AdditiveSharingTensor]
	-> [PointerTensor | me:94226517866 -> alice:74685210613]
	-> [PointerTensor | me:30028513485 -> bob:91228892047]
	*crypto provider: charlie*, Parameter containing:
(Wrapper)>FixedPrecisionTensor>[AdditiveSharingTensor]
	-> [PointerTensor | me:16955185561 -> alice:5015164314]
	-> [PointerTensor | me:77573712688 -> bob:21883177159]
	*crypto provider: charlie*]
***
[FixedPrecisionTensor>[AdditiveSharingTensor]
	-> [PointerTensor | me:94226517866 -> alice:74685210613]
	-> [PointerTensor | me:30028513485 -> bob:91228892047]
	*crypto provider: charlie*, FixedPrecisionTensor>[AdditiveSharingTensor]
	-> [PointerTensor | me:16955185561 -> alice:5015164314]
	-> [PointerTensor | me:77573712688 -> bob:21883177159]
	*crypto provider: charlie*]
```


Discussion:
I can take a look

Resolving patch:
diff --git a/syft/execution/placeholder.py b/syft/execution/placeholder.py
--- a/syft/execution/placeholder.py
+++ b/syft/execution/placeholder.py
@@ -30,12 +30,10 @@ def instantiate(self, tensor):
         Add a tensor as a child attribute. All operations on the placeholder will be also
         executed on this child tensor.
 
-        We remove wrappers or Placeholders if is there are any.
+        We remove Placeholders if is there are any.
         """
         if isinstance(tensor, PlaceHolder):
             self.child = tensor.child
-        elif tensor.is_wrapper:
-            self.instantiate(tensor.child)
         else:
             self.child = tensor
         return self


Test patch:
diff --git a/test/execution/test_plan.py b/test/execution/test_plan.py
--- a/test/execution/test_plan.py
+++ b/test/execution/test_plan.py
@@ -7,6 +7,7 @@
 import torch.optim as optim
 
 import syft as sy
+from itertools import starmap
 from syft.generic.pointers.pointer_tensor import PointerTensor
 from syft.generic.frameworks.types import FrameworkTensor
 from syft.execution.plan import Plan
@@ -641,6 +642,13 @@ def forward(self, x):
     assert th.all(decrypted - expected.detach() < 1e-2)
     # assert fetched_plan.state.state_placeholders != plan.state.state_placeholders #TODO
 
+    assert all(
+        starmap(
+            lambda fetched_tensor, tensor: (fetched_tensor == tensor).get(),
+            zip(fetched_plan.state.tensors(), plan.state.tensors()),
+        )
+    )
+
     # Make sure fetched_plan is using the readable_plan
     assert fetched_plan.forward is None
     assert fetched_plan.is_built