def test_ntt_lsh_method_performance(thread, single_kernel_bootstrap, heavy_performance_load, ntt_lsh_method): if thread.api.get_id() != cuda_id() and ntt_lsh_method == 'cuda_asm': pytest.skip() size = 4096 if heavy_performance_load else 64 rng = numpy.random.RandomState() secret_key, cloud_key = make_key_pair(thread, rng, transform_type='NTT') # TODO: instead of creating a whole key and then checking if the parameters are supported, # we can just create a parameter object separately. if (single_kernel_bootstrap and not single_kernel_bootstrap_supported( secret_key.params, thread.device_params)): pytest.skip() perf_params = PerformanceParameters( secret_key.params, single_kernel_bootstrap=single_kernel_bootstrap, ntt_lsh_method=ntt_lsh_method) results = check_performance(thread, (secret_key, cloud_key), perf_params, shape=size) print() print(check_performance_str(results))
def test_constant_mem_performance( thread, transform_type, single_kernel_bootstrap, heavy_performance_load, use_constant_memory): if not transform_supported(thread.device_params, transform_type): pytest.skip() # We want to test the effect of using constant memory on the bootstrap calculation. # A single-kernel bootstrap uses the `use_constant_memory_multi_iter` option, # and a multi-kernel bootstrap uses the `use_constant_memory_single_iter` option. kwds = dict(single_kernel_bootstrap=single_kernel_bootstrap) if single_kernel_bootstrap: kwds.update(dict(use_constant_memory_multi_iter=use_constant_memory)) else: kwds.update(dict(use_constant_memory_single_iter=use_constant_memory)) size = 4096 if heavy_performance_load else 64 rng = numpy.random.RandomState() secret_key, cloud_key = make_key_pair(thread, rng, transform_type=transform_type) # TODO: instead of creating a whole key and then checking if the parameters are supported, # we can just create a parameter object separately. if (single_kernel_bootstrap and not single_kernel_bootstrap_supported(secret_key.params, thread.device_params)): pytest.skip() perf_params = PerformanceParameters(secret_key.params, **kwds) results = check_performance(thread, (secret_key, cloud_key), perf_params, shape=size) print() print(check_performance_str(results))
def test_single_kernel_bs_performance( thread, transform_type, single_kernel_bootstrap, test_function_name, heavy_performance_load): if not transform_supported(thread.device_params, transform_type): pytest.skip() test_function = dict( NAND=(gate_nand, nand_ref, 2), MUX=(gate_mux, mux_ref, 3), uint_min=(uint_min, uint_min_ref, 2), )[test_function_name] if test_function_name == 'uint_min': shape = (128, 32) if heavy_performance_load else (4, 16) else: shape = 4096 if heavy_performance_load else 64 rng = numpy.random.RandomState() secret_key, cloud_key = make_key_pair(thread, rng, transform_type=transform_type) # TODO: instead of creating a whole key and then checking if the parameters are supported, # we can just create a parameter object separately. if (single_kernel_bootstrap and not single_kernel_bootstrap_supported(secret_key.params, thread.device_params)): pytest.skip() perf_params = PerformanceParameters( secret_key.params, single_kernel_bootstrap=single_kernel_bootstrap) results = check_performance( thread, (secret_key, cloud_key), perf_params, shape=shape, test_function=test_function) print() print(check_performance_str(results))
def test_single_kernel_bs(thread, key_pair, single_kernel_bootstrap): # Test a gate that employs separate calls to bootstrap and keyswitch secret_key, cloud_key = key_pair if (single_kernel_bootstrap and not single_kernel_bootstrap_supported( secret_key.params, thread.device_params)): pytest.skip() perf_params = PerformanceParameters( secret_key.params, single_kernel_bootstrap=single_kernel_bootstrap) check_gate(thread, key_pair, 3, gate_mux, mux_ref, perf_params=perf_params)
def test_single_kernel_bs_with_ks(thread, key_pair, single_kernel_bootstrap): # Test a gate that employs a bootstrap with keyswitch secret_key, cloud_key = key_pair if (single_kernel_bootstrap and not single_kernel_bootstrap_supported(secret_key.params, thread.device_params)): pytest.skip() perf_params = PerformanceParameters( secret_key.params, single_kernel_bootstrap=single_kernel_bootstrap) check_gate(thread, key_pair, 2, gate_nand, nand_ref, perf_params=perf_params)
def test_gate_over_view(thread, key_pair, single_kernel_bootstrap): secret_key, cloud_key = key_pair params = cloud_key.params if (single_kernel_bootstrap and not single_kernel_bootstrap_supported( params, thread.device_params)): pytest.skip() perf_params = PerformanceParameters( params, single_kernel_bootstrap=single_kernel_bootstrap) perf_params = perf_params.for_device(thread.device_params) nufhe_func = gate_nand reference_func = nand_ref num_arguments = 2 rng = DeterministicRNG() shape = (5, 8) # FIXME: negative steps are supported as well, but the current stable PyCUDA # has a bug where in that case it calculates strides incorrectly. # It is fixed in the trunk, so we must add some negative steps here as soon as it is released. slices1 = (slice(3, 5), slice(1, 7, 2)) slices2 = (slice(1, 3), slice(2, 8, 2)) result_slices = (slice(2, 4), slice(0, 6, 2)) plaintexts = get_plaintexts(rng, num_arguments, shape=shape) pt1 = plaintexts[0][slices1] pt2 = plaintexts[1][slices2] ciphertexts = [ encrypt(thread, rng, secret_key, plaintext) for plaintext in plaintexts ] ct1 = ciphertexts[0][slices1] ct2 = ciphertexts[1][slices2] reference = reference_func(pt1, pt2) answer = empty_ciphertext(thread, params, shape) answer_view = answer[result_slices] nufhe_func(thread, cloud_key, answer_view, ct1, ct2, perf_params=perf_params) answer_bits = decrypt(thread, secret_key, answer) answer_bits_view = answer_bits[result_slices] assert (answer_bits_view == reference).all()