How to run ciphertext conversion with 2^14 slots in 60G memory

You have to extract each piece of 2^{11}, then add and rotate it 2^{15}/2^{11} times.

    // Step 1: Setup CryptoContext
    uint32_t multDepth = 2;
    uint32_t scaleModSize = 50;
    uint32_t batchSizeIn = 16;
    uint32_t batchSizeOut = 4;
    uint32_t ringDim = 2*batchSizeIn;

    CCParams<CryptoContextCKKSRNS> parameters;
    parameters.SetMultiplicativeDepth(multDepth);
    parameters.SetScalingModSize(scaleModSize);
    parameters.SetBatchSize(batchSizeIn);
    parameters.SetRingDim(ringDim);
    parameters.SetSecurityLevel(HEStd_NotSet);

    CryptoContext<DCRTPoly> cc = GenCryptoContext(parameters);

    cc->Enable(PKE);
    cc->Enable(KEYSWITCH);
    cc->Enable(LEVELEDSHE);

    // Step 2: Key Generation
    auto keys = cc->KeyGen();
    cc->EvalMultKeyGen(keys.secretKey);
    int32_t index1 = batchSizeOut;
    int32_t index2 = 2*batchSizeOut;
    int32_t index3 = 3*batchSizeOut;
    cc->EvalRotateKeyGen(keys.secretKey, {index1, index2, index3});

    // Step 3: Encoding and encryption of inputs

    // Input
    std::vector<double> x1 = {0.0, 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0};

    // Encoding as plaintexts
    Plaintext ptxt1 = cc->MakeCKKSPackedPlaintext(x1);

    std::cout << "Input x: " << ptxt1 << std::endl;

    // Encrypt the encoded vector
    auto c1 = cc->Encrypt(keys.publicKey, ptxt1);

    // Create a multiplicative mask to extract the smaller vectors
    std::vector<double> mask(batchSizeIn);
    std::transform(mask.begin(), mask.begin()+batchSizeOut, mask.begin(), [&](const double& elem) { return 1.0; });
    Plaintext ptxtMask = cc->MakeCKKSPackedPlaintext(mask, 1, 0, nullptr, batchSizeIn);

    // Construct four sparsely-packed ciphertexts
    auto c1M = cc->EvalMult(c1, ptxtMask);
    auto c2M = cc->EvalMult(cc->EvalRotate(c1, index1), ptxtMask);
    auto c3M = cc->EvalMult(cc->EvalRotate(c1, index2), ptxtMask);
    auto c4M = cc->EvalMult(cc->EvalRotate(c1, index3), ptxtMask);

    for (uint32_t j = 1; j < batchSizeIn / batchSizeOut; j <<= 1) {
        auto temp = cc->EvalAtIndex(c1M, j * batchSizeOut);
        cc->EvalAddInPlace(c1M, temp);
        temp = cc->EvalAtIndex(c2M, j * batchSizeOut);
        cc->EvalAddInPlace(c2M, temp);
        temp = cc->EvalAtIndex(c3M, j * batchSizeOut);
        cc->EvalAddInPlace(c3M, temp);
        temp = cc->EvalAtIndex(c4M, j * batchSizeOut);
        cc->EvalAddInPlace(c4M, temp);
    }
    c1M->SetSlots(batchSizeOut);
    c2M->SetSlots(batchSizeOut);
    c3M->SetSlots(batchSizeOut);
    c4M->SetSlots(batchSizeOut);

    Plaintext result;
    cc->Decrypt(keys.secretKey, c1M, &result);
    std::cout << "First quarter = " << result << std::endl;

    cc->Decrypt(keys.secretKey, c2M, &result);
    std::cout << "Second quarter = " << result << std::endl;

    cc->Decrypt(keys.secretKey, c3M, &result);
    std::cout << "Third quarter = " << result << std::endl;

    cc->Decrypt(keys.secretKey, c4M, &result);
    std::cout << "Fourth quarter = " << result << std::endl;

    return 0;