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

TensealContext serialization #101

Merged
merged 38 commits into from
Jul 17, 2020
Merged

TensealContext serialization #101

merged 38 commits into from
Jul 17, 2020

Conversation

bcebere
Copy link
Member

@bcebere bcebere commented Jul 14, 2020

Description

  • Protobuf support
  • Context serialization/deserialization
  • gtests
  • Python support
  • Tests
  • Bonus: make_public_context crash. Fixed with a scoped guard.

Related to #72

How has this been tested?

  • gtest
  • pytest

Checklist

@bcebere bcebere added the Type: New Feature ➕ Introduction of a completely new addition to the codebase label Jul 14, 2020
@bcebere bcebere changed the title [WIP] TensealContext serialization TensealContext serialization Jul 15, 2020
@bcebere bcebere changed the title TensealContext serialization [WIP] TensealContext serialization Jul 15, 2020
@bcebere bcebere changed the title [WIP] TensealContext serialization TensealContext serialization Jul 15, 2020
@bcebere bcebere changed the title TensealContext serialization [WIP] TensealContext serialization Jul 15, 2020
@bcebere bcebere changed the title [WIP] TensealContext serialization TensealContext serialization Jul 16, 2020
@bcebere bcebere requested review from youben11 and philomath213 July 16, 2020 11:15
Copy link
Member

@youben11 youben11 left a comment

Choose a reason for hiding this comment

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

This is truly amazing! I'm really happy to see serialization working perfectly!

I left some comments and I have also a general comment about how different des/serialization methods are used, ones using strings and others using streams. I see that for the one using strings, you are first saving it into a stream than returning the string, isn't this operation more consuming than maybe calling SerializeToString on the buffer? Some function save function might than only fill the buffer, with two other function either saving using SerializeToString or SerializeToOstream, but I'm not sure if this is the right way, so your call.

@@ -52,6 +52,7 @@ jobs:
pytest -v --ignore=tests/sealapi ./tests
- name: Test with gtest
run: |
cd tenseal/proto && cmake . && make && cd ../../
Copy link
Member

Choose a reason for hiding this comment

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

isn't tenseal_protobuf built as included in the cmake file?

Copy link
Member Author

Choose a reason for hiding this comment

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

Unfortunately, here I'm missing something about cmake builds. For some reason, it doesn't generate the proto headers for the build otherwise.

On the other hand, setup.py generates them just fine, and I cannot spot the actual difference.

Copy link
Member

Choose a reason for hiding this comment

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

when I build the tenseal without BUILD_TEST argument, the build is successful.
example:
cmake .
make

we don't have to build tenseal_proto manually, but when passing the argument BUILD_TEST=TRUE, the build is failed, and we have to build tenseal_proto manually.

I think we are missing something in Unit Tests section in CMakeLists.txt file.

tenseal/__init__.py Outdated Show resolved Hide resolved
tenseal/binding.cpp Outdated Show resolved Hide resolved
tenseal/binding.cpp Outdated Show resolved Hide resolved
.github/workflows/tests.yml Show resolved Hide resolved
tenseal/proto/tensealcontext.proto Outdated Show resolved Hide resolved
Comment on lines +1 to +35
#ifndef TENSEAL_UTILS_SCOPE_H
#define TENSEAL_UTILS_SCOPE_H

#include <functional>

namespace tenseal {

class scope_guard {
public:
template <class Callable>
scope_guard(Callable&& undo_func) try
: f(std::forward<Callable>(undo_func)) {
} catch (...) {
undo_func();
throw;
}

scope_guard(scope_guard&& other) : f(std::move(other.f)) {
other.f = nullptr;
}

~scope_guard() {
if (f) f(); // must not throw
}

void dismiss() noexcept { f = nullptr; }

scope_guard(const scope_guard&) = delete;
void operator=(const scope_guard&) = delete;

private:
std::function<void()> f;
};
} // namespace tenseal
#endif
Copy link
Member

Choose a reason for hiding this comment

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

Can I know what this is doing?

Copy link
Member Author

@bcebere bcebere Jul 17, 2020

Choose a reason for hiding this comment

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

Scoped guards implement a classic C++ idiom - RAII, Resource Acquisition is Initialization. shared_ptr is another example of that.
Long story short, It will get a lambda function on the constructor, and it will call it on its destructor.
The use case is simple: I want to add some logic on a function return. For example, I want to free some resources, a create a scope guard with a lambda that frees the resources, and no matter how many returns I have in the function, the resources will get freed on exit, because the variable's destructor gets called.

As you can see, it calls on destrctuor the lambda received at creation

    ~scope_guard() {
        if (f) f(); 
    }

My issue here was that, while writing serialization test cases, I observed that when calling make_context_public with a true value for galois or relin keys, there was a crash

This is the reason, I am to blame
https://github.com/OpenMined/TenSEAL/blame/master/tenseal/tensealcontext.cpp#L124

I was making the secret key null before creating the galois/relin keys.

The fix is to create a scoped guard that will make the secret key null on exit, no matter how many conditional returns there will be. Something like this, and I'm sure it will make the secret key null everytime
https://github.com/OpenMined/TenSEAL/blob/protobuffs/tenseal/tensealcontext.cpp#L166

I hope the explanation makes sense.

Copy link
Member Author

Choose a reason for hiding this comment

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

I could open another PR for this issue, it was just a "side effect" from the serialization tests

Copy link
Member

Choose a reason for hiding this comment

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

Thanks for the explanation. It's fine to keep it in this PR, but feel free to open another one if it's convenient for you.

tests/test_serialization.py Show resolved Hide resolved
@bcebere bcebere requested a review from youben11 July 17, 2020 15:10
bcebere and others added 3 commits July 17, 2020 20:10
Co-authored-by: Bilal Retiat <bilalphilomath@gmail.com>
Co-authored-by: Bilal Retiat <bilalphilomath@gmail.com>
Co-authored-by: Bilal Retiat <bilalphilomath@gmail.com>
bcebere and others added 2 commits July 17, 2020 20:17
Co-authored-by: Bilal Retiat <bilalphilomath@gmail.com>
Copy link
Member

@youben11 youben11 left a comment

Choose a reason for hiding this comment

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

Awesome!

Copy link
Member

@philomath213 philomath213 left a comment

Choose a reason for hiding this comment

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

Great Work !!

@bcebere bcebere merged commit 6e31894 into master Jul 17, 2020
@delete-merged-branch delete-merged-branch bot deleted the protobuffs branch July 17, 2020 19:48
pierreeliseeflory pushed a commit to pierreeliseeflory/TenSEAL that referenced this pull request Apr 27, 2022
* add protobuffers
* add serialization logic for SEAL objects
* add serialization methods for context
* overwrite deepcopy & pickle logic with protobuffers serialization
* pytests&gtests
* make_public_context crash. Fixed with a scoped guard.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: New Feature ➕ Introduction of a completely new addition to the codebase
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants