HEaaN GPU API in use

1. Check GPU is available

if(!HEaaN::CudaTools::isAvailable()){
        return -1;
}

2. Make context with CUDA device ID

HEaaN::ParameterPreset preset = HEaaN::ParameterPreset::FGb;
HEaaN::Context context = makeContext(preset, {0}); // Use GPU #0
HEaaN::Context context = makeContext(preset, {0, 1}); // Use GPU #0, #1. Not supported
  • Choose ParameterPreset

    • If you plan to use bootstrapping operations, select the bootstrappable parameter. (Please refer the ParameterPreset.hpp)

  • Specify the set of device_ids recognized by the CUDA runtime.

  • Currently, since we provide a single GPU, only {0} is available.

3. Generate various keys and Send to GPU memory

HEaaN requires various keys, which need to be loaded into GPU memory for efficient computation.

You can generate various keys from KeyGenerator.

  • Note that context takes an important role in key generation step.

const auto log_slots = getLogFullSlots(context);

// Secret Key
HEaaN::SecretKey sk(context);

// Keypack
HEaaN::KeyPack pack(context);

// Key Generator
HEaaN::KeyGenerator keygen(context, sk, pack);

// Key generation
keygen.genEncKey();
keygen.genMultKey();
keygen.genConjKey();

// Key generation (for bootstrapping)
keygen.genRotKeysForBootstrap(log_slots);

Once Keys are generated, We have to send them into GPU memory.

// Send keys into GPU memory
pack.to(HEaaN::getCurrentCudaDevice());

4. [For bootstrapping] Generate Bootstrapper and Send to GPU memory

If you are interested at bootstrapping, you have to go through additional several steps.

Create the Bootstrapper which include pre-computed constants for bootstrapping.

// Create Bootstrapper
HEaaN::HomEvaluator eval(context, pack);
HEaaN::Bootstrapper btp(eval);

// Send boot constants data to GPU memory
btp.loadBootConstants(log_slots, HEaaN::getCurrentCudaDevice());

5. Create and Load message to GPU memory

Message is the data that we want to compute on in an encrypted state.

HEaaN::Message msg(log_slots);

// Example random data generation
for (size_t i = 0; i < msg.getSize(); ++i) {
    msg[i].real(randNum());
    msg[i].imag(randNum());
}

// Move to GPU memory
msg.to(HEaaN::getCurrentCudaDevice());

6. Decrypt the result ciphertext

Secret key and Data should be located in the same device.

// Send secret key into GPU memory
sk.to(HEaaN::getCurrentCudaDevice());
HEaaN::Message dmsg, dmsg_boot;

// Decryption
dec.decrypt(ctxt_rst, sk, dmsg);
dec.decrypt(ctxt_boot, sk, dmsg_boot);

7. Send result message into CPU memory

At the end of the day, bring your result to CPU memory by using the to() function.

// dmsg is the decrypted message from previous step
dmsg.to(HEaaN::getDefaultDevice());
dmsg_boot.to(HEaaN::getDefaultDevice());

Last updated

Was this helpful?