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

Quesiton on generating C++ header for FHE Circuit Using Concrete-Python Frontend #1179

Open
duhaode520 opened this issue Dec 11, 2024 · 2 comments

Comments

@duhaode520
Copy link

Hello,

I am trying to set up a workflow where I compile some FHE circuits using the concrete-python frontend and then call these circuits from another project using C++. I have noticed that the compiled circuit includes sharedlib.so library file, leading me to believe this workflow is feasible. What remains is figuring out how to obtain the corresponding header file.

However, I've encountered an issue. The LibrarySupport class's initialization includes a generateCppHeader parameter, which I expected to facilitate the generation of the necessary C++ header.

It appears though, that this parameter does not function as intended; it seems to be ignored in the C++ code .

library_support(const char *outputPath, const char *runtimeLibraryPath,
bool generateSharedLib, bool generateStaticLib,
bool generateClientParameters, bool generateCompilationFeedback,
bool generateCppHeader) {
return LibrarySupport_Py{mlir::concretelang::LibrarySupport(
outputPath, runtimeLibraryPath, generateSharedLib, generateStaticLib,
generateClientParameters, generateCompilationFeedback)};
}

The official documentation provides examples indicating that C++ can indeed be used to call the circuits, including an example with concrete-compiler that compiles MLIR and produces a header file. (https://docs.zama.ai/concrete/developers/contributing/call_from_other_language)

Could you please guide me on how to properly generate the required .h and corresponding .so lib files using Python code? The concrete version I'm working on is v2.8.1

Thank you for your assistance.

@BourgerieQuentin
Copy link
Member

Hello @duhaode520, indeed the generation of cpp headers has been removed but in fact it was mostly experimental and not actually usefull for cpp integration.
In 2.8.1 the documention seems to be good as LibrarySupport is still alive and I guess you can freely ignore that the compilation flag is ignored as we rely on client parameters (json file) and shared library (so file) to make the things works.

There was a big refactoring of client/server API tools since 2.8.1, so we should udpate this part of the documentation by using the updated API. But in few words, with the new cpp API, when you have compiler artifacts in a ARTIFACT_PATH you should rely on:

// Get program info using the Library or unserialize yourself manually
mlir::concretelang::Library lib(ARTIFACT_PATH);
auto programInfo = lib.getProgramInfo().value();

// Generate keyset
concretelang::keysets::Keyset keyset(programInfo.asReader().getKeyset(), 0, 0);

// Setup ServerProgram
mlir::concretelang::ServerProgram server(programInfo, lib.getSharedLibraryPath());

// Setup ClientProgram
auto clientProgram = mlir::concretelang::ClientProgram::createEncrypted (programInfo, keyset.client, std::make_shared<EncryptionCSPRNG>(EncryptionCSPRNG(0)));
auto clientCircuit = clientProgram.getClientCircuit("main");

// Encrypt
auto arg0 = clientCircuit.prepareInput(Value(...), 0).value();
auto arg1 = clientCircuit.prepareInput(Value(...), 1).value();
auto arg2 = clientCircuit.prepareInput(Value(...), 2).value();

// Call server side
serverCircuit = server.getServerCircuit("main");
auto results = serverCircuit.call(keyset.server, {arg0, arg1, arg2}).value();

// Decrypt
auto decrypted_0 = clientProgram.processOutput(results[0]);
auto decrypted_1 = clientProgram.processOutput(results[1]);

Disclaimer: This is just a code snippet wrote in the issue, it's not tested is just to give an overview.

@duhaode520
Copy link
Author

Thank you for providing the detailed examples. I will give it a try to see if this works. BTW do I need to use the concrete-python frontend compiled from the main branch to replace the current version 2.8.1? I am not sure if there will be any compatibility issues between the circuits produced by the older frontend and the latest version of concrete-compile compiled from the source code.

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

No branches or pull requests

2 participants