def check_correctness(input_img, output): torch_pool1 = torch.nn.MaxPool2d(2) x = input_img.to(Config.device).double() x = x.reshape([1] + list(x.shape)) x = pmod(F.conv2d(x, conv1_w.to(Config.device).double(), padding=1), q_23) x = pmod(F.relu(nmod(x, q_23)), q_23) x = pmod(torch_pool1(nmod(x, q_23)), q_23) x = pmod(x // (2**pow_to_div), q_23) x = pmod(F.conv2d(x, conv2_w.to(Config.device).double(), padding=1), q_23) x = x.view(-1) x = pmod( torch.mm(x.view(1, -1), fc1_w.to(Config.device).double().t()).view(-1), q_23) expected = x actual = pmod(output, q_23) if len(expected.shape) == 4 and expected.shape[0] == 1: expected = expected.reshape(expected.shape[1:]) compare_expected_actual(expected, actual, name=test_name, get_relative=True)
def shift_by_exp(data, exp, mode="stochastic"): d = (2**-exp) p = modulus x = data # r = torch.zeros_like(x).uniform_(0, p-1).type(torch.int32).float() # r = torch.zeros_like(x).type(torch.int32).float() # n_elem = data.numel() # r = torch.arange(n_elem).cuda().reshape_as(x) # r = torch.from_numpy(np.random.uniform(0, p-1, size=x.numel())).cuda()\ # .type(torch.int32).type(torch.float).reshape(x.size()) n_elem = data.numel() meta_rg = MetaTruncRandomGenerator() rg = meta_rg.get_rg("plain") r = rg.gen_uniform(n_elem, p).cuda().reshape_as(x) x = nmod(x, p) x = F.relu(x) # x = pmod(x, p) # return torch.floor(x/d) psum_xr = pmod(x + r, p) # print("(psum_xr < r):", torch.mean((psum_xr < r).float()).item()) wrapped = nmod(psum_xr // d - r // d + p // d, p) unwrapped = nmod(psum_xr // d - r // d, p) # return unwrapped # x = unwrapped # x = F.relu(x) # return x x = torch.where(psum_xr < r, wrapped, unwrapped) return x
def correctness_vgg(self, input_img, output, modulus): return torch_pool1 = torch.nn.MaxPool2d(2) torch_pool2 = torch.nn.MaxPool2d(2) x = input_img.cuda().double() x = x.reshape([1] + list(x.shape)) x = pmod(F.conv2d(x, self.layers[1].weight.cuda().double(), padding=1), modulus) x = pmod(F.relu(nmod(x, modulus)), modulus) x = pmod(F.conv2d(x, self.layers[3].weight.cuda().double(), padding=1), modulus) x = pmod(torch_pool1(nmod(x, modulus)), modulus) x = pmod(F.relu(nmod(x, modulus)), modulus) x = pmod(F.conv2d(x, self.layers[6].weight.cuda().double(), padding=1), modulus) x = pmod(F.relu(nmod(x, modulus)), modulus) x = pmod(F.conv2d(x, self.layers[8].weight.cuda().double(), padding=1), modulus) x = pmod(torch_pool2(nmod(x, modulus)), modulus) x = pmod(F.relu(nmod(x, modulus)), modulus) x = pmod(F.conv2d(x, self.layers[11].weight.cuda().double(), padding=1), modulus) x = pmod(F.relu(nmod(x, modulus)), modulus) x = pmod(F.conv2d(x, self.layers[13].weight.cuda().double(), padding=1), modulus) x = pmod(F.relu(nmod(x, modulus)), modulus) x = pmod(F.conv2d(x, self.layers[15].weight.cuda().double(), padding=1), modulus) x = pmod(F.relu(nmod(x, modulus)), modulus) x = x.view(-1) x = pmod(torch.mm(x.view(1, -1), self.layers[18].weight.cuda().double().t()).view(-1), modulus) expected = x actual = pmod(output, modulus) if len(expected.shape) == 4 and expected.shape[0] == 1: expected = expected.reshape(expected.shape[1:]) compare_expected_actual(expected, actual, name="minionn_mnist", get_relative=True)
def check_correctness(self, verify_func, is_argmax=False, truth=None): blob_input_img = BlobTorch(self.get_input_shape(), torch.float, self.comm_base, "input_img") blob_actual_output = BlobTorch(self.get_output_shape(), torch.float, self.comm_base, "actual_output") blob_truth = BlobTorch(1, torch.float, self.comm_base, "truth") if self.is_server(): blob_input_img.prepare_recv() blob_actual_output.prepare_recv() blob_truth.prepare_recv() torch_sync() input_img = blob_input_img.get_recv() actual_output = blob_actual_output.get_recv() truth = int(blob_truth.get_recv().item()) verify_func(self, input_img, actual_output, self.q_23) actual_output = nmod(actual_output, self.q_23).cuda() _, actual_max = torch.max(actual_output, 0) print(f"truth: {truth}, actual: {actual_max}, MatchTruth: {truth == actual_max}") if self.is_client(): torch_sync() actual_output = self.secure_nn_core.get_argmax_output() if is_argmax else self.secure_nn_core.get_output() blob_input_img.send(self.input_img) blob_actual_output.send(actual_output) blob_truth.send(torch.tensor(truth)) return self
def check_correctness(self, input_img, output, modulus): plain_net = get_plain_net() expected = plain_net( input_img.reshape([1] + list(input_img.shape)).cuda()) expected = nmod(expected.reshape(expected.shape[1:]), modulus) actual = nmod(output, modulus).cuda() print("expected", expected) print("actual", actual) compare_expected_actual(expected, actual, name="secure_vgg", get_relative=True) _, expected_max = torch.max(expected, 0) _, actual_max = torch.max(actual, 0) print( f"expected_max: {expected_max}, actual_max: {actual_max}, Match: {expected_max == actual_max}" )
def correctness_relu_only_nn(self, input_img, output, modulus): x = input_img.cuda().double() x = x.reshape([1] + list(x.shape)) x = pmod(F.relu(nmod(x, modulus)), modulus) expected = x actual = pmod(output, modulus) if len(expected.shape) == 4 and expected.shape[0] == 1: expected = expected.reshape(expected.shape[1:]) compare_expected_actual(expected, actual, name="relu_only_nn", get_relative=True)
def forward(ctx, input, weight, store_configs, bias=None, layer_name=None): layer_op_name = layer_name + "Forward" output_q = input.mm(weight.t()) output_q = output_q + bias output_q = nmod(output_q, modulus) output = post_layer_shift(output_q, layer_op_name, store_configs) return output
def correctness_maxpool2x2(self, input_img, output, modulus): torch_pool1 = torch.nn.MaxPool2d(2) x = input_img.cuda().double() x = x.reshape([1] + list(x.shape)) x = pmod(torch_pool1(nmod(x, modulus)), modulus) expected = x actual = pmod(output, modulus) if len(expected.shape) == 4 and expected.shape[0] == 1: expected = expected.reshape(expected.shape[1:]) compare_expected_actual(expected, actual, name="maxpool2x2", get_relative=True)
def reconstructed_to_server(self, comm_base: CommBase, modulus): blob_output_share = BlobTorch(self.get_output_shape(), torch.float, comm_base, self.name + "_output_share") if self.is_server(): blob_output_share.prepare_recv() torch_sync() other_output_share = blob_output_share.get_recv() # print(self.name + "_output_share" + "_server: have", self.get_output_share()) # print(self.name + "_output_share" + "_server: received", other_output_share) self.reconstructed_output = nmod( self.get_output_share() + other_output_share, modulus) # print(self.name + "_output_share" + "_server: recon", self.reconstructed_output) if self.is_client(): torch_sync() blob_output_share.send(self.get_output_share())
def forward(ctx, input, weight, store_configs, bias=None, layer_name=None, pool=None): layer_op_name = layer_name + "Forward" output_q = F.conv2d(input, weight, bias, padding=1) #output_q = output_q + bias#unmodified output_q = nmod(output_q, modulus) if pool is not None: output_q = pool(output_q) output = post_layer_shift(output_q, layer_op_name, store_configs) return output
def mod_move_down(x): return nmod(x, modulus)