OpenFHE SetSlots method: what is the usage scenario?

I know slots is something like the batch size. What is the usage scenario of SetSlots method?
In a machine learning application, the size of cipher text will become smaller due to downsampling, can OpenFHE change batch size or slots dynamically to enable sparse packing and then make bootstrap faster?

Yep, I guess you can

SetSlots can be used to treat the current CKKS ciphertext as a sparse ciphertext (subring element). However, internally this means that a smaller vector has to be cloned as many times as needed to fill the maximum number of slots (half the ring dimension in CKKS). If this ciphertext is not set up this way, the result will be incorrect. GetSlots() is used during CKKS bootstrapping, and during encoding/decoding. All of these run faster for sparse ciphertexts. Note that the number of slots should be set accordingly in EvalBootstrapSetup and EvalBootstrapKeyGen to make bootstrapping faster for sparse ciphertexts.

Thanks for the explanation. Because the size of valid ciphertext is changed in my application. When it becomes smaller, before doing bootstrap, I use setSlots method to set to the small value(the size of currently valid cipher text), but after bootstrap, the value is incorrect.
For example:
The ring dimension is 65536. At first, the size of valid cipher text is 16384. After some computations, the size of valid cipher text becomes 32768. Then 8192, then 4096. I want to change the slots size to these small value to make bootstrapping faster. But Using setSlots method make the results become incorrect.
Could you tell me why? And how can I improve it? Thanks

On which numSlot did you run the bootstrap setup?

When SetSlots is set to a smaller value, you want to make sure that the sparsely packed ciphertext is a proper subring element for the desired number of slots. For example, let N be the ring dimension and n the desired number of slots, a subring element with n slots is formed by cloning the n-sized vector \frac{N}{2n} times. CKKS bootstrapping will work correctly only if the sparsely packed ciphertext is cloned this way.

A naive way to achieve this is by clearing all slots above n (multiply by a binary mask) and then cloning the vector using rotations and additions (similar to EvalSum). This does consume one level. If you can achieve this cloned structure in the previous step, then the extra cost of one level can be avoided.

1 Like

In addition to proper cloning of the ciphertext, EvalBootstrapSetup and EvalBootstrapKeyGen should be called for that value of numSlots, as pointed out by @narger.

after clear/rotate/addition, it works, thanks.

what is the cloned format? a0b0c0 or abcabc?

Cloning means repetition, so your input will be repeated abcabc, in the sense that you will have batch_size | batch_size | … | batch_size for the ring_dimension / batch_size times.