From b94fddef95d082e5832e095121115a4aef9308d2 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 15 Jun 2024 15:09:49 +0300 Subject: [PATCH 01/69] add attack files --- src/engine/Engine.cpp | 2 +- src/engine/Preprocessor.cpp | 7 + .../.vscode/c_cpp_properties.json | 17 ++ .../attack/PGD_Linf_Rand/.vscode/launch.json | 40 +++ .../PGD_Linf_Rand/.vscode/settings.json | 82 ++++++ .../attack/PGD_Linf_Rand/.vscode/tasks.json | 22 ++ .../attack/PGD_Linf_Rand/CMakeLists.txt | 37 +++ src/engine/attack/PGD_Linf_Rand/build_net.py | 146 +++++++++++ .../PGD_Linf_Rand/example_dnn_model.nnet | 239 ++++++++++++++++++ .../attack/PGD_Linf_Rand/pgd_attack.cpp | 80 ++++++ src/engine/attack/PGD_Linf_Rand/pgd_attack.h | 20 ++ src/engine/attack/PGD_Linf_Rand/read_net.cpp | 114 +++++++++ src/engine/attack/PGD_Linf_Rand/read_net.h | 24 ++ 13 files changed, 829 insertions(+), 1 deletion(-) create mode 100644 src/engine/attack/PGD_Linf_Rand/.vscode/c_cpp_properties.json create mode 100644 src/engine/attack/PGD_Linf_Rand/.vscode/launch.json create mode 100644 src/engine/attack/PGD_Linf_Rand/.vscode/settings.json create mode 100644 src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json create mode 100644 src/engine/attack/PGD_Linf_Rand/CMakeLists.txt create mode 100644 src/engine/attack/PGD_Linf_Rand/build_net.py create mode 100644 src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet create mode 100644 src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp create mode 100644 src/engine/attack/PGD_Linf_Rand/pgd_attack.h create mode 100644 src/engine/attack/PGD_Linf_Rand/read_net.cpp create mode 100644 src/engine/attack/PGD_Linf_Rand/read_net.h diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 0fd7dfa688..299d5afd5b 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1427,7 +1427,7 @@ void Engine::initializeNetworkLevelReasoning() } } -bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) +bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) { ENGINE_LOG( "processInputQuery starting\n" ); struct timespec start = TimeUtils::sampleMicro(); diff --git a/src/engine/Preprocessor.cpp b/src/engine/Preprocessor.cpp index e4f2de17e1..5e807e4c4a 100644 --- a/src/engine/Preprocessor.cpp +++ b/src/engine/Preprocessor.cpp @@ -26,6 +26,7 @@ #include "PiecewiseLinearFunctionType.h" #include "Statistics.h" #include "Tightening.h" +#include "attack/PGD_Linf_Rand/" #ifdef _WIN32 #undef INFINITE @@ -174,6 +175,12 @@ std::unique_ptr Preprocessor::preprocess( const InputQuery &query, ASSERT( _preprocessed->getLowerBounds().size() == _preprocessed->getNumberOfVariables() ); ASSERT( _preprocessed->getUpperBounds().size() == _preprocessed->getNumberOfVariables() ); + // run the attack + String networkFilePath = Options::get()->getString( Options::INPUT_FILE_PATH ); + + + + return std::move( _preprocessed ); } diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/c_cpp_properties.json b/src/engine/attack/PGD_Linf_Rand/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000..a0aa6ead37 --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "c17", + "cppStandard": "gnu++17", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/launch.json b/src/engine/attack/PGD_Linf_Rand/.vscode/launch.json new file mode 100644 index 0000000000..042f84e355 --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/.vscode/launch.json @@ -0,0 +1,40 @@ +{ + "version": "0.2.0", + "configurations": [ + { + "name": "(gdb) Launch", + "type": "cppdbg", + "request": "launch", + "program": "/home/maya-swisa/Documents/PGD_Linf_Rand/build/PGD_Linf_Rand", + "args": [], + "stopAtEntry": false, + "cwd": "${workspaceFolder}/build", + "environment": [], + "externalConsole": false, + "MIMode": "gdb", + "setupCommands": [ + { + "description": "Enable pretty-printing for gdb", + "text": "-enable-pretty-printing", + "ignoreFailures": true + } + ], + "miDebuggerPath": "/usr/bin/gdb", + "preLaunchTask": "CMake: build", + "setupCommands": [ + { + "text": "set debuginfod enabled on" + } + ], + "logging": { + "trace": true, + "engineLogging": true, + "traceResponse": true + }, + "stopAtEntry": false, + "debugOptions": [ + "StopAtEntry" + ] + } + ] +} diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/settings.json b/src/engine/attack/PGD_Linf_Rand/.vscode/settings.json new file mode 100644 index 0000000000..63efc6aacf --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/.vscode/settings.json @@ -0,0 +1,82 @@ +{ + "python.venvPath": "/home/maya-swisa/Documents/PGD_Linf_Rand/.venv", + "C_Cpp.errorSquiggles": "disabled", + "files.associations": { + "array": "cpp", + "atomic": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "bitset": "cpp", + "cctype": "cpp", + "charconv": "cpp", + "chrono": "cpp", + "cinttypes": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "compare": "cpp", + "complex": "cpp", + "concepts": "cpp", + "condition_variable": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "forward_list": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "string": "cpp", + "unordered_map": "cpp", + "unordered_set": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "functional": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "ratio": "cpp", + "regex": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "format": "cpp", + "fstream": "cpp", + "future": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "istream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "numbers": "cpp", + "ostream": "cpp", + "semaphore": "cpp", + "shared_mutex": "cpp", + "span": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "stop_token": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "typeindex": "cpp", + "typeinfo": "cpp", + "valarray": "cpp", + "variant": "cpp" + } +} + diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json b/src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json new file mode 100644 index 0000000000..a9479de73e --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json @@ -0,0 +1,22 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "CMake: build", + "type": "shell", + "command": "cmake", + "args": [ + "--build", + "${workspaceFolder}/build" + ], + "group": { + "kind": "build", + "isDefault": true + }, + "problemMatcher": [ + "$gcc" + ], + "detail": "Generated task by CMake Tools." + } + ] +} diff --git a/src/engine/attack/PGD_Linf_Rand/CMakeLists.txt b/src/engine/attack/PGD_Linf_Rand/CMakeLists.txt new file mode 100644 index 0000000000..e8b7c3a360 --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/CMakeLists.txt @@ -0,0 +1,37 @@ +cmake_minimum_required(VERSION 3.18 FATAL_ERROR) +project(PGD_Linf_Rand) + +# Set the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +# Set the CMake prefix path to include the new LibTorch location +list(APPEND CMAKE_PREFIX_PATH "~/libtorch/libtorch/share/cmake/Torch") + +# Unset any environment variables that might influence the build +unset(ENV{CXXFLAGS}) +unset(ENV{LDFLAGS}) + +# Find the required packages +find_package(Torch REQUIRED) + +# Explicitly clear any MKL-related flags +set(CMAKE_CXX_FLAGS "") +set(CMAKE_SHARED_LINKER_FLAGS "") +set(CMAKE_EXE_LINKER_FLAGS "") +set(CMAKE_REQUIRED_LIBRARIES "") + +# Include directories +include_directories(${TORCH_INCLUDE_DIRS}) +include_directories(${TORCH_INCLUDE_DIRS}/torch/csrc/api/include) + +# Add the executable +add_executable(PGD_Linf_Rand main.cpp read_net.cpp pgd_attack.cpp) + +# Link the libraries +target_link_libraries(PGD_Linf_Rand "${TORCH_LIBRARIES}") + +# Ensure you have -D_GLIBCXX_USE_CXX11_ABI=0 for compatibility +set_property(TARGET PGD_Linf_Rand PROPERTY CXX_STANDARD 17) +set_property(TARGET PGD_Linf_Rand PROPERTY CXX_STANDARD_REQUIRED ON) +set_property(TARGET PGD_Linf_Rand PROPERTY CXX_EXTENSIONS OFF) diff --git a/src/engine/attack/PGD_Linf_Rand/build_net.py b/src/engine/attack/PGD_Linf_Rand/build_net.py new file mode 100644 index 0000000000..cd2ef25ad6 --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/build_net.py @@ -0,0 +1,146 @@ +import torch +import torch.nn as nn +import torch.optim as optim +from torch.utils.data import DataLoader, TensorDataset + + + +def generate_nonlinear_data(num_samples, input_size): + x = torch.randn(num_samples, input_size) + y = torch.zeros(num_samples, dtype=torch.long) + for i in range(num_samples): + if torch.sum(x[i] ** 2) > input_size * 0.5: + y[i] = 1 + return x, y + + +def train_model(model, dataloader, criterion, optimizer, num_epochs): + for epoch in range(num_epochs): + running_loss = 0.0 + for inputs, labels in dataloader: + optimizer.zero_grad() + outputs = model(inputs) + loss = criterion(outputs, labels) + loss.backward() + optimizer.step() + running_loss += loss.item() + + avg_loss = running_loss / len(dataloader) + print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {avg_loss:.4f}') + + print("Training complete") + + +class example_DNN(nn.Module): + def __init__(self, input_size, num_classes): + super(example_DNN, self).__init__() + self.fc1 = nn.Linear(input_size, 128) + self.relu1 = nn.ReLU() + self.fc2 = nn.Linear(128, 64) + self.relu2 = nn.ReLU() + self.fc3 = nn.Linear(64, 32) + self.relu3 = nn.ReLU() + self.fc4 = nn.Linear(32, num_classes) + + def forward(self, x): + out = self.fc1(x) + out = self.relu1(out) + out = self.fc2(out) + out = self.relu2(out) + out = self.fc3(out) + out = self.relu3(out) + out = self.fc4(out) + return out + +def save_to_nnet(model, input_size, output_size, filename, input_mins=None, input_maxs=None, input_means=None, input_ranges=None, output_mins=None, output_maxs=None): + layers = [input_size] + biases = [] + weights = [] + activations = [] + + if input_mins is None: + input_mins = [0.0] * input_size + if input_maxs is None: + input_maxs = [1.0] * input_size + if input_means is None: + input_means = [0.0] * input_size + if input_ranges is None: + input_ranges = [1.0] * input_size + if output_mins is None: + output_mins = [-0.1] * output_size + if output_maxs is None: + output_maxs = [1.0] * output_size + + # Mapping from PyTorch activation functions to .nnet format + activation_map = { + nn.ReLU: 'ReLU', + nn.Sigmoid: 'Sigmoid', + nn.Tanh: 'Tanh', + nn.Identity: 'Linear', # no activation + nn.Softmax: 'Softmax', + } + + for layer in model.children(): + if isinstance(layer, nn.Linear): + layers.append(layer.out_features) + biases.append(layer.bias.detach().numpy()) + weights.append(layer.weight.detach().numpy()) + activations.append('Linear') + elif type(layer) in activation_map: + activations[-1] = activation_map[type(layer)] + + with open(filename, 'w') as f: + # Write the header information + f.write(f"{len(layers) - 1}\n") # NumLayers + f.write(' '.join(map(str, layers)) + '\n') + f.write(' '.join(activations) + '\n') + f.write(' '.join(map(str, input_mins)) + '\n') + f.write(' '.join(map(str, input_maxs)) + '\n') + f.write(' '.join(map(str, input_means)) + '\n') + f.write(' '.join(map(str, input_ranges)) + '\n') + f.write(' '.join(map(str, output_mins)) + '\n') + f.write(' '.join(map(str, output_maxs)) + '\n') + + # Write weights and biases for each layer + for w, b in zip(weights, biases): + for row in w: # Weights + f.write(' '.join(map(str, row)) + '\n') + f.write(' '.join(map(str, b)) + '\n') # Biases + +if __name__ == "__main__": + input_size = 10 + num_classes = 2 + num_samples = 100000 + num_epochs = 20 + batch_size = 32 + + x_train, y_train = generate_nonlinear_data(num_samples, input_size) + dataset = TensorDataset(x_train, y_train) + dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True) + + model = example_DNN(input_size, num_classes) + criterion = nn.CrossEntropyLoss() + optimizer = optim.Adam(model.parameters(), lr=0.001) + train_model(model, dataloader, criterion, optimizer, num_epochs) + + example_index = torch.randint(0, num_samples, (1,)).item() + example_input = x_train[example_index] + true_label = y_train[example_index] + model.eval() + + # predict + with torch.no_grad(): + example_output = model(example_input.unsqueeze(0)) + predicted_label = torch.argmax(example_output, dim=1).item() + + print(f'Example input: {example_input}') + print(f'True label: {true_label}') + print(f'Predicted label: {predicted_label}') + + # Save to .nnet file + save_to_nnet(model, input_size, num_classes, 'example_dnn_model.nnet') + print('Model saved as example_dnn_model.nnet') + input_size = 10 # Assuming input size is 10 as in the example + num_samples = 1 # Generate only one sample + x, y = generate_nonlinear_data(num_samples, input_size) + print(f"sample: {x}, true label: {y}") diff --git a/src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet b/src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet new file mode 100644 index 0000000000..8932543aaf --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet @@ -0,0 +1,239 @@ +4 +10 128 64 32 2 +ReLU ReLU ReLU Linear +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 +-0.1 -0.1 +1.0 1.0 +-0.28455138 0.117859654 0.18439096 0.04317837 0.28540727 0.1868404 0.024365509 0.34901863 -0.20105655 0.22752403 +0.3105072 0.39796048 -0.42463934 -0.23280914 -0.030566286 0.022306312 -0.18405044 0.26723912 -0.002429595 0.47206965 +0.2775113 0.024207324 0.31143394 -0.28730217 -0.26322183 0.38700706 -0.10731701 0.5534289 -0.28118485 -0.28138563 +0.054181967 0.014427167 -0.25925308 0.5879159 -0.071230024 0.24331309 0.19552329 0.4051667 0.50161165 -0.20595936 +-0.10182064 0.0755761 0.011579716 0.30420437 0.2917685 -0.47089475 0.08457943 0.18470646 -0.058850735 0.5910261 +0.37326097 -0.4855032 -0.15858142 -0.5004132 0.012236897 0.52280325 -0.038484175 0.021141008 0.29756257 -0.06635491 +-0.40193033 0.14290994 -0.050764624 0.04582046 -0.3330127 -0.06611222 -0.43604583 -0.5081408 -0.034225754 0.4082599 +0.010602157 -0.2074372 -0.055922788 0.22405607 0.011868194 -0.0526929 0.12249411 0.115381986 -0.06539138 0.08719151 +0.12981263 0.22033449 0.3874724 -0.18110098 0.47398034 0.13681911 0.4403632 -0.04718006 0.119150706 0.041176714 +-0.23044953 0.38978156 -0.017102232 -0.106285974 -0.55304956 0.21900891 0.11770189 0.31969005 -0.18385275 -0.41345328 +-0.51556623 0.45312193 0.099884495 -0.2042248 0.06656063 0.43175852 0.056158125 -0.35137838 0.1321477 0.10608647 +0.16051601 -0.30156162 0.34314415 -0.21871717 -0.42474025 -0.16751747 0.24119143 0.19240926 0.12394541 0.426288 +-0.28395078 0.4690801 -0.44548276 -0.19799247 -0.3300124 -0.27249318 0.036338862 -0.17044862 0.248307 -0.1634606 +0.26696423 -0.05358327 0.16336162 -0.12839659 0.44823086 -0.3150219 -0.20776895 -0.24316539 0.2760343 0.46428785 +-0.027324751 -0.42231372 -0.37517393 0.30027363 0.04537024 0.28453803 -0.32876322 -0.07979409 0.12054802 -0.13993585 +-0.18328886 0.23774084 -0.51440084 -0.10227958 -0.14264189 -0.46239448 0.17611115 0.08153784 -0.26750496 -0.13821323 +0.088551156 -0.039042894 0.33623335 0.16488548 0.2959695 0.092411466 0.072079554 0.02075309 0.1308905 -0.39446115 +0.41459405 0.3778683 0.16550462 0.035455488 0.17237507 -0.29076958 -0.2489399 0.33575577 -0.45204002 0.22638363 +-0.01603338 -0.06616335 -0.09541775 0.15022044 0.14184316 0.061307438 -0.046147875 -0.049349733 -0.0440171 -0.13926293 +0.38729164 -0.34005284 -0.06426965 -0.06819088 0.27805808 -0.21413371 -0.27721518 -0.3437389 0.24936727 -0.11903448 +-0.08302598 0.09103244 -0.36246657 0.015074445 0.016474465 -0.04856309 0.10744061 -0.4672421 0.5692139 0.32074508 +-0.26951241 -0.22025183 -0.23851989 -0.42344457 -0.1780842 0.13659143 -0.40865687 -0.09739604 0.15281332 -0.3534441 +0.0076130996 -0.25845188 0.26311985 -0.106487095 0.33384117 -0.0617972 0.26539403 0.55692154 0.051739145 -0.45549506 +-0.13274503 -0.07541892 -0.3187774 -0.039338335 -0.06311795 0.05268189 0.31885815 0.28703627 0.5011776 -0.2951957 +0.022365615 -0.03763504 -0.008561741 -0.0049987556 0.014113599 -0.00526916 -0.038719017 0.020906111 -0.0056984946 0.008327465 +0.05771124 -0.07492643 0.08632411 -0.051183052 0.07215557 0.1215245 0.046334118 -0.03135138 -0.029953923 0.17491612 +0.47011074 0.35060474 -0.07668475 0.14954284 -0.31638902 0.28192323 0.11816618 -0.18365185 0.10113728 0.39163327 +-0.07603965 -0.22875507 0.1362994 0.43870503 -0.12850475 0.04446025 0.15429042 -0.087388486 0.4207373 -0.040396158 +-0.24588016 -0.09789416 -0.045685023 0.47452065 0.4897433 0.20016381 -0.19538702 0.14409441 0.27642623 -0.03839538 +0.03686738 0.0071058734 -0.015280539 0.014117275 -0.023913814 0.008389961 0.01260907 0.01525224 -0.023937952 -0.02853174 +0.10740758 0.36121452 -0.013768305 -0.3586945 0.23422818 0.49373183 -0.07453271 0.31852862 0.27163985 0.2413848 +0.009793528 -0.3581935 0.31161597 0.21680382 0.20667928 0.029715193 -0.34609497 0.46239576 -0.3585545 -0.10134971 +0.15767854 0.19925885 -0.35016078 0.55403066 -0.1511084 -0.34100676 0.029892152 -0.5051252 -0.43173826 0.09250022 +-0.16758004 0.5941135 -0.08349814 0.068881065 0.33423987 0.28420016 -0.23370819 -0.24959014 0.3061083 -0.11302482 +-0.022818562 -0.12887655 0.37929893 0.30370378 -0.53382 -0.4463252 -0.3137285 -0.44218856 -0.01597238 -0.14853694 +-0.23284096 -0.5174152 -0.324022 0.18877333 -0.13539745 0.14509153 0.5600764 0.034933984 -0.20603243 0.17574604 +-0.28923297 -0.08296793 0.19959214 -0.44647893 -0.22015063 -0.3049023 0.4591472 -0.39973325 0.05403408 0.33820346 +-0.15403287 0.2841168 0.22261865 0.12570249 0.1014145 0.14819486 0.19792894 -0.033545956 -0.22475336 -0.16640449 +0.31352127 -0.35852733 -0.32525605 0.15621348 -0.44268006 0.36852244 -0.1935894 0.09239062 0.1382752 0.5441742 +0.101907425 0.43472722 0.18520461 0.2315438 0.4679371 -0.1967645 0.2944849 -0.31745636 0.078904666 -0.36715135 +-0.17314965 -0.2455581 -0.24367897 -0.56859815 0.24822304 -0.036475614 0.2677036 0.51838225 -0.013135833 0.25813267 +-0.06642836 -0.3147509 -0.47122824 0.055085767 0.2179802 0.2819887 -0.013466401 -0.301314 0.07419502 0.31370372 +0.27610424 0.16802591 0.27163342 -0.016057901 -0.43702644 0.17340125 0.11967022 0.32980773 0.39012745 0.3133623 +-0.6118267 0.23692372 -0.17070054 -0.43392485 0.4814441 -0.25067148 -0.30185482 0.0060283337 0.110232614 -0.0045461464 +-0.21913914 0.21445976 -0.08981803 0.034296755 0.24714136 -0.044226702 -0.2349005 0.544771 0.44389427 -0.38168862 +-0.0049906992 0.008606745 -0.03410402 0.008440695 0.09601321 0.082708284 0.030415503 -0.008736973 0.08847122 0.015274575 +-0.1314091 0.04139238 -0.26287 0.34618193 0.29946563 0.30117458 0.01104859 0.08670962 -0.55007917 -0.36144137 +0.068449214 -0.10273849 -0.1069506 0.16671368 -0.06560565 -0.14556059 -0.05493045 0.16397084 -0.10204232 -0.10851353 +-0.4559008 -0.1354479 -0.1739286 0.30340123 -0.1524082 0.33013973 0.12621868 -0.14784122 -0.34168166 0.38747364 +-0.0060651475 -0.006621465 0.012814799 0.006155747 -0.01081555 -0.009769878 0.00020627184 0.004324064 0.0010638997 0.020297946 +-0.3601548 0.0038658846 0.42703134 -0.45277214 0.21655492 0.40475303 -0.14757645 -0.34719428 -0.3597489 0.04115225 +0.0073041604 0.023135105 0.020368993 -0.011070213 -0.027795712 0.020742163 0.009174354 -0.0047257436 0.025252273 0.011830452 +-0.23114154 0.45983648 0.011570652 0.53549385 -0.1012814 0.25666443 0.24681814 0.18818995 -0.1752674 0.4152972 +0.18107013 0.41786426 0.18308738 0.2843345 -0.076477036 -0.10218624 -0.5746205 -0.15373912 0.3829511 -0.3515995 +0.5301879 0.20139302 0.05776631 -0.11035105 -0.51336175 0.017097954 0.12338001 -0.102511115 0.09740772 -0.2962824 +0.37056231 0.01330144 0.2487793 -0.14547579 -0.015848152 0.27512136 0.5775834 -0.14101133 -0.32339254 0.059750777 +-0.17450584 -0.39383227 0.40074453 0.22753482 -0.14159063 -0.25798222 0.17974684 -0.26714122 -0.32277763 -0.5984688 +0.58647484 -0.09427886 -0.33757958 0.17490411 0.11129575 0.09390966 -0.4583271 -0.1760943 -0.036377296 0.18598433 +-0.40673965 -0.514109 -0.02410423 0.05950414 0.33465216 -0.039197784 0.32273668 0.075439386 -0.11181032 -0.42292154 +-0.46050242 -0.32964227 0.012160097 -0.11189483 -0.07768547 0.2593667 -0.04005198 0.4685868 -0.20615672 -0.12681153 +-0.37476596 -0.15956824 -0.4064112 -0.28756392 -0.3729003 0.3957204 -0.27685434 0.12287568 -0.23183523 0.23311102 +-0.42581096 -0.3829482 -0.051080145 0.19595413 0.37400416 -0.3260584 0.14460297 -0.4295164 0.13970433 0.15296096 +-0.05876424 -0.03267093 -0.0974966 -0.033720378 -0.19159131 0.04507669 0.11721643 0.0014088796 0.057089575 0.05453948 +0.07128007 0.3236078 0.089387126 0.5251159 -0.2911699 0.3721201 -0.16029544 -0.3842856 -0.09102168 0.019555645 +0.12856187 0.3026325 -0.2133159 0.14439335 0.46550822 0.049207065 -0.072125524 -0.4576038 -0.33227178 0.17730716 +-0.0042265346 0.005467734 -0.022910886 -0.00640266 0.016942512 0.021487214 -0.009116341 0.0015924831 0.030168597 0.0036327192 +-0.08869967 -0.36943546 0.3245766 0.033851013 0.45802674 0.37847865 -0.3610906 -0.15004572 0.29665983 0.04687242 +0.2229126 -0.44915503 -0.37696195 0.2662045 -0.3155771 -0.3343354 0.33637467 -0.11626375 0.20489724 -0.16025603 +-0.0068123196 -0.0029940098 -0.0057678623 -0.020120041 -0.0028758608 -0.0069830874 -0.012365294 0.029267607 0.0014767732 -0.024816582 +0.31435245 -0.01579723 -0.44479832 -0.28395534 0.06859346 -0.19909827 0.07264357 -0.4232367 0.17481604 -0.20412493 +0.22411191 -0.5050271 0.099488646 -0.43413413 0.15711762 -0.4288477 -0.2465681 0.11568635 0.105006084 -0.2466245 +-0.25034398 -0.24395311 -0.3720052 -0.08639984 0.4801612 -0.22067371 -0.35419622 -0.18985057 -0.31907457 -0.28764147 +0.15418546 -0.33069196 0.12506053 -0.26829848 0.09308444 0.22606921 0.49476507 -0.35053545 0.15035926 -0.27493933 +0.21837892 0.2866439 0.10467524 -0.49094525 -0.052704748 -0.335181 -0.28603292 0.23666522 -0.2534945 -0.3522202 +0.4061538 0.22291237 0.41101003 0.36623672 -0.23440512 -0.50317377 0.13190718 -0.1763437 -0.10721703 0.27222344 +-0.3576493 0.2405982 0.42445877 0.3463452 0.2082779 -0.51947325 0.289207 0.15824386 0.07308001 0.17685579 +0.04453485 -0.025194485 0.073939405 0.021400554 0.010437529 -0.050401766 -0.048501942 -0.12577705 0.04113846 0.06879701 +0.20846556 0.08787045 -0.29259333 -0.06331353 0.6405855 0.28475884 0.26068842 0.40689498 -0.3304113 0.076072775 +0.3795797 0.30519065 -0.39758962 0.14427018 0.212179 -0.34057254 0.38862655 0.04654019 -0.23555708 -0.24054301 +-0.1381455 0.2363341 0.119750485 -0.4602533 -0.070762634 -0.30651638 -0.24514605 0.22993888 0.13864219 0.31968218 +0.32071325 0.026371712 -0.47231522 -0.19915104 -0.40999568 0.13130926 -0.05260096 -0.04913268 -0.2778576 -0.13119315 +-0.13216801 -0.13181157 0.28701097 0.03589806 -0.46139944 0.25418666 -0.18728305 -0.5357403 -0.10361853 -0.18174528 +0.18507242 -0.08682343 0.4284813 0.18598318 0.22848876 -0.04690596 -0.52198005 -0.33305088 -0.5110326 0.30332452 +-0.5499677 -0.19927067 0.25128692 -0.06730761 -0.022750737 -0.300947 -0.13369931 0.093010925 0.1929136 -0.43830335 +-0.009327476 0.016302252 -0.003538069 -0.014251863 0.010429798 0.021142459 -0.016814722 -0.0073514762 -0.029796401 -0.01072346 +-0.22950281 -0.050104816 -0.3476716 0.112840936 -0.47109488 0.1522662 0.0320684 -0.20600763 -0.22843057 -0.46446374 +0.101538055 -0.19443917 0.13180332 -0.021822358 0.22180317 -0.12088015 -0.36139727 0.44727185 0.35283852 0.14962642 +0.11627846 -0.093305044 -0.0021111595 -0.521122 -0.029742675 -0.04395466 -0.2984154 -0.39016253 -0.4346855 0.23861551 +-0.110211834 -0.06172944 0.012876092 0.1480233 0.0047667916 -0.014896821 0.051848404 0.012075839 0.0016197915 -0.16583933 +0.2675201 0.25697446 0.27172685 -0.45764655 0.12845743 0.20949984 0.40958202 -0.2943057 0.41401914 -0.32482842 +0.43373975 -0.2711566 0.46053258 0.3088 0.41185912 0.22801127 0.08747486 0.06330044 -0.050433446 0.15321454 +0.21653865 0.10903641 -0.50414824 -0.047891196 0.2543352 0.35267973 0.019884603 0.10458308 0.26254326 -0.008160648 +-0.28957775 -0.1999873 0.6267224 0.08226321 0.08939566 0.34719914 -0.38958666 0.2215929 0.30908543 0.30996203 +-0.16191465 0.34325638 -0.4020272 -0.17345427 0.1420655 0.27302122 0.54149145 -0.035792146 -0.40335363 0.2281892 +-0.046866655 -0.09081993 -0.29262474 0.1911325 -0.027617848 -0.3974567 0.34932762 0.26974422 0.2495951 0.43868172 +-0.25044978 -0.37739325 0.47803643 -0.1506169 -0.3690877 0.28157714 0.15331063 0.17501883 -0.13746543 0.16995554 +0.07895695 -0.24045517 -0.46401733 -0.13675497 -0.32618582 -0.119944766 -0.37424892 0.093103535 0.35577124 0.09305152 +-0.2894613 -0.23411681 -0.06195192 -0.31506592 -0.34964398 -0.3703217 -0.028258001 0.17967482 -0.6313629 0.0811279 +-0.17569065 -0.35895088 -0.06791566 -0.10139673 -0.20498882 -0.22043465 -0.44075722 0.4202909 0.108130254 0.33689523 +0.14050291 -0.19696921 -0.24666788 -0.30615008 0.12575188 -0.36564392 0.37865818 -0.16586134 -0.16385397 -0.3433574 +-0.28002775 -0.11424993 0.08287238 0.22925903 -0.4146891 -0.32077894 0.56230956 -0.28500438 -0.20560227 0.18216793 +0.2798132 0.058744706 0.15653609 -0.18839653 -0.019620229 -0.31418765 0.28337714 0.34092128 0.3125291 0.05012699 +0.14525717 -0.036599535 0.10270733 0.057970144 0.056752354 0.069755286 -0.0019525104 -0.03223467 0.11431686 0.021904204 +0.058498498 -0.26369753 -0.26003602 -0.19576074 0.25596663 -0.1635211 0.07847372 0.077449806 -0.44665405 0.5582 +-0.52869827 0.050316643 0.18326664 0.100510634 -0.2925465 -0.051629364 0.4834877 0.38333812 0.2599224 0.12870933 +-0.1288649 0.090733975 0.010761775 -0.038485464 0.049444575 0.08405639 -0.17848526 0.15368876 0.09678326 0.07457886 +-0.3511187 -0.040925056 -0.29281735 0.26401553 -0.060264025 -0.3798536 -0.48554844 0.09695743 0.39591253 -0.11304257 +-0.053458456 -0.042193495 -0.16550885 -0.1750925 -0.17554067 -0.11822542 -0.12614903 -0.06233662 0.02918644 0.092849046 +-0.07324428 0.44320002 0.42901474 -0.43367988 -0.30450234 -0.11891289 -0.19800906 -0.097073846 -0.14061426 0.24586539 +-0.23722027 -0.18062265 -0.3538977 -0.254818 -0.27859887 0.5934074 0.12573151 -0.1497591 0.18904237 -0.42394698 +-0.36763623 0.26754713 -0.1903199 0.25381646 -0.54059947 -0.12011553 -0.16615215 0.2843551 0.22627825 0.055720527 +-0.081066966 -0.18988396 -0.052123643 0.4689103 0.2672192 0.46879423 0.34345964 -0.22781855 0.29153413 0.11746829 +-0.35543972 0.272278 0.31975096 -0.18627666 0.3241763 -0.31968057 0.2247543 0.15486833 -0.29239368 -0.5159346 +-0.15778908 0.20889945 0.005726955 0.114532374 0.0656017 0.37546918 -0.59543717 -0.13706394 -0.51085764 -0.12280475 +0.3042335 -0.32086602 -0.20949444 -0.1029553 -0.36514768 -0.0076681715 0.43346438 0.17475663 -0.52909267 0.060691368 +0.3863764 -0.27003223 -0.03224157 0.18260095 0.4354366 -0.14713793 0.059475016 -0.32731634 0.17458081 0.4091818 +0.39920157 -0.4782262 -0.21414787 0.19797263 -0.15580755 -0.41751054 -0.19404264 0.38976473 -0.053107824 -0.1186259 +-0.3426388 -0.17160162 -0.28741536 0.38625196 -0.046557985 -0.07041782 -0.30616528 0.17040268 -0.29714537 0.20434482 +0.0046532303 0.06944184 -0.023675453 -0.0039466196 -0.018111002 0.015383647 -0.004435171 0.023951879 0.013903248 -0.006227614 +-0.077758655 0.033117298 -0.10694162 0.050311413 -0.015050664 0.04689709 0.0441819 -0.024133328 -0.16827172 0.019610966 +0.1775616 0.023685379 0.17498054 0.45607916 -0.34066734 -0.03115786 -0.3107581 0.427013 -0.3900627 -0.111504726 +0.1356229 0.0698497 -0.15551792 0.31239194 -0.0631919 -0.19209367 0.509126 0.14967643 0.28649533 -0.31878892 +0.52660066 -0.49895704 0.07882609 0.44564334 -0.24858457 0.2446494 0.14175005 0.04691269 -0.26790336 -0.10063139 +0.15793765 0.34893242 -0.490477 0.21029106 0.17741542 -0.018613411 -0.24431507 0.36199027 0.092211775 -0.10015655 +-0.05174599 -0.3359824 0.30336913 -0.2319417 -0.40560856 0.06376707 -0.27233434 -0.19169773 0.5443589 -0.041798886 +0.008691748 -0.01350235 -0.017105361 -0.01231288 -0.0061977035 -0.0068901293 0.0037162916 0.007698833 -0.022476904 -0.0059539704 +0.42933464 0.048232384 -0.15957738 -0.15906577 -0.15293288 0.4438881 -0.3381563 -0.23942111 -0.15160505 -0.5422617 +0.32760242 0.20635779 -0.09144 -0.18923871 -0.2845104 -0.43294093 0.45301196 -0.3125431 0.18682526 0.11437156 +-0.4980476 -0.58041525 -0.48866054 -0.38225642 -0.50385785 -0.29256764 -0.541996 0.57920843 -0.28935188 -0.48314875 -0.49368322 -0.25186178 -0.4828902 -0.47614747 -0.34747124 -0.47026178 -0.42798287 -0.37326 0.7506047 -0.32195428 -0.4752328 -0.37266782 -0.38125092 -0.39769676 -0.17578278 0.8383425 -0.61737585 -0.4138284 -0.41648188 -0.14939219 -0.50636286 -0.33551648 -0.40876442 -0.45759198 -0.33284524 -0.40005758 -0.31762153 -0.427266 -0.49846 -0.46467614 -0.541311 -0.28746375 -0.36528778 -0.33746326 -0.27660474 0.21293563 -0.38704872 0.95226437 -0.31665793 -0.08827218 -0.40357965 -0.14328367 -0.41388166 -0.41208395 -0.33830357 -0.5304695 -0.4543723 -0.24983373 -0.38298866 -0.1976541 -0.5260179 -0.49965852 0.87526214 -0.40723968 -0.2142423 -0.11221747 -0.42233157 -0.49477938 -0.13258189 -0.40585133 -0.44803977 -0.37850413 -0.39484218 -0.47244948 -0.30429986 -0.46115646 0.3923856 -0.49000448 -0.38921162 -0.36504218 -0.38433307 -0.31453475 -0.3958369 -0.4090689 -0.11875173 -0.43290916 -0.28137833 -0.40095273 0.6165044 -0.36507034 -0.46115592 -0.30187327 -0.5776016 -0.41535556 -0.27505276 -0.3282344 -0.3173351 -0.38378626 -0.32935178 -0.37675205 -0.34771442 -0.41252607 0.57541937 -0.33784476 -0.42099017 0.4899154 -0.31647876 0.95704293 -0.29085898 -0.4671359 -0.24250484 -0.40116528 -0.36988765 -0.28622502 -0.4228225 -0.41102263 -0.36325663 -0.44478616 -0.2495698 0.63440275 -0.36856088 -0.29797155 -0.42376623 -0.34427726 -0.49648714 -0.08892671 -0.51100785 -0.3199514 +0.25247115 -0.12876284 0.10140871 0.21125874 -0.06747068 -0.06213032 -0.099728964 -0.074982636 -0.062304977 0.30175555 -0.04704971 0.12912212 0.047423627 -0.08007223 -0.23623668 -0.00776405 -0.0023060578 -0.17530265 -0.13943678 -0.0530209 -0.30274048 -0.040164676 0.115671866 0.103205815 0.02684181 -0.11404969 -0.017082287 0.041100368 -0.07981952 -0.14529611 0.09475666 -0.04710138 0.0036608214 -0.08502678 -0.23273945 0.09075107 -0.29113173 0.099548414 0.022440305 -0.058007404 0.09915796 -0.049558416 0.16755404 -0.1076635 0.10239559 -0.1985158 -0.080557354 -0.051981155 0.18615028 -0.000974348 -0.03907409 -0.13166451 -0.021684214 -0.14970933 -0.10365143 -0.06711683 -0.34574267 -0.14298368 -0.15630527 0.042045552 0.031676397 0.058082096 -0.09805584 0.28482893 -0.019177243 0.0046153967 -0.1870979 0.10512655 0.019202217 -0.082971215 0.18728754 -0.0044559073 0.09430838 0.085605465 -0.13287985 -0.11296332 -0.1721771 -0.11169651 -0.14248605 0.13675378 -0.21717453 -0.01830794 -0.1240418 -0.031693988 0.028994706 0.08358371 0.10154661 -0.10033465 -0.08913857 0.1225209 -0.09199355 -0.093348406 -0.052179143 -0.13361965 -0.03232791 0.20825058 0.03529225 -0.051942654 0.08642462 0.009715819 -0.07835139 0.16620241 -0.25719503 0.071884744 0.13018182 -0.16704945 0.015667314 -0.15157427 -0.23210417 0.20237912 0.19080825 0.1533417 -0.22261333 -0.0152152395 -7.128909e-05 0.007287715 -0.09616776 0.18819952 -0.021327883 -0.15319195 -0.12831673 -0.13636489 -0.07430686 -0.12819542 0.020629367 -0.1364513 -0.25210202 -0.20001467 +-0.3061107 -0.058391593 0.14099348 -0.119278796 0.32617742 -0.15434304 0.14434557 -0.0014495926 0.03797238 -0.24748078 -0.15270182 -0.05712759 0.009733153 0.07924787 0.0011039705 -0.14031516 0.26647133 -0.05427487 -0.031985138 -0.045656953 -0.0489848 -0.11982127 0.015052426 -0.082363546 -0.10759615 -0.07762176 -0.1046598 -0.11845488 -0.06942303 -0.059722226 -0.06048842 0.1006053 0.101716995 -0.017098408 0.12305329 -0.06283755 0.023364633 0.1657905 -0.2582612 0.059904713 -0.191074 0.070203654 -0.11318587 0.15773745 0.07527263 -0.0046527013 -0.11512393 -0.07460402 -0.10485363 -0.037711885 0.056305446 -0.09481521 -0.18710306 0.0814657 -0.03177433 -0.0358437 0.066688195 -0.09532622 0.026057433 -0.05293235 -0.12881473 -0.007139806 -0.16083522 -0.11804698 0.028242711 0.05037133 0.09826358 -0.013463977 -0.17532381 0.00017325801 -0.042797823 0.13616353 -0.12949756 0.1559729 0.032087244 0.338494 -0.08194737 -0.071225815 -0.15089966 -0.019118512 -0.3038648 0.0005279033 0.08004321 0.26004577 -0.17140386 -0.11510959 -0.03375195 -0.0699621 -0.010833263 -0.110140435 -0.2018776 -0.10183863 -0.097227514 -0.20772587 0.036443714 -0.07038287 -0.09659145 -0.12828186 -0.10758462 -0.15550399 -0.04212592 0.041788884 -0.14111127 0.010079608 -0.031517237 -0.06013411 0.120718606 0.00868488 -0.061421137 -0.12507209 -0.059790477 -0.1033156 0.05981811 -0.13235423 -0.100659244 0.022813754 -0.15672462 -0.078986205 -0.21410045 -0.05899419 0.023920676 0.17118233 -0.14878246 -0.2262813 -0.18180634 0.008074569 -0.18643099 -0.0841678 +0.06325674 0.3158812 -0.13911664 -0.18776152 -0.047951654 0.211161 0.062503114 -0.28710923 0.09079128 -0.045619227 0.30071843 0.20567226 0.2252348 0.27027816 -0.004445002 0.21881579 0.15869264 0.4756224 -0.3181306 -0.01572822 0.2173839 0.27455717 0.2765112 0.354197 0.08245484 -0.12767263 0.19811189 0.23229283 0.42247215 -0.11688017 0.5027683 0.2967545 0.021459166 0.39556414 0.10228887 0.552294 0.36052066 -0.094374776 0.35989404 0.029373538 0.5504713 0.31356803 -0.023049345 0.08980754 0.12106365 -0.0029841017 -0.26752514 -0.30844316 0.14442082 0.08457967 0.15017903 0.054433156 -0.25979185 0.10473252 0.038123176 -0.11125127 0.023835905 0.15801446 0.13982402 0.1482948 0.4107214 0.307873 -0.12915888 -0.26734403 0.20844214 -0.11004148 0.23696509 -0.02092904 -0.039922804 0.17765476 0.22732271 0.37788844 0.24666594 0.2867848 0.291178 -0.39438 0.0019300872 -0.026859485 -0.060666543 0.17216218 0.2558782 0.07308875 0.275942 0.3788867 -0.019216254 0.1985678 0.042484835 0.3195449 -0.29289567 0.08331348 0.360671 0.23833375 0.3907752 0.01776566 -0.033193797 0.23301572 0.14946708 0.12840798 0.29395285 0.42016885 0.15309967 0.13122329 -0.18296932 -0.023632511 0.20843518 -0.03653492 -0.369909 -0.006083003 0.18158735 0.5730657 -0.23114048 0.18915291 -0.07248513 0.37693876 0.25369298 0.15554538 -0.014345057 0.10498585 -0.032560375 -0.06421591 0.4002657 -0.15114938 0.13111752 0.10376038 0.23710842 -0.0052062892 -0.13777216 0.33482918 +0.054961216 -0.10175659 -0.071475916 0.023482645 -0.07725658 -0.009387395 -0.006831787 0.057659592 0.05583738 -0.019585961 -0.018921576 0.05655799 -0.010803109 -0.019376079 0.00089767086 -0.08273243 -0.025637537 -0.017166179 -0.037294462 -0.111949906 -0.0512868 -0.0064849723 0.015109441 -0.07276224 -0.09003398 -0.0034615383 -0.04583202 -0.023758136 -0.054521598 0.023516465 -0.07379407 -0.024020877 -0.10233397 -0.006212225 -0.072012566 0.07353723 0.038921542 -0.09069568 -0.066179715 0.0064184233 -0.06523892 0.04710325 -0.05309107 -0.08082205 0.07372771 -0.11215838 -0.04980156 -0.06744044 0.019555228 -0.09611448 -0.046267543 0.03399663 0.033441275 0.017609593 0.035101544 0.031318672 0.026587235 0.050718237 -0.08190005 -0.0949771 0.014100369 -0.0841331 -0.06012655 -0.09435812 -0.10023291 0.008053356 -0.0049722195 0.07088896 0.051392104 0.03745146 -0.016621323 -0.09293208 0.033553652 0.03021297 -0.04122296 0.022910716 -0.013370333 0.07229783 0.069237396 -0.029567601 0.054852713 -0.054546874 -0.08504498 -0.0072635296 -0.077413745 -0.0598163 0.026684571 0.007935607 -0.03230557 0.03369837 -0.07754206 0.06247696 0.07478874 -0.029100742 -0.064304635 0.047819443 -0.09725008 -0.022081172 -0.0032462138 -0.0306684 -0.10718476 -0.054282896 -0.08213437 0.043404467 -0.08480738 0.057363205 0.044106245 -0.09768993 -0.01299765 0.032684363 -0.00038142136 -0.0015463931 0.008721837 -0.038669243 -0.00780818 -0.04060742 0.042903677 -0.08808824 0.019236935 0.014808838 -0.077097975 -0.094490275 0.0479333 -0.008427469 -0.0177593 0.062646724 -0.035783272 0.057554632 +-0.02170802 -0.10097058 -0.039423708 0.060791675 -0.062913015 -0.03220438 -0.022258304 -0.0051209973 -0.03452105 -0.038907316 0.029861527 -0.051713835 0.019467387 0.035205204 -0.08472533 0.019922748 -0.07984434 -0.10666134 -0.01831951 -0.06864508 -0.08435263 -0.04425101 -0.018485818 -0.0727034 -0.020571487 -0.04983585 -0.09681881 0.06762959 -0.04297733 0.005685131 -0.07092041 -0.06421981 -0.0454833 -0.03788864 -0.10329039 -0.027022585 0.011297344 -0.022401892 -0.07524064 0.051589422 -0.06950978 -0.088600166 -0.0017300586 -0.005586231 0.018668707 -0.10624136 0.064509206 -0.007048342 -0.035638075 -0.025330352 -0.020504173 0.026181499 0.019381376 0.024736725 0.03123186 0.05435632 0.06707178 0.043984372 -0.07463462 -0.031454388 0.059656326 -0.049991075 -0.10900284 0.061995786 -0.045031924 0.049865633 0.00375619 -0.06763569 -0.01463483 -0.005930814 -0.09862791 -0.0873444 0.028277248 -0.089134365 -0.062314767 0.016837995 0.022312 -0.03162664 0.053771615 -0.0069192993 -0.0089991875 -0.05956258 0.03881303 -0.034841824 0.03204732 -0.061096527 -0.055886388 0.032385323 -0.028350271 -0.08100625 -0.05734499 -0.0028614686 -0.009830259 -0.067465805 0.049192216 -0.043432813 0.052467383 0.017255818 -0.06646106 -0.08176486 -0.060888205 -0.018139215 0.00029124596 0.041514408 -0.09226054 -0.034692712 -0.026714448 0.029750338 -0.0146274995 0.054608297 0.011914438 -0.041482124 0.05138804 0.017733883 -0.0024298865 0.07473682 0.010566117 -0.055306826 -0.10264856 -0.11103316 0.045582097 -0.03909239 -0.07302528 -0.039468635 0.026368648 -0.08538285 -0.008971606 -0.10318031 +-0.082582295 -0.07685 -0.101472124 -0.07500627 0.018734787 -0.019133393 -0.07421398 -0.107861936 0.059763968 0.023681413 0.04928628 0.08105531 -0.013469935 -0.06170649 -0.06520056 -0.058338337 0.03674244 -0.03077781 -0.12168483 0.0068369997 -0.07491326 -0.06001215 0.003145583 -0.05964985 -0.037160277 0.020529192 0.04765161 0.038571317 -0.07493726 -0.033676006 0.07570332 0.014723692 0.047762148 0.042697765 -0.13156334 -0.06449452 0.073702134 -0.09250606 0.047662552 -0.025133286 -0.04406997 -0.05793271 0.05965673 -0.07179908 0.030547034 -0.11094953 0.0026287085 0.03197342 0.039129492 -0.054259375 -0.09820488 0.028148456 -0.043811627 0.04202099 0.027737552 0.008606576 -0.0060273195 -0.098790295 -0.07365758 0.041782856 -0.04757257 0.014550561 -0.069199756 0.04172552 -0.0004291775 0.009942298 -0.084534906 -0.0700213 -0.08702256 -0.08649075 0.02189486 0.013224232 0.048480693 -0.040565263 -0.088066556 -0.07224678 0.013568839 0.047162026 0.031731978 -0.010766615 -0.036400404 -0.03974719 -0.011475018 0.012544085 -0.04173433 0.06344754 -0.061959267 -0.021402163 -0.103156164 -0.021881169 -0.084234595 0.03708155 0.044402733 -0.09520136 -0.009073325 -0.082204 -0.0047706147 0.069188625 -0.10669571 -0.016155342 -0.03851761 0.07352962 -0.06371492 -0.04746283 0.072599605 -0.073483974 0.04092221 0.033173863 -0.08488979 0.019145802 0.006839372 -0.05006693 0.03452816 0.042938583 -0.083784394 -0.07750576 -0.023752801 -0.08367755 0.06723538 -0.06529168 -0.06132087 -0.008829491 0.004402369 -0.013506725 -0.046417087 0.033862762 0.0410583 0.044104133 +0.011137077 -0.06343973 -0.030491995 -0.0029615208 -0.11389895 -0.08109504 -0.0670581 -0.13887674 0.05034063 -0.101518676 -0.06471664 -0.069123946 -0.012437918 -0.01983522 0.0028577985 -0.09327762 0.021602254 0.0032744738 -0.031581804 0.024515066 -0.04336826 0.013064906 -0.070266224 -0.058179665 -0.03229886 0.026457341 -0.062101856 -0.07601838 0.005043699 0.009041147 -0.0625511 -0.0005810921 -0.017289417 0.034096003 -0.046049148 0.0279022 -0.04914798 -0.005565182 0.021771118 -0.029024128 0.0065579684 -0.056926478 0.02076967 0.029735574 -0.07425056 -0.065800525 -0.10491474 0.013381687 0.056476664 0.019829255 -0.044083405 -0.12257732 -0.058799267 0.06573337 0.0010121389 0.084537916 0.008075939 0.0033338643 -0.12155928 0.068173826 0.006757989 -0.023937067 -0.008127655 -0.026121084 -0.02647971 -0.00583874 -0.03160583 0.020195814 0.039262336 0.03192215 -0.114925355 -0.0140241375 -0.08893556 -0.0059375945 0.01464203 0.029281963 0.041142296 0.025081161 0.05481786 -0.018386504 -0.014225417 -0.06341848 0.041474167 -0.055747207 -0.065173835 -0.083882 -0.057681803 -0.011784118 -0.035126947 0.038919434 0.0046390365 -0.055643488 -0.051790234 -0.10886945 -0.039837457 -0.05191047 -0.021975283 0.05731652 0.015286936 -0.045348156 0.01668849 0.06868234 -0.020118034 -0.0020480738 -0.07513503 -0.1277336 -0.08388009 -0.117070034 0.033768695 -0.036237817 -0.097743824 -0.07119531 0.01324869 -0.0053470237 -0.086605355 0.035920665 -0.07704257 -0.102730215 -0.053555936 -0.07145074 0.032306578 -0.0166219 -0.017276451 -0.011479749 -0.054066695 -0.096456714 -0.010856104 -0.001519783 +0.023823932 0.026914034 -0.03396706 0.09124779 0.044073734 -0.013188419 0.090649255 -0.08046404 -0.037058376 -0.012706664 -0.08730524 0.030424632 0.0014093379 0.07601238 -0.03403889 -0.0136894975 -0.08398612 -0.029633671 -0.07127086 -0.05807986 -0.077285916 -0.094569385 0.025602594 -0.005638306 0.046562772 -0.08241678 0.05057043 -0.07436735 -0.015123666 -0.04058743 -0.050811075 0.053511754 -0.07044371 -0.057813175 -0.027080527 0.016587352 0.023340449 -0.118413724 -0.002704401 -0.03386599 0.084112965 -0.013296337 0.06300631 -0.027133599 0.003418498 0.0083862655 0.0073102633 -0.045653727 -0.0067101405 -0.094351515 0.005632115 -0.0034242023 -0.08750844 -0.07208898 0.041487172 0.102971785 -0.041594177 0.024345806 0.063188694 -0.06830075 0.06596806 -0.02424269 -0.07461334 0.012064132 0.057935704 -0.027860511 0.02700163 -0.06489536 -0.072500706 0.06053102 0.014127327 -0.04832635 -0.06765537 0.014739334 -0.030417504 -0.073717505 -0.09789642 0.0022475412 0.06603209 0.057976935 -0.021712111 0.01723799 0.0065516545 0.039193448 0.031036757 0.11170259 -0.04805449 -0.09027551 -0.08169385 0.006479838 -0.047555156 -0.021315247 -0.03533071 -0.0469883 -0.019709969 -0.030474156 0.05579995 -0.004144133 -0.030106595 0.092705406 0.02411421 0.069225475 -0.06693014 -0.011878937 -0.020344516 0.0037588791 0.06279791 0.009124297 -0.0077903476 -0.006622466 0.008238327 0.015194692 0.04518225 0.06517798 -0.0043366263 -0.029658612 -0.042995356 -0.025612164 0.05487492 -0.081285916 -0.006877093 -0.05245376 0.080470555 0.0005917526 0.036429845 -0.052711908 -0.05385736 -0.09300485 +-0.082800634 0.05979247 0.012558824 -0.071049444 -0.07041323 -0.0021917145 0.0063353223 0.022361906 0.035225097 0.018211892 -0.013050156 -0.071435116 -0.01986677 0.059125964 -0.034409862 -0.024576448 0.051289488 -0.011091349 0.038364723 -0.05100956 0.05485109 -0.060785096 0.00640458 -0.08538797 -0.035619125 0.04211274 -0.081940256 -0.07057486 -0.0966498 0.016669009 -0.042527497 -0.026365165 0.04496131 -0.025901346 0.04079664 0.024402445 -0.026294762 -0.07307315 0.027298672 -0.0955006 -0.08808168 -0.095496334 -0.09391398 0.013567587 -0.08009039 -0.09352729 0.017339233 -0.02268059 0.07498543 -0.031835068 0.006161084 -0.094488665 -0.10101812 -0.09315059 0.026633875 -0.03846813 -0.08315019 -0.035819583 -0.07156951 -0.028505493 -0.07439183 0.052459255 -0.027383236 0.0242837 -0.034993418 0.035428174 0.029415831 -0.01937789 0.056449138 -0.0068132016 -0.05034585 0.027220318 0.03861081 -0.08498768 0.039254017 0.03741438 -0.05255135 0.047499843 0.055444233 -0.013781345 0.03128034 -0.00999385 0.004535494 0.005833419 -0.06619209 0.0024952765 0.060537387 0.004797237 -0.07381102 0.015089906 -0.057771802 -0.092807055 -0.094432995 0.0038028643 -0.014482031 0.03423172 -0.013346087 0.0031324783 -0.07185676 -0.039294478 0.002287118 -0.06260134 -0.021597145 -0.019712685 0.03256054 0.03431773 0.0018847588 -0.09992834 -0.08343753 0.03695272 -0.08426996 -0.070075214 0.024301376 -0.045848206 -0.019896468 0.026580447 -0.07325717 0.013863255 -0.059450272 -0.090231664 0.02647703 0.0067761727 0.045088354 -0.07618309 -0.062112965 -0.05794018 0.0070015863 -0.04312601 +0.034972575 0.037921533 -0.07541296 -0.064095765 -0.12984793 -0.0052258675 -0.10827224 -0.15319248 -0.044543825 -0.08033115 -0.05346074 -0.0019150373 0.027990147 0.0056172726 0.048777126 0.0058566714 -0.03878546 -0.11831881 0.03477117 0.021564348 -0.14373018 -0.15935159 -0.04019064 -0.018882552 0.006390219 -0.004626406 -0.0026746176 0.09328503 -0.13508548 -0.0649261 0.012567065 -0.0765606 -0.17289074 0.058964588 -0.098802246 -0.09104751 -0.10063864 0.0062017823 -0.0011591831 -0.12549141 -0.18436342 -0.13172635 0.02276248 0.06270951 -0.056145437 -0.08757345 -0.12834032 -0.09748754 -0.02811091 -0.10254226 -0.0408844 0.02119356 0.017727006 -0.09851564 0.029882431 -0.08124301 0.012250695 0.0067030657 -0.080592975 -0.036864046 -0.04832311 -0.08462023 0.013364378 -0.050055847 -0.12185837 -0.057740808 -0.026835287 0.045801 0.01583684 -0.04896336 -0.13661559 -0.15935326 0.030663738 -0.07893385 -0.07596158 -0.009446063 -0.07092397 -0.03568789 -0.09507795 -0.035578586 0.033195257 0.04139779 -0.06180622 -0.022479804 -0.0021251598 -0.18098973 -0.043669213 -0.017962696 -0.14166178 0.05761907 -0.09379131 -0.12858269 -0.09162191 -0.06672623 -0.06133775 -0.07730333 0.04619586 -0.05514776 -0.07373125 -0.16146302 -0.06082078 -0.032311365 -0.01986905 -0.064529605 -0.16693157 -0.0134060765 -0.009667731 -0.067754224 -0.031084673 -0.1074508 -0.10550139 -0.018866975 -0.13544454 -0.019961342 -0.15067613 -0.11712565 -0.11790995 -0.02180128 -0.0072500976 0.022818534 -0.05005621 -0.03304691 -0.10414552 -0.17896095 0.08105092 -0.10894294 0.012039372 0.03723715 +0.25279292 -0.19361034 0.1094378 0.20131569 0.29359436 0.43926212 0.3179857 -0.28454587 0.13239692 0.35597986 0.23293471 0.25974676 0.20777905 0.39640754 0.23234507 0.22914861 -0.048965465 0.23735271 -0.13768987 0.11668777 -0.082866415 0.26555827 0.20294648 0.09342029 -0.031742446 -0.2814818 -0.29199854 0.16589089 0.084293075 -0.0359847 0.27569842 0.16014995 0.18737788 0.057980854 0.42302537 0.35904607 0.2383979 -0.018479113 0.4984169 0.3435179 0.55916154 0.33068356 -0.3070137 0.20908281 0.20263809 -0.11058465 0.30827844 -0.23711777 -0.053497747 -0.0015292075 -0.037432 0.055313095 0.22125751 0.59573346 0.09948541 0.27158427 0.3765933 0.016864501 0.017281333 0.121840164 0.2519492 0.12491263 -0.27324304 0.1758861 -0.014944004 -0.06630354 0.063939124 0.22107406 -0.07440612 -0.043076962 0.44813582 0.062306147 0.16173841 0.22963141 0.06376438 0.35659555 -0.1939444 0.3912329 0.101959996 0.21965858 0.3213758 0.1627977 0.2710036 0.27857292 0.0057667233 0.3976231 0.2247546 0.0993219 -0.21467099 -0.13989815 0.30969685 0.2301999 0.25939804 0.49252695 0.032663804 -0.10215978 0.3308913 0.091031834 0.22760655 0.15778811 0.07329568 0.24469207 -0.1797695 0.2671821 0.27501926 -0.025360603 0.08865921 -0.2919086 0.19429646 0.3517953 0.4037888 0.2608012 0.40777612 0.22168337 0.30177853 0.1385577 0.19180223 -0.19746126 -0.008374415 -0.0620726 0.29719177 -0.12836854 0.112238124 0.003430933 0.16989774 0.004209546 0.30191574 -0.010232949 +0.0005230873 0.33704168 0.09505411 0.23055625 0.11711579 0.25059932 0.1929889 -0.197914 0.23835793 0.23005103 0.34970492 0.35443777 0.30889982 0.102342285 0.21861018 0.34989744 0.40759626 0.010291543 -0.17619418 0.14010903 0.23007983 0.16792543 0.1919015 0.102378175 0.0262547 -0.19316404 0.43919393 0.34270984 0.1293776 0.11315797 -0.107391715 -0.027717765 0.28394148 -0.037852567 0.24692273 0.07047034 0.26191655 0.24752276 0.31316864 0.27190286 0.04977077 -0.16993508 0.17511004 0.06321101 0.009750783 0.033877578 0.27245694 -0.19962773 0.058323078 -0.07566552 0.41127264 0.023803905 0.3246952 0.17766249 0.08266271 0.3070224 0.12227935 0.30353746 -0.18125468 -0.1178602 0.19364807 0.22207479 -0.20183659 0.26123148 0.2257157 -0.02647015 0.0094512785 0.16810414 0.029187933 0.14526089 0.2883829 0.17401087 0.21468523 0.3746631 0.22309789 0.33824503 0.05864705 0.2851909 0.27733365 0.2932397 0.0906518 0.22205645 0.10350007 0.074674465 0.026174309 0.2503567 0.13255852 0.37551793 -0.09146145 0.16301903 -0.035552163 0.06805484 -0.10983801 0.22603679 0.26108664 0.15249419 0.29718825 0.36276233 0.19505392 0.17678957 0.19504642 0.2628466 -0.04635173 0.11943039 0.23150322 -0.14086355 0.14714542 -0.29370835 0.22310278 0.104778804 0.16252364 0.20331585 0.3389046 -0.026198883 -0.005948574 0.0701904 0.44024196 0.28626162 -0.0033377535 -0.10193171 -0.065573 0.2399463 0.25608736 0.120522305 0.3383942 0.028125847 0.39670965 0.1059482 +0.08090745 -0.08023348 -0.07177413 0.12786052 -0.013173782 0.17540543 0.19297618 -0.19742092 -0.041608434 -0.15553913 -0.018684508 -0.042548195 -0.07420855 -0.06910591 0.07724648 0.0195646 0.004499754 -0.01879066 -0.21977803 -0.03727824 0.048288625 -0.11746477 0.023115678 -0.011276546 0.013576021 -0.011705337 0.0052926573 0.13990842 0.22625369 -0.00068441586 0.04234148 -0.16658644 -0.09952136 0.005388775 0.009274452 0.14567108 0.083184965 -0.07355182 0.22508611 -0.06738796 -0.0388261 0.21092233 -0.032995064 0.024152845 0.07136125 -0.14945054 -0.05022173 -0.13097309 0.18374874 -0.013109742 0.018966971 -0.109935746 -0.123666495 -0.0028964006 -0.08413949 0.14578977 -0.050891347 0.065998815 -0.07564009 -0.051405106 0.30233207 0.031851344 -0.1433286 -0.21195363 -0.16649762 -0.018806336 0.053051617 -0.043254748 -0.14840923 -0.15392666 -0.15668146 -0.14027394 0.23982137 0.1254956 -0.08789801 -0.15355083 -0.1794444 0.08944418 -0.024029637 -0.0054336516 0.045327306 -0.18217492 -0.0724627 -0.10534229 0.009997356 0.09233297 0.07119622 0.12880331 -0.17387895 0.07541593 0.12798631 0.1468153 0.12372773 0.013619179 0.007630263 -0.04015589 0.016405666 -0.0074183173 -0.028762432 -0.18161343 -0.023017144 0.08912338 -0.16034 -0.034875084 -0.039699033 -0.15522817 -0.040181067 -0.14322548 0.023180868 0.27527434 -0.0028294984 0.17208497 -0.11172317 0.10222552 0.19697367 0.0027994541 0.08010178 0.044273857 -0.037767373 -0.20134865 0.0087364195 -0.13342741 0.12971488 0.011184918 0.009587695 -8.8590685e-05 -0.02726119 -0.104606904 +-0.102591 -0.072379395 0.0038108495 -0.0390512 0.021653805 0.05557532 -0.06276534 -0.18689013 -0.028904581 0.06627289 0.024416223 0.012379649 0.065419935 -0.04984626 0.041356742 -0.02633478 -0.02254832 -0.10472434 -0.0126680285 -0.075597115 -0.071482256 -0.006458228 -0.11208636 0.0008114794 -0.060657352 -0.04064969 -0.106206976 0.036494672 -0.13823466 -0.04158128 -0.024237225 -0.0506181 0.06587116 -0.06413634 0.025177106 -0.12224143 -0.05124022 -0.12473581 -0.031308983 0.062292155 -0.060268734 0.024332711 0.019085722 -0.07676082 -0.13514179 -0.016440976 -0.06894556 -0.025529448 0.056235835 -0.022584794 0.07615188 0.052554537 -0.08061384 0.006767556 0.046096504 -0.057292942 -0.11086969 -0.035236143 -0.14333707 0.043185182 0.089623995 -0.13872603 -0.0561753 -0.052667458 0.014561295 -0.08447293 -0.07798978 0.06125349 0.012511141 0.028138297 0.075454675 -0.09218475 -0.022421705 -0.030264933 -0.07556322 0.027569082 -0.13987195 -0.10644339 -0.0019217118 -0.11320035 -0.05107698 0.023648236 0.015803706 0.0019561136 -0.12001138 0.08422135 -0.02717229 -0.08499185 -0.16219816 0.04323028 0.030039812 -0.09390171 -0.01458006 0.028913148 -0.043468658 -0.085869335 0.07933895 -0.106239304 -0.008227926 0.056166865 -0.063148364 -0.059263553 -0.08695284 -0.035979435 -0.064653195 -0.023012204 0.0187024 0.026850397 0.02660541 0.036439545 -0.047385354 0.0023009605 0.004886482 0.05974686 -0.054491386 -0.009258281 -0.08080011 -0.11430586 -0.048880804 -0.104825534 -0.069189884 0.027578514 -0.010656612 -0.11005393 -0.07858137 -0.072229855 -0.028225986 -0.051790733 +0.2843997 -0.07555581 0.2881135 -0.14147405 0.46224403 0.15204225 0.33883733 -0.3497873 0.236573 0.019803947 0.45951134 0.077852026 0.04996174 0.5571992 0.14093259 0.22720286 0.42814106 -0.34433788 -0.1800408 0.21578717 0.33119106 0.17286873 0.1992407 0.31950262 -0.003091425 -0.11449032 0.3404113 0.015635306 -0.042712115 -0.22248605 0.14940494 0.058039475 -0.2310387 0.19269489 0.25043994 -0.16101514 0.48012817 0.08583322 -0.17769276 0.30031103 0.5616202 -0.081152536 0.23609917 0.38075757 0.19875397 0.035741452 -0.24937303 -0.40287703 -0.23926328 0.030211112 -0.18991482 0.09425171 -0.1309385 0.42985302 0.16631657 -0.26206994 0.0160048 0.3169518 0.1754194 0.112601094 -0.3612953 0.251716 -0.15977995 0.4168316 0.03820354 0.031153183 0.03752476 -0.32497805 0.12458132 -0.07959502 0.5196873 0.4114806 0.26460087 0.15643321 0.38712922 0.19991435 0.116269276 -0.12079605 -0.45622352 0.16829306 -0.060791705 0.045539103 -0.09890175 -0.031702176 -0.12589343 -0.05031963 0.18893594 0.22093219 -0.1377165 0.408658 0.0658885 0.23529436 -0.51169187 -0.090965204 0.32847792 -0.12985434 -0.061130706 0.086455874 -0.07811915 0.27558708 0.120046 0.2387753 0.06405832 0.40687037 0.26756966 -0.04671318 0.07553404 -0.23296152 -0.044859763 0.099756256 0.0025624859 0.19061989 0.32512718 -0.09903368 -0.2790073 0.03173576 0.24879333 0.3613448 -0.03432245 -0.2290149 0.34088537 -0.06181288 -0.032811996 -0.1565074 0.15626864 -0.09537763 0.31365335 0.13659704 +0.013721009 0.17380142 0.30208895 0.2841374 0.24393 0.3381574 0.20977172 -0.02267505 0.12608308 0.40927714 0.05996383 0.17484877 0.34575665 0.03625483 0.15270422 0.21435893 0.20517403 0.31964308 -0.2303205 0.13219859 0.23467495 0.2137425 0.24818504 0.21709338 -0.012956809 -0.22994263 0.23354857 0.3361706 0.13167933 0.11063671 0.36688167 0.23614167 0.28733596 0.03985099 0.27620557 0.21289545 0.19142959 -0.013893741 0.2719934 0.20602351 0.2583178 0.17519167 0.08601442 0.008376001 -0.061691243 -0.064658955 0.11255645 -0.26726282 0.047474146 0.044004153 -0.047482662 0.035277862 0.32888332 0.1757347 0.2703975 0.36509955 0.1382695 0.15437105 0.11595304 0.08681558 0.28044692 0.3746766 -0.16610864 0.26236156 -0.003618316 0.05763903 0.40361953 0.24007688 -0.00031063028 0.11343097 0.46373338 0.1878076 0.22141697 0.53501266 0.09779396 0.17939697 0.043317076 0.26623663 0.20834935 0.16196565 0.30010208 0.14988084 0.24587385 0.272907 0.004611332 0.20864594 0.17214257 0.2682163 -0.15054199 0.29961604 0.26012263 0.24590367 0.42700398 0.34275293 0.13788348 0.22995223 0.12451622 0.32149938 0.2951237 0.23023045 0.16463314 0.25259054 0.0032774175 0.11813827 0.30378982 -0.11241999 0.09288862 -0.2741906 0.18907917 0.32039788 0.13964327 0.39103162 -0.09380511 0.032032095 0.13199423 0.097618714 0.288102 0.2199521 0.01521321 -0.15341121 0.14825213 0.10630915 0.17232965 0.19403075 0.3960225 0.11226453 0.3529455 0.20145303 +0.031091338 0.46095842 0.2640863 0.30602562 0.4380904 0.37765613 0.3299477 -0.09463114 0.09575437 0.19998938 0.3604679 0.19339624 0.4113247 0.05600359 0.067155756 0.1617452 0.15302378 0.27164826 -0.23878683 0.14554685 0.23621953 0.2556782 0.06445264 0.18367393 -0.0734284 -0.2157719 0.36558047 0.14021009 0.1292594 -0.025167665 0.17452972 0.250831 0.16750295 0.16437475 0.14625584 0.19271882 0.0554497 0.13102648 0.30759728 0.19336128 0.3101193 0.13364558 0.18866202 0.17818886 0.10959581 -0.06159229 0.34341973 -0.23011822 0.20063777 -0.006028333 0.12726867 -0.03493573 0.3312204 0.23200507 0.16842443 0.20181257 0.41094625 0.1469056 0.107823856 0.043984234 0.27778617 0.33397248 -0.2485471 0.2315835 0.033012655 -0.0596593 0.05523835 0.24572386 0.08999199 0.2237967 0.2926131 0.22728308 0.2063118 0.1838788 0.2312681 0.17871161 -0.076470904 0.35184446 0.26672617 0.19609533 0.03253137 0.15276697 0.15367736 0.24195811 -0.042722326 0.24915978 0.14218998 0.06830876 -0.1754553 0.1526303 0.22474521 0.12549645 0.31351134 0.22203733 0.19019169 0.1482909 0.18689768 0.18446127 0.17486894 0.19478357 0.22627817 0.08477646 -0.14931136 0.16346753 0.06536159 -0.086423144 0.30568507 -0.35259944 0.10218397 0.22024304 0.16773768 0.18038188 0.17748077 0.14791526 0.1963896 0.17208616 0.27547407 0.31556407 -0.098062575 -0.11037697 0.22141787 0.2661277 0.16189216 0.28073633 0.3360488 -0.03271229 0.27122828 0.0058280327 +0.0042506508 -0.023113005 -0.12398538 -0.14988512 -0.102667555 -0.12239753 0.091906905 -0.098650426 -0.224244 -0.029770339 -0.06456202 -0.15589333 0.047750406 0.11082002 -0.083071806 0.059769668 -0.12351707 -0.07173837 -0.02918996 -0.09230959 -0.12488342 -0.008195539 0.032863166 -0.1608466 0.007424324 -0.07266302 -0.1946576 -0.08060813 -0.04579109 -0.14674212 -0.0035449371 0.118576474 -0.19154361 -0.0072687743 0.00086627714 -0.26327673 0.016102746 0.050411064 -0.20915718 -0.09233649 -0.08417016 -0.19398229 -0.11888987 -0.15707746 -0.11903028 -0.106951326 -0.13443696 -0.0035819826 0.01002685 0.07601976 0.0612292 -0.004304789 -0.20455106 -0.18222262 -0.09201861 -0.05716795 -0.0028413571 -0.0077226763 -0.16517864 -0.03460066 -0.03143877 -0.13313207 0.04808825 -0.06690447 -0.17926313 0.014390342 -0.11976049 -0.25733507 -0.015145974 -0.22660904 0.008382793 0.04844682 0.0663258 0.092843294 -0.28147924 -0.21255 -0.09311067 -0.20092294 -0.17255387 0.15496737 -0.045887556 -0.027998807 -0.09048016 -0.14473289 0.010005052 -0.078703806 -0.09264467 0.020221984 -0.029849876 -0.07063214 0.057339627 -0.21272466 -0.0091771865 -0.12805673 -0.1411145 -0.15000941 -0.0008284621 -0.048972953 0.01006202 -0.09671875 -0.2222921 0.022037758 -0.040400185 -0.124128655 -0.12536745 -0.043420766 -0.20130855 0.038632642 -0.10259119 -0.04797878 -0.15215273 -0.026934214 0.011128171 0.07689659 -0.17522931 -0.0469236 -0.050297417 -0.1576827 0.061215878 -0.07432501 -0.11734915 -0.29013383 -0.18528326 -0.25672036 0.056485176 -0.043204065 -0.0008085718 -0.09993849 +0.33819565 0.36417323 -0.21626173 0.24354184 -0.17688313 0.11646499 0.44407395 -0.12717648 0.17381197 -0.5285354 0.17991889 0.27687582 0.31271666 -0.6197714 0.2366881 -0.024023024 0.06957695 -0.096113615 -0.047747195 0.20987307 0.16810274 -0.035247616 0.086601175 0.030954482 -0.04438845 -0.25589767 0.1812513 -0.08935757 0.22212417 0.06284019 0.50603056 0.26016316 0.4647581 0.04309513 0.38926962 -0.030682629 0.24251395 -0.024374269 -0.048645873 0.29059187 0.02020723 0.012654875 0.09681704 -0.060648758 0.049012076 -0.026214195 0.48428538 -0.27594516 0.33939195 0.05315658 0.35816193 -0.03194048 0.10369053 0.5342068 0.11820951 0.02935778 0.4364116 0.325797 0.18302998 0.11788855 0.29627413 0.010713905 -0.2055095 0.14449069 0.13632864 0.001731506 0.0012536796 0.06255971 0.0680572 0.071608126 0.116462275 0.19317068 -0.09724037 0.18844898 0.1694789 -0.12590279 -0.014300091 0.5286675 0.66196567 0.12522365 -0.19674994 -0.0018337904 0.15075493 0.15118228 -0.06577992 0.117026925 0.08952015 -0.069461964 -0.11297577 0.14926639 -0.09241329 0.34411266 0.5329354 0.059015937 -0.009589634 0.39418846 0.28192407 0.29114106 0.10405132 0.15165538 0.15989432 0.28341588 -0.043307185 -0.13557939 0.040198755 -0.11579434 0.3607482 -0.28846022 0.13362086 -0.07170416 0.026474377 0.2828781 -0.08353126 0.13957222 -0.18126878 -0.15053098 0.394018 0.4612739 -0.016160004 -0.19480027 -0.10905497 0.39308205 0.22906336 0.2649197 0.49630585 -0.01038647 0.09738393 0.13364145 +0.18465202 0.48454767 0.3918648 0.30903605 0.22659972 0.2364937 0.22518933 -0.14927776 -0.0012076976 0.42365608 0.18178219 0.15629993 0.3858495 0.19487421 0.005224272 0.10652727 0.18159994 0.34008783 -0.14053984 0.27640516 0.32872537 0.2575689 0.22044104 0.20907335 0.044553436 -0.18911202 0.38393176 0.208016 0.28738418 0.0951882 0.15486805 0.2714591 0.20779762 0.16950688 0.1432744 0.2110135 0.06380174 0.15734431 0.2851005 0.0005771797 0.029077794 0.20334506 0.14805329 0.14981058 0.10456884 0.016166646 0.23741134 -0.16781817 0.17230242 -0.05135142 0.23199761 0.06860998 0.2709409 0.21748427 0.15468964 0.25009394 0.39707074 0.20532371 0.19716305 0.2390405 0.34720397 0.22894654 -0.32792708 0.2606229 0.16335921 -0.030144472 0.17148747 0.14218296 -0.002461501 0.19655155 0.10858987 0.17031355 0.27609733 0.12145989 0.22706713 0.16644335 -0.05070762 0.105394006 0.32452267 0.00015511326 0.18356672 0.21289824 0.22561304 0.088847846 0.035824057 0.09290157 0.1844516 0.14494792 -0.09438699 0.084051184 0.19864313 0.2598805 0.41187403 0.0686285 0.14271823 0.2969369 0.23332231 0.1150042 0.31548932 0.12940706 0.15736504 0.19859388 -0.06454118 0.058251403 0.1313092 -0.102814995 0.15790111 -0.24515325 0.21443243 0.22763944 0.27068576 0.4222166 0.051320948 0.286971 0.18529128 0.2810597 0.18500146 0.24293108 0.06018624 -0.14758782 0.16236125 0.24315494 0.20180753 0.28258345 0.30146322 -0.0056710024 0.26947546 0.09062033 +0.22062913 0.19676565 0.35312244 0.1870897 0.13445643 -0.10531458 0.12531209 -0.061286774 0.18831581 0.4260053 0.37536702 0.22528315 -0.111837775 0.34125015 0.3435314 -0.01579864 0.14571255 0.08972111 -0.108428545 0.009721911 0.39495656 0.054004773 0.22581895 -0.010424826 0.057697784 -0.14825547 0.25693884 0.019602928 0.18989968 -0.03221017 0.123483874 0.39296335 0.28666514 0.34439266 -0.334138 0.1965298 0.3285568 0.119014405 0.5382847 0.27034253 0.25582206 0.22384477 0.20781678 0.28432596 0.19978026 0.0123389475 0.30266765 -0.36390233 0.22644427 -0.018938199 0.25330007 -0.04112275 0.44348314 0.30633923 0.5482768 0.31230685 0.23259316 0.24108455 0.22571781 0.31605703 0.2970522 0.22356227 -0.2346794 0.35753924 0.18212391 0.0119486395 0.16569461 -0.27889195 -0.060443733 -0.08074836 0.1281594 0.28460017 0.057864234 0.068095535 0.11885159 0.3880663 -0.029075274 0.07539755 0.07007453 -0.11165755 0.2557519 0.1123193 0.10335482 0.19630328 0.010321584 0.2603197 0.1324263 0.30856207 -0.074618466 0.21116827 0.28006443 0.089016594 0.3192898 0.23753782 0.18011251 0.07408172 0.043379 -0.04824055 0.21793383 0.046272058 0.14315668 0.3938951 -0.061425958 0.3233973 0.47887862 -0.06615857 -0.082124844 -0.38694695 -0.109676585 0.1624556 0.15224895 0.417523 0.32816288 0.39084873 0.24994296 0.12320648 0.096628964 0.21925746 0.017674558 -0.095216885 0.32102883 0.065065086 0.017432496 0.13109732 0.10707682 -0.051531695 0.30165106 0.21909681 +0.1318786 0.33238596 0.44257298 0.27654597 0.020733953 0.09609295 -0.04487871 -0.28526592 -0.012787881 0.269156 -0.043637976 -0.008561507 0.30593416 -0.11172709 -0.0026796602 0.13259965 0.15302654 0.010896016 -0.20977835 0.26054376 0.14372168 -0.0012719927 0.23759234 0.10403962 -0.07008565 -0.33749682 0.29572818 0.095107436 0.077326454 0.0024760352 -0.04257982 0.123177625 0.28989854 0.21498612 0.07163761 0.21974202 0.03777569 0.069213316 0.347539 0.14237928 -0.1181976 0.12699114 0.28481692 0.049130373 0.11687467 -0.20476492 0.23560448 -0.29000255 0.18479182 0.047252446 0.23818694 -0.02087957 0.16414712 0.10527325 0.10310331 0.2588096 0.1237412 0.21218362 0.17887719 0.114917815 -0.029289117 0.14574216 -0.33852875 0.1120463 0.27486414 -0.031453207 0.050331656 0.17539504 -0.00028281027 0.03173933 0.24872339 0.09145733 -0.091829345 0.10003756 0.06422125 -0.015583926 -0.13143893 0.234922 0.1579429 -0.03348828 0.020105848 -0.040127918 -0.11480044 0.07053848 0.059639663 0.07239019 -0.0015928614 0.18107915 -0.14687382 -0.020042505 -0.21170135 -0.015076009 -0.20934394 -0.087351754 -0.1070334 0.06431536 0.029128307 0.10835044 -0.034353044 0.11171058 0.19393153 0.20521912 -0.1337519 0.20660311 0.13128039 -0.21889424 0.18413505 -0.33968702 0.20442657 -0.0013204429 0.116160266 0.101159014 0.012795508 0.11250612 0.054218758 -0.17581405 0.17381388 0.3190417 -0.010297555 -0.11860445 0.021598568 0.10169667 0.12966514 0.23121102 0.053430315 0.04408434 0.09735723 0.07731464 +-0.075622804 -0.009663358 -0.008456369 0.04637359 -0.012547424 0.012289749 -0.0147922505 -0.09031579 -0.009754119 0.063150704 -0.028468886 0.010632719 -0.011174729 0.016923571 0.030147363 0.008489182 -0.08278708 0.036996637 -0.07636365 0.03783356 0.0054455074 -0.066627905 -0.09452626 -0.06871973 -0.01864097 -0.024758022 0.025218638 0.055285778 -0.064782575 -0.07569462 -0.00841819 0.034139764 -0.00916006 -0.01412847 -0.03604042 -0.028282845 -0.0033774152 -0.08521741 -0.0694063 0.043046724 0.0670585 -0.08915853 0.032508574 0.042869724 -0.04518278 0.051279508 -0.07860646 -0.0774399 0.04390468 -0.10327086 -0.0003654658 -0.03373166 -0.02561061 0.032265224 -0.030462189 -0.00856604 -0.008737736 -0.10025981 0.026785579 -0.021591812 0.011418524 0.024717618 0.0016348098 0.0041598827 -0.023627404 0.027773244 0.039102364 -0.09823539 -0.0010992906 -0.00058480556 -0.07745153 0.05877064 0.0036204616 0.030991428 -0.003442756 -0.0054280725 0.01653751 -0.096872464 0.057173364 -0.05020074 -0.07325503 -0.050434217 0.007825187 -0.026660992 0.026290145 -0.07712084 0.0131484615 0.030984698 -0.08748517 -0.052772574 -0.06866816 -0.07927049 -0.052127127 -0.05778483 -0.05554194 0.021132352 -0.08378234 -0.012579732 -0.05034818 0.04040543 0.049878255 0.017504362 0.026727794 -0.031656574 -0.038297687 -0.043711673 -0.08315865 -0.05763502 -0.03735263 0.009797193 0.0056411913 -0.029630914 -0.01571517 0.070264004 0.0048754304 0.015721012 0.062006798 0.03768371 -0.03862157 -0.007917689 -0.029054858 0.05590473 -0.10116059 -0.09002839 0.010553107 -0.029918741 0.024257433 -0.09544781 +0.3778305 0.61069095 0.12392599 0.38181224 0.08817814 -0.2778511 -0.37532637 -0.023500428 -0.17353418 0.47373003 0.018370407 -0.11396721 -0.12480413 0.2756289 0.20949467 0.29883626 0.030222205 0.2553777 -0.100095116 0.6695427 0.24043582 -0.1699892 -0.06612247 -0.08927465 -0.020844202 -0.26996565 0.37037918 0.362017 0.19936626 -0.01954661 0.01947058 0.25329986 -0.31788215 0.10818054 -0.140694 -0.13104439 -0.1481762 0.30532646 -0.06584906 -0.7222311 -0.18642616 -0.06277581 0.19320604 0.2692183 -0.061888594 -0.031609394 0.21904211 -0.15989405 -0.0609649 -0.15981641 0.2645435 -0.14699385 0.40014586 -0.08655162 0.14132898 0.39354426 0.31139883 0.043047354 0.24520975 -0.01577732 0.3451323 0.54079074 -0.1454859 0.46944156 -0.15306608 -0.11628148 0.25920352 0.25126782 -0.1345152 -0.011437967 -0.035314515 0.17591469 0.223184 -0.026682988 -0.053281702 0.3120986 -0.068541475 0.073222905 0.2338416 0.4482391 0.016352708 0.42659828 0.07368753 0.02444958 0.01913318 0.24375977 0.059978932 -0.57528085 -0.005891576 0.06290725 -0.013872798 0.14675087 -0.2214504 0.62155974 -0.051089652 -0.10776529 0.077206284 0.1906825 0.21911313 0.1747083 -0.02152299 -0.3678653 -0.08782298 -0.026348634 0.007948263 -0.019488564 -0.18661246 -0.43807343 0.27185217 -0.11804317 0.10404115 0.18394713 0.3886514 0.06207907 0.34311345 0.40441385 0.073359236 -0.049069487 -0.023057425 0.019289482 0.26472107 -0.053966254 0.65167534 -0.04350555 0.06540948 -0.07902517 -0.05796209 0.02013638 +-0.006317432 0.017169332 0.2570564 0.3706749 0.03620927 0.109160826 0.37952366 -0.09968559 0.26171032 -0.26306996 0.13261735 -0.08493004 0.23850346 0.103835516 0.14765024 0.26278442 0.32230952 -0.14041024 -0.13752541 0.35754654 0.059534013 0.35655004 0.42820263 0.19915205 0.082768664 -0.29246497 0.10829254 0.06593619 0.057607256 -0.06387586 0.26396164 0.052033838 0.12708032 -0.25727612 -0.011101005 0.13029794 0.0010572287 0.1724199 0.06346343 0.23711924 0.035171207 -0.0654664 -0.049301848 0.3675102 -0.016241778 -0.026608879 0.11317363 -0.087431386 0.16196421 -0.07164549 -0.09807307 -0.09333832 0.013949345 -0.100394 -0.26975924 -0.056490354 0.1641127 0.11999922 0.25094837 -0.22449324 0.26171276 -0.014190972 -0.29921937 -0.08975432 0.27096403 -0.13652863 0.076534905 0.35855266 0.06931859 0.1909138 0.29880586 0.061733875 -0.13986541 0.12396501 -0.17109257 -0.0004687279 -0.14143935 0.040110156 0.47212362 0.25397336 -0.0910003 -0.199527 -0.21932861 0.38727602 -0.046867397 0.3321772 0.18329802 0.2074487 -0.019933106 0.24941127 0.22095862 -0.065143876 -0.031785652 -0.1709975 0.112516284 0.19038376 0.061826345 -0.46931905 -0.13454542 0.39076978 0.06451234 0.18548346 -0.10600382 0.24291262 -0.2026627 -0.38617808 0.07927939 -0.34113485 0.07518245 -0.32161325 -0.63335574 -0.023961853 0.007320792 -0.28156728 -0.09197155 0.273484 0.16430134 0.09018512 -0.07971958 -0.32969886 -0.20192555 0.46014258 0.2311912 -0.08310323 0.13025118 -0.051182296 -0.18617676 0.037527893 +-0.052746557 0.21984828 0.1911236 0.24404103 0.1527698 0.3122357 0.42286795 -0.29737738 0.32707778 0.049640752 -0.1358356 -0.020755723 -0.021350479 0.3360429 0.3660187 -0.046249527 0.2913059 0.30886385 -0.27452013 -0.03986099 0.16675468 0.11167957 0.20327857 0.09171881 -0.035766665 -0.28757203 -0.22698921 0.14685206 0.09929028 -0.05331974 0.031143505 -0.018196277 -0.044374384 0.13818914 0.4876666 0.43010578 0.10465097 0.06752366 0.22804257 0.5001966 0.07745351 -0.20363179 0.29394686 -0.11928423 -0.010903923 -0.14658411 -0.29453513 -0.17871358 0.028613465 0.0057584024 -0.09388378 -0.108753376 -0.2350358 0.4825197 0.120986894 -0.015978351 0.21052735 -0.119557075 -0.20388159 0.006027864 0.22402643 -0.03438852 -0.36908188 -0.13714345 0.0570401 -0.074751064 0.023684973 0.2179322 -0.0018652076 -0.23911355 0.07589214 -0.16267842 0.20298898 0.41805473 0.35892475 0.2812747 0.059879303 0.23834582 0.17409715 0.14409986 0.39946872 0.042930808 0.23167388 0.33456144 -0.10219917 0.48639646 0.2712862 0.58314174 -0.23006071 0.34604424 0.18547307 0.18206783 -0.18220873 -0.06620091 -0.2967462 -0.6934119 0.13727365 0.41123843 0.11807013 0.1722372 -0.22912966 0.09034227 -0.07183065 0.34641606 0.23450682 -0.13365687 0.284899 -0.1388017 0.2099603 0.24566676 0.28144 0.17481562 0.34330758 -0.003626332 -0.027013795 -0.106431775 0.097918175 0.3758 -0.13759464 -0.32266405 0.2094667 0.066153936 0.40875018 -0.03777554 0.34945112 -0.14244445 0.006109509 0.100056104 +-0.08379348 0.04087492 -0.053508844 -0.084422536 -0.004979071 -0.016730107 -0.05520115 0.029782284 -0.02477507 0.01736434 0.04250887 0.023638817 -0.05187866 0.01904032 -0.033867028 -0.031704497 0.010837719 0.04655081 0.011320302 -0.027258374 -0.09144543 0.026734933 0.06915007 -0.016573822 0.016097097 0.028055001 -0.09146446 0.06792634 -0.079506055 0.0044524954 0.007315515 -0.07524372 -0.015535601 0.05870863 -0.074809395 0.07698853 0.014623296 -0.09469627 -0.08407878 -0.07756267 -0.02624107 0.008144251 -0.045608208 0.0014337298 -0.007881865 0.008267113 -0.035879638 0.056597024 -0.033127915 0.05862586 0.059174195 -0.06682329 0.024607675 0.046614524 -0.09221592 -0.0037204195 -0.08243222 0.002083513 -0.05525139 -0.07707335 -0.0041967197 -0.09517863 -0.079025544 -0.04158541 0.014735649 -0.07402049 -0.016497338 0.040185917 -0.017050933 -0.047583893 -0.021503242 0.07154633 -0.065710194 -0.07717611 -0.010717589 0.0060353703 -0.03197191 -0.08130745 0.04868927 -0.02440943 0.0036387146 -0.07933879 -0.01786151 0.03817404 0.014479672 -0.062443305 0.031011302 -0.035284724 -0.07371512 -0.0339541 -0.008800049 -0.04773056 -0.01939577 -0.024655376 -0.07423365 -0.050965726 0.07084181 -0.04672135 -0.022168608 -0.066001914 -0.06951309 0.05593851 0.013611371 -0.038168296 -0.06713491 -0.06464372 0.065918036 -0.100994386 0.050514944 -0.036461666 -0.034466527 -0.08043366 0.016118353 -0.015436431 0.026439443 -0.06334798 -0.09271836 0.061781697 0.013283066 -0.012199084 0.048622075 -0.055780444 -0.002337281 -0.07578219 -0.044358935 0.03295553 0.054855857 -0.007884625 +0.40581304 0.26810616 0.5674228 0.4865312 0.07365437 -0.04979349 0.004499853 -0.25476837 0.26465648 0.17469262 0.43123105 0.16369504 0.40168542 0.3447413 0.21253031 0.4394 0.19636102 0.1409204 -0.28682625 0.14043924 0.56900585 0.2241623 0.0073507642 0.16910061 0.061572757 -0.43573126 0.41901055 0.65109825 0.21379153 -0.012880652 0.29879424 0.1833414 0.40464264 0.047787093 0.053269584 0.2939868 0.4529507 0.2748519 0.48853666 0.17851388 0.2634313 0.17925465 0.36505535 0.5669879 0.10759137 -0.19757017 0.3149464 -0.49847385 0.23970804 -0.04883773 0.32115757 -0.05555463 0.19091152 0.22972322 0.41599178 0.32903138 0.07946427 -0.02899983 0.41671598 0.01657571 0.22837166 0.5214218 -0.39463857 0.2364252 0.33812606 -0.00021347696 -0.09186736 0.44400626 -0.14920768 0.355972 0.04062087 0.26897728 0.1511219 -0.01013863 0.0073152683 0.03429441 -0.297926 0.28442195 0.08083615 0.22537164 0.104821414 0.043792315 0.14045244 0.23884504 0.047620364 0.5371769 0.18455942 0.2368937 -0.28530636 0.19211444 0.043570545 0.12613022 0.26341707 0.26876336 0.16329008 0.15763128 0.1973189 -0.037444096 0.25773558 0.301671 0.2575757 0.23322205 -0.33992043 0.2849338 0.04437526 -0.31321207 0.3638923 -0.42042813 0.058495156 0.09621311 0.123682916 0.13206744 0.46883723 0.06155516 -0.05434412 0.18529516 0.41569582 0.33648267 -0.0071839243 -0.24427554 0.48145026 0.16591845 0.1795416 -0.09742759 0.48380217 -0.11959085 0.15184091 0.12296751 +0.09518256 0.37668696 0.20948072 0.015287706 0.46392837 -0.08785665 0.20665699 -0.032246027 0.35721317 0.28995386 0.13103361 -0.08052522 0.46764314 0.39977425 0.10119007 0.38547173 0.19140457 0.41565296 -0.30981857 0.052172203 0.35393712 0.13480277 0.2693387 -0.016100695 0.0065126484 -0.1647522 0.28180838 -0.034355845 0.4757708 0.061674938 0.42219853 0.058345567 0.19724005 -0.03172595 0.36293325 0.28051725 0.14124545 0.10927052 0.30368534 0.112179235 0.1217135 0.20541866 0.16710123 -0.30840832 -0.1667255 0.0032133278 -0.18404117 -0.21582863 0.3531743 -0.0025668852 0.026518375 -0.035855714 0.2614439 0.17424966 0.328449 0.5984582 -0.1278654 0.08474217 -0.19918497 -0.17299613 0.3677829 0.25581056 -0.12167009 0.1338529 0.096129246 0.010778331 0.11795423 0.1883123 0.02611627 0.38865998 0.061574392 -0.0113758575 0.2832137 0.5400016 0.10045192 0.042359717 0.0069065443 0.24897602 0.09391121 0.09994877 0.31974086 0.10831973 0.18505529 -0.049476527 -0.06957059 0.43103054 0.18958521 0.2863956 -0.30305827 -0.038150225 0.5286073 0.2946112 0.5174446 0.2270646 0.23128581 -0.094016224 0.3008463 0.43119928 0.22991177 0.22592689 0.007989965 0.08184761 -0.054738726 0.1156104 0.022136493 -0.017944619 0.23992771 -0.18898492 0.15984677 0.29875422 0.1573685 0.38701025 0.16518009 0.12728015 0.32386488 0.39947307 0.19623715 0.29843658 0.061993103 -0.102879114 0.014526345 0.16834864 0.15260468 0.25048047 -0.026176646 0.05860718 0.15993063 0.059245963 +0.13477515 0.3377304 0.35907996 0.27041546 0.3201007 0.25889477 0.07666355 -0.07658821 0.1928566 0.40393987 0.12060137 0.22689727 0.32825422 0.22923891 0.2514062 0.32435265 0.14077196 0.15064135 -0.1584208 0.2523283 0.12787555 0.17930475 0.2004745 0.18937257 -0.015384986 -0.25558004 0.32143638 0.38025513 0.11736223 -0.04746897 0.35206386 0.2118295 0.33431187 0.23243977 0.21322462 0.20467363 -0.024395457 0.08284355 0.18759938 0.35636324 0.41866612 0.12035525 0.2580057 0.2542241 0.20690207 0.067223184 0.1924268 -0.21215108 0.21349843 0.023373941 0.32520252 -0.0486601 0.30126742 0.31917185 0.16749746 0.3100582 0.32854673 0.17011937 0.23190528 0.15413746 0.1481002 0.15890291 -0.31349555 0.2501345 0.24315105 0.026909834 0.24251013 0.26268306 -0.03801671 0.22529387 0.32522732 0.15854804 0.066685215 0.28194395 0.22853698 0.3230886 -0.032880932 0.27703625 0.3331686 0.21342136 0.10900299 0.20579381 0.23746756 0.21767241 0.041618913 0.29821426 0.11047305 0.36169663 -0.1536975 0.28886124 0.21519436 0.20162918 0.4262492 0.380171 0.21385701 0.29026362 0.2066497 0.3229864 0.1319003 0.06147603 0.0060505904 0.25549042 -0.096005335 0.26858324 0.19260271 -0.08023738 0.20632428 -0.34917575 0.16847046 0.2339302 0.18889685 0.17347123 0.2074829 0.15367489 0.20891231 0.34426114 0.27367392 0.2564355 -0.09583603 -0.031846087 0.2391837 0.1329699 0.33342418 0.27241182 0.21886627 -0.04054641 0.29197297 0.12423782 +0.35393825 0.39645606 0.592987 -0.15223004 0.41700393 0.47493747 0.32372224 -0.20905647 -0.05664529 0.11107042 0.13019404 -0.054704636 0.44707513 0.17168257 -0.042440113 0.09678743 0.23090895 0.15895626 -0.14778642 0.0937771 0.3137876 0.16335902 0.039900064 -0.16902031 0.08105147 -0.17552716 0.34424874 0.25846854 0.00392884 0.012563791 0.21755852 0.2417692 0.16727608 0.22317076 0.018002586 0.2373457 0.17422223 0.15432432 0.44675794 0.2613367 -0.12915389 0.24323928 0.20751403 0.21210478 0.23496148 0.042786628 -0.2255186 -0.23543651 0.6172816 0.014077654 0.28690523 -0.00021729576 0.25913796 0.27771908 0.16923082 0.040978625 0.09310878 0.28232506 0.06150354 0.17972471 0.23035377 0.4617699 -0.37870947 0.15227693 0.035789087 0.023547558 0.29103276 0.25969294 -0.10034715 0.4179267 0.37023196 0.26363784 0.23459992 0.35040787 0.08468239 0.3095666 0.02426383 0.04030316 0.06251318 0.17178263 0.13690884 0.15907013 0.014308604 0.07101339 -0.074322365 0.16247825 0.27183175 0.3317256 -0.084744096 0.4708347 0.18462743 0.20155983 0.3117959 -0.21579778 0.0393619 -0.031722166 0.034098916 -0.15670644 -0.024751171 0.42602405 0.1681049 0.3955303 -0.032096095 0.04362372 0.16152434 -0.0048185242 0.3003904 -0.24590616 0.15196434 -0.22167718 0.2600465 0.21130581 0.2553743 0.18984243 -0.021628147 0.074764706 -0.11302323 0.5617867 -0.02504267 -0.19234811 0.0729524 0.18718252 -0.17405857 0.19840874 0.1510434 -0.055633515 0.32724863 0.19780466 +0.40682858 0.38352707 0.07914323 0.009829304 0.14327021 0.5304619 -0.08800668 -0.25822487 -0.037194945 0.5399032 0.47894496 0.18740006 0.36937463 0.2054931 -0.09656801 0.2004657 0.14389673 0.19915928 -0.21071038 0.26087356 -0.4952502 0.2632233 0.057642885 0.250518 -0.027219085 -0.26559836 -0.09484236 0.37805638 -0.13226624 -0.25320414 0.24764428 0.040049113 0.093891114 0.22396354 0.31038302 0.0061721425 -0.06486725 0.23714694 0.09118693 -0.033459928 0.11593257 0.21812887 0.22851492 0.19498996 0.47694492 -0.16126762 0.12350092 -0.30706152 0.3049804 0.054296114 0.03232443 -0.014577307 0.3829047 0.16398348 0.07617817 0.036739744 0.49142733 0.23066743 0.228919 -0.06121124 0.027281007 0.14349487 -0.35644028 0.2049019 0.07387678 -0.13152719 0.38678128 0.32017902 -0.26882264 0.040847596 0.116739236 -0.046321075 0.35891688 0.07397558 0.21863382 0.19167884 -0.10445351 0.09606338 -0.64568305 0.11919047 0.015293664 0.38751474 0.33401948 0.34343937 -0.25825715 -0.050813742 -0.25756595 0.32590955 -0.23968266 0.2380248 0.23028784 -0.037125774 -0.1471825 0.21880883 -0.31955695 0.045931876 -0.013113277 0.016265504 -0.044629987 0.051051702 0.051046167 0.090975665 -0.19562939 0.26898018 0.3046096 -0.14036393 0.22778137 -0.25249922 0.18095465 0.18094896 0.5151494 -0.11581218 0.20551488 -0.111680955 0.16512032 0.19109686 0.093483225 0.07289195 0.036902677 -0.22736546 0.5050323 -0.25968012 0.45049554 -0.09656298 0.61347 -0.1424887 -0.26758373 -0.08588675 +0.10736618 0.24692583 0.06524911 0.42920917 -0.2655319 -0.06596387 0.38812461 -0.109593384 0.14762545 0.36813843 0.14274277 0.25480875 0.30400696 0.23700105 -0.010644764 0.20228033 0.18876363 -0.4509011 -0.16226806 0.0036955862 0.39582592 -0.040505577 0.027098494 0.018320717 0.05714884 -0.27907485 0.3110262 0.27883974 0.25936922 -0.078742 0.109290555 0.19415519 -0.16976051 0.03124228 0.3894296 0.16855134 0.48112553 0.30477518 0.45571432 0.064677656 -0.42140394 0.3318262 -0.20381118 -0.045079805 0.22580098 -0.025401607 0.2627118 -0.22524342 0.46022448 0.012100591 0.3760237 0.01260672 0.1270964 0.37987593 -0.34110612 0.25404721 0.19060567 0.14205165 0.031692166 -0.18939649 0.27963945 0.24016812 -0.15716298 0.011075612 0.0045054415 0.07389814 -0.21073702 -0.12666683 -0.0001986895 0.41795483 -0.098844156 -0.09304921 0.4610182 0.27348515 -0.34833634 0.23380877 -0.12252682 0.27346447 0.025986955 0.11130265 0.22250527 -0.01466469 0.16483906 0.29899088 0.044641826 -0.009558632 0.087242216 0.314107 -0.04577585 0.09835272 0.35467178 0.3893738 0.03377842 0.037323564 0.05661172 -0.11788783 0.338591 0.22820422 0.1707369 0.28085908 0.37546453 0.42772 -0.23827085 0.12035879 0.06466916 -0.153788 0.43632817 -0.20893651 0.16087638 -0.0530436 0.34748435 0.24178036 0.21944669 0.051719353 0.33816493 0.46531057 0.3402778 0.31300962 -0.08635716 -0.13615382 0.2149978 0.043037448 0.06252546 0.40530172 0.21896286 -0.053208552 -0.027647631 0.36314484 +0.04317351 0.050866254 -0.09401015 -0.015570616 -0.021605786 0.038959693 -0.04573168 -0.088944525 -0.0033477533 -0.011536237 -0.05065736 -0.0020503637 -0.07783819 -0.06066176 -0.08730546 -0.06574403 0.048798162 -0.052761734 -0.06377185 -0.030553374 0.05041548 -0.020023508 -0.049428396 0.020231048 -0.017415458 -0.0733036 0.023751985 0.05084634 -0.04461001 -0.029731872 -0.042914037 -0.019125698 0.0013968964 0.031178543 0.023795629 -0.07935334 0.056846946 0.019274155 -0.0018149856 -0.063519284 -0.06211241 -0.002584571 -0.060778704 -0.011945856 -0.02378283 0.042144626 -0.024600182 -0.019560322 0.057192657 -0.010837162 0.032401476 -0.061824515 0.02311909 0.015647365 -0.023038486 0.070793346 -0.048272535 -0.0688704 -0.008025185 -0.04469603 -0.06952268 -0.018700693 -0.013646144 -0.028795458 0.00992879 -0.010886345 0.06610266 -0.07694363 0.019706067 0.070454866 -0.0511288 -0.055632293 -0.005610277 -0.0833136 0.04068762 -0.055169284 0.03621193 0.06234177 -0.033700544 -0.081195645 0.06193828 -0.08493394 -0.07774774 -0.03305011 -0.00755386 0.036277056 0.06145921 -0.07338625 -0.088979214 -0.049846034 -0.051813286 0.029945232 0.06464869 -0.006261658 0.060884383 -0.035699945 -0.015574267 -0.055767544 -0.07614011 0.022934934 0.036162663 -0.056933414 -0.062743194 0.06955175 0.029715937 0.029889047 0.06677176 -0.07141069 0.0015513632 -0.033887703 -0.06704826 -0.07341748 -0.036046598 0.018522145 -0.0036035718 -0.077190064 0.0012656925 -0.087410524 0.033040605 -0.069122344 -0.0038207623 -0.077408075 -0.088640176 -0.07679953 0.060931884 0.07203704 0.013571388 -0.02657993 +0.20747255 0.23775949 0.27521494 0.25850233 0.27273348 0.2962308 0.18109 -0.02024708 0.26535198 0.38383493 0.17053257 0.2772971 0.31771532 0.17544287 0.0961572 0.2479843 0.187358 0.13078746 -0.24586447 0.20852499 0.19658728 0.2100018 0.16695139 0.2590832 -0.024795149 -0.22247669 0.29929718 0.12830073 0.14160323 -0.013118539 0.2725717 0.19110106 0.21514492 0.21512988 0.12890497 0.19359137 0.2296369 0.11756733 0.25273138 0.19230743 0.29756224 0.21349059 0.13029084 0.16915035 0.13307197 -0.039170418 0.27763265 -0.31225264 0.09323214 0.033104222 0.26473773 0.055374075 0.26535788 0.29078174 0.22431152 0.31294397 0.27006343 0.1339398 0.11570836 0.022185171 0.2608665 0.23050912 -0.2642089 0.1848656 0.25408557 0.01948965 0.14447291 0.14481848 0.093490094 0.2112784 0.27057296 0.2632455 0.26092112 0.21196954 0.20361322 0.3093042 -0.0068185716 0.20764016 0.21777245 0.18908678 0.17301503 0.23286301 0.23143297 0.23105264 0.05478056 0.19832683 0.16284886 0.25549218 -0.021315008 0.13789496 0.25038645 0.288663 0.39313704 0.22626439 0.21479343 0.25638655 0.21097198 0.21119134 0.23062447 0.22710629 0.22218543 0.2503661 -0.11465278 0.17584155 0.26647684 0.008479123 0.3024445 -0.30646876 0.15111305 0.10591463 0.25669023 0.22599006 0.15205027 0.24491428 0.17993987 0.19656388 0.245523 0.28069064 -0.045095656 -0.13769665 0.21066473 0.17215607 0.3147568 0.19645178 0.33955938 0.029794022 0.17149177 0.20001782 +0.3164696 -0.23977068 0.44650394 0.47550017 0.43778127 -0.1488479 -0.018831208 -0.25966606 0.18111004 0.484197 -0.6914809 0.097443946 0.18980546 0.28993964 0.24347514 0.30686718 0.09085731 -0.2874326 -0.23888935 0.22402003 0.43772826 0.058738347 0.41092733 0.3986888 -0.03266246 -0.335428 0.17908281 0.19607092 0.3662582 0.004162991 0.22048141 0.16623417 0.39058977 -0.29587576 0.15046754 -0.20945923 -0.14293766 0.5417499 -0.22942126 0.17454448 0.10724359 0.2118236 0.37258947 0.24090366 0.126369 -0.0824055 0.040107794 -0.19369535 -0.17683437 -0.09919535 0.016316056 -0.0896849 0.18390927 0.04274808 0.25773752 0.5074639 -0.22668561 -0.3559749 0.012383562 0.10551479 0.10777218 0.129227 -0.16396955 0.055727713 0.06093093 -0.12674811 0.0010070846 0.22505042 0.05173576 0.1791553 -0.21473561 0.16157202 -0.23227476 0.3238712 0.010903647 -0.33465263 -0.25090408 -0.052905597 0.029486192 0.23817916 0.4206987 -0.09656524 -0.04253999 -0.29415634 0.06035388 0.34324685 0.23360088 0.22431917 -0.060616072 0.2667888 0.4877703 0.08962669 0.2994207 -0.009796739 0.26934582 0.011935859 0.22591788 0.14033929 -0.11064442 0.15835269 -0.11039519 0.429636 -0.07924072 -0.1676312 0.034363672 0.009604919 0.076637395 -0.25447524 0.39442113 0.18262374 0.17324565 0.37733898 0.4400524 0.476012 -0.11528486 0.46026227 -0.11117295 -0.3569678 -0.0052505624 -0.23449592 0.017651714 0.2937664 0.044823214 -0.20442463 0.37727648 -0.09991414 0.22226596 0.098003924 +0.060341243 -0.053802382 0.022953687 -0.084859714 0.04754698 -0.06809884 -0.024854345 -0.12364072 -0.015094239 -0.041719586 -0.08678062 -0.051230624 -0.07447863 0.023567325 -0.051293045 0.04084198 0.06689582 -0.039935883 -0.028611109 -0.016272083 -0.023310319 -0.016481664 -0.08057687 -0.005010532 -0.027478123 -0.06109277 -0.05702683 0.0062443516 -0.005485127 -0.06992478 -0.070061006 -0.04093039 -0.040621012 -0.05968563 -0.10145531 -0.010329793 -0.08826138 -0.047793843 -0.11728703 -0.01492567 -0.041312285 -0.0194772 0.03706274 -0.049531136 -0.04228936 -0.009829281 0.0027425487 -0.01936008 0.057638932 0.01333993 0.014615936 -0.01686189 -0.0116236145 -0.03298471 0.04695556 -0.0101938965 0.025784975 -0.051679198 -0.13051176 -0.12598656 0.04912078 0.033991814 -0.05034384 -0.063483976 -0.014965545 0.0022905213 -0.045575332 -0.039755072 -0.016331775 -0.08772349 0.06602946 -0.057783503 -0.07120711 -0.10052105 -0.029719308 -0.082785055 -0.08384373 0.046062518 0.07040444 -0.0107476665 -0.0924473 -0.048758887 -0.054247458 0.027867591 -0.079106174 -0.097017035 0.016857153 -0.021758545 -0.036120884 0.064899415 -0.06627571 -0.10127776 0.010763498 -0.094521366 -0.03630048 -0.12926422 -0.06120398 0.04517158 0.023798157 0.04193722 0.060592044 -0.008030253 -0.073696524 0.012953138 -0.09182903 -0.0011417352 -0.04367352 0.017688049 -0.0012922102 -0.06351826 -0.03690675 0.010483535 0.06276206 -0.05493008 -0.04927732 0.017430916 0.047780477 -0.1156097 -0.06188295 -0.08221885 0.049517192 0.03878426 -0.06467457 -0.104410745 0.033567026 -0.08966292 0.0015074048 -0.062772565 +0.09294325 0.13074721 -0.0024455178 0.013068413 -0.016524361 -0.005044529 -0.08707218 -0.08689508 -0.067761265 -0.07233448 0.11592113 -0.040453415 0.081738666 0.037668303 -0.14737293 0.09725135 -0.06505066 -0.10424817 -0.18319985 -0.17305206 -0.05076932 -0.12734364 0.034517683 0.13248573 -0.08514529 -0.042666644 -0.14089938 -0.006152821 -0.14731784 0.030822352 0.049987856 -0.010411128 -0.050835744 0.04713192 -0.036065474 -0.032924064 -0.04507039 0.06393639 -0.14770131 -0.102246925 -0.050642252 -0.07239978 0.08608024 0.12124991 -0.068726145 -0.043460455 -0.0015818571 -0.17847444 0.09299227 -0.04959876 -0.026900824 0.041061327 0.02216946 -0.07089213 -0.11736837 0.030595213 -0.022103954 -0.1282896 -0.023621 -0.17476557 -0.0575064 0.053382836 -0.04798611 -0.05259104 0.059820183 0.06431896 -0.019366898 -0.15455945 -0.012308975 0.008169634 -0.033419237 -0.10053575 -0.109555915 0.06679072 -0.07065554 -0.018549295 -0.11358065 -0.11924408 0.023398792 0.13845499 -0.10644347 -0.03583629 -0.06789605 -0.069173716 -0.09882588 -0.10521099 -0.05656572 -0.08500578 -0.11988434 -0.081090145 -0.13089183 -0.035563763 -0.06346429 0.090284914 0.03366332 -0.060038112 0.00038380618 0.07042032 -0.1303234 -0.13403407 0.039097205 0.11204634 -0.20951255 -0.13453375 -0.05277072 -0.15653388 0.07721461 -0.16240698 -0.044450503 0.030109594 0.13852581 -0.043270268 -0.08170893 -0.007819557 -0.12244827 -0.12441036 0.0063879183 -0.08417148 -0.035440173 -0.09081391 -0.0037092394 0.04646768 -0.07848522 0.082429886 -0.11832572 -0.030137494 -0.1798684 0.003993938 +-0.013277825 -0.2840564 -0.10766828 -0.03729827 -0.043097753 -0.1552881 -0.112943366 0.027586859 -0.07901176 -0.2730486 -0.103876755 -0.14293161 -0.25217384 -0.11891876 0.052783534 -0.06955262 -0.021702217 0.0042831567 -0.007797045 -0.16298243 -0.12084232 -0.19276541 -0.0075397925 -0.052818917 0.024579464 -0.042443458 -0.2466092 0.08729405 -0.24004574 -0.05494037 -0.1401013 -0.06717212 -0.11588542 -0.094016396 -0.04364251 -0.19733876 -0.07628982 -0.20558196 -0.06294914 -0.17951474 -0.076459214 0.038397077 -0.071708865 -0.28269833 -0.12903813 -0.07257717 0.001468215 0.18448873 -0.046592873 -0.041008238 -0.24494755 -0.0851462 -0.23540412 -0.029335253 -0.16397262 -0.062391445 -0.19296148 -0.028835824 -0.033057496 0.10912157 0.029164607 -0.095251784 0.104328424 -0.08369296 -0.022795161 0.035642453 -0.06423286 0.02927259 0.09329259 -0.097203985 -0.18841586 -0.19795462 0.0021258546 -0.111256815 -0.14915091 0.035382606 -0.117002316 -0.29445788 0.07201173 -0.059073 0.024481867 -0.03413752 -0.069681294 -0.18381199 0.059583068 -0.117318176 -0.062289618 -0.21404988 0.015988022 -0.16297548 0.10843836 -0.2322134 -0.21880524 -0.15662594 0.02327794 -0.21291864 -0.11621259 -0.005369499 -0.09283185 -0.17385727 -0.11590879 -0.14458728 0.030744174 -0.12668946 -0.044690523 -0.1442731 -0.15013368 0.08422522 -0.18631913 -0.11186162 -0.097538345 -0.008634751 -0.097552136 -0.13572657 -0.15255813 -0.028170466 -0.06163155 -0.15756343 0.115762554 -0.019664528 -0.048005857 -0.09438675 -0.060750566 -0.1898546 -0.22521956 -0.10361497 -0.00073095266 -0.16700095 +0.014227125 0.3115541 -0.10448247 0.25926968 0.019400137 -0.13303986 0.09735336 -0.056843657 -0.01033929 0.4357192 0.40039566 0.24748152 0.2682654 0.44649094 0.114710316 0.17268574 0.29425514 -0.19541505 -0.29439446 -0.2030173 0.3187358 0.1283278 0.09000062 0.3295372 -0.074149325 -0.24190125 0.27615058 0.259361 0.23000085 -0.014451416 0.47585225 0.20303036 -0.14777943 0.23576769 0.012743123 0.06801652 0.32012847 0.114060566 0.018494304 -0.21862632 0.16719802 0.064533554 0.21895863 0.35203832 0.28188038 0.15980954 0.3942305 -0.27993187 -0.25524655 0.017817693 -0.09684343 0.094038755 0.49225497 0.37159494 0.044482544 0.123772606 0.32047215 0.016263304 0.18938607 -0.029322788 0.0268926 0.286123 -0.08792742 0.4243803 0.025356382 0.032593455 0.007911766 -0.012838726 -0.045425303 -0.018318478 -0.31004503 0.027857186 0.117086805 -0.29222214 0.22454897 0.3004968 -0.10494757 0.35430416 0.10861614 0.18751727 0.06129428 0.22356711 -0.3509894 0.39386424 0.064306125 -0.09331341 0.09998189 -0.3295697 -0.06303273 -0.043553248 0.19685026 0.17812711 0.33015332 0.4730274 0.18069714 0.16660015 0.22546561 0.25525177 0.045431506 -0.023918549 0.056466077 0.22876994 -0.09568647 0.041366056 0.18553123 0.003454394 0.2271768 -0.26940978 -0.02560409 0.40779647 0.047162488 0.030818025 -0.06444585 -0.025659462 0.030583415 0.2671783 0.2378663 0.22364877 -0.023620982 -0.21773721 0.3121657 -0.04478994 0.1584173 0.20822075 0.44454953 0.021728463 -0.07000164 0.0050058975 +-0.046987172 0.07390328 -0.0907921 -0.22385575 0.045392036 0.10758091 0.30520344 -0.16537474 -0.040107243 -0.22596787 -0.04392603 0.029094217 -0.05910545 0.12358048 -0.13522395 -0.042211186 -0.095191516 -0.017538108 -0.16223179 0.1073988 0.20159474 -0.12282031 -0.07564468 -0.17525406 0.033629004 -0.2099051 0.07809469 0.14274594 -0.36674595 -0.11204031 0.08443205 -0.15042919 -0.055384625 -0.11905226 -0.0634276 -0.048626624 0.1444103 0.003494489 -0.003683582 0.06815153 0.07443811 0.10038908 -0.16563787 -0.16285615 -0.23323481 -0.100489885 0.1907258 -0.22854178 -0.056208834 0.031763956 0.08917389 0.007904389 -0.034635473 0.077610046 0.1629842 0.09890668 0.037648544 0.13674057 0.053579163 -0.0037918033 -0.014490776 0.11280053 -0.17409419 -0.17270751 0.091662765 -0.045551244 0.05277637 -0.0048585054 -0.105594 0.22173446 0.18568131 -0.03281852 0.3011829 -0.0829009 0.027302336 0.22240657 -0.06263518 0.11752519 0.117283955 -0.018783553 0.004253754 0.023856133 -0.057261452 -0.27608797 -0.045837305 0.07224412 -0.17003323 0.19902849 -0.10991217 0.12256227 -0.03513749 -0.02312814 -0.017762622 -0.017555721 -0.006709435 -0.0044780946 0.13814643 -0.01232844 -0.14485532 0.109431766 -0.014714872 0.107646935 -0.09316956 0.11525923 -0.1244404 -0.19601497 0.17457865 -0.08001053 -0.041168105 -0.058019824 0.14967698 -0.17281148 0.049905747 -0.06423236 0.01593801 0.220359 0.043989692 -0.116945885 -0.008957748 -0.111511216 0.24356782 -0.014775516 -0.16339777 -0.016290803 0.017183822 0.011507672 0.060775343 0.22838686 +0.20427872 -0.5677402 0.17847088 0.39355782 0.34840485 -0.21188962 0.13168167 -0.20466097 0.1457134 0.32922164 0.42636657 0.31765333 0.1589745 0.27837276 0.19270237 0.2175927 0.36260474 0.15721376 -0.26171097 0.09724512 -0.24232903 0.08454565 0.020359647 0.1625646 0.108529985 -0.29462293 0.4007335 0.27356118 0.4123979 -0.08321913 -0.07914168 0.14294614 0.11360765 0.35326105 0.30633396 0.14531238 0.33086666 0.29222277 0.31395552 0.31229618 0.35797748 -0.38541934 -0.1667915 0.17162609 0.42548296 -0.1684699 -0.0043449453 -0.26315457 -0.13851973 -0.14225945 0.4289745 0.057007182 -0.08102599 0.42051968 0.18545341 0.15325913 -0.1119857 0.17846628 -0.3856971 0.1551962 0.30554608 -0.08922477 -0.3130382 0.2558885 0.17437391 -0.09101118 0.09010467 0.3932264 -0.04079132 -0.111018136 0.00897988 -0.12881519 0.34650877 0.050936356 0.15996678 -0.455646 -0.041844856 0.37948918 0.3724402 0.0026286065 0.13753456 0.3112534 0.105737776 0.16869336 -0.120122164 0.31154013 0.15193802 0.42971617 -0.13974503 0.19565415 0.28431377 0.0036206038 0.10731645 0.07677738 0.33279842 -0.12302181 0.13533919 0.3426865 0.36177692 0.19670108 0.18831147 0.09500973 -0.14402145 0.47236553 0.03256489 -0.097578 0.23222768 -0.23786685 0.09564466 0.29410255 0.3926067 0.28481302 0.14920892 0.102821894 0.397979 0.5356176 0.5576618 0.016906891 0.08157619 -0.17391428 0.25865528 0.012209198 0.39029336 -0.14073074 -0.116092436 -0.014966637 -0.33301744 0.19078006 +0.035767518 0.08862213 -0.22713648 -0.18994382 0.22761555 0.37100595 0.5885138 -0.105718665 0.13345048 -0.010393797 0.3519682 0.13359022 0.31876978 -0.21554373 -0.02658805 0.2599991 0.24233936 -0.041851353 -0.06691142 0.28401738 0.40024468 0.0023721498 0.16252224 -0.01379832 0.06373184 -0.3421501 0.6069304 0.0027243262 0.2306469 -0.09408809 0.16402362 0.26731098 0.35154897 0.23901859 0.508301 0.027355382 0.10185891 0.26560482 -0.06362358 0.3628409 0.35483977 0.06354372 -0.36110368 0.11712354 -0.12258162 -0.13582851 0.23049349 -0.2068826 0.0660921 -0.07005208 0.08121082 0.038634043 0.21752982 0.074380904 0.03822559 -0.047226675 0.5895793 0.20645109 0.2675392 0.13623972 0.1256958 0.38451552 -0.4335387 0.024360755 0.03988295 -0.067043744 0.2926473 0.1604094 -0.008232008 0.120053254 0.32062215 0.34633034 0.27461785 0.297155 0.17591278 0.14536315 -0.015976338 0.2744093 0.40444914 0.11923163 0.16862899 -0.03768328 0.4013678 -0.031854637 -0.10776657 0.21362312 0.052225295 0.02440798 -0.0980192 0.18569528 -0.098233834 0.17485462 0.4852832 0.052145757 0.13649392 0.1642933 -0.08210369 0.42257 0.30406603 0.09468728 0.28700966 -0.084791966 -0.24551995 -0.18084863 0.16686054 -0.20078808 0.20668414 -0.2702943 0.1992128 -0.074260764 -0.08038262 0.45237502 -0.080961496 -0.1319439 -0.022603597 -0.08096737 0.33114904 0.30066606 0.080271296 -0.2694709 0.0518443 0.25833023 -0.27300066 0.20119193 0.26617312 -0.0077483463 0.56406975 0.079225175 +-0.078799635 0.051722843 0.04431378 -0.025842376 0.07217434 -0.0840839 0.0054693124 -0.02368654 0.009048011 -0.074468315 0.012754753 -0.093831874 -0.01040381 -0.07239046 0.0062174955 -0.09235448 -0.044509344 -0.0995099 -0.09059859 -0.035165492 -0.06367979 -0.06785678 -0.10403614 0.024210697 0.0017999231 -0.013831044 -0.05557882 -0.027608013 0.018444246 -0.074043356 -0.04008653 0.00368783 -0.07339745 0.01105418 -0.052134067 0.039518468 -0.010579982 -0.04232429 -0.09624107 -0.03604768 0.03684525 -0.059454147 0.049840428 -0.079039186 -0.02346512 -0.08462482 -0.098202914 -0.06842929 -0.071514525 -0.052362222 -0.034342434 -0.08833861 0.046862226 0.030597571 -0.071906686 -0.08237308 -0.025228217 -0.07835359 -0.054236867 0.026110254 0.014895689 0.025824893 -0.03433171 0.05660191 0.011379456 -0.10273065 0.00912468 -0.057449553 -0.08911222 -0.097372964 -0.10278984 -0.037309222 0.034970544 0.07002104 0.000654592 -0.08252658 -0.09362385 -0.0039513223 0.042102754 0.067769185 0.051266614 -0.051660176 0.034304854 0.031534906 0.028150925 -0.05085854 0.01763793 0.04376505 -0.008240279 -0.05129197 0.0053613693 -0.072749294 0.023791356 0.04835565 0.065825835 -0.07387315 0.06283738 0.06762692 -0.08380268 0.05879346 -0.007967339 0.04444087 -0.040290195 -0.08404743 -0.018697243 -0.112685345 -0.0159761 -0.12597115 -0.08140568 0.04117809 -0.069309555 -0.06797063 -0.036349747 -0.09671232 -0.09210743 -0.027690195 0.025174422 0.030660903 0.0668533 -0.120074466 0.06881865 -0.10173161 -0.09180034 -0.09063314 -0.053378895 -0.021644374 0.011331657 0.01201329 +-0.044698443 -0.05483551 -0.08408594 -0.06928788 0.026728155 -0.04913295 -0.016313462 -0.002547193 -0.058405615 -0.08934493 -0.03602872 0.033334948 -0.11726453 0.046869833 -0.03970815 -0.07189368 0.011560292 -0.056945637 -0.11471384 0.14678253 -0.061730906 -0.0075075123 0.053130835 -0.05827557 -0.042398702 -0.10306325 0.0007707475 0.001616205 0.028794514 0.05325448 -0.0037555795 -0.0005675498 0.09766771 -0.12659627 0.08982792 0.06793043 -0.007515866 0.07469212 0.04996982 0.03187496 0.045201693 -0.009044893 0.020704368 -0.055643693 -0.13146456 -0.08851759 -0.034678806 -0.089826785 -0.0011297857 -0.06940593 0.046355706 0.044999648 -0.06611465 -0.013019951 0.023229772 -0.076691225 0.11311106 0.04985318 -0.015361886 -0.018797807 -0.026008718 -0.06679218 -0.13490804 0.029116368 0.009519814 -0.03436306 -0.012394124 0.01666716 -0.075069934 -0.003534309 -0.005325299 0.036876682 -0.045202672 0.04294657 -0.03626442 -0.058768082 -0.073699 0.03099328 -0.05811097 -0.06902103 -0.0075681033 -0.033712413 -0.047379714 0.052197177 0.0056767077 0.099293664 0.048701808 -0.10264679 -0.0007334695 -0.055554006 -0.005079265 -0.029778223 0.06745823 -0.078429036 0.011723551 0.0329098 -0.01731549 0.05459756 -0.006795108 -0.012815014 -0.09312008 -0.06561231 -0.023425369 -0.04494367 -0.027417894 0.01694876 0.106559426 -0.041246966 -0.037393935 -0.10033814 -0.0034544137 -0.058687214 -0.020124966 -0.03112838 -0.023251886 0.012537845 0.024379436 -0.05003736 -0.07630127 -0.10871228 -0.010061271 0.058789693 -0.03404267 -0.07320422 0.102829576 -0.08659351 -0.003995578 0.020019514 +0.14030825 -0.51056165 -0.14977399 -0.34105018 -0.2211237 0.4738519 0.24484819 -0.09180007 -0.11008439 -0.0041041677 -0.28009138 0.46720338 0.36565718 -0.13652702 -0.008674278 0.14464818 0.10435664 0.029790027 -0.10699531 -0.03271259 0.09762348 -0.16828103 0.1436865 -0.072402254 -0.052241415 -0.051531717 0.25094333 0.2551942 -0.24456428 -0.08348752 -0.40489006 -0.5763571 0.37673035 0.1565815 0.2699808 0.2090634 0.17195737 0.24546841 0.37503347 0.23010717 0.10019407 0.386177 0.19956201 -0.31064168 -0.008314845 -0.023315344 0.14014487 -0.33447954 -0.025922127 -0.25456426 0.18453354 0.07329296 -0.40192515 0.12615612 -0.061189532 0.0839783 0.032015394 0.22501937 0.21201417 -0.3658434 0.037950445 0.37400773 -0.121163964 0.28785235 0.23956014 -0.019218482 0.050525006 0.34562364 -0.22269449 0.20378403 0.263392 0.18410273 0.19146934 0.0962161 -0.14800175 -0.060983673 0.044467837 0.1936137 0.020134674 -0.30596885 -0.030889492 0.046262767 0.39790022 0.08428592 -0.041885354 0.34732878 -0.51878965 0.42457122 -0.20455106 -0.31409162 0.34018958 -0.026417777 0.34593344 -0.21185952 -0.26849404 0.36386737 0.25047973 0.104346156 0.057417534 0.030520746 0.35586897 0.14943929 -0.08329696 0.32737252 -0.02796951 -0.5474195 -0.12970126 -0.17436221 0.10046334 -0.08268354 -0.20342474 0.033972505 -0.13818438 0.21115023 0.22416602 0.11810904 -0.18426675 -0.31043836 -0.052088525 -0.0170325 -0.5813377 -0.3198454 0.011326989 -0.34582087 0.5143766 0.0060773143 -0.29998565 0.027952868 +0.19751312 -0.14511901 0.6214709 0.21915323 0.3168021 0.36520234 0.3918528 -0.12018045 0.17135847 0.037708614 0.15464535 0.099030346 0.039032996 0.06825439 0.079902366 -0.061655387 0.23626132 0.22070105 -0.13933185 0.100352906 -0.04474028 0.2927325 0.26121283 -0.123275466 -0.09880815 -0.10630711 -0.24729423 -0.2786571 0.0059262924 0.0042114942 0.0804523 0.15058047 0.026042627 0.37672237 0.20020367 0.39828724 -0.07290536 0.1361311 0.14325692 0.37212607 0.14706409 0.28927165 -0.040552292 0.017257303 0.22780167 -0.12176805 0.17814144 -0.09914311 0.3981103 0.016716793 0.34658816 -0.025421591 -0.022084031 0.2570913 0.33935 0.35818458 0.2294873 -0.076187745 0.34587747 0.23283614 0.44477838 -0.07135242 -0.45464084 0.019023307 0.3247839 -0.04854179 -0.03765746 0.24263653 0.019481367 -0.03193951 0.4554732 0.13388713 0.09891812 0.2609945 0.4370009 0.26503298 -0.10727818 0.1893718 0.24074312 -0.2950434 -0.020577043 -0.15189892 0.38919565 -0.0991558 -0.089180924 -0.14000301 0.20628923 0.37062088 -0.14381237 0.0131591 0.3131233 0.23646215 0.12559398 0.092721894 0.124008656 0.21547455 0.10784737 0.05697634 0.059778884 0.25112525 0.12929007 0.27636033 -0.08944078 0.29741496 -0.17461394 -0.12724957 0.45943287 -0.40641215 0.15870064 0.10484008 0.20971389 -0.17165066 0.13961925 0.4080346 0.30875537 0.11635081 0.34270665 0.25507605 -0.05554657 -0.07898113 0.028881183 0.3122244 0.23751636 0.25624382 -0.0108384695 0.051959578 0.15976688 0.04318742 +-0.039998937 0.049099654 0.021609884 -0.013929638 0.055284936 -0.05304574 -0.11367723 -0.05679486 0.03835972 -0.078076154 -0.046558384 -0.08752907 -0.051536437 -0.010309787 0.042483587 0.058710776 -0.0865686 -0.06999838 -0.07376587 -0.046866182 -0.08691923 -0.09183958 0.016431687 -0.07943521 -0.002919499 -0.056336354 -0.055289365 0.011076279 -0.09108817 -0.07565395 -0.11000667 0.013650329 -0.083610594 -0.114067875 -0.13579212 -0.0013263643 -0.048048995 0.04939255 -0.01991706 -0.09881252 -0.040483665 -0.009600314 -0.04712964 0.04386978 0.039650027 -0.081291005 -0.08040062 0.0028716223 0.06313834 -0.025632894 0.05685978 -0.04321752 0.02653695 -0.10241036 -0.09208701 -0.081303544 -0.10871748 -0.061728142 0.011829223 0.05683139 0.06264042 0.024366712 -0.085767485 -0.07454703 0.035088077 -0.016795382 -0.10150136 -0.0076925186 -0.12897412 -0.068632744 0.02253024 0.0023093186 -0.011833167 -0.006848284 -0.0055261347 -0.034949426 -0.014922045 -0.07572834 0.008671813 -0.043614723 -0.06661664 -0.0864457 0.013633271 -0.08885921 -0.06624801 0.022009978 0.06669134 0.024396256 -0.013767422 -0.032423653 0.023511726 -0.03274786 0.063776255 -0.07120686 -0.025842445 -0.07609209 -0.07945793 -0.050379932 -0.034469787 -0.04125404 0.066004544 -0.0022518747 -0.115013845 0.05655561 0.015347686 0.026992854 -0.07477907 0.014094321 -0.03932436 0.06950247 -0.09021125 -0.08811298 -0.0012370858 -0.082147196 -0.0235359 -0.046531044 -0.103425175 0.056122918 -0.060534634 0.009808091 -0.09185199 -0.010056805 0.026722232 0.023964627 -0.058096197 -0.1016085 -0.084804624 0.06595089 +0.2832186 0.067910805 0.0035658914 0.162475 -0.07948559 0.24984388 -0.4317578 -0.21899183 0.055416107 0.32605317 0.17583083 0.3040095 -0.17673169 0.14240061 0.07252142 0.15975812 0.16733694 -0.073396385 -0.31825668 0.11057497 0.25107494 0.20101818 0.09607587 -0.12501004 0.025303498 -0.25220525 0.5235974 0.02763491 0.21383211 -0.060548794 0.46274444 -0.079148434 0.22250247 0.1445188 -0.119779594 0.02384856 0.244307 0.15778449 0.12856117 -0.22818214 -0.020126099 0.13619538 0.33888438 -0.03772599 0.0021987704 -0.17375332 -0.099216774 -0.22539194 0.25581503 -0.13600525 0.17362003 0.02350021 0.50011444 -0.19964093 -0.16453958 0.16627017 -0.09402537 -0.06187207 -0.2951518 0.07530693 0.19860232 -0.1509706 -0.26507324 0.2364912 -0.037854727 -0.023865024 0.20181462 -0.062307402 -0.24393734 0.0688664 0.22612664 0.10557135 -0.20428255 -0.28614876 0.07005811 0.14201592 -0.22428168 0.098598495 0.18708088 -0.14621806 0.09302438 0.054323733 -0.029828448 0.20268364 -0.19468364 0.203218 0.007291137 0.34384742 -0.1850077 -0.23676935 -0.045399196 -0.06081298 0.5019646 0.39281937 0.15791357 0.07110568 0.30222222 -0.085829206 0.23262678 0.18385766 0.28852394 0.25414863 -0.10749254 -0.1368518 0.2936854 -0.0482574 -0.04686789 -0.32385528 -0.027084578 0.2340085 0.12977996 0.073699854 -0.05667381 -0.019027125 0.20944153 0.11756177 -0.0417758 0.09658401 0.077032246 -0.1503087 0.31389558 0.2776651 -0.07791109 -0.031744905 0.23509748 -0.2029339 -0.023355387 0.10068341 +0.05885242 -0.086075544 -0.17055516 0.0083686765 0.047365386 -0.1439386 -0.10387994 0.068032645 -0.06908104 -0.4023207 -0.10952516 0.18234925 -0.25368467 -0.011403958 0.061518773 -0.080840036 0.1009953 -0.120064475 0.047091972 -0.12065696 0.0706789 -0.16795598 -0.00073109637 -0.16832833 0.0962258 0.054861218 -0.032369137 0.0010906996 0.06977596 0.10278614 0.010035678 -0.1321808 -0.18938985 -0.074093804 -0.1559817 -0.20777082 0.03078753 -0.18882877 -0.010505951 -0.3019942 -6.9103844e-06 0.12643519 -0.088184014 -0.2223908 -0.15635413 -0.027256798 0.074574545 0.116883665 0.13027439 0.0447134 -0.0527594 0.08268675 -0.18205169 -0.14180698 0.11651352 -0.06240584 -0.17999491 -0.09005967 0.036221378 0.21790609 0.030737765 -0.13199474 0.090113 -0.28636286 -0.033317167 0.011666246 0.1906245 -0.109118745 0.009578276 0.028881613 -0.2629735 -0.10875118 -0.06055366 -0.031575985 -0.14809935 0.047321703 -0.13245697 -0.11261377 -0.17031147 -0.05861608 -0.17786422 -0.07033377 -0.18509169 -0.2808071 -0.031683013 -0.24363412 -0.09662762 -0.081843466 0.00085714005 -0.1394895 0.092783056 -0.22829671 -0.129485 -0.061164107 0.22894171 -0.11299924 0.019164136 0.06255576 -0.102554664 -0.118276335 -0.11757833 0.047732558 0.018343585 0.06752136 -0.009375453 -0.04655986 -0.11203433 0.06721959 -0.12560785 -0.124631174 -0.25256935 0.105194695 -0.30439073 -0.10013532 -0.20018019 -0.0083725825 -0.059987802 -0.121252276 0.06587944 0.006337549 -0.20582123 -0.12118071 -0.18979883 -0.35432762 -0.2127865 -0.0779759 -0.01400546 0.018651098 +0.045563653 0.3432867 0.04582936 -0.14024962 -0.08208092 -0.2726434 0.06485741 -0.0024017768 0.09385586 -0.12906367 -0.3696335 0.19474451 -0.0157727 0.13853753 -0.20859559 -0.044720214 0.10216875 0.31881022 -0.10101881 -0.28524384 0.132039 -0.13584924 0.22333835 0.036104273 -0.11176821 -0.0682587 -0.03774414 0.036417097 -0.021028208 -0.004361334 0.2870162 0.123804234 -0.24945171 0.06178884 -0.30589104 0.05371086 -0.22804739 -0.1821359 -0.08295024 0.06778218 0.02459642 -0.2993974 0.114762574 0.24038562 0.2226476 -0.03880777 0.025661524 -0.038055044 -0.21532053 0.02440414 -0.11832482 -0.034565415 -0.28636366 -0.02401545 -0.3807877 0.017813776 -0.20262177 0.10379118 -0.13589598 -0.089878336 -0.36593023 0.16997288 -0.032967202 -0.08806341 0.08710733 -0.09897782 -0.24137904 -0.02487192 -0.033780564 -0.088793576 -0.11663271 -0.35862088 -0.2615839 0.11063389 -0.14055735 0.027706634 -0.18740517 0.20520736 0.15077537 0.19522014 -0.16266516 0.0785627 0.05175212 -0.10871144 -0.062428646 -0.20478083 0.15430816 -0.08578139 -0.1383597 -0.4784271 -0.028318597 0.17461166 -0.30197173 -0.028354317 0.20300093 0.16285573 -0.08147733 -0.37573868 -0.08884118 -0.0847961 -0.2512444 0.074246295 -0.11977838 0.13470928 0.077642955 -0.043767214 -0.17427191 -0.05063095 -0.15231445 -0.14515054 -0.3217391 -0.06261759 0.114484556 -0.17285068 0.08275228 0.20797363 0.043252327 -0.36743593 -0.013443208 -0.19458438 -0.20139094 -0.19072264 0.06346793 0.25686508 -0.16557252 -0.18040413 -0.2808103 -0.11462475 +0.10844927 0.31236902 0.4204689 0.47214368 0.30760515 0.20200449 0.24575059 -0.085074395 0.085359216 0.27159697 0.4367641 0.16309287 0.28050914 0.08948181 0.2474148 0.1958696 -0.06953027 0.22782408 -0.084417574 0.28079242 0.16992344 0.25157416 0.19859444 0.318402 0.018237943 -0.15200791 -0.09050595 0.24714886 0.36967528 0.049723595 0.45239988 0.13568299 0.09641683 -0.053621005 0.026320891 0.10257606 0.11834991 0.19125117 -0.04073439 -0.2587595 0.27458423 0.22014445 0.3198844 0.44422266 0.11488198 0.038292196 0.32561406 -0.3204792 0.22789893 0.023521326 0.21038409 0.0030783669 -0.13783777 -0.18423073 0.34795147 0.41165566 0.26453525 0.21787624 0.527657 0.099709295 -0.08408177 0.37073612 -0.36163118 0.19147152 -0.009287589 0.039458334 0.1974941 0.1369977 -0.045604024 0.1603677 0.281164 0.45161858 -0.1966528 0.32662678 0.45305693 0.1290563 -0.13619636 0.27740428 0.22261769 0.16929677 0.1696779 -0.016267855 0.26972136 -0.036313165 -0.044140927 0.45774978 0.060002003 0.10596591 -0.024930395 -0.04730269 0.2990699 0.2563968 0.45214072 -0.03531828 -0.12543122 0.20094235 -0.029339334 -0.19017676 -0.35091028 0.1636193 0.22826087 0.19084048 -0.08757287 0.07845795 0.26093328 0.04500053 0.18706538 -0.32363895 0.46764272 0.15887797 0.08852697 0.049459983 0.12769969 0.33263963 -0.20497106 0.07190056 -0.046120673 0.08555578 -0.005474111 -0.21171041 0.105458595 0.3940065 0.36752534 0.24511883 0.07887615 0.07341431 0.46817458 0.13723654 +0.0847501 0.420288 0.45878732 0.3128288 0.4021988 0.30841827 0.20308888 -0.21680818 0.020556694 0.11444975 0.33322844 0.07085348 0.08618564 0.40184107 0.03306849 0.078274764 0.41166407 0.14346404 -0.14958218 0.0980759 0.24611679 0.19341505 0.059150588 0.30519438 0.079737194 -0.19277042 0.17070426 0.085203715 0.20361437 -0.04732961 0.28695622 0.18127596 0.11680865 0.15800408 -0.117965 0.3014989 0.09973377 -0.026131345 0.111827366 0.2544842 0.37131476 -0.15175094 0.38789922 0.2973908 0.076327346 0.014191099 0.27788526 -0.26972154 0.45441154 -0.0008983197 0.16974327 -0.00662302 0.3829993 0.350333 0.06594276 0.08205941 0.20724846 -0.13110153 -0.03910145 0.1398437 0.17941236 0.14468363 -0.30394292 0.2909698 0.18729962 0.05289144 0.025107658 0.12394951 0.096180774 -0.066649534 0.11347878 0.24552059 -0.0053186235 0.005526741 0.34705797 0.0866747 -0.054298144 0.4347637 0.37817508 0.24935818 -0.18109532 0.18556929 -0.16298343 0.17921251 0.04886889 0.03459862 0.0792718 -0.058562733 -0.090414986 0.31240645 -0.15976311 0.19330278 0.19994159 0.26833308 0.32220542 0.11271086 0.31870154 0.07073046 0.08054147 0.21161206 0.08505449 0.08365824 -0.13987193 0.38198397 0.057330176 -0.0055792085 0.35047632 -0.355049 0.1195698 0.3363422 0.25226754 0.11292706 0.35302123 0.009824037 0.2913465 0.17722747 0.4356719 0.39574423 0.0041804872 -0.15383576 0.37003705 0.41260827 -0.21422108 0.21264237 0.3338183 0.016317729 0.098424144 -0.066209644 +-0.051938202 -0.038498826 0.015455961 -0.09566491 -0.13544069 -0.11360405 0.013115272 -0.1596439 -0.24815354 0.16874619 -0.1034593 0.0668928 -0.033505823 -0.19727017 0.14634047 0.03245558 -0.020919405 -0.018352794 -0.014641548 -0.17071478 -0.081726015 0.005433666 0.10181065 -0.04714738 0.04630091 0.012627596 -0.24318889 -0.329038 -0.14278787 -0.022905096 0.027171336 -0.14439459 -0.15971698 -0.0023036688 0.056883223 -0.31099966 -0.003029623 -0.21256684 -0.19507508 -0.09410876 -0.16942495 -0.110412136 -0.026019853 -0.13316193 0.046928383 -0.059631594 0.08643375 -0.100343205 -0.053636376 -0.005376669 -0.12597634 0.014356297 -0.33944073 0.10293505 0.08389876 -0.03475216 -0.14341311 -0.19434977 -0.07062619 0.09346749 -0.03217715 -0.197737 -0.05022091 0.06832406 0.0034525727 0.065290555 -0.084372595 -0.33849835 0.040680427 -0.014447435 -0.10198047 -0.010787306 -0.177543 0.048759326 -0.08941611 -0.03921537 -0.21627714 -0.123234876 -0.06353442 -0.016023755 -0.1128931 0.05726477 -0.23115939 -0.07945348 -0.06132063 0.03859396 -0.13644338 -0.10159367 -0.091187686 0.050056946 -0.014349876 -0.28065497 -0.16250288 -0.18634818 -0.12826115 -0.13853337 -0.01385298 -0.22869834 -0.15646759 -0.15098332 -0.2629341 -0.0677647 -0.17223991 -0.11943827 -0.11765883 0.025971575 -0.14518718 -0.030934494 -0.057081442 -0.09499952 -0.15450945 -0.10654261 0.02898563 -0.15146305 -0.31898373 -0.054996144 -0.42896995 -0.2026779 0.04311328 -0.12748209 -0.1203666 -0.26431495 -0.1376752 0.018857831 0.016971722 -0.062409725 0.19775885 -0.07483946 +0.15632293 0.31995422 0.2586828 0.19937083 0.35485548 0.33542103 0.26513007 -0.09421375 0.2096759 0.3099949 0.2611777 0.26350856 0.43512046 0.08280221 0.16592878 0.19287282 0.05588937 0.24325278 -0.25637817 0.22686143 0.15832546 0.21235348 0.13313574 0.2342088 0.055368554 -0.16874105 0.043823086 0.36165413 0.11157494 -0.074688 0.24575917 0.15555787 0.30375725 -0.06438441 0.23063141 0.22983031 0.045321107 0.15780167 0.29009792 0.114383794 0.35838085 0.17406431 0.052287478 0.28288415 0.086895466 -0.08618777 0.237991 -0.2648798 0.09690012 0.011951675 0.13845253 -0.034481984 0.1483956 -0.100511886 0.022146313 0.36436787 0.40215823 0.19807701 0.18353584 0.10950008 0.22707132 0.29216793 -0.29377368 0.00023722944 0.24339098 -0.03191041 0.19808546 0.23358501 0.066411346 0.25747347 0.16426149 0.26421678 0.18580215 0.25259393 0.20664819 0.2853264 -0.09870007 0.3542891 0.2926011 0.16262892 0.13365722 0.2238285 0.15782899 0.2092986 0.015336498 0.19152834 0.055196512 0.13442615 -0.10094652 0.051858515 0.18191428 0.20936736 0.28118417 0.11733629 0.20674914 0.34961262 0.25963184 0.18611644 0.16613947 0.11531179 0.23986524 0.1532441 -0.054144327 0.24569549 0.26709342 -0.085017495 0.37493813 -0.18615654 0.10487302 0.13213147 0.21874188 0.24820372 0.25465617 0.2156595 0.18085842 0.20231496 0.41090927 0.25648355 0.00027325773 -0.13298446 0.2654041 0.23646924 0.2476882 0.15910369 0.29946184 0.010262432 0.24106136 0.07548948 +0.43415722 0.35069293 0.32533845 -0.09245735 0.31323132 0.050459128 -0.12106704 -0.25641233 0.092375614 -0.038211983 0.22227982 0.3144816 0.43397865 0.23461227 -0.105558164 0.525352 0.25369522 0.24254346 -0.1666847 0.22670434 0.033190455 0.12921575 -0.29570216 0.10398897 0.022801984 -0.25209585 0.32950178 0.22687748 0.012919888 -0.059656225 -0.026725499 0.019082796 0.5012316 0.1899892 0.16107531 -0.22218782 -0.0027894375 0.29245204 0.39414677 0.31095466 -0.37448317 -0.0010065363 0.356558 0.36621946 0.27710012 -0.104197316 0.30570254 -0.27305198 0.27175796 -0.04417656 0.2884493 0.01906056 0.2917213 0.3735427 0.10778607 0.13208207 0.20563255 0.026834827 -0.06447111 -0.061326854 0.3847304 0.17810202 -0.30003214 0.005864127 0.22485028 -0.0021858932 0.024530616 0.4604553 -0.12139182 -0.10623899 -0.0341898 0.24210761 0.20604716 0.10015286 0.21325995 0.3379417 0.040844247 -0.11128874 0.002697832 0.14370695 0.019528618 0.30229518 0.30391824 -0.062849924 -0.05408174 0.44047302 0.30934504 0.48708764 -0.09594049 0.25241724 0.25560814 -0.18705188 -0.09525515 0.311959 0.1791245 0.31584048 -0.09235725 0.18443067 -0.047792155 -0.0852972 0.12586477 0.042606603 -0.11376011 0.08415544 -0.04264632 -0.07367098 0.22652324 -0.17731114 0.30021656 0.31147903 -0.0010664326 0.027556092 0.37171602 0.10366603 -0.17548594 0.16724938 0.031054148 0.31643087 -0.06999562 -0.055893283 0.15738733 0.13855919 0.30492637 0.086967416 0.5207336 -0.06707559 0.054686364 0.028673489 +-0.10834323 0.20543407 -0.24540165 0.04275225 -0.04972961 0.1371124 0.23431109 -0.09963303 0.08248988 0.3592511 0.26857424 0.23832925 0.16830942 0.40547708 0.12251519 0.3764499 0.12287718 0.2869345 -0.24581927 0.12062072 0.41392758 0.021153294 0.24336912 0.34050164 -0.04318666 -0.08307056 0.09104006 0.31973583 0.35707238 -0.047808804 0.32697818 0.10357044 0.3103777 -0.118254706 0.4818041 0.31218782 0.2129178 0.056348108 0.042996407 0.21821731 0.1957361 0.17018574 -0.06984241 0.078211784 0.10532712 0.030189006 0.24022955 -0.3283703 0.05610006 0.07524082 -0.20504245 0.02803004 0.15165657 0.32329777 0.05731876 0.29183784 0.1994071 0.3946798 -0.025876906 0.09570879 0.13155498 0.20592543 -0.24006632 0.02862575 0.025859606 -0.070629895 0.12012089 0.06877909 -0.13612303 0.2137675 0.24789403 0.06496405 0.20336425 0.5770411 0.18076622 0.37889174 0.021599751 0.24237715 0.24192922 0.18450733 0.37698844 0.22657815 -0.024325743 0.42503488 -0.038219463 0.26977316 0.07120697 0.09004896 -0.11367513 0.26504093 0.55942386 0.28683665 0.34456527 0.22476432 0.04212632 0.2123365 0.22905222 0.1982589 0.15023991 0.063660234 0.15081799 0.27854255 0.04580058 -0.15240832 0.35264456 0.043691598 0.16536534 -0.19356123 0.33245787 0.22130464 0.16069864 0.5178661 0.15043904 -0.033654172 0.032267656 0.15946242 -0.19592853 0.26663685 -0.01975921 -0.1251066 0.14134851 0.010078145 0.26391196 -0.15873656 0.28059354 0.03279103 0.08659206 0.08850507 +0.06423589 0.28002062 0.45731875 0.3129279 0.41361487 0.18115169 0.32309863 -0.13107881 0.21524946 0.42102364 0.35797834 -0.033130452 0.31966347 0.32571968 -0.038618058 0.19099647 0.23135066 0.2692841 -0.18644422 0.03130331 0.29347423 0.21999533 0.12297604 0.41888854 -0.061038695 -0.21052039 0.0038388139 -0.32482404 0.07803224 -0.032371737 0.22042076 0.30820394 0.13647117 0.009532485 0.103818804 0.4865756 0.12852632 0.19870381 0.21442926 0.120132565 0.26801398 0.15245312 -0.0040773246 0.20697789 0.135278 0.020435361 0.1326066 -0.26014686 0.3618572 -0.054103773 0.17128836 0.09330641 0.2435389 0.24613231 0.06787569 0.33160824 0.15077013 -0.114019364 -0.030607613 0.18861897 0.12597075 0.08943471 -0.25960207 0.19519961 -0.066505656 0.053852066 0.115520366 0.16506805 -0.015220356 0.22118212 0.023823755 0.2172184 -0.03204623 0.05547188 0.1790876 0.03341857 -0.10333803 0.28302366 0.2802262 0.059729144 -0.016675983 0.2052458 0.031464092 0.033463065 -0.053853013 0.32019177 0.14005084 -0.08784533 -0.12795135 0.369827 0.16747597 0.23045942 0.3364803 0.23276958 0.21056302 0.0710835 0.40312156 0.016117701 0.27303654 0.26244283 0.051080678 0.1324503 -0.16110426 0.2130762 0.007940555 -0.021286111 0.3550122 -0.20264609 0.13052785 0.33936858 0.313464 0.14233546 0.40679884 0.16257712 0.28490558 0.29368973 0.22158918 0.26795503 -0.05106957 0.021662286 0.2954127 0.27434918 0.11966913 0.22047824 0.18372275 -0.016472237 0.18731512 0.16416486 +0.0949396 0.3460457 0.25683904 0.24484208 0.41962734 0.25520685 0.30586022 -0.053349573 0.08085545 0.3042299 0.23255453 0.29153466 0.31873417 0.16095752 0.23799974 0.23422575 0.15634328 0.2533181 -0.18313524 0.0848796 0.14296982 0.17132685 0.13789476 0.2670634 0.03529659 -0.27200046 0.28153622 0.3030695 0.18814851 -0.015910003 0.2696768 0.19532917 0.18773328 0.11099234 0.18238612 0.24004193 0.16732182 0.17782667 0.28576833 0.28142408 0.20519602 0.26712462 0.22416557 0.26695704 0.122257754 0.0054550255 0.34130317 -0.1819855 0.07419322 -0.053602207 -0.086648144 -0.011624673 0.19137146 0.36124584 0.14076467 0.37378606 0.24023587 0.21543531 0.22543333 0.030944444 0.24176463 0.38019666 -0.3614704 0.34323436 0.10009706 -0.090558864 0.16114041 0.17805551 -0.03627377 0.10020172 0.27329728 0.29577896 0.15461431 0.2625852 0.21304664 0.22800381 -0.109386615 0.29075456 0.23845012 0.2060233 0.162783 0.1896407 0.05950654 0.3324222 -0.032478586 0.2504362 0.27468905 -0.010793683 -0.059707854 0.28050327 0.18002222 0.21731573 0.28192383 0.30538052 0.2102243 0.10483433 0.15812035 0.16575113 0.20097339 0.13535684 0.10991173 0.23574011 -0.13894926 0.15878944 0.23604318 -0.019012298 0.3526738 -0.26285324 0.19247222 0.371067 0.20916137 0.23492937 0.28209484 0.1992753 0.1905414 0.25168693 0.32326266 0.24008381 0.004428869 -0.07288975 0.17839769 0.19362016 0.27538013 0.16966957 0.31080103 -0.066068694 0.33248165 0.13412307 +-0.020765955 -0.07081177 0.04687861 -0.08898408 -0.04287752 0.0056039197 0.011823491 -0.033573437 0.040589735 -0.08768804 -0.0063342927 -0.014660366 -0.06425151 0.03825933 -0.04314936 -0.074123 0.023095451 -0.07996826 -0.02640229 -0.028572874 0.004408148 -0.033363335 -0.090319656 0.01871916 0.022811685 -0.024564488 -0.09136193 -0.049818292 -0.014202256 -0.04532911 -0.02648642 -0.09265616 -0.08966108 -0.08584948 -0.06495593 -0.06712047 -0.09966796 -0.0040263473 0.025405593 0.024450643 -0.06267951 0.011319352 0.0020738002 -0.08900121 0.07327679 0.026765224 0.0327028 -0.03444405 0.04777675 0.056101516 -0.07559624 0.011537029 0.039759856 0.028782455 0.059481926 -0.09885639 -0.03140658 -0.047679387 -0.059015315 0.0014212991 0.015784051 -0.017769942 -0.05480861 0.05833909 -0.02194392 -0.08435512 -0.046488553 -0.090375595 -0.05250868 -0.057325542 -0.08994758 -0.057908334 0.015833165 -0.06394807 0.062328387 -0.026215687 -0.08163467 -0.09217533 -0.053678587 -0.090312526 -0.039775994 -0.077886924 -0.023048198 0.0004944088 0.063286476 0.033121627 0.012938253 -0.008916232 -0.030920995 -0.08834482 0.012201009 0.06829075 -0.021467049 0.02882229 0.049194977 -0.031087372 -0.013784857 0.047471836 -0.09999872 0.08078426 -0.047156345 0.06120708 -0.012937271 0.02846948 0.03847395 0.0098574655 0.04264946 -0.064033754 0.05319005 -0.04749407 -0.09294563 0.02774574 -0.03864814 -0.08995193 -0.017792106 -0.07282782 0.046471607 0.044668995 -0.04099872 -0.040494252 0.016263051 -0.066352844 0.053874046 -0.011094844 0.003652665 0.041115023 0.05383729 0.02222764 +0.14541978 0.2779862 0.16570893 0.14462063 0.28592232 0.33697245 0.18461557 -0.04882446 0.08187049 0.083850615 0.49758324 0.33715853 -0.026175268 0.23235603 0.20017233 0.024323637 0.052161228 0.120695 -0.12779665 0.123946674 0.0154367685 0.14212215 0.060099345 0.01359371 -0.036714513 -0.21843599 0.3019487 0.38768473 0.13344492 -0.02048713 0.38803723 0.25490603 0.24571593 0.39684138 0.25237736 0.15988307 0.2942548 0.06596446 0.19579424 0.12639475 0.4313869 0.09242181 0.14474338 0.4592881 0.1387339 0.0069797547 0.2872641 -0.20333734 0.13314268 0.016259316 0.20929228 -0.004453372 0.25851458 0.35559106 0.09480636 0.25808057 0.35194686 0.21941838 0.24503024 0.2017658 0.12775801 0.23670119 -0.3292763 0.29664493 0.19252178 -0.0033694126 0.08600918 -0.046312664 -0.13110985 0.1265098 0.08251613 0.34147838 0.25026056 -0.14003016 0.23265283 0.17957355 -0.010331368 0.23541345 0.2230628 0.064025916 0.07560568 0.1791188 0.08175129 0.33978444 0.045186438 0.10211407 0.16733104 0.05421857 -0.09422907 0.15203626 0.2175219 0.23084864 0.22983073 0.31633458 0.075282365 0.40256283 -0.0915894 0.1284492 0.16333342 0.021104772 0.30363247 0.13009235 -0.054522287 0.09542902 0.1723923 0.0014461692 0.18350801 -0.31364807 0.004248758 0.2740016 -0.0239069 0.29936412 -0.091306515 0.14593674 0.13793215 0.23748958 0.19029838 0.38949752 -0.018738313 -0.17249636 0.43669915 -0.033917215 0.3190568 0.39630282 0.32014444 -0.017490977 0.1478673 0.16047172 +0.034677047 0.050652344 0.011827258 0.06477358 0.0027994725 -0.08162858 -0.084625654 -0.023264399 -0.020574655 0.06653995 -0.06124671 -0.070906535 0.046230316 -0.025696581 -0.03192816 -0.07880569 -0.06517657 -0.053141527 -0.064425886 0.00605402 -0.050503142 0.076168455 -0.050962865 -0.020535218 0.05857764 -0.078358255 -0.032332096 -0.020566417 0.04282892 0.0061331266 0.0067866365 -0.093248084 -0.0016005371 0.003007923 -0.03133584 -0.09172029 0.040504213 -0.07164733 0.06407968 -0.017683763 0.0602355 -0.035001036 -0.03355149 -0.048006155 -0.04515152 -0.098930635 -0.036321867 -0.08582517 0.015613032 -0.09823424 -0.0792555 0.051072985 0.062224325 -0.06828286 -0.06664209 0.03299587 0.0020879337 0.016681874 0.07304433 -0.06053578 -0.008540745 -0.013315865 -0.012969243 0.0413874 -0.071608685 -0.040232357 0.043133076 -0.07606585 0.06323875 0.007240863 -0.029644292 -0.08580913 0.060351875 -0.012561934 -0.03169839 0.010984725 -0.058133785 -0.024444645 0.005978973 -0.050732724 0.028465373 -0.044668406 0.033713847 0.02998941 -0.07630241 -0.08798676 -0.07761201 -0.07386414 -0.073134206 -0.08663005 0.014517185 0.041589808 0.016482892 0.029688584 0.012105669 0.05099108 0.023941273 0.0064321044 0.029821381 -0.052913975 -0.06508249 0.045692746 0.016039299 -0.07274264 0.03332322 0.06891455 0.043924868 0.0056238817 0.042590376 -0.09316424 -0.019601021 0.0108321365 -0.06697963 -0.0779622 -0.07558516 0.0865793 -0.060838368 -4.777918e-05 -0.09579048 -0.04161876 0.04035543 -0.024755264 0.06503231 -0.094333656 0.051293645 0.046566084 -0.07412771 0.003917318 +-0.12550579 0.0046118996 0.035847154 0.042123724 -0.07412457 0.040777832 -0.010737563 -0.114648946 0.047587924 0.05074621 0.019502493 -0.015697459 -0.007483194 -0.17118867 -0.07306667 -0.024485214 -0.026883055 -0.11627306 -0.079330444 -0.11204599 -0.09679732 0.03819829 0.082075655 0.032643463 -0.012522255 -0.112276316 0.024840418 -0.04899119 -0.038538903 -0.07362059 0.028497588 -0.09777382 -0.16439712 0.06692272 -0.035924926 -0.06683892 -0.0009616961 -0.027083792 0.03290462 0.018687883 -0.09025234 -0.06168314 -0.034636255 -0.08615133 -0.11375983 -0.022562925 -0.07070742 -0.1231319 -0.107245065 -0.07770164 -0.08792 -0.052321278 0.009885092 0.07653175 -0.00017232692 -0.003616353 -0.09468464 0.042886242 -0.039980397 -0.12823173 -0.09783213 -0.07693716 -0.11648492 0.0735763 -0.05437276 -0.15562014 -0.055586655 -0.05070079 -0.05453083 0.08804887 0.11726364 0.012341639 0.020656627 -0.0010414462 0.04857887 0.01225652 -0.02919148 0.022005064 -0.044090305 0.018037302 -0.039563734 0.020961285 -0.022796938 -0.018456634 -0.0029484697 0.04812432 -0.05849438 -0.13337477 -0.013462031 0.07566596 -0.062206723 -0.03513313 -0.023949903 -0.04872344 -0.14060798 -0.104904056 -0.023266263 -0.10660003 -0.076491766 0.014034668 0.004344351 -0.08247214 0.039674442 -0.016235169 0.02429374 0.012410558 -0.05571447 -0.037594583 -0.12810777 0.0038504212 0.053916186 -0.037281934 0.055999205 -0.15663922 0.01672284 0.029448276 -0.02638481 -0.02319485 -0.06279176 -0.04308031 -0.118223 -0.081471376 -0.055065285 -0.067053676 -0.041729216 -0.086885944 0.09028857 0.019898279 +-4.095291e-05 -0.092439145 -0.08659252 -0.055108503 0.057324458 0.030755512 0.032828845 0.061955694 -0.02974515 -0.089179955 0.02028003 -0.0009713836 -0.058033288 -0.09682222 0.025045449 -0.0006676724 -0.057060372 -0.023018291 0.0280788 -0.05661139 -0.007251798 0.01749577 0.00074134156 -0.032017007 -0.07601266 -0.10035335 -0.0053586047 -0.09507639 0.026274126 -0.0854384 0.014408614 -0.019539515 -0.011928476 0.0070155384 0.04461547 0.039875656 -0.015349663 -0.087574966 -0.082266994 -0.014069567 0.00287146 -0.008652599 -0.0360167 0.043153506 -0.04639184 0.015437315 -0.04508 -0.035687774 -0.022958247 -0.09255542 -0.11795469 0.019373324 0.036522213 -0.042924352 0.022680365 -0.022536708 0.034666162 -0.021256436 0.013399911 -0.07827123 -0.029786315 -0.09508456 -0.08862553 -0.044444 -0.053539086 -0.09223583 0.047548536 -0.06590932 -0.03182993 0.039859463 -0.05169339 -0.03661759 -0.06224566 -0.04942269 -0.10168282 -0.080115244 -0.03978588 0.0025536504 -0.042358104 -0.021675315 -0.08866591 0.048374526 0.027209701 -0.042087425 0.06814091 -0.070419505 0.030759104 -0.08114505 -0.04672779 0.03248225 0.009911377 -0.08991804 -0.048595704 -0.02443355 -0.097034216 0.015183258 -0.05234727 0.0037457943 -0.04451353 0.052336387 -0.08505443 -0.06498458 0.055349518 0.062845126 -0.035667267 0.014445311 0.0402843 -0.06519292 -0.06700821 -0.04605909 0.036738116 -0.054890472 -0.03689157 -0.029829597 -0.015805867 0.023653775 -0.035591234 0.06404452 -0.012032085 -0.052588645 0.0017476998 0.0688615 0.07260483 -0.03934408 0.023192344 0.0006528368 -0.04216154 0.04712172 +-0.12723328 0.022906044 -0.5198894 -0.07616407 0.050239857 -0.08716409 -0.014180876 -0.036117256 -0.020886937 -0.017225936 -0.5926452 -0.6852836 -0.24571253 0.0017826499 -0.4702797 -0.7057091 -0.66826224 0.083909996 -0.59151375 -0.7587437 -0.6779932 -0.5364921 -0.030617142 -0.4385624 -0.3036045 -0.37321764 -0.06620731 -0.5841631 -0.5558642 -0.73464686 -0.63682103 -0.43889374 -0.5445574 -0.04386489 -0.71147054 -0.48390785 -0.10105459 -0.18897893 0.42093167 -0.4235336 -0.11104679 -0.5496439 -0.39259267 0.0153622 -0.07875102 -0.36817974 -0.58082443 -0.068536334 -0.27064753 0.33617955 0.010858564 -0.5531676 -0.5474654 0.23587601 -0.7244058 -0.5473107 -0.6134465 -0.6511908 -0.78013825 0.050863557 -0.65947795 -0.095985845 -0.090339966 0.0051605995 +0.1378013 0.122852944 0.2585414 -0.090439714 0.06438927 -0.06742472 0.0726306 0.086532354 -0.042606167 -0.034518823 0.27626842 0.009627682 0.19156553 6.271042e-05 0.32880226 0.17949751 0.07789256 0.15865736 0.11423657 0.21040773 0.36770228 0.10076134 0.09298604 0.37775183 0.24647896 0.062965915 -0.013505359 0.24976608 0.21056345 0.24856876 0.16356465 0.16846617 0.17633232 -0.03229159 0.08586948 0.20880193 -0.030581146 -0.068766065 0.184543 0.16482304 -0.04280925 0.24260369 0.2486462 -0.03968135 0.053902768 0.21111214 0.17955291 0.046554465 0.25710365 0.1924279 0.08846152 0.2687502 0.1593267 0.24918662 0.16275732 0.083502404 0.14076571 0.15028282 0.27148783 -0.023265112 0.016160084 -0.059670318 0.021129038 0.031224556 +0.06390019 -0.048405945 -0.16478078 -0.0859455 0.027167564 -0.13462438 -0.010591198 0.012845924 -0.10049078 0.052168544 -0.08269453 -0.15946855 -0.11998792 -0.089811 0.02389506 -0.12332246 0.013771247 0.076021865 -0.035940867 -0.06265381 0.053514116 0.051034912 -0.058161214 -0.090820566 0.0949223 0.048288435 -0.09415154 0.038132448 -0.078367904 -0.060138434 -0.11324274 0.08213649 -0.07553307 -0.00863199 -0.16573162 -0.11798418 -0.029407404 -0.059779387 -0.041376315 0.03644603 0.09360885 -0.12442879 0.0680826 -0.102756985 -0.050937314 -0.024436241 -0.0906986 -0.012087232 -0.09319784 -0.1483801 0.01860638 0.068661354 -4.6454177e-05 -0.008794929 0.012613706 -0.0032201945 -0.048492886 -0.067029804 -0.14190361 -0.093458086 0.004871551 -0.0647037 -0.055594556 0.11170962 +0.15396789 0.027472714 -0.0017498174 -0.055734213 0.033299092 0.05042656 0.030157536 -0.060990088 -0.016077917 0.09937253 -0.038848717 -0.1017535 0.016861038 0.013343558 -0.18202245 -0.0767136 0.018533705 0.12353758 -0.083262905 0.051747702 -0.07341764 0.02966716 -0.044522975 -0.21829855 -0.22602329 -0.049297377 -0.05086617 -0.063275464 -0.03399851 -0.30233958 -0.12737508 -0.23227714 -0.021011267 0.07325666 -0.1309003 -0.050440945 0.018505732 0.084423944 0.072969094 -0.030318864 -0.057348937 -0.13828412 0.028029293 0.09050746 0.1199786 -0.16578421 -0.12463035 -0.058466826 0.044878937 0.13823693 -0.010328928 -0.12511426 -0.05328944 0.19602767 -0.029450154 -0.0046097757 -0.08110054 -0.080122106 -0.037990987 0.11358452 -0.073322944 -0.0675155 -0.019645857 -0.042768802 +0.10629512 0.11250462 0.13824426 -0.034793325 -0.032994393 0.037336025 -0.08224394 -0.06319637 0.056691367 -0.10607124 0.13968375 -0.013313045 -0.050691973 -0.043049242 0.23835708 0.062139824 -0.09019839 0.042615343 0.20113344 -0.018463103 0.29043555 0.08207573 -0.032100804 0.06968219 0.24423341 0.14216055 0.027670331 0.21842134 0.07510274 0.16326417 -0.029983616 0.13561335 0.14307648 -0.050964847 0.08098722 0.11772003 0.1486323 -0.12238753 0.24251921 -0.048578497 0.06050625 0.22749963 0.123371765 0.02264692 -0.053617574 0.2071529 0.017992947 0.011444272 -0.12843455 0.19617121 0.15408325 0.063326694 -0.0051825033 0.10204897 -0.07789348 0.039804224 0.07363462 -0.06975813 0.18922949 -0.0859624 -0.13041317 -0.08428833 -0.08494811 0.032007825 +0.15629293 0.10856876 -0.09261194 0.02568013 -0.0087697515 0.044345297 -0.027868155 -0.019975936 -0.10056303 0.08360998 -0.057456248 -0.098879054 -0.015912602 -0.08470117 -0.15280631 -0.034596898 -0.011011613 0.1682435 -0.054629255 -0.051382728 -0.15453278 -0.04960336 0.09547904 -0.080682874 -0.25830734 -0.16788894 -0.047719773 0.110165395 -0.111557044 -0.30155343 -0.15247191 -0.09943273 -0.08412816 0.078880355 -0.048487008 -0.06705916 0.021336108 -0.0033453607 0.12371454 -0.042821847 -0.06522829 -0.035187103 0.0058604116 0.018116254 -0.050113145 -0.16087586 0.021591255 -0.07258315 -0.14411978 0.21412958 0.09590355 -0.07880258 -0.0585794 0.14441141 -0.05573762 -0.100653246 -0.042652134 0.033866454 -0.02584011 -0.12904657 -0.15093586 0.080270685 0.04843231 0.073897064 +-0.040848058 -0.05288426 0.013745429 0.022631878 0.06382816 0.109882176 -0.08409434 -0.09720433 -0.10914445 0.06806869 0.03909288 0.05776455 0.025479252 0.08531338 -0.029353429 -0.051393367 0.009177119 -0.11986541 -0.15389019 -0.17225794 -0.009853139 -0.08800717 -0.0131800035 -0.1267224 0.08994934 -0.1533652 0.07424761 0.11217092 -0.062256027 -0.016108248 -0.15469715 -0.11644598 -0.1622394 -0.03206292 -0.07703742 0.112879835 -0.05174972 -0.07601947 -0.14874355 -0.010562108 0.018406054 0.058638953 -0.15001546 -0.005663762 0.09544643 0.016261801 -0.06505369 -0.0946928 0.09578762 0.07448887 -0.062321167 -0.0421621 -0.05903367 -0.113712 0.056219023 -0.10890986 -0.063604705 -0.18694697 -0.07151637 0.060187485 -0.118444055 -0.1317313 0.10009574 0.034615587 +0.091859534 0.14645524 -0.22358046 -0.05078967 0.037390642 0.11072238 -0.0017686903 0.09405925 -0.029295495 0.024427183 0.06084175 -0.27393314 0.15749662 0.011995465 -0.106458195 -0.11267011 0.0034312967 0.033157915 0.09528558 -0.18256459 -0.17156132 0.07136703 0.10587553 0.22043909 0.18438308 -0.006965694 0.1018732 -0.069956824 -0.16953857 -0.3803009 -0.024495846 -0.009186688 -0.35546634 -0.05332616 -0.21775137 -0.38805252 -0.029313708 0.2572503 0.050111253 -0.22150567 0.33299664 -0.06360325 0.13790178 0.09445717 0.08552013 -0.10025135 -0.020017087 -0.0053512836 0.035870142 0.23599976 0.46457222 -0.046660166 -0.08054533 0.06934421 -0.36162782 -0.3005417 0.00643138 0.060076516 -0.168331 -0.12441894 -0.09569953 0.036763173 -0.10078311 0.02021307 +0.11835386 0.14491357 0.21494724 -0.073896006 0.056995247 0.07480573 0.027708665 -0.1013044 -0.014569499 0.17219615 0.25483137 0.14064069 0.04630185 -0.058010574 0.33001414 0.3776342 0.13949786 0.18880484 0.16543025 0.2607913 0.3602643 -0.05489732 0.11131202 0.3580631 0.27068877 0.06964937 0.038062464 0.26836294 0.23803905 0.40844432 0.26496 0.15002625 0.15946051 0.13634866 0.1826052 0.30208656 0.1644664 0.04788351 0.2270615 0.15327214 -0.0648989 0.4173686 0.28432605 -0.007784095 0.05091869 0.251695 0.104469426 -0.025101176 0.11608391 0.09425334 -0.020179348 0.3366665 0.16756283 0.24383867 0.30401793 0.25647983 0.19526371 0.24140926 0.3204879 0.03565393 0.17121439 -0.026630128 0.05787588 -0.00060401845 +0.15759453 0.114996046 0.1393906 0.040394608 -0.05293411 -0.0070569143 -0.093205586 -0.120698385 0.013008318 0.066545166 0.21309517 0.032085314 -0.0024144722 -0.1411903 0.36225182 0.21887136 -0.069148876 0.07789866 0.21575126 0.084371135 0.29632846 0.022665245 -0.049658358 0.19891143 0.27957082 0.15589218 -0.04531663 0.13695186 0.02079385 0.28659764 0.23158132 0.13252304 0.24552432 0.09571886 0.24494892 0.13475913 0.0226294 0.053979315 0.10331904 0.17346504 -0.061195545 0.33981952 0.10192331 0.037463102 -0.10125801 0.25045514 0.15747991 -0.008713555 0.1366271 0.19407164 0.087705374 0.10512783 0.1245355 0.24343263 0.1649721 0.06154294 0.09008204 0.026219925 0.27247968 0.11719546 0.11840369 0.056824166 0.017373707 0.10018043 +0.520974 0.59964097 0.031219501 0.032520123 0.025338847 -0.121865146 -0.01352736 -0.10892654 -0.0700099 0.19840723 0.060767226 -0.343554 0.4839107 0.07978482 -0.1494974 -0.4358914 -0.45184416 0.16361716 0.12790614 -0.63227665 -0.13850911 -0.11548714 0.061798867 0.3382824 0.5630951 0.25158608 -0.029889492 0.004497678 -0.106172375 -0.7106193 -0.26258215 0.53872955 0.08206982 0.041173898 -0.6073398 0.3374129 0.1267827 0.29143667 0.3268509 0.08830169 0.61188203 0.19090186 0.16641459 -0.10735583 0.08985685 0.079549104 0.10968232 -0.046334468 0.3214813 0.35046473 0.6331912 -0.091849655 -0.16986299 0.24384622 -0.43004617 -0.18335785 -0.25987333 -0.33063456 -0.31992128 -0.10678123 -0.33161026 -0.07196378 0.24237013 0.054740444 +0.22535479 0.043615762 0.03397134 -0.064783596 -0.081724524 -0.07188039 -0.025119694 0.08906968 0.109899156 0.05292809 -0.0080429595 0.034033697 0.19395597 0.096723616 0.3712682 0.07818361 -0.060158323 0.1558181 0.038742818 -0.06901919 0.26340926 0.048637815 0.011880762 0.05225182 0.17577282 0.03445155 -0.08235831 0.18532375 0.10475401 0.1297221 0.08460357 0.030786958 0.13167405 -0.040913556 -0.13796254 0.09512417 -0.06532977 -0.058336448 -0.21801071 -0.004957184 -0.0035523488 0.019674044 0.1630042 0.12683845 -0.060587715 0.016342387 0.12825526 -0.07820336 0.19044252 -0.16002373 0.15333588 -0.027162397 0.053161703 0.17725912 -0.196775 -0.050724853 0.097546354 0.09070096 -0.05950122 0.01630401 -0.1196389 -0.09406375 0.0976926 0.036323573 +-0.020441644 0.1286521 -0.19564946 -0.06674779 0.04516537 0.0031744116 -0.074803635 -0.0033299236 0.042051513 -0.080748804 0.06077783 -0.13149478 0.057544827 0.054189455 -0.20807455 -0.15086114 -0.01464815 0.0937327 -0.088393874 -0.03425429 -0.22138686 0.097449705 0.07149927 -0.15377547 -0.26091546 -0.20024033 0.044755653 0.11913005 0.06858127 -0.11183507 -0.0749588 -0.14916946 -0.18056466 0.10436801 0.030045547 -0.13932016 0.008682389 -0.016025953 0.1306242 -0.0810291 0.10187364 -0.20184515 -0.1520494 0.055097353 0.012994354 -0.34702745 -0.0030117086 0.11077064 -0.23334496 0.059724838 -0.040657476 0.012183917 -0.12874444 0.16320549 -0.020379186 -0.09097882 -0.07880674 0.09140376 -0.14485568 -0.03468689 -0.005760543 -0.07601382 -0.061092917 0.07681074 +0.16198605 0.29782295 0.11903604 0.01858877 -0.044626515 0.13560703 -0.010199719 -0.07274405 -0.003985294 0.055972375 0.042626075 0.00617857 0.18043336 0.03040078 0.29322347 0.076021075 0.017674807 0.1956138 0.03725683 0.061865613 0.1737 -0.021201469 -0.02391103 0.19473787 0.23115587 0.19319035 0.0036499242 0.21989623 0.07894939 0.18364365 -0.017070683 0.09442294 0.0317042 0.0016184946 0.09447496 0.12479152 -0.013917674 -0.029526077 0.33845946 0.029997997 0.047173988 0.018650586 -0.08239488 0.06202808 0.017477367 0.22102328 0.11067462 0.08554116 -0.09336047 0.1986696 0.25576705 0.25471368 -0.08025346 0.23854017 0.035558958 0.10197278 -0.06330687 -0.13455947 0.15033753 0.03944658 -0.069490954 -0.11676038 -0.07825418 -0.036357053 +-0.020233277 0.12534058 -0.0034608068 -0.08127787 0.013291101 -0.055763252 -0.08265841 0.028339798 -0.093119845 -0.032637723 -0.18080176 -0.14752778 -0.06153035 -0.12380307 -0.08617207 -0.019259753 -0.027866399 0.21707992 0.083600536 0.08371484 0.08754881 -0.08778005 -0.098780535 0.078709655 -0.06815992 -0.11780132 -0.010876028 -0.075514734 0.017611623 0.13420926 -0.036785122 -0.014355611 -0.056173768 -0.024935486 -0.12732968 -0.089633815 -0.06388447 -0.08332238 -0.004005737 -0.025489315 0.08155812 0.016690359 0.06858913 0.037871096 -0.055011272 -0.03190099 0.04623043 0.085440986 -0.0011943477 -0.26540923 0.061274793 -0.050945494 -0.018458184 -0.02220264 -0.08005215 -0.11327793 -0.009730724 -0.075478315 -0.016128074 0.05297016 -0.14135574 0.029771242 -0.0031336774 -0.09867254 +0.082267724 0.12093154 0.24794275 -0.055299267 -0.06426893 -0.08077607 -0.13870978 0.110185355 -0.05423723 0.0771895 0.20935918 0.2571899 0.107830666 0.020436268 0.3422747 0.2726444 0.09925024 0.08687271 0.26584587 0.30420345 0.32314903 -0.0013369353 0.00015559938 0.24158737 0.39565074 0.19164862 0.053453848 0.28555104 0.29287052 0.35482588 0.29276973 0.19548845 0.24000475 -0.033635877 0.16420332 0.26325572 0.033725187 0.111054935 0.12568803 0.077912 0.08697327 0.25146103 0.1617412 0.02886609 0.003291996 0.27146035 0.31297007 0.003375652 0.06638983 0.3106423 0.0045001106 0.33906943 0.120600045 0.11266669 0.13744666 0.2720336 0.1280297 0.22319657 0.40207925 -0.035131875 0.21457748 -0.01105677 0.10734544 0.12169862 +0.18471883 0.108881794 0.017564075 -0.059031114 0.034895733 0.03635156 -0.07050447 0.06321408 0.07461406 -0.119729236 0.27101114 0.005293528 0.22949225 -0.052096307 0.20026585 -0.2801693 -0.24632365 0.014229184 -0.06579487 -0.44841483 0.1534557 0.06446321 -0.077407524 0.41672826 0.52833253 0.25493875 0.08743361 0.51826125 0.0724331 0.08953066 0.17568974 0.48131758 0.14559221 -0.075981244 -0.26377276 0.1560799 -0.067383885 0.0062907184 -0.5140818 -0.016806953 0.34188536 0.30458844 -0.008544355 -0.116234705 0.041083243 0.06614002 0.30595767 0.08180928 0.469383 -0.18233453 0.123322025 0.08859349 0.13087763 -0.035405513 -0.13684338 0.10619407 0.1778728 -0.005600022 0.010060035 0.07685673 -0.08762967 0.09759268 -0.09531901 -0.07970455 +0.11910972 0.2913108 -0.06623312 0.06769712 0.0534919 -0.09977751 -0.009552985 0.018449187 -0.023882218 -0.056258515 0.08252767 0.0551117 0.16266306 -0.092028454 0.14371555 -0.021928892 -0.12826425 0.10592764 0.02672347 0.075170115 0.035355646 -0.019958254 -0.09364768 0.020321349 0.27745265 0.066241905 0.04389831 0.17489603 0.063591555 0.18610592 0.0024997948 0.07459402 0.20759214 -0.0741749 0.03313181 0.25639465 0.0720236 -0.076766774 0.013407968 0.11364409 -0.05602076 0.20991829 0.16148083 -0.061022487 0.020235613 0.22421308 0.052322168 -0.09901102 0.092500865 -0.07747288 -0.06368988 0.1573838 0.12449448 0.19818254 0.15011637 8.6818094e-05 0.13284233 0.051307615 0.052395284 0.0992199 -0.09392717 0.045885414 -0.053628057 0.08465074 +0.04980516 -0.03951162 -0.020674622 0.06989612 -0.09956089 0.055184726 -0.11314369 0.054461524 0.10049867 0.081958614 -0.036116146 0.06482925 -0.0097346455 0.0007656599 -0.09903899 -0.17393877 -0.11043378 -0.025918141 -0.16273181 0.056296967 -0.109220035 -0.038873877 0.047616623 -0.15956873 0.0003209846 -0.07164346 -0.11752921 -0.11718417 -0.12537502 0.07161863 -0.041571498 0.051967263 -0.09406404 -0.032326188 -0.19114257 -0.15998033 0.056657493 0.039807808 -0.063727126 -0.12766196 0.1034753 0.0031631321 -0.098258294 -0.08851291 0.099222735 0.13992298 0.013449072 0.026223723 -0.075287454 -0.011041979 -0.07750733 -0.0770286 -0.18056147 0.05931581 -0.09698105 0.051334985 0.057321835 -0.020476205 -0.07906094 -0.12106597 -0.042174734 0.009466071 0.023957914 0.036795847 +0.054164633 0.24429697 0.03644184 0.0042059557 0.023642896 0.07860015 -0.023056414 0.010082111 -0.02555309 -0.064025216 -0.31214148 -0.25914356 0.039716136 -0.009968457 0.23348618 -0.23575523 -0.114866674 -0.115779616 -0.26494998 -0.091781035 0.090200946 -0.07316008 -0.102294944 0.14978452 0.120892815 0.020556238 0.09909995 -0.105875626 0.16833979 0.07514927 0.19142136 -0.2188493 -0.09944053 0.065923996 -0.25679535 -0.16201195 -0.031191958 0.06415345 0.37565055 -0.08396621 0.08977407 -0.044724904 -0.122398704 0.08692069 0.1053716 0.07562312 -0.17556468 0.09453883 -0.17226541 0.0789938 0.27196416 0.07691988 -0.19878459 0.05212466 -0.12913543 -0.02569145 -0.08820654 -0.12570414 -0.1281983 -0.12184917 -0.011284999 -0.116063386 -0.054273188 0.028735952 +0.5237081 0.16883971 0.12259084 -0.0070942477 0.049744852 -0.093658976 -0.11428407 -0.05380737 0.007737089 -0.054560687 -0.20126434 -0.11682025 0.20170791 -0.042728443 -0.11273211 -0.06437525 -0.24203292 0.025432894 -0.20260674 -0.28622863 -0.3786497 -0.07602646 0.104248025 0.35781553 0.3358937 0.034959048 0.09114094 -0.14234872 -0.013022898 -0.32772562 0.0063111847 -0.03067664 -0.07622053 0.07309994 -0.23291409 -0.020492205 0.03163034 0.12379825 0.115516484 0.22084178 0.3188232 -0.15712315 -0.019436225 0.046994332 -0.07835499 0.22796942 0.100174226 -0.012045292 -0.10762212 0.016660485 0.5096392 0.25902748 0.022994379 0.17734411 -0.10460885 0.16112638 -0.15037473 0.22311215 -0.24745925 0.021579323 3.4587705e-05 0.025768604 0.096518196 0.10281033 +0.1030126 0.1093309 0.14590752 0.0024132982 -0.0031385946 0.107869335 0.06255661 -0.09298259 0.097042195 -0.09434036 0.25641876 0.16633642 0.05325643 -0.048584547 0.2508255 0.3117609 0.17730223 0.11521895 0.31597024 0.1967451 0.40860203 0.052551437 -0.048556462 0.24982695 0.18575457 0.20691781 -0.08619209 0.23501728 0.28116748 0.33296788 0.13059887 0.27286562 0.1967397 -0.004141197 0.2923398 0.14814611 -0.053878617 -0.03934907 0.26191202 0.0038061026 0.14625889 0.29861823 0.18463606 -0.0035886473 0.023109417 0.16652909 0.28165594 0.009143127 0.13388304 0.12265673 0.08051241 0.122950286 0.024188774 0.11675344 0.23904316 0.083728805 0.06454031 0.12631908 0.19692242 -0.043284383 0.075770296 -0.07104134 -0.04045651 0.021263845 +-0.06206329 0.11110152 -0.07720491 -0.017565656 -0.031755317 0.058432426 0.09395864 0.016690817 0.09182525 -0.111757405 0.051867943 -0.019448487 0.019125056 -0.12420459 -0.028985279 -0.1953131 0.034684945 -0.01290791 -0.158361 -0.098559335 -0.18044187 -0.00067409815 -0.053563505 -0.006237672 -0.01409948 -0.0029362775 0.039746523 -0.015681695 -0.104658835 0.038102526 -0.058976006 0.061424397 -0.121590145 0.09502551 -0.161757 -0.08773674 -0.03387145 0.047197253 -0.17122144 -0.08109508 -0.04662235 0.029511092 -0.11579408 0.0038979636 -0.05312592 0.04128475 -0.13347216 -0.09054076 0.012290563 0.020250114 -0.07801899 -0.13821584 0.030024063 -0.16545457 -0.09368343 -0.18572368 -0.19234532 -0.002991532 0.027285807 0.04646511 -0.046736527 -0.053498715 -0.0754854 0.07025626 +0.079703756 0.21315393 0.25237685 0.08401435 0.10873539 -0.06990418 -0.10023681 0.037007038 -0.013912855 -0.036879785 0.07423318 0.04884223 0.14983146 0.04782026 0.33526343 0.18102533 0.061067645 0.1649626 0.23966189 0.052397836 0.21462111 -0.05804563 -0.0999112 0.27388853 0.2850436 0.17740123 0.036255784 0.15979914 0.0437921 0.17211951 0.2247902 0.24603623 0.14118566 0.017924 0.07471345 0.20534731 -0.03186023 0.012125353 0.23454623 0.060507204 -0.0075858794 0.32128713 0.13035326 0.038222924 -0.07605768 0.2885286 0.14958102 0.0041881776 0.09773516 0.14689565 0.015316402 0.044299636 0.027018197 0.25897497 0.07458832 0.17879665 -0.057994686 0.18604709 0.18234405 -0.08643574 0.11780951 0.07426081 -0.08963359 0.016042968 +0.03482768 -0.04877349 -0.17190854 0.07068098 -0.010516556 0.112406805 0.06565846 -0.0074740895 -0.09955178 -0.0861785 0.06985262 -0.07934646 -0.07619258 -0.07362824 -0.13247977 -0.13488539 0.05139059 0.07727062 -0.1858854 0.045394175 -0.1778127 0.12608832 -0.0012594741 -0.2889528 -0.19702503 -0.06943198 0.094257645 0.02509725 -0.1426688 -0.26468682 -0.032393523 -0.048070136 -0.022684019 -0.021316934 0.07924387 -0.1861231 -0.08549019 0.11207709 0.067756966 -0.007507787 -0.11366398 -0.061400726 -0.14130224 0.0023604862 0.0005781098 -0.18797077 -0.1476019 0.113903694 -0.18059005 0.14286542 0.015068132 -0.066342965 -0.11702102 0.15661703 0.0109270355 -0.076817684 -0.073913805 -0.005600875 -0.062017728 -0.07686851 -0.13782588 -0.0249736 0.0071113533 0.014256068 +0.28783062 0.29156986 0.044847976 -0.0022228996 -0.022338934 -0.061533846 0.083700985 0.10800079 0.13638592 0.04216577 0.029448345 0.013418156 0.09851437 -0.05277288 0.1861571 -0.100844435 -0.07923676 0.11940402 0.023534786 0.12334147 0.29219905 -0.0073636486 0.122366644 0.20609541 0.33005348 -0.06074578 -0.08387477 0.36750063 -0.03136075 0.08110635 0.08442772 0.4698156 0.22138827 -0.077871636 0.016242804 0.23110288 -0.06087755 -0.2874949 0.0140878195 0.17153057 0.19683678 0.40007108 0.19524163 -0.09927925 0.059219126 0.35842627 0.002342296 0.014362078 0.44419822 -0.20393637 0.53788775 0.12224696 0.05425677 -0.19943425 0.23182674 0.054430347 0.0018112784 0.15689106 0.08468096 -0.101875044 0.027292885 -0.043777857 -0.07323721 0.05319369 +0.20459439 -0.035580102 0.04883236 -0.018117754 -0.049641885 -0.11448763 0.03599298 -0.1254951 0.069294855 -0.03052844 -0.024817647 -0.09040103 0.22489676 -0.008587936 -0.16741875 0.013933508 -0.25287575 0.06820572 0.17145985 -0.21398823 -0.27901208 0.115819044 0.04478165 0.004434518 0.22319248 0.012239549 -0.02462009 -0.25729418 -0.10262675 -0.2842518 -0.10627177 -0.028982509 0.077706695 -0.087844945 -0.24313085 -0.08814091 -0.042190123 0.23014133 0.24880014 0.014519569 0.46283752 -0.09004781 0.053807937 0.06574945 0.0889922 0.018186603 0.031761795 0.005689713 -0.0599909 0.25609565 0.41100568 0.077814125 -0.23103279 0.11095395 -0.27953818 -0.023450151 -0.070123374 -0.01066068 -0.09171211 -0.071235485 -0.42689896 -0.07080224 0.025229469 -0.027046079 +-0.11352209 -0.14644271 0.030486856 -0.07325185 -0.064591244 -0.090964705 -0.09126776 0.07770007 -0.12429133 -0.079227716 -0.06360701 0.05963329 0.08088577 -0.10882388 -0.14091331 -0.052719966 -0.16552936 0.06871853 -0.024756607 0.051423706 -0.12975569 -0.15340379 -0.03346181 -0.12332553 0.118418366 0.044443753 -0.036220238 -0.14635304 -0.051035073 0.07862214 -0.1594591 -0.044985246 -0.044488207 0.017548382 -0.16007286 0.0877575 -0.114156924 -0.061517216 -0.09711964 0.055124566 0.08857658 -0.13929982 0.056799594 -0.040348813 0.10819212 0.08760201 -0.10173234 0.11845325 0.034056332 0.002165543 -0.08313206 -0.096684195 -0.014548383 0.026085328 0.0025616998 -0.0668623 -0.071412764 0.03764707 -0.029272737 0.05873078 -0.057662413 0.049962297 -0.056811333 0.07849261 +0.21730898 0.2020778 0.123282075 0.024591586 -0.09860217 0.011657721 0.076910436 -0.053993825 -0.09102177 0.0777202 0.10043123 0.09708253 0.123402655 -0.10603686 0.3355538 0.027166639 -0.119143374 0.16963233 0.14901288 0.0025405842 0.222115 -0.028775109 0.006180673 0.24871638 0.26285625 0.057397056 -0.07186053 0.19534416 0.082720995 0.104962215 0.03738035 0.16415465 0.15144852 0.059286132 0.12994185 0.16285947 0.02562871 0.009724737 0.3614015 0.009148241 0.11566976 0.13930973 0.0783673 -0.078807436 -0.10784437 0.29929662 0.22810988 0.041243587 0.14338613 0.13349883 0.12328762 0.1485585 -0.052017473 0.12282907 0.010245827 -0.039959814 0.03226006 0.13931087 0.070638195 0.026276698 0.09742858 0.014402947 -0.085794 -0.10075329 +0.06956389 0.0037160083 -0.05528899 0.13197279 -0.097877964 0.10306828 0.044267707 -0.0013003278 0.03505696 0.0018697927 0.03380905 -0.065468974 -0.077990055 -0.034425747 0.09347054 -0.0046163434 -0.09389615 0.07687734 -0.1288893 0.030446937 0.113255136 0.047210373 -0.035957694 -0.054828867 -0.13042133 -0.00026837387 0.06204687 -0.055171046 -0.032226875 -0.08783506 0.017895155 -0.038042665 -0.02269642 0.0012175784 -0.060920462 0.09121147 -0.10291942 0.10324893 -0.22679543 -0.109592944 0.14111452 -0.06428377 0.096342586 -0.091976866 0.0037707041 0.07230816 -0.08556388 -0.10701327 0.13365738 -0.12723014 0.06346541 -0.0535626 -0.14914016 -0.07930355 0.04252224 0.018383488 0.03684307 -0.049166646 0.16964889 -0.10466766 -0.08147278 0.054045707 -0.09219066 -0.09852995 +0.17004548 0.16563368 0.1497223 -0.029192008 0.121049955 0.009293286 -0.058750633 -0.101088054 0.002546997 -0.10559251 0.09935291 0.06381162 0.06214938 -0.00086858985 0.2500903 0.23355727 -0.01183984 0.14707682 0.28937548 0.034774154 0.36795512 0.017282726 -0.06271944 0.18199927 0.20840989 0.08538777 0.123738565 0.028816212 0.16678233 0.33197367 0.23343477 0.2106288 0.20913233 0.13852835 0.16671738 0.21682994 0.10165302 -0.09972167 0.29291067 0.07754789 0.085743256 0.29267302 0.17959394 0.14447959 -0.08689463 0.24356933 0.19581221 -0.082665406 0.23449413 0.12166938 0.049716145 0.25899404 0.12470804 0.21271357 0.0924148 0.09146234 0.13676567 0.054578528 0.30180743 0.051753912 0.08365558 -0.112204365 -0.106755376 -0.030200055 +0.042479694 0.13256007 -0.08633078 -0.12399639 -0.05093786 -0.049632203 -0.04536554 -0.020431325 0.00588713 0.041544516 0.036054295 -0.0852016 -0.1294363 -0.08014586 -0.2296124 -0.026385702 0.023046201 0.131335 -0.13280357 -0.101241484 -0.15460956 -0.032869156 0.034629356 -0.22037746 -0.16924004 -0.11989324 -0.08316225 0.04380729 -0.037425756 -0.24711958 -0.074365616 -0.094938524 -0.1706681 -0.10189891 -0.07219588 -0.10539137 -0.11261494 0.08205239 0.24926344 0.052908313 0.037326146 -0.089808196 -0.11544931 0.05259774 0.10347795 -0.13493887 -0.07389637 -0.10525736 -0.06583611 0.2486559 -0.108139604 -0.16252054 -0.08913273 0.012136418 0.04130011 -0.035961274 -0.08299628 0.07772742 -0.16195449 0.06719529 -0.082918115 0.06428361 0.03855723 0.086648285 +0.25398132 0.008260143 0.15142672 0.027022546 -0.04573616 -0.08531553 -0.1017991 -0.05920992 0.046825904 -0.04789848 -0.022505285 -0.15165114 0.21711017 0.0024269647 -0.07189007 -0.26918167 -0.043765172 0.11352691 -0.08602305 -0.13596453 0.0039643073 -0.095904335 -0.043372717 -0.26869184 0.29009065 -0.03945541 0.08232044 0.075800635 0.04820068 -0.2057322 0.29165286 0.061218243 -0.122589335 0.0117345145 -0.32955468 -0.21252888 0.009608937 -0.007759408 0.08739287 -0.45483842 0.13343348 -0.046456452 0.26288265 -0.08011442 -0.065363236 -0.045581967 -0.20569602 0.08807132 -0.08680548 0.09825351 0.25457087 0.10980122 -0.15875827 0.06567453 -0.19635054 0.06610827 -0.17079805 -0.24736166 -0.18937673 0.0316336 -0.07324038 0.037343055 0.11476621 0.041128613 +-0.5746274 -0.09257152 0.912285 -0.6090957 0.9643285 -0.1026967 0.6721287 -0.6588699 -0.5802004 0.5310756 -0.543982 0.8772337 -0.61903805 -0.3024232 -0.6671719 -0.41806293 -0.46223813 -0.054980833 0.03122825 0.2547884 -0.59486645 -0.061039817 -0.52836484 0.95376176 -0.3981046 0.07674091 -0.13550112 -0.5619845 -0.35677204 -0.6301644 1.0061067 0.7413826 +-0.31724322 0.0017957278 0.37811512 -0.005011656 0.63329345 -0.118556194 0.8208675 -0.4984193 -0.19168231 1.4298196 -0.008222425 0.39445338 -0.12938818 0.010719266 -0.45608497 -0.02108335 0.07785899 -0.110035166 0.12688221 0.12037774 -0.44246748 0.15095623 -0.15013023 0.5887744 -0.11484556 -0.058196153 0.14892133 -0.06916103 -0.09514606 -0.117880985 0.42844328 0.6533205 +0.19357188 -0.012248634 -0.5285921 0.10025003 -0.6583721 -0.09696889 -0.7027063 0.55014205 0.12758593 -1.6589307 0.0679601 -0.5856124 -0.02406927 0.031731416 0.51928836 0.10078484 0.111478105 -0.19389181 -0.17720659 -0.32946518 0.37413028 0.13153392 0.07136435 -0.52441144 0.0047997595 -0.09315095 0.14301816 -0.010904155 -0.1211448 0.20019644 -0.6107775 -0.7599318 +0.7856079 -0.5583929 diff --git a/src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp b/src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp new file mode 100644 index 0000000000..5bcdb0aaea --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp @@ -0,0 +1,80 @@ +#include "pgd_attack.h" +#include +#include "read_net.h" + +PGD_Linf_Rand::PGD_Linf_Rand(CustomDNN model, torch::Device device) + : model(std::move(model)), device(device), + optimizer(this->model->parameters(), torch::optim::SGDOptions(0.01).momentum(0.9)) {} + +torch::Tensor PGD_Linf_Rand::pgd_linf_rand(const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter) { + torch::Tensor delta = torch::zeros_like(X).uniform_(-epsilon, epsilon).to(device); + delta.set_requires_grad(true); + + torch::Tensor target = torch::tensor({y}, torch::kInt64).to(device); + + for (int i = 0; i < num_iter; ++i) { + // Clear gradients + optimizer.zero_grad(); + if (delta.grad().defined()) { + delta.grad().zero_(); + } + + torch::Tensor pred = model->forward(X + delta); + torch::Tensor loss = torch::nn::functional::cross_entropy(pred, target); + loss.backward(); + + // Update delta + delta = (delta + alpha * delta.grad().sign()).clamp(-epsilon, epsilon).detach(); + delta.set_requires_grad(true); + } + + return delta; +} + +bool PGD_Linf_Rand::display_adversarial_example(const torch::Tensor& input, int target) { + std::cout<<"starting the attack"<< std::endl; + + auto x = input.to(device); + + float epsilon = 0.1; + float alpha = 0.01; + int num_iter = 40; + torch::Tensor adversarial_delta = pgd_linf_rand(x, target, epsilon, alpha, num_iter); + torch::Tensor adversarial_x = x + adversarial_delta; + + // Check if the model is fooled + auto original_pred = model->forward(x).argmax(1); + auto adversarial_pred = model->forward(adversarial_x).argmax(1); + bool is_fooled = original_pred.item() != adversarial_pred.item(); + + std::cout << "Original Prediction: " << original_pred.item() << "\n"; + std::cout << "Adversarial Prediction: " << adversarial_pred.item() << "\n"; + std::cout << "Model fooled: " << (is_fooled ? "Yes" : "No") << std::endl; + + return is_fooled; +} + +bool main(std::string filename) { + // filepath "/home/maya-swisa/Documents/Lab/PGD_Linf_Rand/example_dnn_model.nnet"; + std::vector layers; + std::vector activations; + std::vector>> weights; + std::vector> biases; + + load_nnet(filename, layers, activations, weights, biases); + + CustomDNN model(layers, activations, weights, biases); + + torch::Device device(torch::kCPU); + + torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); + int target = 0; + + PGD_Linf_Rand pgd_attack(model, device); + + // Display adversarial example + return display_adversarial_example(input, target); + +} + + diff --git a/src/engine/attack/PGD_Linf_Rand/pgd_attack.h b/src/engine/attack/PGD_Linf_Rand/pgd_attack.h new file mode 100644 index 0000000000..8582fe5d88 --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/pgd_attack.h @@ -0,0 +1,20 @@ +#ifndef PGD_ATTACK_H +#define PGD_ATTACK_H + +#include +#include "read_net.h" + +class PGD_Linf_Rand { +public: + PGD_Linf_Rand(CustomDNN model, torch::Device device); + bool main(std::string filename); + +private: + CustomDNN model; + torch::Device device; + torch::optim::SGD optimizer; + torch::Tensor pgd_linf_rand(const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter); + bool display_adversarial_example(const torch::Tensor& input, int target); +}; + +#endif // PGD_ATTACK_H diff --git a/src/engine/attack/PGD_Linf_Rand/read_net.cpp b/src/engine/attack/PGD_Linf_Rand/read_net.cpp new file mode 100644 index 0000000000..e139ddad2c --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/read_net.cpp @@ -0,0 +1,114 @@ +#include "read_net.h" +#include +#include +#include +#include +#include + +std::vector split_line(const std::string& line) { + std::istringstream input_stream(line); + std::vector tokens; + std::string token; + while (input_stream >> token) { + tokens.push_back(token); + } + return tokens; +} + +void load_nnet(const std::string& filename, std::vector& layers, std::vector& activations, + std::vector>>& weights, std::vector>& biases) { + std::ifstream input_file(filename); + if (!input_file) { + std::cerr << "Could not open file: " << filename << std::endl; + exit(1); + } + + std::string line; + std::getline(input_file, line); + int num_layers = std::stoi(line); + + std::getline(input_file, line); + std::vector layer_sizes_str = split_line(line); + for (const auto& size_str : layer_sizes_str) { + layers.push_back(std::stoi(size_str)); + } + + std::getline(input_file, line); + activations = split_line(line); + + // Skip input mins, max, means, ranges + for (int i = 0; i < 6; ++i) { + std::getline(input_file, line); + } + + for (int i = 0; i < num_layers; ++i) { + std::vector> layer_weights; + int weight_next_layer = layers[i + 1]; + int weight_cur_layer = layers[i]; + + for (int j = 0; j < weight_next_layer; ++j) { + std::getline(input_file, line); + std::vector weights_next_str = split_line(line); + if (weights_next_str.size() != weight_cur_layer) { + std::cerr << "Error: Expected " << weight_cur_layer << " columns but got " << weights_next_str.size() << std::endl; + exit(1); + } + std::vector weights_next; + for (const auto& weight_str : weights_next_str) { + weights_next.push_back(std::stof(weight_str)); + } + layer_weights.push_back(weights_next); + } + weights.push_back(layer_weights); + + std::getline(input_file, line); + std::vector biases_next_str = split_line(line); + if (biases_next_str.size() != weight_next_layer) { + std::cerr << "Error: Expected " << weight_next_layer << " biases but got " << biases_next_str.size() << std::endl; + exit(1); + } + std::vector layer_biases; + for (const auto& bias_str : biases_next_str) { + layer_biases.push_back(std::stof(bias_str)); + } + biases.push_back(layer_biases); + } + input_file.close(); + std::cout<<"done loading the network!"<< std::endl; +} + +CustomDNN::CustomDNN(const std::vector& layer_sizes, const std::vector& activation_functions, + const std::vector>>& weights, const std::vector>& biases) { + for (size_t i = 0; i < layer_sizes.size() - 1; ++i) { + auto layer = register_module("fc" + std::to_string(i), torch::nn::Linear(layer_sizes[i], layer_sizes[i+1])); + linear_layers.push_back(layer); + activations.push_back(activation_functions[i]); + + std::vector flattened_weights; + for (const auto& row : weights[i]) { + flattened_weights.insert(flattened_weights.end(), row.begin(), row.end()); + } + + torch::Tensor weight_tensor = torch::tensor(flattened_weights, torch::kFloat).view({layer_sizes[i+1], layer_sizes[i]}); + torch::Tensor bias_tensor = torch::tensor(biases[i], torch::kFloat); + + layer->weight.data().copy_(weight_tensor); + layer->bias.data().copy_(bias_tensor); + } +} + +torch::Tensor CustomDNN::forward(torch::Tensor x) { + for (size_t i = 0; i < linear_layers.size(); ++i) { + x = linear_layers[i]->forward(x); + if (activations[i] == "ReLU") { + x = torch::relu(x); + } else if (activations[i] == "Sigmoid") { + x = torch::sigmoid(x); + } else if (activations[i] == "Tanh") { + x = torch::tanh(x); + } else if (activations[i] == "Softmax") { + x = torch::softmax(x, 1); + } + } + return x; +} diff --git a/src/engine/attack/PGD_Linf_Rand/read_net.h b/src/engine/attack/PGD_Linf_Rand/read_net.h new file mode 100644 index 0000000000..362106b922 --- /dev/null +++ b/src/engine/attack/PGD_Linf_Rand/read_net.h @@ -0,0 +1,24 @@ +#ifndef READ_NET_H +#define READ_NET_H + +#include +#include +#include + +std::vector split_line(const std::string& line); + +void load_nnet(const std::string& filename, std::vector& layers, std::vector& activations, + std::vector>>& weights, std::vector>& biases); + +struct CustomDNN : torch::nn::Module { + std::vector linear_layers; + std::vector activations; + + CustomDNN(const std::vector& layer_sizes, const std::vector& activation_functions, + const std::vector>>& weights, const std::vector>& biases); + + torch::Tensor forward(torch::Tensor x); +}; +TORCH_MODULE(CustomDNN); + +#endif // READ_NET_H From f7f4fdce9fe0b77c1371b4541570065473853578 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 18 Jun 2024 20:31:58 +0300 Subject: [PATCH 02/69] changes for attack --- .../.vscode => .vscode}/c_cpp_properties.json | 0 .../.vscode => .vscode}/settings.json | 51 ++-- CMakeLists.txt | 18 ++ src/engine/CMakeLists.txt | 3 + src/engine/Preprocessor.cpp | 17 +- src/engine/attack/CustomDNN.cpp | 102 ++++++++ src/engine/attack/CustomDNN.h | 36 +++ src/engine/attack/PGD.cpp | 53 ++++ src/engine/attack/PGD.h | 19 ++ .../attack/PGD_Linf_Rand/.vscode/launch.json | 40 --- .../attack/PGD_Linf_Rand/.vscode/tasks.json | 22 -- .../attack/PGD_Linf_Rand/CMakeLists.txt | 37 --- src/engine/attack/PGD_Linf_Rand/build_net.py | 146 ----------- .../PGD_Linf_Rand/example_dnn_model.nnet | 239 ------------------ .../attack/PGD_Linf_Rand/pgd_attack.cpp | 80 ------ src/engine/attack/PGD_Linf_Rand/pgd_attack.h | 20 -- src/engine/attack/PGD_Linf_Rand/read_net.cpp | 114 --------- src/engine/attack/PGD_Linf_Rand/read_net.h | 24 -- 18 files changed, 279 insertions(+), 742 deletions(-) rename {src/engine/attack/PGD_Linf_Rand/.vscode => .vscode}/c_cpp_properties.json (100%) rename {src/engine/attack/PGD_Linf_Rand/.vscode => .vscode}/settings.json (78%) create mode 100644 src/engine/attack/CustomDNN.cpp create mode 100644 src/engine/attack/CustomDNN.h create mode 100644 src/engine/attack/PGD.cpp create mode 100644 src/engine/attack/PGD.h delete mode 100644 src/engine/attack/PGD_Linf_Rand/.vscode/launch.json delete mode 100644 src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json delete mode 100644 src/engine/attack/PGD_Linf_Rand/CMakeLists.txt delete mode 100644 src/engine/attack/PGD_Linf_Rand/build_net.py delete mode 100644 src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet delete mode 100644 src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp delete mode 100644 src/engine/attack/PGD_Linf_Rand/pgd_attack.h delete mode 100644 src/engine/attack/PGD_Linf_Rand/read_net.cpp delete mode 100644 src/engine/attack/PGD_Linf_Rand/read_net.h diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json similarity index 100% rename from src/engine/attack/PGD_Linf_Rand/.vscode/c_cpp_properties.json rename to .vscode/c_cpp_properties.json diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/settings.json b/.vscode/settings.json similarity index 78% rename from src/engine/attack/PGD_Linf_Rand/.vscode/settings.json rename to .vscode/settings.json index 63efc6aacf..1b10435680 100644 --- a/src/engine/attack/PGD_Linf_Rand/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,32 +1,38 @@ { - "python.venvPath": "/home/maya-swisa/Documents/PGD_Linf_Rand/.venv", - "C_Cpp.errorSquiggles": "disabled", "files.associations": { + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "csetjmp": "cpp", + "csignal": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "*.ipp": "cpp", + "any": "cpp", "array": "cpp", "atomic": "cpp", + "strstream": "cpp", + "barrier": "cpp", "bit": "cpp", "*.tcc": "cpp", "bitset": "cpp", - "cctype": "cpp", + "cfenv": "cpp", "charconv": "cpp", "chrono": "cpp", "cinttypes": "cpp", - "clocale": "cpp", - "cmath": "cpp", + "codecvt": "cpp", "compare": "cpp", "complex": "cpp", "concepts": "cpp", "condition_variable": "cpp", - "csignal": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", + "coroutine": "cpp", "cstdint": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", "deque": "cpp", "forward_list": "cpp", "list": "cpp", @@ -37,6 +43,7 @@ "unordered_set": "cpp", "vector": "cpp", "exception": "cpp", + "expected": "cpp", "algorithm": "cpp", "functional": "cpp", "iterator": "cpp", @@ -47,11 +54,14 @@ "random": "cpp", "ratio": "cpp", "regex": "cpp", + "source_location": "cpp", "string_view": "cpp", "system_error": "cpp", "tuple": "cpp", "type_traits": "cpp", "utility": "cpp", + "rope": "cpp", + "slist": "cpp", "format": "cpp", "fstream": "cpp", "future": "cpp", @@ -60,23 +70,30 @@ "iosfwd": "cpp", "iostream": "cpp", "istream": "cpp", + "latch": "cpp", "limits": "cpp", "mutex": "cpp", "new": "cpp", "numbers": "cpp", "ostream": "cpp", + "ranges": "cpp", + "scoped_allocator": "cpp", "semaphore": "cpp", "shared_mutex": "cpp", "span": "cpp", + "spanstream": "cpp", "sstream": "cpp", + "stacktrace": "cpp", "stdexcept": "cpp", + "stdfloat": "cpp", "stop_token": "cpp", "streambuf": "cpp", + "syncstream": "cpp", "thread": "cpp", "typeindex": "cpp", "typeinfo": "cpp", "valarray": "cpp", "variant": "cpp" - } -} - + }, + "C_Cpp.errorSquiggles": "disabled" +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 32ce965f35..1eb14ad2ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,17 @@ add_definitions("-DMARABOU_VERSION=\"${MARABOU_VERSION}\"") set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) +if (NOT MSVC) + if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(COMPILE_FLAGS -Wall -Wextra -Werror -MMD -Qunused-arguments -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-dangling-reference) + elseif (CMAKE_BUILD_TYPE MATCHES "Release") + set(COMPILE_FLAGS -Wall -Wno-dangling-reference) + else() + set(COMPILE_FLAGS -Wall -Wextra -Werror -MMD -Wno-dangling-reference) #-Wno-deprecated + endif() + set(RELEASE_FLAGS ${COMPILE_FLAGS} -O3) #-Wno-deprecated +endif() + ################## ## User options ## ################## @@ -327,6 +338,13 @@ target_compile_options(${MARABOU_LIB} PRIVATE ${RELEASE_FLAGS}) target_link_libraries(${MARABOU_EXE} ${MARABOU_LIB}) target_include_directories(${MARABOU_EXE} PRIVATE ${LIBS_INCLUDES}) +# libtorch +list(APPEND CMAKE_PREFIX_PATH "~/libtorch/libtorch/share/cmake/Torch") +find_package(Torch REQUIRED) +target_link_libraries(${MARABOU_LIB} "${TORCH_LIBRARIES}") +target_include_directories(${MARABOU_LIB} PRIVATE "${TORCH_INCLUDE_DIRS}") +set(CMAKE_PREFIX_PATH "~/libtorch/libtorch") + ###################### ## Build Python API ## ###################### diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index 707c6e1759..9319ec23e5 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -1,6 +1,9 @@ file(GLOB SRCS "*.cpp") file(GLOB HEADERS "*.h") +file(GLOB ATTACK_SRCS "attack/*.cpp") +file(GLOB ATTACK_HEADERS "attack/*.h") + target_sources(${MARABOU_LIB} PRIVATE ${SRCS}) target_include_directories(${MARABOU_LIB} PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}") diff --git a/src/engine/Preprocessor.cpp b/src/engine/Preprocessor.cpp index 5e807e4c4a..91e1490329 100644 --- a/src/engine/Preprocessor.cpp +++ b/src/engine/Preprocessor.cpp @@ -13,6 +13,12 @@ **/ +#include + +#ifdef LOG +#undef LOG +#endif + #include "Preprocessor.h" #include "Debug.h" @@ -26,8 +32,8 @@ #include "PiecewiseLinearFunctionType.h" #include "Statistics.h" #include "Tightening.h" -#include "attack/PGD_Linf_Rand/" - +#include "attack/CustomDNN.h" +#include "attack/PGD.h" #ifdef _WIN32 #undef INFINITE #endif @@ -175,7 +181,12 @@ std::unique_ptr Preprocessor::preprocess( const InputQuery &query, ASSERT( _preprocessed->getLowerBounds().size() == _preprocessed->getNumberOfVariables() ); ASSERT( _preprocessed->getUpperBounds().size() == _preprocessed->getNumberOfVariables() ); - // run the attack + attack::CustomDNNImpl network = attack::CustomDNNImpl(*(_preprocessed->_networkLevelReasoner)); + torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); + int target = 0; + torch::Device device(torch::kCPU); + attack::displayAdversarialExample(network, input, target, device); + String networkFilePath = Options::get()->getString( Options::INPUT_FILE_PATH ); diff --git a/src/engine/attack/CustomDNN.cpp b/src/engine/attack/CustomDNN.cpp new file mode 100644 index 0000000000..689ad56a46 --- /dev/null +++ b/src/engine/attack/CustomDNN.cpp @@ -0,0 +1,102 @@ + + +#include "CustomDNN.h" +#include "NetworkLevelReasoner.h" + +namespace attack{ +CustomDNNImpl::CustomDNNImpl(const std::vector& layerSizes, const std::vector& activationFunctions, + const std::vector>>& weights, const std::vector>& biases){ + for (size_t i = 0; i < layerSizes.size() - 1; ++i) { + auto layer = register_module("fc" + std::to_string(i), torch::nn::Linear(layerSizes[i], layerSizes[i+1])); + linearLayers.push_back(layer); + activations.push_back(activationFunctions[i]); + + std::vector flattened_weights; + for (const auto& row : weights[i]) { + flattened_weights.insert(flattened_weights.end(), row.begin(), row.end()); + } + + torch::Tensor weightTensor = torch::tensor(flattened_weights, torch::kFloat).view({layerSizes[i+1], layerSizes[i]}); + torch::Tensor biasTensor = torch::tensor(biases[i], torch::kFloat); + + layer->weight.data().copy_(weightTensor); + layer->bias.data().copy_(biasTensor); + } +} + + +CustomDNNImpl::CustomDNNImpl(NLR::NetworkLevelReasoner& nlr){ + + std::vector layerSizes; + std::vector activationFunctions; + std::vector>> weights; + std::vector> biases; + + int numLayers = nlr.getNumberOfLayers(); + for (unsigned i = 0; i < numLayers; ++i){ + const NLR::Layer* layer = nlr.getLayer(i); + layerSizes.push_back(layer->getSize()); + + switch (layer->getLayerType()){ + case NLR::Layer::RELU: + activationFunctions.push_back("relu"); + break; + case NLR::Layer::SIGMOID: + activationFunctions.push_back("sigmoid"); + break; + default: + activationFunctions.push_back("none"); + break; + } + + if (i < numLayers -1){ + const NLR::Layer* nextLayer = nlr.getLayer(i+1); + std::vector> layerWeights(nextLayer->getSize(), std::vector(layer->getSize())); + std::vector layerBiases(layer->getSize()); + + for (unsigned j=0; jgetSize(); j++){ + for (unsigned k=0; k< layer->getSize(); ++k){ + layerWeights[j][k] = static_cast(nlr.getLayer(i)->getWeight(i, k, j)); + } + } + for (unsigned j = 0; j < nextLayer->getSize(); ++j) { + layerBiases[j] = static_cast(layer->getBias(j)); + } + + weights.push_back(layerWeights); + biases.push_back(layerBiases); + } + } + + for (size_t i = 0; i < layerSizes.size() - 1; ++i) { + linearLayers.push_back(register_module("linear" + std::to_string(i), torch::nn::Linear(layerSizes[i], layerSizes[i+1]))); + std::vector flattenedWeights; + for (const auto& row : weights[i]) { + flattenedWeights.insert(flattenedWeights.end(), row.begin(), row.end()); + } + + torch::Tensor weightTensor = torch::tensor(flattenedWeights, torch::kFloat).view({layerSizes[i+1], layerSizes[i]}); + torch::Tensor biasTensor = torch::tensor(biases[i], torch::kFloat); + auto& linear = linearLayers.back(); + linear->weight.data().copy_(weightTensor); + linear->bias.data().copy_(biasTensor); + } + +} +torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { + for (size_t i = 0; i < linearLayers.size(); ++i) { + x = linearLayers[i]->forward(x); + if (activations[i] == "ReLU") { + x = torch::relu(x); + } else if (activations[i] == "Sigmoid") { + x = torch::sigmoid(x); + } else if (activations[i] == "Tanh") { + x = torch::tanh(x); + } else if (activations[i] == "Softmax") { + x = torch::softmax(x, 1); + } + } + return x; +} + +} \ No newline at end of file diff --git a/src/engine/attack/CustomDNN.h b/src/engine/attack/CustomDNN.h new file mode 100644 index 0000000000..16d945e09d --- /dev/null +++ b/src/engine/attack/CustomDNN.h @@ -0,0 +1,36 @@ +#ifndef CUSTOM_DNN_H +#define CUSTOM_DNN_H + +#include + +#ifdef LOG +#undef LOG +#endif + + +#include +#include +#include "NetworkLevelReasoner.h" + +namespace attack { + +class CustomDNNImpl : public torch::nn::Module { +public: + std::vector layerSizes; + std::vector activations; + std::vector>> weights; + std::vector> biases; + std::vector linearLayers; + + CustomDNNImpl(const std::vector& layer_sizes, const std::vector& activationFunctions, + const std::vector>>& weights, const std::vector>& biases); + CustomDNNImpl(const NLR::NetworkLevelReasoner& nlr); + + torch::Tensor forward(torch::Tensor x); +}; + +TORCH_MODULE(CustomDNN); + +} + +#endif // CUSTOM_DNN_H diff --git a/src/engine/attack/PGD.cpp b/src/engine/attack/PGD.cpp new file mode 100644 index 0000000000..f918a92058 --- /dev/null +++ b/src/engine/attack/PGD.cpp @@ -0,0 +1,53 @@ +#include "PGD.h" +#include + +namespace attack { + +torch::Tensor findDelta(CustomDNNImpl& model, const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter, torch::Device device) { + torch::Tensor delta = torch::zeros_like(X).uniform_(-epsilon, epsilon).to(device); + delta.set_requires_grad(true); + + torch::Tensor target = torch::tensor({y}, torch::kInt64).to(device); + + torch::optim::SGD optimizer(model.parameters(), torch::optim::SGDOptions(0.01).momentum(0.9)); + + for (unsigned i = 0; i < num_iter; ++i) { + optimizer.zero_grad(); + if (delta.grad().defined()) { + delta.grad().zero_(); + } + + torch::Tensor pred = model.forward(X + delta); + torch::Tensor loss = torch::nn::functional::cross_entropy(pred, target); + loss.backward(); + + delta = (delta + alpha * delta.grad().sign()).clamp(-epsilon, epsilon).detach(); + delta.set_requires_grad(true); + } + + return delta; +} + +bool displayAdversarialExample(CustomDNNImpl& model, const torch::Tensor& input, int target, torch::Device device) { + std::cout << "starting the attack" << std::endl; + + auto x = input.to(device); + + float epsilon = 0.1; + float alpha = 0.01; + int num_iter = 40; + torch::Tensor adversarial_delta = findDelta(model, x, target, epsilon, alpha, num_iter, device); + torch::Tensor adversarial_x = x + adversarial_delta; + + auto original_pred = model.forward(x).argmax(1); + auto adversarial_pred = model.forward(adversarial_x).argmax(1); + bool is_fooled = original_pred.item() != adversarial_pred.item(); + + std::cout << "Original Prediction: " << original_pred.item() << "\n"; + std::cout << "Adversarial Prediction: " << adversarial_pred.item() << "\n"; + std::cout << "Model fooled: " << (is_fooled ? "Yes" : "No") << std::endl; + + return is_fooled; +} + +} // namespace attack diff --git a/src/engine/attack/PGD.h b/src/engine/attack/PGD.h new file mode 100644 index 0000000000..8a1ad2a556 --- /dev/null +++ b/src/engine/attack/PGD.h @@ -0,0 +1,19 @@ +#ifndef PGD_H +#define PGD_H + +#include + +#ifdef LOG +#undef LOG +#endif + +#include "CustomDNN.h" + +namespace attack { + +torch::Tensor findDelta(CustomDNNImpl& model, const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter, torch::Device device); +bool displayAdversarialExample(CustomDNNImpl& model, const torch::Tensor& input, int target, torch::Device device); + +} // namespace attack + +#endif // PGD_H diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/launch.json b/src/engine/attack/PGD_Linf_Rand/.vscode/launch.json deleted file mode 100644 index 042f84e355..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/.vscode/launch.json +++ /dev/null @@ -1,40 +0,0 @@ -{ - "version": "0.2.0", - "configurations": [ - { - "name": "(gdb) Launch", - "type": "cppdbg", - "request": "launch", - "program": "/home/maya-swisa/Documents/PGD_Linf_Rand/build/PGD_Linf_Rand", - "args": [], - "stopAtEntry": false, - "cwd": "${workspaceFolder}/build", - "environment": [], - "externalConsole": false, - "MIMode": "gdb", - "setupCommands": [ - { - "description": "Enable pretty-printing for gdb", - "text": "-enable-pretty-printing", - "ignoreFailures": true - } - ], - "miDebuggerPath": "/usr/bin/gdb", - "preLaunchTask": "CMake: build", - "setupCommands": [ - { - "text": "set debuginfod enabled on" - } - ], - "logging": { - "trace": true, - "engineLogging": true, - "traceResponse": true - }, - "stopAtEntry": false, - "debugOptions": [ - "StopAtEntry" - ] - } - ] -} diff --git a/src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json b/src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json deleted file mode 100644 index a9479de73e..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/.vscode/tasks.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "version": "2.0.0", - "tasks": [ - { - "label": "CMake: build", - "type": "shell", - "command": "cmake", - "args": [ - "--build", - "${workspaceFolder}/build" - ], - "group": { - "kind": "build", - "isDefault": true - }, - "problemMatcher": [ - "$gcc" - ], - "detail": "Generated task by CMake Tools." - } - ] -} diff --git a/src/engine/attack/PGD_Linf_Rand/CMakeLists.txt b/src/engine/attack/PGD_Linf_Rand/CMakeLists.txt deleted file mode 100644 index e8b7c3a360..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/CMakeLists.txt +++ /dev/null @@ -1,37 +0,0 @@ -cmake_minimum_required(VERSION 3.18 FATAL_ERROR) -project(PGD_Linf_Rand) - -# Set the C++ standard -set(CMAKE_CXX_STANDARD 17) -set(CMAKE_CXX_STANDARD_REQUIRED ON) - -# Set the CMake prefix path to include the new LibTorch location -list(APPEND CMAKE_PREFIX_PATH "~/libtorch/libtorch/share/cmake/Torch") - -# Unset any environment variables that might influence the build -unset(ENV{CXXFLAGS}) -unset(ENV{LDFLAGS}) - -# Find the required packages -find_package(Torch REQUIRED) - -# Explicitly clear any MKL-related flags -set(CMAKE_CXX_FLAGS "") -set(CMAKE_SHARED_LINKER_FLAGS "") -set(CMAKE_EXE_LINKER_FLAGS "") -set(CMAKE_REQUIRED_LIBRARIES "") - -# Include directories -include_directories(${TORCH_INCLUDE_DIRS}) -include_directories(${TORCH_INCLUDE_DIRS}/torch/csrc/api/include) - -# Add the executable -add_executable(PGD_Linf_Rand main.cpp read_net.cpp pgd_attack.cpp) - -# Link the libraries -target_link_libraries(PGD_Linf_Rand "${TORCH_LIBRARIES}") - -# Ensure you have -D_GLIBCXX_USE_CXX11_ABI=0 for compatibility -set_property(TARGET PGD_Linf_Rand PROPERTY CXX_STANDARD 17) -set_property(TARGET PGD_Linf_Rand PROPERTY CXX_STANDARD_REQUIRED ON) -set_property(TARGET PGD_Linf_Rand PROPERTY CXX_EXTENSIONS OFF) diff --git a/src/engine/attack/PGD_Linf_Rand/build_net.py b/src/engine/attack/PGD_Linf_Rand/build_net.py deleted file mode 100644 index cd2ef25ad6..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/build_net.py +++ /dev/null @@ -1,146 +0,0 @@ -import torch -import torch.nn as nn -import torch.optim as optim -from torch.utils.data import DataLoader, TensorDataset - - - -def generate_nonlinear_data(num_samples, input_size): - x = torch.randn(num_samples, input_size) - y = torch.zeros(num_samples, dtype=torch.long) - for i in range(num_samples): - if torch.sum(x[i] ** 2) > input_size * 0.5: - y[i] = 1 - return x, y - - -def train_model(model, dataloader, criterion, optimizer, num_epochs): - for epoch in range(num_epochs): - running_loss = 0.0 - for inputs, labels in dataloader: - optimizer.zero_grad() - outputs = model(inputs) - loss = criterion(outputs, labels) - loss.backward() - optimizer.step() - running_loss += loss.item() - - avg_loss = running_loss / len(dataloader) - print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {avg_loss:.4f}') - - print("Training complete") - - -class example_DNN(nn.Module): - def __init__(self, input_size, num_classes): - super(example_DNN, self).__init__() - self.fc1 = nn.Linear(input_size, 128) - self.relu1 = nn.ReLU() - self.fc2 = nn.Linear(128, 64) - self.relu2 = nn.ReLU() - self.fc3 = nn.Linear(64, 32) - self.relu3 = nn.ReLU() - self.fc4 = nn.Linear(32, num_classes) - - def forward(self, x): - out = self.fc1(x) - out = self.relu1(out) - out = self.fc2(out) - out = self.relu2(out) - out = self.fc3(out) - out = self.relu3(out) - out = self.fc4(out) - return out - -def save_to_nnet(model, input_size, output_size, filename, input_mins=None, input_maxs=None, input_means=None, input_ranges=None, output_mins=None, output_maxs=None): - layers = [input_size] - biases = [] - weights = [] - activations = [] - - if input_mins is None: - input_mins = [0.0] * input_size - if input_maxs is None: - input_maxs = [1.0] * input_size - if input_means is None: - input_means = [0.0] * input_size - if input_ranges is None: - input_ranges = [1.0] * input_size - if output_mins is None: - output_mins = [-0.1] * output_size - if output_maxs is None: - output_maxs = [1.0] * output_size - - # Mapping from PyTorch activation functions to .nnet format - activation_map = { - nn.ReLU: 'ReLU', - nn.Sigmoid: 'Sigmoid', - nn.Tanh: 'Tanh', - nn.Identity: 'Linear', # no activation - nn.Softmax: 'Softmax', - } - - for layer in model.children(): - if isinstance(layer, nn.Linear): - layers.append(layer.out_features) - biases.append(layer.bias.detach().numpy()) - weights.append(layer.weight.detach().numpy()) - activations.append('Linear') - elif type(layer) in activation_map: - activations[-1] = activation_map[type(layer)] - - with open(filename, 'w') as f: - # Write the header information - f.write(f"{len(layers) - 1}\n") # NumLayers - f.write(' '.join(map(str, layers)) + '\n') - f.write(' '.join(activations) + '\n') - f.write(' '.join(map(str, input_mins)) + '\n') - f.write(' '.join(map(str, input_maxs)) + '\n') - f.write(' '.join(map(str, input_means)) + '\n') - f.write(' '.join(map(str, input_ranges)) + '\n') - f.write(' '.join(map(str, output_mins)) + '\n') - f.write(' '.join(map(str, output_maxs)) + '\n') - - # Write weights and biases for each layer - for w, b in zip(weights, biases): - for row in w: # Weights - f.write(' '.join(map(str, row)) + '\n') - f.write(' '.join(map(str, b)) + '\n') # Biases - -if __name__ == "__main__": - input_size = 10 - num_classes = 2 - num_samples = 100000 - num_epochs = 20 - batch_size = 32 - - x_train, y_train = generate_nonlinear_data(num_samples, input_size) - dataset = TensorDataset(x_train, y_train) - dataloader = DataLoader(dataset, batch_size=batch_size, shuffle=True) - - model = example_DNN(input_size, num_classes) - criterion = nn.CrossEntropyLoss() - optimizer = optim.Adam(model.parameters(), lr=0.001) - train_model(model, dataloader, criterion, optimizer, num_epochs) - - example_index = torch.randint(0, num_samples, (1,)).item() - example_input = x_train[example_index] - true_label = y_train[example_index] - model.eval() - - # predict - with torch.no_grad(): - example_output = model(example_input.unsqueeze(0)) - predicted_label = torch.argmax(example_output, dim=1).item() - - print(f'Example input: {example_input}') - print(f'True label: {true_label}') - print(f'Predicted label: {predicted_label}') - - # Save to .nnet file - save_to_nnet(model, input_size, num_classes, 'example_dnn_model.nnet') - print('Model saved as example_dnn_model.nnet') - input_size = 10 # Assuming input size is 10 as in the example - num_samples = 1 # Generate only one sample - x, y = generate_nonlinear_data(num_samples, input_size) - print(f"sample: {x}, true label: {y}") diff --git a/src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet b/src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet deleted file mode 100644 index 8932543aaf..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/example_dnn_model.nnet +++ /dev/null @@ -1,239 +0,0 @@ -4 -10 128 64 32 2 -ReLU ReLU ReLU Linear -0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 -0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 -1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 1.0 --0.1 -0.1 -1.0 1.0 --0.28455138 0.117859654 0.18439096 0.04317837 0.28540727 0.1868404 0.024365509 0.34901863 -0.20105655 0.22752403 -0.3105072 0.39796048 -0.42463934 -0.23280914 -0.030566286 0.022306312 -0.18405044 0.26723912 -0.002429595 0.47206965 -0.2775113 0.024207324 0.31143394 -0.28730217 -0.26322183 0.38700706 -0.10731701 0.5534289 -0.28118485 -0.28138563 -0.054181967 0.014427167 -0.25925308 0.5879159 -0.071230024 0.24331309 0.19552329 0.4051667 0.50161165 -0.20595936 --0.10182064 0.0755761 0.011579716 0.30420437 0.2917685 -0.47089475 0.08457943 0.18470646 -0.058850735 0.5910261 -0.37326097 -0.4855032 -0.15858142 -0.5004132 0.012236897 0.52280325 -0.038484175 0.021141008 0.29756257 -0.06635491 --0.40193033 0.14290994 -0.050764624 0.04582046 -0.3330127 -0.06611222 -0.43604583 -0.5081408 -0.034225754 0.4082599 -0.010602157 -0.2074372 -0.055922788 0.22405607 0.011868194 -0.0526929 0.12249411 0.115381986 -0.06539138 0.08719151 -0.12981263 0.22033449 0.3874724 -0.18110098 0.47398034 0.13681911 0.4403632 -0.04718006 0.119150706 0.041176714 --0.23044953 0.38978156 -0.017102232 -0.106285974 -0.55304956 0.21900891 0.11770189 0.31969005 -0.18385275 -0.41345328 --0.51556623 0.45312193 0.099884495 -0.2042248 0.06656063 0.43175852 0.056158125 -0.35137838 0.1321477 0.10608647 -0.16051601 -0.30156162 0.34314415 -0.21871717 -0.42474025 -0.16751747 0.24119143 0.19240926 0.12394541 0.426288 --0.28395078 0.4690801 -0.44548276 -0.19799247 -0.3300124 -0.27249318 0.036338862 -0.17044862 0.248307 -0.1634606 -0.26696423 -0.05358327 0.16336162 -0.12839659 0.44823086 -0.3150219 -0.20776895 -0.24316539 0.2760343 0.46428785 --0.027324751 -0.42231372 -0.37517393 0.30027363 0.04537024 0.28453803 -0.32876322 -0.07979409 0.12054802 -0.13993585 --0.18328886 0.23774084 -0.51440084 -0.10227958 -0.14264189 -0.46239448 0.17611115 0.08153784 -0.26750496 -0.13821323 -0.088551156 -0.039042894 0.33623335 0.16488548 0.2959695 0.092411466 0.072079554 0.02075309 0.1308905 -0.39446115 -0.41459405 0.3778683 0.16550462 0.035455488 0.17237507 -0.29076958 -0.2489399 0.33575577 -0.45204002 0.22638363 --0.01603338 -0.06616335 -0.09541775 0.15022044 0.14184316 0.061307438 -0.046147875 -0.049349733 -0.0440171 -0.13926293 -0.38729164 -0.34005284 -0.06426965 -0.06819088 0.27805808 -0.21413371 -0.27721518 -0.3437389 0.24936727 -0.11903448 --0.08302598 0.09103244 -0.36246657 0.015074445 0.016474465 -0.04856309 0.10744061 -0.4672421 0.5692139 0.32074508 --0.26951241 -0.22025183 -0.23851989 -0.42344457 -0.1780842 0.13659143 -0.40865687 -0.09739604 0.15281332 -0.3534441 -0.0076130996 -0.25845188 0.26311985 -0.106487095 0.33384117 -0.0617972 0.26539403 0.55692154 0.051739145 -0.45549506 --0.13274503 -0.07541892 -0.3187774 -0.039338335 -0.06311795 0.05268189 0.31885815 0.28703627 0.5011776 -0.2951957 -0.022365615 -0.03763504 -0.008561741 -0.0049987556 0.014113599 -0.00526916 -0.038719017 0.020906111 -0.0056984946 0.008327465 -0.05771124 -0.07492643 0.08632411 -0.051183052 0.07215557 0.1215245 0.046334118 -0.03135138 -0.029953923 0.17491612 -0.47011074 0.35060474 -0.07668475 0.14954284 -0.31638902 0.28192323 0.11816618 -0.18365185 0.10113728 0.39163327 --0.07603965 -0.22875507 0.1362994 0.43870503 -0.12850475 0.04446025 0.15429042 -0.087388486 0.4207373 -0.040396158 --0.24588016 -0.09789416 -0.045685023 0.47452065 0.4897433 0.20016381 -0.19538702 0.14409441 0.27642623 -0.03839538 -0.03686738 0.0071058734 -0.015280539 0.014117275 -0.023913814 0.008389961 0.01260907 0.01525224 -0.023937952 -0.02853174 -0.10740758 0.36121452 -0.013768305 -0.3586945 0.23422818 0.49373183 -0.07453271 0.31852862 0.27163985 0.2413848 -0.009793528 -0.3581935 0.31161597 0.21680382 0.20667928 0.029715193 -0.34609497 0.46239576 -0.3585545 -0.10134971 -0.15767854 0.19925885 -0.35016078 0.55403066 -0.1511084 -0.34100676 0.029892152 -0.5051252 -0.43173826 0.09250022 --0.16758004 0.5941135 -0.08349814 0.068881065 0.33423987 0.28420016 -0.23370819 -0.24959014 0.3061083 -0.11302482 --0.022818562 -0.12887655 0.37929893 0.30370378 -0.53382 -0.4463252 -0.3137285 -0.44218856 -0.01597238 -0.14853694 --0.23284096 -0.5174152 -0.324022 0.18877333 -0.13539745 0.14509153 0.5600764 0.034933984 -0.20603243 0.17574604 --0.28923297 -0.08296793 0.19959214 -0.44647893 -0.22015063 -0.3049023 0.4591472 -0.39973325 0.05403408 0.33820346 --0.15403287 0.2841168 0.22261865 0.12570249 0.1014145 0.14819486 0.19792894 -0.033545956 -0.22475336 -0.16640449 -0.31352127 -0.35852733 -0.32525605 0.15621348 -0.44268006 0.36852244 -0.1935894 0.09239062 0.1382752 0.5441742 -0.101907425 0.43472722 0.18520461 0.2315438 0.4679371 -0.1967645 0.2944849 -0.31745636 0.078904666 -0.36715135 --0.17314965 -0.2455581 -0.24367897 -0.56859815 0.24822304 -0.036475614 0.2677036 0.51838225 -0.013135833 0.25813267 --0.06642836 -0.3147509 -0.47122824 0.055085767 0.2179802 0.2819887 -0.013466401 -0.301314 0.07419502 0.31370372 -0.27610424 0.16802591 0.27163342 -0.016057901 -0.43702644 0.17340125 0.11967022 0.32980773 0.39012745 0.3133623 --0.6118267 0.23692372 -0.17070054 -0.43392485 0.4814441 -0.25067148 -0.30185482 0.0060283337 0.110232614 -0.0045461464 --0.21913914 0.21445976 -0.08981803 0.034296755 0.24714136 -0.044226702 -0.2349005 0.544771 0.44389427 -0.38168862 --0.0049906992 0.008606745 -0.03410402 0.008440695 0.09601321 0.082708284 0.030415503 -0.008736973 0.08847122 0.015274575 --0.1314091 0.04139238 -0.26287 0.34618193 0.29946563 0.30117458 0.01104859 0.08670962 -0.55007917 -0.36144137 -0.068449214 -0.10273849 -0.1069506 0.16671368 -0.06560565 -0.14556059 -0.05493045 0.16397084 -0.10204232 -0.10851353 --0.4559008 -0.1354479 -0.1739286 0.30340123 -0.1524082 0.33013973 0.12621868 -0.14784122 -0.34168166 0.38747364 --0.0060651475 -0.006621465 0.012814799 0.006155747 -0.01081555 -0.009769878 0.00020627184 0.004324064 0.0010638997 0.020297946 --0.3601548 0.0038658846 0.42703134 -0.45277214 0.21655492 0.40475303 -0.14757645 -0.34719428 -0.3597489 0.04115225 -0.0073041604 0.023135105 0.020368993 -0.011070213 -0.027795712 0.020742163 0.009174354 -0.0047257436 0.025252273 0.011830452 --0.23114154 0.45983648 0.011570652 0.53549385 -0.1012814 0.25666443 0.24681814 0.18818995 -0.1752674 0.4152972 -0.18107013 0.41786426 0.18308738 0.2843345 -0.076477036 -0.10218624 -0.5746205 -0.15373912 0.3829511 -0.3515995 -0.5301879 0.20139302 0.05776631 -0.11035105 -0.51336175 0.017097954 0.12338001 -0.102511115 0.09740772 -0.2962824 -0.37056231 0.01330144 0.2487793 -0.14547579 -0.015848152 0.27512136 0.5775834 -0.14101133 -0.32339254 0.059750777 --0.17450584 -0.39383227 0.40074453 0.22753482 -0.14159063 -0.25798222 0.17974684 -0.26714122 -0.32277763 -0.5984688 -0.58647484 -0.09427886 -0.33757958 0.17490411 0.11129575 0.09390966 -0.4583271 -0.1760943 -0.036377296 0.18598433 --0.40673965 -0.514109 -0.02410423 0.05950414 0.33465216 -0.039197784 0.32273668 0.075439386 -0.11181032 -0.42292154 --0.46050242 -0.32964227 0.012160097 -0.11189483 -0.07768547 0.2593667 -0.04005198 0.4685868 -0.20615672 -0.12681153 --0.37476596 -0.15956824 -0.4064112 -0.28756392 -0.3729003 0.3957204 -0.27685434 0.12287568 -0.23183523 0.23311102 --0.42581096 -0.3829482 -0.051080145 0.19595413 0.37400416 -0.3260584 0.14460297 -0.4295164 0.13970433 0.15296096 --0.05876424 -0.03267093 -0.0974966 -0.033720378 -0.19159131 0.04507669 0.11721643 0.0014088796 0.057089575 0.05453948 -0.07128007 0.3236078 0.089387126 0.5251159 -0.2911699 0.3721201 -0.16029544 -0.3842856 -0.09102168 0.019555645 -0.12856187 0.3026325 -0.2133159 0.14439335 0.46550822 0.049207065 -0.072125524 -0.4576038 -0.33227178 0.17730716 --0.0042265346 0.005467734 -0.022910886 -0.00640266 0.016942512 0.021487214 -0.009116341 0.0015924831 0.030168597 0.0036327192 --0.08869967 -0.36943546 0.3245766 0.033851013 0.45802674 0.37847865 -0.3610906 -0.15004572 0.29665983 0.04687242 -0.2229126 -0.44915503 -0.37696195 0.2662045 -0.3155771 -0.3343354 0.33637467 -0.11626375 0.20489724 -0.16025603 --0.0068123196 -0.0029940098 -0.0057678623 -0.020120041 -0.0028758608 -0.0069830874 -0.012365294 0.029267607 0.0014767732 -0.024816582 -0.31435245 -0.01579723 -0.44479832 -0.28395534 0.06859346 -0.19909827 0.07264357 -0.4232367 0.17481604 -0.20412493 -0.22411191 -0.5050271 0.099488646 -0.43413413 0.15711762 -0.4288477 -0.2465681 0.11568635 0.105006084 -0.2466245 --0.25034398 -0.24395311 -0.3720052 -0.08639984 0.4801612 -0.22067371 -0.35419622 -0.18985057 -0.31907457 -0.28764147 -0.15418546 -0.33069196 0.12506053 -0.26829848 0.09308444 0.22606921 0.49476507 -0.35053545 0.15035926 -0.27493933 -0.21837892 0.2866439 0.10467524 -0.49094525 -0.052704748 -0.335181 -0.28603292 0.23666522 -0.2534945 -0.3522202 -0.4061538 0.22291237 0.41101003 0.36623672 -0.23440512 -0.50317377 0.13190718 -0.1763437 -0.10721703 0.27222344 --0.3576493 0.2405982 0.42445877 0.3463452 0.2082779 -0.51947325 0.289207 0.15824386 0.07308001 0.17685579 -0.04453485 -0.025194485 0.073939405 0.021400554 0.010437529 -0.050401766 -0.048501942 -0.12577705 0.04113846 0.06879701 -0.20846556 0.08787045 -0.29259333 -0.06331353 0.6405855 0.28475884 0.26068842 0.40689498 -0.3304113 0.076072775 -0.3795797 0.30519065 -0.39758962 0.14427018 0.212179 -0.34057254 0.38862655 0.04654019 -0.23555708 -0.24054301 --0.1381455 0.2363341 0.119750485 -0.4602533 -0.070762634 -0.30651638 -0.24514605 0.22993888 0.13864219 0.31968218 -0.32071325 0.026371712 -0.47231522 -0.19915104 -0.40999568 0.13130926 -0.05260096 -0.04913268 -0.2778576 -0.13119315 --0.13216801 -0.13181157 0.28701097 0.03589806 -0.46139944 0.25418666 -0.18728305 -0.5357403 -0.10361853 -0.18174528 -0.18507242 -0.08682343 0.4284813 0.18598318 0.22848876 -0.04690596 -0.52198005 -0.33305088 -0.5110326 0.30332452 --0.5499677 -0.19927067 0.25128692 -0.06730761 -0.022750737 -0.300947 -0.13369931 0.093010925 0.1929136 -0.43830335 --0.009327476 0.016302252 -0.003538069 -0.014251863 0.010429798 0.021142459 -0.016814722 -0.0073514762 -0.029796401 -0.01072346 --0.22950281 -0.050104816 -0.3476716 0.112840936 -0.47109488 0.1522662 0.0320684 -0.20600763 -0.22843057 -0.46446374 -0.101538055 -0.19443917 0.13180332 -0.021822358 0.22180317 -0.12088015 -0.36139727 0.44727185 0.35283852 0.14962642 -0.11627846 -0.093305044 -0.0021111595 -0.521122 -0.029742675 -0.04395466 -0.2984154 -0.39016253 -0.4346855 0.23861551 --0.110211834 -0.06172944 0.012876092 0.1480233 0.0047667916 -0.014896821 0.051848404 0.012075839 0.0016197915 -0.16583933 -0.2675201 0.25697446 0.27172685 -0.45764655 0.12845743 0.20949984 0.40958202 -0.2943057 0.41401914 -0.32482842 -0.43373975 -0.2711566 0.46053258 0.3088 0.41185912 0.22801127 0.08747486 0.06330044 -0.050433446 0.15321454 -0.21653865 0.10903641 -0.50414824 -0.047891196 0.2543352 0.35267973 0.019884603 0.10458308 0.26254326 -0.008160648 --0.28957775 -0.1999873 0.6267224 0.08226321 0.08939566 0.34719914 -0.38958666 0.2215929 0.30908543 0.30996203 --0.16191465 0.34325638 -0.4020272 -0.17345427 0.1420655 0.27302122 0.54149145 -0.035792146 -0.40335363 0.2281892 --0.046866655 -0.09081993 -0.29262474 0.1911325 -0.027617848 -0.3974567 0.34932762 0.26974422 0.2495951 0.43868172 --0.25044978 -0.37739325 0.47803643 -0.1506169 -0.3690877 0.28157714 0.15331063 0.17501883 -0.13746543 0.16995554 -0.07895695 -0.24045517 -0.46401733 -0.13675497 -0.32618582 -0.119944766 -0.37424892 0.093103535 0.35577124 0.09305152 --0.2894613 -0.23411681 -0.06195192 -0.31506592 -0.34964398 -0.3703217 -0.028258001 0.17967482 -0.6313629 0.0811279 --0.17569065 -0.35895088 -0.06791566 -0.10139673 -0.20498882 -0.22043465 -0.44075722 0.4202909 0.108130254 0.33689523 -0.14050291 -0.19696921 -0.24666788 -0.30615008 0.12575188 -0.36564392 0.37865818 -0.16586134 -0.16385397 -0.3433574 --0.28002775 -0.11424993 0.08287238 0.22925903 -0.4146891 -0.32077894 0.56230956 -0.28500438 -0.20560227 0.18216793 -0.2798132 0.058744706 0.15653609 -0.18839653 -0.019620229 -0.31418765 0.28337714 0.34092128 0.3125291 0.05012699 -0.14525717 -0.036599535 0.10270733 0.057970144 0.056752354 0.069755286 -0.0019525104 -0.03223467 0.11431686 0.021904204 -0.058498498 -0.26369753 -0.26003602 -0.19576074 0.25596663 -0.1635211 0.07847372 0.077449806 -0.44665405 0.5582 --0.52869827 0.050316643 0.18326664 0.100510634 -0.2925465 -0.051629364 0.4834877 0.38333812 0.2599224 0.12870933 --0.1288649 0.090733975 0.010761775 -0.038485464 0.049444575 0.08405639 -0.17848526 0.15368876 0.09678326 0.07457886 --0.3511187 -0.040925056 -0.29281735 0.26401553 -0.060264025 -0.3798536 -0.48554844 0.09695743 0.39591253 -0.11304257 --0.053458456 -0.042193495 -0.16550885 -0.1750925 -0.17554067 -0.11822542 -0.12614903 -0.06233662 0.02918644 0.092849046 --0.07324428 0.44320002 0.42901474 -0.43367988 -0.30450234 -0.11891289 -0.19800906 -0.097073846 -0.14061426 0.24586539 --0.23722027 -0.18062265 -0.3538977 -0.254818 -0.27859887 0.5934074 0.12573151 -0.1497591 0.18904237 -0.42394698 --0.36763623 0.26754713 -0.1903199 0.25381646 -0.54059947 -0.12011553 -0.16615215 0.2843551 0.22627825 0.055720527 --0.081066966 -0.18988396 -0.052123643 0.4689103 0.2672192 0.46879423 0.34345964 -0.22781855 0.29153413 0.11746829 --0.35543972 0.272278 0.31975096 -0.18627666 0.3241763 -0.31968057 0.2247543 0.15486833 -0.29239368 -0.5159346 --0.15778908 0.20889945 0.005726955 0.114532374 0.0656017 0.37546918 -0.59543717 -0.13706394 -0.51085764 -0.12280475 -0.3042335 -0.32086602 -0.20949444 -0.1029553 -0.36514768 -0.0076681715 0.43346438 0.17475663 -0.52909267 0.060691368 -0.3863764 -0.27003223 -0.03224157 0.18260095 0.4354366 -0.14713793 0.059475016 -0.32731634 0.17458081 0.4091818 -0.39920157 -0.4782262 -0.21414787 0.19797263 -0.15580755 -0.41751054 -0.19404264 0.38976473 -0.053107824 -0.1186259 --0.3426388 -0.17160162 -0.28741536 0.38625196 -0.046557985 -0.07041782 -0.30616528 0.17040268 -0.29714537 0.20434482 -0.0046532303 0.06944184 -0.023675453 -0.0039466196 -0.018111002 0.015383647 -0.004435171 0.023951879 0.013903248 -0.006227614 --0.077758655 0.033117298 -0.10694162 0.050311413 -0.015050664 0.04689709 0.0441819 -0.024133328 -0.16827172 0.019610966 -0.1775616 0.023685379 0.17498054 0.45607916 -0.34066734 -0.03115786 -0.3107581 0.427013 -0.3900627 -0.111504726 -0.1356229 0.0698497 -0.15551792 0.31239194 -0.0631919 -0.19209367 0.509126 0.14967643 0.28649533 -0.31878892 -0.52660066 -0.49895704 0.07882609 0.44564334 -0.24858457 0.2446494 0.14175005 0.04691269 -0.26790336 -0.10063139 -0.15793765 0.34893242 -0.490477 0.21029106 0.17741542 -0.018613411 -0.24431507 0.36199027 0.092211775 -0.10015655 --0.05174599 -0.3359824 0.30336913 -0.2319417 -0.40560856 0.06376707 -0.27233434 -0.19169773 0.5443589 -0.041798886 -0.008691748 -0.01350235 -0.017105361 -0.01231288 -0.0061977035 -0.0068901293 0.0037162916 0.007698833 -0.022476904 -0.0059539704 -0.42933464 0.048232384 -0.15957738 -0.15906577 -0.15293288 0.4438881 -0.3381563 -0.23942111 -0.15160505 -0.5422617 -0.32760242 0.20635779 -0.09144 -0.18923871 -0.2845104 -0.43294093 0.45301196 -0.3125431 0.18682526 0.11437156 --0.4980476 -0.58041525 -0.48866054 -0.38225642 -0.50385785 -0.29256764 -0.541996 0.57920843 -0.28935188 -0.48314875 -0.49368322 -0.25186178 -0.4828902 -0.47614747 -0.34747124 -0.47026178 -0.42798287 -0.37326 0.7506047 -0.32195428 -0.4752328 -0.37266782 -0.38125092 -0.39769676 -0.17578278 0.8383425 -0.61737585 -0.4138284 -0.41648188 -0.14939219 -0.50636286 -0.33551648 -0.40876442 -0.45759198 -0.33284524 -0.40005758 -0.31762153 -0.427266 -0.49846 -0.46467614 -0.541311 -0.28746375 -0.36528778 -0.33746326 -0.27660474 0.21293563 -0.38704872 0.95226437 -0.31665793 -0.08827218 -0.40357965 -0.14328367 -0.41388166 -0.41208395 -0.33830357 -0.5304695 -0.4543723 -0.24983373 -0.38298866 -0.1976541 -0.5260179 -0.49965852 0.87526214 -0.40723968 -0.2142423 -0.11221747 -0.42233157 -0.49477938 -0.13258189 -0.40585133 -0.44803977 -0.37850413 -0.39484218 -0.47244948 -0.30429986 -0.46115646 0.3923856 -0.49000448 -0.38921162 -0.36504218 -0.38433307 -0.31453475 -0.3958369 -0.4090689 -0.11875173 -0.43290916 -0.28137833 -0.40095273 0.6165044 -0.36507034 -0.46115592 -0.30187327 -0.5776016 -0.41535556 -0.27505276 -0.3282344 -0.3173351 -0.38378626 -0.32935178 -0.37675205 -0.34771442 -0.41252607 0.57541937 -0.33784476 -0.42099017 0.4899154 -0.31647876 0.95704293 -0.29085898 -0.4671359 -0.24250484 -0.40116528 -0.36988765 -0.28622502 -0.4228225 -0.41102263 -0.36325663 -0.44478616 -0.2495698 0.63440275 -0.36856088 -0.29797155 -0.42376623 -0.34427726 -0.49648714 -0.08892671 -0.51100785 -0.3199514 -0.25247115 -0.12876284 0.10140871 0.21125874 -0.06747068 -0.06213032 -0.099728964 -0.074982636 -0.062304977 0.30175555 -0.04704971 0.12912212 0.047423627 -0.08007223 -0.23623668 -0.00776405 -0.0023060578 -0.17530265 -0.13943678 -0.0530209 -0.30274048 -0.040164676 0.115671866 0.103205815 0.02684181 -0.11404969 -0.017082287 0.041100368 -0.07981952 -0.14529611 0.09475666 -0.04710138 0.0036608214 -0.08502678 -0.23273945 0.09075107 -0.29113173 0.099548414 0.022440305 -0.058007404 0.09915796 -0.049558416 0.16755404 -0.1076635 0.10239559 -0.1985158 -0.080557354 -0.051981155 0.18615028 -0.000974348 -0.03907409 -0.13166451 -0.021684214 -0.14970933 -0.10365143 -0.06711683 -0.34574267 -0.14298368 -0.15630527 0.042045552 0.031676397 0.058082096 -0.09805584 0.28482893 -0.019177243 0.0046153967 -0.1870979 0.10512655 0.019202217 -0.082971215 0.18728754 -0.0044559073 0.09430838 0.085605465 -0.13287985 -0.11296332 -0.1721771 -0.11169651 -0.14248605 0.13675378 -0.21717453 -0.01830794 -0.1240418 -0.031693988 0.028994706 0.08358371 0.10154661 -0.10033465 -0.08913857 0.1225209 -0.09199355 -0.093348406 -0.052179143 -0.13361965 -0.03232791 0.20825058 0.03529225 -0.051942654 0.08642462 0.009715819 -0.07835139 0.16620241 -0.25719503 0.071884744 0.13018182 -0.16704945 0.015667314 -0.15157427 -0.23210417 0.20237912 0.19080825 0.1533417 -0.22261333 -0.0152152395 -7.128909e-05 0.007287715 -0.09616776 0.18819952 -0.021327883 -0.15319195 -0.12831673 -0.13636489 -0.07430686 -0.12819542 0.020629367 -0.1364513 -0.25210202 -0.20001467 --0.3061107 -0.058391593 0.14099348 -0.119278796 0.32617742 -0.15434304 0.14434557 -0.0014495926 0.03797238 -0.24748078 -0.15270182 -0.05712759 0.009733153 0.07924787 0.0011039705 -0.14031516 0.26647133 -0.05427487 -0.031985138 -0.045656953 -0.0489848 -0.11982127 0.015052426 -0.082363546 -0.10759615 -0.07762176 -0.1046598 -0.11845488 -0.06942303 -0.059722226 -0.06048842 0.1006053 0.101716995 -0.017098408 0.12305329 -0.06283755 0.023364633 0.1657905 -0.2582612 0.059904713 -0.191074 0.070203654 -0.11318587 0.15773745 0.07527263 -0.0046527013 -0.11512393 -0.07460402 -0.10485363 -0.037711885 0.056305446 -0.09481521 -0.18710306 0.0814657 -0.03177433 -0.0358437 0.066688195 -0.09532622 0.026057433 -0.05293235 -0.12881473 -0.007139806 -0.16083522 -0.11804698 0.028242711 0.05037133 0.09826358 -0.013463977 -0.17532381 0.00017325801 -0.042797823 0.13616353 -0.12949756 0.1559729 0.032087244 0.338494 -0.08194737 -0.071225815 -0.15089966 -0.019118512 -0.3038648 0.0005279033 0.08004321 0.26004577 -0.17140386 -0.11510959 -0.03375195 -0.0699621 -0.010833263 -0.110140435 -0.2018776 -0.10183863 -0.097227514 -0.20772587 0.036443714 -0.07038287 -0.09659145 -0.12828186 -0.10758462 -0.15550399 -0.04212592 0.041788884 -0.14111127 0.010079608 -0.031517237 -0.06013411 0.120718606 0.00868488 -0.061421137 -0.12507209 -0.059790477 -0.1033156 0.05981811 -0.13235423 -0.100659244 0.022813754 -0.15672462 -0.078986205 -0.21410045 -0.05899419 0.023920676 0.17118233 -0.14878246 -0.2262813 -0.18180634 0.008074569 -0.18643099 -0.0841678 -0.06325674 0.3158812 -0.13911664 -0.18776152 -0.047951654 0.211161 0.062503114 -0.28710923 0.09079128 -0.045619227 0.30071843 0.20567226 0.2252348 0.27027816 -0.004445002 0.21881579 0.15869264 0.4756224 -0.3181306 -0.01572822 0.2173839 0.27455717 0.2765112 0.354197 0.08245484 -0.12767263 0.19811189 0.23229283 0.42247215 -0.11688017 0.5027683 0.2967545 0.021459166 0.39556414 0.10228887 0.552294 0.36052066 -0.094374776 0.35989404 0.029373538 0.5504713 0.31356803 -0.023049345 0.08980754 0.12106365 -0.0029841017 -0.26752514 -0.30844316 0.14442082 0.08457967 0.15017903 0.054433156 -0.25979185 0.10473252 0.038123176 -0.11125127 0.023835905 0.15801446 0.13982402 0.1482948 0.4107214 0.307873 -0.12915888 -0.26734403 0.20844214 -0.11004148 0.23696509 -0.02092904 -0.039922804 0.17765476 0.22732271 0.37788844 0.24666594 0.2867848 0.291178 -0.39438 0.0019300872 -0.026859485 -0.060666543 0.17216218 0.2558782 0.07308875 0.275942 0.3788867 -0.019216254 0.1985678 0.042484835 0.3195449 -0.29289567 0.08331348 0.360671 0.23833375 0.3907752 0.01776566 -0.033193797 0.23301572 0.14946708 0.12840798 0.29395285 0.42016885 0.15309967 0.13122329 -0.18296932 -0.023632511 0.20843518 -0.03653492 -0.369909 -0.006083003 0.18158735 0.5730657 -0.23114048 0.18915291 -0.07248513 0.37693876 0.25369298 0.15554538 -0.014345057 0.10498585 -0.032560375 -0.06421591 0.4002657 -0.15114938 0.13111752 0.10376038 0.23710842 -0.0052062892 -0.13777216 0.33482918 -0.054961216 -0.10175659 -0.071475916 0.023482645 -0.07725658 -0.009387395 -0.006831787 0.057659592 0.05583738 -0.019585961 -0.018921576 0.05655799 -0.010803109 -0.019376079 0.00089767086 -0.08273243 -0.025637537 -0.017166179 -0.037294462 -0.111949906 -0.0512868 -0.0064849723 0.015109441 -0.07276224 -0.09003398 -0.0034615383 -0.04583202 -0.023758136 -0.054521598 0.023516465 -0.07379407 -0.024020877 -0.10233397 -0.006212225 -0.072012566 0.07353723 0.038921542 -0.09069568 -0.066179715 0.0064184233 -0.06523892 0.04710325 -0.05309107 -0.08082205 0.07372771 -0.11215838 -0.04980156 -0.06744044 0.019555228 -0.09611448 -0.046267543 0.03399663 0.033441275 0.017609593 0.035101544 0.031318672 0.026587235 0.050718237 -0.08190005 -0.0949771 0.014100369 -0.0841331 -0.06012655 -0.09435812 -0.10023291 0.008053356 -0.0049722195 0.07088896 0.051392104 0.03745146 -0.016621323 -0.09293208 0.033553652 0.03021297 -0.04122296 0.022910716 -0.013370333 0.07229783 0.069237396 -0.029567601 0.054852713 -0.054546874 -0.08504498 -0.0072635296 -0.077413745 -0.0598163 0.026684571 0.007935607 -0.03230557 0.03369837 -0.07754206 0.06247696 0.07478874 -0.029100742 -0.064304635 0.047819443 -0.09725008 -0.022081172 -0.0032462138 -0.0306684 -0.10718476 -0.054282896 -0.08213437 0.043404467 -0.08480738 0.057363205 0.044106245 -0.09768993 -0.01299765 0.032684363 -0.00038142136 -0.0015463931 0.008721837 -0.038669243 -0.00780818 -0.04060742 0.042903677 -0.08808824 0.019236935 0.014808838 -0.077097975 -0.094490275 0.0479333 -0.008427469 -0.0177593 0.062646724 -0.035783272 0.057554632 --0.02170802 -0.10097058 -0.039423708 0.060791675 -0.062913015 -0.03220438 -0.022258304 -0.0051209973 -0.03452105 -0.038907316 0.029861527 -0.051713835 0.019467387 0.035205204 -0.08472533 0.019922748 -0.07984434 -0.10666134 -0.01831951 -0.06864508 -0.08435263 -0.04425101 -0.018485818 -0.0727034 -0.020571487 -0.04983585 -0.09681881 0.06762959 -0.04297733 0.005685131 -0.07092041 -0.06421981 -0.0454833 -0.03788864 -0.10329039 -0.027022585 0.011297344 -0.022401892 -0.07524064 0.051589422 -0.06950978 -0.088600166 -0.0017300586 -0.005586231 0.018668707 -0.10624136 0.064509206 -0.007048342 -0.035638075 -0.025330352 -0.020504173 0.026181499 0.019381376 0.024736725 0.03123186 0.05435632 0.06707178 0.043984372 -0.07463462 -0.031454388 0.059656326 -0.049991075 -0.10900284 0.061995786 -0.045031924 0.049865633 0.00375619 -0.06763569 -0.01463483 -0.005930814 -0.09862791 -0.0873444 0.028277248 -0.089134365 -0.062314767 0.016837995 0.022312 -0.03162664 0.053771615 -0.0069192993 -0.0089991875 -0.05956258 0.03881303 -0.034841824 0.03204732 -0.061096527 -0.055886388 0.032385323 -0.028350271 -0.08100625 -0.05734499 -0.0028614686 -0.009830259 -0.067465805 0.049192216 -0.043432813 0.052467383 0.017255818 -0.06646106 -0.08176486 -0.060888205 -0.018139215 0.00029124596 0.041514408 -0.09226054 -0.034692712 -0.026714448 0.029750338 -0.0146274995 0.054608297 0.011914438 -0.041482124 0.05138804 0.017733883 -0.0024298865 0.07473682 0.010566117 -0.055306826 -0.10264856 -0.11103316 0.045582097 -0.03909239 -0.07302528 -0.039468635 0.026368648 -0.08538285 -0.008971606 -0.10318031 --0.082582295 -0.07685 -0.101472124 -0.07500627 0.018734787 -0.019133393 -0.07421398 -0.107861936 0.059763968 0.023681413 0.04928628 0.08105531 -0.013469935 -0.06170649 -0.06520056 -0.058338337 0.03674244 -0.03077781 -0.12168483 0.0068369997 -0.07491326 -0.06001215 0.003145583 -0.05964985 -0.037160277 0.020529192 0.04765161 0.038571317 -0.07493726 -0.033676006 0.07570332 0.014723692 0.047762148 0.042697765 -0.13156334 -0.06449452 0.073702134 -0.09250606 0.047662552 -0.025133286 -0.04406997 -0.05793271 0.05965673 -0.07179908 0.030547034 -0.11094953 0.0026287085 0.03197342 0.039129492 -0.054259375 -0.09820488 0.028148456 -0.043811627 0.04202099 0.027737552 0.008606576 -0.0060273195 -0.098790295 -0.07365758 0.041782856 -0.04757257 0.014550561 -0.069199756 0.04172552 -0.0004291775 0.009942298 -0.084534906 -0.0700213 -0.08702256 -0.08649075 0.02189486 0.013224232 0.048480693 -0.040565263 -0.088066556 -0.07224678 0.013568839 0.047162026 0.031731978 -0.010766615 -0.036400404 -0.03974719 -0.011475018 0.012544085 -0.04173433 0.06344754 -0.061959267 -0.021402163 -0.103156164 -0.021881169 -0.084234595 0.03708155 0.044402733 -0.09520136 -0.009073325 -0.082204 -0.0047706147 0.069188625 -0.10669571 -0.016155342 -0.03851761 0.07352962 -0.06371492 -0.04746283 0.072599605 -0.073483974 0.04092221 0.033173863 -0.08488979 0.019145802 0.006839372 -0.05006693 0.03452816 0.042938583 -0.083784394 -0.07750576 -0.023752801 -0.08367755 0.06723538 -0.06529168 -0.06132087 -0.008829491 0.004402369 -0.013506725 -0.046417087 0.033862762 0.0410583 0.044104133 -0.011137077 -0.06343973 -0.030491995 -0.0029615208 -0.11389895 -0.08109504 -0.0670581 -0.13887674 0.05034063 -0.101518676 -0.06471664 -0.069123946 -0.012437918 -0.01983522 0.0028577985 -0.09327762 0.021602254 0.0032744738 -0.031581804 0.024515066 -0.04336826 0.013064906 -0.070266224 -0.058179665 -0.03229886 0.026457341 -0.062101856 -0.07601838 0.005043699 0.009041147 -0.0625511 -0.0005810921 -0.017289417 0.034096003 -0.046049148 0.0279022 -0.04914798 -0.005565182 0.021771118 -0.029024128 0.0065579684 -0.056926478 0.02076967 0.029735574 -0.07425056 -0.065800525 -0.10491474 0.013381687 0.056476664 0.019829255 -0.044083405 -0.12257732 -0.058799267 0.06573337 0.0010121389 0.084537916 0.008075939 0.0033338643 -0.12155928 0.068173826 0.006757989 -0.023937067 -0.008127655 -0.026121084 -0.02647971 -0.00583874 -0.03160583 0.020195814 0.039262336 0.03192215 -0.114925355 -0.0140241375 -0.08893556 -0.0059375945 0.01464203 0.029281963 0.041142296 0.025081161 0.05481786 -0.018386504 -0.014225417 -0.06341848 0.041474167 -0.055747207 -0.065173835 -0.083882 -0.057681803 -0.011784118 -0.035126947 0.038919434 0.0046390365 -0.055643488 -0.051790234 -0.10886945 -0.039837457 -0.05191047 -0.021975283 0.05731652 0.015286936 -0.045348156 0.01668849 0.06868234 -0.020118034 -0.0020480738 -0.07513503 -0.1277336 -0.08388009 -0.117070034 0.033768695 -0.036237817 -0.097743824 -0.07119531 0.01324869 -0.0053470237 -0.086605355 0.035920665 -0.07704257 -0.102730215 -0.053555936 -0.07145074 0.032306578 -0.0166219 -0.017276451 -0.011479749 -0.054066695 -0.096456714 -0.010856104 -0.001519783 -0.023823932 0.026914034 -0.03396706 0.09124779 0.044073734 -0.013188419 0.090649255 -0.08046404 -0.037058376 -0.012706664 -0.08730524 0.030424632 0.0014093379 0.07601238 -0.03403889 -0.0136894975 -0.08398612 -0.029633671 -0.07127086 -0.05807986 -0.077285916 -0.094569385 0.025602594 -0.005638306 0.046562772 -0.08241678 0.05057043 -0.07436735 -0.015123666 -0.04058743 -0.050811075 0.053511754 -0.07044371 -0.057813175 -0.027080527 0.016587352 0.023340449 -0.118413724 -0.002704401 -0.03386599 0.084112965 -0.013296337 0.06300631 -0.027133599 0.003418498 0.0083862655 0.0073102633 -0.045653727 -0.0067101405 -0.094351515 0.005632115 -0.0034242023 -0.08750844 -0.07208898 0.041487172 0.102971785 -0.041594177 0.024345806 0.063188694 -0.06830075 0.06596806 -0.02424269 -0.07461334 0.012064132 0.057935704 -0.027860511 0.02700163 -0.06489536 -0.072500706 0.06053102 0.014127327 -0.04832635 -0.06765537 0.014739334 -0.030417504 -0.073717505 -0.09789642 0.0022475412 0.06603209 0.057976935 -0.021712111 0.01723799 0.0065516545 0.039193448 0.031036757 0.11170259 -0.04805449 -0.09027551 -0.08169385 0.006479838 -0.047555156 -0.021315247 -0.03533071 -0.0469883 -0.019709969 -0.030474156 0.05579995 -0.004144133 -0.030106595 0.092705406 0.02411421 0.069225475 -0.06693014 -0.011878937 -0.020344516 0.0037588791 0.06279791 0.009124297 -0.0077903476 -0.006622466 0.008238327 0.015194692 0.04518225 0.06517798 -0.0043366263 -0.029658612 -0.042995356 -0.025612164 0.05487492 -0.081285916 -0.006877093 -0.05245376 0.080470555 0.0005917526 0.036429845 -0.052711908 -0.05385736 -0.09300485 --0.082800634 0.05979247 0.012558824 -0.071049444 -0.07041323 -0.0021917145 0.0063353223 0.022361906 0.035225097 0.018211892 -0.013050156 -0.071435116 -0.01986677 0.059125964 -0.034409862 -0.024576448 0.051289488 -0.011091349 0.038364723 -0.05100956 0.05485109 -0.060785096 0.00640458 -0.08538797 -0.035619125 0.04211274 -0.081940256 -0.07057486 -0.0966498 0.016669009 -0.042527497 -0.026365165 0.04496131 -0.025901346 0.04079664 0.024402445 -0.026294762 -0.07307315 0.027298672 -0.0955006 -0.08808168 -0.095496334 -0.09391398 0.013567587 -0.08009039 -0.09352729 0.017339233 -0.02268059 0.07498543 -0.031835068 0.006161084 -0.094488665 -0.10101812 -0.09315059 0.026633875 -0.03846813 -0.08315019 -0.035819583 -0.07156951 -0.028505493 -0.07439183 0.052459255 -0.027383236 0.0242837 -0.034993418 0.035428174 0.029415831 -0.01937789 0.056449138 -0.0068132016 -0.05034585 0.027220318 0.03861081 -0.08498768 0.039254017 0.03741438 -0.05255135 0.047499843 0.055444233 -0.013781345 0.03128034 -0.00999385 0.004535494 0.005833419 -0.06619209 0.0024952765 0.060537387 0.004797237 -0.07381102 0.015089906 -0.057771802 -0.092807055 -0.094432995 0.0038028643 -0.014482031 0.03423172 -0.013346087 0.0031324783 -0.07185676 -0.039294478 0.002287118 -0.06260134 -0.021597145 -0.019712685 0.03256054 0.03431773 0.0018847588 -0.09992834 -0.08343753 0.03695272 -0.08426996 -0.070075214 0.024301376 -0.045848206 -0.019896468 0.026580447 -0.07325717 0.013863255 -0.059450272 -0.090231664 0.02647703 0.0067761727 0.045088354 -0.07618309 -0.062112965 -0.05794018 0.0070015863 -0.04312601 -0.034972575 0.037921533 -0.07541296 -0.064095765 -0.12984793 -0.0052258675 -0.10827224 -0.15319248 -0.044543825 -0.08033115 -0.05346074 -0.0019150373 0.027990147 0.0056172726 0.048777126 0.0058566714 -0.03878546 -0.11831881 0.03477117 0.021564348 -0.14373018 -0.15935159 -0.04019064 -0.018882552 0.006390219 -0.004626406 -0.0026746176 0.09328503 -0.13508548 -0.0649261 0.012567065 -0.0765606 -0.17289074 0.058964588 -0.098802246 -0.09104751 -0.10063864 0.0062017823 -0.0011591831 -0.12549141 -0.18436342 -0.13172635 0.02276248 0.06270951 -0.056145437 -0.08757345 -0.12834032 -0.09748754 -0.02811091 -0.10254226 -0.0408844 0.02119356 0.017727006 -0.09851564 0.029882431 -0.08124301 0.012250695 0.0067030657 -0.080592975 -0.036864046 -0.04832311 -0.08462023 0.013364378 -0.050055847 -0.12185837 -0.057740808 -0.026835287 0.045801 0.01583684 -0.04896336 -0.13661559 -0.15935326 0.030663738 -0.07893385 -0.07596158 -0.009446063 -0.07092397 -0.03568789 -0.09507795 -0.035578586 0.033195257 0.04139779 -0.06180622 -0.022479804 -0.0021251598 -0.18098973 -0.043669213 -0.017962696 -0.14166178 0.05761907 -0.09379131 -0.12858269 -0.09162191 -0.06672623 -0.06133775 -0.07730333 0.04619586 -0.05514776 -0.07373125 -0.16146302 -0.06082078 -0.032311365 -0.01986905 -0.064529605 -0.16693157 -0.0134060765 -0.009667731 -0.067754224 -0.031084673 -0.1074508 -0.10550139 -0.018866975 -0.13544454 -0.019961342 -0.15067613 -0.11712565 -0.11790995 -0.02180128 -0.0072500976 0.022818534 -0.05005621 -0.03304691 -0.10414552 -0.17896095 0.08105092 -0.10894294 0.012039372 0.03723715 -0.25279292 -0.19361034 0.1094378 0.20131569 0.29359436 0.43926212 0.3179857 -0.28454587 0.13239692 0.35597986 0.23293471 0.25974676 0.20777905 0.39640754 0.23234507 0.22914861 -0.048965465 0.23735271 -0.13768987 0.11668777 -0.082866415 0.26555827 0.20294648 0.09342029 -0.031742446 -0.2814818 -0.29199854 0.16589089 0.084293075 -0.0359847 0.27569842 0.16014995 0.18737788 0.057980854 0.42302537 0.35904607 0.2383979 -0.018479113 0.4984169 0.3435179 0.55916154 0.33068356 -0.3070137 0.20908281 0.20263809 -0.11058465 0.30827844 -0.23711777 -0.053497747 -0.0015292075 -0.037432 0.055313095 0.22125751 0.59573346 0.09948541 0.27158427 0.3765933 0.016864501 0.017281333 0.121840164 0.2519492 0.12491263 -0.27324304 0.1758861 -0.014944004 -0.06630354 0.063939124 0.22107406 -0.07440612 -0.043076962 0.44813582 0.062306147 0.16173841 0.22963141 0.06376438 0.35659555 -0.1939444 0.3912329 0.101959996 0.21965858 0.3213758 0.1627977 0.2710036 0.27857292 0.0057667233 0.3976231 0.2247546 0.0993219 -0.21467099 -0.13989815 0.30969685 0.2301999 0.25939804 0.49252695 0.032663804 -0.10215978 0.3308913 0.091031834 0.22760655 0.15778811 0.07329568 0.24469207 -0.1797695 0.2671821 0.27501926 -0.025360603 0.08865921 -0.2919086 0.19429646 0.3517953 0.4037888 0.2608012 0.40777612 0.22168337 0.30177853 0.1385577 0.19180223 -0.19746126 -0.008374415 -0.0620726 0.29719177 -0.12836854 0.112238124 0.003430933 0.16989774 0.004209546 0.30191574 -0.010232949 -0.0005230873 0.33704168 0.09505411 0.23055625 0.11711579 0.25059932 0.1929889 -0.197914 0.23835793 0.23005103 0.34970492 0.35443777 0.30889982 0.102342285 0.21861018 0.34989744 0.40759626 0.010291543 -0.17619418 0.14010903 0.23007983 0.16792543 0.1919015 0.102378175 0.0262547 -0.19316404 0.43919393 0.34270984 0.1293776 0.11315797 -0.107391715 -0.027717765 0.28394148 -0.037852567 0.24692273 0.07047034 0.26191655 0.24752276 0.31316864 0.27190286 0.04977077 -0.16993508 0.17511004 0.06321101 0.009750783 0.033877578 0.27245694 -0.19962773 0.058323078 -0.07566552 0.41127264 0.023803905 0.3246952 0.17766249 0.08266271 0.3070224 0.12227935 0.30353746 -0.18125468 -0.1178602 0.19364807 0.22207479 -0.20183659 0.26123148 0.2257157 -0.02647015 0.0094512785 0.16810414 0.029187933 0.14526089 0.2883829 0.17401087 0.21468523 0.3746631 0.22309789 0.33824503 0.05864705 0.2851909 0.27733365 0.2932397 0.0906518 0.22205645 0.10350007 0.074674465 0.026174309 0.2503567 0.13255852 0.37551793 -0.09146145 0.16301903 -0.035552163 0.06805484 -0.10983801 0.22603679 0.26108664 0.15249419 0.29718825 0.36276233 0.19505392 0.17678957 0.19504642 0.2628466 -0.04635173 0.11943039 0.23150322 -0.14086355 0.14714542 -0.29370835 0.22310278 0.104778804 0.16252364 0.20331585 0.3389046 -0.026198883 -0.005948574 0.0701904 0.44024196 0.28626162 -0.0033377535 -0.10193171 -0.065573 0.2399463 0.25608736 0.120522305 0.3383942 0.028125847 0.39670965 0.1059482 -0.08090745 -0.08023348 -0.07177413 0.12786052 -0.013173782 0.17540543 0.19297618 -0.19742092 -0.041608434 -0.15553913 -0.018684508 -0.042548195 -0.07420855 -0.06910591 0.07724648 0.0195646 0.004499754 -0.01879066 -0.21977803 -0.03727824 0.048288625 -0.11746477 0.023115678 -0.011276546 0.013576021 -0.011705337 0.0052926573 0.13990842 0.22625369 -0.00068441586 0.04234148 -0.16658644 -0.09952136 0.005388775 0.009274452 0.14567108 0.083184965 -0.07355182 0.22508611 -0.06738796 -0.0388261 0.21092233 -0.032995064 0.024152845 0.07136125 -0.14945054 -0.05022173 -0.13097309 0.18374874 -0.013109742 0.018966971 -0.109935746 -0.123666495 -0.0028964006 -0.08413949 0.14578977 -0.050891347 0.065998815 -0.07564009 -0.051405106 0.30233207 0.031851344 -0.1433286 -0.21195363 -0.16649762 -0.018806336 0.053051617 -0.043254748 -0.14840923 -0.15392666 -0.15668146 -0.14027394 0.23982137 0.1254956 -0.08789801 -0.15355083 -0.1794444 0.08944418 -0.024029637 -0.0054336516 0.045327306 -0.18217492 -0.0724627 -0.10534229 0.009997356 0.09233297 0.07119622 0.12880331 -0.17387895 0.07541593 0.12798631 0.1468153 0.12372773 0.013619179 0.007630263 -0.04015589 0.016405666 -0.0074183173 -0.028762432 -0.18161343 -0.023017144 0.08912338 -0.16034 -0.034875084 -0.039699033 -0.15522817 -0.040181067 -0.14322548 0.023180868 0.27527434 -0.0028294984 0.17208497 -0.11172317 0.10222552 0.19697367 0.0027994541 0.08010178 0.044273857 -0.037767373 -0.20134865 0.0087364195 -0.13342741 0.12971488 0.011184918 0.009587695 -8.8590685e-05 -0.02726119 -0.104606904 --0.102591 -0.072379395 0.0038108495 -0.0390512 0.021653805 0.05557532 -0.06276534 -0.18689013 -0.028904581 0.06627289 0.024416223 0.012379649 0.065419935 -0.04984626 0.041356742 -0.02633478 -0.02254832 -0.10472434 -0.0126680285 -0.075597115 -0.071482256 -0.006458228 -0.11208636 0.0008114794 -0.060657352 -0.04064969 -0.106206976 0.036494672 -0.13823466 -0.04158128 -0.024237225 -0.0506181 0.06587116 -0.06413634 0.025177106 -0.12224143 -0.05124022 -0.12473581 -0.031308983 0.062292155 -0.060268734 0.024332711 0.019085722 -0.07676082 -0.13514179 -0.016440976 -0.06894556 -0.025529448 0.056235835 -0.022584794 0.07615188 0.052554537 -0.08061384 0.006767556 0.046096504 -0.057292942 -0.11086969 -0.035236143 -0.14333707 0.043185182 0.089623995 -0.13872603 -0.0561753 -0.052667458 0.014561295 -0.08447293 -0.07798978 0.06125349 0.012511141 0.028138297 0.075454675 -0.09218475 -0.022421705 -0.030264933 -0.07556322 0.027569082 -0.13987195 -0.10644339 -0.0019217118 -0.11320035 -0.05107698 0.023648236 0.015803706 0.0019561136 -0.12001138 0.08422135 -0.02717229 -0.08499185 -0.16219816 0.04323028 0.030039812 -0.09390171 -0.01458006 0.028913148 -0.043468658 -0.085869335 0.07933895 -0.106239304 -0.008227926 0.056166865 -0.063148364 -0.059263553 -0.08695284 -0.035979435 -0.064653195 -0.023012204 0.0187024 0.026850397 0.02660541 0.036439545 -0.047385354 0.0023009605 0.004886482 0.05974686 -0.054491386 -0.009258281 -0.08080011 -0.11430586 -0.048880804 -0.104825534 -0.069189884 0.027578514 -0.010656612 -0.11005393 -0.07858137 -0.072229855 -0.028225986 -0.051790733 -0.2843997 -0.07555581 0.2881135 -0.14147405 0.46224403 0.15204225 0.33883733 -0.3497873 0.236573 0.019803947 0.45951134 0.077852026 0.04996174 0.5571992 0.14093259 0.22720286 0.42814106 -0.34433788 -0.1800408 0.21578717 0.33119106 0.17286873 0.1992407 0.31950262 -0.003091425 -0.11449032 0.3404113 0.015635306 -0.042712115 -0.22248605 0.14940494 0.058039475 -0.2310387 0.19269489 0.25043994 -0.16101514 0.48012817 0.08583322 -0.17769276 0.30031103 0.5616202 -0.081152536 0.23609917 0.38075757 0.19875397 0.035741452 -0.24937303 -0.40287703 -0.23926328 0.030211112 -0.18991482 0.09425171 -0.1309385 0.42985302 0.16631657 -0.26206994 0.0160048 0.3169518 0.1754194 0.112601094 -0.3612953 0.251716 -0.15977995 0.4168316 0.03820354 0.031153183 0.03752476 -0.32497805 0.12458132 -0.07959502 0.5196873 0.4114806 0.26460087 0.15643321 0.38712922 0.19991435 0.116269276 -0.12079605 -0.45622352 0.16829306 -0.060791705 0.045539103 -0.09890175 -0.031702176 -0.12589343 -0.05031963 0.18893594 0.22093219 -0.1377165 0.408658 0.0658885 0.23529436 -0.51169187 -0.090965204 0.32847792 -0.12985434 -0.061130706 0.086455874 -0.07811915 0.27558708 0.120046 0.2387753 0.06405832 0.40687037 0.26756966 -0.04671318 0.07553404 -0.23296152 -0.044859763 0.099756256 0.0025624859 0.19061989 0.32512718 -0.09903368 -0.2790073 0.03173576 0.24879333 0.3613448 -0.03432245 -0.2290149 0.34088537 -0.06181288 -0.032811996 -0.1565074 0.15626864 -0.09537763 0.31365335 0.13659704 -0.013721009 0.17380142 0.30208895 0.2841374 0.24393 0.3381574 0.20977172 -0.02267505 0.12608308 0.40927714 0.05996383 0.17484877 0.34575665 0.03625483 0.15270422 0.21435893 0.20517403 0.31964308 -0.2303205 0.13219859 0.23467495 0.2137425 0.24818504 0.21709338 -0.012956809 -0.22994263 0.23354857 0.3361706 0.13167933 0.11063671 0.36688167 0.23614167 0.28733596 0.03985099 0.27620557 0.21289545 0.19142959 -0.013893741 0.2719934 0.20602351 0.2583178 0.17519167 0.08601442 0.008376001 -0.061691243 -0.064658955 0.11255645 -0.26726282 0.047474146 0.044004153 -0.047482662 0.035277862 0.32888332 0.1757347 0.2703975 0.36509955 0.1382695 0.15437105 0.11595304 0.08681558 0.28044692 0.3746766 -0.16610864 0.26236156 -0.003618316 0.05763903 0.40361953 0.24007688 -0.00031063028 0.11343097 0.46373338 0.1878076 0.22141697 0.53501266 0.09779396 0.17939697 0.043317076 0.26623663 0.20834935 0.16196565 0.30010208 0.14988084 0.24587385 0.272907 0.004611332 0.20864594 0.17214257 0.2682163 -0.15054199 0.29961604 0.26012263 0.24590367 0.42700398 0.34275293 0.13788348 0.22995223 0.12451622 0.32149938 0.2951237 0.23023045 0.16463314 0.25259054 0.0032774175 0.11813827 0.30378982 -0.11241999 0.09288862 -0.2741906 0.18907917 0.32039788 0.13964327 0.39103162 -0.09380511 0.032032095 0.13199423 0.097618714 0.288102 0.2199521 0.01521321 -0.15341121 0.14825213 0.10630915 0.17232965 0.19403075 0.3960225 0.11226453 0.3529455 0.20145303 -0.031091338 0.46095842 0.2640863 0.30602562 0.4380904 0.37765613 0.3299477 -0.09463114 0.09575437 0.19998938 0.3604679 0.19339624 0.4113247 0.05600359 0.067155756 0.1617452 0.15302378 0.27164826 -0.23878683 0.14554685 0.23621953 0.2556782 0.06445264 0.18367393 -0.0734284 -0.2157719 0.36558047 0.14021009 0.1292594 -0.025167665 0.17452972 0.250831 0.16750295 0.16437475 0.14625584 0.19271882 0.0554497 0.13102648 0.30759728 0.19336128 0.3101193 0.13364558 0.18866202 0.17818886 0.10959581 -0.06159229 0.34341973 -0.23011822 0.20063777 -0.006028333 0.12726867 -0.03493573 0.3312204 0.23200507 0.16842443 0.20181257 0.41094625 0.1469056 0.107823856 0.043984234 0.27778617 0.33397248 -0.2485471 0.2315835 0.033012655 -0.0596593 0.05523835 0.24572386 0.08999199 0.2237967 0.2926131 0.22728308 0.2063118 0.1838788 0.2312681 0.17871161 -0.076470904 0.35184446 0.26672617 0.19609533 0.03253137 0.15276697 0.15367736 0.24195811 -0.042722326 0.24915978 0.14218998 0.06830876 -0.1754553 0.1526303 0.22474521 0.12549645 0.31351134 0.22203733 0.19019169 0.1482909 0.18689768 0.18446127 0.17486894 0.19478357 0.22627817 0.08477646 -0.14931136 0.16346753 0.06536159 -0.086423144 0.30568507 -0.35259944 0.10218397 0.22024304 0.16773768 0.18038188 0.17748077 0.14791526 0.1963896 0.17208616 0.27547407 0.31556407 -0.098062575 -0.11037697 0.22141787 0.2661277 0.16189216 0.28073633 0.3360488 -0.03271229 0.27122828 0.0058280327 -0.0042506508 -0.023113005 -0.12398538 -0.14988512 -0.102667555 -0.12239753 0.091906905 -0.098650426 -0.224244 -0.029770339 -0.06456202 -0.15589333 0.047750406 0.11082002 -0.083071806 0.059769668 -0.12351707 -0.07173837 -0.02918996 -0.09230959 -0.12488342 -0.008195539 0.032863166 -0.1608466 0.007424324 -0.07266302 -0.1946576 -0.08060813 -0.04579109 -0.14674212 -0.0035449371 0.118576474 -0.19154361 -0.0072687743 0.00086627714 -0.26327673 0.016102746 0.050411064 -0.20915718 -0.09233649 -0.08417016 -0.19398229 -0.11888987 -0.15707746 -0.11903028 -0.106951326 -0.13443696 -0.0035819826 0.01002685 0.07601976 0.0612292 -0.004304789 -0.20455106 -0.18222262 -0.09201861 -0.05716795 -0.0028413571 -0.0077226763 -0.16517864 -0.03460066 -0.03143877 -0.13313207 0.04808825 -0.06690447 -0.17926313 0.014390342 -0.11976049 -0.25733507 -0.015145974 -0.22660904 0.008382793 0.04844682 0.0663258 0.092843294 -0.28147924 -0.21255 -0.09311067 -0.20092294 -0.17255387 0.15496737 -0.045887556 -0.027998807 -0.09048016 -0.14473289 0.010005052 -0.078703806 -0.09264467 0.020221984 -0.029849876 -0.07063214 0.057339627 -0.21272466 -0.0091771865 -0.12805673 -0.1411145 -0.15000941 -0.0008284621 -0.048972953 0.01006202 -0.09671875 -0.2222921 0.022037758 -0.040400185 -0.124128655 -0.12536745 -0.043420766 -0.20130855 0.038632642 -0.10259119 -0.04797878 -0.15215273 -0.026934214 0.011128171 0.07689659 -0.17522931 -0.0469236 -0.050297417 -0.1576827 0.061215878 -0.07432501 -0.11734915 -0.29013383 -0.18528326 -0.25672036 0.056485176 -0.043204065 -0.0008085718 -0.09993849 -0.33819565 0.36417323 -0.21626173 0.24354184 -0.17688313 0.11646499 0.44407395 -0.12717648 0.17381197 -0.5285354 0.17991889 0.27687582 0.31271666 -0.6197714 0.2366881 -0.024023024 0.06957695 -0.096113615 -0.047747195 0.20987307 0.16810274 -0.035247616 0.086601175 0.030954482 -0.04438845 -0.25589767 0.1812513 -0.08935757 0.22212417 0.06284019 0.50603056 0.26016316 0.4647581 0.04309513 0.38926962 -0.030682629 0.24251395 -0.024374269 -0.048645873 0.29059187 0.02020723 0.012654875 0.09681704 -0.060648758 0.049012076 -0.026214195 0.48428538 -0.27594516 0.33939195 0.05315658 0.35816193 -0.03194048 0.10369053 0.5342068 0.11820951 0.02935778 0.4364116 0.325797 0.18302998 0.11788855 0.29627413 0.010713905 -0.2055095 0.14449069 0.13632864 0.001731506 0.0012536796 0.06255971 0.0680572 0.071608126 0.116462275 0.19317068 -0.09724037 0.18844898 0.1694789 -0.12590279 -0.014300091 0.5286675 0.66196567 0.12522365 -0.19674994 -0.0018337904 0.15075493 0.15118228 -0.06577992 0.117026925 0.08952015 -0.069461964 -0.11297577 0.14926639 -0.09241329 0.34411266 0.5329354 0.059015937 -0.009589634 0.39418846 0.28192407 0.29114106 0.10405132 0.15165538 0.15989432 0.28341588 -0.043307185 -0.13557939 0.040198755 -0.11579434 0.3607482 -0.28846022 0.13362086 -0.07170416 0.026474377 0.2828781 -0.08353126 0.13957222 -0.18126878 -0.15053098 0.394018 0.4612739 -0.016160004 -0.19480027 -0.10905497 0.39308205 0.22906336 0.2649197 0.49630585 -0.01038647 0.09738393 0.13364145 -0.18465202 0.48454767 0.3918648 0.30903605 0.22659972 0.2364937 0.22518933 -0.14927776 -0.0012076976 0.42365608 0.18178219 0.15629993 0.3858495 0.19487421 0.005224272 0.10652727 0.18159994 0.34008783 -0.14053984 0.27640516 0.32872537 0.2575689 0.22044104 0.20907335 0.044553436 -0.18911202 0.38393176 0.208016 0.28738418 0.0951882 0.15486805 0.2714591 0.20779762 0.16950688 0.1432744 0.2110135 0.06380174 0.15734431 0.2851005 0.0005771797 0.029077794 0.20334506 0.14805329 0.14981058 0.10456884 0.016166646 0.23741134 -0.16781817 0.17230242 -0.05135142 0.23199761 0.06860998 0.2709409 0.21748427 0.15468964 0.25009394 0.39707074 0.20532371 0.19716305 0.2390405 0.34720397 0.22894654 -0.32792708 0.2606229 0.16335921 -0.030144472 0.17148747 0.14218296 -0.002461501 0.19655155 0.10858987 0.17031355 0.27609733 0.12145989 0.22706713 0.16644335 -0.05070762 0.105394006 0.32452267 0.00015511326 0.18356672 0.21289824 0.22561304 0.088847846 0.035824057 0.09290157 0.1844516 0.14494792 -0.09438699 0.084051184 0.19864313 0.2598805 0.41187403 0.0686285 0.14271823 0.2969369 0.23332231 0.1150042 0.31548932 0.12940706 0.15736504 0.19859388 -0.06454118 0.058251403 0.1313092 -0.102814995 0.15790111 -0.24515325 0.21443243 0.22763944 0.27068576 0.4222166 0.051320948 0.286971 0.18529128 0.2810597 0.18500146 0.24293108 0.06018624 -0.14758782 0.16236125 0.24315494 0.20180753 0.28258345 0.30146322 -0.0056710024 0.26947546 0.09062033 -0.22062913 0.19676565 0.35312244 0.1870897 0.13445643 -0.10531458 0.12531209 -0.061286774 0.18831581 0.4260053 0.37536702 0.22528315 -0.111837775 0.34125015 0.3435314 -0.01579864 0.14571255 0.08972111 -0.108428545 0.009721911 0.39495656 0.054004773 0.22581895 -0.010424826 0.057697784 -0.14825547 0.25693884 0.019602928 0.18989968 -0.03221017 0.123483874 0.39296335 0.28666514 0.34439266 -0.334138 0.1965298 0.3285568 0.119014405 0.5382847 0.27034253 0.25582206 0.22384477 0.20781678 0.28432596 0.19978026 0.0123389475 0.30266765 -0.36390233 0.22644427 -0.018938199 0.25330007 -0.04112275 0.44348314 0.30633923 0.5482768 0.31230685 0.23259316 0.24108455 0.22571781 0.31605703 0.2970522 0.22356227 -0.2346794 0.35753924 0.18212391 0.0119486395 0.16569461 -0.27889195 -0.060443733 -0.08074836 0.1281594 0.28460017 0.057864234 0.068095535 0.11885159 0.3880663 -0.029075274 0.07539755 0.07007453 -0.11165755 0.2557519 0.1123193 0.10335482 0.19630328 0.010321584 0.2603197 0.1324263 0.30856207 -0.074618466 0.21116827 0.28006443 0.089016594 0.3192898 0.23753782 0.18011251 0.07408172 0.043379 -0.04824055 0.21793383 0.046272058 0.14315668 0.3938951 -0.061425958 0.3233973 0.47887862 -0.06615857 -0.082124844 -0.38694695 -0.109676585 0.1624556 0.15224895 0.417523 0.32816288 0.39084873 0.24994296 0.12320648 0.096628964 0.21925746 0.017674558 -0.095216885 0.32102883 0.065065086 0.017432496 0.13109732 0.10707682 -0.051531695 0.30165106 0.21909681 -0.1318786 0.33238596 0.44257298 0.27654597 0.020733953 0.09609295 -0.04487871 -0.28526592 -0.012787881 0.269156 -0.043637976 -0.008561507 0.30593416 -0.11172709 -0.0026796602 0.13259965 0.15302654 0.010896016 -0.20977835 0.26054376 0.14372168 -0.0012719927 0.23759234 0.10403962 -0.07008565 -0.33749682 0.29572818 0.095107436 0.077326454 0.0024760352 -0.04257982 0.123177625 0.28989854 0.21498612 0.07163761 0.21974202 0.03777569 0.069213316 0.347539 0.14237928 -0.1181976 0.12699114 0.28481692 0.049130373 0.11687467 -0.20476492 0.23560448 -0.29000255 0.18479182 0.047252446 0.23818694 -0.02087957 0.16414712 0.10527325 0.10310331 0.2588096 0.1237412 0.21218362 0.17887719 0.114917815 -0.029289117 0.14574216 -0.33852875 0.1120463 0.27486414 -0.031453207 0.050331656 0.17539504 -0.00028281027 0.03173933 0.24872339 0.09145733 -0.091829345 0.10003756 0.06422125 -0.015583926 -0.13143893 0.234922 0.1579429 -0.03348828 0.020105848 -0.040127918 -0.11480044 0.07053848 0.059639663 0.07239019 -0.0015928614 0.18107915 -0.14687382 -0.020042505 -0.21170135 -0.015076009 -0.20934394 -0.087351754 -0.1070334 0.06431536 0.029128307 0.10835044 -0.034353044 0.11171058 0.19393153 0.20521912 -0.1337519 0.20660311 0.13128039 -0.21889424 0.18413505 -0.33968702 0.20442657 -0.0013204429 0.116160266 0.101159014 0.012795508 0.11250612 0.054218758 -0.17581405 0.17381388 0.3190417 -0.010297555 -0.11860445 0.021598568 0.10169667 0.12966514 0.23121102 0.053430315 0.04408434 0.09735723 0.07731464 --0.075622804 -0.009663358 -0.008456369 0.04637359 -0.012547424 0.012289749 -0.0147922505 -0.09031579 -0.009754119 0.063150704 -0.028468886 0.010632719 -0.011174729 0.016923571 0.030147363 0.008489182 -0.08278708 0.036996637 -0.07636365 0.03783356 0.0054455074 -0.066627905 -0.09452626 -0.06871973 -0.01864097 -0.024758022 0.025218638 0.055285778 -0.064782575 -0.07569462 -0.00841819 0.034139764 -0.00916006 -0.01412847 -0.03604042 -0.028282845 -0.0033774152 -0.08521741 -0.0694063 0.043046724 0.0670585 -0.08915853 0.032508574 0.042869724 -0.04518278 0.051279508 -0.07860646 -0.0774399 0.04390468 -0.10327086 -0.0003654658 -0.03373166 -0.02561061 0.032265224 -0.030462189 -0.00856604 -0.008737736 -0.10025981 0.026785579 -0.021591812 0.011418524 0.024717618 0.0016348098 0.0041598827 -0.023627404 0.027773244 0.039102364 -0.09823539 -0.0010992906 -0.00058480556 -0.07745153 0.05877064 0.0036204616 0.030991428 -0.003442756 -0.0054280725 0.01653751 -0.096872464 0.057173364 -0.05020074 -0.07325503 -0.050434217 0.007825187 -0.026660992 0.026290145 -0.07712084 0.0131484615 0.030984698 -0.08748517 -0.052772574 -0.06866816 -0.07927049 -0.052127127 -0.05778483 -0.05554194 0.021132352 -0.08378234 -0.012579732 -0.05034818 0.04040543 0.049878255 0.017504362 0.026727794 -0.031656574 -0.038297687 -0.043711673 -0.08315865 -0.05763502 -0.03735263 0.009797193 0.0056411913 -0.029630914 -0.01571517 0.070264004 0.0048754304 0.015721012 0.062006798 0.03768371 -0.03862157 -0.007917689 -0.029054858 0.05590473 -0.10116059 -0.09002839 0.010553107 -0.029918741 0.024257433 -0.09544781 -0.3778305 0.61069095 0.12392599 0.38181224 0.08817814 -0.2778511 -0.37532637 -0.023500428 -0.17353418 0.47373003 0.018370407 -0.11396721 -0.12480413 0.2756289 0.20949467 0.29883626 0.030222205 0.2553777 -0.100095116 0.6695427 0.24043582 -0.1699892 -0.06612247 -0.08927465 -0.020844202 -0.26996565 0.37037918 0.362017 0.19936626 -0.01954661 0.01947058 0.25329986 -0.31788215 0.10818054 -0.140694 -0.13104439 -0.1481762 0.30532646 -0.06584906 -0.7222311 -0.18642616 -0.06277581 0.19320604 0.2692183 -0.061888594 -0.031609394 0.21904211 -0.15989405 -0.0609649 -0.15981641 0.2645435 -0.14699385 0.40014586 -0.08655162 0.14132898 0.39354426 0.31139883 0.043047354 0.24520975 -0.01577732 0.3451323 0.54079074 -0.1454859 0.46944156 -0.15306608 -0.11628148 0.25920352 0.25126782 -0.1345152 -0.011437967 -0.035314515 0.17591469 0.223184 -0.026682988 -0.053281702 0.3120986 -0.068541475 0.073222905 0.2338416 0.4482391 0.016352708 0.42659828 0.07368753 0.02444958 0.01913318 0.24375977 0.059978932 -0.57528085 -0.005891576 0.06290725 -0.013872798 0.14675087 -0.2214504 0.62155974 -0.051089652 -0.10776529 0.077206284 0.1906825 0.21911313 0.1747083 -0.02152299 -0.3678653 -0.08782298 -0.026348634 0.007948263 -0.019488564 -0.18661246 -0.43807343 0.27185217 -0.11804317 0.10404115 0.18394713 0.3886514 0.06207907 0.34311345 0.40441385 0.073359236 -0.049069487 -0.023057425 0.019289482 0.26472107 -0.053966254 0.65167534 -0.04350555 0.06540948 -0.07902517 -0.05796209 0.02013638 --0.006317432 0.017169332 0.2570564 0.3706749 0.03620927 0.109160826 0.37952366 -0.09968559 0.26171032 -0.26306996 0.13261735 -0.08493004 0.23850346 0.103835516 0.14765024 0.26278442 0.32230952 -0.14041024 -0.13752541 0.35754654 0.059534013 0.35655004 0.42820263 0.19915205 0.082768664 -0.29246497 0.10829254 0.06593619 0.057607256 -0.06387586 0.26396164 0.052033838 0.12708032 -0.25727612 -0.011101005 0.13029794 0.0010572287 0.1724199 0.06346343 0.23711924 0.035171207 -0.0654664 -0.049301848 0.3675102 -0.016241778 -0.026608879 0.11317363 -0.087431386 0.16196421 -0.07164549 -0.09807307 -0.09333832 0.013949345 -0.100394 -0.26975924 -0.056490354 0.1641127 0.11999922 0.25094837 -0.22449324 0.26171276 -0.014190972 -0.29921937 -0.08975432 0.27096403 -0.13652863 0.076534905 0.35855266 0.06931859 0.1909138 0.29880586 0.061733875 -0.13986541 0.12396501 -0.17109257 -0.0004687279 -0.14143935 0.040110156 0.47212362 0.25397336 -0.0910003 -0.199527 -0.21932861 0.38727602 -0.046867397 0.3321772 0.18329802 0.2074487 -0.019933106 0.24941127 0.22095862 -0.065143876 -0.031785652 -0.1709975 0.112516284 0.19038376 0.061826345 -0.46931905 -0.13454542 0.39076978 0.06451234 0.18548346 -0.10600382 0.24291262 -0.2026627 -0.38617808 0.07927939 -0.34113485 0.07518245 -0.32161325 -0.63335574 -0.023961853 0.007320792 -0.28156728 -0.09197155 0.273484 0.16430134 0.09018512 -0.07971958 -0.32969886 -0.20192555 0.46014258 0.2311912 -0.08310323 0.13025118 -0.051182296 -0.18617676 0.037527893 --0.052746557 0.21984828 0.1911236 0.24404103 0.1527698 0.3122357 0.42286795 -0.29737738 0.32707778 0.049640752 -0.1358356 -0.020755723 -0.021350479 0.3360429 0.3660187 -0.046249527 0.2913059 0.30886385 -0.27452013 -0.03986099 0.16675468 0.11167957 0.20327857 0.09171881 -0.035766665 -0.28757203 -0.22698921 0.14685206 0.09929028 -0.05331974 0.031143505 -0.018196277 -0.044374384 0.13818914 0.4876666 0.43010578 0.10465097 0.06752366 0.22804257 0.5001966 0.07745351 -0.20363179 0.29394686 -0.11928423 -0.010903923 -0.14658411 -0.29453513 -0.17871358 0.028613465 0.0057584024 -0.09388378 -0.108753376 -0.2350358 0.4825197 0.120986894 -0.015978351 0.21052735 -0.119557075 -0.20388159 0.006027864 0.22402643 -0.03438852 -0.36908188 -0.13714345 0.0570401 -0.074751064 0.023684973 0.2179322 -0.0018652076 -0.23911355 0.07589214 -0.16267842 0.20298898 0.41805473 0.35892475 0.2812747 0.059879303 0.23834582 0.17409715 0.14409986 0.39946872 0.042930808 0.23167388 0.33456144 -0.10219917 0.48639646 0.2712862 0.58314174 -0.23006071 0.34604424 0.18547307 0.18206783 -0.18220873 -0.06620091 -0.2967462 -0.6934119 0.13727365 0.41123843 0.11807013 0.1722372 -0.22912966 0.09034227 -0.07183065 0.34641606 0.23450682 -0.13365687 0.284899 -0.1388017 0.2099603 0.24566676 0.28144 0.17481562 0.34330758 -0.003626332 -0.027013795 -0.106431775 0.097918175 0.3758 -0.13759464 -0.32266405 0.2094667 0.066153936 0.40875018 -0.03777554 0.34945112 -0.14244445 0.006109509 0.100056104 --0.08379348 0.04087492 -0.053508844 -0.084422536 -0.004979071 -0.016730107 -0.05520115 0.029782284 -0.02477507 0.01736434 0.04250887 0.023638817 -0.05187866 0.01904032 -0.033867028 -0.031704497 0.010837719 0.04655081 0.011320302 -0.027258374 -0.09144543 0.026734933 0.06915007 -0.016573822 0.016097097 0.028055001 -0.09146446 0.06792634 -0.079506055 0.0044524954 0.007315515 -0.07524372 -0.015535601 0.05870863 -0.074809395 0.07698853 0.014623296 -0.09469627 -0.08407878 -0.07756267 -0.02624107 0.008144251 -0.045608208 0.0014337298 -0.007881865 0.008267113 -0.035879638 0.056597024 -0.033127915 0.05862586 0.059174195 -0.06682329 0.024607675 0.046614524 -0.09221592 -0.0037204195 -0.08243222 0.002083513 -0.05525139 -0.07707335 -0.0041967197 -0.09517863 -0.079025544 -0.04158541 0.014735649 -0.07402049 -0.016497338 0.040185917 -0.017050933 -0.047583893 -0.021503242 0.07154633 -0.065710194 -0.07717611 -0.010717589 0.0060353703 -0.03197191 -0.08130745 0.04868927 -0.02440943 0.0036387146 -0.07933879 -0.01786151 0.03817404 0.014479672 -0.062443305 0.031011302 -0.035284724 -0.07371512 -0.0339541 -0.008800049 -0.04773056 -0.01939577 -0.024655376 -0.07423365 -0.050965726 0.07084181 -0.04672135 -0.022168608 -0.066001914 -0.06951309 0.05593851 0.013611371 -0.038168296 -0.06713491 -0.06464372 0.065918036 -0.100994386 0.050514944 -0.036461666 -0.034466527 -0.08043366 0.016118353 -0.015436431 0.026439443 -0.06334798 -0.09271836 0.061781697 0.013283066 -0.012199084 0.048622075 -0.055780444 -0.002337281 -0.07578219 -0.044358935 0.03295553 0.054855857 -0.007884625 -0.40581304 0.26810616 0.5674228 0.4865312 0.07365437 -0.04979349 0.004499853 -0.25476837 0.26465648 0.17469262 0.43123105 0.16369504 0.40168542 0.3447413 0.21253031 0.4394 0.19636102 0.1409204 -0.28682625 0.14043924 0.56900585 0.2241623 0.0073507642 0.16910061 0.061572757 -0.43573126 0.41901055 0.65109825 0.21379153 -0.012880652 0.29879424 0.1833414 0.40464264 0.047787093 0.053269584 0.2939868 0.4529507 0.2748519 0.48853666 0.17851388 0.2634313 0.17925465 0.36505535 0.5669879 0.10759137 -0.19757017 0.3149464 -0.49847385 0.23970804 -0.04883773 0.32115757 -0.05555463 0.19091152 0.22972322 0.41599178 0.32903138 0.07946427 -0.02899983 0.41671598 0.01657571 0.22837166 0.5214218 -0.39463857 0.2364252 0.33812606 -0.00021347696 -0.09186736 0.44400626 -0.14920768 0.355972 0.04062087 0.26897728 0.1511219 -0.01013863 0.0073152683 0.03429441 -0.297926 0.28442195 0.08083615 0.22537164 0.104821414 0.043792315 0.14045244 0.23884504 0.047620364 0.5371769 0.18455942 0.2368937 -0.28530636 0.19211444 0.043570545 0.12613022 0.26341707 0.26876336 0.16329008 0.15763128 0.1973189 -0.037444096 0.25773558 0.301671 0.2575757 0.23322205 -0.33992043 0.2849338 0.04437526 -0.31321207 0.3638923 -0.42042813 0.058495156 0.09621311 0.123682916 0.13206744 0.46883723 0.06155516 -0.05434412 0.18529516 0.41569582 0.33648267 -0.0071839243 -0.24427554 0.48145026 0.16591845 0.1795416 -0.09742759 0.48380217 -0.11959085 0.15184091 0.12296751 -0.09518256 0.37668696 0.20948072 0.015287706 0.46392837 -0.08785665 0.20665699 -0.032246027 0.35721317 0.28995386 0.13103361 -0.08052522 0.46764314 0.39977425 0.10119007 0.38547173 0.19140457 0.41565296 -0.30981857 0.052172203 0.35393712 0.13480277 0.2693387 -0.016100695 0.0065126484 -0.1647522 0.28180838 -0.034355845 0.4757708 0.061674938 0.42219853 0.058345567 0.19724005 -0.03172595 0.36293325 0.28051725 0.14124545 0.10927052 0.30368534 0.112179235 0.1217135 0.20541866 0.16710123 -0.30840832 -0.1667255 0.0032133278 -0.18404117 -0.21582863 0.3531743 -0.0025668852 0.026518375 -0.035855714 0.2614439 0.17424966 0.328449 0.5984582 -0.1278654 0.08474217 -0.19918497 -0.17299613 0.3677829 0.25581056 -0.12167009 0.1338529 0.096129246 0.010778331 0.11795423 0.1883123 0.02611627 0.38865998 0.061574392 -0.0113758575 0.2832137 0.5400016 0.10045192 0.042359717 0.0069065443 0.24897602 0.09391121 0.09994877 0.31974086 0.10831973 0.18505529 -0.049476527 -0.06957059 0.43103054 0.18958521 0.2863956 -0.30305827 -0.038150225 0.5286073 0.2946112 0.5174446 0.2270646 0.23128581 -0.094016224 0.3008463 0.43119928 0.22991177 0.22592689 0.007989965 0.08184761 -0.054738726 0.1156104 0.022136493 -0.017944619 0.23992771 -0.18898492 0.15984677 0.29875422 0.1573685 0.38701025 0.16518009 0.12728015 0.32386488 0.39947307 0.19623715 0.29843658 0.061993103 -0.102879114 0.014526345 0.16834864 0.15260468 0.25048047 -0.026176646 0.05860718 0.15993063 0.059245963 -0.13477515 0.3377304 0.35907996 0.27041546 0.3201007 0.25889477 0.07666355 -0.07658821 0.1928566 0.40393987 0.12060137 0.22689727 0.32825422 0.22923891 0.2514062 0.32435265 0.14077196 0.15064135 -0.1584208 0.2523283 0.12787555 0.17930475 0.2004745 0.18937257 -0.015384986 -0.25558004 0.32143638 0.38025513 0.11736223 -0.04746897 0.35206386 0.2118295 0.33431187 0.23243977 0.21322462 0.20467363 -0.024395457 0.08284355 0.18759938 0.35636324 0.41866612 0.12035525 0.2580057 0.2542241 0.20690207 0.067223184 0.1924268 -0.21215108 0.21349843 0.023373941 0.32520252 -0.0486601 0.30126742 0.31917185 0.16749746 0.3100582 0.32854673 0.17011937 0.23190528 0.15413746 0.1481002 0.15890291 -0.31349555 0.2501345 0.24315105 0.026909834 0.24251013 0.26268306 -0.03801671 0.22529387 0.32522732 0.15854804 0.066685215 0.28194395 0.22853698 0.3230886 -0.032880932 0.27703625 0.3331686 0.21342136 0.10900299 0.20579381 0.23746756 0.21767241 0.041618913 0.29821426 0.11047305 0.36169663 -0.1536975 0.28886124 0.21519436 0.20162918 0.4262492 0.380171 0.21385701 0.29026362 0.2066497 0.3229864 0.1319003 0.06147603 0.0060505904 0.25549042 -0.096005335 0.26858324 0.19260271 -0.08023738 0.20632428 -0.34917575 0.16847046 0.2339302 0.18889685 0.17347123 0.2074829 0.15367489 0.20891231 0.34426114 0.27367392 0.2564355 -0.09583603 -0.031846087 0.2391837 0.1329699 0.33342418 0.27241182 0.21886627 -0.04054641 0.29197297 0.12423782 -0.35393825 0.39645606 0.592987 -0.15223004 0.41700393 0.47493747 0.32372224 -0.20905647 -0.05664529 0.11107042 0.13019404 -0.054704636 0.44707513 0.17168257 -0.042440113 0.09678743 0.23090895 0.15895626 -0.14778642 0.0937771 0.3137876 0.16335902 0.039900064 -0.16902031 0.08105147 -0.17552716 0.34424874 0.25846854 0.00392884 0.012563791 0.21755852 0.2417692 0.16727608 0.22317076 0.018002586 0.2373457 0.17422223 0.15432432 0.44675794 0.2613367 -0.12915389 0.24323928 0.20751403 0.21210478 0.23496148 0.042786628 -0.2255186 -0.23543651 0.6172816 0.014077654 0.28690523 -0.00021729576 0.25913796 0.27771908 0.16923082 0.040978625 0.09310878 0.28232506 0.06150354 0.17972471 0.23035377 0.4617699 -0.37870947 0.15227693 0.035789087 0.023547558 0.29103276 0.25969294 -0.10034715 0.4179267 0.37023196 0.26363784 0.23459992 0.35040787 0.08468239 0.3095666 0.02426383 0.04030316 0.06251318 0.17178263 0.13690884 0.15907013 0.014308604 0.07101339 -0.074322365 0.16247825 0.27183175 0.3317256 -0.084744096 0.4708347 0.18462743 0.20155983 0.3117959 -0.21579778 0.0393619 -0.031722166 0.034098916 -0.15670644 -0.024751171 0.42602405 0.1681049 0.3955303 -0.032096095 0.04362372 0.16152434 -0.0048185242 0.3003904 -0.24590616 0.15196434 -0.22167718 0.2600465 0.21130581 0.2553743 0.18984243 -0.021628147 0.074764706 -0.11302323 0.5617867 -0.02504267 -0.19234811 0.0729524 0.18718252 -0.17405857 0.19840874 0.1510434 -0.055633515 0.32724863 0.19780466 -0.40682858 0.38352707 0.07914323 0.009829304 0.14327021 0.5304619 -0.08800668 -0.25822487 -0.037194945 0.5399032 0.47894496 0.18740006 0.36937463 0.2054931 -0.09656801 0.2004657 0.14389673 0.19915928 -0.21071038 0.26087356 -0.4952502 0.2632233 0.057642885 0.250518 -0.027219085 -0.26559836 -0.09484236 0.37805638 -0.13226624 -0.25320414 0.24764428 0.040049113 0.093891114 0.22396354 0.31038302 0.0061721425 -0.06486725 0.23714694 0.09118693 -0.033459928 0.11593257 0.21812887 0.22851492 0.19498996 0.47694492 -0.16126762 0.12350092 -0.30706152 0.3049804 0.054296114 0.03232443 -0.014577307 0.3829047 0.16398348 0.07617817 0.036739744 0.49142733 0.23066743 0.228919 -0.06121124 0.027281007 0.14349487 -0.35644028 0.2049019 0.07387678 -0.13152719 0.38678128 0.32017902 -0.26882264 0.040847596 0.116739236 -0.046321075 0.35891688 0.07397558 0.21863382 0.19167884 -0.10445351 0.09606338 -0.64568305 0.11919047 0.015293664 0.38751474 0.33401948 0.34343937 -0.25825715 -0.050813742 -0.25756595 0.32590955 -0.23968266 0.2380248 0.23028784 -0.037125774 -0.1471825 0.21880883 -0.31955695 0.045931876 -0.013113277 0.016265504 -0.044629987 0.051051702 0.051046167 0.090975665 -0.19562939 0.26898018 0.3046096 -0.14036393 0.22778137 -0.25249922 0.18095465 0.18094896 0.5151494 -0.11581218 0.20551488 -0.111680955 0.16512032 0.19109686 0.093483225 0.07289195 0.036902677 -0.22736546 0.5050323 -0.25968012 0.45049554 -0.09656298 0.61347 -0.1424887 -0.26758373 -0.08588675 -0.10736618 0.24692583 0.06524911 0.42920917 -0.2655319 -0.06596387 0.38812461 -0.109593384 0.14762545 0.36813843 0.14274277 0.25480875 0.30400696 0.23700105 -0.010644764 0.20228033 0.18876363 -0.4509011 -0.16226806 0.0036955862 0.39582592 -0.040505577 0.027098494 0.018320717 0.05714884 -0.27907485 0.3110262 0.27883974 0.25936922 -0.078742 0.109290555 0.19415519 -0.16976051 0.03124228 0.3894296 0.16855134 0.48112553 0.30477518 0.45571432 0.064677656 -0.42140394 0.3318262 -0.20381118 -0.045079805 0.22580098 -0.025401607 0.2627118 -0.22524342 0.46022448 0.012100591 0.3760237 0.01260672 0.1270964 0.37987593 -0.34110612 0.25404721 0.19060567 0.14205165 0.031692166 -0.18939649 0.27963945 0.24016812 -0.15716298 0.011075612 0.0045054415 0.07389814 -0.21073702 -0.12666683 -0.0001986895 0.41795483 -0.098844156 -0.09304921 0.4610182 0.27348515 -0.34833634 0.23380877 -0.12252682 0.27346447 0.025986955 0.11130265 0.22250527 -0.01466469 0.16483906 0.29899088 0.044641826 -0.009558632 0.087242216 0.314107 -0.04577585 0.09835272 0.35467178 0.3893738 0.03377842 0.037323564 0.05661172 -0.11788783 0.338591 0.22820422 0.1707369 0.28085908 0.37546453 0.42772 -0.23827085 0.12035879 0.06466916 -0.153788 0.43632817 -0.20893651 0.16087638 -0.0530436 0.34748435 0.24178036 0.21944669 0.051719353 0.33816493 0.46531057 0.3402778 0.31300962 -0.08635716 -0.13615382 0.2149978 0.043037448 0.06252546 0.40530172 0.21896286 -0.053208552 -0.027647631 0.36314484 -0.04317351 0.050866254 -0.09401015 -0.015570616 -0.021605786 0.038959693 -0.04573168 -0.088944525 -0.0033477533 -0.011536237 -0.05065736 -0.0020503637 -0.07783819 -0.06066176 -0.08730546 -0.06574403 0.048798162 -0.052761734 -0.06377185 -0.030553374 0.05041548 -0.020023508 -0.049428396 0.020231048 -0.017415458 -0.0733036 0.023751985 0.05084634 -0.04461001 -0.029731872 -0.042914037 -0.019125698 0.0013968964 0.031178543 0.023795629 -0.07935334 0.056846946 0.019274155 -0.0018149856 -0.063519284 -0.06211241 -0.002584571 -0.060778704 -0.011945856 -0.02378283 0.042144626 -0.024600182 -0.019560322 0.057192657 -0.010837162 0.032401476 -0.061824515 0.02311909 0.015647365 -0.023038486 0.070793346 -0.048272535 -0.0688704 -0.008025185 -0.04469603 -0.06952268 -0.018700693 -0.013646144 -0.028795458 0.00992879 -0.010886345 0.06610266 -0.07694363 0.019706067 0.070454866 -0.0511288 -0.055632293 -0.005610277 -0.0833136 0.04068762 -0.055169284 0.03621193 0.06234177 -0.033700544 -0.081195645 0.06193828 -0.08493394 -0.07774774 -0.03305011 -0.00755386 0.036277056 0.06145921 -0.07338625 -0.088979214 -0.049846034 -0.051813286 0.029945232 0.06464869 -0.006261658 0.060884383 -0.035699945 -0.015574267 -0.055767544 -0.07614011 0.022934934 0.036162663 -0.056933414 -0.062743194 0.06955175 0.029715937 0.029889047 0.06677176 -0.07141069 0.0015513632 -0.033887703 -0.06704826 -0.07341748 -0.036046598 0.018522145 -0.0036035718 -0.077190064 0.0012656925 -0.087410524 0.033040605 -0.069122344 -0.0038207623 -0.077408075 -0.088640176 -0.07679953 0.060931884 0.07203704 0.013571388 -0.02657993 -0.20747255 0.23775949 0.27521494 0.25850233 0.27273348 0.2962308 0.18109 -0.02024708 0.26535198 0.38383493 0.17053257 0.2772971 0.31771532 0.17544287 0.0961572 0.2479843 0.187358 0.13078746 -0.24586447 0.20852499 0.19658728 0.2100018 0.16695139 0.2590832 -0.024795149 -0.22247669 0.29929718 0.12830073 0.14160323 -0.013118539 0.2725717 0.19110106 0.21514492 0.21512988 0.12890497 0.19359137 0.2296369 0.11756733 0.25273138 0.19230743 0.29756224 0.21349059 0.13029084 0.16915035 0.13307197 -0.039170418 0.27763265 -0.31225264 0.09323214 0.033104222 0.26473773 0.055374075 0.26535788 0.29078174 0.22431152 0.31294397 0.27006343 0.1339398 0.11570836 0.022185171 0.2608665 0.23050912 -0.2642089 0.1848656 0.25408557 0.01948965 0.14447291 0.14481848 0.093490094 0.2112784 0.27057296 0.2632455 0.26092112 0.21196954 0.20361322 0.3093042 -0.0068185716 0.20764016 0.21777245 0.18908678 0.17301503 0.23286301 0.23143297 0.23105264 0.05478056 0.19832683 0.16284886 0.25549218 -0.021315008 0.13789496 0.25038645 0.288663 0.39313704 0.22626439 0.21479343 0.25638655 0.21097198 0.21119134 0.23062447 0.22710629 0.22218543 0.2503661 -0.11465278 0.17584155 0.26647684 0.008479123 0.3024445 -0.30646876 0.15111305 0.10591463 0.25669023 0.22599006 0.15205027 0.24491428 0.17993987 0.19656388 0.245523 0.28069064 -0.045095656 -0.13769665 0.21066473 0.17215607 0.3147568 0.19645178 0.33955938 0.029794022 0.17149177 0.20001782 -0.3164696 -0.23977068 0.44650394 0.47550017 0.43778127 -0.1488479 -0.018831208 -0.25966606 0.18111004 0.484197 -0.6914809 0.097443946 0.18980546 0.28993964 0.24347514 0.30686718 0.09085731 -0.2874326 -0.23888935 0.22402003 0.43772826 0.058738347 0.41092733 0.3986888 -0.03266246 -0.335428 0.17908281 0.19607092 0.3662582 0.004162991 0.22048141 0.16623417 0.39058977 -0.29587576 0.15046754 -0.20945923 -0.14293766 0.5417499 -0.22942126 0.17454448 0.10724359 0.2118236 0.37258947 0.24090366 0.126369 -0.0824055 0.040107794 -0.19369535 -0.17683437 -0.09919535 0.016316056 -0.0896849 0.18390927 0.04274808 0.25773752 0.5074639 -0.22668561 -0.3559749 0.012383562 0.10551479 0.10777218 0.129227 -0.16396955 0.055727713 0.06093093 -0.12674811 0.0010070846 0.22505042 0.05173576 0.1791553 -0.21473561 0.16157202 -0.23227476 0.3238712 0.010903647 -0.33465263 -0.25090408 -0.052905597 0.029486192 0.23817916 0.4206987 -0.09656524 -0.04253999 -0.29415634 0.06035388 0.34324685 0.23360088 0.22431917 -0.060616072 0.2667888 0.4877703 0.08962669 0.2994207 -0.009796739 0.26934582 0.011935859 0.22591788 0.14033929 -0.11064442 0.15835269 -0.11039519 0.429636 -0.07924072 -0.1676312 0.034363672 0.009604919 0.076637395 -0.25447524 0.39442113 0.18262374 0.17324565 0.37733898 0.4400524 0.476012 -0.11528486 0.46026227 -0.11117295 -0.3569678 -0.0052505624 -0.23449592 0.017651714 0.2937664 0.044823214 -0.20442463 0.37727648 -0.09991414 0.22226596 0.098003924 -0.060341243 -0.053802382 0.022953687 -0.084859714 0.04754698 -0.06809884 -0.024854345 -0.12364072 -0.015094239 -0.041719586 -0.08678062 -0.051230624 -0.07447863 0.023567325 -0.051293045 0.04084198 0.06689582 -0.039935883 -0.028611109 -0.016272083 -0.023310319 -0.016481664 -0.08057687 -0.005010532 -0.027478123 -0.06109277 -0.05702683 0.0062443516 -0.005485127 -0.06992478 -0.070061006 -0.04093039 -0.040621012 -0.05968563 -0.10145531 -0.010329793 -0.08826138 -0.047793843 -0.11728703 -0.01492567 -0.041312285 -0.0194772 0.03706274 -0.049531136 -0.04228936 -0.009829281 0.0027425487 -0.01936008 0.057638932 0.01333993 0.014615936 -0.01686189 -0.0116236145 -0.03298471 0.04695556 -0.0101938965 0.025784975 -0.051679198 -0.13051176 -0.12598656 0.04912078 0.033991814 -0.05034384 -0.063483976 -0.014965545 0.0022905213 -0.045575332 -0.039755072 -0.016331775 -0.08772349 0.06602946 -0.057783503 -0.07120711 -0.10052105 -0.029719308 -0.082785055 -0.08384373 0.046062518 0.07040444 -0.0107476665 -0.0924473 -0.048758887 -0.054247458 0.027867591 -0.079106174 -0.097017035 0.016857153 -0.021758545 -0.036120884 0.064899415 -0.06627571 -0.10127776 0.010763498 -0.094521366 -0.03630048 -0.12926422 -0.06120398 0.04517158 0.023798157 0.04193722 0.060592044 -0.008030253 -0.073696524 0.012953138 -0.09182903 -0.0011417352 -0.04367352 0.017688049 -0.0012922102 -0.06351826 -0.03690675 0.010483535 0.06276206 -0.05493008 -0.04927732 0.017430916 0.047780477 -0.1156097 -0.06188295 -0.08221885 0.049517192 0.03878426 -0.06467457 -0.104410745 0.033567026 -0.08966292 0.0015074048 -0.062772565 -0.09294325 0.13074721 -0.0024455178 0.013068413 -0.016524361 -0.005044529 -0.08707218 -0.08689508 -0.067761265 -0.07233448 0.11592113 -0.040453415 0.081738666 0.037668303 -0.14737293 0.09725135 -0.06505066 -0.10424817 -0.18319985 -0.17305206 -0.05076932 -0.12734364 0.034517683 0.13248573 -0.08514529 -0.042666644 -0.14089938 -0.006152821 -0.14731784 0.030822352 0.049987856 -0.010411128 -0.050835744 0.04713192 -0.036065474 -0.032924064 -0.04507039 0.06393639 -0.14770131 -0.102246925 -0.050642252 -0.07239978 0.08608024 0.12124991 -0.068726145 -0.043460455 -0.0015818571 -0.17847444 0.09299227 -0.04959876 -0.026900824 0.041061327 0.02216946 -0.07089213 -0.11736837 0.030595213 -0.022103954 -0.1282896 -0.023621 -0.17476557 -0.0575064 0.053382836 -0.04798611 -0.05259104 0.059820183 0.06431896 -0.019366898 -0.15455945 -0.012308975 0.008169634 -0.033419237 -0.10053575 -0.109555915 0.06679072 -0.07065554 -0.018549295 -0.11358065 -0.11924408 0.023398792 0.13845499 -0.10644347 -0.03583629 -0.06789605 -0.069173716 -0.09882588 -0.10521099 -0.05656572 -0.08500578 -0.11988434 -0.081090145 -0.13089183 -0.035563763 -0.06346429 0.090284914 0.03366332 -0.060038112 0.00038380618 0.07042032 -0.1303234 -0.13403407 0.039097205 0.11204634 -0.20951255 -0.13453375 -0.05277072 -0.15653388 0.07721461 -0.16240698 -0.044450503 0.030109594 0.13852581 -0.043270268 -0.08170893 -0.007819557 -0.12244827 -0.12441036 0.0063879183 -0.08417148 -0.035440173 -0.09081391 -0.0037092394 0.04646768 -0.07848522 0.082429886 -0.11832572 -0.030137494 -0.1798684 0.003993938 --0.013277825 -0.2840564 -0.10766828 -0.03729827 -0.043097753 -0.1552881 -0.112943366 0.027586859 -0.07901176 -0.2730486 -0.103876755 -0.14293161 -0.25217384 -0.11891876 0.052783534 -0.06955262 -0.021702217 0.0042831567 -0.007797045 -0.16298243 -0.12084232 -0.19276541 -0.0075397925 -0.052818917 0.024579464 -0.042443458 -0.2466092 0.08729405 -0.24004574 -0.05494037 -0.1401013 -0.06717212 -0.11588542 -0.094016396 -0.04364251 -0.19733876 -0.07628982 -0.20558196 -0.06294914 -0.17951474 -0.076459214 0.038397077 -0.071708865 -0.28269833 -0.12903813 -0.07257717 0.001468215 0.18448873 -0.046592873 -0.041008238 -0.24494755 -0.0851462 -0.23540412 -0.029335253 -0.16397262 -0.062391445 -0.19296148 -0.028835824 -0.033057496 0.10912157 0.029164607 -0.095251784 0.104328424 -0.08369296 -0.022795161 0.035642453 -0.06423286 0.02927259 0.09329259 -0.097203985 -0.18841586 -0.19795462 0.0021258546 -0.111256815 -0.14915091 0.035382606 -0.117002316 -0.29445788 0.07201173 -0.059073 0.024481867 -0.03413752 -0.069681294 -0.18381199 0.059583068 -0.117318176 -0.062289618 -0.21404988 0.015988022 -0.16297548 0.10843836 -0.2322134 -0.21880524 -0.15662594 0.02327794 -0.21291864 -0.11621259 -0.005369499 -0.09283185 -0.17385727 -0.11590879 -0.14458728 0.030744174 -0.12668946 -0.044690523 -0.1442731 -0.15013368 0.08422522 -0.18631913 -0.11186162 -0.097538345 -0.008634751 -0.097552136 -0.13572657 -0.15255813 -0.028170466 -0.06163155 -0.15756343 0.115762554 -0.019664528 -0.048005857 -0.09438675 -0.060750566 -0.1898546 -0.22521956 -0.10361497 -0.00073095266 -0.16700095 -0.014227125 0.3115541 -0.10448247 0.25926968 0.019400137 -0.13303986 0.09735336 -0.056843657 -0.01033929 0.4357192 0.40039566 0.24748152 0.2682654 0.44649094 0.114710316 0.17268574 0.29425514 -0.19541505 -0.29439446 -0.2030173 0.3187358 0.1283278 0.09000062 0.3295372 -0.074149325 -0.24190125 0.27615058 0.259361 0.23000085 -0.014451416 0.47585225 0.20303036 -0.14777943 0.23576769 0.012743123 0.06801652 0.32012847 0.114060566 0.018494304 -0.21862632 0.16719802 0.064533554 0.21895863 0.35203832 0.28188038 0.15980954 0.3942305 -0.27993187 -0.25524655 0.017817693 -0.09684343 0.094038755 0.49225497 0.37159494 0.044482544 0.123772606 0.32047215 0.016263304 0.18938607 -0.029322788 0.0268926 0.286123 -0.08792742 0.4243803 0.025356382 0.032593455 0.007911766 -0.012838726 -0.045425303 -0.018318478 -0.31004503 0.027857186 0.117086805 -0.29222214 0.22454897 0.3004968 -0.10494757 0.35430416 0.10861614 0.18751727 0.06129428 0.22356711 -0.3509894 0.39386424 0.064306125 -0.09331341 0.09998189 -0.3295697 -0.06303273 -0.043553248 0.19685026 0.17812711 0.33015332 0.4730274 0.18069714 0.16660015 0.22546561 0.25525177 0.045431506 -0.023918549 0.056466077 0.22876994 -0.09568647 0.041366056 0.18553123 0.003454394 0.2271768 -0.26940978 -0.02560409 0.40779647 0.047162488 0.030818025 -0.06444585 -0.025659462 0.030583415 0.2671783 0.2378663 0.22364877 -0.023620982 -0.21773721 0.3121657 -0.04478994 0.1584173 0.20822075 0.44454953 0.021728463 -0.07000164 0.0050058975 --0.046987172 0.07390328 -0.0907921 -0.22385575 0.045392036 0.10758091 0.30520344 -0.16537474 -0.040107243 -0.22596787 -0.04392603 0.029094217 -0.05910545 0.12358048 -0.13522395 -0.042211186 -0.095191516 -0.017538108 -0.16223179 0.1073988 0.20159474 -0.12282031 -0.07564468 -0.17525406 0.033629004 -0.2099051 0.07809469 0.14274594 -0.36674595 -0.11204031 0.08443205 -0.15042919 -0.055384625 -0.11905226 -0.0634276 -0.048626624 0.1444103 0.003494489 -0.003683582 0.06815153 0.07443811 0.10038908 -0.16563787 -0.16285615 -0.23323481 -0.100489885 0.1907258 -0.22854178 -0.056208834 0.031763956 0.08917389 0.007904389 -0.034635473 0.077610046 0.1629842 0.09890668 0.037648544 0.13674057 0.053579163 -0.0037918033 -0.014490776 0.11280053 -0.17409419 -0.17270751 0.091662765 -0.045551244 0.05277637 -0.0048585054 -0.105594 0.22173446 0.18568131 -0.03281852 0.3011829 -0.0829009 0.027302336 0.22240657 -0.06263518 0.11752519 0.117283955 -0.018783553 0.004253754 0.023856133 -0.057261452 -0.27608797 -0.045837305 0.07224412 -0.17003323 0.19902849 -0.10991217 0.12256227 -0.03513749 -0.02312814 -0.017762622 -0.017555721 -0.006709435 -0.0044780946 0.13814643 -0.01232844 -0.14485532 0.109431766 -0.014714872 0.107646935 -0.09316956 0.11525923 -0.1244404 -0.19601497 0.17457865 -0.08001053 -0.041168105 -0.058019824 0.14967698 -0.17281148 0.049905747 -0.06423236 0.01593801 0.220359 0.043989692 -0.116945885 -0.008957748 -0.111511216 0.24356782 -0.014775516 -0.16339777 -0.016290803 0.017183822 0.011507672 0.060775343 0.22838686 -0.20427872 -0.5677402 0.17847088 0.39355782 0.34840485 -0.21188962 0.13168167 -0.20466097 0.1457134 0.32922164 0.42636657 0.31765333 0.1589745 0.27837276 0.19270237 0.2175927 0.36260474 0.15721376 -0.26171097 0.09724512 -0.24232903 0.08454565 0.020359647 0.1625646 0.108529985 -0.29462293 0.4007335 0.27356118 0.4123979 -0.08321913 -0.07914168 0.14294614 0.11360765 0.35326105 0.30633396 0.14531238 0.33086666 0.29222277 0.31395552 0.31229618 0.35797748 -0.38541934 -0.1667915 0.17162609 0.42548296 -0.1684699 -0.0043449453 -0.26315457 -0.13851973 -0.14225945 0.4289745 0.057007182 -0.08102599 0.42051968 0.18545341 0.15325913 -0.1119857 0.17846628 -0.3856971 0.1551962 0.30554608 -0.08922477 -0.3130382 0.2558885 0.17437391 -0.09101118 0.09010467 0.3932264 -0.04079132 -0.111018136 0.00897988 -0.12881519 0.34650877 0.050936356 0.15996678 -0.455646 -0.041844856 0.37948918 0.3724402 0.0026286065 0.13753456 0.3112534 0.105737776 0.16869336 -0.120122164 0.31154013 0.15193802 0.42971617 -0.13974503 0.19565415 0.28431377 0.0036206038 0.10731645 0.07677738 0.33279842 -0.12302181 0.13533919 0.3426865 0.36177692 0.19670108 0.18831147 0.09500973 -0.14402145 0.47236553 0.03256489 -0.097578 0.23222768 -0.23786685 0.09564466 0.29410255 0.3926067 0.28481302 0.14920892 0.102821894 0.397979 0.5356176 0.5576618 0.016906891 0.08157619 -0.17391428 0.25865528 0.012209198 0.39029336 -0.14073074 -0.116092436 -0.014966637 -0.33301744 0.19078006 -0.035767518 0.08862213 -0.22713648 -0.18994382 0.22761555 0.37100595 0.5885138 -0.105718665 0.13345048 -0.010393797 0.3519682 0.13359022 0.31876978 -0.21554373 -0.02658805 0.2599991 0.24233936 -0.041851353 -0.06691142 0.28401738 0.40024468 0.0023721498 0.16252224 -0.01379832 0.06373184 -0.3421501 0.6069304 0.0027243262 0.2306469 -0.09408809 0.16402362 0.26731098 0.35154897 0.23901859 0.508301 0.027355382 0.10185891 0.26560482 -0.06362358 0.3628409 0.35483977 0.06354372 -0.36110368 0.11712354 -0.12258162 -0.13582851 0.23049349 -0.2068826 0.0660921 -0.07005208 0.08121082 0.038634043 0.21752982 0.074380904 0.03822559 -0.047226675 0.5895793 0.20645109 0.2675392 0.13623972 0.1256958 0.38451552 -0.4335387 0.024360755 0.03988295 -0.067043744 0.2926473 0.1604094 -0.008232008 0.120053254 0.32062215 0.34633034 0.27461785 0.297155 0.17591278 0.14536315 -0.015976338 0.2744093 0.40444914 0.11923163 0.16862899 -0.03768328 0.4013678 -0.031854637 -0.10776657 0.21362312 0.052225295 0.02440798 -0.0980192 0.18569528 -0.098233834 0.17485462 0.4852832 0.052145757 0.13649392 0.1642933 -0.08210369 0.42257 0.30406603 0.09468728 0.28700966 -0.084791966 -0.24551995 -0.18084863 0.16686054 -0.20078808 0.20668414 -0.2702943 0.1992128 -0.074260764 -0.08038262 0.45237502 -0.080961496 -0.1319439 -0.022603597 -0.08096737 0.33114904 0.30066606 0.080271296 -0.2694709 0.0518443 0.25833023 -0.27300066 0.20119193 0.26617312 -0.0077483463 0.56406975 0.079225175 --0.078799635 0.051722843 0.04431378 -0.025842376 0.07217434 -0.0840839 0.0054693124 -0.02368654 0.009048011 -0.074468315 0.012754753 -0.093831874 -0.01040381 -0.07239046 0.0062174955 -0.09235448 -0.044509344 -0.0995099 -0.09059859 -0.035165492 -0.06367979 -0.06785678 -0.10403614 0.024210697 0.0017999231 -0.013831044 -0.05557882 -0.027608013 0.018444246 -0.074043356 -0.04008653 0.00368783 -0.07339745 0.01105418 -0.052134067 0.039518468 -0.010579982 -0.04232429 -0.09624107 -0.03604768 0.03684525 -0.059454147 0.049840428 -0.079039186 -0.02346512 -0.08462482 -0.098202914 -0.06842929 -0.071514525 -0.052362222 -0.034342434 -0.08833861 0.046862226 0.030597571 -0.071906686 -0.08237308 -0.025228217 -0.07835359 -0.054236867 0.026110254 0.014895689 0.025824893 -0.03433171 0.05660191 0.011379456 -0.10273065 0.00912468 -0.057449553 -0.08911222 -0.097372964 -0.10278984 -0.037309222 0.034970544 0.07002104 0.000654592 -0.08252658 -0.09362385 -0.0039513223 0.042102754 0.067769185 0.051266614 -0.051660176 0.034304854 0.031534906 0.028150925 -0.05085854 0.01763793 0.04376505 -0.008240279 -0.05129197 0.0053613693 -0.072749294 0.023791356 0.04835565 0.065825835 -0.07387315 0.06283738 0.06762692 -0.08380268 0.05879346 -0.007967339 0.04444087 -0.040290195 -0.08404743 -0.018697243 -0.112685345 -0.0159761 -0.12597115 -0.08140568 0.04117809 -0.069309555 -0.06797063 -0.036349747 -0.09671232 -0.09210743 -0.027690195 0.025174422 0.030660903 0.0668533 -0.120074466 0.06881865 -0.10173161 -0.09180034 -0.09063314 -0.053378895 -0.021644374 0.011331657 0.01201329 --0.044698443 -0.05483551 -0.08408594 -0.06928788 0.026728155 -0.04913295 -0.016313462 -0.002547193 -0.058405615 -0.08934493 -0.03602872 0.033334948 -0.11726453 0.046869833 -0.03970815 -0.07189368 0.011560292 -0.056945637 -0.11471384 0.14678253 -0.061730906 -0.0075075123 0.053130835 -0.05827557 -0.042398702 -0.10306325 0.0007707475 0.001616205 0.028794514 0.05325448 -0.0037555795 -0.0005675498 0.09766771 -0.12659627 0.08982792 0.06793043 -0.007515866 0.07469212 0.04996982 0.03187496 0.045201693 -0.009044893 0.020704368 -0.055643693 -0.13146456 -0.08851759 -0.034678806 -0.089826785 -0.0011297857 -0.06940593 0.046355706 0.044999648 -0.06611465 -0.013019951 0.023229772 -0.076691225 0.11311106 0.04985318 -0.015361886 -0.018797807 -0.026008718 -0.06679218 -0.13490804 0.029116368 0.009519814 -0.03436306 -0.012394124 0.01666716 -0.075069934 -0.003534309 -0.005325299 0.036876682 -0.045202672 0.04294657 -0.03626442 -0.058768082 -0.073699 0.03099328 -0.05811097 -0.06902103 -0.0075681033 -0.033712413 -0.047379714 0.052197177 0.0056767077 0.099293664 0.048701808 -0.10264679 -0.0007334695 -0.055554006 -0.005079265 -0.029778223 0.06745823 -0.078429036 0.011723551 0.0329098 -0.01731549 0.05459756 -0.006795108 -0.012815014 -0.09312008 -0.06561231 -0.023425369 -0.04494367 -0.027417894 0.01694876 0.106559426 -0.041246966 -0.037393935 -0.10033814 -0.0034544137 -0.058687214 -0.020124966 -0.03112838 -0.023251886 0.012537845 0.024379436 -0.05003736 -0.07630127 -0.10871228 -0.010061271 0.058789693 -0.03404267 -0.07320422 0.102829576 -0.08659351 -0.003995578 0.020019514 -0.14030825 -0.51056165 -0.14977399 -0.34105018 -0.2211237 0.4738519 0.24484819 -0.09180007 -0.11008439 -0.0041041677 -0.28009138 0.46720338 0.36565718 -0.13652702 -0.008674278 0.14464818 0.10435664 0.029790027 -0.10699531 -0.03271259 0.09762348 -0.16828103 0.1436865 -0.072402254 -0.052241415 -0.051531717 0.25094333 0.2551942 -0.24456428 -0.08348752 -0.40489006 -0.5763571 0.37673035 0.1565815 0.2699808 0.2090634 0.17195737 0.24546841 0.37503347 0.23010717 0.10019407 0.386177 0.19956201 -0.31064168 -0.008314845 -0.023315344 0.14014487 -0.33447954 -0.025922127 -0.25456426 0.18453354 0.07329296 -0.40192515 0.12615612 -0.061189532 0.0839783 0.032015394 0.22501937 0.21201417 -0.3658434 0.037950445 0.37400773 -0.121163964 0.28785235 0.23956014 -0.019218482 0.050525006 0.34562364 -0.22269449 0.20378403 0.263392 0.18410273 0.19146934 0.0962161 -0.14800175 -0.060983673 0.044467837 0.1936137 0.020134674 -0.30596885 -0.030889492 0.046262767 0.39790022 0.08428592 -0.041885354 0.34732878 -0.51878965 0.42457122 -0.20455106 -0.31409162 0.34018958 -0.026417777 0.34593344 -0.21185952 -0.26849404 0.36386737 0.25047973 0.104346156 0.057417534 0.030520746 0.35586897 0.14943929 -0.08329696 0.32737252 -0.02796951 -0.5474195 -0.12970126 -0.17436221 0.10046334 -0.08268354 -0.20342474 0.033972505 -0.13818438 0.21115023 0.22416602 0.11810904 -0.18426675 -0.31043836 -0.052088525 -0.0170325 -0.5813377 -0.3198454 0.011326989 -0.34582087 0.5143766 0.0060773143 -0.29998565 0.027952868 -0.19751312 -0.14511901 0.6214709 0.21915323 0.3168021 0.36520234 0.3918528 -0.12018045 0.17135847 0.037708614 0.15464535 0.099030346 0.039032996 0.06825439 0.079902366 -0.061655387 0.23626132 0.22070105 -0.13933185 0.100352906 -0.04474028 0.2927325 0.26121283 -0.123275466 -0.09880815 -0.10630711 -0.24729423 -0.2786571 0.0059262924 0.0042114942 0.0804523 0.15058047 0.026042627 0.37672237 0.20020367 0.39828724 -0.07290536 0.1361311 0.14325692 0.37212607 0.14706409 0.28927165 -0.040552292 0.017257303 0.22780167 -0.12176805 0.17814144 -0.09914311 0.3981103 0.016716793 0.34658816 -0.025421591 -0.022084031 0.2570913 0.33935 0.35818458 0.2294873 -0.076187745 0.34587747 0.23283614 0.44477838 -0.07135242 -0.45464084 0.019023307 0.3247839 -0.04854179 -0.03765746 0.24263653 0.019481367 -0.03193951 0.4554732 0.13388713 0.09891812 0.2609945 0.4370009 0.26503298 -0.10727818 0.1893718 0.24074312 -0.2950434 -0.020577043 -0.15189892 0.38919565 -0.0991558 -0.089180924 -0.14000301 0.20628923 0.37062088 -0.14381237 0.0131591 0.3131233 0.23646215 0.12559398 0.092721894 0.124008656 0.21547455 0.10784737 0.05697634 0.059778884 0.25112525 0.12929007 0.27636033 -0.08944078 0.29741496 -0.17461394 -0.12724957 0.45943287 -0.40641215 0.15870064 0.10484008 0.20971389 -0.17165066 0.13961925 0.4080346 0.30875537 0.11635081 0.34270665 0.25507605 -0.05554657 -0.07898113 0.028881183 0.3122244 0.23751636 0.25624382 -0.0108384695 0.051959578 0.15976688 0.04318742 --0.039998937 0.049099654 0.021609884 -0.013929638 0.055284936 -0.05304574 -0.11367723 -0.05679486 0.03835972 -0.078076154 -0.046558384 -0.08752907 -0.051536437 -0.010309787 0.042483587 0.058710776 -0.0865686 -0.06999838 -0.07376587 -0.046866182 -0.08691923 -0.09183958 0.016431687 -0.07943521 -0.002919499 -0.056336354 -0.055289365 0.011076279 -0.09108817 -0.07565395 -0.11000667 0.013650329 -0.083610594 -0.114067875 -0.13579212 -0.0013263643 -0.048048995 0.04939255 -0.01991706 -0.09881252 -0.040483665 -0.009600314 -0.04712964 0.04386978 0.039650027 -0.081291005 -0.08040062 0.0028716223 0.06313834 -0.025632894 0.05685978 -0.04321752 0.02653695 -0.10241036 -0.09208701 -0.081303544 -0.10871748 -0.061728142 0.011829223 0.05683139 0.06264042 0.024366712 -0.085767485 -0.07454703 0.035088077 -0.016795382 -0.10150136 -0.0076925186 -0.12897412 -0.068632744 0.02253024 0.0023093186 -0.011833167 -0.006848284 -0.0055261347 -0.034949426 -0.014922045 -0.07572834 0.008671813 -0.043614723 -0.06661664 -0.0864457 0.013633271 -0.08885921 -0.06624801 0.022009978 0.06669134 0.024396256 -0.013767422 -0.032423653 0.023511726 -0.03274786 0.063776255 -0.07120686 -0.025842445 -0.07609209 -0.07945793 -0.050379932 -0.034469787 -0.04125404 0.066004544 -0.0022518747 -0.115013845 0.05655561 0.015347686 0.026992854 -0.07477907 0.014094321 -0.03932436 0.06950247 -0.09021125 -0.08811298 -0.0012370858 -0.082147196 -0.0235359 -0.046531044 -0.103425175 0.056122918 -0.060534634 0.009808091 -0.09185199 -0.010056805 0.026722232 0.023964627 -0.058096197 -0.1016085 -0.084804624 0.06595089 -0.2832186 0.067910805 0.0035658914 0.162475 -0.07948559 0.24984388 -0.4317578 -0.21899183 0.055416107 0.32605317 0.17583083 0.3040095 -0.17673169 0.14240061 0.07252142 0.15975812 0.16733694 -0.073396385 -0.31825668 0.11057497 0.25107494 0.20101818 0.09607587 -0.12501004 0.025303498 -0.25220525 0.5235974 0.02763491 0.21383211 -0.060548794 0.46274444 -0.079148434 0.22250247 0.1445188 -0.119779594 0.02384856 0.244307 0.15778449 0.12856117 -0.22818214 -0.020126099 0.13619538 0.33888438 -0.03772599 0.0021987704 -0.17375332 -0.099216774 -0.22539194 0.25581503 -0.13600525 0.17362003 0.02350021 0.50011444 -0.19964093 -0.16453958 0.16627017 -0.09402537 -0.06187207 -0.2951518 0.07530693 0.19860232 -0.1509706 -0.26507324 0.2364912 -0.037854727 -0.023865024 0.20181462 -0.062307402 -0.24393734 0.0688664 0.22612664 0.10557135 -0.20428255 -0.28614876 0.07005811 0.14201592 -0.22428168 0.098598495 0.18708088 -0.14621806 0.09302438 0.054323733 -0.029828448 0.20268364 -0.19468364 0.203218 0.007291137 0.34384742 -0.1850077 -0.23676935 -0.045399196 -0.06081298 0.5019646 0.39281937 0.15791357 0.07110568 0.30222222 -0.085829206 0.23262678 0.18385766 0.28852394 0.25414863 -0.10749254 -0.1368518 0.2936854 -0.0482574 -0.04686789 -0.32385528 -0.027084578 0.2340085 0.12977996 0.073699854 -0.05667381 -0.019027125 0.20944153 0.11756177 -0.0417758 0.09658401 0.077032246 -0.1503087 0.31389558 0.2776651 -0.07791109 -0.031744905 0.23509748 -0.2029339 -0.023355387 0.10068341 -0.05885242 -0.086075544 -0.17055516 0.0083686765 0.047365386 -0.1439386 -0.10387994 0.068032645 -0.06908104 -0.4023207 -0.10952516 0.18234925 -0.25368467 -0.011403958 0.061518773 -0.080840036 0.1009953 -0.120064475 0.047091972 -0.12065696 0.0706789 -0.16795598 -0.00073109637 -0.16832833 0.0962258 0.054861218 -0.032369137 0.0010906996 0.06977596 0.10278614 0.010035678 -0.1321808 -0.18938985 -0.074093804 -0.1559817 -0.20777082 0.03078753 -0.18882877 -0.010505951 -0.3019942 -6.9103844e-06 0.12643519 -0.088184014 -0.2223908 -0.15635413 -0.027256798 0.074574545 0.116883665 0.13027439 0.0447134 -0.0527594 0.08268675 -0.18205169 -0.14180698 0.11651352 -0.06240584 -0.17999491 -0.09005967 0.036221378 0.21790609 0.030737765 -0.13199474 0.090113 -0.28636286 -0.033317167 0.011666246 0.1906245 -0.109118745 0.009578276 0.028881613 -0.2629735 -0.10875118 -0.06055366 -0.031575985 -0.14809935 0.047321703 -0.13245697 -0.11261377 -0.17031147 -0.05861608 -0.17786422 -0.07033377 -0.18509169 -0.2808071 -0.031683013 -0.24363412 -0.09662762 -0.081843466 0.00085714005 -0.1394895 0.092783056 -0.22829671 -0.129485 -0.061164107 0.22894171 -0.11299924 0.019164136 0.06255576 -0.102554664 -0.118276335 -0.11757833 0.047732558 0.018343585 0.06752136 -0.009375453 -0.04655986 -0.11203433 0.06721959 -0.12560785 -0.124631174 -0.25256935 0.105194695 -0.30439073 -0.10013532 -0.20018019 -0.0083725825 -0.059987802 -0.121252276 0.06587944 0.006337549 -0.20582123 -0.12118071 -0.18979883 -0.35432762 -0.2127865 -0.0779759 -0.01400546 0.018651098 -0.045563653 0.3432867 0.04582936 -0.14024962 -0.08208092 -0.2726434 0.06485741 -0.0024017768 0.09385586 -0.12906367 -0.3696335 0.19474451 -0.0157727 0.13853753 -0.20859559 -0.044720214 0.10216875 0.31881022 -0.10101881 -0.28524384 0.132039 -0.13584924 0.22333835 0.036104273 -0.11176821 -0.0682587 -0.03774414 0.036417097 -0.021028208 -0.004361334 0.2870162 0.123804234 -0.24945171 0.06178884 -0.30589104 0.05371086 -0.22804739 -0.1821359 -0.08295024 0.06778218 0.02459642 -0.2993974 0.114762574 0.24038562 0.2226476 -0.03880777 0.025661524 -0.038055044 -0.21532053 0.02440414 -0.11832482 -0.034565415 -0.28636366 -0.02401545 -0.3807877 0.017813776 -0.20262177 0.10379118 -0.13589598 -0.089878336 -0.36593023 0.16997288 -0.032967202 -0.08806341 0.08710733 -0.09897782 -0.24137904 -0.02487192 -0.033780564 -0.088793576 -0.11663271 -0.35862088 -0.2615839 0.11063389 -0.14055735 0.027706634 -0.18740517 0.20520736 0.15077537 0.19522014 -0.16266516 0.0785627 0.05175212 -0.10871144 -0.062428646 -0.20478083 0.15430816 -0.08578139 -0.1383597 -0.4784271 -0.028318597 0.17461166 -0.30197173 -0.028354317 0.20300093 0.16285573 -0.08147733 -0.37573868 -0.08884118 -0.0847961 -0.2512444 0.074246295 -0.11977838 0.13470928 0.077642955 -0.043767214 -0.17427191 -0.05063095 -0.15231445 -0.14515054 -0.3217391 -0.06261759 0.114484556 -0.17285068 0.08275228 0.20797363 0.043252327 -0.36743593 -0.013443208 -0.19458438 -0.20139094 -0.19072264 0.06346793 0.25686508 -0.16557252 -0.18040413 -0.2808103 -0.11462475 -0.10844927 0.31236902 0.4204689 0.47214368 0.30760515 0.20200449 0.24575059 -0.085074395 0.085359216 0.27159697 0.4367641 0.16309287 0.28050914 0.08948181 0.2474148 0.1958696 -0.06953027 0.22782408 -0.084417574 0.28079242 0.16992344 0.25157416 0.19859444 0.318402 0.018237943 -0.15200791 -0.09050595 0.24714886 0.36967528 0.049723595 0.45239988 0.13568299 0.09641683 -0.053621005 0.026320891 0.10257606 0.11834991 0.19125117 -0.04073439 -0.2587595 0.27458423 0.22014445 0.3198844 0.44422266 0.11488198 0.038292196 0.32561406 -0.3204792 0.22789893 0.023521326 0.21038409 0.0030783669 -0.13783777 -0.18423073 0.34795147 0.41165566 0.26453525 0.21787624 0.527657 0.099709295 -0.08408177 0.37073612 -0.36163118 0.19147152 -0.009287589 0.039458334 0.1974941 0.1369977 -0.045604024 0.1603677 0.281164 0.45161858 -0.1966528 0.32662678 0.45305693 0.1290563 -0.13619636 0.27740428 0.22261769 0.16929677 0.1696779 -0.016267855 0.26972136 -0.036313165 -0.044140927 0.45774978 0.060002003 0.10596591 -0.024930395 -0.04730269 0.2990699 0.2563968 0.45214072 -0.03531828 -0.12543122 0.20094235 -0.029339334 -0.19017676 -0.35091028 0.1636193 0.22826087 0.19084048 -0.08757287 0.07845795 0.26093328 0.04500053 0.18706538 -0.32363895 0.46764272 0.15887797 0.08852697 0.049459983 0.12769969 0.33263963 -0.20497106 0.07190056 -0.046120673 0.08555578 -0.005474111 -0.21171041 0.105458595 0.3940065 0.36752534 0.24511883 0.07887615 0.07341431 0.46817458 0.13723654 -0.0847501 0.420288 0.45878732 0.3128288 0.4021988 0.30841827 0.20308888 -0.21680818 0.020556694 0.11444975 0.33322844 0.07085348 0.08618564 0.40184107 0.03306849 0.078274764 0.41166407 0.14346404 -0.14958218 0.0980759 0.24611679 0.19341505 0.059150588 0.30519438 0.079737194 -0.19277042 0.17070426 0.085203715 0.20361437 -0.04732961 0.28695622 0.18127596 0.11680865 0.15800408 -0.117965 0.3014989 0.09973377 -0.026131345 0.111827366 0.2544842 0.37131476 -0.15175094 0.38789922 0.2973908 0.076327346 0.014191099 0.27788526 -0.26972154 0.45441154 -0.0008983197 0.16974327 -0.00662302 0.3829993 0.350333 0.06594276 0.08205941 0.20724846 -0.13110153 -0.03910145 0.1398437 0.17941236 0.14468363 -0.30394292 0.2909698 0.18729962 0.05289144 0.025107658 0.12394951 0.096180774 -0.066649534 0.11347878 0.24552059 -0.0053186235 0.005526741 0.34705797 0.0866747 -0.054298144 0.4347637 0.37817508 0.24935818 -0.18109532 0.18556929 -0.16298343 0.17921251 0.04886889 0.03459862 0.0792718 -0.058562733 -0.090414986 0.31240645 -0.15976311 0.19330278 0.19994159 0.26833308 0.32220542 0.11271086 0.31870154 0.07073046 0.08054147 0.21161206 0.08505449 0.08365824 -0.13987193 0.38198397 0.057330176 -0.0055792085 0.35047632 -0.355049 0.1195698 0.3363422 0.25226754 0.11292706 0.35302123 0.009824037 0.2913465 0.17722747 0.4356719 0.39574423 0.0041804872 -0.15383576 0.37003705 0.41260827 -0.21422108 0.21264237 0.3338183 0.016317729 0.098424144 -0.066209644 --0.051938202 -0.038498826 0.015455961 -0.09566491 -0.13544069 -0.11360405 0.013115272 -0.1596439 -0.24815354 0.16874619 -0.1034593 0.0668928 -0.033505823 -0.19727017 0.14634047 0.03245558 -0.020919405 -0.018352794 -0.014641548 -0.17071478 -0.081726015 0.005433666 0.10181065 -0.04714738 0.04630091 0.012627596 -0.24318889 -0.329038 -0.14278787 -0.022905096 0.027171336 -0.14439459 -0.15971698 -0.0023036688 0.056883223 -0.31099966 -0.003029623 -0.21256684 -0.19507508 -0.09410876 -0.16942495 -0.110412136 -0.026019853 -0.13316193 0.046928383 -0.059631594 0.08643375 -0.100343205 -0.053636376 -0.005376669 -0.12597634 0.014356297 -0.33944073 0.10293505 0.08389876 -0.03475216 -0.14341311 -0.19434977 -0.07062619 0.09346749 -0.03217715 -0.197737 -0.05022091 0.06832406 0.0034525727 0.065290555 -0.084372595 -0.33849835 0.040680427 -0.014447435 -0.10198047 -0.010787306 -0.177543 0.048759326 -0.08941611 -0.03921537 -0.21627714 -0.123234876 -0.06353442 -0.016023755 -0.1128931 0.05726477 -0.23115939 -0.07945348 -0.06132063 0.03859396 -0.13644338 -0.10159367 -0.091187686 0.050056946 -0.014349876 -0.28065497 -0.16250288 -0.18634818 -0.12826115 -0.13853337 -0.01385298 -0.22869834 -0.15646759 -0.15098332 -0.2629341 -0.0677647 -0.17223991 -0.11943827 -0.11765883 0.025971575 -0.14518718 -0.030934494 -0.057081442 -0.09499952 -0.15450945 -0.10654261 0.02898563 -0.15146305 -0.31898373 -0.054996144 -0.42896995 -0.2026779 0.04311328 -0.12748209 -0.1203666 -0.26431495 -0.1376752 0.018857831 0.016971722 -0.062409725 0.19775885 -0.07483946 -0.15632293 0.31995422 0.2586828 0.19937083 0.35485548 0.33542103 0.26513007 -0.09421375 0.2096759 0.3099949 0.2611777 0.26350856 0.43512046 0.08280221 0.16592878 0.19287282 0.05588937 0.24325278 -0.25637817 0.22686143 0.15832546 0.21235348 0.13313574 0.2342088 0.055368554 -0.16874105 0.043823086 0.36165413 0.11157494 -0.074688 0.24575917 0.15555787 0.30375725 -0.06438441 0.23063141 0.22983031 0.045321107 0.15780167 0.29009792 0.114383794 0.35838085 0.17406431 0.052287478 0.28288415 0.086895466 -0.08618777 0.237991 -0.2648798 0.09690012 0.011951675 0.13845253 -0.034481984 0.1483956 -0.100511886 0.022146313 0.36436787 0.40215823 0.19807701 0.18353584 0.10950008 0.22707132 0.29216793 -0.29377368 0.00023722944 0.24339098 -0.03191041 0.19808546 0.23358501 0.066411346 0.25747347 0.16426149 0.26421678 0.18580215 0.25259393 0.20664819 0.2853264 -0.09870007 0.3542891 0.2926011 0.16262892 0.13365722 0.2238285 0.15782899 0.2092986 0.015336498 0.19152834 0.055196512 0.13442615 -0.10094652 0.051858515 0.18191428 0.20936736 0.28118417 0.11733629 0.20674914 0.34961262 0.25963184 0.18611644 0.16613947 0.11531179 0.23986524 0.1532441 -0.054144327 0.24569549 0.26709342 -0.085017495 0.37493813 -0.18615654 0.10487302 0.13213147 0.21874188 0.24820372 0.25465617 0.2156595 0.18085842 0.20231496 0.41090927 0.25648355 0.00027325773 -0.13298446 0.2654041 0.23646924 0.2476882 0.15910369 0.29946184 0.010262432 0.24106136 0.07548948 -0.43415722 0.35069293 0.32533845 -0.09245735 0.31323132 0.050459128 -0.12106704 -0.25641233 0.092375614 -0.038211983 0.22227982 0.3144816 0.43397865 0.23461227 -0.105558164 0.525352 0.25369522 0.24254346 -0.1666847 0.22670434 0.033190455 0.12921575 -0.29570216 0.10398897 0.022801984 -0.25209585 0.32950178 0.22687748 0.012919888 -0.059656225 -0.026725499 0.019082796 0.5012316 0.1899892 0.16107531 -0.22218782 -0.0027894375 0.29245204 0.39414677 0.31095466 -0.37448317 -0.0010065363 0.356558 0.36621946 0.27710012 -0.104197316 0.30570254 -0.27305198 0.27175796 -0.04417656 0.2884493 0.01906056 0.2917213 0.3735427 0.10778607 0.13208207 0.20563255 0.026834827 -0.06447111 -0.061326854 0.3847304 0.17810202 -0.30003214 0.005864127 0.22485028 -0.0021858932 0.024530616 0.4604553 -0.12139182 -0.10623899 -0.0341898 0.24210761 0.20604716 0.10015286 0.21325995 0.3379417 0.040844247 -0.11128874 0.002697832 0.14370695 0.019528618 0.30229518 0.30391824 -0.062849924 -0.05408174 0.44047302 0.30934504 0.48708764 -0.09594049 0.25241724 0.25560814 -0.18705188 -0.09525515 0.311959 0.1791245 0.31584048 -0.09235725 0.18443067 -0.047792155 -0.0852972 0.12586477 0.042606603 -0.11376011 0.08415544 -0.04264632 -0.07367098 0.22652324 -0.17731114 0.30021656 0.31147903 -0.0010664326 0.027556092 0.37171602 0.10366603 -0.17548594 0.16724938 0.031054148 0.31643087 -0.06999562 -0.055893283 0.15738733 0.13855919 0.30492637 0.086967416 0.5207336 -0.06707559 0.054686364 0.028673489 --0.10834323 0.20543407 -0.24540165 0.04275225 -0.04972961 0.1371124 0.23431109 -0.09963303 0.08248988 0.3592511 0.26857424 0.23832925 0.16830942 0.40547708 0.12251519 0.3764499 0.12287718 0.2869345 -0.24581927 0.12062072 0.41392758 0.021153294 0.24336912 0.34050164 -0.04318666 -0.08307056 0.09104006 0.31973583 0.35707238 -0.047808804 0.32697818 0.10357044 0.3103777 -0.118254706 0.4818041 0.31218782 0.2129178 0.056348108 0.042996407 0.21821731 0.1957361 0.17018574 -0.06984241 0.078211784 0.10532712 0.030189006 0.24022955 -0.3283703 0.05610006 0.07524082 -0.20504245 0.02803004 0.15165657 0.32329777 0.05731876 0.29183784 0.1994071 0.3946798 -0.025876906 0.09570879 0.13155498 0.20592543 -0.24006632 0.02862575 0.025859606 -0.070629895 0.12012089 0.06877909 -0.13612303 0.2137675 0.24789403 0.06496405 0.20336425 0.5770411 0.18076622 0.37889174 0.021599751 0.24237715 0.24192922 0.18450733 0.37698844 0.22657815 -0.024325743 0.42503488 -0.038219463 0.26977316 0.07120697 0.09004896 -0.11367513 0.26504093 0.55942386 0.28683665 0.34456527 0.22476432 0.04212632 0.2123365 0.22905222 0.1982589 0.15023991 0.063660234 0.15081799 0.27854255 0.04580058 -0.15240832 0.35264456 0.043691598 0.16536534 -0.19356123 0.33245787 0.22130464 0.16069864 0.5178661 0.15043904 -0.033654172 0.032267656 0.15946242 -0.19592853 0.26663685 -0.01975921 -0.1251066 0.14134851 0.010078145 0.26391196 -0.15873656 0.28059354 0.03279103 0.08659206 0.08850507 -0.06423589 0.28002062 0.45731875 0.3129279 0.41361487 0.18115169 0.32309863 -0.13107881 0.21524946 0.42102364 0.35797834 -0.033130452 0.31966347 0.32571968 -0.038618058 0.19099647 0.23135066 0.2692841 -0.18644422 0.03130331 0.29347423 0.21999533 0.12297604 0.41888854 -0.061038695 -0.21052039 0.0038388139 -0.32482404 0.07803224 -0.032371737 0.22042076 0.30820394 0.13647117 0.009532485 0.103818804 0.4865756 0.12852632 0.19870381 0.21442926 0.120132565 0.26801398 0.15245312 -0.0040773246 0.20697789 0.135278 0.020435361 0.1326066 -0.26014686 0.3618572 -0.054103773 0.17128836 0.09330641 0.2435389 0.24613231 0.06787569 0.33160824 0.15077013 -0.114019364 -0.030607613 0.18861897 0.12597075 0.08943471 -0.25960207 0.19519961 -0.066505656 0.053852066 0.115520366 0.16506805 -0.015220356 0.22118212 0.023823755 0.2172184 -0.03204623 0.05547188 0.1790876 0.03341857 -0.10333803 0.28302366 0.2802262 0.059729144 -0.016675983 0.2052458 0.031464092 0.033463065 -0.053853013 0.32019177 0.14005084 -0.08784533 -0.12795135 0.369827 0.16747597 0.23045942 0.3364803 0.23276958 0.21056302 0.0710835 0.40312156 0.016117701 0.27303654 0.26244283 0.051080678 0.1324503 -0.16110426 0.2130762 0.007940555 -0.021286111 0.3550122 -0.20264609 0.13052785 0.33936858 0.313464 0.14233546 0.40679884 0.16257712 0.28490558 0.29368973 0.22158918 0.26795503 -0.05106957 0.021662286 0.2954127 0.27434918 0.11966913 0.22047824 0.18372275 -0.016472237 0.18731512 0.16416486 -0.0949396 0.3460457 0.25683904 0.24484208 0.41962734 0.25520685 0.30586022 -0.053349573 0.08085545 0.3042299 0.23255453 0.29153466 0.31873417 0.16095752 0.23799974 0.23422575 0.15634328 0.2533181 -0.18313524 0.0848796 0.14296982 0.17132685 0.13789476 0.2670634 0.03529659 -0.27200046 0.28153622 0.3030695 0.18814851 -0.015910003 0.2696768 0.19532917 0.18773328 0.11099234 0.18238612 0.24004193 0.16732182 0.17782667 0.28576833 0.28142408 0.20519602 0.26712462 0.22416557 0.26695704 0.122257754 0.0054550255 0.34130317 -0.1819855 0.07419322 -0.053602207 -0.086648144 -0.011624673 0.19137146 0.36124584 0.14076467 0.37378606 0.24023587 0.21543531 0.22543333 0.030944444 0.24176463 0.38019666 -0.3614704 0.34323436 0.10009706 -0.090558864 0.16114041 0.17805551 -0.03627377 0.10020172 0.27329728 0.29577896 0.15461431 0.2625852 0.21304664 0.22800381 -0.109386615 0.29075456 0.23845012 0.2060233 0.162783 0.1896407 0.05950654 0.3324222 -0.032478586 0.2504362 0.27468905 -0.010793683 -0.059707854 0.28050327 0.18002222 0.21731573 0.28192383 0.30538052 0.2102243 0.10483433 0.15812035 0.16575113 0.20097339 0.13535684 0.10991173 0.23574011 -0.13894926 0.15878944 0.23604318 -0.019012298 0.3526738 -0.26285324 0.19247222 0.371067 0.20916137 0.23492937 0.28209484 0.1992753 0.1905414 0.25168693 0.32326266 0.24008381 0.004428869 -0.07288975 0.17839769 0.19362016 0.27538013 0.16966957 0.31080103 -0.066068694 0.33248165 0.13412307 --0.020765955 -0.07081177 0.04687861 -0.08898408 -0.04287752 0.0056039197 0.011823491 -0.033573437 0.040589735 -0.08768804 -0.0063342927 -0.014660366 -0.06425151 0.03825933 -0.04314936 -0.074123 0.023095451 -0.07996826 -0.02640229 -0.028572874 0.004408148 -0.033363335 -0.090319656 0.01871916 0.022811685 -0.024564488 -0.09136193 -0.049818292 -0.014202256 -0.04532911 -0.02648642 -0.09265616 -0.08966108 -0.08584948 -0.06495593 -0.06712047 -0.09966796 -0.0040263473 0.025405593 0.024450643 -0.06267951 0.011319352 0.0020738002 -0.08900121 0.07327679 0.026765224 0.0327028 -0.03444405 0.04777675 0.056101516 -0.07559624 0.011537029 0.039759856 0.028782455 0.059481926 -0.09885639 -0.03140658 -0.047679387 -0.059015315 0.0014212991 0.015784051 -0.017769942 -0.05480861 0.05833909 -0.02194392 -0.08435512 -0.046488553 -0.090375595 -0.05250868 -0.057325542 -0.08994758 -0.057908334 0.015833165 -0.06394807 0.062328387 -0.026215687 -0.08163467 -0.09217533 -0.053678587 -0.090312526 -0.039775994 -0.077886924 -0.023048198 0.0004944088 0.063286476 0.033121627 0.012938253 -0.008916232 -0.030920995 -0.08834482 0.012201009 0.06829075 -0.021467049 0.02882229 0.049194977 -0.031087372 -0.013784857 0.047471836 -0.09999872 0.08078426 -0.047156345 0.06120708 -0.012937271 0.02846948 0.03847395 0.0098574655 0.04264946 -0.064033754 0.05319005 -0.04749407 -0.09294563 0.02774574 -0.03864814 -0.08995193 -0.017792106 -0.07282782 0.046471607 0.044668995 -0.04099872 -0.040494252 0.016263051 -0.066352844 0.053874046 -0.011094844 0.003652665 0.041115023 0.05383729 0.02222764 -0.14541978 0.2779862 0.16570893 0.14462063 0.28592232 0.33697245 0.18461557 -0.04882446 0.08187049 0.083850615 0.49758324 0.33715853 -0.026175268 0.23235603 0.20017233 0.024323637 0.052161228 0.120695 -0.12779665 0.123946674 0.0154367685 0.14212215 0.060099345 0.01359371 -0.036714513 -0.21843599 0.3019487 0.38768473 0.13344492 -0.02048713 0.38803723 0.25490603 0.24571593 0.39684138 0.25237736 0.15988307 0.2942548 0.06596446 0.19579424 0.12639475 0.4313869 0.09242181 0.14474338 0.4592881 0.1387339 0.0069797547 0.2872641 -0.20333734 0.13314268 0.016259316 0.20929228 -0.004453372 0.25851458 0.35559106 0.09480636 0.25808057 0.35194686 0.21941838 0.24503024 0.2017658 0.12775801 0.23670119 -0.3292763 0.29664493 0.19252178 -0.0033694126 0.08600918 -0.046312664 -0.13110985 0.1265098 0.08251613 0.34147838 0.25026056 -0.14003016 0.23265283 0.17957355 -0.010331368 0.23541345 0.2230628 0.064025916 0.07560568 0.1791188 0.08175129 0.33978444 0.045186438 0.10211407 0.16733104 0.05421857 -0.09422907 0.15203626 0.2175219 0.23084864 0.22983073 0.31633458 0.075282365 0.40256283 -0.0915894 0.1284492 0.16333342 0.021104772 0.30363247 0.13009235 -0.054522287 0.09542902 0.1723923 0.0014461692 0.18350801 -0.31364807 0.004248758 0.2740016 -0.0239069 0.29936412 -0.091306515 0.14593674 0.13793215 0.23748958 0.19029838 0.38949752 -0.018738313 -0.17249636 0.43669915 -0.033917215 0.3190568 0.39630282 0.32014444 -0.017490977 0.1478673 0.16047172 -0.034677047 0.050652344 0.011827258 0.06477358 0.0027994725 -0.08162858 -0.084625654 -0.023264399 -0.020574655 0.06653995 -0.06124671 -0.070906535 0.046230316 -0.025696581 -0.03192816 -0.07880569 -0.06517657 -0.053141527 -0.064425886 0.00605402 -0.050503142 0.076168455 -0.050962865 -0.020535218 0.05857764 -0.078358255 -0.032332096 -0.020566417 0.04282892 0.0061331266 0.0067866365 -0.093248084 -0.0016005371 0.003007923 -0.03133584 -0.09172029 0.040504213 -0.07164733 0.06407968 -0.017683763 0.0602355 -0.035001036 -0.03355149 -0.048006155 -0.04515152 -0.098930635 -0.036321867 -0.08582517 0.015613032 -0.09823424 -0.0792555 0.051072985 0.062224325 -0.06828286 -0.06664209 0.03299587 0.0020879337 0.016681874 0.07304433 -0.06053578 -0.008540745 -0.013315865 -0.012969243 0.0413874 -0.071608685 -0.040232357 0.043133076 -0.07606585 0.06323875 0.007240863 -0.029644292 -0.08580913 0.060351875 -0.012561934 -0.03169839 0.010984725 -0.058133785 -0.024444645 0.005978973 -0.050732724 0.028465373 -0.044668406 0.033713847 0.02998941 -0.07630241 -0.08798676 -0.07761201 -0.07386414 -0.073134206 -0.08663005 0.014517185 0.041589808 0.016482892 0.029688584 0.012105669 0.05099108 0.023941273 0.0064321044 0.029821381 -0.052913975 -0.06508249 0.045692746 0.016039299 -0.07274264 0.03332322 0.06891455 0.043924868 0.0056238817 0.042590376 -0.09316424 -0.019601021 0.0108321365 -0.06697963 -0.0779622 -0.07558516 0.0865793 -0.060838368 -4.777918e-05 -0.09579048 -0.04161876 0.04035543 -0.024755264 0.06503231 -0.094333656 0.051293645 0.046566084 -0.07412771 0.003917318 --0.12550579 0.0046118996 0.035847154 0.042123724 -0.07412457 0.040777832 -0.010737563 -0.114648946 0.047587924 0.05074621 0.019502493 -0.015697459 -0.007483194 -0.17118867 -0.07306667 -0.024485214 -0.026883055 -0.11627306 -0.079330444 -0.11204599 -0.09679732 0.03819829 0.082075655 0.032643463 -0.012522255 -0.112276316 0.024840418 -0.04899119 -0.038538903 -0.07362059 0.028497588 -0.09777382 -0.16439712 0.06692272 -0.035924926 -0.06683892 -0.0009616961 -0.027083792 0.03290462 0.018687883 -0.09025234 -0.06168314 -0.034636255 -0.08615133 -0.11375983 -0.022562925 -0.07070742 -0.1231319 -0.107245065 -0.07770164 -0.08792 -0.052321278 0.009885092 0.07653175 -0.00017232692 -0.003616353 -0.09468464 0.042886242 -0.039980397 -0.12823173 -0.09783213 -0.07693716 -0.11648492 0.0735763 -0.05437276 -0.15562014 -0.055586655 -0.05070079 -0.05453083 0.08804887 0.11726364 0.012341639 0.020656627 -0.0010414462 0.04857887 0.01225652 -0.02919148 0.022005064 -0.044090305 0.018037302 -0.039563734 0.020961285 -0.022796938 -0.018456634 -0.0029484697 0.04812432 -0.05849438 -0.13337477 -0.013462031 0.07566596 -0.062206723 -0.03513313 -0.023949903 -0.04872344 -0.14060798 -0.104904056 -0.023266263 -0.10660003 -0.076491766 0.014034668 0.004344351 -0.08247214 0.039674442 -0.016235169 0.02429374 0.012410558 -0.05571447 -0.037594583 -0.12810777 0.0038504212 0.053916186 -0.037281934 0.055999205 -0.15663922 0.01672284 0.029448276 -0.02638481 -0.02319485 -0.06279176 -0.04308031 -0.118223 -0.081471376 -0.055065285 -0.067053676 -0.041729216 -0.086885944 0.09028857 0.019898279 --4.095291e-05 -0.092439145 -0.08659252 -0.055108503 0.057324458 0.030755512 0.032828845 0.061955694 -0.02974515 -0.089179955 0.02028003 -0.0009713836 -0.058033288 -0.09682222 0.025045449 -0.0006676724 -0.057060372 -0.023018291 0.0280788 -0.05661139 -0.007251798 0.01749577 0.00074134156 -0.032017007 -0.07601266 -0.10035335 -0.0053586047 -0.09507639 0.026274126 -0.0854384 0.014408614 -0.019539515 -0.011928476 0.0070155384 0.04461547 0.039875656 -0.015349663 -0.087574966 -0.082266994 -0.014069567 0.00287146 -0.008652599 -0.0360167 0.043153506 -0.04639184 0.015437315 -0.04508 -0.035687774 -0.022958247 -0.09255542 -0.11795469 0.019373324 0.036522213 -0.042924352 0.022680365 -0.022536708 0.034666162 -0.021256436 0.013399911 -0.07827123 -0.029786315 -0.09508456 -0.08862553 -0.044444 -0.053539086 -0.09223583 0.047548536 -0.06590932 -0.03182993 0.039859463 -0.05169339 -0.03661759 -0.06224566 -0.04942269 -0.10168282 -0.080115244 -0.03978588 0.0025536504 -0.042358104 -0.021675315 -0.08866591 0.048374526 0.027209701 -0.042087425 0.06814091 -0.070419505 0.030759104 -0.08114505 -0.04672779 0.03248225 0.009911377 -0.08991804 -0.048595704 -0.02443355 -0.097034216 0.015183258 -0.05234727 0.0037457943 -0.04451353 0.052336387 -0.08505443 -0.06498458 0.055349518 0.062845126 -0.035667267 0.014445311 0.0402843 -0.06519292 -0.06700821 -0.04605909 0.036738116 -0.054890472 -0.03689157 -0.029829597 -0.015805867 0.023653775 -0.035591234 0.06404452 -0.012032085 -0.052588645 0.0017476998 0.0688615 0.07260483 -0.03934408 0.023192344 0.0006528368 -0.04216154 0.04712172 --0.12723328 0.022906044 -0.5198894 -0.07616407 0.050239857 -0.08716409 -0.014180876 -0.036117256 -0.020886937 -0.017225936 -0.5926452 -0.6852836 -0.24571253 0.0017826499 -0.4702797 -0.7057091 -0.66826224 0.083909996 -0.59151375 -0.7587437 -0.6779932 -0.5364921 -0.030617142 -0.4385624 -0.3036045 -0.37321764 -0.06620731 -0.5841631 -0.5558642 -0.73464686 -0.63682103 -0.43889374 -0.5445574 -0.04386489 -0.71147054 -0.48390785 -0.10105459 -0.18897893 0.42093167 -0.4235336 -0.11104679 -0.5496439 -0.39259267 0.0153622 -0.07875102 -0.36817974 -0.58082443 -0.068536334 -0.27064753 0.33617955 0.010858564 -0.5531676 -0.5474654 0.23587601 -0.7244058 -0.5473107 -0.6134465 -0.6511908 -0.78013825 0.050863557 -0.65947795 -0.095985845 -0.090339966 0.0051605995 -0.1378013 0.122852944 0.2585414 -0.090439714 0.06438927 -0.06742472 0.0726306 0.086532354 -0.042606167 -0.034518823 0.27626842 0.009627682 0.19156553 6.271042e-05 0.32880226 0.17949751 0.07789256 0.15865736 0.11423657 0.21040773 0.36770228 0.10076134 0.09298604 0.37775183 0.24647896 0.062965915 -0.013505359 0.24976608 0.21056345 0.24856876 0.16356465 0.16846617 0.17633232 -0.03229159 0.08586948 0.20880193 -0.030581146 -0.068766065 0.184543 0.16482304 -0.04280925 0.24260369 0.2486462 -0.03968135 0.053902768 0.21111214 0.17955291 0.046554465 0.25710365 0.1924279 0.08846152 0.2687502 0.1593267 0.24918662 0.16275732 0.083502404 0.14076571 0.15028282 0.27148783 -0.023265112 0.016160084 -0.059670318 0.021129038 0.031224556 -0.06390019 -0.048405945 -0.16478078 -0.0859455 0.027167564 -0.13462438 -0.010591198 0.012845924 -0.10049078 0.052168544 -0.08269453 -0.15946855 -0.11998792 -0.089811 0.02389506 -0.12332246 0.013771247 0.076021865 -0.035940867 -0.06265381 0.053514116 0.051034912 -0.058161214 -0.090820566 0.0949223 0.048288435 -0.09415154 0.038132448 -0.078367904 -0.060138434 -0.11324274 0.08213649 -0.07553307 -0.00863199 -0.16573162 -0.11798418 -0.029407404 -0.059779387 -0.041376315 0.03644603 0.09360885 -0.12442879 0.0680826 -0.102756985 -0.050937314 -0.024436241 -0.0906986 -0.012087232 -0.09319784 -0.1483801 0.01860638 0.068661354 -4.6454177e-05 -0.008794929 0.012613706 -0.0032201945 -0.048492886 -0.067029804 -0.14190361 -0.093458086 0.004871551 -0.0647037 -0.055594556 0.11170962 -0.15396789 0.027472714 -0.0017498174 -0.055734213 0.033299092 0.05042656 0.030157536 -0.060990088 -0.016077917 0.09937253 -0.038848717 -0.1017535 0.016861038 0.013343558 -0.18202245 -0.0767136 0.018533705 0.12353758 -0.083262905 0.051747702 -0.07341764 0.02966716 -0.044522975 -0.21829855 -0.22602329 -0.049297377 -0.05086617 -0.063275464 -0.03399851 -0.30233958 -0.12737508 -0.23227714 -0.021011267 0.07325666 -0.1309003 -0.050440945 0.018505732 0.084423944 0.072969094 -0.030318864 -0.057348937 -0.13828412 0.028029293 0.09050746 0.1199786 -0.16578421 -0.12463035 -0.058466826 0.044878937 0.13823693 -0.010328928 -0.12511426 -0.05328944 0.19602767 -0.029450154 -0.0046097757 -0.08110054 -0.080122106 -0.037990987 0.11358452 -0.073322944 -0.0675155 -0.019645857 -0.042768802 -0.10629512 0.11250462 0.13824426 -0.034793325 -0.032994393 0.037336025 -0.08224394 -0.06319637 0.056691367 -0.10607124 0.13968375 -0.013313045 -0.050691973 -0.043049242 0.23835708 0.062139824 -0.09019839 0.042615343 0.20113344 -0.018463103 0.29043555 0.08207573 -0.032100804 0.06968219 0.24423341 0.14216055 0.027670331 0.21842134 0.07510274 0.16326417 -0.029983616 0.13561335 0.14307648 -0.050964847 0.08098722 0.11772003 0.1486323 -0.12238753 0.24251921 -0.048578497 0.06050625 0.22749963 0.123371765 0.02264692 -0.053617574 0.2071529 0.017992947 0.011444272 -0.12843455 0.19617121 0.15408325 0.063326694 -0.0051825033 0.10204897 -0.07789348 0.039804224 0.07363462 -0.06975813 0.18922949 -0.0859624 -0.13041317 -0.08428833 -0.08494811 0.032007825 -0.15629293 0.10856876 -0.09261194 0.02568013 -0.0087697515 0.044345297 -0.027868155 -0.019975936 -0.10056303 0.08360998 -0.057456248 -0.098879054 -0.015912602 -0.08470117 -0.15280631 -0.034596898 -0.011011613 0.1682435 -0.054629255 -0.051382728 -0.15453278 -0.04960336 0.09547904 -0.080682874 -0.25830734 -0.16788894 -0.047719773 0.110165395 -0.111557044 -0.30155343 -0.15247191 -0.09943273 -0.08412816 0.078880355 -0.048487008 -0.06705916 0.021336108 -0.0033453607 0.12371454 -0.042821847 -0.06522829 -0.035187103 0.0058604116 0.018116254 -0.050113145 -0.16087586 0.021591255 -0.07258315 -0.14411978 0.21412958 0.09590355 -0.07880258 -0.0585794 0.14441141 -0.05573762 -0.100653246 -0.042652134 0.033866454 -0.02584011 -0.12904657 -0.15093586 0.080270685 0.04843231 0.073897064 --0.040848058 -0.05288426 0.013745429 0.022631878 0.06382816 0.109882176 -0.08409434 -0.09720433 -0.10914445 0.06806869 0.03909288 0.05776455 0.025479252 0.08531338 -0.029353429 -0.051393367 0.009177119 -0.11986541 -0.15389019 -0.17225794 -0.009853139 -0.08800717 -0.0131800035 -0.1267224 0.08994934 -0.1533652 0.07424761 0.11217092 -0.062256027 -0.016108248 -0.15469715 -0.11644598 -0.1622394 -0.03206292 -0.07703742 0.112879835 -0.05174972 -0.07601947 -0.14874355 -0.010562108 0.018406054 0.058638953 -0.15001546 -0.005663762 0.09544643 0.016261801 -0.06505369 -0.0946928 0.09578762 0.07448887 -0.062321167 -0.0421621 -0.05903367 -0.113712 0.056219023 -0.10890986 -0.063604705 -0.18694697 -0.07151637 0.060187485 -0.118444055 -0.1317313 0.10009574 0.034615587 -0.091859534 0.14645524 -0.22358046 -0.05078967 0.037390642 0.11072238 -0.0017686903 0.09405925 -0.029295495 0.024427183 0.06084175 -0.27393314 0.15749662 0.011995465 -0.106458195 -0.11267011 0.0034312967 0.033157915 0.09528558 -0.18256459 -0.17156132 0.07136703 0.10587553 0.22043909 0.18438308 -0.006965694 0.1018732 -0.069956824 -0.16953857 -0.3803009 -0.024495846 -0.009186688 -0.35546634 -0.05332616 -0.21775137 -0.38805252 -0.029313708 0.2572503 0.050111253 -0.22150567 0.33299664 -0.06360325 0.13790178 0.09445717 0.08552013 -0.10025135 -0.020017087 -0.0053512836 0.035870142 0.23599976 0.46457222 -0.046660166 -0.08054533 0.06934421 -0.36162782 -0.3005417 0.00643138 0.060076516 -0.168331 -0.12441894 -0.09569953 0.036763173 -0.10078311 0.02021307 -0.11835386 0.14491357 0.21494724 -0.073896006 0.056995247 0.07480573 0.027708665 -0.1013044 -0.014569499 0.17219615 0.25483137 0.14064069 0.04630185 -0.058010574 0.33001414 0.3776342 0.13949786 0.18880484 0.16543025 0.2607913 0.3602643 -0.05489732 0.11131202 0.3580631 0.27068877 0.06964937 0.038062464 0.26836294 0.23803905 0.40844432 0.26496 0.15002625 0.15946051 0.13634866 0.1826052 0.30208656 0.1644664 0.04788351 0.2270615 0.15327214 -0.0648989 0.4173686 0.28432605 -0.007784095 0.05091869 0.251695 0.104469426 -0.025101176 0.11608391 0.09425334 -0.020179348 0.3366665 0.16756283 0.24383867 0.30401793 0.25647983 0.19526371 0.24140926 0.3204879 0.03565393 0.17121439 -0.026630128 0.05787588 -0.00060401845 -0.15759453 0.114996046 0.1393906 0.040394608 -0.05293411 -0.0070569143 -0.093205586 -0.120698385 0.013008318 0.066545166 0.21309517 0.032085314 -0.0024144722 -0.1411903 0.36225182 0.21887136 -0.069148876 0.07789866 0.21575126 0.084371135 0.29632846 0.022665245 -0.049658358 0.19891143 0.27957082 0.15589218 -0.04531663 0.13695186 0.02079385 0.28659764 0.23158132 0.13252304 0.24552432 0.09571886 0.24494892 0.13475913 0.0226294 0.053979315 0.10331904 0.17346504 -0.061195545 0.33981952 0.10192331 0.037463102 -0.10125801 0.25045514 0.15747991 -0.008713555 0.1366271 0.19407164 0.087705374 0.10512783 0.1245355 0.24343263 0.1649721 0.06154294 0.09008204 0.026219925 0.27247968 0.11719546 0.11840369 0.056824166 0.017373707 0.10018043 -0.520974 0.59964097 0.031219501 0.032520123 0.025338847 -0.121865146 -0.01352736 -0.10892654 -0.0700099 0.19840723 0.060767226 -0.343554 0.4839107 0.07978482 -0.1494974 -0.4358914 -0.45184416 0.16361716 0.12790614 -0.63227665 -0.13850911 -0.11548714 0.061798867 0.3382824 0.5630951 0.25158608 -0.029889492 0.004497678 -0.106172375 -0.7106193 -0.26258215 0.53872955 0.08206982 0.041173898 -0.6073398 0.3374129 0.1267827 0.29143667 0.3268509 0.08830169 0.61188203 0.19090186 0.16641459 -0.10735583 0.08985685 0.079549104 0.10968232 -0.046334468 0.3214813 0.35046473 0.6331912 -0.091849655 -0.16986299 0.24384622 -0.43004617 -0.18335785 -0.25987333 -0.33063456 -0.31992128 -0.10678123 -0.33161026 -0.07196378 0.24237013 0.054740444 -0.22535479 0.043615762 0.03397134 -0.064783596 -0.081724524 -0.07188039 -0.025119694 0.08906968 0.109899156 0.05292809 -0.0080429595 0.034033697 0.19395597 0.096723616 0.3712682 0.07818361 -0.060158323 0.1558181 0.038742818 -0.06901919 0.26340926 0.048637815 0.011880762 0.05225182 0.17577282 0.03445155 -0.08235831 0.18532375 0.10475401 0.1297221 0.08460357 0.030786958 0.13167405 -0.040913556 -0.13796254 0.09512417 -0.06532977 -0.058336448 -0.21801071 -0.004957184 -0.0035523488 0.019674044 0.1630042 0.12683845 -0.060587715 0.016342387 0.12825526 -0.07820336 0.19044252 -0.16002373 0.15333588 -0.027162397 0.053161703 0.17725912 -0.196775 -0.050724853 0.097546354 0.09070096 -0.05950122 0.01630401 -0.1196389 -0.09406375 0.0976926 0.036323573 --0.020441644 0.1286521 -0.19564946 -0.06674779 0.04516537 0.0031744116 -0.074803635 -0.0033299236 0.042051513 -0.080748804 0.06077783 -0.13149478 0.057544827 0.054189455 -0.20807455 -0.15086114 -0.01464815 0.0937327 -0.088393874 -0.03425429 -0.22138686 0.097449705 0.07149927 -0.15377547 -0.26091546 -0.20024033 0.044755653 0.11913005 0.06858127 -0.11183507 -0.0749588 -0.14916946 -0.18056466 0.10436801 0.030045547 -0.13932016 0.008682389 -0.016025953 0.1306242 -0.0810291 0.10187364 -0.20184515 -0.1520494 0.055097353 0.012994354 -0.34702745 -0.0030117086 0.11077064 -0.23334496 0.059724838 -0.040657476 0.012183917 -0.12874444 0.16320549 -0.020379186 -0.09097882 -0.07880674 0.09140376 -0.14485568 -0.03468689 -0.005760543 -0.07601382 -0.061092917 0.07681074 -0.16198605 0.29782295 0.11903604 0.01858877 -0.044626515 0.13560703 -0.010199719 -0.07274405 -0.003985294 0.055972375 0.042626075 0.00617857 0.18043336 0.03040078 0.29322347 0.076021075 0.017674807 0.1956138 0.03725683 0.061865613 0.1737 -0.021201469 -0.02391103 0.19473787 0.23115587 0.19319035 0.0036499242 0.21989623 0.07894939 0.18364365 -0.017070683 0.09442294 0.0317042 0.0016184946 0.09447496 0.12479152 -0.013917674 -0.029526077 0.33845946 0.029997997 0.047173988 0.018650586 -0.08239488 0.06202808 0.017477367 0.22102328 0.11067462 0.08554116 -0.09336047 0.1986696 0.25576705 0.25471368 -0.08025346 0.23854017 0.035558958 0.10197278 -0.06330687 -0.13455947 0.15033753 0.03944658 -0.069490954 -0.11676038 -0.07825418 -0.036357053 --0.020233277 0.12534058 -0.0034608068 -0.08127787 0.013291101 -0.055763252 -0.08265841 0.028339798 -0.093119845 -0.032637723 -0.18080176 -0.14752778 -0.06153035 -0.12380307 -0.08617207 -0.019259753 -0.027866399 0.21707992 0.083600536 0.08371484 0.08754881 -0.08778005 -0.098780535 0.078709655 -0.06815992 -0.11780132 -0.010876028 -0.075514734 0.017611623 0.13420926 -0.036785122 -0.014355611 -0.056173768 -0.024935486 -0.12732968 -0.089633815 -0.06388447 -0.08332238 -0.004005737 -0.025489315 0.08155812 0.016690359 0.06858913 0.037871096 -0.055011272 -0.03190099 0.04623043 0.085440986 -0.0011943477 -0.26540923 0.061274793 -0.050945494 -0.018458184 -0.02220264 -0.08005215 -0.11327793 -0.009730724 -0.075478315 -0.016128074 0.05297016 -0.14135574 0.029771242 -0.0031336774 -0.09867254 -0.082267724 0.12093154 0.24794275 -0.055299267 -0.06426893 -0.08077607 -0.13870978 0.110185355 -0.05423723 0.0771895 0.20935918 0.2571899 0.107830666 0.020436268 0.3422747 0.2726444 0.09925024 0.08687271 0.26584587 0.30420345 0.32314903 -0.0013369353 0.00015559938 0.24158737 0.39565074 0.19164862 0.053453848 0.28555104 0.29287052 0.35482588 0.29276973 0.19548845 0.24000475 -0.033635877 0.16420332 0.26325572 0.033725187 0.111054935 0.12568803 0.077912 0.08697327 0.25146103 0.1617412 0.02886609 0.003291996 0.27146035 0.31297007 0.003375652 0.06638983 0.3106423 0.0045001106 0.33906943 0.120600045 0.11266669 0.13744666 0.2720336 0.1280297 0.22319657 0.40207925 -0.035131875 0.21457748 -0.01105677 0.10734544 0.12169862 -0.18471883 0.108881794 0.017564075 -0.059031114 0.034895733 0.03635156 -0.07050447 0.06321408 0.07461406 -0.119729236 0.27101114 0.005293528 0.22949225 -0.052096307 0.20026585 -0.2801693 -0.24632365 0.014229184 -0.06579487 -0.44841483 0.1534557 0.06446321 -0.077407524 0.41672826 0.52833253 0.25493875 0.08743361 0.51826125 0.0724331 0.08953066 0.17568974 0.48131758 0.14559221 -0.075981244 -0.26377276 0.1560799 -0.067383885 0.0062907184 -0.5140818 -0.016806953 0.34188536 0.30458844 -0.008544355 -0.116234705 0.041083243 0.06614002 0.30595767 0.08180928 0.469383 -0.18233453 0.123322025 0.08859349 0.13087763 -0.035405513 -0.13684338 0.10619407 0.1778728 -0.005600022 0.010060035 0.07685673 -0.08762967 0.09759268 -0.09531901 -0.07970455 -0.11910972 0.2913108 -0.06623312 0.06769712 0.0534919 -0.09977751 -0.009552985 0.018449187 -0.023882218 -0.056258515 0.08252767 0.0551117 0.16266306 -0.092028454 0.14371555 -0.021928892 -0.12826425 0.10592764 0.02672347 0.075170115 0.035355646 -0.019958254 -0.09364768 0.020321349 0.27745265 0.066241905 0.04389831 0.17489603 0.063591555 0.18610592 0.0024997948 0.07459402 0.20759214 -0.0741749 0.03313181 0.25639465 0.0720236 -0.076766774 0.013407968 0.11364409 -0.05602076 0.20991829 0.16148083 -0.061022487 0.020235613 0.22421308 0.052322168 -0.09901102 0.092500865 -0.07747288 -0.06368988 0.1573838 0.12449448 0.19818254 0.15011637 8.6818094e-05 0.13284233 0.051307615 0.052395284 0.0992199 -0.09392717 0.045885414 -0.053628057 0.08465074 -0.04980516 -0.03951162 -0.020674622 0.06989612 -0.09956089 0.055184726 -0.11314369 0.054461524 0.10049867 0.081958614 -0.036116146 0.06482925 -0.0097346455 0.0007656599 -0.09903899 -0.17393877 -0.11043378 -0.025918141 -0.16273181 0.056296967 -0.109220035 -0.038873877 0.047616623 -0.15956873 0.0003209846 -0.07164346 -0.11752921 -0.11718417 -0.12537502 0.07161863 -0.041571498 0.051967263 -0.09406404 -0.032326188 -0.19114257 -0.15998033 0.056657493 0.039807808 -0.063727126 -0.12766196 0.1034753 0.0031631321 -0.098258294 -0.08851291 0.099222735 0.13992298 0.013449072 0.026223723 -0.075287454 -0.011041979 -0.07750733 -0.0770286 -0.18056147 0.05931581 -0.09698105 0.051334985 0.057321835 -0.020476205 -0.07906094 -0.12106597 -0.042174734 0.009466071 0.023957914 0.036795847 -0.054164633 0.24429697 0.03644184 0.0042059557 0.023642896 0.07860015 -0.023056414 0.010082111 -0.02555309 -0.064025216 -0.31214148 -0.25914356 0.039716136 -0.009968457 0.23348618 -0.23575523 -0.114866674 -0.115779616 -0.26494998 -0.091781035 0.090200946 -0.07316008 -0.102294944 0.14978452 0.120892815 0.020556238 0.09909995 -0.105875626 0.16833979 0.07514927 0.19142136 -0.2188493 -0.09944053 0.065923996 -0.25679535 -0.16201195 -0.031191958 0.06415345 0.37565055 -0.08396621 0.08977407 -0.044724904 -0.122398704 0.08692069 0.1053716 0.07562312 -0.17556468 0.09453883 -0.17226541 0.0789938 0.27196416 0.07691988 -0.19878459 0.05212466 -0.12913543 -0.02569145 -0.08820654 -0.12570414 -0.1281983 -0.12184917 -0.011284999 -0.116063386 -0.054273188 0.028735952 -0.5237081 0.16883971 0.12259084 -0.0070942477 0.049744852 -0.093658976 -0.11428407 -0.05380737 0.007737089 -0.054560687 -0.20126434 -0.11682025 0.20170791 -0.042728443 -0.11273211 -0.06437525 -0.24203292 0.025432894 -0.20260674 -0.28622863 -0.3786497 -0.07602646 0.104248025 0.35781553 0.3358937 0.034959048 0.09114094 -0.14234872 -0.013022898 -0.32772562 0.0063111847 -0.03067664 -0.07622053 0.07309994 -0.23291409 -0.020492205 0.03163034 0.12379825 0.115516484 0.22084178 0.3188232 -0.15712315 -0.019436225 0.046994332 -0.07835499 0.22796942 0.100174226 -0.012045292 -0.10762212 0.016660485 0.5096392 0.25902748 0.022994379 0.17734411 -0.10460885 0.16112638 -0.15037473 0.22311215 -0.24745925 0.021579323 3.4587705e-05 0.025768604 0.096518196 0.10281033 -0.1030126 0.1093309 0.14590752 0.0024132982 -0.0031385946 0.107869335 0.06255661 -0.09298259 0.097042195 -0.09434036 0.25641876 0.16633642 0.05325643 -0.048584547 0.2508255 0.3117609 0.17730223 0.11521895 0.31597024 0.1967451 0.40860203 0.052551437 -0.048556462 0.24982695 0.18575457 0.20691781 -0.08619209 0.23501728 0.28116748 0.33296788 0.13059887 0.27286562 0.1967397 -0.004141197 0.2923398 0.14814611 -0.053878617 -0.03934907 0.26191202 0.0038061026 0.14625889 0.29861823 0.18463606 -0.0035886473 0.023109417 0.16652909 0.28165594 0.009143127 0.13388304 0.12265673 0.08051241 0.122950286 0.024188774 0.11675344 0.23904316 0.083728805 0.06454031 0.12631908 0.19692242 -0.043284383 0.075770296 -0.07104134 -0.04045651 0.021263845 --0.06206329 0.11110152 -0.07720491 -0.017565656 -0.031755317 0.058432426 0.09395864 0.016690817 0.09182525 -0.111757405 0.051867943 -0.019448487 0.019125056 -0.12420459 -0.028985279 -0.1953131 0.034684945 -0.01290791 -0.158361 -0.098559335 -0.18044187 -0.00067409815 -0.053563505 -0.006237672 -0.01409948 -0.0029362775 0.039746523 -0.015681695 -0.104658835 0.038102526 -0.058976006 0.061424397 -0.121590145 0.09502551 -0.161757 -0.08773674 -0.03387145 0.047197253 -0.17122144 -0.08109508 -0.04662235 0.029511092 -0.11579408 0.0038979636 -0.05312592 0.04128475 -0.13347216 -0.09054076 0.012290563 0.020250114 -0.07801899 -0.13821584 0.030024063 -0.16545457 -0.09368343 -0.18572368 -0.19234532 -0.002991532 0.027285807 0.04646511 -0.046736527 -0.053498715 -0.0754854 0.07025626 -0.079703756 0.21315393 0.25237685 0.08401435 0.10873539 -0.06990418 -0.10023681 0.037007038 -0.013912855 -0.036879785 0.07423318 0.04884223 0.14983146 0.04782026 0.33526343 0.18102533 0.061067645 0.1649626 0.23966189 0.052397836 0.21462111 -0.05804563 -0.0999112 0.27388853 0.2850436 0.17740123 0.036255784 0.15979914 0.0437921 0.17211951 0.2247902 0.24603623 0.14118566 0.017924 0.07471345 0.20534731 -0.03186023 0.012125353 0.23454623 0.060507204 -0.0075858794 0.32128713 0.13035326 0.038222924 -0.07605768 0.2885286 0.14958102 0.0041881776 0.09773516 0.14689565 0.015316402 0.044299636 0.027018197 0.25897497 0.07458832 0.17879665 -0.057994686 0.18604709 0.18234405 -0.08643574 0.11780951 0.07426081 -0.08963359 0.016042968 -0.03482768 -0.04877349 -0.17190854 0.07068098 -0.010516556 0.112406805 0.06565846 -0.0074740895 -0.09955178 -0.0861785 0.06985262 -0.07934646 -0.07619258 -0.07362824 -0.13247977 -0.13488539 0.05139059 0.07727062 -0.1858854 0.045394175 -0.1778127 0.12608832 -0.0012594741 -0.2889528 -0.19702503 -0.06943198 0.094257645 0.02509725 -0.1426688 -0.26468682 -0.032393523 -0.048070136 -0.022684019 -0.021316934 0.07924387 -0.1861231 -0.08549019 0.11207709 0.067756966 -0.007507787 -0.11366398 -0.061400726 -0.14130224 0.0023604862 0.0005781098 -0.18797077 -0.1476019 0.113903694 -0.18059005 0.14286542 0.015068132 -0.066342965 -0.11702102 0.15661703 0.0109270355 -0.076817684 -0.073913805 -0.005600875 -0.062017728 -0.07686851 -0.13782588 -0.0249736 0.0071113533 0.014256068 -0.28783062 0.29156986 0.044847976 -0.0022228996 -0.022338934 -0.061533846 0.083700985 0.10800079 0.13638592 0.04216577 0.029448345 0.013418156 0.09851437 -0.05277288 0.1861571 -0.100844435 -0.07923676 0.11940402 0.023534786 0.12334147 0.29219905 -0.0073636486 0.122366644 0.20609541 0.33005348 -0.06074578 -0.08387477 0.36750063 -0.03136075 0.08110635 0.08442772 0.4698156 0.22138827 -0.077871636 0.016242804 0.23110288 -0.06087755 -0.2874949 0.0140878195 0.17153057 0.19683678 0.40007108 0.19524163 -0.09927925 0.059219126 0.35842627 0.002342296 0.014362078 0.44419822 -0.20393637 0.53788775 0.12224696 0.05425677 -0.19943425 0.23182674 0.054430347 0.0018112784 0.15689106 0.08468096 -0.101875044 0.027292885 -0.043777857 -0.07323721 0.05319369 -0.20459439 -0.035580102 0.04883236 -0.018117754 -0.049641885 -0.11448763 0.03599298 -0.1254951 0.069294855 -0.03052844 -0.024817647 -0.09040103 0.22489676 -0.008587936 -0.16741875 0.013933508 -0.25287575 0.06820572 0.17145985 -0.21398823 -0.27901208 0.115819044 0.04478165 0.004434518 0.22319248 0.012239549 -0.02462009 -0.25729418 -0.10262675 -0.2842518 -0.10627177 -0.028982509 0.077706695 -0.087844945 -0.24313085 -0.08814091 -0.042190123 0.23014133 0.24880014 0.014519569 0.46283752 -0.09004781 0.053807937 0.06574945 0.0889922 0.018186603 0.031761795 0.005689713 -0.0599909 0.25609565 0.41100568 0.077814125 -0.23103279 0.11095395 -0.27953818 -0.023450151 -0.070123374 -0.01066068 -0.09171211 -0.071235485 -0.42689896 -0.07080224 0.025229469 -0.027046079 --0.11352209 -0.14644271 0.030486856 -0.07325185 -0.064591244 -0.090964705 -0.09126776 0.07770007 -0.12429133 -0.079227716 -0.06360701 0.05963329 0.08088577 -0.10882388 -0.14091331 -0.052719966 -0.16552936 0.06871853 -0.024756607 0.051423706 -0.12975569 -0.15340379 -0.03346181 -0.12332553 0.118418366 0.044443753 -0.036220238 -0.14635304 -0.051035073 0.07862214 -0.1594591 -0.044985246 -0.044488207 0.017548382 -0.16007286 0.0877575 -0.114156924 -0.061517216 -0.09711964 0.055124566 0.08857658 -0.13929982 0.056799594 -0.040348813 0.10819212 0.08760201 -0.10173234 0.11845325 0.034056332 0.002165543 -0.08313206 -0.096684195 -0.014548383 0.026085328 0.0025616998 -0.0668623 -0.071412764 0.03764707 -0.029272737 0.05873078 -0.057662413 0.049962297 -0.056811333 0.07849261 -0.21730898 0.2020778 0.123282075 0.024591586 -0.09860217 0.011657721 0.076910436 -0.053993825 -0.09102177 0.0777202 0.10043123 0.09708253 0.123402655 -0.10603686 0.3355538 0.027166639 -0.119143374 0.16963233 0.14901288 0.0025405842 0.222115 -0.028775109 0.006180673 0.24871638 0.26285625 0.057397056 -0.07186053 0.19534416 0.082720995 0.104962215 0.03738035 0.16415465 0.15144852 0.059286132 0.12994185 0.16285947 0.02562871 0.009724737 0.3614015 0.009148241 0.11566976 0.13930973 0.0783673 -0.078807436 -0.10784437 0.29929662 0.22810988 0.041243587 0.14338613 0.13349883 0.12328762 0.1485585 -0.052017473 0.12282907 0.010245827 -0.039959814 0.03226006 0.13931087 0.070638195 0.026276698 0.09742858 0.014402947 -0.085794 -0.10075329 -0.06956389 0.0037160083 -0.05528899 0.13197279 -0.097877964 0.10306828 0.044267707 -0.0013003278 0.03505696 0.0018697927 0.03380905 -0.065468974 -0.077990055 -0.034425747 0.09347054 -0.0046163434 -0.09389615 0.07687734 -0.1288893 0.030446937 0.113255136 0.047210373 -0.035957694 -0.054828867 -0.13042133 -0.00026837387 0.06204687 -0.055171046 -0.032226875 -0.08783506 0.017895155 -0.038042665 -0.02269642 0.0012175784 -0.060920462 0.09121147 -0.10291942 0.10324893 -0.22679543 -0.109592944 0.14111452 -0.06428377 0.096342586 -0.091976866 0.0037707041 0.07230816 -0.08556388 -0.10701327 0.13365738 -0.12723014 0.06346541 -0.0535626 -0.14914016 -0.07930355 0.04252224 0.018383488 0.03684307 -0.049166646 0.16964889 -0.10466766 -0.08147278 0.054045707 -0.09219066 -0.09852995 -0.17004548 0.16563368 0.1497223 -0.029192008 0.121049955 0.009293286 -0.058750633 -0.101088054 0.002546997 -0.10559251 0.09935291 0.06381162 0.06214938 -0.00086858985 0.2500903 0.23355727 -0.01183984 0.14707682 0.28937548 0.034774154 0.36795512 0.017282726 -0.06271944 0.18199927 0.20840989 0.08538777 0.123738565 0.028816212 0.16678233 0.33197367 0.23343477 0.2106288 0.20913233 0.13852835 0.16671738 0.21682994 0.10165302 -0.09972167 0.29291067 0.07754789 0.085743256 0.29267302 0.17959394 0.14447959 -0.08689463 0.24356933 0.19581221 -0.082665406 0.23449413 0.12166938 0.049716145 0.25899404 0.12470804 0.21271357 0.0924148 0.09146234 0.13676567 0.054578528 0.30180743 0.051753912 0.08365558 -0.112204365 -0.106755376 -0.030200055 -0.042479694 0.13256007 -0.08633078 -0.12399639 -0.05093786 -0.049632203 -0.04536554 -0.020431325 0.00588713 0.041544516 0.036054295 -0.0852016 -0.1294363 -0.08014586 -0.2296124 -0.026385702 0.023046201 0.131335 -0.13280357 -0.101241484 -0.15460956 -0.032869156 0.034629356 -0.22037746 -0.16924004 -0.11989324 -0.08316225 0.04380729 -0.037425756 -0.24711958 -0.074365616 -0.094938524 -0.1706681 -0.10189891 -0.07219588 -0.10539137 -0.11261494 0.08205239 0.24926344 0.052908313 0.037326146 -0.089808196 -0.11544931 0.05259774 0.10347795 -0.13493887 -0.07389637 -0.10525736 -0.06583611 0.2486559 -0.108139604 -0.16252054 -0.08913273 0.012136418 0.04130011 -0.035961274 -0.08299628 0.07772742 -0.16195449 0.06719529 -0.082918115 0.06428361 0.03855723 0.086648285 -0.25398132 0.008260143 0.15142672 0.027022546 -0.04573616 -0.08531553 -0.1017991 -0.05920992 0.046825904 -0.04789848 -0.022505285 -0.15165114 0.21711017 0.0024269647 -0.07189007 -0.26918167 -0.043765172 0.11352691 -0.08602305 -0.13596453 0.0039643073 -0.095904335 -0.043372717 -0.26869184 0.29009065 -0.03945541 0.08232044 0.075800635 0.04820068 -0.2057322 0.29165286 0.061218243 -0.122589335 0.0117345145 -0.32955468 -0.21252888 0.009608937 -0.007759408 0.08739287 -0.45483842 0.13343348 -0.046456452 0.26288265 -0.08011442 -0.065363236 -0.045581967 -0.20569602 0.08807132 -0.08680548 0.09825351 0.25457087 0.10980122 -0.15875827 0.06567453 -0.19635054 0.06610827 -0.17079805 -0.24736166 -0.18937673 0.0316336 -0.07324038 0.037343055 0.11476621 0.041128613 --0.5746274 -0.09257152 0.912285 -0.6090957 0.9643285 -0.1026967 0.6721287 -0.6588699 -0.5802004 0.5310756 -0.543982 0.8772337 -0.61903805 -0.3024232 -0.6671719 -0.41806293 -0.46223813 -0.054980833 0.03122825 0.2547884 -0.59486645 -0.061039817 -0.52836484 0.95376176 -0.3981046 0.07674091 -0.13550112 -0.5619845 -0.35677204 -0.6301644 1.0061067 0.7413826 --0.31724322 0.0017957278 0.37811512 -0.005011656 0.63329345 -0.118556194 0.8208675 -0.4984193 -0.19168231 1.4298196 -0.008222425 0.39445338 -0.12938818 0.010719266 -0.45608497 -0.02108335 0.07785899 -0.110035166 0.12688221 0.12037774 -0.44246748 0.15095623 -0.15013023 0.5887744 -0.11484556 -0.058196153 0.14892133 -0.06916103 -0.09514606 -0.117880985 0.42844328 0.6533205 -0.19357188 -0.012248634 -0.5285921 0.10025003 -0.6583721 -0.09696889 -0.7027063 0.55014205 0.12758593 -1.6589307 0.0679601 -0.5856124 -0.02406927 0.031731416 0.51928836 0.10078484 0.111478105 -0.19389181 -0.17720659 -0.32946518 0.37413028 0.13153392 0.07136435 -0.52441144 0.0047997595 -0.09315095 0.14301816 -0.010904155 -0.1211448 0.20019644 -0.6107775 -0.7599318 -0.7856079 -0.5583929 diff --git a/src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp b/src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp deleted file mode 100644 index 5bcdb0aaea..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/pgd_attack.cpp +++ /dev/null @@ -1,80 +0,0 @@ -#include "pgd_attack.h" -#include -#include "read_net.h" - -PGD_Linf_Rand::PGD_Linf_Rand(CustomDNN model, torch::Device device) - : model(std::move(model)), device(device), - optimizer(this->model->parameters(), torch::optim::SGDOptions(0.01).momentum(0.9)) {} - -torch::Tensor PGD_Linf_Rand::pgd_linf_rand(const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter) { - torch::Tensor delta = torch::zeros_like(X).uniform_(-epsilon, epsilon).to(device); - delta.set_requires_grad(true); - - torch::Tensor target = torch::tensor({y}, torch::kInt64).to(device); - - for (int i = 0; i < num_iter; ++i) { - // Clear gradients - optimizer.zero_grad(); - if (delta.grad().defined()) { - delta.grad().zero_(); - } - - torch::Tensor pred = model->forward(X + delta); - torch::Tensor loss = torch::nn::functional::cross_entropy(pred, target); - loss.backward(); - - // Update delta - delta = (delta + alpha * delta.grad().sign()).clamp(-epsilon, epsilon).detach(); - delta.set_requires_grad(true); - } - - return delta; -} - -bool PGD_Linf_Rand::display_adversarial_example(const torch::Tensor& input, int target) { - std::cout<<"starting the attack"<< std::endl; - - auto x = input.to(device); - - float epsilon = 0.1; - float alpha = 0.01; - int num_iter = 40; - torch::Tensor adversarial_delta = pgd_linf_rand(x, target, epsilon, alpha, num_iter); - torch::Tensor adversarial_x = x + adversarial_delta; - - // Check if the model is fooled - auto original_pred = model->forward(x).argmax(1); - auto adversarial_pred = model->forward(adversarial_x).argmax(1); - bool is_fooled = original_pred.item() != adversarial_pred.item(); - - std::cout << "Original Prediction: " << original_pred.item() << "\n"; - std::cout << "Adversarial Prediction: " << adversarial_pred.item() << "\n"; - std::cout << "Model fooled: " << (is_fooled ? "Yes" : "No") << std::endl; - - return is_fooled; -} - -bool main(std::string filename) { - // filepath "/home/maya-swisa/Documents/Lab/PGD_Linf_Rand/example_dnn_model.nnet"; - std::vector layers; - std::vector activations; - std::vector>> weights; - std::vector> biases; - - load_nnet(filename, layers, activations, weights, biases); - - CustomDNN model(layers, activations, weights, biases); - - torch::Device device(torch::kCPU); - - torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); - int target = 0; - - PGD_Linf_Rand pgd_attack(model, device); - - // Display adversarial example - return display_adversarial_example(input, target); - -} - - diff --git a/src/engine/attack/PGD_Linf_Rand/pgd_attack.h b/src/engine/attack/PGD_Linf_Rand/pgd_attack.h deleted file mode 100644 index 8582fe5d88..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/pgd_attack.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef PGD_ATTACK_H -#define PGD_ATTACK_H - -#include -#include "read_net.h" - -class PGD_Linf_Rand { -public: - PGD_Linf_Rand(CustomDNN model, torch::Device device); - bool main(std::string filename); - -private: - CustomDNN model; - torch::Device device; - torch::optim::SGD optimizer; - torch::Tensor pgd_linf_rand(const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter); - bool display_adversarial_example(const torch::Tensor& input, int target); -}; - -#endif // PGD_ATTACK_H diff --git a/src/engine/attack/PGD_Linf_Rand/read_net.cpp b/src/engine/attack/PGD_Linf_Rand/read_net.cpp deleted file mode 100644 index e139ddad2c..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/read_net.cpp +++ /dev/null @@ -1,114 +0,0 @@ -#include "read_net.h" -#include -#include -#include -#include -#include - -std::vector split_line(const std::string& line) { - std::istringstream input_stream(line); - std::vector tokens; - std::string token; - while (input_stream >> token) { - tokens.push_back(token); - } - return tokens; -} - -void load_nnet(const std::string& filename, std::vector& layers, std::vector& activations, - std::vector>>& weights, std::vector>& biases) { - std::ifstream input_file(filename); - if (!input_file) { - std::cerr << "Could not open file: " << filename << std::endl; - exit(1); - } - - std::string line; - std::getline(input_file, line); - int num_layers = std::stoi(line); - - std::getline(input_file, line); - std::vector layer_sizes_str = split_line(line); - for (const auto& size_str : layer_sizes_str) { - layers.push_back(std::stoi(size_str)); - } - - std::getline(input_file, line); - activations = split_line(line); - - // Skip input mins, max, means, ranges - for (int i = 0; i < 6; ++i) { - std::getline(input_file, line); - } - - for (int i = 0; i < num_layers; ++i) { - std::vector> layer_weights; - int weight_next_layer = layers[i + 1]; - int weight_cur_layer = layers[i]; - - for (int j = 0; j < weight_next_layer; ++j) { - std::getline(input_file, line); - std::vector weights_next_str = split_line(line); - if (weights_next_str.size() != weight_cur_layer) { - std::cerr << "Error: Expected " << weight_cur_layer << " columns but got " << weights_next_str.size() << std::endl; - exit(1); - } - std::vector weights_next; - for (const auto& weight_str : weights_next_str) { - weights_next.push_back(std::stof(weight_str)); - } - layer_weights.push_back(weights_next); - } - weights.push_back(layer_weights); - - std::getline(input_file, line); - std::vector biases_next_str = split_line(line); - if (biases_next_str.size() != weight_next_layer) { - std::cerr << "Error: Expected " << weight_next_layer << " biases but got " << biases_next_str.size() << std::endl; - exit(1); - } - std::vector layer_biases; - for (const auto& bias_str : biases_next_str) { - layer_biases.push_back(std::stof(bias_str)); - } - biases.push_back(layer_biases); - } - input_file.close(); - std::cout<<"done loading the network!"<< std::endl; -} - -CustomDNN::CustomDNN(const std::vector& layer_sizes, const std::vector& activation_functions, - const std::vector>>& weights, const std::vector>& biases) { - for (size_t i = 0; i < layer_sizes.size() - 1; ++i) { - auto layer = register_module("fc" + std::to_string(i), torch::nn::Linear(layer_sizes[i], layer_sizes[i+1])); - linear_layers.push_back(layer); - activations.push_back(activation_functions[i]); - - std::vector flattened_weights; - for (const auto& row : weights[i]) { - flattened_weights.insert(flattened_weights.end(), row.begin(), row.end()); - } - - torch::Tensor weight_tensor = torch::tensor(flattened_weights, torch::kFloat).view({layer_sizes[i+1], layer_sizes[i]}); - torch::Tensor bias_tensor = torch::tensor(biases[i], torch::kFloat); - - layer->weight.data().copy_(weight_tensor); - layer->bias.data().copy_(bias_tensor); - } -} - -torch::Tensor CustomDNN::forward(torch::Tensor x) { - for (size_t i = 0; i < linear_layers.size(); ++i) { - x = linear_layers[i]->forward(x); - if (activations[i] == "ReLU") { - x = torch::relu(x); - } else if (activations[i] == "Sigmoid") { - x = torch::sigmoid(x); - } else if (activations[i] == "Tanh") { - x = torch::tanh(x); - } else if (activations[i] == "Softmax") { - x = torch::softmax(x, 1); - } - } - return x; -} diff --git a/src/engine/attack/PGD_Linf_Rand/read_net.h b/src/engine/attack/PGD_Linf_Rand/read_net.h deleted file mode 100644 index 362106b922..0000000000 --- a/src/engine/attack/PGD_Linf_Rand/read_net.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef READ_NET_H -#define READ_NET_H - -#include -#include -#include - -std::vector split_line(const std::string& line); - -void load_nnet(const std::string& filename, std::vector& layers, std::vector& activations, - std::vector>>& weights, std::vector>& biases); - -struct CustomDNN : torch::nn::Module { - std::vector linear_layers; - std::vector activations; - - CustomDNN(const std::vector& layer_sizes, const std::vector& activation_functions, - const std::vector>>& weights, const std::vector>& biases); - - torch::Tensor forward(torch::Tensor x); -}; -TORCH_MODULE(CustomDNN); - -#endif // READ_NET_H From fb07f91fe9fcea0bd76680cc8c59511319cd069d Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 19 Jun 2024 09:59:07 +0300 Subject: [PATCH 03/69] cmake --- CMakeLists.txt | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1eb14ad2ac..4d80b50ab7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,16 +7,6 @@ add_definitions("-DMARABOU_VERSION=\"${MARABOU_VERSION}\"") set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) -if (NOT MSVC) - if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") - set(COMPILE_FLAGS -Wall -Wextra -Werror -MMD -Qunused-arguments -Wno-deprecated-declarations -Wno-unused-but-set-variable -Wno-dangling-reference) - elseif (CMAKE_BUILD_TYPE MATCHES "Release") - set(COMPILE_FLAGS -Wall -Wno-dangling-reference) - else() - set(COMPILE_FLAGS -Wall -Wextra -Werror -MMD -Wno-dangling-reference) #-Wno-deprecated - endif() - set(RELEASE_FLAGS ${COMPILE_FLAGS} -O3) #-Wno-deprecated -endif() ################## ## User options ## From d7e67ef0af33749beda586cfc1e643adf940321e Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 19 Jun 2024 12:24:53 +0300 Subject: [PATCH 04/69] fix --- .vscode/launch.json | 7 +++++++ src/engine/CMakeLists.txt | 2 -- src/engine/{attack => }/CustomDNN.cpp | 7 ++----- src/engine/{attack => }/CustomDNN.h | 13 +++---------- src/engine/{attack => }/PGD.cpp | 6 +++--- src/engine/{attack => }/PGD.h | 10 +--------- src/engine/Preprocessor.cpp | 12 ++++-------- 7 files changed, 20 insertions(+), 37 deletions(-) create mode 100644 .vscode/launch.json rename src/engine/{attack => }/CustomDNN.cpp (96%) rename src/engine/{attack => }/CustomDNN.h (81%) rename src/engine/{attack => }/PGD.cpp (95%) rename src/engine/{attack => }/PGD.h (79%) diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000000..5c7247b40a --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,7 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [] +} \ No newline at end of file diff --git a/src/engine/CMakeLists.txt b/src/engine/CMakeLists.txt index 9319ec23e5..afe7d2ad6c 100644 --- a/src/engine/CMakeLists.txt +++ b/src/engine/CMakeLists.txt @@ -1,8 +1,6 @@ file(GLOB SRCS "*.cpp") file(GLOB HEADERS "*.h") -file(GLOB ATTACK_SRCS "attack/*.cpp") -file(GLOB ATTACK_HEADERS "attack/*.h") target_sources(${MARABOU_LIB} PRIVATE ${SRCS}) diff --git a/src/engine/attack/CustomDNN.cpp b/src/engine/CustomDNN.cpp similarity index 96% rename from src/engine/attack/CustomDNN.cpp rename to src/engine/CustomDNN.cpp index 689ad56a46..b39793f845 100644 --- a/src/engine/attack/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -3,10 +3,9 @@ #include "CustomDNN.h" #include "NetworkLevelReasoner.h" -namespace attack{ CustomDNNImpl::CustomDNNImpl(const std::vector& layerSizes, const std::vector& activationFunctions, const std::vector>>& weights, const std::vector>& biases){ - for (size_t i = 0; i < layerSizes.size() - 1; ++i) { + for (int i = 0; i < layerSizes.size() - 1; ++i) { auto layer = register_module("fc" + std::to_string(i), torch::nn::Linear(layerSizes[i], layerSizes[i+1])); linearLayers.push_back(layer); activations.push_back(activationFunctions[i]); @@ -33,7 +32,7 @@ CustomDNNImpl::CustomDNNImpl(NLR::NetworkLevelReasoner& nlr){ std::vector> biases; int numLayers = nlr.getNumberOfLayers(); - for (unsigned i = 0; i < numLayers; ++i){ + for (int i = 0; i < numLayers; ++i){ const NLR::Layer* layer = nlr.getLayer(i); layerSizes.push_back(layer->getSize()); @@ -98,5 +97,3 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { } return x; } - -} \ No newline at end of file diff --git a/src/engine/attack/CustomDNN.h b/src/engine/CustomDNN.h similarity index 81% rename from src/engine/attack/CustomDNN.h rename to src/engine/CustomDNN.h index 16d945e09d..cf4cbfac6d 100644 --- a/src/engine/attack/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -3,16 +3,13 @@ #include -#ifdef LOG -#undef LOG -#endif + #include #include #include "NetworkLevelReasoner.h" -namespace attack { class CustomDNNImpl : public torch::nn::Module { public: @@ -24,13 +21,9 @@ class CustomDNNImpl : public torch::nn::Module { CustomDNNImpl(const std::vector& layer_sizes, const std::vector& activationFunctions, const std::vector>>& weights, const std::vector>& biases); - CustomDNNImpl(const NLR::NetworkLevelReasoner& nlr); + CustomDNNImpl(NLR::NetworkLevelReasoner& nlr); torch::Tensor forward(torch::Tensor x); }; -TORCH_MODULE(CustomDNN); - -} - -#endif // CUSTOM_DNN_H +#endif \ No newline at end of file diff --git a/src/engine/attack/PGD.cpp b/src/engine/PGD.cpp similarity index 95% rename from src/engine/attack/PGD.cpp rename to src/engine/PGD.cpp index f918a92058..1ba6d7ee0d 100644 --- a/src/engine/attack/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,7 +1,7 @@ #include "PGD.h" #include -namespace attack { + torch::Tensor findDelta(CustomDNNImpl& model, const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter, torch::Device device) { torch::Tensor delta = torch::zeros_like(X).uniform_(-epsilon, epsilon).to(device); @@ -11,7 +11,7 @@ torch::Tensor findDelta(CustomDNNImpl& model, const torch::Tensor& X, int y, flo torch::optim::SGD optimizer(model.parameters(), torch::optim::SGDOptions(0.01).momentum(0.9)); - for (unsigned i = 0; i < num_iter; ++i) { + for (int i = 0; i < num_iter; ++i) { optimizer.zero_grad(); if (delta.grad().defined()) { delta.grad().zero_(); @@ -50,4 +50,4 @@ bool displayAdversarialExample(CustomDNNImpl& model, const torch::Tensor& input, return is_fooled; } -} // namespace attack + diff --git a/src/engine/attack/PGD.h b/src/engine/PGD.h similarity index 79% rename from src/engine/attack/PGD.h rename to src/engine/PGD.h index 8a1ad2a556..47b9d1b1c6 100644 --- a/src/engine/attack/PGD.h +++ b/src/engine/PGD.h @@ -2,18 +2,10 @@ #define PGD_H #include - -#ifdef LOG -#undef LOG -#endif - #include "CustomDNN.h" -namespace attack { - torch::Tensor findDelta(CustomDNNImpl& model, const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter, torch::Device device); bool displayAdversarialExample(CustomDNNImpl& model, const torch::Tensor& input, int target, torch::Device device); -} // namespace attack -#endif // PGD_H +#endif diff --git a/src/engine/Preprocessor.cpp b/src/engine/Preprocessor.cpp index 91e1490329..1b298c3337 100644 --- a/src/engine/Preprocessor.cpp +++ b/src/engine/Preprocessor.cpp @@ -15,10 +15,6 @@ #include -#ifdef LOG -#undef LOG -#endif - #include "Preprocessor.h" #include "Debug.h" @@ -32,8 +28,8 @@ #include "PiecewiseLinearFunctionType.h" #include "Statistics.h" #include "Tightening.h" -#include "attack/CustomDNN.h" -#include "attack/PGD.h" +#include "CustomDNN.h" +#include "PGD.h" #ifdef _WIN32 #undef INFINITE #endif @@ -181,11 +177,11 @@ std::unique_ptr Preprocessor::preprocess( const InputQuery &query, ASSERT( _preprocessed->getLowerBounds().size() == _preprocessed->getNumberOfVariables() ); ASSERT( _preprocessed->getUpperBounds().size() == _preprocessed->getNumberOfVariables() ); - attack::CustomDNNImpl network = attack::CustomDNNImpl(*(_preprocessed->_networkLevelReasoner)); + CustomDNNImpl network = CustomDNNImpl(*(_preprocessed->_networkLevelReasoner)); torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); int target = 0; torch::Device device(torch::kCPU); - attack::displayAdversarialExample(network, input, target, device); + displayAdversarialExample(network, input, target, device); String networkFilePath = Options::get()->getString( Options::INPUT_FILE_PATH ); From 96f31ef4ec3da8caecf19e67f7f943466f5b76b0 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 25 Jun 2024 15:44:55 +0300 Subject: [PATCH 05/69] all --- CMakeLists.txt | 44 ++++++++++++++++--- src/basis_factorization/GaussianEliminator.h | 2 +- src/basis_factorization/LUFactorization.h | 2 +- .../SparseFTFactorization.h | 2 +- .../SparseGaussianEliminator.h | 2 +- .../SparseLUFactorization.h | 2 +- src/cegar/IncrementalLinearization.h | 2 +- src/engine/DantzigsRule.h | 2 +- src/engine/DnCManager.h | 2 +- src/engine/InputQuery.cpp | 2 +- src/engine/PLConstraintScoreTracker.h | 2 +- src/engine/ProjectedSteepestEdge.h | 2 +- src/nlr/IterativePropagator.h | 2 +- src/nlr/LPFormulator.h | 2 +- 14 files changed, 51 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d80b50ab7..d347a35a73 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,6 +104,43 @@ endif() set(LIBS_INCLUDES ${Boost_INCLUDE_DIRS}) list(APPEND LIBS ${Boost_LIBRARIES}) +########### +## torch ## +########### + +# set(TORCH_VERSION 1.10.0) +# set(TOOLS_DIR "${CMAKE_SOURCE_DIR}/tools") +# set(Torch_DIR "${TOOLS_DIR}/libtorch/libtorch/share/cmake/Torch") + +# find_package(Torch QUIET PATHS ${Torch_DIR} NO_DEFAULT_PATH) +# if(NOT Torch_FOUND) +# message(STATUS "Libtorch not found, attempting to download...") +# execute_process( +# COMMAND "${TOOLS_DIR}/download_libtorch.${SCRIPT_EXTENSION}" ${TORCH_VERSION} +# RESULT_VARIABLE SCRIPT_RESULT +# WORKING_DIRECTORY ${TOOLS_DIR} +# OUTPUT_VARIABLE DOWNLOAD_OUTPUT +# ERROR_VARIABLE DOWNLOAD_ERRORS) + +# find_package(Torch REQUIRED PATHS ${Torch_DIR} NO_DEFAULT_PATH) +# endif() + +# include_directories(${TORCH_INCLUDE_DIRS}) +# link_libraries(APPEND LIBS ${TORCH_LIBRARIES}) + +if (NOT TORCH_DIR) + set(TORCH_DIR "${TOOLS_DIR}/libtorch/libtorch") +endif() + + +set(TORCH_LIB torch) +add_library(${TORCH_LIB} SHARED IMPORTED) +set_property(TARGET ${TORCH_LIB} PROPERTY POSITION_INDEPENDENT_CODE ON) +set_target_properties(${TORCH_LIB} PROPERTIES IMPORTED_LOCATION ${TORCH_DIR}/lib/libtorch.so) +target_include_directories(${TORCH_LIB} INTERFACE ${TORCH_DIR}/include/torch/csrc/api/include) +list(APPEND LIBS ${TORCH_LIB}) + + ############## ## Protobuf ## ############## @@ -328,12 +365,7 @@ target_compile_options(${MARABOU_LIB} PRIVATE ${RELEASE_FLAGS}) target_link_libraries(${MARABOU_EXE} ${MARABOU_LIB}) target_include_directories(${MARABOU_EXE} PRIVATE ${LIBS_INCLUDES}) -# libtorch -list(APPEND CMAKE_PREFIX_PATH "~/libtorch/libtorch/share/cmake/Torch") -find_package(Torch REQUIRED) -target_link_libraries(${MARABOU_LIB} "${TORCH_LIBRARIES}") -target_include_directories(${MARABOU_LIB} PRIVATE "${TORCH_INCLUDE_DIRS}") -set(CMAKE_PREFIX_PATH "~/libtorch/libtorch") + ###################### ## Build Python API ## diff --git a/src/basis_factorization/GaussianEliminator.h b/src/basis_factorization/GaussianEliminator.h index 2177021e55..6f93605ff6 100644 --- a/src/basis_factorization/GaussianEliminator.h +++ b/src/basis_factorization/GaussianEliminator.h @@ -19,7 +19,7 @@ #include "LUFactors.h" #define GAUSSIAN_LOG( x, ... ) \ - LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "GaussianEliminator: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "GaussianEliminator: %s\n", x ) class GaussianEliminator { diff --git a/src/basis_factorization/LUFactorization.h b/src/basis_factorization/LUFactorization.h index 400d53eb88..ae4befd5e7 100644 --- a/src/basis_factorization/LUFactorization.h +++ b/src/basis_factorization/LUFactorization.h @@ -22,7 +22,7 @@ #include "List.h" #define LU_FACTORIZATION_LOG( x, ... ) \ - LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "LUFactorization: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "LUFactorization: %s\n", x ) class EtaMatrix; class LPElement; diff --git a/src/basis_factorization/SparseFTFactorization.h b/src/basis_factorization/SparseFTFactorization.h index 906f5b205e..b885cab4b2 100644 --- a/src/basis_factorization/SparseFTFactorization.h +++ b/src/basis_factorization/SparseFTFactorization.h @@ -24,7 +24,7 @@ #include "Statistics.h" #define SFTF_FACTORIZATION_LOG( x, ... ) \ - LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseFTFactorization: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseFTFactorization: %s\n", x ) /* This class performs a sparse FT factorization of a given matrix. diff --git a/src/basis_factorization/SparseGaussianEliminator.h b/src/basis_factorization/SparseGaussianEliminator.h index 48078b42d9..fd6a061dce 100644 --- a/src/basis_factorization/SparseGaussianEliminator.h +++ b/src/basis_factorization/SparseGaussianEliminator.h @@ -23,7 +23,7 @@ #include "Statistics.h" #define SGAUSSIAN_LOG( x, ... ) \ - LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "SparseGaussianEliminator: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "SparseGaussianEliminator: %s\n", x ) class SparseGaussianEliminator { diff --git a/src/basis_factorization/SparseLUFactorization.h b/src/basis_factorization/SparseLUFactorization.h index 7b925fec48..7d75ebe3c4 100644 --- a/src/basis_factorization/SparseLUFactorization.h +++ b/src/basis_factorization/SparseLUFactorization.h @@ -22,7 +22,7 @@ #include "SparseLUFactors.h" #define BASIS_FACTORIZATION_LOG( x, ... ) \ - LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseLUFactorization: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseLUFactorization: %s\n", x ) class EtaMatrix; class LPElement; diff --git a/src/cegar/IncrementalLinearization.h b/src/cegar/IncrementalLinearization.h index bd0c4d6ef0..a188df3a77 100644 --- a/src/cegar/IncrementalLinearization.h +++ b/src/cegar/IncrementalLinearization.h @@ -20,7 +20,7 @@ #include "Map.h" #define INCREMENTAL_LINEARIZATION_LOG( x, ... ) \ - LOG( GlobalConfiguration::CEGAR_LOGGING, "IncrementalLinearization: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::CEGAR_LOGGING, "IncrementalLinearization: %s\n", x ) class Engine; class InputQuery; diff --git a/src/engine/DantzigsRule.h b/src/engine/DantzigsRule.h index 5e57e28c24..b3fda42e77 100644 --- a/src/engine/DantzigsRule.h +++ b/src/engine/DantzigsRule.h @@ -19,7 +19,7 @@ #include "EntrySelectionStrategy.h" #define DANTZIG_LOG( x, ... ) \ - LOG( GlobalConfiguration::DANTZIGS_RULE_LOGGING, "DantzigsRule: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::DANTZIGS_RULE_LOGGING, "DantzigsRule: %s\n", x ) class String; diff --git a/src/engine/DnCManager.h b/src/engine/DnCManager.h index e8e50cac39..de0111c00c 100644 --- a/src/engine/DnCManager.h +++ b/src/engine/DnCManager.h @@ -25,7 +25,7 @@ #include #define DNC_MANAGER_LOG( x, ... ) \ - LOG( GlobalConfiguration::DNC_MANAGER_LOGGING, "DnCManager: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::DNC_MANAGER_LOGGING, "DnCManager: %s\n", x ) class DnCManager { diff --git a/src/engine/InputQuery.cpp b/src/engine/InputQuery.cpp index 877ed2738b..657a764d2f 100644 --- a/src/engine/InputQuery.cpp +++ b/src/engine/InputQuery.cpp @@ -29,7 +29,7 @@ #include "SymbolicBoundTighteningType.h" #define INPUT_QUERY_LOG( x, ... ) \ - LOG( GlobalConfiguration::INPUT_QUERY_LOGGING, "Input Query: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::INPUT_QUERY_LOGGING, "Input Query: %s\n", x ) InputQuery::InputQuery() : _ensureSameSourceLayerInNLR( Options::get()->getSymbolicBoundTighteningType() == diff --git a/src/engine/PLConstraintScoreTracker.h b/src/engine/PLConstraintScoreTracker.h index ab62333e6b..6798074dd2 100644 --- a/src/engine/PLConstraintScoreTracker.h +++ b/src/engine/PLConstraintScoreTracker.h @@ -24,7 +24,7 @@ #include #define SCORE_TRACKER_LOG( x, ... ) \ - LOG( GlobalConfiguration::SCORE_TRACKER_LOGGING, "PLConstraintScoreTracker: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::SCORE_TRACKER_LOGGING, "PLConstraintScoreTracker: %s\n", x ) struct ScoreEntry { diff --git a/src/engine/ProjectedSteepestEdge.h b/src/engine/ProjectedSteepestEdge.h index 70b3265ef0..c84ba9bac9 100644 --- a/src/engine/ProjectedSteepestEdge.h +++ b/src/engine/ProjectedSteepestEdge.h @@ -20,7 +20,7 @@ #include "SparseUnsortedList.h" #define PSE_LOG( x, ... ) \ - LOG( GlobalConfiguration::PROJECTED_STEEPEST_EDGE_LOGGING, "Projected SE: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::PROJECTED_STEEPEST_EDGE_LOGGING, "Projected SE: %s\n", x ) class ProjectedSteepestEdgeRule : public IProjectedSteepestEdgeRule { diff --git a/src/nlr/IterativePropagator.h b/src/nlr/IterativePropagator.h index 7a7fba671a..0c3a593f89 100644 --- a/src/nlr/IterativePropagator.h +++ b/src/nlr/IterativePropagator.h @@ -27,7 +27,7 @@ namespace NLR { #define IterativePropagator_LOG( x, ... ) \ - LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "Iterativepropagator: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "Iterativepropagator: %s\n", x ) class IterativePropagator : public ParallelSolver { diff --git a/src/nlr/LPFormulator.h b/src/nlr/LPFormulator.h index 9a12a9e617..3d6d527360 100644 --- a/src/nlr/LPFormulator.h +++ b/src/nlr/LPFormulator.h @@ -31,7 +31,7 @@ namespace NLR { #define LPFormulator_LOG( x, ... ) \ - LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "LP Preprocessor: %s\n", x ) + MARABOU_LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "LP Preprocessor: %s\n", x ) class LPFormulator : public ParallelSolver { From 502118cdf2e0cf38d326f0413ec140b67cd53dda Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 26 Jun 2024 08:58:15 +0300 Subject: [PATCH 06/69] install torch --- CMakeLists.txt | 17 ++- src/common/Debug.h | 4 +- src/engine/CDSmtCore.h | 2 +- src/engine/CustomDNN.cpp | 161 +++++++++++++---------- src/engine/CustomDNN.h | 24 ++-- src/engine/Engine.h | 2 +- src/engine/PGD.cpp | 55 +++++--- src/engine/PGD.h | 18 ++- src/engine/SmtCore.h | 2 +- src/engine/SumOfInfeasibilitiesManager.h | 2 +- src/engine/Tableau.h | 2 +- src/input_parsers/MpsParser.h | 2 +- src/input_parsers/OnnxParser.h | 2 +- src/nlr/NetworkLevelReasoner.cpp | 2 +- src/query_loader/QueryLoader.h | 2 +- tools/download_libtorch.bat | 14 ++ tools/download_libtorch.sh | 13 ++ 17 files changed, 208 insertions(+), 116 deletions(-) create mode 100644 tools/download_libtorch.bat create mode 100755 tools/download_libtorch.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index d347a35a73..54735fb5ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -128,19 +128,32 @@ list(APPEND LIBS ${Boost_LIBRARIES}) # include_directories(${TORCH_INCLUDE_DIRS}) # link_libraries(APPEND LIBS ${TORCH_LIBRARIES}) +set(TORCH_VERSION 1.10.0) if (NOT TORCH_DIR) - set(TORCH_DIR "${TOOLS_DIR}/libtorch/libtorch") + set(TORCH_DIR "${TOOLS_DIR}/libtorch") endif() +if(NOT Torch_FOUND) + message(STATUS "Libtorch not found, attempting to download...") + execute_process( + COMMAND "${TOOLS_DIR}/download_libtorch.${SCRIPT_EXTENSION}" ${TORCH_VERSION} + RESULT_VARIABLE SCRIPT_RESULT + WORKING_DIRECTORY ${TOOLS_DIR} + OUTPUT_VARIABLE DOWNLOAD_OUTPUT + ERROR_VARIABLE DOWNLOAD_ERRORS) + + find_package(Torch REQUIRED PATHS ${Torch_DIR} NO_DEFAULT_PATH) +endif() set(TORCH_LIB torch) add_library(${TORCH_LIB} SHARED IMPORTED) -set_property(TARGET ${TORCH_LIB} PROPERTY POSITION_INDEPENDENT_CODE ON) set_target_properties(${TORCH_LIB} PROPERTIES IMPORTED_LOCATION ${TORCH_DIR}/lib/libtorch.so) +target_include_directories(${TORCH_LIB} INTERFACE ${TORCH_DIR}/include) target_include_directories(${TORCH_LIB} INTERFACE ${TORCH_DIR}/include/torch/csrc/api/include) list(APPEND LIBS ${TORCH_LIB}) + ############## ## Protobuf ## ############## diff --git a/src/common/Debug.h b/src/common/Debug.h index 55dfda4a92..a6d9d67907 100644 --- a/src/common/Debug.h +++ b/src/common/Debug.h @@ -27,7 +27,7 @@ #endif #ifndef NDEBUG -#define LOG( x, f, y, ... ) \ +#define MARABOU_LOG( x, f, y, ... ) \ { \ if ( ( x ) ) \ { \ @@ -35,7 +35,7 @@ } \ } #else -#define LOG( x, f, y, ... ) \ +#define MARABOU_LOG( x, f, y, ... ) \ { \ } #endif diff --git a/src/engine/CDSmtCore.h b/src/engine/CDSmtCore.h index 8cbeebc5c0..a352f2c6ec 100644 --- a/src/engine/CDSmtCore.h +++ b/src/engine/CDSmtCore.h @@ -76,7 +76,7 @@ #include "context/cdlist.h" #include "context/context.h" -#define SMT_LOG( x, ... ) LOG( GlobalConfiguration::SMT_CORE_LOGGING, "CDSmtCore: %s\n", x ) +#define SMT_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::SMT_CORE_LOGGING, "CDSmtCore: %s\n", x ) class EngineState; class Engine; diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index b39793f845..b3e98f17ba 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,99 +1,128 @@ - - #include "CustomDNN.h" + #include "NetworkLevelReasoner.h" -CustomDNNImpl::CustomDNNImpl(const std::vector& layerSizes, const std::vector& activationFunctions, - const std::vector>>& weights, const std::vector>& biases){ - for (int i = 0; i < layerSizes.size() - 1; ++i) { - auto layer = register_module("fc" + std::to_string(i), torch::nn::Linear(layerSizes[i], layerSizes[i+1])); - linearLayers.push_back(layer); - activations.push_back(activationFunctions[i]); - +CustomDNNImpl::CustomDNNImpl( const std::vector &layerSizes, + const std::vector &activationFunctions, + const std::vector>> &weights, + const std::vector> &biases ) +{ + for ( size_t i = 0; i < layerSizes.size() - 1; ++i ) + { + auto layer = register_module( "fc" + std::to_string( i ), + torch::nn::Linear( layerSizes[i], layerSizes[i + 1] ) ); + linearLayers.push_back( layer ); + activations.push_back( activationFunctions[i] ); + std::vector flattened_weights; - for (const auto& row : weights[i]) { - flattened_weights.insert(flattened_weights.end(), row.begin(), row.end()); - } + for ( const auto &weight : weights[i] ) + { + flattened_weights.insert( flattened_weights.end(), weight.begin(), weight.end() ); + } + - torch::Tensor weightTensor = torch::tensor(flattened_weights, torch::kFloat).view({layerSizes[i+1], layerSizes[i]}); - torch::Tensor biasTensor = torch::tensor(biases[i], torch::kFloat); + torch::Tensor weightTensor = torch::tensor( flattened_weights, torch::kFloat ); + weightTensor = weightTensor.view( { layerSizes[i + 1], layerSizes[i] } ); - layer->weight.data().copy_(weightTensor); - layer->bias.data().copy_(biasTensor); + torch::Tensor biasTensor = torch::tensor( biases[i], torch::kFloat ); + + layer->weight.data().copy_( weightTensor ); + layer->bias.data().copy_( biasTensor ); } } -CustomDNNImpl::CustomDNNImpl(NLR::NetworkLevelReasoner& nlr){ - +CustomDNNImpl::CustomDNNImpl( NLR::NetworkLevelReasoner &nlr ) +{ std::vector layerSizes; std::vector activationFunctions; std::vector>> weights; std::vector> biases; int numLayers = nlr.getNumberOfLayers(); - for (int i = 0; i < numLayers; ++i){ - const NLR::Layer* layer = nlr.getLayer(i); - layerSizes.push_back(layer->getSize()); - - switch (layer->getLayerType()){ - case NLR::Layer::RELU: - activationFunctions.push_back("relu"); - break; - case NLR::Layer::SIGMOID: - activationFunctions.push_back("sigmoid"); - break; - default: - activationFunctions.push_back("none"); - break; + for ( int i = 0; i < numLayers; ++i ) + { + const NLR::Layer *layer = nlr.getLayer( i ); + layerSizes.push_back( layer->getSize() ); + + switch ( layer->getLayerType() ) + { + case NLR::Layer::RELU: + activationFunctions.push_back( "relu" ); + break; + case NLR::Layer::SIGMOID: + activationFunctions.push_back( "sigmoid" ); + break; + default: + activationFunctions.push_back( "none" ); + break; } - if (i < numLayers -1){ - const NLR::Layer* nextLayer = nlr.getLayer(i+1); - std::vector> layerWeights(nextLayer->getSize(), std::vector(layer->getSize())); - std::vector layerBiases(layer->getSize()); + if ( i < numLayers - 1 ) + { + const NLR::Layer *nextLayer = nlr.getLayer( i + 1 ); + std::vector> layerWeights( nextLayer->getSize(), + std::vector( layer->getSize() ) ); + std::vector layerBiases( layer->getSize() ); - for (unsigned j=0; jgetSize(); j++){ - for (unsigned k=0; k< layer->getSize(); ++k){ - layerWeights[j][k] = static_cast(nlr.getLayer(i)->getWeight(i, k, j)); + for ( unsigned j = 0; j < nextLayer->getSize(); j++ ) + { + for ( unsigned k = 0; k < layer->getSize(); ++k ) + { + layerWeights[j][k] = + static_cast( nlr.getLayer( i )->getWeight( i, k, j ) ); } } - for (unsigned j = 0; j < nextLayer->getSize(); ++j) { - layerBiases[j] = static_cast(layer->getBias(j)); + for ( unsigned j = 0; j < nextLayer->getSize(); ++j ) + { + layerBiases[j] = static_cast( layer->getBias( j ) ); } - - weights.push_back(layerWeights); - biases.push_back(layerBiases); + + weights.push_back( layerWeights ); + biases.push_back( layerBiases ); } } - for (size_t i = 0; i < layerSizes.size() - 1; ++i) { - linearLayers.push_back(register_module("linear" + std::to_string(i), torch::nn::Linear(layerSizes[i], layerSizes[i+1]))); + for ( size_t i = 0; i < layerSizes.size() - 1; ++i ) + { + linearLayers.push_back( + register_module( "linear" + std::to_string( i ), + torch::nn::Linear( layerSizes[i], layerSizes[i + 1] ) ) ); std::vector flattenedWeights; - for (const auto& row : weights[i]) { - flattenedWeights.insert(flattenedWeights.end(), row.begin(), row.end()); + for ( const auto &weight : weights[i] ) + { + flattenedWeights.insert( flattenedWeights.end(), weight.begin(), weight.end() ); } - torch::Tensor weightTensor = torch::tensor(flattenedWeights, torch::kFloat).view({layerSizes[i+1], layerSizes[i]}); - torch::Tensor biasTensor = torch::tensor(biases[i], torch::kFloat); - auto& linear = linearLayers.back(); - linear->weight.data().copy_(weightTensor); - linear->bias.data().copy_(biasTensor); + torch::Tensor weightTensor = torch::tensor( flattenedWeights, torch::kFloat ) + .view( { layerSizes[i + 1], layerSizes[i] } ); + torch::Tensor biasTensor = torch::tensor( biases[i], torch::kFloat ); + auto &linear = linearLayers.back(); + linear->weight.data().copy_( weightTensor ); + linear->bias.data().copy_( biasTensor ); } - } -torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { - for (size_t i = 0; i < linearLayers.size(); ++i) { - x = linearLayers[i]->forward(x); - if (activations[i] == "ReLU") { - x = torch::relu(x); - } else if (activations[i] == "Sigmoid") { - x = torch::sigmoid(x); - } else if (activations[i] == "Tanh") { - x = torch::tanh(x); - } else if (activations[i] == "Softmax") { - x = torch::softmax(x, 1); +torch::Tensor CustomDNNImpl::forward( torch::Tensor x ) +{ + for ( size_t i = 0; i < linearLayers.size(); ++i ) + { + x = linearLayers[i]->forward( x ); + if ( activations[i] == "ReLU" ) + { + x = torch::relu( x ); + } + else if ( activations[i] == "Sigmoid" ) + { + x = torch::sigmoid( x ); + } + else if ( activations[i] == "Tanh" ) + { + x = torch::tanh( x ); + } + else if ( activations[i] == "Softmax" ) + { + x = torch::softmax( x, 1 ); } } return x; -} +} \ No newline at end of file diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index cf4cbfac6d..6c03edc817 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -1,17 +1,15 @@ #ifndef CUSTOM_DNN_H #define CUSTOM_DNN_H -#include - - - +#include "NetworkLevelReasoner.h" -#include #include -#include "NetworkLevelReasoner.h" +#include +#include -class CustomDNNImpl : public torch::nn::Module { +class CustomDNNImpl : public torch::nn::Module +{ public: std::vector layerSizes; std::vector activations; @@ -19,11 +17,13 @@ class CustomDNNImpl : public torch::nn::Module { std::vector> biases; std::vector linearLayers; - CustomDNNImpl(const std::vector& layer_sizes, const std::vector& activationFunctions, - const std::vector>>& weights, const std::vector>& biases); - CustomDNNImpl(NLR::NetworkLevelReasoner& nlr); + CustomDNNImpl( const std::vector &layer_sizes, + const std::vector &activationFunctions, + const std::vector>> &weights, + const std::vector> &biases ); + CustomDNNImpl( NLR::NetworkLevelReasoner &nlr ); - torch::Tensor forward(torch::Tensor x); + torch::Tensor forward( torch::Tensor x ); }; -#endif \ No newline at end of file +#endif \ No newline at end of file diff --git a/src/engine/Engine.h b/src/engine/Engine.h index feb9ac1279..a3bf2cfdc9 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -56,7 +56,7 @@ #undef ERROR #endif -#define ENGINE_LOG( x, ... ) LOG( GlobalConfiguration::ENGINE_LOGGING, "Engine: %s\n", x ) +#define ENGINE_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::ENGINE_LOGGING, "Engine: %s\n", x ) class EngineState; class InputQuery; diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 1ba6d7ee0d..400ae1b39c 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,53 +1,66 @@ #include "PGD.h" -#include +#include -torch::Tensor findDelta(CustomDNNImpl& model, const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter, torch::Device device) { - torch::Tensor delta = torch::zeros_like(X).uniform_(-epsilon, epsilon).to(device); - delta.set_requires_grad(true); +torch::Tensor findDelta( CustomDNNImpl &model, + const torch::Tensor &X, + int y, + float epsilon, + float alpha, + int num_iter, + torch::Device device ) +{ + torch::Tensor delta = torch::zeros_like( X ).uniform_( -epsilon, epsilon ).to( device ); + delta.set_requires_grad( true ); - torch::Tensor target = torch::tensor({y}, torch::kInt64).to(device); + torch::Tensor target = torch::tensor( { y }, torch::kInt64 ).to( device ); - torch::optim::SGD optimizer(model.parameters(), torch::optim::SGDOptions(0.01).momentum(0.9)); + torch::optim::SGD optimizer( model.parameters(), + torch::optim::SGDOptions( 0.01 ).momentum( 0.9 ) ); - for (int i = 0; i < num_iter; ++i) { + for ( int i = 0; i < num_iter; ++i ) + { optimizer.zero_grad(); - if (delta.grad().defined()) { + if ( delta.grad().defined() ) + { delta.grad().zero_(); } - torch::Tensor pred = model.forward(X + delta); - torch::Tensor loss = torch::nn::functional::cross_entropy(pred, target); + torch::Tensor pred = model.forward( X + delta ); + torch::Tensor loss = torch::nn::functional::cross_entropy( pred, target ); loss.backward(); - delta = (delta + alpha * delta.grad().sign()).clamp(-epsilon, epsilon).detach(); - delta.set_requires_grad(true); + delta = ( delta + alpha * delta.grad().sign() ).clamp( -epsilon, epsilon ).detach(); + delta.set_requires_grad( true ); } return delta; } -bool displayAdversarialExample(CustomDNNImpl& model, const torch::Tensor& input, int target, torch::Device device) { +bool displayAdversarialExample( CustomDNNImpl &model, + const torch::Tensor &input, + int target, + torch::Device device ) +{ std::cout << "starting the attack" << std::endl; - auto x = input.to(device); + auto x = input.to( device ); float epsilon = 0.1; float alpha = 0.01; int num_iter = 40; - torch::Tensor adversarial_delta = findDelta(model, x, target, epsilon, alpha, num_iter, device); + torch::Tensor adversarial_delta = + findDelta( model, x, target, epsilon, alpha, num_iter, device ); torch::Tensor adversarial_x = x + adversarial_delta; - auto original_pred = model.forward(x).argmax(1); - auto adversarial_pred = model.forward(adversarial_x).argmax(1); + auto original_pred = model.forward( x ).argmax( 1 ); + auto adversarial_pred = model.forward( adversarial_x ).argmax( 1 ); bool is_fooled = original_pred.item() != adversarial_pred.item(); std::cout << "Original Prediction: " << original_pred.item() << "\n"; std::cout << "Adversarial Prediction: " << adversarial_pred.item() << "\n"; - std::cout << "Model fooled: " << (is_fooled ? "Yes" : "No") << std::endl; + std::cout << "Model fooled: " << ( is_fooled ? "Yes" : "No" ) << std::endl; return is_fooled; -} - - +} \ No newline at end of file diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 47b9d1b1c6..b739c97e0c 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -1,11 +1,21 @@ #ifndef PGD_H #define PGD_H -#include #include "CustomDNN.h" -torch::Tensor findDelta(CustomDNNImpl& model, const torch::Tensor& X, int y, float epsilon, float alpha, int num_iter, torch::Device device); -bool displayAdversarialExample(CustomDNNImpl& model, const torch::Tensor& input, int target, torch::Device device); +#include +torch::Tensor findDelta( CustomDNNImpl &model, + const torch::Tensor &X, + int y, + float epsilon, + float alpha, + int num_iter, + torch::Device device ); +bool displayAdversarialExample( CustomDNNImpl &model, + const torch::Tensor &input, + int target, + torch::Device device ); -#endif + +#endif \ No newline at end of file diff --git a/src/engine/SmtCore.h b/src/engine/SmtCore.h index ad1d61f8e9..0274d475b6 100644 --- a/src/engine/SmtCore.h +++ b/src/engine/SmtCore.h @@ -28,7 +28,7 @@ #include -#define SMT_LOG( x, ... ) LOG( GlobalConfiguration::SMT_CORE_LOGGING, "SmtCore: %s\n", x ) +#define SMT_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::SMT_CORE_LOGGING, "SmtCore: %s\n", x ) class EngineState; class IEngine; diff --git a/src/engine/SumOfInfeasibilitiesManager.h b/src/engine/SumOfInfeasibilitiesManager.h index ccc67e9e1b..43ba50e7b7 100644 --- a/src/engine/SumOfInfeasibilitiesManager.h +++ b/src/engine/SumOfInfeasibilitiesManager.h @@ -29,7 +29,7 @@ #include "T/stdlib.h" #include "Vector.h" -#define SOI_LOG( x, ... ) LOG( GlobalConfiguration::SOI_LOGGING, "SoIManager: %s\n", x ) +#define SOI_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::SOI_LOGGING, "SoIManager: %s\n", x ) class SumOfInfeasibilitiesManager { diff --git a/src/engine/Tableau.h b/src/engine/Tableau.h index f5bf063f57..175efbe3c8 100644 --- a/src/engine/Tableau.h +++ b/src/engine/Tableau.h @@ -29,7 +29,7 @@ #include "SparseUnsortedList.h" #include "Statistics.h" -#define TABLEAU_LOG( x, ... ) LOG( GlobalConfiguration::TABLEAU_LOGGING, "Tableau: %s\n", x ) +#define TABLEAU_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::TABLEAU_LOGGING, "Tableau: %s\n", x ) class Equation; class ICostFunctionManager; diff --git a/src/input_parsers/MpsParser.h b/src/input_parsers/MpsParser.h index 06e3bf046f..31ebc529ba 100644 --- a/src/input_parsers/MpsParser.h +++ b/src/input_parsers/MpsParser.h @@ -20,7 +20,7 @@ #include "Map.h" #include "Set.h" -#define MPS_LOG( x, ... ) LOG( GlobalConfiguration::MPS_PARSER_LOGGING, "MpsParser: %s\n", x ) +#define MPS_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::MPS_PARSER_LOGGING, "MpsParser: %s\n", x ) class InputQuery; class String; diff --git a/src/input_parsers/OnnxParser.h b/src/input_parsers/OnnxParser.h index e6ce8035a5..4317411ea5 100644 --- a/src/input_parsers/OnnxParser.h +++ b/src/input_parsers/OnnxParser.h @@ -25,7 +25,7 @@ #include "Vector.h" #include "onnx.proto3.pb.h" -#define ONNX_LOG( x, ... ) LOG( GlobalConfiguration::ONNX_PARSER_LOGGING, "OnnxParser: %s\n", x ) +#define ONNX_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::ONNX_PARSER_LOGGING, "OnnxParser: %s\n", x ) class OnnxParser diff --git a/src/nlr/NetworkLevelReasoner.cpp b/src/nlr/NetworkLevelReasoner.cpp index 6d93535021..badb0bbc3d 100644 --- a/src/nlr/NetworkLevelReasoner.cpp +++ b/src/nlr/NetworkLevelReasoner.cpp @@ -34,7 +34,7 @@ #include -#define NLR_LOG( x, ... ) LOG( GlobalConfiguration::NETWORK_LEVEL_REASONER_LOGGING, "NLR: %s\n", x ) +#define NLR_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::NETWORK_LEVEL_REASONER_LOGGING, "NLR: %s\n", x ) namespace NLR { diff --git a/src/query_loader/QueryLoader.h b/src/query_loader/QueryLoader.h index c079cd298d..896aea5105 100644 --- a/src/query_loader/QueryLoader.h +++ b/src/query_loader/QueryLoader.h @@ -19,7 +19,7 @@ #include "InputQuery.h" -#define QL_LOG( x, ... ) LOG( GlobalConfiguration::QUERY_LOADER_LOGGING, "QueryLoader: %s\n", x ) +#define QL_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::QUERY_LOADER_LOGGING, "QueryLoader: %s\n", x ) class QueryLoader { diff --git a/tools/download_libtorch.bat b/tools/download_libtorch.bat new file mode 100644 index 0000000000..87bc81ff8c --- /dev/null +++ b/tools/download_libtorch.bat @@ -0,0 +1,14 @@ +@echo off +set LIBTORCH_VERSION=%1 +set LIBTORCH_DIR=%~dp0 + +set TEMP_DIR=%LIBTORCH_DIR%\temp + +if not exist "%TEMP_DIR%" mkdir "%TEMP_DIR%" + +powershell -command "Invoke-WebRequest -Uri https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-%LIBTORCH_VERSION%+cpu.zip -OutFile %TEMP_DIR%\libtorch.zip" + +powershell -command "Expand-Archive -Path %TEMP_DIR%\libtorch.zip -DestinationPath %LIBTORCH_DIR%" + +del "%TEMP_DIR%\libtorch.zip" +rmdir /s /q "%TEMP_DIR%" diff --git a/tools/download_libtorch.sh b/tools/download_libtorch.sh new file mode 100755 index 0000000000..d378417e3c --- /dev/null +++ b/tools/download_libtorch.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +LIBTORCH_VERSION=$1 +LIBTORCH_DIR=$(dirname $0) + +TEMP_DIR=$(mktemp -d) +mkdir -p ${TEMP_DIR} + +wget https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.3.1%2Bcpu.zip -O ${TEMP_DIR}/libtorch.zip +unzip -o ${TEMP_DIR}/libtorch.zip -d ${LIBTORCH_DIR} +rm ${TEMP_DIR}/libtorch.zip + +rm -rf ${TEMP_DIR} From aac8eb18b92f793de1cc3bd23c4fe6c4d3006e81 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 8 Jul 2024 11:48:17 +0300 Subject: [PATCH 07/69] fix attack and torch --- CMakeLists.txt | 63 +++-------- src/engine/CustomDNN.cpp | 215 +++++++++++++++++------------------- src/engine/CustomDNN.h | 23 ++-- src/engine/Engine.cpp | 19 ++++ src/engine/PGD.cpp | 135 +++++++++++++--------- src/engine/PGD.h | 44 +++++--- src/engine/Preprocessor.cpp | 10 +- tools/download_boost.sh | 2 +- tools/download_libtorch.bat | 2 +- tools/download_libtorch.sh | 22 ++-- tools/download_onnx.sh | 2 +- tools/download_protobuf.sh | 3 +- tools/download_pybind11.sh | 3 +- 13 files changed, 282 insertions(+), 261 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 54735fb5ba..c8a6e9473d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -104,55 +104,6 @@ endif() set(LIBS_INCLUDES ${Boost_INCLUDE_DIRS}) list(APPEND LIBS ${Boost_LIBRARIES}) -########### -## torch ## -########### - -# set(TORCH_VERSION 1.10.0) -# set(TOOLS_DIR "${CMAKE_SOURCE_DIR}/tools") -# set(Torch_DIR "${TOOLS_DIR}/libtorch/libtorch/share/cmake/Torch") - -# find_package(Torch QUIET PATHS ${Torch_DIR} NO_DEFAULT_PATH) -# if(NOT Torch_FOUND) -# message(STATUS "Libtorch not found, attempting to download...") -# execute_process( -# COMMAND "${TOOLS_DIR}/download_libtorch.${SCRIPT_EXTENSION}" ${TORCH_VERSION} -# RESULT_VARIABLE SCRIPT_RESULT -# WORKING_DIRECTORY ${TOOLS_DIR} -# OUTPUT_VARIABLE DOWNLOAD_OUTPUT -# ERROR_VARIABLE DOWNLOAD_ERRORS) - -# find_package(Torch REQUIRED PATHS ${Torch_DIR} NO_DEFAULT_PATH) -# endif() - -# include_directories(${TORCH_INCLUDE_DIRS}) -# link_libraries(APPEND LIBS ${TORCH_LIBRARIES}) - -set(TORCH_VERSION 1.10.0) -if (NOT TORCH_DIR) - set(TORCH_DIR "${TOOLS_DIR}/libtorch") -endif() - -if(NOT Torch_FOUND) - message(STATUS "Libtorch not found, attempting to download...") - execute_process( - COMMAND "${TOOLS_DIR}/download_libtorch.${SCRIPT_EXTENSION}" ${TORCH_VERSION} - RESULT_VARIABLE SCRIPT_RESULT - WORKING_DIRECTORY ${TOOLS_DIR} - OUTPUT_VARIABLE DOWNLOAD_OUTPUT - ERROR_VARIABLE DOWNLOAD_ERRORS) - - find_package(Torch REQUIRED PATHS ${Torch_DIR} NO_DEFAULT_PATH) -endif() - -set(TORCH_LIB torch) -add_library(${TORCH_LIB} SHARED IMPORTED) -set_target_properties(${TORCH_LIB} PROPERTIES IMPORTED_LOCATION ${TORCH_DIR}/lib/libtorch.so) -target_include_directories(${TORCH_LIB} INTERFACE ${TORCH_DIR}/include) -target_include_directories(${TORCH_LIB} INTERFACE ${TORCH_DIR}/include/torch/csrc/api/include) -list(APPEND LIBS ${TORCH_LIB}) - - ############## ## Protobuf ## @@ -197,6 +148,20 @@ endif() file(GLOB DEPS_ONNX "${ONNX_DIR}/*.cc") include_directories(SYSTEM ${ONNX_DIR}) +############# +## Pytorch ## +############# + +set(PYTORCH_VERSION 2.2.1) +set(PYTORCH_DIR "${TOOLS_DIR}/libtorch-${PYTORCH_VERSION}") +list(APPEND CMAKE_PREFIX_PATH ${PYTORCH_DIR}) +if(NOT EXISTS "${PYTORCH_DIR}") + execute_process(COMMAND ${TOOLS_DIR}/download_libtorch.sh ${PYTORCH_VERSION}) +endif() +find_package(Torch ${PYTORCH_VERSION} REQUIRED) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}") +list(APPEND LIBS ${TORCH_LIBRARIES}) + ############ ## Gurobi ## ############ diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index b3e98f17ba..aad6ce984d 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,127 +1,116 @@ #include "CustomDNN.h" - +#include "Vector.h" #include "NetworkLevelReasoner.h" -CustomDNNImpl::CustomDNNImpl( const std::vector &layerSizes, - const std::vector &activationFunctions, - const std::vector>> &weights, - const std::vector> &biases ) -{ - for ( size_t i = 0; i < layerSizes.size() - 1; ++i ) - { - auto layer = register_module( "fc" + std::to_string( i ), - torch::nn::Linear( layerSizes[i], layerSizes[i + 1] ) ); - linearLayers.push_back( layer ); - activations.push_back( activationFunctions[i] ); - - std::vector flattened_weights; - for ( const auto &weight : weights[i] ) - { - flattened_weights.insert( flattened_weights.end(), weight.begin(), weight.end() ); - } - - - torch::Tensor weightTensor = torch::tensor( flattened_weights, torch::kFloat ); - weightTensor = weightTensor.view( { layerSizes[i + 1], layerSizes[i] } ); - - torch::Tensor biasTensor = torch::tensor( biases[i], torch::kFloat ); - - layer->weight.data().copy_( weightTensor ); - layer->bias.data().copy_( biasTensor ); - } -} - - -CustomDNNImpl::CustomDNNImpl( NLR::NetworkLevelReasoner &nlr ) -{ - std::vector layerSizes; - std::vector activationFunctions; - std::vector>> weights; - std::vector> biases; - - int numLayers = nlr.getNumberOfLayers(); - for ( int i = 0; i < numLayers; ++i ) - { - const NLR::Layer *layer = nlr.getLayer( i ); - layerSizes.push_back( layer->getSize() ); - - switch ( layer->getLayerType() ) - { - case NLR::Layer::RELU: - activationFunctions.push_back( "relu" ); - break; - case NLR::Layer::SIGMOID: - activationFunctions.push_back( "sigmoid" ); - break; - default: - activationFunctions.push_back( "none" ); - break; - } - - if ( i < numLayers - 1 ) - { - const NLR::Layer *nextLayer = nlr.getLayer( i + 1 ); - std::vector> layerWeights( nextLayer->getSize(), - std::vector( layer->getSize() ) ); - std::vector layerBiases( layer->getSize() ); +CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReasoner) { + unsigned totalVariables = 0; + unsigned linearLayersNum = 0; + + std::cout << "----- Construct Custom Network -----" << std::endl; + + // Iterate over layers + for (unsigned i = 0; i < networkLevelReasoner->getNumberOfLayers(); i++) { + const NLR::Layer* layer = networkLevelReasoner->getLayer(i); + layerSizes.append(layer->getSize()); + totalVariables += layer->getSize(); + NLR::Layer::Type layerType = layer->getLayerType(); + + if (layerType == NLR::Layer::WEIGHTED_SUM) { + // Fully connected layer + linearLayersNum ++; + unsigned sourceLayer = i - 1; + const NLR::Layer *prevLayer = networkLevelReasoner->getLayer(sourceLayer); + unsigned inputSize = prevLayer->getSize(); + unsigned outputSize = layer->getSize(); + + if (outputSize > 0) { + auto linearLayer = torch::nn::Linear(torch::nn::LinearOptions(inputSize, outputSize)); + linearLayers.append(linearLayer); + register_module("linear" + std::to_string(i), linearLayer); + + Vector> layerWeights(outputSize, Vector(inputSize)); + Vector layerBiases(layer->getSize()); + + // Fetch weights and biases from the networkLevelReasoner + for (unsigned j = 0; j < outputSize; j++) { + for (unsigned k = 0; k < inputSize; k++) { + double weight_value = layer->getWeight(sourceLayer, k, j); + layerWeights[j][k] = static_cast(weight_value); + } + double bias_value = layer->getBias(j); + layerBiases[j] = static_cast(bias_value); + } - for ( unsigned j = 0; j < nextLayer->getSize(); j++ ) - { - for ( unsigned k = 0; k < layer->getSize(); ++k ) - { - layerWeights[j][k] = - static_cast( nlr.getLayer( i )->getWeight( i, k, j ) ); + Vector flattenedWeights; + for (const auto& weight : layerWeights) { + for (const auto& w : weight) { + flattenedWeights.append(w); + } } - } - for ( unsigned j = 0; j < nextLayer->getSize(); ++j ) - { - layerBiases[j] = static_cast( layer->getBias( j ) ); + + torch::Tensor weightTensor = torch::tensor(flattenedWeights.getContainer(), torch::kFloat) + .view({ layer->getSize(), prevLayer->getSize() }); + torch::Tensor biasTensor = torch::tensor(layerBiases.getContainer(), torch::kFloat); + torch::NoGradGuard no_grad; + linearLayer->weight.set_(weightTensor); + linearLayer->bias.set_(biasTensor); } - weights.push_back( layerWeights ); - biases.push_back( layerBiases ); + } else if (layerType == NLR::Layer::RELU || layerType == NLR::Layer::LEAKY_RELU || + layerType == NLR::Layer::SIGMOID || layerType == NLR::Layer::ABSOLUTE_VALUE || + layerType == NLR::Layer::MAX || layerType == NLR::Layer::SIGN || + layerType == NLR::Layer::ROUND || layerType == NLR::Layer::SOFTMAX) { + // Handle activation layers + activations.append(layerType); + } else if (layerType == NLR::Layer::BILINEAR) { + // Handle bilinear layers todo what ? + } else if (layerType == NLR::Layer::INPUT) { + // No action needed for input layer + } else { + std::cerr << "Unsupported layer type: " << layerType << std::endl; } } + std::cout << "Number of linear layers: " << linearLayers.size() + 1<< std::endl; // add 1 for input layer. + std::cout << "Number of activations: " << activations.size() << std::endl; + std::cout << "Total number of variables: " << totalVariables << std::endl; + std::cout << "Input layer size: " << layerSizes.first() << std::endl; + std::cout << "Output layer size: " << layerSizes.last() << std::endl; - for ( size_t i = 0; i < layerSizes.size() - 1; ++i ) - { - linearLayers.push_back( - register_module( "linear" + std::to_string( i ), - torch::nn::Linear( layerSizes[i], layerSizes[i + 1] ) ) ); - std::vector flattenedWeights; - for ( const auto &weight : weights[i] ) - { - flattenedWeights.insert( flattenedWeights.end(), weight.begin(), weight.end() ); - } - - torch::Tensor weightTensor = torch::tensor( flattenedWeights, torch::kFloat ) - .view( { layerSizes[i + 1], layerSizes[i] } ); - torch::Tensor biasTensor = torch::tensor( biases[i], torch::kFloat ); - auto &linear = linearLayers.back(); - linear->weight.data().copy_( weightTensor ); - linear->bias.data().copy_( biasTensor ); - } } -torch::Tensor CustomDNNImpl::forward( torch::Tensor x ) -{ - for ( size_t i = 0; i < linearLayers.size(); ++i ) - { - x = linearLayers[i]->forward( x ); - if ( activations[i] == "ReLU" ) - { - x = torch::relu( x ); - } - else if ( activations[i] == "Sigmoid" ) - { - x = torch::sigmoid( x ); - } - else if ( activations[i] == "Tanh" ) - { - x = torch::tanh( x ); - } - else if ( activations[i] == "Softmax" ) - { - x = torch::softmax( x, 1 ); + +torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { + for (unsigned i = 0; i < linearLayers.size(); i++) { + x = linearLayers[i]->forward(x); + if (i < activations.size()) { + switch (activations[i]) { + case NLR::Layer::RELU: + x = torch::relu(x); + break; + case NLR::Layer::LEAKY_RELU: + x = torch::leaky_relu(x, 0.01); + break; + case NLR::Layer::SIGMOID: + x = torch::sigmoid(x); + break; + case NLR::Layer::ABSOLUTE_VALUE: + x = torch::abs(x); + break; + case NLR::Layer::MAX: + x = std::get<0>(torch::max( x ,1)); + break; + case NLR::Layer::SIGN: + x = torch::sign(x); + break; + case NLR::Layer::ROUND: + x = torch::round(x); + break; + case NLR::Layer::SOFTMAX: + x = torch::softmax(x, 1); + break; + default: + std::cerr << "Unsupported activation type: " << activations[i] << std::endl; + break; + } } } return x; diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index 6c03edc817..1f857981e3 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -4,24 +4,23 @@ #include "NetworkLevelReasoner.h" #include -#include #include +#undef Warning +#include + class CustomDNNImpl : public torch::nn::Module { public: - std::vector layerSizes; - std::vector activations; - std::vector>> weights; - std::vector> biases; - std::vector linearLayers; - - CustomDNNImpl( const std::vector &layer_sizes, - const std::vector &activationFunctions, - const std::vector>> &weights, - const std::vector> &biases ); - CustomDNNImpl( NLR::NetworkLevelReasoner &nlr ); + Vector layerSizes; + Vector activations; + Vector>> weights; + Vector> biases; + Vector linearLayers; + + + explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); torch::Tensor forward( torch::Tensor x ); }; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 299d5afd5b..5942bf28ee 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -32,9 +32,15 @@ #include "TimeUtils.h" #include "VariableOutOfBoundDuringOptimizationException.h" #include "Vector.h" +#include "CustomDNN.h" +#include "PGD.h" #include +#undef Warning +#include + + Engine::Engine() : _context() , _boundManager( _context ) @@ -1435,10 +1441,23 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) try { informConstraintsOfInitialBounds( inputQuery ); + // for (auto& inputVar : inputQuery.getInputVariables()) { + // inputQuery.setLowerBound(inputVar, -1.0); // Set lower bounds + // inputQuery.setUpperBound(inputVar, 1.0); // Set upper bounds + // } + invokePreprocessor( inputQuery, preprocess ); if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); + + CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); + // torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); + // int target = 0; + torch::Device device(torch::kCPU); + PGDAttack pgd_attack(network, inputQuery.getLowerBounds(), inputQuery.getUpperBounds()); + pgd_attack.displayAdversarialExample(); + if ( preprocess ) { performSymbolicBoundTightening( &( *_preprocessedQuery ) ); diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 400ae1b39c..80c9ba25e5 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,66 +1,101 @@ #include "PGD.h" - #include +// Constructor +PGDAttack::PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, + const Map &upperBounds) + : model(model), lowerBounds(lowerBounds), upperBounds(upperBounds), device(DEFAULT_DEVICE_TYPE), + alpha(DEFAULT_ALPHA), num_iter(DEFAULT_NUM_ITER), num_restarts(DEFAULT_NUM_RESTARTS) { + inputSize = model.layerSizes.first(); + std::pair variables = generateSampleAndEpsilon(); + originalInput = variables.first; + epsilon = variables.second; -torch::Tensor findDelta( CustomDNNImpl &model, - const torch::Tensor &X, - int y, - float epsilon, - float alpha, - int num_iter, - torch::Device device ) -{ - torch::Tensor delta = torch::zeros_like( X ).uniform_( -epsilon, epsilon ).to( device ); - delta.set_requires_grad( true ); - - torch::Tensor target = torch::tensor( { y }, torch::kInt64 ).to( device ); - - torch::optim::SGD optimizer( model.parameters(), - torch::optim::SGDOptions( 0.01 ).momentum( 0.9 ) ); - - for ( int i = 0; i < num_iter; ++i ) - { - optimizer.zero_grad(); - if ( delta.grad().defined() ) - { - delta.grad().zero_(); - } +} + + +PGDAttack::PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, + const Map &upperBounds, double alpha, unsigned num_iter, + unsigned num_restarts, torch::Device device) + : model(model), lowerBounds(lowerBounds), upperBounds(upperBounds), device(device), + alpha(alpha), num_iter(num_iter), num_restarts(num_restarts){ + inputSize = model.layerSizes.first(); + std::pair variables = generateSampleAndEpsilon(); + originalInput = variables.first; + epsilon = variables.second; +} + + +std::pair PGDAttack::generateSampleAndEpsilon() { + Vector sample(inputSize, 0.0f); + Vector epsilons(inputSize, 0.0f); + for (unsigned j = 0; j < inputSize; ++j) { + double lowerBound = lowerBounds.exists(j) ? lowerBounds.at(j) : -std::numeric_limits::infinity(); + double upperBound = upperBounds.exists(j) ? upperBounds.at(j) : std::numeric_limits::infinity(); + sample[j] = lowerBound + (upperBound - lowerBound) / 2.0f; + epsilons[j] = (upperBound - lowerBound) / 2.0f; + } + return {torch::tensor(sample.getContainer()).unsqueeze(0).to(device), + torch::tensor(epsilons.getContainer()).to(device)}; +} + +torch::Tensor PGDAttack::findDelta(int originalPred) { + torch::Tensor max_delta = torch::zeros_like(originalInput).to(device); + torch::Tensor target = torch::tensor({ originalPred }, torch::kInt64).to(device); + torch::Tensor max_loss = torch::tensor(-std::numeric_limits::infinity()).to(device); + + for (unsigned i = 0; i < num_restarts; i++) { + torch::Tensor delta = torch::zeros_like(originalInput).uniform_(-1, 1).mul(epsilon).to(device); + delta.set_requires_grad(true); - torch::Tensor pred = model.forward( X + delta ); - torch::Tensor loss = torch::nn::functional::cross_entropy( pred, target ); - loss.backward(); + for (unsigned j = 0; j < num_iter; j++) { + if (delta.grad().defined()) { + delta.grad().zero_(); + } - delta = ( delta + alpha * delta.grad().sign() ).clamp( -epsilon, epsilon ).detach(); - delta.set_requires_grad( true ); + torch::Tensor pred = model.forward(originalInput + delta); + torch::Tensor loss = torch::nn::functional::cross_entropy(pred, target); + loss.backward(); + + torch::Tensor alpha_tensor = torch::tensor(alpha).to(device); + // Update delta + delta.data().add_(alpha_tensor * delta.grad().sign()).clamp_(-epsilon, epsilon); + } + torch::Tensor current_loss = torch::nn::functional::cross_entropy(model.forward(originalInput + delta), target); + if (current_loss.item() > max_loss.item()) { + max_loss = current_loss; + max_delta = delta.detach().clone(); + } } - return delta; + return max_delta; } -bool displayAdversarialExample( CustomDNNImpl &model, - const torch::Tensor &input, - int target, - torch::Device device ) -{ - std::cout << "starting the attack" << std::endl; - auto x = input.to( device ); +bool PGDAttack::displayAdversarialExample() { + std::cout << "-----Starting PGD attack-----" << std::endl; + model.eval(); + + int original_pred = model.forward(originalInput).argmax(1).item(); - float epsilon = 0.1; - float alpha = 0.01; - int num_iter = 40; - torch::Tensor adversarial_delta = - findDelta( model, x, target, epsilon, alpha, num_iter, device ); - torch::Tensor adversarial_x = x + adversarial_delta; + torch::Tensor adversarial_delta = findDelta(original_pred); + torch::Tensor adversarial_x = originalInput + adversarial_delta; - auto original_pred = model.forward( x ).argmax( 1 ); - auto adversarial_pred = model.forward( adversarial_x ).argmax( 1 ); - bool is_fooled = original_pred.item() != adversarial_pred.item(); + auto adversarial_pred = model.forward(adversarial_x).argmax(1); + bool is_fooled = original_pred != adversarial_pred.item(); - std::cout << "Original Prediction: " << original_pred.item() << "\n"; - std::cout << "Adversarial Prediction: " << adversarial_pred.item() << "\n"; - std::cout << "Model fooled: " << ( is_fooled ? "Yes" : "No" ) << std::endl; + std::cout << "Original Prediction: " << original_pred + << ", Adversarial Prediction: " << adversarial_pred.item() + << ", Model fooled: " << (is_fooled ? "Yes" : "No") << "\n"; + + if (is_fooled) { + std::cout << "Found a successful adversarial example:\n"; + std::cout << "Original Input: " << originalInput << "\n"; + std::cout << "Adversarial Example: " << adversarial_x << "\n"; + std::cout << "Epsilon used: " << adversarial_delta.abs().max().item() << "\n"; + return true; + } - return is_fooled; + std::cout << "------ PGD attack failed ------" << "\n\n"; + return false; } \ No newline at end of file diff --git a/src/engine/PGD.h b/src/engine/PGD.h index b739c97e0c..ab4ec6c184 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -2,20 +2,38 @@ #define PGD_H #include "CustomDNN.h" - +#undef Warning #include -torch::Tensor findDelta( CustomDNNImpl &model, - const torch::Tensor &X, - int y, - float epsilon, - float alpha, - int num_iter, - torch::Device device ); -bool displayAdversarialExample( CustomDNNImpl &model, - const torch::Tensor &input, - int target, - torch::Device device ); +constexpr float DEFAULT_ALPHA = 0.01; +constexpr unsigned DEFAULT_NUM_ITER = 100; +constexpr unsigned DEFAULT_NUM_RESTARTS = 50; +constexpr torch::DeviceType DEFAULT_DEVICE_TYPE = torch::kCPU; + +class PGDAttack { +public: + PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, + const Map &upperBounds); + PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, + const Map &upperBounds, double alpha, unsigned num_iter, + unsigned num_restarts, torch::Device device); + + bool displayAdversarialExample(); + +private: + CustomDNNImpl &model; + const Map &lowerBounds; + const Map &upperBounds; + torch::Device device; + torch::Tensor epsilon; + torch::Tensor originalInput; + double alpha; + unsigned num_iter; + unsigned num_restarts; + unsigned inputSize; + torch::Tensor findDelta(int originalPred); + std::pair generateSampleAndEpsilon(); +}; -#endif \ No newline at end of file +#endif // PGD_H diff --git a/src/engine/Preprocessor.cpp b/src/engine/Preprocessor.cpp index 1b298c3337..08a00c0487 100644 --- a/src/engine/Preprocessor.cpp +++ b/src/engine/Preprocessor.cpp @@ -13,7 +13,6 @@ **/ -#include #include "Preprocessor.h" @@ -28,8 +27,6 @@ #include "PiecewiseLinearFunctionType.h" #include "Statistics.h" #include "Tightening.h" -#include "CustomDNN.h" -#include "PGD.h" #ifdef _WIN32 #undef INFINITE #endif @@ -177,12 +174,7 @@ std::unique_ptr Preprocessor::preprocess( const InputQuery &query, ASSERT( _preprocessed->getLowerBounds().size() == _preprocessed->getNumberOfVariables() ); ASSERT( _preprocessed->getUpperBounds().size() == _preprocessed->getNumberOfVariables() ); - CustomDNNImpl network = CustomDNNImpl(*(_preprocessed->_networkLevelReasoner)); - torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); - int target = 0; - torch::Device device(torch::kCPU); - displayAdversarialExample(network, input, target, device); - + String networkFilePath = Options::get()->getString( Options::INPUT_FILE_PATH ); diff --git a/tools/download_boost.sh b/tools/download_boost.sh index f77d5fbd42..83bbc0e4d8 100755 --- a/tools/download_boost.sh +++ b/tools/download_boost.sh @@ -9,7 +9,7 @@ cd $mydir # multiple lines echo "Downloading boost" underscore_version=${version//./_} -wget -q https://sourceforge.net/projects/boost/files/boost/$version/boost_$underscore_version.tar.gz/download -O boost-$version.tar.gz +wget https://sourceforge.net/projects/boost/files/boost/$version/boost_$underscore_version.tar.gz/download -O boost-$version.tar.gz -q --show-progress --progress=bar:force:noscroll echo "Unzipping boost" tar xzvf boost-$version.tar.gz >> /dev/null diff --git a/tools/download_libtorch.bat b/tools/download_libtorch.bat index 87bc81ff8c..177d0ad323 100644 --- a/tools/download_libtorch.bat +++ b/tools/download_libtorch.bat @@ -6,7 +6,7 @@ set TEMP_DIR=%LIBTORCH_DIR%\temp if not exist "%TEMP_DIR%" mkdir "%TEMP_DIR%" -powershell -command "Invoke-WebRequest -Uri https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-%LIBTORCH_VERSION%+cpu.zip -OutFile %TEMP_DIR%\libtorch.zip" +powershell -command "Invoke-WebRequest -Uri https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.3.1%2Bcpu.zip -OutFile %TEMP_DIR%\libtorch.zip" powershell -command "Expand-Archive -Path %TEMP_DIR%\libtorch.zip -DestinationPath %LIBTORCH_DIR%" diff --git a/tools/download_libtorch.sh b/tools/download_libtorch.sh index d378417e3c..90f1884b42 100755 --- a/tools/download_libtorch.sh +++ b/tools/download_libtorch.sh @@ -1,13 +1,19 @@ #!/bin/bash +curdir=$pwd +mydir="${0%/*}" +version=$1 -LIBTORCH_VERSION=$1 -LIBTORCH_DIR=$(dirname $0) +cd $mydir -TEMP_DIR=$(mktemp -d) -mkdir -p ${TEMP_DIR} +# Need to download the cxx11-abi version of libtorch in order to ensure compatability +# with boost. +# +# See https://discuss.pytorch.org/t/issues-linking-with-libtorch-c-11-abi/29510 for details. +echo "Downloading PyTorch" +wget https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-$version%2Bcpu.zip -O libtorch-$version.zip -q --show-progress --progress=bar:force:noscroll -wget https://download.pytorch.org/libtorch/cpu/libtorch-cxx11-abi-shared-with-deps-2.3.1%2Bcpu.zip -O ${TEMP_DIR}/libtorch.zip -unzip -o ${TEMP_DIR}/libtorch.zip -d ${LIBTORCH_DIR} -rm ${TEMP_DIR}/libtorch.zip +echo "Unzipping PyTorch" +unzip libtorch-$version.zip >> /dev/null +mv libtorch libtorch-$version -rm -rf ${TEMP_DIR} +cd $curdir diff --git a/tools/download_onnx.sh b/tools/download_onnx.sh index 3ca484754e..8c0cd22e4e 100755 --- a/tools/download_onnx.sh +++ b/tools/download_onnx.sh @@ -17,7 +17,7 @@ cd $mydir mkdir -p $onnxdir cd $onnxdir echo "Downloading ONNX proto file" -wget -q https://raw.githubusercontent.com/onnx/onnx/v$version/onnx/onnx.proto3 -O onnx.proto3 +wget https://raw.githubusercontent.com/onnx/onnx/v$version/onnx/onnx.proto3 -O onnx.proto3 -q --show-progress --progress=bar:force:noscroll echo "Compiling the ONNX proto file" ../$protobufdir/installed/bin/protoc --cpp_out=. onnx.proto3 diff --git a/tools/download_protobuf.sh b/tools/download_protobuf.sh index 2b0e4e31a6..29e9bc8972 100755 --- a/tools/download_protobuf.sh +++ b/tools/download_protobuf.sh @@ -17,8 +17,7 @@ fi cd $mydir echo "Downloading protobuf-$version" -wget -q https://github.com/protocolbuffers/protobuf/releases/download/v$version/protobuf-cpp-$version.tar.gz -O protobuf-cpp-$version.tar.gz - +wget https://github.com/protocolbuffers/protobuf/releases/download/v$version/protobuf-cpp-$version.tar.gz -O protobuf-cpp-$version.tar.gz -q --show-progress --progress=bar:force:noscroll echo "Unzipping protobuf-$version" tar -xzf protobuf-cpp-$version.tar.gz # >> /dev/null diff --git a/tools/download_pybind11.sh b/tools/download_pybind11.sh index 7dec0beec1..73698e9161 100755 --- a/tools/download_pybind11.sh +++ b/tools/download_pybind11.sh @@ -8,8 +8,7 @@ cd $mydir # TODO: add progress bar, -q is quite, if removing it the progress bar is in # multiple lines echo "downloading pybind" -wget -q https://github.com/pybind/pybind11/archive/v$version.tar.gz -O pybind11-$version.tar.gz - +wget https://github.com/pybind/pybind11/archive/v$version.tar.gz -O pybind11-$version.tar.gz -q --show-progress --progress=bar:force:noscroll echo "unzipping pybind" tar xzvf pybind11-$version.tar.gz >> /dev/null From 654619b6037094d6b200b05590c8fb4838b3f525 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 8 Jul 2024 11:49:16 +0300 Subject: [PATCH 08/69] torch --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index afd5e86479..334109fb3b 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ _deps /tools/protobuf* /tools/OpenBLAS* /tools/onnx* +/tools/libtorch* build From 4cad1dcfc5d2647ee9383497d3e6addf3294d464 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 10 Jul 2024 11:09:54 +0300 Subject: [PATCH 09/69] fix attack and torch --- src/engine/Engine.cpp | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 5942bf28ee..7a42f0e71e 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1451,12 +1451,16 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); - // torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); - // int target = 0; - torch::Device device(torch::kCPU); - PGDAttack pgd_attack(network, inputQuery.getLowerBounds(), inputQuery.getUpperBounds()); - pgd_attack.displayAdversarialExample(); + if ( _networkLevelReasoner ) + { + CustomDNNImpl network = CustomDNNImpl( _networkLevelReasoner ); + // torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, + // 0.2141, -1.1153, 0.8332, 0.0851}}); int target = 0; + // torch::Device device( torch::kCPU ); + PGDAttack pgd_attack( network, inputQuery.getLowerBounds(), inputQuery.getUpperBounds() ); + pgd_attack.displayAdversarialExample(); + } + if ( preprocess ) { From ad2cb592fda941e7b1614768e6e5385bf5cdf060 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 10 Jul 2024 11:18:45 +0300 Subject: [PATCH 10/69] check nlr null --- src/engine/Engine.cpp | 16 ++++++---------- src/input_parsers/OnnxParser.cpp | 2 +- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 7a42f0e71e..5942bf28ee 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1451,16 +1451,12 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - if ( _networkLevelReasoner ) - { - CustomDNNImpl network = CustomDNNImpl( _networkLevelReasoner ); - // torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, - // 0.2141, -1.1153, 0.8332, 0.0851}}); int target = 0; - // torch::Device device( torch::kCPU ); - PGDAttack pgd_attack( network, inputQuery.getLowerBounds(), inputQuery.getUpperBounds() ); - pgd_attack.displayAdversarialExample(); - } - + CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); + // torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); + // int target = 0; + torch::Device device(torch::kCPU); + PGDAttack pgd_attack(network, inputQuery.getLowerBounds(), inputQuery.getUpperBounds()); + pgd_attack.displayAdversarialExample(); if ( preprocess ) { diff --git a/src/input_parsers/OnnxParser.cpp b/src/input_parsers/OnnxParser.cpp index 71848dad3b..19e5e28003 100644 --- a/src/input_parsers/OnnxParser.cpp +++ b/src/input_parsers/OnnxParser.cpp @@ -972,7 +972,7 @@ void OnnxParser::makeMarabouEquations( onnx::NodeProto &node, bool makeEquations void OnnxParser::constant( onnx::NodeProto &node ) { String outputNodeName = node.output()[0]; - const onnx::TensorProto &value = getTensorAttribute( node, "value" ); + const onnx::TensorProto value = getTensorAttribute( node, "value" ); const TensorShape shape = shapeOfConstant( value ); _shapeMap[outputNodeName] = shape; From 336c3dc5f786a6aee188fb8372d816f167071b1b Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 13 Jul 2024 12:42:13 +0300 Subject: [PATCH 11/69] output bounds check --- src/engine/Engine.cpp | 4 +- src/engine/PGD.cpp | 173 ++++++++++++++++++++++++++++++++---------- src/engine/PGD.h | 28 ++++--- 3 files changed, 155 insertions(+), 50 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 5942bf28ee..e24c00ed3d 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1452,10 +1452,8 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) initializeNetworkLevelReasoning(); CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); - // torch::Tensor input = torch::tensor({{0.1300, -0.6401, 0.3475, -0.0579, -0.9246, 0.7567, 0.2141, -1.1153, 0.8332, 0.0851}}); - // int target = 0; torch::Device device(torch::kCPU); - PGDAttack pgd_attack(network, inputQuery.getLowerBounds(), inputQuery.getUpperBounds()); + PGDAttack pgd_attack(network, inputQuery); pgd_attack.displayAdversarialExample(); if ( preprocess ) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 80c9ba25e5..34709565b2 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,67 +1,159 @@ #include "PGD.h" +#include #include // Constructor -PGDAttack::PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, - const Map &upperBounds) - : model(model), lowerBounds(lowerBounds), upperBounds(upperBounds), device(DEFAULT_DEVICE_TYPE), - alpha(DEFAULT_ALPHA), num_iter(DEFAULT_NUM_ITER), num_restarts(DEFAULT_NUM_RESTARTS) { +PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery) + : model(model), inputQuery(inputQuery), device(DEFAULT_DEVICE_TYPE), + alpha(DEFAULT_ALPHA), num_iter(DEFAULT_NUM_ITER), num_restarts(DEFAULT_NUM_RESTARTS), lambdaPenalty( PANELTY ) { inputSize = model.layerSizes.first(); + inputBounds = getBounds(INPUT); + outputBounds = getBounds(OUTPUT); std::pair variables = generateSampleAndEpsilon(); originalInput = variables.first; epsilon = variables.second; - } - -PGDAttack::PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, - const Map &upperBounds, double alpha, unsigned num_iter, - unsigned num_restarts, torch::Device device) - : model(model), lowerBounds(lowerBounds), upperBounds(upperBounds), device(device), - alpha(alpha), num_iter(num_iter), num_restarts(num_restarts){ +PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery, double alpha, unsigned num_iter, + unsigned num_restarts, torch::Device device, double lambdaPenalty) + : model(model), inputQuery(inputQuery), device(device), + alpha(alpha), num_iter(num_iter), num_restarts(num_restarts), lambdaPenalty( lambdaPenalty ) { inputSize = model.layerSizes.first(); + std::pair, Vector> inputBounds = getBounds(INPUT); + std::pair, Vector> outputBounds = getBounds(OUTPUT); std::pair variables = generateSampleAndEpsilon(); originalInput = variables.first; epsilon = variables.second; } +std::pair, Vector> PGDAttack::getBounds(unsigned type) { + Vector upperBounds; + Vector lowerBounds; + + List variables = type == INPUT ? inputQuery.getInputVariables() : inputQuery.getOutputVariables(); + + for (auto it = variables.begin(); it != variables.end(); ++it) { + double upperBound = inputQuery.getUpperBounds().exists(*it) + ? inputQuery.getUpperBounds().get(*it) + : std::numeric_limits::infinity(); + double lowerBound = inputQuery.getLowerBounds().exists(*it) + ? inputQuery.getLowerBounds().get(*it) + : -std::numeric_limits::infinity(); + + upperBounds.append(upperBound); + lowerBounds.append(lowerBound); + } + return {lowerBounds, upperBounds}; +} std::pair PGDAttack::generateSampleAndEpsilon() { Vector sample(inputSize, 0.0f); Vector epsilons(inputSize, 0.0f); - for (unsigned j = 0; j < inputSize; ++j) { - double lowerBound = lowerBounds.exists(j) ? lowerBounds.at(j) : -std::numeric_limits::infinity(); - double upperBound = upperBounds.exists(j) ? upperBounds.at(j) : std::numeric_limits::infinity(); - sample[j] = lowerBound + (upperBound - lowerBound) / 2.0f; - epsilons[j] = (upperBound - lowerBound) / 2.0f; + Vector lowerBounds = inputBounds.first; + Vector upperBounds = inputBounds.second; + + for (unsigned i = 0; i < inputSize; i++) { + double lower = lowerBounds.get(i); + double upper = upperBounds.get(i); + + if (std::isinf(lower) && std::isinf(upper)) { + // Both bounds are infinite + sample[i] = 0.0f; + epsilons[i] = std::numeric_limits::infinity(); // todo choose a default value + } else if (std::isinf(lower)) { + // Only lower bound is infinite + sample[i] = upper - 1.0f; // todo choose a value slightly below upper bound + epsilons[i] = 1.0f; // todo change to the same value as the decrease in upper + } else if (std::isinf(upper)) { + // Only upper bound is infinite + sample[i] = lower + 1.0f; // todo choose a value above lower bound + epsilons[i] = 1.0f; // todo change to the same value as the increase in upper + } else { + // Both bounds are finite + sample[i] = lower + (upper - lower) / 2.0f; + epsilons[i] = (upper - lower) / 2.0f; + } } + return {torch::tensor(sample.getContainer()).unsqueeze(0).to(device), torch::tensor(epsilons.getContainer()).to(device)}; } -torch::Tensor PGDAttack::findDelta(int originalPred) { +bool PGDAttack::isWithinBounds(const torch::Tensor& sample, unsigned type) { + std::pair, Vector> bounds = getBounds(type); + Vector lowerBounds = bounds.first; + Vector upperBounds = bounds.second; + + torch::Tensor flatInput = sample.view({-1}); + + for (int64_t i = 0; i < flatInput.size(0); i++) { + double value = flatInput[i].item(); + double lower = lowerBounds.get(i); + double upper = upperBounds.get(i); + + if (std::isinf(lower) && std::isinf(upper)) { + // If both bounds are infinite, any value is acceptable + continue; + } else if (std::isinf(lower)) { + // Only check upper bound + if (value > upper) return false; + } else if (std::isinf(upper)) { + // Only check lower bound + if (value < lower) return false; + } else { + // Check both bounds + if (value < lower || value > upper) return false; + } + } + + return true; +} + + +torch::Tensor PGDAttack::calculateLoss(const torch::Tensor& predictions) { + // Convert output bounds to tensors + torch::Tensor lowerBoundTensor = torch::tensor(outputBounds.first.data(), torch::kFloat32).to(device); + torch::Tensor upperBoundTensor = torch::tensor(outputBounds.second.data(), torch::kFloat32).to(device); + + // Compute the penalty: We want to penalize if predictions are inside the bounds + torch::Tensor penalty = torch::add( + torch::relu(predictions - upperBoundTensor), // Penalize if pred > upperBound + torch::relu(lowerBoundTensor - predictions) // Penalize if pred < lowerBound + ); + + return torch::sum(penalty); +} + + +torch::Tensor PGDAttack::findDelta() { torch::Tensor max_delta = torch::zeros_like(originalInput).to(device); - torch::Tensor target = torch::tensor({ originalPred }, torch::kInt64).to(device); torch::Tensor max_loss = torch::tensor(-std::numeric_limits::infinity()).to(device); + std::cout << "-----Starting num restarts-----" << std::endl; for (unsigned i = 0; i < num_restarts; i++) { torch::Tensor delta = torch::zeros_like(originalInput).uniform_(-1, 1).mul(epsilon).to(device); delta.set_requires_grad(true); + torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions(alpha)); + for (unsigned j = 0; j < num_iter; j++) { - if (delta.grad().defined()) { - delta.grad().zero_(); - } + optimizer.zero_grad(); torch::Tensor pred = model.forward(originalInput + delta); - torch::Tensor loss = torch::nn::functional::cross_entropy(pred, target); - loss.backward(); + torch::Tensor loss = calculateLoss(pred); + + // Negate the loss for maximization + (-loss).backward(); - torch::Tensor alpha_tensor = torch::tensor(alpha).to(device); - // Update delta - delta.data().add_(alpha_tensor * delta.grad().sign()).clamp_(-epsilon, epsilon); + // Step the optimizer + optimizer.step(); + + // Project delta back to epsilon-ball + delta.data() = delta.data().clamp(-epsilon, epsilon); } - torch::Tensor current_loss = torch::nn::functional::cross_entropy(model.forward(originalInput + delta), target); + + torch::Tensor currentPrediction = model.forward(originalInput + delta); + torch::Tensor current_loss = calculateLoss(currentPrediction); if (current_loss.item() > max_loss.item()) { max_loss = current_loss; max_delta = delta.detach().clone(); @@ -71,31 +163,36 @@ torch::Tensor PGDAttack::findDelta(int originalPred) { return max_delta; } - bool PGDAttack::displayAdversarialExample() { std::cout << "-----Starting PGD attack-----" << std::endl; model.eval(); - int original_pred = model.forward(originalInput).argmax(1).item(); + auto original_pred = model.forward(originalInput); + + torch::Tensor adv_delta = findDelta(); + torch::Tensor adv_example = originalInput + adv_delta; - torch::Tensor adversarial_delta = findDelta(original_pred); - torch::Tensor adversarial_x = originalInput + adversarial_delta; + auto adv_pred = model.forward(adv_example); - auto adversarial_pred = model.forward(adversarial_x).argmax(1); - bool is_fooled = original_pred != adversarial_pred.item(); + auto loss = calculateLoss(adv_pred); + + std::cout << "-----displayAdversarialExample line 128-----" << std::endl; + + bool is_fooled = isWithinBounds( adv_example, INPUT ) && !isWithinBounds( adv_pred, OUTPUT ); std::cout << "Original Prediction: " << original_pred - << ", Adversarial Prediction: " << adversarial_pred.item() + << ", Adversarial Prediction: " << adv_pred << ", Model fooled: " << (is_fooled ? "Yes" : "No") << "\n"; if (is_fooled) { std::cout << "Found a successful adversarial example:\n"; std::cout << "Original Input: " << originalInput << "\n"; - std::cout << "Adversarial Example: " << adversarial_x << "\n"; - std::cout << "Epsilon used: " << adversarial_delta.abs().max().item() << "\n"; + std::cout << "Adversarial Example: " << adv_example << "\n"; + std::cout << "Epsilon used: " << adv_delta.abs().max().item() << "\n"; return true; } - std::cout << "------ PGD attack failed ------" << "\n\n"; + std::cout << "------ PGD attack failed ------" + << "\n\n"; return false; -} \ No newline at end of file +} diff --git a/src/engine/PGD.h b/src/engine/PGD.h index ab4ec6c184..65cc48930a 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -2,28 +2,30 @@ #define PGD_H #include "CustomDNN.h" +#include "CustomLoss.h" #undef Warning #include constexpr float DEFAULT_ALPHA = 0.01; +constexpr float PANELTY = 0.1; constexpr unsigned DEFAULT_NUM_ITER = 100; -constexpr unsigned DEFAULT_NUM_RESTARTS = 50; +constexpr unsigned DEFAULT_NUM_RESTARTS = 100; +constexpr unsigned INPUT = 0; +constexpr unsigned OUTPUT = 1; +// todo change device config constexpr torch::DeviceType DEFAULT_DEVICE_TYPE = torch::kCPU; class PGDAttack { public: - PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, - const Map &upperBounds); - PGDAttack(CustomDNNImpl &model, const Map &lowerBounds, - const Map &upperBounds, double alpha, unsigned num_iter, - unsigned num_restarts, torch::Device device); + PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery); + PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery, double alpha, unsigned num_iter, + unsigned num_restarts, torch::Device device, double lambdaPenalty); bool displayAdversarialExample(); private: CustomDNNImpl &model; - const Map &lowerBounds; - const Map &upperBounds; + InputQuery &inputQuery; torch::Device device; torch::Tensor epsilon; torch::Tensor originalInput; @@ -31,9 +33,17 @@ class PGDAttack { unsigned num_iter; unsigned num_restarts; unsigned inputSize; + double lambdaPenalty; + std::pair, Vector> inputBounds; + std::pair, Vector> outputBounds; - torch::Tensor findDelta(int originalPred); + torch::Tensor findDelta(); std::pair generateSampleAndEpsilon(); + bool isWithinBounds( const torch::Tensor &sample, unsigned type ); + std::pair, Vector> getBounds(unsigned type); + torch::Tensor calculateLoss( const torch::Tensor &predictions ); }; + + #endif // PGD_H From 1b237491b1562143b366f4a2c305829e5a9ef95f Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 13 Jul 2024 16:26:15 +0300 Subject: [PATCH 12/69] onnexParser 975 & --- src/input_parsers/OnnxParser.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/input_parsers/OnnxParser.cpp b/src/input_parsers/OnnxParser.cpp index 19e5e28003..71848dad3b 100644 --- a/src/input_parsers/OnnxParser.cpp +++ b/src/input_parsers/OnnxParser.cpp @@ -972,7 +972,7 @@ void OnnxParser::makeMarabouEquations( onnx::NodeProto &node, bool makeEquations void OnnxParser::constant( onnx::NodeProto &node ) { String outputNodeName = node.output()[0]; - const onnx::TensorProto value = getTensorAttribute( node, "value" ); + const onnx::TensorProto &value = getTensorAttribute( node, "value" ); const TensorShape shape = shapeOfConstant( value ); _shapeMap[outputNodeName] = shape; From 0e1f9a17c7deea30d37912da2326d8f09f57c8c2 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 13 Jul 2024 16:26:48 +0300 Subject: [PATCH 13/69] check _networkLevelReasoner not null in Engine.cpp --- src/engine/Engine.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index e24c00ed3d..219050ea3e 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1445,16 +1445,16 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) // inputQuery.setLowerBound(inputVar, -1.0); // Set lower bounds // inputQuery.setUpperBound(inputVar, 1.0); // Set upper bounds // } - invokePreprocessor( inputQuery, preprocess ); if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - - CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); - torch::Device device(torch::kCPU); - PGDAttack pgd_attack(network, inputQuery); - pgd_attack.displayAdversarialExample(); + if (_networkLevelReasoner) + { + CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); + PGDAttack pgd_attack(network, inputQuery); + pgd_attack.displayAdversarialExample(); + } if ( preprocess ) { From f52451751ceff8b30eb4faf36eb4c7db0e5775d1 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 13 Jul 2024 19:51:10 +0300 Subject: [PATCH 14/69] minor changes --- src/engine/PGD.cpp | 92 +++++++++++++++++--------------- src/engine/PGD.h | 25 +++++---- src/input_parsers/OnnxParser.cpp | 2 +- 3 files changed, 65 insertions(+), 54 deletions(-) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 34709565b2..7e2d840e9b 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -2,14 +2,13 @@ #include #include -// Constructor PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery) - : model(model), inputQuery(inputQuery), device(DEFAULT_DEVICE_TYPE), + : model(model), inputQuery(inputQuery), device(torch::kCPU), alpha(DEFAULT_ALPHA), num_iter(DEFAULT_NUM_ITER), num_restarts(DEFAULT_NUM_RESTARTS), lambdaPenalty( PANELTY ) { inputSize = model.layerSizes.first(); - inputBounds = getBounds(INPUT); - outputBounds = getBounds(OUTPUT); - std::pair variables = generateSampleAndEpsilon(); + inputBounds = _getBounds(INPUT); + outputBounds = _getBounds(OUTPUT); + std::pair variables = _generateSampleAndEpsilon(); originalInput = variables.first; epsilon = variables.second; } @@ -19,14 +18,25 @@ PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery, double alpha, : model(model), inputQuery(inputQuery), device(device), alpha(alpha), num_iter(num_iter), num_restarts(num_restarts), lambdaPenalty( lambdaPenalty ) { inputSize = model.layerSizes.first(); - std::pair, Vector> inputBounds = getBounds(INPUT); - std::pair, Vector> outputBounds = getBounds(OUTPUT); - std::pair variables = generateSampleAndEpsilon(); + std::pair, Vector> inputBounds = _getBounds(INPUT); + std::pair, Vector> outputBounds = _getBounds(OUTPUT); + std::pair variables = _generateSampleAndEpsilon(); originalInput = variables.first; epsilon = variables.second; } -std::pair, Vector> PGDAttack::getBounds(unsigned type) { +torch::Device PGDAttack::getDevice() { + if (torch::cuda::is_available()) { + std::cout << "CUDA is available. Using GPU." << std::endl; + return {torch::kCUDA}; + } else { + std::cout << "CUDA is not available. Using CPU." << std::endl; + return {torch::kCPU}; + } +} + +std::pair, Vector> PGDAttack::_getBounds(unsigned type ) const +{ Vector upperBounds; Vector lowerBounds; @@ -46,7 +56,7 @@ std::pair, Vector> PGDAttack::getBounds(unsigned type) { return {lowerBounds, upperBounds}; } -std::pair PGDAttack::generateSampleAndEpsilon() { +std::pair PGDAttack::_generateSampleAndEpsilon() { Vector sample(inputSize, 0.0f); Vector epsilons(inputSize, 0.0f); Vector lowerBounds = inputBounds.first; @@ -59,15 +69,15 @@ std::pair PGDAttack::generateSampleAndEpsilon() { if (std::isinf(lower) && std::isinf(upper)) { // Both bounds are infinite sample[i] = 0.0f; - epsilons[i] = std::numeric_limits::infinity(); // todo choose a default value + epsilons[i] = std::numeric_limits::infinity(); } else if (std::isinf(lower)) { // Only lower bound is infinite - sample[i] = upper - 1.0f; // todo choose a value slightly below upper bound - epsilons[i] = 1.0f; // todo change to the same value as the decrease in upper + sample[i] = upper - ATTACK_EPSILON; + epsilons[i] = ATTACK_EPSILON; } else if (std::isinf(upper)) { // Only upper bound is infinite - sample[i] = lower + 1.0f; // todo choose a value above lower bound - epsilons[i] = 1.0f; // todo change to the same value as the increase in upper + sample[i] = lower + ATTACK_EPSILON; + epsilons[i] = ATTACK_EPSILON; } else { // Both bounds are finite sample[i] = lower + (upper - lower) / 2.0f; @@ -79,8 +89,8 @@ std::pair PGDAttack::generateSampleAndEpsilon() { torch::tensor(epsilons.getContainer()).to(device)}; } -bool PGDAttack::isWithinBounds(const torch::Tensor& sample, unsigned type) { - std::pair, Vector> bounds = getBounds(type); +bool PGDAttack::_isWithinBounds(const torch::Tensor& sample, unsigned type) { + std::pair, Vector> bounds = _getBounds(type); Vector lowerBounds = bounds.first; Vector upperBounds = bounds.second; @@ -110,28 +120,28 @@ bool PGDAttack::isWithinBounds(const torch::Tensor& sample, unsigned type) { } -torch::Tensor PGDAttack::calculateLoss(const torch::Tensor& predictions) { +torch::Tensor PGDAttack::_calculateLoss(const torch::Tensor& predictions) { // Convert output bounds to tensors torch::Tensor lowerBoundTensor = torch::tensor(outputBounds.first.data(), torch::kFloat32).to(device); torch::Tensor upperBoundTensor = torch::tensor(outputBounds.second.data(), torch::kFloat32).to(device); // Compute the penalty: We want to penalize if predictions are inside the bounds torch::Tensor penalty = torch::add( - torch::relu(predictions - upperBoundTensor), // Penalize if pred > upperBound - torch::relu(lowerBoundTensor - predictions) // Penalize if pred < lowerBound + - torch::relu(predictions - upperBoundTensor), // Penalize if pred > upperBound + - torch::relu(lowerBoundTensor - predictions) // Penalize if pred < lowerBound ); return torch::sum(penalty); } -torch::Tensor PGDAttack::findDelta() { +torch::Tensor PGDAttack::_findDelta() { torch::Tensor max_delta = torch::zeros_like(originalInput).to(device); torch::Tensor max_loss = torch::tensor(-std::numeric_limits::infinity()).to(device); - std::cout << "-----Starting num restarts-----" << std::endl; for (unsigned i = 0; i < num_restarts; i++) { - torch::Tensor delta = torch::zeros_like(originalInput).uniform_(-1, 1).mul(epsilon).to(device); + torch::Tensor delta = torch::rand(inputSize).to(device); + delta = delta.mul(epsilon); delta.set_requires_grad(true); torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions(alpha)); @@ -140,7 +150,7 @@ torch::Tensor PGDAttack::findDelta() { optimizer.zero_grad(); torch::Tensor pred = model.forward(originalInput + delta); - torch::Tensor loss = calculateLoss(pred); + torch::Tensor loss = _calculateLoss(pred); // Negate the loss for maximization (-loss).backward(); @@ -153,7 +163,7 @@ torch::Tensor PGDAttack::findDelta() { } torch::Tensor currentPrediction = model.forward(originalInput + delta); - torch::Tensor current_loss = calculateLoss(currentPrediction); + torch::Tensor current_loss = _calculateLoss(currentPrediction); if (current_loss.item() > max_loss.item()) { max_loss = current_loss; max_delta = delta.detach().clone(); @@ -169,30 +179,26 @@ bool PGDAttack::displayAdversarialExample() { auto original_pred = model.forward(originalInput); - torch::Tensor adv_delta = findDelta(); + torch::Tensor adv_delta = _findDelta(); torch::Tensor adv_example = originalInput + adv_delta; auto adv_pred = model.forward(adv_example); - auto loss = calculateLoss(adv_pred); + auto loss = _calculateLoss(adv_pred); - std::cout << "-----displayAdversarialExample line 128-----" << std::endl; - bool is_fooled = isWithinBounds( adv_example, INPUT ) && !isWithinBounds( adv_pred, OUTPUT ); + bool isFooled = _isWithinBounds( adv_example, INPUT ) && !_isWithinBounds( adv_pred, OUTPUT ); - std::cout << "Original Prediction: " << original_pred - << ", Adversarial Prediction: " << adv_pred - << ", Model fooled: " << (is_fooled ? "Yes" : "No") << "\n"; - - if (is_fooled) { - std::cout << "Found a successful adversarial example:\n"; - std::cout << "Original Input: " << originalInput << "\n"; - std::cout << "Adversarial Example: " << adv_example << "\n"; - std::cout << "Epsilon used: " << adv_delta.abs().max().item() << "\n"; - return true; - } + std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer() << "\n"; + std::cout << "Input Upper Bounds : " << inputBounds.second.getContainer() << "\n\n"; + std::cout << "Original Input: " << originalInput << "\n"; + std::cout << "Adversarial Example: " << adv_example << "\n\n"; + std::cout << "Output Lower Bounds : " << outputBounds.first.getContainer() << "\n"; + std::cout << "Output Lower Bounds : " << outputBounds.second.getContainer() << "\n"; + std::cout << "Original Prediction: " << original_pred << "\n"; + std::cout << ", Adversarial Prediction: " << adv_pred << "\n\n"; + std::cout << "Model fooled: " << (isFooled ? "Yes \n ------ PGD Attack Succeed ------" : + "No \n ------ PGD Attack Failed ------") << "\n"; - std::cout << "------ PGD attack failed ------" - << "\n\n"; - return false; + return isFooled; } diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 65cc48930a..8843bae089 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -2,7 +2,6 @@ #define PGD_H #include "CustomDNN.h" -#include "CustomLoss.h" #undef Warning #include @@ -12,14 +11,18 @@ constexpr unsigned DEFAULT_NUM_ITER = 100; constexpr unsigned DEFAULT_NUM_RESTARTS = 100; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; -// todo change device config -constexpr torch::DeviceType DEFAULT_DEVICE_TYPE = torch::kCPU; +constexpr unsigned ATTACK_EPSILON = 10.0f; class PGDAttack { public: PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery); - PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery, double alpha, unsigned num_iter, - unsigned num_restarts, torch::Device device, double lambdaPenalty); + PGDAttack( CustomDNNImpl &model, + InputQuery &inputQuery, + double alpha, + unsigned num_iter, + unsigned num_restarts, + torch::Device device, + double lambdaPenalty ); bool displayAdversarialExample(); @@ -37,11 +40,13 @@ class PGDAttack { std::pair, Vector> inputBounds; std::pair, Vector> outputBounds; - torch::Tensor findDelta(); - std::pair generateSampleAndEpsilon(); - bool isWithinBounds( const torch::Tensor &sample, unsigned type ); - std::pair, Vector> getBounds(unsigned type); - torch::Tensor calculateLoss( const torch::Tensor &predictions ); + torch::Tensor _findDelta(); + std::pair _generateSampleAndEpsilon(); + bool _isWithinBounds( const torch::Tensor &sample, unsigned type ); + std::pair, Vector> _getBounds(unsigned type ) const; + torch::Tensor _calculateLoss( const torch::Tensor &predictions ); + static torch::Device _getDevice(); + }; diff --git a/src/input_parsers/OnnxParser.cpp b/src/input_parsers/OnnxParser.cpp index 71848dad3b..19e5e28003 100644 --- a/src/input_parsers/OnnxParser.cpp +++ b/src/input_parsers/OnnxParser.cpp @@ -972,7 +972,7 @@ void OnnxParser::makeMarabouEquations( onnx::NodeProto &node, bool makeEquations void OnnxParser::constant( onnx::NodeProto &node ) { String outputNodeName = node.output()[0]; - const onnx::TensorProto &value = getTensorAttribute( node, "value" ); + const onnx::TensorProto value = getTensorAttribute( node, "value" ); const TensorShape shape = shapeOfConstant( value ); _shapeMap[outputNodeName] = shape; From 367abaa4b266b7ff6cb1d93c011b28150c8a04b0 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sun, 14 Jul 2024 13:32:37 +0300 Subject: [PATCH 15/69] minor changes --- src/engine/PGD.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 7e2d840e9b..022eeabad9 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -25,7 +25,7 @@ PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery, double alpha, epsilon = variables.second; } -torch::Device PGDAttack::getDevice() { +torch::Device PGDAttack::_getDevice() { if (torch::cuda::is_available()) { std::cout << "CUDA is available. Using GPU." << std::endl; return {torch::kCUDA}; From d159b7868c6cf63c9e460add4604be518f993a7b Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 15 Jul 2024 09:35:23 +0300 Subject: [PATCH 16/69] change to cmake cluster --- CMakeLists.txt | 220 +++++++++++++++++++++++++------------------------ 1 file changed, 114 insertions(+), 106 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c8a6e9473d..b58b029479 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.16) +cmake_minimum_required (VERSION 3.12) project(Marabou) set(MARABOU_VERSION 2.0.0) @@ -31,19 +31,19 @@ option(CODE_COVERAGE "Add code coverage" OFF) # Available only in debug mode # Get the name of the working branch execute_process( - COMMAND git rev-parse --abbrev-ref HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE GIT_BRANCH - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND git rev-parse --abbrev-ref HEAD + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_BRANCH + OUTPUT_STRIP_TRAILING_WHITESPACE ) add_definitions("-DGIT_BRANCH=\"${GIT_BRANCH}\"") # Get the latest abbreviated commit hash of the working branch execute_process( - COMMAND git log -1 --format=%h - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE GIT_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE + COMMAND git log -1 --format=%h + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + OUTPUT_VARIABLE GIT_COMMIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE ) add_definitions("-DGIT_COMMIT_HASH=\"${GIT_COMMIT_HASH}\"") @@ -61,9 +61,9 @@ set(COMMON_DIR "${SRC_DIR}/common") set(BASIS_DIR "${SRC_DIR}/basis_factorization") if (MSVC) - set(SCRIPT_EXTENSION bat) + set(SCRIPT_EXTENSION bat) else() - set(SCRIPT_EXTENSION sh) + set(SCRIPT_EXTENSION sh) endif() ########## @@ -83,23 +83,23 @@ include_directories(SYSTEM ${CVC4_DIR} ${CVC4_DIR}/include) # Avoid using deprecated operations add_definitions(-DBOOST_NO_CXX98_FUNCTION_BASE) -set(BOOST_VERSION 1.84.0) +set(BOOST_VERSION 1.67.0) set(BOOST_DIR "${TOOLS_DIR}/boost-${BOOST_VERSION}") if (MSVC) - set(BOOST_ROOT "${BOOST_DIR}/win_installed") - set(Boost_NAMESPACE libboost) + set(BOOST_ROOT "${BOOST_DIR}/win_installed") + set(Boost_NAMESPACE libboost) elseif (${CMAKE_SIZEOF_VOID_P} EQUAL 4 AND NOT MSVC) - set(BOOST_ROOT "${BOOST_DIR}/installed32") + set(BOOST_ROOT "${BOOST_DIR}/installed32") else() - set(BOOST_ROOT "${BOOST_DIR}/installed") + set(BOOST_ROOT "${BOOST_DIR}/installed") endif() set(Boost_USE_DEBUG_RUNTIME FALSE) find_package(Boost ${BOOST_VERSION} COMPONENTS program_options timer chrono thread) # Find boost if (NOT ${Boost_FOUND}) - execute_process(COMMAND ${TOOLS_DIR}/download_boost.${SCRIPT_EXTENSION} ${BOOST_VERSION}) - find_package(Boost ${BOOST_VERSION} REQUIRED COMPONENTS program_options timer chrono thread) + execute_process(COMMAND ${TOOLS_DIR}/download_boost.${SCRIPT_EXTENSION} ${BOOST_VERSION}) + find_package(Boost ${BOOST_VERSION} REQUIRED COMPONENTS program_options timer chrono thread) endif() set(LIBS_INCLUDES ${Boost_INCLUDE_DIRS}) list(APPEND LIBS ${Boost_LIBRARIES}) @@ -153,12 +153,20 @@ include_directories(SYSTEM ${ONNX_DIR}) ############# set(PYTORCH_VERSION 2.2.1) -set(PYTORCH_DIR "${TOOLS_DIR}/libtorch-${PYTORCH_VERSION}") -list(APPEND CMAKE_PREFIX_PATH ${PYTORCH_DIR}) -if(NOT EXISTS "${PYTORCH_DIR}") - execute_process(COMMAND ${TOOLS_DIR}/download_libtorch.sh ${PYTORCH_VERSION}) +message(STATUS "Hi 4") +find_package(Torch ${PYTORCH_VERSION} QUIET) +message(STATUS "Hi 1") +if (NOT Torch_FOUND) + message(STATUS "Hi 2") + set(PYTORCH_DIR "${TOOLS_DIR}/libtorch-${PYTORCH_VERSION}") + list(APPEND CMAKE_PREFIX_PATH ${PYTORCH_DIR}) + if(NOT EXISTS "${PYTORCH_DIR}") + message(STATUS "Hi 5") + execute_process(COMMAND ${TOOLS_DIR}/download_libtorch.sh ${PYTORCH_VERSION}) + endif() + set(Torch_DIR ${PYTORCH_DIR}/share/cmake/Torch) + find_package(Torch ${PYTORCH_VERSION} REQUIRED) endif() -find_package(Torch ${PYTORCH_VERSION} REQUIRED) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}") list(APPEND LIBS ${TORCH_LIBRARIES}) @@ -167,31 +175,31 @@ list(APPEND LIBS ${TORCH_LIBRARIES}) ############ if (${ENABLE_GUROBI}) - message(STATUS "Using Gurobi for LP relaxation for bound tightening") - if (NOT DEFINED GUROBI_DIR) - set(GUROBI_DIR $ENV{GUROBI_HOME}) - endif() - add_compile_definitions(ENABLE_GUROBI) - - set(GUROBI_LIB1 "gurobi_c++") - set(GUROBI_LIB2 "gurobi95") - - add_library(${GUROBI_LIB1} SHARED IMPORTED) - set_target_properties(${GUROBI_LIB1} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi_c++.a) - list(APPEND LIBS ${GUROBI_LIB1}) - target_include_directories(${GUROBI_LIB1} INTERFACE ${GUROBI_DIR}/include/) - - add_library(${GUROBI_LIB2} SHARED IMPORTED) - - # MACOSx uses .dylib instead of .so for its Gurobi downloads. - if (APPLE) - set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi95.dylib) - else() - set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi95.so) - endif () - - list(APPEND LIBS ${GUROBI_LIB2}) - target_include_directories(${GUROBI_LIB2} INTERFACE ${GUROBI_DIR}/include/) + message(STATUS "Using Gurobi for LP relaxation for bound tightening") + if (NOT DEFINED GUROBI_DIR) + set(GUROBI_DIR $ENV{GUROBI_HOME}) + endif() + add_compile_definitions(ENABLE_GUROBI) + + set(GUROBI_LIB1 "gurobi_c++") + set(GUROBI_LIB2 "gurobi95") + + add_library(${GUROBI_LIB1} SHARED IMPORTED) + set_target_properties(${GUROBI_LIB1} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi_c++.a) + list(APPEND LIBS ${GUROBI_LIB1}) + target_include_directories(${GUROBI_LIB1} INTERFACE ${GUROBI_DIR}/include/) + + add_library(${GUROBI_LIB2} SHARED IMPORTED) + + # MACOSx uses .dylib instead of .so for its Gurobi downloads. + if (APPLE) + set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi95.dylib) + else() + set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi95.so) + endif () + + list(APPEND LIBS ${GUROBI_LIB2}) + target_include_directories(${GUROBI_LIB2} INTERFACE ${GUROBI_DIR}/include/) endif() ############## @@ -199,30 +207,30 @@ endif() ############## if (NOT MSVC AND ${ENABLE_OPENBLAS}) - set(OPENBLAS_VERSION 0.3.19) - - set(OPENBLAS_LIB openblas) - set(OPENBLAS_DEFAULT_DIR "${TOOLS_DIR}/OpenBLAS-${OPENBLAS_VERSION}") - if (NOT OPENBLAS_DIR) - set(OPENBLAS_DIR ${OPENBLAS_DEFAULT_DIR}) - endif() - - message(STATUS "Using OpenBLAS for matrix multiplication") - add_compile_definitions(ENABLE_OPENBLAS) - if(NOT EXISTS "${OPENBLAS_DIR}/installed/lib/libopenblas.a") - message("Can't find OpenBLAS, installing. If OpenBLAS is installed please use the OPENBLAS_DIR parameter to pass the path") - if (${OPENBLAS_DIR} STREQUAL ${OPENBLAS_DEFAULT_DIR}) - message("Installing OpenBLAS") - execute_process(COMMAND ${TOOLS_DIR}/download_openBLAS.sh ${OPENBLAS_VERSION}) - else() - message(FATAL_ERROR "Can't find OpenBLAS in the supplied directory") - endif() - endif() - - add_library(${OPENBLAS_LIB} SHARED IMPORTED) - set_target_properties(${OPENBLAS_LIB} PROPERTIES IMPORTED_LOCATION ${OPENBLAS_DIR}/installed/lib/libopenblas.a) - list(APPEND LIBS ${OPENBLAS_LIB}) - target_include_directories(${OPENBLAS_LIB} INTERFACE ${OPENBLAS_DIR}/installed/include) + set(OPENBLAS_VERSION 0.3.19) + + set(OPENBLAS_LIB openblas) + set(OPENBLAS_DEFAULT_DIR "${TOOLS_DIR}/OpenBLAS-${OPENBLAS_VERSION}") + if (NOT OPENBLAS_DIR) + set(OPENBLAS_DIR ${OPENBLAS_DEFAULT_DIR}) + endif() + + message(STATUS "Using OpenBLAS for matrix multiplication") + add_compile_definitions(ENABLE_OPENBLAS) + if(NOT EXISTS "${OPENBLAS_DIR}/installed/lib/libopenblas.a") + message("Can't find OpenBLAS, installing. If OpenBLAS is installed please use the OPENBLAS_DIR parameter to pass the path") + if (${OPENBLAS_DIR} STREQUAL ${OPENBLAS_DEFAULT_DIR}) + message("Installing OpenBLAS") + execute_process(COMMAND ${TOOLS_DIR}/download_openBLAS.sh ${OPENBLAS_VERSION}) + else() + message(FATAL_ERROR "Can't find OpenBLAS in the supplied directory") + endif() + endif() + + add_library(${OPENBLAS_LIB} SHARED IMPORTED) + set_target_properties(${OPENBLAS_LIB} PROPERTIES IMPORTED_LOCATION ${OPENBLAS_DIR}/installed/lib/libopenblas.a) + list(APPEND LIBS ${OPENBLAS_LIB}) + target_include_directories(${OPENBLAS_LIB} INTERFACE ${OPENBLAS_DIR}/installed/include) endif() ########### @@ -255,7 +263,7 @@ set(INPUT_PARSERS_DIR input_parsers) include(ProcessorCount) ProcessorCount(CTEST_NTHREADS) if(CTEST_NTHREADS EQUAL 0) - set(CTEST_NTHREADS 1) + set(CTEST_NTHREADS 1) endif() # --------------- set build type ---------------------------- @@ -263,20 +271,20 @@ set(BUILD_TYPES Release Debug MinSizeRel RelWithDebInfo) # Set the default build type to Production if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE - Release CACHE STRING "Options are: Release Debug MinSizeRel RelWithDebInfo" FORCE) - # Provide drop down menu options in cmake-gui - set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${BUILD_TYPES}) + set(CMAKE_BUILD_TYPE + Release CACHE STRING "Options are: Release Debug MinSizeRel RelWithDebInfo" FORCE) + # Provide drop down menu options in cmake-gui + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS ${BUILD_TYPES}) endif() message(STATUS "Building ${CMAKE_BUILD_TYPE} build") #-------------------------set code coverage----------------------------------# # Allow coverage only in debug mode only in gcc if(CODE_COVERAGE AND CMAKE_CXX_COMPILER_ID MATCHES "GNU" AND CMAKE_BUILD_TYPE MATCHES Debug) - message(STATUS "Building with code coverage") - set(COVERAGE_COMPILER_FLAGS "-g -O0 --coverage" CACHE INTERNAL "") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}") - set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") + message(STATUS "Building with code coverage") + set(COVERAGE_COMPILER_FLAGS "-g -O0 --coverage" CACHE INTERNAL "") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${COVERAGE_COMPILER_FLAGS}") + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --coverage") endif() # We build a static library that is the core of the project, the link it to the @@ -289,7 +297,7 @@ set(MARABOU_EXE Marabou${CMAKE_EXECUTABLE_SUFFIX}) add_executable(${MARABOU_EXE} "${ENGINE_DIR}/main.cpp") set(MARABOU_EXE_PATH "${BIN_DIR}/${MARABOU_EXE}") add_custom_command(TARGET ${MARABOU_EXE} POST_BUILD - COMMAND ${CMAKE_COMMAND} -E copy $ ${MARABOU_EXE_PATH} ) + COMMAND ${CMAKE_COMMAND} -E copy $ ${MARABOU_EXE_PATH} ) set(MPS_PARSER_PATH "${BIN_DIR}/${MPS_PARSER}") @@ -330,10 +338,10 @@ find_package(Threads REQUIRED) list(APPEND LIBS Threads::Threads) if (BUILD_STATIC_MARABOU) - # build a static library - target_link_libraries(${MARABOU_LIB} ${LIBS} -static) + # build a static library + target_link_libraries(${MARABOU_LIB} ${LIBS} -static) else() - target_link_libraries(${MARABOU_LIB} ${LIBS}) + target_link_libraries(${MARABOU_LIB} ${LIBS}) endif() target_include_directories(${MARABOU_LIB} PRIVATE ${LIBS_INCLUDES}) @@ -365,10 +373,10 @@ endif() set(PYTHON32 FALSE) if(${BUILD_PYTHON}) execute_process(COMMAND "${PYTHON_EXECUTABLE}" "-c" - "import struct; print(struct.calcsize('@P'));" - RESULT_VARIABLE _PYTHON_SUCCESS - OUTPUT_VARIABLE PYTHON_SIZEOF_VOID_P - ERROR_VARIABLE _PYTHON_ERROR_VALUE) + "import struct; print(struct.calcsize('@P'));" + RESULT_VARIABLE _PYTHON_SUCCESS + OUTPUT_VARIABLE PYTHON_SIZEOF_VOID_P + ERROR_VARIABLE _PYTHON_ERROR_VALUE) # message("PYTHON SIZEOF VOID p ${PYTHON_SIZEOF_VOID_P}") if (PYTHON_SIZEOF_VOID_P EQUAL 4 AND NOT ${FORCE_PYTHON_BUILD}) set(PYTHON32 TRUE) @@ -388,8 +396,8 @@ endif() # Actually build Python if (${BUILD_PYTHON}) - set(PYBIND11_VERSION 2.10.4) - set(PYBIND11_DIR "${TOOLS_DIR}/pybind11-${PYBIND11_VERSION}") + set(PYBIND11_VERSION 2.10.4) + set(PYBIND11_DIR "${TOOLS_DIR}/pybind11-${PYBIND11_VERSION}") # This is suppose to set the PYTHON_EXECUTABLE variable # First try to find the default python version @@ -401,7 +409,7 @@ if (${BUILD_PYTHON}) if (NOT EXISTS ${PYBIND11_DIR}) message("didnt find pybind, getting it") - execute_process(COMMAND ${TOOLS_DIR}/download_pybind11.${SCRIPT_EXTENSION} ${PYBIND11_VERSION}) + execute_process(COMMAND ${TOOLS_DIR}/download_pybind11.${SCRIPT_EXTENSION} ${PYBIND11_VERSION}) endif() add_subdirectory(${PYBIND11_DIR}) @@ -412,7 +420,7 @@ if (${BUILD_PYTHON}) target_include_directories(${MARABOU_PY} PRIVATE ${LIBS_INCLUDES}) set_target_properties(${MARABOU_PY} PROPERTIES - LIBRARY_OUTPUT_DIRECTORY ${PYTHON_LIBRARY_OUTPUT_DIRECTORY}) + LIBRARY_OUTPUT_DIRECTORY ${PYTHON_LIBRARY_OUTPUT_DIRECTORY}) if(NOT MSVC) target_compile_options(${MARABOU_LIB} PRIVATE -fPIC ${RELEASE_FLAGS}) endif() @@ -443,8 +451,8 @@ target_compile_options(${MARABOU_TEST_LIB} PRIVATE ${CXXTEST_FLAGS}) add_custom_target(build-tests ALL) add_custom_target(check - COMMAND ctest --output-on-failure -j${CTEST_NTHREADS} $$ARGS - DEPENDS build-tests build_input_parsers ${MARABOU_EXE}) + COMMAND ctest --output-on-failure -j${CTEST_NTHREADS} $$ARGS + DEPENDS build-tests build_input_parsers ${MARABOU_EXE}) # Decide which tests to run and execute set(TESTS_TO_RUN "") @@ -470,33 +478,33 @@ if (NOT ${TESTS_TO_RUN} STREQUAL "") # make ctest verbose set(CTEST_OUTPUT_ON_FAILURE 1) add_custom_command( - TARGET build-tests - POST_BUILD - COMMAND ctest --output-on-failure -L "\"(${TESTS_TO_RUN})\"" -j${CTEST_NTHREADS} $$ARGS + TARGET build-tests + POST_BUILD + COMMAND ctest --output-on-failure -L "\"(${TESTS_TO_RUN})\"" -j${CTEST_NTHREADS} $$ARGS ) endif() if (${BUILD_PYTHON} AND ${RUN_PYTHON_TEST}) if (MSVC) add_custom_command( - TARGET build-tests - POST_BUILD - COMMAND cp ${PYTHON_API_DIR}/Release/* ${PYTHON_API_DIR} + TARGET build-tests + POST_BUILD + COMMAND cp ${PYTHON_API_DIR}/Release/* ${PYTHON_API_DIR} ) endif() add_custom_command( - TARGET build-tests - POST_BUILD - COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYTHON_API_DIR}/test + TARGET build-tests + POST_BUILD + COMMAND ${PYTHON_EXECUTABLE} -m pytest ${PYTHON_API_DIR}/test ) endif() # Add the input parsers add_custom_target(build_input_parsers) add_dependencies(build_input_parsers ${MPS_PARSER} ${ACAS_PARSER} - ${BERKELEY_PARSER}) + ${BERKELEY_PARSER}) add_subdirectory(${SRC_DIR}) add_subdirectory(${TOOLS_DIR}) -add_subdirectory(${REGRESS_DIR}) +add_subdirectory(${REGRESS_DIR}) \ No newline at end of file From 57914476d03329444157ffd5e97964a601bcd2e1 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 17 Jul 2024 11:53:01 +0300 Subject: [PATCH 17/69] fix activations --- src/engine/CustomDNN.cpp | 17 +++++------------ src/engine/PGD.cpp | 11 +++-------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index aad6ce984d..081b2d91b6 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -3,21 +3,16 @@ #include "NetworkLevelReasoner.h" CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReasoner) { - unsigned totalVariables = 0; - unsigned linearLayersNum = 0; std::cout << "----- Construct Custom Network -----" << std::endl; - // Iterate over layers for (unsigned i = 0; i < networkLevelReasoner->getNumberOfLayers(); i++) { const NLR::Layer* layer = networkLevelReasoner->getLayer(i); layerSizes.append(layer->getSize()); - totalVariables += layer->getSize(); NLR::Layer::Type layerType = layer->getLayerType(); if (layerType == NLR::Layer::WEIGHTED_SUM) { // Fully connected layer - linearLayersNum ++; unsigned sourceLayer = i - 1; const NLR::Layer *prevLayer = networkLevelReasoner->getLayer(sourceLayer); unsigned inputSize = prevLayer->getSize(); @@ -55,24 +50,22 @@ CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReason linearLayer->weight.set_(weightTensor); linearLayer->bias.set_(biasTensor); } - + // activation layers } else if (layerType == NLR::Layer::RELU || layerType == NLR::Layer::LEAKY_RELU || layerType == NLR::Layer::SIGMOID || layerType == NLR::Layer::ABSOLUTE_VALUE || layerType == NLR::Layer::MAX || layerType == NLR::Layer::SIGN || layerType == NLR::Layer::ROUND || layerType == NLR::Layer::SOFTMAX) { - // Handle activation layers activations.append(layerType); } else if (layerType == NLR::Layer::BILINEAR) { - // Handle bilinear layers todo what ? + // todo what to do when BILINEAR ? } else if (layerType == NLR::Layer::INPUT) { // No action needed for input layer } else { std::cerr << "Unsupported layer type: " << layerType << std::endl; } } - std::cout << "Number of linear layers: " << linearLayers.size() + 1<< std::endl; // add 1 for input layer. + std::cout << "Number of layers: " << linearLayers.size() + 1<< std::endl; // add 1 for input layer. std::cout << "Number of activations: " << activations.size() << std::endl; - std::cout << "Total number of variables: " << totalVariables << std::endl; std::cout << "Input layer size: " << layerSizes.first() << std::endl; std::cout << "Output layer size: " << layerSizes.last() << std::endl; @@ -87,7 +80,7 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { x = torch::relu(x); break; case NLR::Layer::LEAKY_RELU: - x = torch::leaky_relu(x, 0.01); + x = torch::leaky_relu(x); break; case NLR::Layer::SIGMOID: x = torch::sigmoid(x); @@ -96,7 +89,7 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { x = torch::abs(x); break; case NLR::Layer::MAX: - x = std::get<0>(torch::max( x ,1)); + x = torch::max( x ); break; case NLR::Layer::SIGN: x = torch::sign(x); diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 022eeabad9..f594db5205 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -121,14 +121,13 @@ bool PGDAttack::_isWithinBounds(const torch::Tensor& sample, unsigned type) { torch::Tensor PGDAttack::_calculateLoss(const torch::Tensor& predictions) { - // Convert output bounds to tensors torch::Tensor lowerBoundTensor = torch::tensor(outputBounds.first.data(), torch::kFloat32).to(device); torch::Tensor upperBoundTensor = torch::tensor(outputBounds.second.data(), torch::kFloat32).to(device); - // Compute the penalty: We want to penalize if predictions are inside the bounds + // Compute the penalty: We want high loss if predictions are inside the bounds torch::Tensor penalty = torch::add( - - torch::relu(predictions - upperBoundTensor), // Penalize if pred > upperBound - - torch::relu(lowerBoundTensor - predictions) // Penalize if pred < lowerBound + - torch::relu(predictions - upperBoundTensor), + - torch::relu(lowerBoundTensor - predictions) ); return torch::sum(penalty); @@ -151,13 +150,9 @@ torch::Tensor PGDAttack::_findDelta() { torch::Tensor pred = model.forward(originalInput + delta); torch::Tensor loss = _calculateLoss(pred); - // Negate the loss for maximization (-loss).backward(); - - // Step the optimizer optimizer.step(); - // Project delta back to epsilon-ball delta.data() = delta.data().clamp(-epsilon, epsilon); } From 70511661d9a6cbbe21a1c1e9670c4bf33c93682c Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 23 Jul 2024 12:39:07 +0300 Subject: [PATCH 18/69] fix bounds and output, improve loss and verify customDNN --- src/engine/CustomDNN.cpp | 64 +++++++++++++++++------ src/engine/CustomDNN.h | 9 +++- src/engine/Engine.cpp | 10 ++-- src/engine/PGD.cpp | 108 ++++++++++++++++++++------------------- src/engine/PGD.h | 20 ++++---- 5 files changed, 125 insertions(+), 86 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 081b2d91b6..1cf0896017 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -6,12 +6,14 @@ CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReason std::cout << "----- Construct Custom Network -----" << std::endl; - for (unsigned i = 0; i < networkLevelReasoner->getNumberOfLayers(); i++) { + numberOfLayers = networkLevelReasoner->getNumberOfLayers(); + for (unsigned i = 0; i < numberOfLayers; i++) { const NLR::Layer* layer = networkLevelReasoner->getLayer(i); layerSizes.append(layer->getSize()); NLR::Layer::Type layerType = layer->getLayerType(); if (layerType == NLR::Layer::WEIGHTED_SUM) { + layersOrder.append( LINEAR ); // Fully connected layer unsigned sourceLayer = i - 1; const NLR::Layer *prevLayer = networkLevelReasoner->getLayer(sourceLayer); @@ -55,16 +57,16 @@ CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReason layerType == NLR::Layer::SIGMOID || layerType == NLR::Layer::ABSOLUTE_VALUE || layerType == NLR::Layer::MAX || layerType == NLR::Layer::SIGN || layerType == NLR::Layer::ROUND || layerType == NLR::Layer::SOFTMAX) { + layersOrder.append( ACTIVATION ); activations.append(layerType); - } else if (layerType == NLR::Layer::BILINEAR) { - // todo what to do when BILINEAR ? } else if (layerType == NLR::Layer::INPUT) { // No action needed for input layer + layersOrder.append( INPUT ); } else { std::cerr << "Unsupported layer type: " << layerType << std::endl; } } - std::cout << "Number of layers: " << linearLayers.size() + 1<< std::endl; // add 1 for input layer. + std::cout << "Number of layers: " << linearLayers.size() + 1<< std::endl; std::cout << "Number of activations: " << activations.size() << std::endl; std::cout << "Input layer size: " << layerSizes.first() << std::endl; std::cout << "Output layer size: " << layerSizes.last() << std::endl; @@ -72,37 +74,65 @@ CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReason } torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { - for (unsigned i = 0; i < linearLayers.size(); i++) { - x = linearLayers[i]->forward(x); - if (i < activations.size()) { - switch (activations[i]) { + unsigned linearIndex = 0; + unsigned activationIndex = 0; + for ( unsigned i = 1; i < numberOfLayers; i++ ) + { + switch (layersOrder[i]) + { + case LINEAR: + + x = linearLayers[linearIndex]->forward( x ); + linearIndex ++; + break; + + case ACTIVATION: + { + switch ( activations[activationIndex] ) + { case NLR::Layer::RELU: - x = torch::relu(x); + x = torch::relu( x ); + activationIndex ++; break; + case NLR::Layer::LEAKY_RELU: - x = torch::leaky_relu(x); + x = torch::leaky_relu( x ); + activationIndex ++; break; + case NLR::Layer::SIGMOID: - x = torch::sigmoid(x); + x = torch::sigmoid( x ); + activationIndex ++; break; + case NLR::Layer::ABSOLUTE_VALUE: - x = torch::abs(x); + x = torch::abs( x ); + activationIndex ++; break; + case NLR::Layer::MAX: - x = torch::max( x ); + x = std::get<0>( torch::max( x, 1, true ) ); + activationIndex ++; break; + case NLR::Layer::SIGN: - x = torch::sign(x); + x = torch::sign( x ); + activationIndex ++; break; + case NLR::Layer::ROUND: - x = torch::round(x); + x = torch::round( x ); + activationIndex ++; break; + case NLR::Layer::SOFTMAX: - x = torch::softmax(x, 1); + x = torch::softmax( x, 1 ); + activationIndex ++; break; + default: std::cerr << "Unsupported activation type: " << activations[i] << std::endl; - break; + } } } } diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index 1f857981e3..c931a8a137 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -9,16 +9,21 @@ #undef Warning #include - class CustomDNNImpl : public torch::nn::Module { public: + enum Type { + INPUT, + LINEAR, + ACTIVATION, + }; Vector layerSizes; Vector activations; Vector>> weights; Vector> biases; Vector linearLayers; - + Vector layersOrder; + unsigned numberOfLayers; explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 219050ea3e..b3447a9d24 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1441,10 +1441,10 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) try { informConstraintsOfInitialBounds( inputQuery ); - // for (auto& inputVar : inputQuery.getInputVariables()) { - // inputQuery.setLowerBound(inputVar, -1.0); // Set lower bounds - // inputQuery.setUpperBound(inputVar, 1.0); // Set upper bounds - // } + for (auto& inputVar : inputQuery.getInputVariables()) { + inputQuery.setLowerBound(inputVar, -1.5); + inputQuery.setUpperBound(inputVar, 1.6); + } invokePreprocessor( inputQuery, preprocess ); if ( _verbosity > 1 ) printInputBounds( inputQuery ); @@ -1452,7 +1452,7 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) if (_networkLevelReasoner) { CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); - PGDAttack pgd_attack(network, inputQuery); + PGDAttack pgd_attack(network, _networkLevelReasoner); pgd_attack.displayAdversarialExample(); } diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index f594db5205..c3ed34bbf9 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -2,9 +2,9 @@ #include #include -PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery) - : model(model), inputQuery(inputQuery), device(torch::kCPU), - alpha(DEFAULT_ALPHA), num_iter(DEFAULT_NUM_ITER), num_restarts(DEFAULT_NUM_RESTARTS), lambdaPenalty( PANELTY ) { +PGDAttack::PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner) + : model(model), networkLevelReasoner( networkLevelReasoner ), device(torch::kCPU), + learningRate(LR), num_iter(DEFAULT_NUM_ITER), num_restarts(DEFAULT_NUM_RESTARTS), penalty( PANELTY ) { inputSize = model.layerSizes.first(); inputBounds = _getBounds(INPUT); outputBounds = _getBounds(OUTPUT); @@ -13,13 +13,14 @@ PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery) epsilon = variables.second; } -PGDAttack::PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery, double alpha, unsigned num_iter, - unsigned num_restarts, torch::Device device, double lambdaPenalty) - : model(model), inputQuery(inputQuery), device(device), - alpha(alpha), num_iter(num_iter), num_restarts(num_restarts), lambdaPenalty( lambdaPenalty ) { +PGDAttack::PGDAttack(CustomDNNImpl &model, + const NLR::NetworkLevelReasoner* networkLevelReasoner, double learningRate, unsigned num_iter, + unsigned num_restarts, torch::Device device, double penalty) + : model(model), networkLevelReasoner( networkLevelReasoner ), device(device), + learningRate(learningRate), num_iter(num_iter), num_restarts(num_restarts), penalty( penalty ) { inputSize = model.layerSizes.first(); - std::pair, Vector> inputBounds = _getBounds(INPUT); - std::pair, Vector> outputBounds = _getBounds(OUTPUT); + inputBounds = _getBounds(INPUT); + outputBounds = _getBounds(OUTPUT); std::pair variables = _generateSampleAndEpsilon(); originalInput = variables.first; epsilon = variables.second; @@ -39,19 +40,15 @@ std::pair, Vector> PGDAttack::_getBounds(unsigned type ) { Vector upperBounds; Vector lowerBounds; + unsigned layerIndex = type == INPUT ? 0 : networkLevelReasoner->getNumberOfLayers() -1; + const NLR::Layer *layer = networkLevelReasoner->getLayer( layerIndex ); - List variables = type == INPUT ? inputQuery.getInputVariables() : inputQuery.getOutputVariables(); + for (unsigned neuron = 0 ; neuron < layer->getSize(); ++neuron) { + double lowerBound = layer->getLb(neuron); + double upperBound = layer->getUb(neuron); - for (auto it = variables.begin(); it != variables.end(); ++it) { - double upperBound = inputQuery.getUpperBounds().exists(*it) - ? inputQuery.getUpperBounds().get(*it) - : std::numeric_limits::infinity(); - double lowerBound = inputQuery.getLowerBounds().exists(*it) - ? inputQuery.getLowerBounds().get(*it) - : -std::numeric_limits::infinity(); - - upperBounds.append(upperBound); - lowerBounds.append(lowerBound); + lowerBounds.append( lowerBound ); + upperBounds.append( upperBound ); } return {lowerBounds, upperBounds}; } @@ -95,6 +92,9 @@ bool PGDAttack::_isWithinBounds(const torch::Tensor& sample, unsigned type) { Vector upperBounds = bounds.second; torch::Tensor flatInput = sample.view({-1}); + if (flatInput.numel() != lowerBounds.size() || flatInput.numel() != upperBounds.size()) { + throw std::runtime_error("Mismatch in sizes of input and bounds"); + } for (int64_t i = 0; i < flatInput.size(0); i++) { double value = flatInput[i].item(); @@ -124,48 +124,48 @@ torch::Tensor PGDAttack::_calculateLoss(const torch::Tensor& predictions) { torch::Tensor lowerBoundTensor = torch::tensor(outputBounds.first.data(), torch::kFloat32).to(device); torch::Tensor upperBoundTensor = torch::tensor(outputBounds.second.data(), torch::kFloat32).to(device); - // Compute the penalty: We want high loss if predictions are inside the bounds - torch::Tensor penalty = torch::add( - - torch::relu(predictions - upperBoundTensor), - - torch::relu(lowerBoundTensor - predictions) - ); + // Compute the penalty: We want high loss if predictions are outside the bounds + torch::Tensor total_violation = torch::add( + torch::relu(predictions - upperBoundTensor), + torch::relu(lowerBoundTensor - predictions)); - return torch::sum(penalty); + torch::Tensor smoothed_violation = torch::log1p(total_violation) * penalty; + return torch::sum(smoothed_violation).pow( 2 );; } torch::Tensor PGDAttack::_findDelta() { - torch::Tensor max_delta = torch::zeros_like(originalInput).to(device); - torch::Tensor max_loss = torch::tensor(-std::numeric_limits::infinity()).to(device); + torch::Tensor bestDelta = torch::zeros_like(originalInput).to(device); + torch::Tensor minLoss = torch::tensor(std::numeric_limits::infinity()).to(device); for (unsigned i = 0; i < num_restarts; i++) { torch::Tensor delta = torch::rand(inputSize).to(device); delta = delta.mul(epsilon); delta.set_requires_grad(true); - torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions(alpha)); + torch::optim::Adam optimizer({delta}, + torch::optim::AdamOptions(learningRate)); for (unsigned j = 0; j < num_iter; j++) { optimizer.zero_grad(); - torch::Tensor pred = model.forward(originalInput + delta); - torch::Tensor loss = _calculateLoss(pred); - // Negate the loss for maximization - (-loss).backward(); + torch::Tensor prediction = model.forward(originalInput + delta); + torch::Tensor loss = _calculateLoss(prediction); + loss.backward(); optimizer.step(); // Project delta back to epsilon-ball delta.data() = delta.data().clamp(-epsilon, epsilon); } torch::Tensor currentPrediction = model.forward(originalInput + delta); - torch::Tensor current_loss = _calculateLoss(currentPrediction); - if (current_loss.item() > max_loss.item()) { - max_loss = current_loss; - max_delta = delta.detach().clone(); + torch::Tensor currentLoss = _calculateLoss(currentPrediction); + if (currentLoss.item() < minLoss.item()) { + minLoss = currentLoss; + bestDelta = delta.detach().clone(); } } - return max_delta; + return bestDelta; } bool PGDAttack::displayAdversarialExample() { @@ -175,25 +175,29 @@ bool PGDAttack::displayAdversarialExample() { auto original_pred = model.forward(originalInput); torch::Tensor adv_delta = _findDelta(); - torch::Tensor adv_example = originalInput + adv_delta; + torch::Tensor advInput = originalInput + adv_delta; - auto adv_pred = model.forward(adv_example); + auto advPred = model.forward(advInput); - auto loss = _calculateLoss(adv_pred); + bool isFooled = _isWithinBounds( advInput, INPUT ) && + _isWithinBounds( advPred, OUTPUT ); - - bool isFooled = _isWithinBounds( adv_example, INPUT ) && !_isWithinBounds( adv_pred, OUTPUT ); - - std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer() << "\n"; - std::cout << "Input Upper Bounds : " << inputBounds.second.getContainer() << "\n\n"; - std::cout << "Original Input: " << originalInput << "\n"; - std::cout << "Adversarial Example: " << adv_example << "\n\n"; + std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer()<< "\n"; + std::cout << "Input Upper Bounds : " << inputBounds.second.getContainer() << "\n"; + std::cout << "Adversarial Input: \n"; + auto* example = advInput.data_ptr(); + for (int i = 0; i < advInput.numel(); ++i) { + std::cout << "x" << i << " = "<< example[i] << "\n"; + } std::cout << "Output Lower Bounds : " << outputBounds.first.getContainer() << "\n"; - std::cout << "Output Lower Bounds : " << outputBounds.second.getContainer() << "\n"; - std::cout << "Original Prediction: " << original_pred << "\n"; - std::cout << ", Adversarial Prediction: " << adv_pred << "\n\n"; + std::cout << "Output Upper Bounds : " << outputBounds.second.getContainer() << "\n"; + std::cout << "Adversarial Prediction: \n"; + auto* prediction = advPred.data_ptr(); + for (int i = 0; i < advPred.numel(); ++i) { + std::cout << "y" << i << " = "<< prediction[i] << "\n"; + } std::cout << "Model fooled: " << (isFooled ? "Yes \n ------ PGD Attack Succeed ------" : - "No \n ------ PGD Attack Failed ------") << "\n"; + "No \n ------ PGD Attack Failed ------") << "\n\n"; return isFooled; } diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 8843bae089..46581e8dde 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -5,19 +5,19 @@ #undef Warning #include -constexpr float DEFAULT_ALPHA = 0.01; -constexpr float PANELTY = 0.1; -constexpr unsigned DEFAULT_NUM_ITER = 100; -constexpr unsigned DEFAULT_NUM_RESTARTS = 100; +constexpr float LR = 0.2; +constexpr float PANELTY = 10; +constexpr unsigned DEFAULT_NUM_ITER = 1000; +constexpr unsigned DEFAULT_NUM_RESTARTS = 10; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; -constexpr unsigned ATTACK_EPSILON = 10.0f; +constexpr unsigned ATTACK_EPSILON = 100.0f; class PGDAttack { public: - PGDAttack(CustomDNNImpl &model, InputQuery &inputQuery); + PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner); PGDAttack( CustomDNNImpl &model, - InputQuery &inputQuery, + const NLR::NetworkLevelReasoner* networkLevelReasoner, double alpha, unsigned num_iter, unsigned num_restarts, @@ -28,15 +28,15 @@ class PGDAttack { private: CustomDNNImpl &model; - InputQuery &inputQuery; + const NLR::NetworkLevelReasoner* networkLevelReasoner; torch::Device device; torch::Tensor epsilon; torch::Tensor originalInput; - double alpha; + double learningRate; unsigned num_iter; unsigned num_restarts; unsigned inputSize; - double lambdaPenalty; + double penalty; std::pair, Vector> inputBounds; std::pair, Vector> outputBounds; From 7c6385fe27123f30a288ef5b556b2625b8bf697b Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 23 Jul 2024 16:27:25 +0300 Subject: [PATCH 19/69] change num iters and CMakeLists.txt for cluster. --- CMakeLists.txt | 2 +- src/engine/PGD.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b58b029479..b1f81ee563 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ option(RUN_SYSTEM_TEST "Run system tests on build" OFF) option(RUN_MEMORY_TEST "Run cxxtest testing with ASAN ON" ON) option(RUN_PYTHON_TEST "Run Python API tests if building with Python" OFF) option(ENABLE_GUROBI "Enable use the Gurobi optimizer" OFF) -option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" ON) # Not available on Windows +option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" OFF) # Not available on Windows option(CODE_COVERAGE "Add code coverage" OFF) # Available only in debug mode ################### diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 46581e8dde..da99b0662b 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -5,9 +5,9 @@ #undef Warning #include -constexpr float LR = 0.2; +constexpr float LR = 0.1; constexpr float PANELTY = 10; -constexpr unsigned DEFAULT_NUM_ITER = 1000; +constexpr unsigned DEFAULT_NUM_ITER = 10000; constexpr unsigned DEFAULT_NUM_RESTARTS = 10; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; From 476c5199832d33895cb9f85cb5f609c98d88c813 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 29 Jul 2024 09:45:30 +0300 Subject: [PATCH 20/69] maxPool and improve LR --- src/configuration/GlobalConfiguration.cpp | 2 +- src/engine/CustomDNN.cpp | 67 +++++++++++++++++++---- src/engine/CustomDNN.h | 6 +- src/engine/PGD.cpp | 6 ++ 4 files changed, 69 insertions(+), 12 deletions(-) diff --git a/src/configuration/GlobalConfiguration.cpp b/src/configuration/GlobalConfiguration.cpp index c70ce013ef..bf1d0b9371 100644 --- a/src/configuration/GlobalConfiguration.cpp +++ b/src/configuration/GlobalConfiguration.cpp @@ -78,7 +78,7 @@ const bool GlobalConfiguration::PREPROCESS_INPUT_QUERY = true; const bool GlobalConfiguration::PREPROCESSOR_ELIMINATE_VARIABLES = true; const bool GlobalConfiguration::PL_CONSTRAINTS_ADD_AUX_EQUATIONS_AFTER_PREPROCESSING = true; const bool GlobalConfiguration::NL_CONSTRAINTS_ADD_AUX_EQUATIONS_AFTER_PREPROCESSING = true; -const double GlobalConfiguration::PREPROCESSOR_ALMOST_FIXED_THRESHOLD = 0.00001; +const double GlobalConfiguration::PREPROCESSOR_ALMOST_FIXED_THRESHOLD = 0.000000001; const unsigned GlobalConfiguration::PREPROCESSSING_MAX_TIGHTEING_ROUND = 1000; diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 1cf0896017..7c5559de03 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -2,10 +2,10 @@ #include "Vector.h" #include "NetworkLevelReasoner.h" -CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReasoner) { +CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* nlr) { std::cout << "----- Construct Custom Network -----" << std::endl; - + networkLevelReasoner = nlr; numberOfLayers = networkLevelReasoner->getNumberOfLayers(); for (unsigned i = 0; i < numberOfLayers; i++) { const NLR::Layer* layer = networkLevelReasoner->getLayer(i); @@ -55,12 +55,17 @@ CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReason // activation layers } else if (layerType == NLR::Layer::RELU || layerType == NLR::Layer::LEAKY_RELU || layerType == NLR::Layer::SIGMOID || layerType == NLR::Layer::ABSOLUTE_VALUE || - layerType == NLR::Layer::MAX || layerType == NLR::Layer::SIGN || + layerType == NLR::Layer::SIGN || layerType == NLR::Layer::ROUND || layerType == NLR::Layer::SOFTMAX) { layersOrder.append( ACTIVATION ); activations.append(layerType); - } else if (layerType == NLR::Layer::INPUT) { - // No action needed for input layer + } + else if(layerType == NLR::Layer::MAX) + { + maxLayerIndices.append( i ); + layersOrder.append( ACTIVATION ); + activations.append(layerType); + }else if (layerType == NLR::Layer::INPUT) { layersOrder.append( INPUT ); } else { std::cerr << "Unsupported layer type: " << layerType << std::endl; @@ -73,26 +78,62 @@ CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* networkLevelReason } + + + +torch::Tensor CustomDNNImpl::customMaxPool(unsigned maxLayerIndex, torch::Tensor *x) +{ + const NLR::Layer *layer = networkLevelReasoner->getLayer(maxLayerIndex); + Vector newX; + for (unsigned neuron = 0; neuron < layer->getSize(); ++neuron) + { + float maxVal = -std::numeric_limits::infinity(); + for (const NLR::NeuronIndex activationNeuron : layer->getActivationSources(neuron)) + { + int index = static_cast(activationNeuron._neuron); + maxVal = (std::max(maxVal, x->index({0, index}).item())); + } + newX.append(maxVal); + } + + unsigned batchSize = x->size(0); + unsigned newSize = static_cast(newX.size()); + return torch::tensor(newX.getContainer(), torch::kFloat).view({batchSize, newSize}); +} + + + torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { unsigned linearIndex = 0; unsigned activationIndex = 0; - for ( unsigned i = 1; i < numberOfLayers; i++ ) + unsigned maxPoolNum = 0; + for ( unsigned i = 0; i < numberOfLayers; i++ ) { - switch (layersOrder[i]) + Type layerType = layersOrder[i]; + switch (layerType) { + case INPUT: + // std::cout << "input layer " << i << ": shape: " << x.sizes() << std::endl; + break; case LINEAR: - + // std::cout << "linear Layer " << i << ": shape: " << x.sizes() << std::endl; x = linearLayers[linearIndex]->forward( x ); linearIndex ++; + // std::cout << " after linear Layer " << i << ": shape: " << x.sizes() << std::endl; + break; case ACTIVATION: { - switch ( activations[activationIndex] ) + NLR::Layer::Type activationType = activations[activationIndex]; + switch ( activationType ) { case NLR::Layer::RELU: + // std::cout << "Relu Layer " << i << ": shape: " << x.sizes() << std::endl; x = torch::relu( x ); activationIndex ++; + // std::cout << "after Relu Layer " << i << ": shape: " << x.sizes() << std::endl; + break; case NLR::Layer::LEAKY_RELU: @@ -111,9 +152,15 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { break; case NLR::Layer::MAX: - x = std::get<0>( torch::max( x, 1, true ) ); + { + // std::cout << "max Layer " << i << ": shape: " << x.sizes() << std::endl; + unsigned maxLayerIndex = maxLayerIndices[maxPoolNum]; + x = customMaxPool(maxLayerIndex, &x); activationIndex ++; + maxPoolNum ++; + // std::cout << "after max Layer " << i << ": shape: " << x.sizes() << std::endl; break; + } case NLR::Layer::SIGN: x = torch::sign( x ); diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index c931a8a137..73b61ed66b 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -17,17 +17,21 @@ class CustomDNNImpl : public torch::nn::Module LINEAR, ACTIVATION, }; + const NLR::NetworkLevelReasoner* networkLevelReasoner; Vector layerSizes; Vector activations; Vector>> weights; Vector> biases; Vector linearLayers; - Vector layersOrder; + Vector layersOrder; unsigned numberOfLayers; + Vector maxLayerIndices; explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); + torch::Tensor customMaxPool(unsigned max_layer_inxes, torch::Tensor *x ); torch::Tensor forward( torch::Tensor x ); }; + #endif \ No newline at end of file diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index c3ed34bbf9..14c4d38023 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -159,10 +159,16 @@ torch::Tensor PGDAttack::_findDelta() { torch::Tensor currentPrediction = model.forward(originalInput + delta); torch::Tensor currentLoss = _calculateLoss(currentPrediction); + if (_isWithinBounds( currentPrediction, OUTPUT )) + { + return delta; + } if (currentLoss.item() < minLoss.item()) { minLoss = currentLoss; bestDelta = delta.detach().clone(); } + + learningRate *=2; } return bestDelta; From 7b695401ecb0af34d900632681ba73158ab64cb0 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 29 Jul 2024 09:46:30 +0300 Subject: [PATCH 21/69] update DEFAULT_NUM_RESTARTS --- src/engine/PGD.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index da99b0662b..4e1c006aad 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -8,7 +8,7 @@ constexpr float LR = 0.1; constexpr float PANELTY = 10; constexpr unsigned DEFAULT_NUM_ITER = 10000; -constexpr unsigned DEFAULT_NUM_RESTARTS = 10; +constexpr unsigned DEFAULT_NUM_RESTARTS = 20; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned ATTACK_EPSILON = 100.0f; From bc1375d0a63ca00bf69586dc04dd8bfb8c9a708b Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 30 Jul 2024 16:38:12 +0300 Subject: [PATCH 22/69] find delta to find example --- src/engine/PGD.cpp | 20 ++++++++++---------- src/engine/PGD.h | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 14c4d38023..e504980b96 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -134,9 +134,11 @@ torch::Tensor PGDAttack::_calculateLoss(const torch::Tensor& predictions) { } -torch::Tensor PGDAttack::_findDelta() { +std::pair PGDAttack::_findAdvExample() { torch::Tensor bestDelta = torch::zeros_like(originalInput).to(device); torch::Tensor minLoss = torch::tensor(std::numeric_limits::infinity()).to(device); + torch::Tensor currentPrediction; + torch::Tensor currentExample; for (unsigned i = 0; i < num_restarts; i++) { torch::Tensor delta = torch::rand(inputSize).to(device); @@ -156,12 +158,12 @@ torch::Tensor PGDAttack::_findDelta() { // Project delta back to epsilon-ball delta.data() = delta.data().clamp(-epsilon, epsilon); } - - torch::Tensor currentPrediction = model.forward(originalInput + delta); + currentExample = originalInput + delta; + currentPrediction = model.forward(currentExample); torch::Tensor currentLoss = _calculateLoss(currentPrediction); if (_isWithinBounds( currentPrediction, OUTPUT )) { - return delta; + return {currentExample, currentPrediction}; } if (currentLoss.item() < minLoss.item()) { minLoss = currentLoss; @@ -171,7 +173,7 @@ torch::Tensor PGDAttack::_findDelta() { learningRate *=2; } - return bestDelta; + return {currentExample, currentPrediction};; } bool PGDAttack::displayAdversarialExample() { @@ -179,11 +181,9 @@ bool PGDAttack::displayAdversarialExample() { model.eval(); auto original_pred = model.forward(originalInput); - - torch::Tensor adv_delta = _findDelta(); - torch::Tensor advInput = originalInput + adv_delta; - - auto advPred = model.forward(advInput); + auto adversarial = _findAdvExample(); + torch::Tensor advInput = adversarial.first; + auto advPred = adversarial.second; bool isFooled = _isWithinBounds( advInput, INPUT ) && _isWithinBounds( advPred, OUTPUT ); diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 4e1c006aad..e4d3b9e47f 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -7,8 +7,8 @@ constexpr float LR = 0.1; constexpr float PANELTY = 10; -constexpr unsigned DEFAULT_NUM_ITER = 10000; -constexpr unsigned DEFAULT_NUM_RESTARTS = 20; +constexpr unsigned DEFAULT_NUM_ITER = 100; +constexpr unsigned DEFAULT_NUM_RESTARTS = 10; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned ATTACK_EPSILON = 100.0f; @@ -40,7 +40,7 @@ class PGDAttack { std::pair, Vector> inputBounds; std::pair, Vector> outputBounds; - torch::Tensor _findDelta(); + std::pair _findAdvExample(); std::pair _generateSampleAndEpsilon(); bool _isWithinBounds( const torch::Tensor &sample, unsigned type ); std::pair, Vector> _getBounds(unsigned type ) const; From 51c70902c6d405d80d8c92d9fc3352a42505c81b Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 30 Jul 2024 17:19:15 +0300 Subject: [PATCH 23/69] improve loss --- src/engine/PGD.cpp | 27 +++++++++++++-------------- src/engine/PGD.h | 10 +++++----- 2 files changed, 18 insertions(+), 19 deletions(-) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index e504980b96..271e63c909 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -4,7 +4,7 @@ PGDAttack::PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner) : model(model), networkLevelReasoner( networkLevelReasoner ), device(torch::kCPU), - learningRate(LR), num_iter(DEFAULT_NUM_ITER), num_restarts(DEFAULT_NUM_RESTARTS), penalty( PANELTY ) { + learningRate(LR), iters(DEFAULT_NUM_ITER), restarts(DEFAULT_NUM_RESTARTS), penalty( PANELTY ) { inputSize = model.layerSizes.first(); inputBounds = _getBounds(INPUT); outputBounds = _getBounds(OUTPUT); @@ -17,7 +17,7 @@ PGDAttack::PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner, double learningRate, unsigned num_iter, unsigned num_restarts, torch::Device device, double penalty) : model(model), networkLevelReasoner( networkLevelReasoner ), device(device), - learningRate(learningRate), num_iter(num_iter), num_restarts(num_restarts), penalty( penalty ) { + learningRate(learningRate), iters(num_iter), restarts(num_restarts), penalty( penalty ) { inputSize = model.layerSizes.first(); inputBounds = _getBounds(INPUT); outputBounds = _getBounds(OUTPUT); @@ -69,12 +69,12 @@ std::pair PGDAttack::_generateSampleAndEpsilon() { epsilons[i] = std::numeric_limits::infinity(); } else if (std::isinf(lower)) { // Only lower bound is infinite - sample[i] = upper - ATTACK_EPSILON; - epsilons[i] = ATTACK_EPSILON; + sample[i] = upper - RANGE; + epsilons[i] = RANGE; } else if (std::isinf(upper)) { // Only upper bound is infinite - sample[i] = lower + ATTACK_EPSILON; - epsilons[i] = ATTACK_EPSILON; + sample[i] = lower + RANGE; + epsilons[i] = RANGE; } else { // Both bounds are finite sample[i] = lower + (upper - lower) / 2.0f; @@ -125,12 +125,11 @@ torch::Tensor PGDAttack::_calculateLoss(const torch::Tensor& predictions) { torch::Tensor upperBoundTensor = torch::tensor(outputBounds.second.data(), torch::kFloat32).to(device); // Compute the penalty: We want high loss if predictions are outside the bounds - torch::Tensor total_violation = torch::add( - torch::relu(predictions - upperBoundTensor), - torch::relu(lowerBoundTensor - predictions)); - - torch::Tensor smoothed_violation = torch::log1p(total_violation) * penalty; - return torch::sum(smoothed_violation).pow( 2 );; + torch::Tensor ubViolation = torch::sum(torch::square( + torch::relu(predictions - upperBoundTensor ))); + torch::Tensor lbViolation = torch::sum(torch::square( + torch::relu(lowerBoundTensor - predictions) )); + return torch::sum(ubViolation + lbViolation) ; } @@ -140,7 +139,7 @@ std::pair PGDAttack::_findAdvExample() { torch::Tensor currentPrediction; torch::Tensor currentExample; - for (unsigned i = 0; i < num_restarts; i++) { + for (unsigned i = 0; i < restarts; i++) { torch::Tensor delta = torch::rand(inputSize).to(device); delta = delta.mul(epsilon); delta.set_requires_grad(true); @@ -148,7 +147,7 @@ std::pair PGDAttack::_findAdvExample() { torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions(learningRate)); - for (unsigned j = 0; j < num_iter; j++) { + for (unsigned j = 0; j < iters; j++) { optimizer.zero_grad(); torch::Tensor prediction = model.forward(originalInput + delta); diff --git a/src/engine/PGD.h b/src/engine/PGD.h index e4d3b9e47f..d49a898e30 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -7,11 +7,11 @@ constexpr float LR = 0.1; constexpr float PANELTY = 10; -constexpr unsigned DEFAULT_NUM_ITER = 100; -constexpr unsigned DEFAULT_NUM_RESTARTS = 10; +constexpr unsigned DEFAULT_NUM_ITER = 1000; +constexpr unsigned DEFAULT_NUM_RESTARTS = 5; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; -constexpr unsigned ATTACK_EPSILON = 100.0f; +constexpr unsigned RANGE = 1000.0f; class PGDAttack { public: @@ -33,8 +33,8 @@ class PGDAttack { torch::Tensor epsilon; torch::Tensor originalInput; double learningRate; - unsigned num_iter; - unsigned num_restarts; + unsigned iters; + unsigned restarts; unsigned inputSize; double penalty; std::pair, Vector> inputBounds; From 1102cbf95d73fab3379bd57730fad09dcefb59ce Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 1 Aug 2024 16:26:48 +0300 Subject: [PATCH 24/69] pgd class & --- src/engine/CustomDNN.cpp | 23 ++------- src/engine/CustomDNN.h | 4 +- src/engine/PGD.cpp | 101 +++++++++++++++------------------------ src/engine/PGD.h | 18 +++---- 4 files changed, 50 insertions(+), 96 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 7c5559de03..06ba3b0e9e 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -71,17 +71,11 @@ CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* nlr) { std::cerr << "Unsupported layer type: " << layerType << std::endl; } } - std::cout << "Number of layers: " << linearLayers.size() + 1<< std::endl; - std::cout << "Number of activations: " << activations.size() << std::endl; - std::cout << "Input layer size: " << layerSizes.first() << std::endl; - std::cout << "Output layer size: " << layerSizes.last() << std::endl; } - - -torch::Tensor CustomDNNImpl::customMaxPool(unsigned maxLayerIndex, torch::Tensor *x) +torch::Tensor CustomDNNImpl::customMaxPool(unsigned maxLayerIndex, torch::Tensor x ) const { const NLR::Layer *layer = networkLevelReasoner->getLayer(maxLayerIndex); Vector newX; @@ -91,18 +85,17 @@ torch::Tensor CustomDNNImpl::customMaxPool(unsigned maxLayerIndex, torch::Tensor for (const NLR::NeuronIndex activationNeuron : layer->getActivationSources(neuron)) { int index = static_cast(activationNeuron._neuron); - maxVal = (std::max(maxVal, x->index({0, index}).item())); + maxVal = (std::max(maxVal, x.index({0, index}).item())); } newX.append(maxVal); } - unsigned batchSize = x->size(0); + unsigned batchSize = x.size(0); unsigned newSize = static_cast(newX.size()); return torch::tensor(newX.getContainer(), torch::kFloat).view({batchSize, newSize}); } - torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { unsigned linearIndex = 0; unsigned activationIndex = 0; @@ -113,13 +106,10 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { switch (layerType) { case INPUT: - // std::cout << "input layer " << i << ": shape: " << x.sizes() << std::endl; break; case LINEAR: - // std::cout << "linear Layer " << i << ": shape: " << x.sizes() << std::endl; x = linearLayers[linearIndex]->forward( x ); linearIndex ++; - // std::cout << " after linear Layer " << i << ": shape: " << x.sizes() << std::endl; break; @@ -129,10 +119,8 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { switch ( activationType ) { case NLR::Layer::RELU: - // std::cout << "Relu Layer " << i << ": shape: " << x.sizes() << std::endl; x = torch::relu( x ); activationIndex ++; - // std::cout << "after Relu Layer " << i << ": shape: " << x.sizes() << std::endl; break; @@ -153,12 +141,9 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { case NLR::Layer::MAX: { - // std::cout << "max Layer " << i << ": shape: " << x.sizes() << std::endl; - unsigned maxLayerIndex = maxLayerIndices[maxPoolNum]; - x = customMaxPool(maxLayerIndex, &x); + x = customMaxPool(maxLayerIndices[maxPoolNum], x); activationIndex ++; maxPoolNum ++; - // std::cout << "after max Layer " << i << ": shape: " << x.sizes() << std::endl; break; } diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index 73b61ed66b..642c55e9f9 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -2,8 +2,6 @@ #define CUSTOM_DNN_H #include "NetworkLevelReasoner.h" - -#include #include #undef Warning @@ -29,7 +27,7 @@ class CustomDNNImpl : public torch::nn::Module explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); - torch::Tensor customMaxPool(unsigned max_layer_inxes, torch::Tensor *x ); + torch::Tensor customMaxPool(unsigned max_layer_inxes, torch::Tensor x ) const; torch::Tensor forward( torch::Tensor x ); }; diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 271e63c909..5a9d37726c 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -4,25 +4,25 @@ PGDAttack::PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner) : model(model), networkLevelReasoner( networkLevelReasoner ), device(torch::kCPU), - learningRate(LR), iters(DEFAULT_NUM_ITER), restarts(DEFAULT_NUM_RESTARTS), penalty( PANELTY ) { + iters(DEFAULT_NUM_ITER), restarts(DEFAULT_NUM_RESTARTS) { inputSize = model.layerSizes.first(); - inputBounds = _getBounds(INPUT); - outputBounds = _getBounds(OUTPUT); + _getBounds(inputBounds, INPUT); + _getBounds(outputBounds, OUTPUT); std::pair variables = _generateSampleAndEpsilon(); - originalInput = variables.first; + InputExample = variables.first; epsilon = variables.second; } PGDAttack::PGDAttack(CustomDNNImpl &model, - const NLR::NetworkLevelReasoner* networkLevelReasoner, double learningRate, unsigned num_iter, - unsigned num_restarts, torch::Device device, double penalty) + const NLR::NetworkLevelReasoner* networkLevelReasoner, unsigned num_iter, + unsigned num_restarts, torch::Device device) : model(model), networkLevelReasoner( networkLevelReasoner ), device(device), - learningRate(learningRate), iters(num_iter), restarts(num_restarts), penalty( penalty ) { + iters(num_iter), restarts(num_restarts) { inputSize = model.layerSizes.first(); - inputBounds = _getBounds(INPUT); - outputBounds = _getBounds(OUTPUT); + _getBounds(inputBounds, INPUT); + _getBounds(outputBounds, OUTPUT); std::pair variables = _generateSampleAndEpsilon(); - originalInput = variables.first; + InputExample = variables.first; epsilon = variables.second; } @@ -36,43 +36,33 @@ torch::Device PGDAttack::_getDevice() { } } -std::pair, Vector> PGDAttack::_getBounds(unsigned type ) const +void PGDAttack::_getBounds(std::pair, Vector> &bounds, + const signed type ) const { - Vector upperBounds; - Vector lowerBounds; unsigned layerIndex = type == INPUT ? 0 : networkLevelReasoner->getNumberOfLayers() -1; const NLR::Layer *layer = networkLevelReasoner->getLayer( layerIndex ); for (unsigned neuron = 0 ; neuron < layer->getSize(); ++neuron) { - double lowerBound = layer->getLb(neuron); - double upperBound = layer->getUb(neuron); - - lowerBounds.append( lowerBound ); - upperBounds.append( upperBound ); + bounds.first.append( layer->getLb(neuron) ); + bounds.second.append( layer->getUb(neuron) ); } - return {lowerBounds, upperBounds}; } std::pair PGDAttack::_generateSampleAndEpsilon() { Vector sample(inputSize, 0.0f); Vector epsilons(inputSize, 0.0f); - Vector lowerBounds = inputBounds.first; - Vector upperBounds = inputBounds.second; for (unsigned i = 0; i < inputSize; i++) { - double lower = lowerBounds.get(i); - double upper = upperBounds.get(i); + double lower = inputBounds.first.get(i); + double upper = inputBounds.second.get(i); if (std::isinf(lower) && std::isinf(upper)) { - // Both bounds are infinite sample[i] = 0.0f; epsilons[i] = std::numeric_limits::infinity(); } else if (std::isinf(lower)) { - // Only lower bound is infinite sample[i] = upper - RANGE; epsilons[i] = RANGE; } else if (std::isinf(upper)) { - // Only upper bound is infinite sample[i] = lower + RANGE; epsilons[i] = RANGE; } else { @@ -86,20 +76,18 @@ std::pair PGDAttack::_generateSampleAndEpsilon() { torch::tensor(epsilons.getContainer()).to(device)}; } -bool PGDAttack::_isWithinBounds(const torch::Tensor& sample, unsigned type) { - std::pair, Vector> bounds = _getBounds(type); - Vector lowerBounds = bounds.first; - Vector upperBounds = bounds.second; +bool PGDAttack::_isWithinBounds(const torch::Tensor& sample, + const std::pair, Vector> &bounds) { torch::Tensor flatInput = sample.view({-1}); - if (flatInput.numel() != lowerBounds.size() || flatInput.numel() != upperBounds.size()) { + if (flatInput.numel() != bounds.first.size() || flatInput.numel() != bounds.second.size()) { throw std::runtime_error("Mismatch in sizes of input and bounds"); } for (int64_t i = 0; i < flatInput.size(0); i++) { - double value = flatInput[i].item(); - double lower = lowerBounds.get(i); - double upper = upperBounds.get(i); + auto value = flatInput[i].item(); + double lower = bounds.first.get(i); + double upper = bounds.second.get(i); if (std::isinf(lower) && std::isinf(upper)) { // If both bounds are infinite, any value is acceptable @@ -126,50 +114,40 @@ torch::Tensor PGDAttack::_calculateLoss(const torch::Tensor& predictions) { // Compute the penalty: We want high loss if predictions are outside the bounds torch::Tensor ubViolation = torch::sum(torch::square( - torch::relu(predictions - upperBoundTensor ))); + torch::relu(predictions - upperBoundTensor ))).to(device); torch::Tensor lbViolation = torch::sum(torch::square( - torch::relu(lowerBoundTensor - predictions) )); - return torch::sum(ubViolation + lbViolation) ; + torch::relu(lowerBoundTensor - predictions) )).to(device); + return torch::sum(ubViolation + lbViolation).to(device); } std::pair PGDAttack::_findAdvExample() { - torch::Tensor bestDelta = torch::zeros_like(originalInput).to(device); - torch::Tensor minLoss = torch::tensor(std::numeric_limits::infinity()).to(device); - torch::Tensor currentPrediction; torch::Tensor currentExample; + torch::Tensor currentPrediction; - for (unsigned i = 0; i < restarts; i++) { - torch::Tensor delta = torch::rand(inputSize).to(device); - delta = delta.mul(epsilon); + for (unsigned i = 0; i < restarts; ++i) { + torch::Tensor delta = torch::rand(inputSize).mul(epsilon).to(device); delta.set_requires_grad(true); + torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions()); - torch::optim::Adam optimizer({delta}, - torch::optim::AdamOptions(learningRate)); - - for (unsigned j = 0; j < iters; j++) { + for (unsigned j = 0; j < iters; ++j) { + currentExample = InputExample + delta; + currentPrediction = model.forward(currentExample); + torch::Tensor loss = _calculateLoss(currentPrediction); optimizer.zero_grad(); - - torch::Tensor prediction = model.forward(originalInput + delta); - torch::Tensor loss = _calculateLoss(prediction); loss.backward(); optimizer.step(); - // Project delta back to epsilon-ball delta.data() = delta.data().clamp(-epsilon, epsilon); } - currentExample = originalInput + delta; + + currentExample = InputExample + delta; currentPrediction = model.forward(currentExample); torch::Tensor currentLoss = _calculateLoss(currentPrediction); - if (_isWithinBounds( currentPrediction, OUTPUT )) + if (_isWithinBounds( currentPrediction, outputBounds )) { return {currentExample, currentPrediction}; } - if (currentLoss.item() < minLoss.item()) { - minLoss = currentLoss; - bestDelta = delta.detach().clone(); - } - learningRate *=2; } return {currentExample, currentPrediction};; @@ -177,15 +155,12 @@ std::pair PGDAttack::_findAdvExample() { bool PGDAttack::displayAdversarialExample() { std::cout << "-----Starting PGD attack-----" << std::endl; - model.eval(); - - auto original_pred = model.forward(originalInput); auto adversarial = _findAdvExample(); torch::Tensor advInput = adversarial.first; auto advPred = adversarial.second; - bool isFooled = _isWithinBounds( advInput, INPUT ) && - _isWithinBounds( advPred, OUTPUT ); + bool isFooled = _isWithinBounds( advInput, inputBounds ) && + _isWithinBounds( advPred, outputBounds ); std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer()<< "\n"; std::cout << "Input Upper Bounds : " << inputBounds.second.getContainer() << "\n"; diff --git a/src/engine/PGD.h b/src/engine/PGD.h index d49a898e30..fe9a6f0c59 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -5,10 +5,9 @@ #undef Warning #include -constexpr float LR = 0.1; -constexpr float PANELTY = 10; +constexpr float LR = 0.05; constexpr unsigned DEFAULT_NUM_ITER = 1000; -constexpr unsigned DEFAULT_NUM_RESTARTS = 5; +constexpr unsigned DEFAULT_NUM_RESTARTS = 20; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; @@ -18,11 +17,9 @@ class PGDAttack { PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner); PGDAttack( CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner, - double alpha, unsigned num_iter, unsigned num_restarts, - torch::Device device, - double lambdaPenalty ); + torch::Device device); bool displayAdversarialExample(); @@ -31,19 +28,18 @@ class PGDAttack { const NLR::NetworkLevelReasoner* networkLevelReasoner; torch::Device device; torch::Tensor epsilon; - torch::Tensor originalInput; - double learningRate; + torch::Tensor InputExample; unsigned iters; unsigned restarts; unsigned inputSize; - double penalty; std::pair, Vector> inputBounds; std::pair, Vector> outputBounds; std::pair _findAdvExample(); std::pair _generateSampleAndEpsilon(); - bool _isWithinBounds( const torch::Tensor &sample, unsigned type ); - std::pair, Vector> _getBounds(unsigned type ) const; + static bool _isWithinBounds(const torch::Tensor& sample, + const std::pair, Vector> &bounds); + void _getBounds(std::pair, Vector> &bounds, signed type ) const; torch::Tensor _calculateLoss( const torch::Tensor &predictions ); static torch::Device _getDevice(); From 7cbe917b3e5bf7470c57d50573c5d21bfc53d5ef Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 10 Aug 2024 14:08:49 +0300 Subject: [PATCH 25/69] fix customDNN class & --- src/engine/CustomDNN.cpp | 415 ++++++++++++++++++++++++++------------- src/engine/CustomDNN.h | 23 ++- 2 files changed, 291 insertions(+), 147 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 06ba3b0e9e..7a3868d7c0 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,172 +1,305 @@ #include "CustomDNN.h" -#include "Vector.h" + #include "NetworkLevelReasoner.h" +#include "Vector.h" -CustomDNNImpl::CustomDNNImpl(const NLR::NetworkLevelReasoner* nlr) { +#include - std::cout << "----- Construct Custom Network -----" << std::endl; - networkLevelReasoner = nlr; - numberOfLayers = networkLevelReasoner->getNumberOfLayers(); - for (unsigned i = 0; i < numberOfLayers; i++) { - const NLR::Layer* layer = networkLevelReasoner->getLayer(i); - layerSizes.append(layer->getSize()); - NLR::Layer::Type layerType = layer->getLayerType(); - if (layerType == NLR::Layer::WEIGHTED_SUM) { - layersOrder.append( LINEAR ); - // Fully connected layer - unsigned sourceLayer = i - 1; - const NLR::Layer *prevLayer = networkLevelReasoner->getLayer(sourceLayer); - unsigned inputSize = prevLayer->getSize(); - unsigned outputSize = layer->getSize(); - - if (outputSize > 0) { - auto linearLayer = torch::nn::Linear(torch::nn::LinearOptions(inputSize, outputSize)); - linearLayers.append(linearLayer); - register_module("linear" + std::to_string(i), linearLayer); - - Vector> layerWeights(outputSize, Vector(inputSize)); - Vector layerBiases(layer->getSize()); - - // Fetch weights and biases from the networkLevelReasoner - for (unsigned j = 0; j < outputSize; j++) { - for (unsigned k = 0; k < inputSize; k++) { - double weight_value = layer->getWeight(sourceLayer, k, j); - layerWeights[j][k] = static_cast(weight_value); - } - double bias_value = layer->getBias(j); - layerBiases[j] = static_cast(bias_value); - } - - Vector flattenedWeights; - for (const auto& weight : layerWeights) { - for (const auto& w : weight) { - flattenedWeights.append(w); - } - } - - torch::Tensor weightTensor = torch::tensor(flattenedWeights.getContainer(), torch::kFloat) - .view({ layer->getSize(), prevLayer->getSize() }); - torch::Tensor biasTensor = torch::tensor(layerBiases.getContainer(), torch::kFloat); - torch::NoGradGuard no_grad; - linearLayer->weight.set_(weightTensor); - linearLayer->bias.set_(biasTensor); - } - // activation layers - } else if (layerType == NLR::Layer::RELU || layerType == NLR::Layer::LEAKY_RELU || - layerType == NLR::Layer::SIGMOID || layerType == NLR::Layer::ABSOLUTE_VALUE || - layerType == NLR::Layer::SIGN || - layerType == NLR::Layer::ROUND || layerType == NLR::Layer::SOFTMAX) { - layersOrder.append( ACTIVATION ); - activations.append(layerType); - } - else if(layerType == NLR::Layer::MAX) +CustomMaxPool::CustomMaxPool(const NLR::NetworkLevelReasoner* nlr, unsigned layerIndex) + : networkLevelReasoner(nlr), maxLayerIndex(layerIndex) {} + +torch::Tensor CustomMaxPool::forward( torch::Tensor x ) const +{ + std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; + fflush( stdout ); + + const NLR::Layer *layer = networkLevelReasoner->getLayer( maxLayerIndex ); + torch::Tensor maxOutputs = torch::zeros( { 1, layer->getSize() } ); + + for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) + { + auto sources = layer->getActivationSources( neuron ); + torch::Tensor maxSource = torch::zeros( sources.size(), torch::kFloat ); + + for ( int i = sources.size() - 1; i >= 0; --i ) { - maxLayerIndices.append( i ); - layersOrder.append( ACTIVATION ); - activations.append(layerType); - }else if (layerType == NLR::Layer::INPUT) { - layersOrder.append( INPUT ); - } else { - std::cerr << "Unsupported layer type: " << layerType << std::endl; + const NLR::NeuronIndex &activationNeuron = sources.back(); + sources.popBack(); + int index = static_cast( activationNeuron._neuron ); + maxSource[i] = x.index( { 0, index } ); } + maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); } -} + std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; + fflush( stdout ); + return maxOutputs; +} -torch::Tensor CustomDNNImpl::customMaxPool(unsigned maxLayerIndex, torch::Tensor x ) const +void CustomDNNImpl::weightedSum( unsigned i, const NLR::Layer *layer) { - const NLR::Layer *layer = networkLevelReasoner->getLayer(maxLayerIndex); - Vector newX; - for (unsigned neuron = 0; neuron < layer->getSize(); ++neuron) + unsigned sourceLayer = i - 1; + const NLR::Layer *prevLayer = networkLevelReasoner->getLayer( sourceLayer ); + unsigned inputSize = prevLayer->getSize(); + unsigned outputSize = layer->getSize(); + + if ( outputSize > 0 ) { - float maxVal = -std::numeric_limits::infinity(); - for (const NLR::NeuronIndex activationNeuron : layer->getActivationSources(neuron)) + auto linearLayer = torch::nn::Linear( torch::nn::LinearOptions( inputSize, outputSize ) ); + linearLayers.append( linearLayer ); + register_module( "linear" + std::to_string( i ), linearLayer ); + + Vector> layerWeights( outputSize, Vector( inputSize ) ); + Vector layerBiases( layer->getSize() ); + + // Fetch weights and biases from the networkLevelReasoner + for ( unsigned j = 0; j < outputSize; j++ ) { - int index = static_cast(activationNeuron._neuron); - maxVal = (std::max(maxVal, x.index({0, index}).item())); + for ( unsigned k = 0; k < inputSize; k++ ) + { + double weight_value = layer->getWeight( sourceLayer, k, j ); + layerWeights[j][k] = static_cast( weight_value ); + } + double bias_value = layer->getBias( j ); + layerBiases[j] = static_cast( bias_value ); } - newX.append(maxVal); - } - - unsigned batchSize = x.size(0); - unsigned newSize = static_cast(newX.size()); - return torch::tensor(newX.getContainer(), torch::kFloat).view({batchSize, newSize}); -} + Vector flattenedWeights; + for ( const auto &weight : layerWeights ) + { + for ( const auto &w : weight ) + { + flattenedWeights.append( w ); + } + } -torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { - unsigned linearIndex = 0; - unsigned activationIndex = 0; - unsigned maxPoolNum = 0; + torch::Tensor weightTensor = torch::tensor( flattenedWeights.getContainer(), torch::kFloat ) + .view( { layer->getSize(), prevLayer->getSize() } ); + torch::Tensor biasTensor = torch::tensor( layerBiases.getContainer(), torch::kFloat ); + torch::NoGradGuard no_grad; + linearLayer->weight.set_( weightTensor ); + linearLayer->bias.set_( biasTensor ); + } +} +CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) +{ + std::cout << "----- Construct Custom Network -----" << std::endl; + networkLevelReasoner = nlr; + numberOfLayers = networkLevelReasoner->getNumberOfLayers(); for ( unsigned i = 0; i < numberOfLayers; i++ ) { - Type layerType = layersOrder[i]; + const NLR::Layer *layer = networkLevelReasoner->getLayer( i ); + layerSizes.append( layer->getSize() ); + NLR::Layer::Type layerType = layer->getLayerType(); + layersOrder.append( layerType ); switch (layerType) { - case INPUT: + case NLR::Layer::INPUT: break; - case LINEAR: - x = linearLayers[linearIndex]->forward( x ); - linearIndex ++; - + case NLR::Layer::WEIGHTED_SUM: + weightedSum( i, layer ); break; + case NLR::Layer::RELU: + { + auto reluLayer = torch::nn::ReLU( torch::nn::ReLUOptions() ); + reluLayers.append( reluLayer ); + register_module( "relu" + std::to_string( i ), reluLayer ); + break; + } + case NLR::Layer::LEAKY_RELU: + { + auto reluLayer = torch::nn::LeakyReLU( torch::nn::LeakyReLUOptions() ); + leakyReluLayers.append( reluLayer ); + register_module( "leaky_relu" + std::to_string( i ), reluLayer ); + break; + } + case NLR::Layer::MAX: + { + auto customMaxPoolLayer = std::make_shared(networkLevelReasoner, i); + customMaxPoolLayers.append(customMaxPoolLayer); + register_module("custom_max_pool" + std::to_string(i), customMaxPoolLayer); + break; + } + case NLR::Layer::SIGMOID: + { + auto sigmoidLayer = torch::nn::Sigmoid(); + sigmoidLayers.append(sigmoidLayer); + register_module("sigmoid" + std::to_string(i), sigmoidLayer); + break; + } + default: + std::cerr << "Unsupported layer type: " << layerType << std::endl; + break; + } + } +} - case ACTIVATION: - { - NLR::Layer::Type activationType = activations[activationIndex]; - switch ( activationType ) - { - case NLR::Layer::RELU: - x = torch::relu( x ); - activationIndex ++; - - break; - - case NLR::Layer::LEAKY_RELU: - x = torch::leaky_relu( x ); - activationIndex ++; - break; - - case NLR::Layer::SIGMOID: - x = torch::sigmoid( x ); - activationIndex ++; - break; - - case NLR::Layer::ABSOLUTE_VALUE: - x = torch::abs( x ); - activationIndex ++; - break; - - case NLR::Layer::MAX: - { - x = customMaxPool(maxLayerIndices[maxPoolNum], x); - activationIndex ++; - maxPoolNum ++; - break; - } - case NLR::Layer::SIGN: - x = torch::sign( x ); - activationIndex ++; - break; - case NLR::Layer::ROUND: - x = torch::round( x ); - activationIndex ++; - break; +// torch::Tensor CustomDNNImpl::customMaxPool( unsigned maxLayerIndex, torch::Tensor x ) const +// { +// std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; +// fflush( stdout ); +// const NLR::Layer *layer = networkLevelReasoner->getLayer( maxLayerIndex ); +// torch::Tensor maxOutputs = torch::zeros( { 1, layer->getSize() } ); +// +// torch::Tensor maxSource; +// +// for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) +// { +// auto sources = layer->getActivationSources( neuron ); +// maxSource = torch::zeros( sources.size(), torch::kFloat ); +// +// for ( int i = sources.size() - 1; i >= 0; --i ) +// { +// const NLR::NeuronIndex &activationNeuron = sources.back(); +// sources.popBack(); +// int index = static_cast( activationNeuron._neuron ); +// maxSource[i] = x.index( { 0, index } ); +// } +// maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); +// } +// std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; +// fflush( stdout ); +// +// +// return maxOutputs; +// } - case NLR::Layer::SOFTMAX: - x = torch::softmax( x, 1 ); - activationIndex ++; - break; +torch::Tensor CustomDNNImpl::forward(torch::Tensor x) +{ + unsigned linearIndex = 0; + unsigned reluIndex = 0; + unsigned maxPoolIndex = 0; + unsigned leakyReluIndex = 0; + unsigned sigmoidIndex = 0; + for (unsigned i = 0; i < numberOfLayers; i++) + { + NLR::Layer::Type layerType = layersOrder[i]; + switch (layerType) + { + case NLR::Layer::INPUT: + break; + case NLR::Layer::WEIGHTED_SUM: + x = linearLayers[linearIndex]->forward(x); + linearIndex++; + break; + case NLR::Layer::RELU: + x = reluLayers[reluIndex]->forward( x ); + reluIndex++; + break; + case NLR::Layer::MAX: + x = customMaxPoolLayers[maxPoolIndex]->forward( x ); + maxPoolIndex++; + break; + case NLR::Layer::LEAKY_RELU: + x = leakyReluLayers[leakyReluIndex]->forward(x); + leakyReluIndex++; + break; + case NLR::Layer::SIGMOID: + x = sigmoidLayers[sigmoidIndex]->forward(x); + sigmoidIndex++; + break; + default: + std::cerr << "Unsupported activation type: " << activations[i] << std::endl; - default: - std::cerr << "Unsupported activation type: " << activations[i] << std::endl; - } - } } } return x; -} \ No newline at end of file +} + + + +// torch::Tensor CustomDNNImpl::forward( torch::Tensor x ) +// { +// unsigned linearIndex = 0; +// unsigned activationIndex = 0; +// unsigned maxPoolNum = 0; +// for ( unsigned i = 0; i < numberOfLayers; i++ ) +// { +// NLR::Layer::Type layerType = layersOrder[i]; +// switch ( layerType ) +// { +// case NLR::Layer::INPUT: +// break; +// case NLR::Layer::WEIGHTED_SUM: +// x = linearLayers[linearIndex]->forward( x ); +// linearIndex++; +// +// break; +// +// case ACTIVATION: +// { +// NLR::Layer::Type activationType = activations[activationIndex]; +// switch ( activationType ) +// { +// case NLR::Layer::RELU: +// x = torch::relu( x ); +// activationIndex++; +// +// break; +// +// case NLR::Layer::LEAKY_RELU: +// x = torch::leaky_relu( x ); +// activationIndex++; +// break; +// +// case NLR::Layer::SIGMOID: +// x = torch::sigmoid( x ); +// activationIndex++; +// break; +// +// case NLR::Layer::ABSOLUTE_VALUE: +// x = torch::abs( x ); +// activationIndex++; +// break; +// +// case NLR::Layer::MAX: +// { +// std::cout << x.dim() << std::endl; +// std::cout << "dim 1: " << x.size( 0 ) << std::endl; +// std::cout << "dim 2: " << x.size( 1 ) << std::endl; +// int kernel_size = 0; +// // x = customMaxPool( maxLayerIndices[maxPoolNum], x ); +// if ( x.size( 1 ) == 33856 ) +// kernel_size = 2881; +// else if (x.size(1) == 5184) +// kernel_size = 1089; +// else if (x.size( 1 ) == 256) +// kernel_size = 1; +// // Apply the max pooling operation +// torch::nn::MaxPool1d max_pool1d( +// torch::nn::MaxPool1dOptions( kernel_size ).stride( 4 ) ); +// +// x = max_pool1d( x ); +// x = torch::max_pool1d( x, 4, 4); +// std::cout << "end max pool" << x.size( 1 ) << std::endl; +// activationIndex++; +// maxPoolNum++; +// break; +// } +// +// case NLR::Layer::SIGN: +// x = torch::sign( x ); +// activationIndex++; +// break; +// +// case NLR::Layer::ROUND: +// x = torch::round( x ); +// activationIndex++; +// break; +// +// case NLR::Layer::SOFTMAX: +// x = torch::softmax( x, 1 ); +// activationIndex++; +// break; +// +// default: +// std::cerr << "Unsupported activation type: " << activations[i] << std::endl; +// } +// } +// } +// } +// return x; diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index 642c55e9f9..bf41fe73ac 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -7,24 +7,35 @@ #undef Warning #include +class CustomMaxPool : public torch::nn::Module { +public: + CustomMaxPool(const NLR::NetworkLevelReasoner* nlr, unsigned layerIndex); + torch::Tensor forward(torch::Tensor x) const; + +private: + const NLR::NetworkLevelReasoner* networkLevelReasoner; + unsigned maxLayerIndex; +}; + class CustomDNNImpl : public torch::nn::Module { public: - enum Type { - INPUT, - LINEAR, - ACTIVATION, - }; + const NLR::NetworkLevelReasoner* networkLevelReasoner; Vector layerSizes; + Vector reluLayers; + Vector leakyReluLayers; + Vector sigmoidLayers; + Vector> customMaxPoolLayers; Vector activations; Vector>> weights; Vector> biases; Vector linearLayers; - Vector layersOrder; + Vector layersOrder; unsigned numberOfLayers; Vector maxLayerIndices; + void weightedSum( unsigned i, const NLR::Layer *layer ); explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); torch::Tensor customMaxPool(unsigned max_layer_inxes, torch::Tensor x ) const; From 1d192894ec37e46dec9d464cd47dd7ec3f4e2197 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sun, 18 Aug 2024 10:20:25 +0300 Subject: [PATCH 26/69] fix customDNN --- src/engine/CustomDNN.cpp | 215 +++++++++------------------------------ src/engine/CustomDNN.h | 5 + 2 files changed, 53 insertions(+), 167 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 7a3868d7c0..35c5bea6f3 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,8 +1,6 @@ #include "CustomDNN.h" - #include "NetworkLevelReasoner.h" #include "Vector.h" - #include @@ -38,51 +36,60 @@ torch::Tensor CustomMaxPool::forward( torch::Tensor x ) const return maxOutputs; } -void CustomDNNImpl::weightedSum( unsigned i, const NLR::Layer *layer) +void CustomDNNImpl::setWeightsAndBiases(torch::nn::Linear& linearLayer, const NLR::Layer* layer, unsigned sourceLayer, unsigned inputSize, unsigned outputSize) { - unsigned sourceLayer = i - 1; - const NLR::Layer *prevLayer = networkLevelReasoner->getLayer( sourceLayer ); - unsigned inputSize = prevLayer->getSize(); - unsigned outputSize = layer->getSize(); + Vector> layerWeights(outputSize, Vector(inputSize)); + Vector layerBiases(outputSize); - if ( outputSize > 0 ) + // Fetch weights and biases from networkLevelReasoner + for (unsigned j = 0; j < outputSize; j++) { - auto linearLayer = torch::nn::Linear( torch::nn::LinearOptions( inputSize, outputSize ) ); - linearLayers.append( linearLayer ); - register_module( "linear" + std::to_string( i ), linearLayer ); - - Vector> layerWeights( outputSize, Vector( inputSize ) ); - Vector layerBiases( layer->getSize() ); - - // Fetch weights and biases from the networkLevelReasoner - for ( unsigned j = 0; j < outputSize; j++ ) + for (unsigned k = 0; k < inputSize; k++) { - for ( unsigned k = 0; k < inputSize; k++ ) - { - double weight_value = layer->getWeight( sourceLayer, k, j ); - layerWeights[j][k] = static_cast( weight_value ); - } - double bias_value = layer->getBias( j ); - layerBiases[j] = static_cast( bias_value ); + double weight_value = layer->getWeight(sourceLayer, k, j); + layerWeights[j][k] = static_cast(weight_value); } + double bias_value = layer->getBias(j); + layerBiases[j] = static_cast(bias_value); + } - Vector flattenedWeights; - for ( const auto &weight : layerWeights ) + Vector flattenedWeights; + for (const auto& weight : layerWeights) + { + for (const auto& w : weight) { - for ( const auto &w : weight ) - { - flattenedWeights.append( w ); - } + flattenedWeights.append(w); } + } - torch::Tensor weightTensor = torch::tensor( flattenedWeights.getContainer(), torch::kFloat ) - .view( { layer->getSize(), prevLayer->getSize() } ); - torch::Tensor biasTensor = torch::tensor( layerBiases.getContainer(), torch::kFloat ); - torch::NoGradGuard no_grad; - linearLayer->weight.set_( weightTensor ); - linearLayer->bias.set_( biasTensor ); + torch::Tensor weightTensor = torch::tensor(flattenedWeights.getContainer(), torch::kFloat) + .view({outputSize, inputSize}); + torch::Tensor biasTensor = torch::tensor(layerBiases.getContainer(), torch::kFloat); + + torch::NoGradGuard no_grad; + linearLayer->weight.set_(weightTensor); + linearLayer->bias.set_(biasTensor); +} + +void CustomDNNImpl::weightedSum(unsigned i, const NLR::Layer *layer) +{ + unsigned sourceLayer = i - 1; + const NLR::Layer *prevLayer = networkLevelReasoner->getLayer(sourceLayer); + unsigned inputSize = prevLayer->getSize(); + unsigned outputSize = layer->getSize(); + + if (outputSize > 0) + { + auto linearLayer = torch::nn::Linear(torch::nn::LinearOptions(inputSize, outputSize)); + linearLayers.append(linearLayer); + + setWeightsAndBiases(linearLayer, layer, sourceLayer, inputSize, outputSize); + + register_module("linear" + std::to_string(i), linearLayer); } } + + CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) { std::cout << "----- Construct Custom Network -----" << std::endl; @@ -105,21 +112,21 @@ CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) { auto reluLayer = torch::nn::ReLU( torch::nn::ReLUOptions() ); reluLayers.append( reluLayer ); - register_module( "relu" + std::to_string( i ), reluLayer ); + register_module( "ReLU" + std::to_string( i ), reluLayer ); break; } case NLR::Layer::LEAKY_RELU: { auto reluLayer = torch::nn::LeakyReLU( torch::nn::LeakyReLUOptions() ); leakyReluLayers.append( reluLayer ); - register_module( "leaky_relu" + std::to_string( i ), reluLayer ); + register_module( "leakyReLU" + std::to_string( i ), reluLayer ); break; } case NLR::Layer::MAX: { auto customMaxPoolLayer = std::make_shared(networkLevelReasoner, i); customMaxPoolLayers.append(customMaxPoolLayer); - register_module("custom_max_pool" + std::to_string(i), customMaxPoolLayer); + register_module("maxPool" + std::to_string(i), customMaxPoolLayer); break; } case NLR::Layer::SIGMOID: @@ -136,38 +143,6 @@ CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) } } - - -// torch::Tensor CustomDNNImpl::customMaxPool( unsigned maxLayerIndex, torch::Tensor x ) const -// { -// std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; -// fflush( stdout ); -// const NLR::Layer *layer = networkLevelReasoner->getLayer( maxLayerIndex ); -// torch::Tensor maxOutputs = torch::zeros( { 1, layer->getSize() } ); -// -// torch::Tensor maxSource; -// -// for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) -// { -// auto sources = layer->getActivationSources( neuron ); -// maxSource = torch::zeros( sources.size(), torch::kFloat ); -// -// for ( int i = sources.size() - 1; i >= 0; --i ) -// { -// const NLR::NeuronIndex &activationNeuron = sources.back(); -// sources.popBack(); -// int index = static_cast( activationNeuron._neuron ); -// maxSource[i] = x.index( { 0, index } ); -// } -// maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); -// } -// std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; -// fflush( stdout ); -// -// -// return maxOutputs; -// } - torch::Tensor CustomDNNImpl::forward(torch::Tensor x) { unsigned linearIndex = 0; @@ -177,7 +152,7 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) unsigned sigmoidIndex = 0; for (unsigned i = 0; i < numberOfLayers; i++) { - NLR::Layer::Type layerType = layersOrder[i]; + const NLR::Layer::Type layerType = layersOrder[i]; switch (layerType) { case NLR::Layer::INPUT: @@ -203,103 +178,9 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) sigmoidIndex++; break; default: - std::cerr << "Unsupported activation type: " << activations[i] << std::endl; + std::cerr << "Unsupported activation type: " << layerType << std::endl; } } return x; } - - - -// torch::Tensor CustomDNNImpl::forward( torch::Tensor x ) -// { -// unsigned linearIndex = 0; -// unsigned activationIndex = 0; -// unsigned maxPoolNum = 0; -// for ( unsigned i = 0; i < numberOfLayers; i++ ) -// { -// NLR::Layer::Type layerType = layersOrder[i]; -// switch ( layerType ) -// { -// case NLR::Layer::INPUT: -// break; -// case NLR::Layer::WEIGHTED_SUM: -// x = linearLayers[linearIndex]->forward( x ); -// linearIndex++; -// -// break; -// -// case ACTIVATION: -// { -// NLR::Layer::Type activationType = activations[activationIndex]; -// switch ( activationType ) -// { -// case NLR::Layer::RELU: -// x = torch::relu( x ); -// activationIndex++; -// -// break; -// -// case NLR::Layer::LEAKY_RELU: -// x = torch::leaky_relu( x ); -// activationIndex++; -// break; -// -// case NLR::Layer::SIGMOID: -// x = torch::sigmoid( x ); -// activationIndex++; -// break; -// -// case NLR::Layer::ABSOLUTE_VALUE: -// x = torch::abs( x ); -// activationIndex++; -// break; -// -// case NLR::Layer::MAX: -// { -// std::cout << x.dim() << std::endl; -// std::cout << "dim 1: " << x.size( 0 ) << std::endl; -// std::cout << "dim 2: " << x.size( 1 ) << std::endl; -// int kernel_size = 0; -// // x = customMaxPool( maxLayerIndices[maxPoolNum], x ); -// if ( x.size( 1 ) == 33856 ) -// kernel_size = 2881; -// else if (x.size(1) == 5184) -// kernel_size = 1089; -// else if (x.size( 1 ) == 256) -// kernel_size = 1; -// // Apply the max pooling operation -// torch::nn::MaxPool1d max_pool1d( -// torch::nn::MaxPool1dOptions( kernel_size ).stride( 4 ) ); -// -// x = max_pool1d( x ); -// x = torch::max_pool1d( x, 4, 4); -// std::cout << "end max pool" << x.size( 1 ) << std::endl; -// activationIndex++; -// maxPoolNum++; -// break; -// } -// -// case NLR::Layer::SIGN: -// x = torch::sign( x ); -// activationIndex++; -// break; -// -// case NLR::Layer::ROUND: -// x = torch::round( x ); -// activationIndex++; -// break; -// -// case NLR::Layer::SOFTMAX: -// x = torch::softmax( x, 1 ); -// activationIndex++; -// break; -// -// default: -// std::cerr << "Unsupported activation type: " << activations[i] << std::endl; -// } -// } -// } -// } -// return x; diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index bf41fe73ac..cdadf88526 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -35,6 +35,11 @@ class CustomDNNImpl : public torch::nn::Module unsigned numberOfLayers; Vector maxLayerIndices; + static void setWeightsAndBiases( torch::nn::Linear &linearLayer, + const NLR::Layer *layer, + unsigned sourceLayer, + unsigned inputSize, + unsigned outputSize ); void weightedSum( unsigned i, const NLR::Layer *layer ); explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); From 343bbbf58d0c8775ea2f9155816008fb006fcd08 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 10:10:33 +0300 Subject: [PATCH 27/69] exit if attack succeeded --- src/engine/Engine.cpp | 14 +++++++++----- src/engine/IEngine.h | 1 + src/engine/Marabou.cpp | 9 +++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index b3447a9d24..a3858715b2 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1441,10 +1441,10 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) try { informConstraintsOfInitialBounds( inputQuery ); - for (auto& inputVar : inputQuery.getInputVariables()) { - inputQuery.setLowerBound(inputVar, -1.5); - inputQuery.setUpperBound(inputVar, 1.6); - } + // for (auto& inputVar : inputQuery.getInputVariables()) { + // inputQuery.setLowerBound(inputVar, -3); + // inputQuery.setUpperBound(inputVar, 3); + // } invokePreprocessor( inputQuery, preprocess ); if ( _verbosity > 1 ) printInputBounds( inputQuery ); @@ -1452,8 +1452,12 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) if (_networkLevelReasoner) { CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); + std::cout<< network <getInt( Options::TIMEOUT ); + if (_engine->getExitCode() == Engine::ATTACK_SAT) + { + return; + } if ( _engine->processInputQuery( _inputQuery ) ) { _engine->solve( timeoutInSeconds ); @@ -300,6 +304,11 @@ void Marabou::displayResults( unsigned long long microSecondsElapsed ) const printf( "\n" ); } } + else if (result == Engine::ATTACK_SAT) + { + resultString = "sat"; + printf( "sat\n" ); + } else if ( result == Engine::TIMEOUT ) { resultString = "TIMEOUT"; From 61d1cbf16025b313cd1f2189d4e9c08b137d2db9 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 10:24:37 +0300 Subject: [PATCH 28/69] change default restarts --- src/engine/PGD.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index fe9a6f0c59..e894b3a9a8 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -7,7 +7,7 @@ constexpr float LR = 0.05; constexpr unsigned DEFAULT_NUM_ITER = 1000; -constexpr unsigned DEFAULT_NUM_RESTARTS = 20; +constexpr unsigned DEFAULT_NUM_RESTARTS = 4; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; From 53738b68c747ae7d48e32416e214cf0586ec87f6 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 12:46:52 +0300 Subject: [PATCH 29/69] change default restarts and iterations --- src/engine/PGD.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index e894b3a9a8..9decc74022 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -6,7 +6,7 @@ #include constexpr float LR = 0.05; -constexpr unsigned DEFAULT_NUM_ITER = 1000; +constexpr unsigned DEFAULT_NUM_ITER = 100; constexpr unsigned DEFAULT_NUM_RESTARTS = 4; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; From 8b7aeb8f8f89b12185e3044fc67a0bb893406e66 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 12:49:36 +0300 Subject: [PATCH 30/69] remove prints --- src/engine/CustomDNN.cpp | 8 ++++---- src/engine/CustomDNN.h | 1 - 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 35c5bea6f3..472dd8bb13 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -9,8 +9,8 @@ CustomMaxPool::CustomMaxPool(const NLR::NetworkLevelReasoner* nlr, unsigned laye torch::Tensor CustomMaxPool::forward( torch::Tensor x ) const { - std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; - fflush( stdout ); + // std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; + // fflush( stdout ); const NLR::Layer *layer = networkLevelReasoner->getLayer( maxLayerIndex ); torch::Tensor maxOutputs = torch::zeros( { 1, layer->getSize() } ); @@ -30,8 +30,8 @@ torch::Tensor CustomMaxPool::forward( torch::Tensor x ) const maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); } - std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; - fflush( stdout ); + // std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; + // fflush( stdout ); return maxOutputs; } diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index cdadf88526..b604a854fd 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -43,7 +43,6 @@ class CustomDNNImpl : public torch::nn::Module void weightedSum( unsigned i, const NLR::Layer *layer ); explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); - torch::Tensor customMaxPool(unsigned max_layer_inxes, torch::Tensor x ) const; torch::Tensor forward( torch::Tensor x ); }; From def3a1cbfcaba31c372f6bee902d04dc973238b1 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 16:05:33 +0300 Subject: [PATCH 31/69] change default restarts --- src/engine/PGD.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 9decc74022..2e5e260314 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -7,7 +7,7 @@ constexpr float LR = 0.05; constexpr unsigned DEFAULT_NUM_ITER = 100; -constexpr unsigned DEFAULT_NUM_RESTARTS = 4; +constexpr unsigned DEFAULT_NUM_RESTARTS = 3; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; From 0ce47baa6e81ea096aac74bc70c1bfc2c258e8be Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 17:05:51 +0300 Subject: [PATCH 32/69] change default restarts --- src/engine/PGD.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 2e5e260314..ce786b6e86 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -6,7 +6,7 @@ #include constexpr float LR = 0.05; -constexpr unsigned DEFAULT_NUM_ITER = 100; +constexpr unsigned DEFAULT_NUM_ITER = 300; constexpr unsigned DEFAULT_NUM_RESTARTS = 3; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; From 6b17d94be2c22368dc20fa4f58598607506b856a Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 17:29:22 +0300 Subject: [PATCH 33/69] change default restarts --- src/engine/PGD.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index ce786b6e86..42097dc8f0 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -6,8 +6,8 @@ #include constexpr float LR = 0.05; -constexpr unsigned DEFAULT_NUM_ITER = 300; -constexpr unsigned DEFAULT_NUM_RESTARTS = 3; +constexpr unsigned DEFAULT_NUM_ITER = 350; +constexpr unsigned DEFAULT_NUM_RESTARTS = 2; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; From 3b70087c868412596433bfa29ffaa4d0a8eccb6c Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 29 Aug 2024 17:29:57 +0300 Subject: [PATCH 34/69] change default restarts --- src/engine/PGD.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 42097dc8f0..fa25851d6a 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -5,7 +5,6 @@ #undef Warning #include -constexpr float LR = 0.05; constexpr unsigned DEFAULT_NUM_ITER = 350; constexpr unsigned DEFAULT_NUM_RESTARTS = 2; constexpr unsigned INPUT = 0; From 5357411655de3b6eabb90ec3824d57572488d87f Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 31 Aug 2024 12:02:08 +0300 Subject: [PATCH 35/69] change default restarts --- src/engine/PGD.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index fa25851d6a..3abceafb9b 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -5,8 +5,8 @@ #undef Warning #include -constexpr unsigned DEFAULT_NUM_ITER = 350; -constexpr unsigned DEFAULT_NUM_RESTARTS = 2; +constexpr unsigned DEFAULT_NUM_ITER = 150; +constexpr unsigned DEFAULT_NUM_RESTARTS = 4; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; From a8a167d88cf28e5e53eb8f113565b6b4be203088 Mon Sep 17 00:00:00 2001 From: idan0610 Date: Wed, 11 Sep 2024 18:06:08 +0300 Subject: [PATCH 36/69] implementation for backward of maxpool --- src/engine/CustomDNN.cpp | 167 ++++++++++++++++++++++++--------------- src/engine/CustomDNN.h | 11 +++ src/engine/Engine.cpp | 1 + 3 files changed, 115 insertions(+), 64 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 472dd8bb13..bae189dda9 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,91 +1,76 @@ #include "CustomDNN.h" + #include "NetworkLevelReasoner.h" #include "Vector.h" + #include -CustomMaxPool::CustomMaxPool(const NLR::NetworkLevelReasoner* nlr, unsigned layerIndex) - : networkLevelReasoner(nlr), maxLayerIndex(layerIndex) {} +CustomMaxPool::CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) + : networkLevelReasoner( nlr ) + , maxLayerIndex( layerIndex ) +{ +} torch::Tensor CustomMaxPool::forward( torch::Tensor x ) const { - // std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; - // fflush( stdout ); - - const NLR::Layer *layer = networkLevelReasoner->getLayer( maxLayerIndex ); - torch::Tensor maxOutputs = torch::zeros( { 1, layer->getSize() } ); - - for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) - { - auto sources = layer->getActivationSources( neuron ); - torch::Tensor maxSource = torch::zeros( sources.size(), torch::kFloat ); - - for ( int i = sources.size() - 1; i >= 0; --i ) - { - const NLR::NeuronIndex &activationNeuron = sources.back(); - sources.popBack(); - int index = static_cast( activationNeuron._neuron ); - maxSource[i] = x.index( { 0, index } ); - } - maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); - } - - // std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; - // fflush( stdout ); - - return maxOutputs; + return CustomMaxPoolFunction::apply( x, networkLevelReasoner, maxLayerIndex ); } -void CustomDNNImpl::setWeightsAndBiases(torch::nn::Linear& linearLayer, const NLR::Layer* layer, unsigned sourceLayer, unsigned inputSize, unsigned outputSize) +void CustomDNNImpl::setWeightsAndBiases( torch::nn::Linear &linearLayer, + const NLR::Layer *layer, + unsigned sourceLayer, + unsigned inputSize, + unsigned outputSize ) { - Vector> layerWeights(outputSize, Vector(inputSize)); - Vector layerBiases(outputSize); + Vector> layerWeights( outputSize, Vector( inputSize ) ); + Vector layerBiases( outputSize ); // Fetch weights and biases from networkLevelReasoner - for (unsigned j = 0; j < outputSize; j++) + for ( unsigned j = 0; j < outputSize; j++ ) { - for (unsigned k = 0; k < inputSize; k++) + for ( unsigned k = 0; k < inputSize; k++ ) { - double weight_value = layer->getWeight(sourceLayer, k, j); - layerWeights[j][k] = static_cast(weight_value); + double weight_value = layer->getWeight( sourceLayer, k, j ); + layerWeights[j][k] = static_cast( weight_value ); } - double bias_value = layer->getBias(j); - layerBiases[j] = static_cast(bias_value); + double bias_value = layer->getBias( j ); + layerBiases[j] = static_cast( bias_value ); } Vector flattenedWeights; - for (const auto& weight : layerWeights) + for ( const auto &weight : layerWeights ) { - for (const auto& w : weight) + for ( const auto &w : weight ) { - flattenedWeights.append(w); + flattenedWeights.append( w ); } } - torch::Tensor weightTensor = torch::tensor(flattenedWeights.getContainer(), torch::kFloat) - .view({outputSize, inputSize}); - torch::Tensor biasTensor = torch::tensor(layerBiases.getContainer(), torch::kFloat); + torch::Tensor weightTensor = torch::tensor( flattenedWeights.getContainer(), torch::kFloat ) + .view( { outputSize, inputSize } ); + torch::Tensor biasTensor = torch::tensor( layerBiases.getContainer(), torch::kFloat ); torch::NoGradGuard no_grad; - linearLayer->weight.set_(weightTensor); - linearLayer->bias.set_(biasTensor); + linearLayer->weight.set_( weightTensor ); + linearLayer->bias.set_( biasTensor ); } -void CustomDNNImpl::weightedSum(unsigned i, const NLR::Layer *layer) +void CustomDNNImpl::weightedSum( unsigned i, const NLR::Layer *layer ) { unsigned sourceLayer = i - 1; - const NLR::Layer *prevLayer = networkLevelReasoner->getLayer(sourceLayer); + const NLR::Layer *prevLayer = networkLevelReasoner->getLayer( sourceLayer ); unsigned inputSize = prevLayer->getSize(); unsigned outputSize = layer->getSize(); - if (outputSize > 0) + if ( outputSize > 0 ) { - auto linearLayer = torch::nn::Linear(torch::nn::LinearOptions(inputSize, outputSize)); - linearLayers.append(linearLayer); + auto linearLayer = torch::nn::Linear( torch::nn::LinearOptions( inputSize, outputSize ) ); + linearLayers.append( linearLayer ); - setWeightsAndBiases(linearLayer, layer, sourceLayer, inputSize, outputSize); + setWeightsAndBiases( linearLayer, layer, sourceLayer, inputSize, outputSize ); - register_module("linear" + std::to_string(i), linearLayer); + register_module( "linear" + std::to_string( i ), linearLayer ); } } @@ -101,7 +86,7 @@ CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) layerSizes.append( layer->getSize() ); NLR::Layer::Type layerType = layer->getLayerType(); layersOrder.append( layerType ); - switch (layerType) + switch ( layerType ) { case NLR::Layer::INPUT: break; @@ -124,16 +109,16 @@ CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) } case NLR::Layer::MAX: { - auto customMaxPoolLayer = std::make_shared(networkLevelReasoner, i); - customMaxPoolLayers.append(customMaxPoolLayer); - register_module("maxPool" + std::to_string(i), customMaxPoolLayer); + auto customMaxPoolLayer = std::make_shared( networkLevelReasoner, i ); + customMaxPoolLayers.append( customMaxPoolLayer ); + register_module( "maxPool" + std::to_string( i ), customMaxPoolLayer ); break; } case NLR::Layer::SIGMOID: { auto sigmoidLayer = torch::nn::Sigmoid(); - sigmoidLayers.append(sigmoidLayer); - register_module("sigmoid" + std::to_string(i), sigmoidLayer); + sigmoidLayers.append( sigmoidLayer ); + register_module( "sigmoid" + std::to_string( i ), sigmoidLayer ); break; } default: @@ -143,22 +128,22 @@ CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) } } -torch::Tensor CustomDNNImpl::forward(torch::Tensor x) +torch::Tensor CustomDNNImpl::forward( torch::Tensor x ) { unsigned linearIndex = 0; unsigned reluIndex = 0; unsigned maxPoolIndex = 0; unsigned leakyReluIndex = 0; unsigned sigmoidIndex = 0; - for (unsigned i = 0; i < numberOfLayers; i++) + for ( unsigned i = 0; i < numberOfLayers; i++ ) { const NLR::Layer::Type layerType = layersOrder[i]; - switch (layerType) + switch ( layerType ) { case NLR::Layer::INPUT: break; case NLR::Layer::WEIGHTED_SUM: - x = linearLayers[linearIndex]->forward(x); + x = linearLayers[linearIndex]->forward( x ); linearIndex++; break; case NLR::Layer::RELU: @@ -170,17 +155,71 @@ torch::Tensor CustomDNNImpl::forward(torch::Tensor x) maxPoolIndex++; break; case NLR::Layer::LEAKY_RELU: - x = leakyReluLayers[leakyReluIndex]->forward(x); + x = leakyReluLayers[leakyReluIndex]->forward( x ); leakyReluIndex++; break; case NLR::Layer::SIGMOID: - x = sigmoidLayers[sigmoidIndex]->forward(x); + x = sigmoidLayers[sigmoidIndex]->forward( x ); sigmoidIndex++; break; default: std::cerr << "Unsupported activation type: " << layerType << std::endl; - } } return x; } + +torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext *ctx, + torch::Tensor x, + const NLR::NetworkLevelReasoner *nlr, + unsigned int layerIndex ) +{ + // std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; + // fflush( stdout ); + ctx->save_for_backward( { x } ); + + const NLR::Layer *layer = nlr->getLayer( layerIndex ); + torch::Tensor maxOutputs = torch::zeros( { 1, layer->getSize() } ); + torch::Tensor argMaxOutputs = torch::zeros( { 1, layer->getSize() }, torch::kInt64 ); + + for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) + { + auto sources = layer->getActivationSources( neuron ); + torch::Tensor maxSource = torch::zeros( sources.size(), torch::kFloat ); + torch::Tensor sourceIndices = torch::zeros( sources.size() ); + + for ( int i = sources.size() - 1; i >= 0; --i ) + { + const NLR::NeuronIndex &activationNeuron = sources.back(); + sources.popBack(); + int index = static_cast( activationNeuron._neuron ); + maxSource[i] = x.index( { 0, index } ); + sourceIndices[i] = index; + } + maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); + argMaxOutputs.index_put_( { 0, static_cast( neuron ) }, + sourceIndices[torch::argmax( maxSource )] ); + } + + // std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; + // fflush( stdout ); + + ctx->saved_data["argMaxOutputs"] = argMaxOutputs; + + return maxOutputs; +} + +std::vector CustomMaxPoolFunction::backward( torch::autograd::AutogradContext *ctx, + std::vector grad_output ) +{ + auto saved = ctx->get_saved_variables(); + auto input = saved[0]; + + auto grad_input = torch::zeros_like( input ); + + auto indices = ctx->saved_data["argMaxOutputs"].toTensor(); + + grad_input.index_add_( 1, indices.flatten(), grad_output[0] ); + + return { grad_input, torch::Tensor(), torch::Tensor() }; +} diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index b604a854fd..ad81c26bca 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -7,6 +7,17 @@ #undef Warning #include +class CustomMaxPoolFunction : public torch::autograd::Function { +public: + static torch::Tensor forward(torch::autograd::AutogradContext *ctx, + torch::Tensor x, + const NLR::NetworkLevelReasoner *nlr, + unsigned layerIndex); + + static std::vector backward(torch::autograd::AutogradContext *ctx, std::vector + grad_output); +}; + class CustomMaxPool : public torch::nn::Module { public: CustomMaxPool(const NLR::NetworkLevelReasoner* nlr, unsigned layerIndex); diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index a3858715b2..6bc8569818 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1457,6 +1457,7 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) if( pgd_attack.displayAdversarialExample() ) { _exitCode = Engine::ATTACK_SAT; + return false; } } From 8977cc9fa441a5786d847f7618474cbd004361c0 Mon Sep 17 00:00:00 2001 From: idan0610 Date: Sun, 15 Sep 2024 10:02:21 +0300 Subject: [PATCH 37/69] bug fix in CustomMaxPool backward + extract solution from PGD attack if success (buggy) --- .vscode/c_cpp_properties.json | 17 --------- src/engine/CustomDNN.cpp | 21 ++++------- src/engine/CustomDNN.h | 6 ++-- src/engine/Engine.cpp | 23 +++++++----- src/engine/Engine.h | 5 +++ src/engine/PGD.cpp | 37 ++++++++++--------- src/engine/PGD.h | 61 +++++++++++++++----------------- src/nlr/NetworkLevelReasoner.cpp | 13 +++++-- 8 files changed, 87 insertions(+), 96 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index a0aa6ead37..0000000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c17", - "cppStandard": "gnu++17", - "intelliSenseMode": "linux-gcc-x64", - "configurationProvider": "ms-vscode.cmake-tools" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index bae189dda9..566748b1fc 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,9 +1,6 @@ #include "CustomDNN.h" - -#include "NetworkLevelReasoner.h" #include "Vector.h" - -#include +#include "TimeUtils.h" CustomMaxPool::CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) @@ -174,8 +171,6 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * const NLR::NetworkLevelReasoner *nlr, unsigned int layerIndex ) { - // std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; - // fflush( stdout ); ctx->save_for_backward( { x } ); const NLR::Layer *layer = nlr->getLayer( layerIndex ); @@ -185,7 +180,7 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) { auto sources = layer->getActivationSources( neuron ); - torch::Tensor maxSource = torch::zeros( sources.size(), torch::kFloat ); + torch::Tensor sourceValues = torch::zeros( sources.size(), torch::kFloat ); torch::Tensor sourceIndices = torch::zeros( sources.size() ); for ( int i = sources.size() - 1; i >= 0; --i ) @@ -193,17 +188,15 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * const NLR::NeuronIndex &activationNeuron = sources.back(); sources.popBack(); int index = static_cast( activationNeuron._neuron ); - maxSource[i] = x.index( { 0, index } ); + sourceValues[i] = x.index( { 0, index } ); sourceIndices[i] = index; } - maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); + + maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( sourceValues ) ); argMaxOutputs.index_put_( { 0, static_cast( neuron ) }, - sourceIndices[torch::argmax( maxSource )] ); + sourceIndices[torch::argmax( sourceValues )] ); } - // std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; - // fflush( stdout ); - ctx->saved_data["argMaxOutputs"] = argMaxOutputs; return maxOutputs; @@ -219,7 +212,7 @@ std::vector CustomMaxPoolFunction::backward( torch::autograd::Aut auto indices = ctx->saved_data["argMaxOutputs"].toTensor(); - grad_input.index_add_( 1, indices.flatten(), grad_output[0] ); + grad_input[0].index_add_( 0, indices.flatten(), grad_output[0].flatten() ); return { grad_input, torch::Tensor(), torch::Tensor() }; } diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index ad81c26bca..03f66e58b6 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -1,5 +1,5 @@ -#ifndef CUSTOM_DNN_H -#define CUSTOM_DNN_H +#ifndef __CustomDNN_h__ +#define __CustomDNN_h__ #include "NetworkLevelReasoner.h" #include @@ -58,4 +58,4 @@ class CustomDNNImpl : public torch::nn::Module }; -#endif \ No newline at end of file +#endif // __CustomDNN_h__ \ No newline at end of file diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 6bc8569818..43857088fa 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1433,7 +1433,7 @@ void Engine::initializeNetworkLevelReasoning() } } -bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) +bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) { ENGINE_LOG( "processInputQuery starting\n" ); struct timespec start = TimeUtils::sampleMicro(); @@ -1449,14 +1449,13 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - if (_networkLevelReasoner) + if ( _networkLevelReasoner ) { - CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); - std::cout<< network <displayAdversarialExample() ) { - _exitCode = Engine::ATTACK_SAT; + _exitCode = Engine::SAT; + _isAttackSuccessful = true; return false; } } @@ -1776,11 +1775,17 @@ void Engine::extractSolution( InputQuery &inputQuery, Preprocessor *preprocessor variable = preprocessorInUse->getNewIndex( variable ); // Finally, set the assigned value - inputQuery.setSolutionValue( i, _tableau->getValue( variable ) ); + if ( _isAttackSuccessful ) + inputQuery.setSolutionValue( i, _pgdAttack->getAssignments( variable ) ); + else + inputQuery.setSolutionValue( i, _tableau->getValue( variable ) ); } else { - inputQuery.setSolutionValue( i, _tableau->getValue( i ) ); + if ( _isAttackSuccessful ) + inputQuery.setSolutionValue( i, _pgdAttack->getAssignments( i ) ); + else + inputQuery.setSolutionValue( i, _tableau->getValue( i ) ); } } diff --git a/src/engine/Engine.h b/src/engine/Engine.h index a3bf2cfdc9..44dde596c3 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -36,6 +36,7 @@ #include "MILPEncoder.h" #include "Map.h" #include "Options.h" +#include "PGD.h" #include "PrecisionRestorer.h" #include "Preprocessor.h" #include "SignalHandler.h" @@ -48,6 +49,7 @@ #include "SymbolicBoundTighteningType.h" #include "UnsatCertificateNode.h" + #include #include @@ -536,6 +538,9 @@ class Engine LinearExpression _heuristicCost; + PGDAttack *_pgdAttack; + bool _isAttackSuccessful = false; + /* Perform a simplex step: compute the cost function, pick the entering and leaving variables and perform a pivot. diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 5a9d37726c..b6dd9d176d 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,10 +1,11 @@ #include "PGD.h" -#include +#include "InputQuery.h" + #include -PGDAttack::PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner) - : model(model), networkLevelReasoner( networkLevelReasoner ), device(torch::kCPU), - iters(DEFAULT_NUM_ITER), restarts(DEFAULT_NUM_RESTARTS) { +PGDAttack::PGDAttack( NLR::NetworkLevelReasoner* networkLevelReasoner) + : networkLevelReasoner( networkLevelReasoner ), device(torch::kCPU), + model(CustomDNNImpl( networkLevelReasoner )), iters(DEFAULT_NUM_ITER), restarts(DEFAULT_NUM_RESTARTS) { inputSize = model.layerSizes.first(); _getBounds(inputBounds, INPUT); _getBounds(outputBounds, OUTPUT); @@ -13,18 +14,6 @@ PGDAttack::PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* netw epsilon = variables.second; } -PGDAttack::PGDAttack(CustomDNNImpl &model, - const NLR::NetworkLevelReasoner* networkLevelReasoner, unsigned num_iter, - unsigned num_restarts, torch::Device device) - : model(model), networkLevelReasoner( networkLevelReasoner ), device(device), - iters(num_iter), restarts(num_restarts) { - inputSize = model.layerSizes.first(); - _getBounds(inputBounds, INPUT); - _getBounds(outputBounds, OUTPUT); - std::pair variables = _generateSampleAndEpsilon(); - InputExample = variables.first; - epsilon = variables.second; -} torch::Device PGDAttack::_getDevice() { if (torch::cuda::is_available()) { @@ -131,6 +120,7 @@ std::pair PGDAttack::_findAdvExample() { torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions()); for (unsigned j = 0; j < iters; ++j) { + std::cout << "restart " << i << "; iter " << j << std::endl; currentExample = InputExample + delta; currentPrediction = model.forward(currentExample); torch::Tensor loss = _calculateLoss(currentPrediction); @@ -153,6 +143,13 @@ std::pair PGDAttack::_findAdvExample() { return {currentExample, currentPrediction};; } + +double PGDAttack::getAssignments( int index ) +{ + return assignments[index]; +} + + bool PGDAttack::displayAdversarialExample() { std::cout << "-----Starting PGD attack-----" << std::endl; auto adversarial = _findAdvExample(); @@ -165,19 +162,21 @@ bool PGDAttack::displayAdversarialExample() { std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer()<< "\n"; std::cout << "Input Upper Bounds : " << inputBounds.second.getContainer() << "\n"; std::cout << "Adversarial Input: \n"; - auto* example = advInput.data_ptr(); + auto* example = advInput.data_ptr(); for (int i = 0; i < advInput.numel(); ++i) { std::cout << "x" << i << " = "<< example[i] << "\n"; } std::cout << "Output Lower Bounds : " << outputBounds.first.getContainer() << "\n"; std::cout << "Output Upper Bounds : " << outputBounds.second.getContainer() << "\n"; std::cout << "Adversarial Prediction: \n"; - auto* prediction = advPred.data_ptr(); + auto* prediction = advPred.data_ptr(); for (int i = 0; i < advPred.numel(); ++i) { std::cout << "y" << i << " = "<< prediction[i] << "\n"; } std::cout << "Model fooled: " << (isFooled ? "Yes \n ------ PGD Attack Succeed ------" : "No \n ------ PGD Attack Failed ------") << "\n\n"; + networkLevelReasoner->concretizeInputAssignment( assignments ); + return isFooled; -} +} \ No newline at end of file diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 3abceafb9b..e951b26211 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -1,49 +1,46 @@ -#ifndef PGD_H -#define PGD_H +#ifndef __PGD_h__ +#define __PGD_h__ #include "CustomDNN.h" + #undef Warning #include -constexpr unsigned DEFAULT_NUM_ITER = 150; +constexpr unsigned DEFAULT_NUM_ITER = 50; constexpr unsigned DEFAULT_NUM_RESTARTS = 4; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; -class PGDAttack { +class PGDAttack +{ public: - PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner); - PGDAttack( CustomDNNImpl &model, - const NLR::NetworkLevelReasoner* networkLevelReasoner, - unsigned num_iter, - unsigned num_restarts, - torch::Device device); + PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ); + bool displayAdversarialExample(); + double getAssignments( int index ); - bool displayAdversarialExample(); private: - CustomDNNImpl &model; - const NLR::NetworkLevelReasoner* networkLevelReasoner; - torch::Device device; - torch::Tensor epsilon; - torch::Tensor InputExample; - unsigned iters; - unsigned restarts; - unsigned inputSize; - std::pair, Vector> inputBounds; - std::pair, Vector> outputBounds; - - std::pair _findAdvExample(); - std::pair _generateSampleAndEpsilon(); - static bool _isWithinBounds(const torch::Tensor& sample, - const std::pair, Vector> &bounds); - void _getBounds(std::pair, Vector> &bounds, signed type ) const; - torch::Tensor _calculateLoss( const torch::Tensor &predictions ); - static torch::Device _getDevice(); - + NLR::NetworkLevelReasoner *networkLevelReasoner; + torch::Device device; + torch::Tensor epsilon; + torch::Tensor InputExample; + CustomDNNImpl model; + unsigned iters; + unsigned restarts; + unsigned inputSize; + std::pair, Vector> inputBounds; + std::pair, Vector> outputBounds; + Map assignments; + + std::pair _findAdvExample(); + std::pair _generateSampleAndEpsilon(); + static bool _isWithinBounds( const torch::Tensor &sample, + const std::pair, Vector> &bounds ); + void _getBounds( std::pair, Vector> &bounds, signed type ) const; + torch::Tensor _calculateLoss( const torch::Tensor &predictions ); + static torch::Device _getDevice(); }; - -#endif // PGD_H +#endif // __PGD_h__ diff --git a/src/nlr/NetworkLevelReasoner.cpp b/src/nlr/NetworkLevelReasoner.cpp index badb0bbc3d..402e569bb5 100644 --- a/src/nlr/NetworkLevelReasoner.cpp +++ b/src/nlr/NetworkLevelReasoner.cpp @@ -34,7 +34,8 @@ #include -#define NLR_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::NETWORK_LEVEL_REASONER_LOGGING, "NLR: %s\n", x ) +#define NLR_LOG( x, ... ) \ + MARABOU_LOG( GlobalConfiguration::NETWORK_LEVEL_REASONER_LOGGING, "NLR: %s\n", x ) namespace NLR { @@ -144,7 +145,15 @@ void NetworkLevelReasoner::concretizeInputAssignment( Map &ass if ( !inputLayer->neuronEliminated( index ) ) { unsigned variable = inputLayer->neuronToVariable( index ); - double value = _tableau->getValue( variable ); + double value; +// if ( pgd != nullptr ) +// { +// value = pgd->getAssignment( index ); +// } +// else +// { + value = _tableau->getValue( variable ); +// } input[index] = value; assignment[variable] = value; } From d5b708c14da1c46eb7264b4866b7fd722d5f034b Mon Sep 17 00:00:00 2001 From: idan0610 Date: Sun, 15 Sep 2024 13:13:12 +0300 Subject: [PATCH 38/69] Possible fix for building bug --- src/engine/CustomDNN.cpp | 19 +-- src/engine/CustomDNN.h | 6 +- src/engine/Engine.cpp | 26 ++-- src/engine/Engine.h | 4 + src/engine/PGD.cpp | 241 +++++++++++++++++++------------ src/engine/PGD.h | 63 ++++---- src/nlr/NetworkLevelReasoner.cpp | 10 +- src/nlr/NetworkLevelReasoner.h | 3 +- 8 files changed, 216 insertions(+), 156 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index bae189dda9..bb6230b574 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -2,8 +2,7 @@ #include "NetworkLevelReasoner.h" #include "Vector.h" - -#include +#include "TimeUtils.h" CustomMaxPool::CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) @@ -174,8 +173,6 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * const NLR::NetworkLevelReasoner *nlr, unsigned int layerIndex ) { - // std::cout << "start time: " << TimeUtils::now().ascii() << std::endl; - // fflush( stdout ); ctx->save_for_backward( { x } ); const NLR::Layer *layer = nlr->getLayer( layerIndex ); @@ -185,7 +182,7 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) { auto sources = layer->getActivationSources( neuron ); - torch::Tensor maxSource = torch::zeros( sources.size(), torch::kFloat ); + torch::Tensor sourceValues = torch::zeros( sources.size(), torch::kFloat ); torch::Tensor sourceIndices = torch::zeros( sources.size() ); for ( int i = sources.size() - 1; i >= 0; --i ) @@ -193,17 +190,15 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * const NLR::NeuronIndex &activationNeuron = sources.back(); sources.popBack(); int index = static_cast( activationNeuron._neuron ); - maxSource[i] = x.index( { 0, index } ); + sourceValues[i] = x.index( { 0, index } ); sourceIndices[i] = index; } - maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( maxSource ) ); + + maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( sourceValues ) ); argMaxOutputs.index_put_( { 0, static_cast( neuron ) }, - sourceIndices[torch::argmax( maxSource )] ); + sourceIndices[torch::argmax( sourceValues )] ); } - // std::cout << "end time: " << TimeUtils::now().ascii() << std::endl; - // fflush( stdout ); - ctx->saved_data["argMaxOutputs"] = argMaxOutputs; return maxOutputs; @@ -219,7 +214,7 @@ std::vector CustomMaxPoolFunction::backward( torch::autograd::Aut auto indices = ctx->saved_data["argMaxOutputs"].toTensor(); - grad_input.index_add_( 1, indices.flatten(), grad_output[0] ); + grad_input[0].index_add_( 0, indices.flatten(), grad_output[0].flatten() ); return { grad_input, torch::Tensor(), torch::Tensor() }; } diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index ad81c26bca..03f66e58b6 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -1,5 +1,5 @@ -#ifndef CUSTOM_DNN_H -#define CUSTOM_DNN_H +#ifndef __CustomDNN_h__ +#define __CustomDNN_h__ #include "NetworkLevelReasoner.h" #include @@ -58,4 +58,4 @@ class CustomDNNImpl : public torch::nn::Module }; -#endif \ No newline at end of file +#endif // __CustomDNN_h__ \ No newline at end of file diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 6bc8569818..828afbcfff 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -26,14 +26,13 @@ #include "MalformedBasisException.h" #include "MarabouError.h" #include "NLRError.h" +#include "PGD.h" #include "PiecewiseLinearConstraint.h" #include "Preprocessor.h" #include "TableauRow.h" #include "TimeUtils.h" #include "VariableOutOfBoundDuringOptimizationException.h" #include "Vector.h" -#include "CustomDNN.h" -#include "PGD.h" #include @@ -1433,7 +1432,7 @@ void Engine::initializeNetworkLevelReasoning() } } -bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) +bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) { ENGINE_LOG( "processInputQuery starting\n" ); struct timespec start = TimeUtils::sampleMicro(); @@ -1449,14 +1448,13 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess) if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - if (_networkLevelReasoner) + if ( _networkLevelReasoner ) { - CustomDNNImpl network = CustomDNNImpl(_networkLevelReasoner); - std::cout<< network <displayAdversarialExample() ) { - _exitCode = Engine::ATTACK_SAT; + _exitCode = Engine::SAT; + _isAttackSuccessful = true; return false; } } @@ -1776,11 +1774,17 @@ void Engine::extractSolution( InputQuery &inputQuery, Preprocessor *preprocessor variable = preprocessorInUse->getNewIndex( variable ); // Finally, set the assigned value - inputQuery.setSolutionValue( i, _tableau->getValue( variable ) ); + if ( _isAttackSuccessful ) + inputQuery.setSolutionValue( i, _pgdAttack->getAssignment( variable ) ); + else + inputQuery.setSolutionValue( i, _tableau->getValue( variable ) ); } else { - inputQuery.setSolutionValue( i, _tableau->getValue( i ) ); + if ( _isAttackSuccessful ) + inputQuery.setSolutionValue( i, _pgdAttack->getAssignment( i ) ); + else + inputQuery.setSolutionValue( i, _tableau->getValue( i ) ); } } diff --git a/src/engine/Engine.h b/src/engine/Engine.h index a3bf2cfdc9..19a5f8ea7f 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -51,6 +51,7 @@ #include #include +class PGDAttack; #ifdef _WIN32 #undef ERROR @@ -536,6 +537,9 @@ class Engine LinearExpression _heuristicCost; + PGDAttack *_pgdAttack; + bool _isAttackSuccessful = false; + /* Perform a simplex step: compute the cost function, pick the entering and leaving variables and perform a pivot. diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 5a9d37726c..dd6ea9a10d 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,106 +1,126 @@ #include "PGD.h" -#include -#include +#include "InputQuery.h" -PGDAttack::PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner) - : model(model), networkLevelReasoner( networkLevelReasoner ), device(torch::kCPU), - iters(DEFAULT_NUM_ITER), restarts(DEFAULT_NUM_RESTARTS) { - inputSize = model.layerSizes.first(); - _getBounds(inputBounds, INPUT); - _getBounds(outputBounds, OUTPUT); - std::pair variables = _generateSampleAndEpsilon(); - InputExample = variables.first; - epsilon = variables.second; -} +#include -PGDAttack::PGDAttack(CustomDNNImpl &model, - const NLR::NetworkLevelReasoner* networkLevelReasoner, unsigned num_iter, - unsigned num_restarts, torch::Device device) - : model(model), networkLevelReasoner( networkLevelReasoner ), device(device), - iters(num_iter), restarts(num_restarts) { +PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) + : networkLevelReasoner( networkLevelReasoner ) + , device( torch::kCPU ) + , model( CustomDNNImpl( networkLevelReasoner ) ) + , iters( DEFAULT_NUM_ITER ) + , restarts( DEFAULT_NUM_RESTARTS ) + , _adversarialInput( nullptr ) + , _adversarialOutput( nullptr ) +{ inputSize = model.layerSizes.first(); - _getBounds(inputBounds, INPUT); - _getBounds(outputBounds, OUTPUT); + _getBounds( inputBounds, INPUT ); + _getBounds( outputBounds, OUTPUT ); std::pair variables = _generateSampleAndEpsilon(); InputExample = variables.first; epsilon = variables.second; } -torch::Device PGDAttack::_getDevice() { - if (torch::cuda::is_available()) { +torch::Device PGDAttack::_getDevice() +{ + if ( torch::cuda::is_available() ) + { std::cout << "CUDA is available. Using GPU." << std::endl; - return {torch::kCUDA}; - } else { + return { torch::kCUDA }; + } + else + { std::cout << "CUDA is not available. Using CPU." << std::endl; - return {torch::kCPU}; + return { torch::kCPU }; } } -void PGDAttack::_getBounds(std::pair, Vector> &bounds, +void PGDAttack::_getBounds( std::pair, Vector> &bounds, const signed type ) const { - unsigned layerIndex = type == INPUT ? 0 : networkLevelReasoner->getNumberOfLayers() -1; + unsigned layerIndex = type == INPUT ? 0 : networkLevelReasoner->getNumberOfLayers() - 1; const NLR::Layer *layer = networkLevelReasoner->getLayer( layerIndex ); - for (unsigned neuron = 0 ; neuron < layer->getSize(); ++neuron) { - bounds.first.append( layer->getLb(neuron) ); - bounds.second.append( layer->getUb(neuron) ); + for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) + { + bounds.first.append( layer->getLb( neuron ) ); + bounds.second.append( layer->getUb( neuron ) ); } } -std::pair PGDAttack::_generateSampleAndEpsilon() { - Vector sample(inputSize, 0.0f); - Vector epsilons(inputSize, 0.0f); +std::pair PGDAttack::_generateSampleAndEpsilon() +{ + Vector sample( inputSize, 0.0f ); + Vector epsilons( inputSize, 0.0f ); - for (unsigned i = 0; i < inputSize; i++) { - double lower = inputBounds.first.get(i); - double upper = inputBounds.second.get(i); + for ( unsigned i = 0; i < inputSize; i++ ) + { + double lower = inputBounds.first.get( i ); + double upper = inputBounds.second.get( i ); - if (std::isinf(lower) && std::isinf(upper)) { + if ( std::isinf( lower ) && std::isinf( upper ) ) + { sample[i] = 0.0f; epsilons[i] = std::numeric_limits::infinity(); - } else if (std::isinf(lower)) { + } + else if ( std::isinf( lower ) ) + { sample[i] = upper - RANGE; epsilons[i] = RANGE; - } else if (std::isinf(upper)) { + } + else if ( std::isinf( upper ) ) + { sample[i] = lower + RANGE; epsilons[i] = RANGE; - } else { + } + else + { // Both bounds are finite - sample[i] = lower + (upper - lower) / 2.0f; - epsilons[i] = (upper - lower) / 2.0f; + sample[i] = lower + ( upper - lower ) / 2.0f; + epsilons[i] = ( upper - lower ) / 2.0f; } } - return {torch::tensor(sample.getContainer()).unsqueeze(0).to(device), - torch::tensor(epsilons.getContainer()).to(device)}; + return { torch::tensor( sample.getContainer() ).unsqueeze( 0 ).to( device ), + torch::tensor( epsilons.getContainer() ).to( device ) }; } -bool PGDAttack::_isWithinBounds(const torch::Tensor& sample, - const std::pair, Vector> &bounds) { - - torch::Tensor flatInput = sample.view({-1}); - if (flatInput.numel() != bounds.first.size() || flatInput.numel() != bounds.second.size()) { - throw std::runtime_error("Mismatch in sizes of input and bounds"); +bool PGDAttack::_isWithinBounds( const torch::Tensor &sample, + const std::pair, Vector> &bounds ) +{ + torch::Tensor flatInput = sample.view( { -1 } ); + if ( flatInput.numel() != bounds.first.size() || flatInput.numel() != bounds.second.size() ) + { + throw std::runtime_error( "Mismatch in sizes of input and bounds" ); } - for (int64_t i = 0; i < flatInput.size(0); i++) { + for ( int64_t i = 0; i < flatInput.size( 0 ); i++ ) + { auto value = flatInput[i].item(); - double lower = bounds.first.get(i); - double upper = bounds.second.get(i); + double lower = bounds.first.get( i ); + double upper = bounds.second.get( i ); - if (std::isinf(lower) && std::isinf(upper)) { + if ( std::isinf( lower ) && std::isinf( upper ) ) + { // If both bounds are infinite, any value is acceptable continue; - } else if (std::isinf(lower)) { + } + else if ( std::isinf( lower ) ) + { // Only check upper bound - if (value > upper) return false; - } else if (std::isinf(upper)) { + if ( value > upper ) + return false; + } + else if ( std::isinf( upper ) ) + { // Only check lower bound - if (value < lower) return false; - } else { + if ( value < lower ) + return false; + } + else + { // Check both bounds - if (value < lower || value > upper) return false; + if ( value < lower || value > upper ) + return false; } } @@ -108,76 +128,107 @@ bool PGDAttack::_isWithinBounds(const torch::Tensor& sample, } -torch::Tensor PGDAttack::_calculateLoss(const torch::Tensor& predictions) { - torch::Tensor lowerBoundTensor = torch::tensor(outputBounds.first.data(), torch::kFloat32).to(device); - torch::Tensor upperBoundTensor = torch::tensor(outputBounds.second.data(), torch::kFloat32).to(device); +torch::Tensor PGDAttack::_calculateLoss( const torch::Tensor &predictions ) +{ + torch::Tensor lowerBoundTensor = + torch::tensor( outputBounds.first.data(), torch::kFloat32 ).to( device ); + torch::Tensor upperBoundTensor = + torch::tensor( outputBounds.second.data(), torch::kFloat32 ).to( device ); // Compute the penalty: We want high loss if predictions are outside the bounds - torch::Tensor ubViolation = torch::sum(torch::square( - torch::relu(predictions - upperBoundTensor ))).to(device); - torch::Tensor lbViolation = torch::sum(torch::square( - torch::relu(lowerBoundTensor - predictions) )).to(device); - return torch::sum(ubViolation + lbViolation).to(device); + torch::Tensor ubViolation = + torch::sum( torch::square( torch::relu( predictions - upperBoundTensor ) ) ).to( device ); + torch::Tensor lbViolation = + torch::sum( torch::square( torch::relu( lowerBoundTensor - predictions ) ) ).to( device ); + return torch::sum( ubViolation + lbViolation ).to( device ); } -std::pair PGDAttack::_findAdvExample() { +std::pair PGDAttack::_findAdvExample() +{ torch::Tensor currentExample; torch::Tensor currentPrediction; - for (unsigned i = 0; i < restarts; ++i) { - torch::Tensor delta = torch::rand(inputSize).mul(epsilon).to(device); - delta.set_requires_grad(true); - torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions()); + for ( unsigned i = 0; i < restarts; ++i ) + { + torch::Tensor delta = torch::rand( inputSize ).mul( epsilon ).to( device ); + delta.set_requires_grad( true ); + torch::optim::Adam optimizer( { delta }, torch::optim::AdamOptions() ); - for (unsigned j = 0; j < iters; ++j) { + for ( unsigned j = 0; j < iters; ++j ) + { currentExample = InputExample + delta; - currentPrediction = model.forward(currentExample); - torch::Tensor loss = _calculateLoss(currentPrediction); + currentPrediction = model.forward( currentExample ); + torch::Tensor loss = _calculateLoss( currentPrediction ); optimizer.zero_grad(); loss.backward(); optimizer.step(); - delta.data() = delta.data().clamp(-epsilon, epsilon); + delta.data() = delta.data().clamp( -epsilon, epsilon ); } currentExample = InputExample + delta; - currentPrediction = model.forward(currentExample); - torch::Tensor currentLoss = _calculateLoss(currentPrediction); - if (_isWithinBounds( currentPrediction, outputBounds )) + currentPrediction = model.forward( currentExample ); + torch::Tensor currentLoss = _calculateLoss( currentPrediction ); + if ( _isWithinBounds( currentPrediction, outputBounds ) ) { - return {currentExample, currentPrediction}; + return { currentExample, currentPrediction }; } - } - return {currentExample, currentPrediction};; + return { currentExample, currentPrediction }; + ; } -bool PGDAttack::displayAdversarialExample() { +double PGDAttack::getAssignment( int index ) +{ + return assignments[index]; +} + +bool PGDAttack::displayAdversarialExample() +{ std::cout << "-----Starting PGD attack-----" << std::endl; auto adversarial = _findAdvExample(); torch::Tensor advInput = adversarial.first; - auto advPred = adversarial.second; + torch::Tensor advPred = adversarial.second; - bool isFooled = _isWithinBounds( advInput, inputBounds ) && - _isWithinBounds( advPred, outputBounds ); + bool isFooled = + _isWithinBounds( advInput, inputBounds ) && _isWithinBounds( advPred, outputBounds ); - std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer()<< "\n"; + auto *example = advInput.data_ptr(); + auto *prediction = advPred.data_ptr(); + size_t outputSize = advPred.size( 1 ); + ASSERT( advInput.size( 1 ) == inputSize && outputSize == model.layerSizes.last() ); + + if ( isFooled ) + { + _adversarialInput = new double[advInput.size( 1 )]; + _adversarialOutput = new double[advPred.size( 1 )]; + + std::copy( example, example + inputSize, _adversarialInput ); + std::copy( prediction, prediction + outputSize, _adversarialOutput ); + } + + std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer() << "\n"; std::cout << "Input Upper Bounds : " << inputBounds.second.getContainer() << "\n"; std::cout << "Adversarial Input: \n"; - auto* example = advInput.data_ptr(); - for (int i = 0; i < advInput.numel(); ++i) { - std::cout << "x" << i << " = "<< example[i] << "\n"; + for ( int i = 0; i < advInput.numel(); ++i ) + { + std::cout << "x" << i << " = " << example[i] << "\n"; } std::cout << "Output Lower Bounds : " << outputBounds.first.getContainer() << "\n"; std::cout << "Output Upper Bounds : " << outputBounds.second.getContainer() << "\n"; std::cout << "Adversarial Prediction: \n"; - auto* prediction = advPred.data_ptr(); - for (int i = 0; i < advPred.numel(); ++i) { - std::cout << "y" << i << " = "<< prediction[i] << "\n"; + for ( int i = 0; i < advPred.numel(); ++i ) + { + std::cout << "y" << i << " = " << prediction[i] << "\n"; } - std::cout << "Model fooled: " << (isFooled ? "Yes \n ------ PGD Attack Succeed ------" : - "No \n ------ PGD Attack Failed ------") << "\n\n"; + std::cout << "Model fooled: " + << ( isFooled ? "Yes \n ------ PGD Attack Succeed ------" + : "No \n ------ PGD Attack Failed ------" ) + << "\n\n"; + + if ( _adversarialInput ) + networkLevelReasoner->concretizeInputAssignment( assignments, _adversarialInput ); return isFooled; } diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 3abceafb9b..2e519c951f 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -1,49 +1,48 @@ -#ifndef PGD_H -#define PGD_H +#ifndef __PGD_h__ +#define __PGD_h__ #include "CustomDNN.h" + #undef Warning #include -constexpr unsigned DEFAULT_NUM_ITER = 150; +constexpr unsigned DEFAULT_NUM_ITER = 50; constexpr unsigned DEFAULT_NUM_RESTARTS = 4; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; -class PGDAttack { +class PGDAttack +{ public: - PGDAttack(CustomDNNImpl &model, const NLR::NetworkLevelReasoner* networkLevelReasoner); - PGDAttack( CustomDNNImpl &model, - const NLR::NetworkLevelReasoner* networkLevelReasoner, - unsigned num_iter, - unsigned num_restarts, - torch::Device device); + PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ); + bool displayAdversarialExample(); + double getAssignment( int index ); - bool displayAdversarialExample(); private: - CustomDNNImpl &model; - const NLR::NetworkLevelReasoner* networkLevelReasoner; - torch::Device device; - torch::Tensor epsilon; - torch::Tensor InputExample; - unsigned iters; - unsigned restarts; - unsigned inputSize; - std::pair, Vector> inputBounds; - std::pair, Vector> outputBounds; - - std::pair _findAdvExample(); - std::pair _generateSampleAndEpsilon(); - static bool _isWithinBounds(const torch::Tensor& sample, - const std::pair, Vector> &bounds); - void _getBounds(std::pair, Vector> &bounds, signed type ) const; - torch::Tensor _calculateLoss( const torch::Tensor &predictions ); - static torch::Device _getDevice(); - + NLR::NetworkLevelReasoner *networkLevelReasoner; + torch::Device device; + torch::Tensor epsilon; + torch::Tensor InputExample; + CustomDNNImpl model; + unsigned iters; + unsigned restarts; + unsigned inputSize; + std::pair, Vector> inputBounds; + std::pair, Vector> outputBounds; + Map assignments; + double *_adversarialInput; + double *_adversarialOutput; + + std::pair _findAdvExample(); + std::pair _generateSampleAndEpsilon(); + static bool _isWithinBounds( const torch::Tensor &sample, + const std::pair, Vector> &bounds ); + void _getBounds( std::pair, Vector> &bounds, signed type ) const; + torch::Tensor _calculateLoss( const torch::Tensor &predictions ); + static torch::Device _getDevice(); }; - -#endif // PGD_H +#endif // __PGD_h__ diff --git a/src/nlr/NetworkLevelReasoner.cpp b/src/nlr/NetworkLevelReasoner.cpp index badb0bbc3d..f577b19960 100644 --- a/src/nlr/NetworkLevelReasoner.cpp +++ b/src/nlr/NetworkLevelReasoner.cpp @@ -128,7 +128,8 @@ void NetworkLevelReasoner::evaluate( double *input, double *output ) memcpy( output, outputLayer->getAssignment(), sizeof( double ) * outputLayer->getSize() ); } -void NetworkLevelReasoner::concretizeInputAssignment( Map &assignment ) +void NetworkLevelReasoner::concretizeInputAssignment( Map &assignment, + const double *pgdAdversarialInput ) { Layer *inputLayer = _layerIndexToLayer[0]; ASSERT( inputLayer->getLayerType() == Layer::INPUT ); @@ -144,7 +145,12 @@ void NetworkLevelReasoner::concretizeInputAssignment( Map &ass if ( !inputLayer->neuronEliminated( index ) ) { unsigned variable = inputLayer->neuronToVariable( index ); - double value = _tableau->getValue( variable ); + double value; + if (pgdAdversarialInput) + value = pgdAdversarialInput[index]; + else + value = _tableau->getValue( variable ); + input[index] = value; assignment[variable] = value; } diff --git a/src/nlr/NetworkLevelReasoner.h b/src/nlr/NetworkLevelReasoner.h index 93fa39423a..926cee6b1b 100644 --- a/src/nlr/NetworkLevelReasoner.h +++ b/src/nlr/NetworkLevelReasoner.h @@ -79,7 +79,8 @@ class NetworkLevelReasoner : public LayerOwner Perform an evaluation of the network for the current input variable assignment and store the resulting variable assignment in the assignment. */ - void concretizeInputAssignment( Map &assignment ); + void concretizeInputAssignment( Map &assignment, + const double *pgdAdversarialInput = nullptr ); /* Perform a simulation of the network for a specific input From 4683d77d8d84f76ba2adf3bf05a3ec63dbc415bb Mon Sep 17 00:00:00 2001 From: idan0610 Date: Sun, 15 Sep 2024 10:02:21 +0300 Subject: [PATCH 39/69] bug fix in CustomMaxPool backward + extract solution from PGD attack if success (buggy) --- .vscode/c_cpp_properties.json | 17 ----------------- src/engine/CustomDNN.cpp | 2 -- src/engine/Engine.h | 2 ++ 3 files changed, 2 insertions(+), 19 deletions(-) delete mode 100644 .vscode/c_cpp_properties.json diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index a0aa6ead37..0000000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,17 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "${workspaceFolder}/**" - ], - "defines": [], - "compilerPath": "/usr/bin/gcc", - "cStandard": "c17", - "cppStandard": "gnu++17", - "intelliSenseMode": "linux-gcc-x64", - "configurationProvider": "ms-vscode.cmake-tools" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index bb6230b574..566748b1fc 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,6 +1,4 @@ #include "CustomDNN.h" - -#include "NetworkLevelReasoner.h" #include "Vector.h" #include "TimeUtils.h" diff --git a/src/engine/Engine.h b/src/engine/Engine.h index 19a5f8ea7f..5d31a0c1bf 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -36,6 +36,7 @@ #include "MILPEncoder.h" #include "Map.h" #include "Options.h" +#include "PGD.h" #include "PrecisionRestorer.h" #include "Preprocessor.h" #include "SignalHandler.h" @@ -48,6 +49,7 @@ #include "SymbolicBoundTighteningType.h" #include "UnsatCertificateNode.h" + #include #include From a3b8d333e1c215174c4ca6940956f6459633416e Mon Sep 17 00:00:00 2001 From: idan0610 Date: Sun, 15 Sep 2024 14:53:16 +0300 Subject: [PATCH 40/69] minor --- src/engine/Engine.h | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/Engine.h b/src/engine/Engine.h index 5d31a0c1bf..bf16ac56c5 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -36,7 +36,6 @@ #include "MILPEncoder.h" #include "Map.h" #include "Options.h" -#include "PGD.h" #include "PrecisionRestorer.h" #include "Preprocessor.h" #include "SignalHandler.h" From 780318a871d0042ce239fc1941828c8362f4da1f Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 16 Sep 2024 08:08:02 +0300 Subject: [PATCH 41/69] fix advInput PGD.cpp --- src/engine/PGD.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index dd6ea9a10d..d3fda9e21d 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -188,8 +188,8 @@ bool PGDAttack::displayAdversarialExample() { std::cout << "-----Starting PGD attack-----" << std::endl; auto adversarial = _findAdvExample(); - torch::Tensor advInput = adversarial.first; - torch::Tensor advPred = adversarial.second; + torch::Tensor advInput = adversarial.first.to(torch::kDouble); + torch::Tensor advPred = adversarial.second.to(torch::kDouble); bool isFooled = _isWithinBounds( advInput, inputBounds ) && _isWithinBounds( advPred, outputBounds ); From c9d75addeb242566965e09858397837ba43e33ec Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 16 Sep 2024 10:12:05 +0300 Subject: [PATCH 42/69] improve loss --- src/engine/PGD.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index d3fda9e21d..548d9acdca 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -136,11 +136,10 @@ torch::Tensor PGDAttack::_calculateLoss( const torch::Tensor &predictions ) torch::tensor( outputBounds.second.data(), torch::kFloat32 ).to( device ); // Compute the penalty: We want high loss if predictions are outside the bounds - torch::Tensor ubViolation = - torch::sum( torch::square( torch::relu( predictions - upperBoundTensor ) ) ).to( device ); - torch::Tensor lbViolation = - torch::sum( torch::square( torch::relu( lowerBoundTensor - predictions ) ) ).to( device ); - return torch::sum( ubViolation + lbViolation ).to( device ); + torch::Tensor ubViolation = torch::sum(torch::relu(predictions - upperBoundTensor)).to(device); + torch::Tensor lbViolation = torch::sum(torch::relu(lowerBoundTensor - predictions)).to(device); + return ubViolation + lbViolation; + } @@ -148,16 +147,17 @@ std::pair PGDAttack::_findAdvExample() { torch::Tensor currentExample; torch::Tensor currentPrediction; + torch::Tensor lowerBoundTensor = torch::tensor(inputBounds.first.data(), torch::kFloat32).to(device); + torch::Tensor upperBoundTensor = torch::tensor(inputBounds.second.data(), torch::kFloat32).to(device); for ( unsigned i = 0; i < restarts; ++i ) { - torch::Tensor delta = torch::rand( inputSize ).mul( epsilon ).to( device ); - delta.set_requires_grad( true ); - torch::optim::Adam optimizer( { delta }, torch::optim::AdamOptions() ); + torch::Tensor delta = torch::zeros(inputSize).to(device).requires_grad_(true); + torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions()); for ( unsigned j = 0; j < iters; ++j ) { - currentExample = InputExample + delta; + currentExample = torch::clamp(InputExample + delta, lowerBoundTensor, upperBoundTensor); currentPrediction = model.forward( currentExample ); torch::Tensor loss = _calculateLoss( currentPrediction ); optimizer.zero_grad(); @@ -166,7 +166,6 @@ std::pair PGDAttack::_findAdvExample() delta.data() = delta.data().clamp( -epsilon, epsilon ); } - currentExample = InputExample + delta; currentPrediction = model.forward( currentExample ); torch::Tensor currentLoss = _calculateLoss( currentPrediction ); if ( _isWithinBounds( currentPrediction, outputBounds ) ) From 0680f21d2cf6092a90efefd69d61e8f0cfcb7f11 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 16 Sep 2024 19:47:56 +0300 Subject: [PATCH 43/69] fix _findAdvExample --- src/engine/Engine.cpp | 12 +++++++----- src/engine/Marabou.cpp | 3 +++ src/engine/PGD.cpp | 34 ++++++++++++++-------------------- src/engine/PGD.h | 4 ++-- 4 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 828afbcfff..a65607076d 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -37,7 +37,7 @@ #include #undef Warning -#include +#include Engine::Engine() @@ -1440,23 +1440,25 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) try { informConstraintsOfInitialBounds( inputQuery ); - // for (auto& inputVar : inputQuery.getInputVariables()) { - // inputQuery.setLowerBound(inputVar, -3); - // inputQuery.setUpperBound(inputVar, 3); - // } invokePreprocessor( inputQuery, preprocess ); if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); if ( _networkLevelReasoner ) { + std::cout << "start time attack: " << TimeUtils::now().ascii() << std::endl; + fflush( stdout ); _pgdAttack = new PGDAttack(_networkLevelReasoner); if ( _pgdAttack->displayAdversarialExample() ) { + std::cout << "end time attack: " << TimeUtils::now().ascii() << std::endl; + fflush( stdout ); _exitCode = Engine::SAT; _isAttackSuccessful = true; return false; } + std::cout << "end time attack: " << TimeUtils::now().ascii() << std::endl; + fflush( stdout ); } if ( preprocess ) diff --git a/src/engine/Marabou.cpp b/src/engine/Marabou.cpp index 0e2f3813d9..d321da66ac 100644 --- a/src/engine/Marabou.cpp +++ b/src/engine/Marabou.cpp @@ -57,6 +57,7 @@ Marabou::~Marabou() void Marabou::run() { + std::cout << "start run time: " << TimeUtils::now().ascii() << std::endl; struct timespec start = TimeUtils::sampleMicro(); prepareInputQuery(); @@ -69,6 +70,8 @@ void Marabou::run() if ( Options::get()->getBool( Options::EXPORT_ASSIGNMENT ) ) exportAssignment(); + + std::cout << "end run time: " << TimeUtils::now().ascii() << std::endl; } void Marabou::prepareInputQuery() diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 548d9acdca..40ecaa62a6 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -136,46 +136,40 @@ torch::Tensor PGDAttack::_calculateLoss( const torch::Tensor &predictions ) torch::tensor( outputBounds.second.data(), torch::kFloat32 ).to( device ); // Compute the penalty: We want high loss if predictions are outside the bounds - torch::Tensor ubViolation = torch::sum(torch::relu(predictions - upperBoundTensor)).to(device); - torch::Tensor lbViolation = torch::sum(torch::relu(lowerBoundTensor - predictions)).to(device); - return ubViolation + lbViolation; - + torch::Tensor ubViolation = torch::sum(torch::square( + torch::relu(predictions - upperBoundTensor ))).to(device); + torch::Tensor lbViolation = torch::sum(torch::square( + torch::relu(lowerBoundTensor - predictions) )).to(device); + return torch::sum(ubViolation + lbViolation).to(device); } - std::pair PGDAttack::_findAdvExample() { - torch::Tensor currentExample; + torch::Tensor currentExample = InputExample; torch::Tensor currentPrediction; torch::Tensor lowerBoundTensor = torch::tensor(inputBounds.first.data(), torch::kFloat32).to(device); torch::Tensor upperBoundTensor = torch::tensor(inputBounds.second.data(), torch::kFloat32).to(device); - + torch::Tensor delta = torch::zeros(inputSize).to(device).requires_grad_(true); for ( unsigned i = 0; i < restarts; ++i ) { - torch::Tensor delta = torch::zeros(inputSize).to(device).requires_grad_(true); torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions()); - for ( unsigned j = 0; j < iters; ++j ) { - currentExample = torch::clamp(InputExample + delta, lowerBoundTensor, upperBoundTensor); + currentExample = currentExample + delta; currentPrediction = model.forward( currentExample ); - torch::Tensor loss = _calculateLoss( currentPrediction ); + if ( _isWithinBounds( currentPrediction, outputBounds ) ) + { + return { currentExample, currentPrediction }; + } optimizer.zero_grad(); + torch::Tensor loss = _calculateLoss( currentPrediction ); loss.backward(); optimizer.step(); delta.data() = delta.data().clamp( -epsilon, epsilon ); } - - currentPrediction = model.forward( currentExample ); - torch::Tensor currentLoss = _calculateLoss( currentPrediction ); - if ( _isWithinBounds( currentPrediction, outputBounds ) ) - { - return { currentExample, currentPrediction }; - } + delta = (torch::rand(inputSize) * 2 - 1).mul(epsilon).to(device).requires_grad_(true); } - return { currentExample, currentPrediction }; - ; } double PGDAttack::getAssignment( int index ) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 2e519c951f..f51ee102f9 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -6,8 +6,8 @@ #undef Warning #include -constexpr unsigned DEFAULT_NUM_ITER = 50; -constexpr unsigned DEFAULT_NUM_RESTARTS = 4; +constexpr unsigned DEFAULT_NUM_ITER = 100; +constexpr unsigned DEFAULT_NUM_RESTARTS = 3; constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; From c5f02076a7134e2b6bf1dc1ccb7b1bdaa9863601 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 5 Nov 2024 12:51:57 +0200 Subject: [PATCH 44/69] v --- src/engine/CustomDNN.cpp | 3 ++- src/engine/CustomDNN.h | 32 +++++++++++++++++--------------- src/engine/PGD.h | 1 + 3 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 566748b1fc..6705f065c1 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,6 +1,7 @@ #include "CustomDNN.h" -#include "Vector.h" + #include "TimeUtils.h" +#include "Vector.h" CustomMaxPool::CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index 03f66e58b6..298eaeaabf 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -2,37 +2,39 @@ #define __CustomDNN_h__ #include "NetworkLevelReasoner.h" + #include #undef Warning #include -class CustomMaxPoolFunction : public torch::autograd::Function { +class CustomMaxPoolFunction : public torch::autograd::Function +{ public: - static torch::Tensor forward(torch::autograd::AutogradContext *ctx, + static torch::Tensor forward( torch::autograd::AutogradContext *ctx, torch::Tensor x, const NLR::NetworkLevelReasoner *nlr, - unsigned layerIndex); + unsigned layerIndex ); - static std::vector backward(torch::autograd::AutogradContext *ctx, std::vector - grad_output); + static std::vector backward( torch::autograd::AutogradContext *ctx, + std::vector grad_output ); }; -class CustomMaxPool : public torch::nn::Module { +class CustomMaxPool : public torch::nn::Module +{ public: - CustomMaxPool(const NLR::NetworkLevelReasoner* nlr, unsigned layerIndex); - torch::Tensor forward(torch::Tensor x) const; + CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ); + torch::Tensor forward( torch::Tensor x ) const; private: - const NLR::NetworkLevelReasoner* networkLevelReasoner; + const NLR::NetworkLevelReasoner *networkLevelReasoner; unsigned maxLayerIndex; }; class CustomDNNImpl : public torch::nn::Module { public: - - const NLR::NetworkLevelReasoner* networkLevelReasoner; + const NLR::NetworkLevelReasoner *networkLevelReasoner; Vector layerSizes; Vector reluLayers; Vector leakyReluLayers; @@ -47,10 +49,10 @@ class CustomDNNImpl : public torch::nn::Module Vector maxLayerIndices; static void setWeightsAndBiases( torch::nn::Linear &linearLayer, - const NLR::Layer *layer, - unsigned sourceLayer, - unsigned inputSize, - unsigned outputSize ); + const NLR::Layer *layer, + unsigned sourceLayer, + unsigned inputSize, + unsigned outputSize ); void weightedSum( unsigned i, const NLR::Layer *layer ); explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); diff --git a/src/engine/PGD.h b/src/engine/PGD.h index f51ee102f9..53ae48a7f4 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -8,6 +8,7 @@ constexpr unsigned DEFAULT_NUM_ITER = 100; constexpr unsigned DEFAULT_NUM_RESTARTS = 3; + constexpr unsigned INPUT = 0; constexpr unsigned OUTPUT = 1; constexpr unsigned RANGE = 1000.0f; From e091387faa4ad1e72f8a12df449ed2a1236afc13 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Sat, 9 Nov 2024 15:57:14 +0200 Subject: [PATCH 45/69] changes for pull request --- src/configuration/GlobalConfiguration.cpp | 8 + src/configuration/GlobalConfiguration.h | 12 ++ src/engine/CustomDNN.cpp | 68 +++++---- src/engine/CustomDNN.h | 49 ++++--- src/engine/Engine.cpp | 4 +- src/engine/PGD.cpp | 170 ++++++++++++---------- src/engine/PGD.h | 75 +++++++--- 7 files changed, 233 insertions(+), 153 deletions(-) diff --git a/src/configuration/GlobalConfiguration.cpp b/src/configuration/GlobalConfiguration.cpp index bf1d0b9371..1f2502a8da 100644 --- a/src/configuration/GlobalConfiguration.cpp +++ b/src/configuration/GlobalConfiguration.cpp @@ -117,6 +117,12 @@ const bool GlobalConfiguration::WRITE_JSON_PROOF = false; const unsigned GlobalConfiguration::BACKWARD_BOUND_PROPAGATION_DEPTH = 3; const unsigned GlobalConfiguration::MAX_ROUNDS_OF_BACKWARD_ANALYSIS = 10; +const GlobalConfiguration::PdgBoundType GlobalConfiguration::PGD_BOUND_TYPE = + GlobalConfiguration::PGD_INPUT; +const unsigned GlobalConfiguration::PGD_DEFAULT_NUM_ITER = 100; // todo run argument +const unsigned GlobalConfiguration::PGD_NUM_RESTARTS = 3; // todo run argument +const double GlobalConfiguration::PGD_INPUT_RANGE = 1000; + #ifdef ENABLE_GUROBI const unsigned GlobalConfiguration::GUROBI_NUMBER_OF_THREADS = 1; const bool GlobalConfiguration::GUROBI_LOGGING = false; @@ -141,6 +147,8 @@ const bool GlobalConfiguration::ONNX_PARSER_LOGGING = false; const bool GlobalConfiguration::SOI_LOGGING = false; const bool GlobalConfiguration::SCORE_TRACKER_LOGGING = false; const bool GlobalConfiguration::CEGAR_LOGGING = false; +const bool GlobalConfiguration::CUSTOM_DNN_LOGGING = false; +const bool GlobalConfiguration::PGD_LOG = false; const bool GlobalConfiguration::USE_SMART_FIX = false; const bool GlobalConfiguration::USE_LEAST_FIX = false; diff --git a/src/configuration/GlobalConfiguration.h b/src/configuration/GlobalConfiguration.h index c89c1d54b3..b2a83d4cb7 100644 --- a/src/configuration/GlobalConfiguration.h +++ b/src/configuration/GlobalConfiguration.h @@ -257,6 +257,16 @@ class GlobalConfiguration */ static const unsigned MAX_ROUNDS_OF_BACKWARD_ANALYSIS; + enum PdgBoundType { + PGD_INPUT = 0, + PGD_OUTPUT = 1 + }; + static const PdgBoundType PGD_BOUND_TYPE; + static const unsigned PGD_DEFAULT_NUM_ITER; + static const unsigned PGD_NUM_RESTARTS; + static const double PGD_INPUT_RANGE; + + #ifdef ENABLE_GUROBI /* The number of threads Gurobi spawns @@ -286,6 +296,8 @@ class GlobalConfiguration static const bool SOI_LOGGING; static const bool SCORE_TRACKER_LOGGING; static const bool CEGAR_LOGGING; + static const bool CUSTOM_DNN_LOGGING; + static const bool PGD_LOG; }; #endif // __GlobalConfiguration_h__ diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 6705f065c1..249ae5702b 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -5,17 +5,17 @@ CustomMaxPool::CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) - : networkLevelReasoner( nlr ) - , maxLayerIndex( layerIndex ) + : _networkLevelReasoner( nlr ) + , _maxLayerIndex( layerIndex ) { } torch::Tensor CustomMaxPool::forward( torch::Tensor x ) const { - return CustomMaxPoolFunction::apply( x, networkLevelReasoner, maxLayerIndex ); + return CustomMaxPoolFunction::apply( x, _networkLevelReasoner, _maxLayerIndex ); } -void CustomDNNImpl::setWeightsAndBiases( torch::nn::Linear &linearLayer, +void CustomDNN::setWeightsAndBiases( torch::nn::Linear &linearLayer, const NLR::Layer *layer, unsigned sourceLayer, unsigned inputSize, @@ -54,17 +54,17 @@ void CustomDNNImpl::setWeightsAndBiases( torch::nn::Linear &linearLayer, linearLayer->bias.set_( biasTensor ); } -void CustomDNNImpl::weightedSum( unsigned i, const NLR::Layer *layer ) +void CustomDNN::weightedSum( unsigned i, const NLR::Layer *layer ) { unsigned sourceLayer = i - 1; - const NLR::Layer *prevLayer = networkLevelReasoner->getLayer( sourceLayer ); + const NLR::Layer *prevLayer = _networkLevelReasoner->getLayer( sourceLayer ); unsigned inputSize = prevLayer->getSize(); unsigned outputSize = layer->getSize(); if ( outputSize > 0 ) { auto linearLayer = torch::nn::Linear( torch::nn::LinearOptions( inputSize, outputSize ) ); - linearLayers.append( linearLayer ); + _linearLayers.append( linearLayer ); setWeightsAndBiases( linearLayer, layer, sourceLayer, inputSize, outputSize ); @@ -73,17 +73,17 @@ void CustomDNNImpl::weightedSum( unsigned i, const NLR::Layer *layer ) } -CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) +CustomDNN::CustomDNN( const NLR::NetworkLevelReasoner *nlr ) { - std::cout << "----- Construct Custom Network -----" << std::endl; - networkLevelReasoner = nlr; - numberOfLayers = networkLevelReasoner->getNumberOfLayers(); - for ( unsigned i = 0; i < numberOfLayers; i++ ) + CUSTOM_DNN_LOG("----- Construct Custom Network -----" ); + _networkLevelReasoner = nlr; + _numberOfLayers = _networkLevelReasoner->getNumberOfLayers(); + for ( unsigned i = 0; i < _numberOfLayers; i++ ) { - const NLR::Layer *layer = networkLevelReasoner->getLayer( i ); - layerSizes.append( layer->getSize() ); + const NLR::Layer *layer = _networkLevelReasoner->getLayer( i ); + _layerSizes.append( layer->getSize() ); NLR::Layer::Type layerType = layer->getLayerType(); - layersOrder.append( layerType ); + _layersOrder.append( layerType ); switch ( layerType ) { case NLR::Layer::INPUT: @@ -94,74 +94,77 @@ CustomDNNImpl::CustomDNNImpl( const NLR::NetworkLevelReasoner *nlr ) case NLR::Layer::RELU: { auto reluLayer = torch::nn::ReLU( torch::nn::ReLUOptions() ); - reluLayers.append( reluLayer ); + _reluLayers.append( reluLayer ); register_module( "ReLU" + std::to_string( i ), reluLayer ); break; } case NLR::Layer::LEAKY_RELU: { auto reluLayer = torch::nn::LeakyReLU( torch::nn::LeakyReLUOptions() ); - leakyReluLayers.append( reluLayer ); + _leakyReluLayers.append( reluLayer ); register_module( "leakyReLU" + std::to_string( i ), reluLayer ); break; } case NLR::Layer::MAX: { - auto customMaxPoolLayer = std::make_shared( networkLevelReasoner, i ); - customMaxPoolLayers.append( customMaxPoolLayer ); + auto customMaxPoolLayer = std::make_shared( _networkLevelReasoner, i ); + _customMaxPoolLayers.append( customMaxPoolLayer ); register_module( "maxPool" + std::to_string( i ), customMaxPoolLayer ); break; } case NLR::Layer::SIGMOID: { auto sigmoidLayer = torch::nn::Sigmoid(); - sigmoidLayers.append( sigmoidLayer ); + _sigmoidLayers.append( sigmoidLayer ); register_module( "sigmoid" + std::to_string( i ), sigmoidLayer ); break; } default: - std::cerr << "Unsupported layer type: " << layerType << std::endl; + CUSTOM_DNN_LOG( "Unsupported layer type\n" ); + throw MarabouError( MarabouError::DEBUGGING_ERROR ); break; } } } -torch::Tensor CustomDNNImpl::forward( torch::Tensor x ) +torch::Tensor CustomDNN::forward( torch::Tensor x ) { unsigned linearIndex = 0; unsigned reluIndex = 0; unsigned maxPoolIndex = 0; unsigned leakyReluIndex = 0; unsigned sigmoidIndex = 0; - for ( unsigned i = 0; i < numberOfLayers; i++ ) + for ( unsigned i = 0; i < _numberOfLayers; i++ ) { - const NLR::Layer::Type layerType = layersOrder[i]; + const NLR::Layer::Type layerType = _layersOrder[i]; switch ( layerType ) { case NLR::Layer::INPUT: break; case NLR::Layer::WEIGHTED_SUM: - x = linearLayers[linearIndex]->forward( x ); + x = _linearLayers[linearIndex]->forward( x ); linearIndex++; break; case NLR::Layer::RELU: - x = reluLayers[reluIndex]->forward( x ); + x = _reluLayers[reluIndex]->forward( x ); reluIndex++; break; case NLR::Layer::MAX: - x = customMaxPoolLayers[maxPoolIndex]->forward( x ); + x = _customMaxPoolLayers[maxPoolIndex]->forward( x ); maxPoolIndex++; break; case NLR::Layer::LEAKY_RELU: - x = leakyReluLayers[leakyReluIndex]->forward( x ); + x = _leakyReluLayers[leakyReluIndex]->forward( x ); leakyReluIndex++; break; case NLR::Layer::SIGMOID: - x = sigmoidLayers[sigmoidIndex]->forward( x ); + x = _sigmoidLayers[sigmoidIndex]->forward( x ); sigmoidIndex++; break; default: - std::cerr << "Unsupported activation type: " << layerType << std::endl; + CUSTOM_DNN_LOG( "Unsupported layer type\n" ); + throw MarabouError( MarabouError::DEBUGGING_ERROR ); + break; } } return x; @@ -217,3 +220,8 @@ std::vector CustomMaxPoolFunction::backward( torch::autograd::Aut return { grad_input, torch::Tensor(), torch::Tensor() }; } + +const Vector& CustomDNN::getLayerSizes() const +{ + return _layerSizes; +} \ No newline at end of file diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index 298eaeaabf..d1e6688de8 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -7,7 +7,12 @@ #undef Warning #include +#define CUSTOM_DNN_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "customDNN: %s\n", x ) +/* + Custom differentiation function for max pooling, implementing the forward and backward propagation for + the max pooling operation according to each variable's source layer as defined in the nlr. +*/ class CustomMaxPoolFunction : public torch::autograd::Function { public: @@ -27,36 +32,36 @@ class CustomMaxPool : public torch::nn::Module torch::Tensor forward( torch::Tensor x ) const; private: - const NLR::NetworkLevelReasoner *networkLevelReasoner; - unsigned maxLayerIndex; + const NLR::NetworkLevelReasoner *_networkLevelReasoner; + unsigned _maxLayerIndex; }; -class CustomDNNImpl : public torch::nn::Module +/* + torch implementation of the network according to the nlr. + */ +class CustomDNN : public torch::nn::Module { public: - const NLR::NetworkLevelReasoner *networkLevelReasoner; - Vector layerSizes; - Vector reluLayers; - Vector leakyReluLayers; - Vector sigmoidLayers; - Vector> customMaxPoolLayers; - Vector activations; - Vector>> weights; - Vector> biases; - Vector linearLayers; - Vector layersOrder; - unsigned numberOfLayers; - Vector maxLayerIndices; - static void setWeightsAndBiases( torch::nn::Linear &linearLayer, - const NLR::Layer *layer, - unsigned sourceLayer, - unsigned inputSize, - unsigned outputSize ); + const NLR::Layer *layer, + unsigned sourceLayer, + unsigned inputSize, + unsigned outputSize ); void weightedSum( unsigned i, const NLR::Layer *layer ); - explicit CustomDNNImpl( const NLR::NetworkLevelReasoner *networkLevelReasoner ); + explicit CustomDNN( const NLR::NetworkLevelReasoner *networkLevelReasoner ); torch::Tensor forward( torch::Tensor x ); + const Vector &getLayerSizes() const; +private: + const NLR::NetworkLevelReasoner *_networkLevelReasoner; + Vector _layerSizes; + Vector _reluLayers; + Vector _leakyReluLayers; + Vector _sigmoidLayers; + Vector> _customMaxPoolLayers; + Vector _linearLayers; + Vector _layersOrder; + unsigned _numberOfLayers; }; diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index a65607076d..8beda932b7 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1449,7 +1449,7 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) std::cout << "start time attack: " << TimeUtils::now().ascii() << std::endl; fflush( stdout ); _pgdAttack = new PGDAttack(_networkLevelReasoner); - if ( _pgdAttack->displayAdversarialExample() ) + if ( _pgdAttack->hasAdversarialExample() ) { std::cout << "end time attack: " << TimeUtils::now().ascii() << std::endl; fflush( stdout ); @@ -2133,7 +2133,7 @@ void Engine::applySplit( const PiecewiseLinearCaseSplit &split ) else { ENGINE_LOG( - Stringf( "x%u: upper bound set to %.3lf", variable, bound._value ).ascii() ); + Stringf( c ).ascii() ); if ( _produceUNSATProofs && FloatUtils::lt( bound._value, _boundManager.getUpperBound( bound._variable ) ) ) { diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 40ecaa62a6..a1d41657e0 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,43 +1,42 @@ #include "PGD.h" #include "InputQuery.h" - #include PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) : networkLevelReasoner( networkLevelReasoner ) - , device( torch::kCPU ) - , model( CustomDNNImpl( networkLevelReasoner ) ) - , iters( DEFAULT_NUM_ITER ) - , restarts( DEFAULT_NUM_RESTARTS ) + , _device( torch::kCPU ) + , _model( CustomDNN( networkLevelReasoner ) ) + , _iters( GlobalConfiguration::PGD_DEFAULT_NUM_ITER ) + , _restarts( GlobalConfiguration::PGD_NUM_RESTARTS ) , _adversarialInput( nullptr ) , _adversarialOutput( nullptr ) { - inputSize = model.layerSizes.first(); - _getBounds( inputBounds, INPUT ); - _getBounds( outputBounds, OUTPUT ); - std::pair variables = _generateSampleAndEpsilon(); - InputExample = variables.first; - epsilon = variables.second; + _inputSize = _model.getLayerSizes().first(); + getBounds( _inputBounds, GlobalConfiguration::PdgBoundType::PGD_INPUT ); + getBounds( _outputBounds, GlobalConfiguration::PdgBoundType::PGD_OUTPUT ); + std::pair variables = generateSampleAndEpsilon(); + _inputExample = variables.first; + _epsilon = variables.second; } -torch::Device PGDAttack::_getDevice() +torch::Device PGDAttack::getDevice() { if ( torch::cuda::is_available() ) { - std::cout << "CUDA is available. Using GPU." << std::endl; + PGD_LOG( "CUDA Device available. Using GPU" ); return { torch::kCUDA }; } else { - std::cout << "CUDA is not available. Using CPU." << std::endl; + PGD_LOG( "CUDA Device not available. Using CPU" ); return { torch::kCPU }; } } -void PGDAttack::_getBounds( std::pair, Vector> &bounds, - const signed type ) const +void PGDAttack::getBounds( std::pair, Vector> &bounds, + const signed type ) const { - unsigned layerIndex = type == INPUT ? 0 : networkLevelReasoner->getNumberOfLayers() - 1; + unsigned layerIndex = type == GlobalConfiguration::PdgBoundType::PGD_INPUT ? 0 : networkLevelReasoner->getNumberOfLayers() - 1; const NLR::Layer *layer = networkLevelReasoner->getLayer( layerIndex ); for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) @@ -47,15 +46,15 @@ void PGDAttack::_getBounds( std::pair, Vector> &bounds, } } -std::pair PGDAttack::_generateSampleAndEpsilon() +std::pair PGDAttack::generateSampleAndEpsilon() { - Vector sample( inputSize, 0.0f ); - Vector epsilons( inputSize, 0.0f ); + Vector sample( _inputSize, 0.0f ); + Vector epsilons( _inputSize, 0.0f ); - for ( unsigned i = 0; i < inputSize; i++ ) + for ( unsigned i = 0; i < _inputSize; i++ ) { - double lower = inputBounds.first.get( i ); - double upper = inputBounds.second.get( i ); + double lower = _inputBounds.first.get( i ); + double upper = _inputBounds.second.get( i ); if ( std::isinf( lower ) && std::isinf( upper ) ) { @@ -64,13 +63,13 @@ std::pair PGDAttack::_generateSampleAndEpsilon() } else if ( std::isinf( lower ) ) { - sample[i] = upper - RANGE; - epsilons[i] = RANGE; + sample[i] = upper - GlobalConfiguration::PGD_INPUT_RANGE; + epsilons[i] = GlobalConfiguration::PGD_INPUT_RANGE; } else if ( std::isinf( upper ) ) { - sample[i] = lower + RANGE; - epsilons[i] = RANGE; + sample[i] = lower + GlobalConfiguration::PGD_INPUT_RANGE; + epsilons[i] = GlobalConfiguration::PGD_INPUT_RANGE; } else { @@ -80,12 +79,12 @@ std::pair PGDAttack::_generateSampleAndEpsilon() } } - return { torch::tensor( sample.getContainer() ).unsqueeze( 0 ).to( device ), - torch::tensor( epsilons.getContainer() ).to( device ) }; + return { torch::tensor( sample.getContainer() ).unsqueeze( 0 ).to( _device ), + torch::tensor( epsilons.getContainer() ).to( _device ) }; } -bool PGDAttack::_isWithinBounds( const torch::Tensor &sample, - const std::pair, Vector> &bounds ) +bool PGDAttack::isWithinBounds( const torch::Tensor &sample, + const std::pair, Vector> &bounds ) { torch::Tensor flatInput = sample.view( { -1 } ); if ( flatInput.numel() != bounds.first.size() || flatInput.numel() != bounds.second.size() ) @@ -128,100 +127,119 @@ bool PGDAttack::_isWithinBounds( const torch::Tensor &sample, } -torch::Tensor PGDAttack::_calculateLoss( const torch::Tensor &predictions ) +torch::Tensor PGDAttack::calculateLoss( const torch::Tensor &predictions ) { torch::Tensor lowerBoundTensor = - torch::tensor( outputBounds.first.data(), torch::kFloat32 ).to( device ); + torch::tensor( _outputBounds.first.data(), torch::kFloat32 ).to( _device ); torch::Tensor upperBoundTensor = - torch::tensor( outputBounds.second.data(), torch::kFloat32 ).to( device ); - - // Compute the penalty: We want high loss if predictions are outside the bounds - torch::Tensor ubViolation = torch::sum(torch::square( - torch::relu(predictions - upperBoundTensor ))).to(device); - torch::Tensor lbViolation = torch::sum(torch::square( - torch::relu(lowerBoundTensor - predictions) )).to(device); - return torch::sum(ubViolation + lbViolation).to(device); + torch::tensor( _outputBounds.second.data(), torch::kFloat32 ).to( _device ); + + // Compute the penalty: High loss if predictions are outside the bounds + torch::Tensor ubViolation = + torch::sum( torch::square( torch::relu( predictions - upperBoundTensor ) ) ).to( _device ); + torch::Tensor lbViolation = + torch::sum( torch::square( torch::relu( lowerBoundTensor - predictions ) ) ).to( _device ); + return torch::sum( ubViolation + lbViolation ).to( _device ); } -std::pair PGDAttack::_findAdvExample() +std::pair PGDAttack::findAdvExample() { - torch::Tensor currentExample = InputExample; + torch::Tensor currentExample = _inputExample; torch::Tensor currentPrediction; - torch::Tensor lowerBoundTensor = torch::tensor(inputBounds.first.data(), torch::kFloat32).to(device); - torch::Tensor upperBoundTensor = torch::tensor(inputBounds.second.data(), torch::kFloat32).to(device); - torch::Tensor delta = torch::zeros(inputSize).to(device).requires_grad_(true); - for ( unsigned i = 0; i < restarts; ++i ) + torch::Tensor lowerBoundTensor = + torch::tensor( _inputBounds.first.data(), torch::kFloat32 ).to( _device ); + torch::Tensor upperBoundTensor = + torch::tensor( _inputBounds.second.data(), torch::kFloat32 ).to( _device ); + torch::Tensor delta = torch::zeros( _inputSize ).to( _device ).requires_grad_( true ); + for ( unsigned i = 0; i < _restarts; ++i ) { - torch::optim::Adam optimizer({delta}, torch::optim::AdamOptions()); - for ( unsigned j = 0; j < iters; ++j ) + torch::optim::Adam optimizer( { delta }, torch::optim::AdamOptions() ); + for ( unsigned j = 0; j < _iters; ++j ) { currentExample = currentExample + delta; - currentPrediction = model.forward( currentExample ); - if ( _isWithinBounds( currentPrediction, outputBounds ) ) + currentPrediction = _model.forward( currentExample ); + if ( isWithinBounds( currentPrediction, _outputBounds ) ) { return { currentExample, currentPrediction }; } optimizer.zero_grad(); - torch::Tensor loss = _calculateLoss( currentPrediction ); + torch::Tensor loss = calculateLoss( currentPrediction ); loss.backward(); optimizer.step(); - delta.data() = delta.data().clamp( -epsilon, epsilon ); + delta.data() = delta.data().clamp( -_epsilon, _epsilon ); } - delta = (torch::rand(inputSize) * 2 - 1).mul(epsilon).to(device).requires_grad_(true); + delta = ( torch::rand( _inputSize ) * 2 - 1 ) + .mul( _epsilon ) + .to( _device ) + .requires_grad_( true ); } return { currentExample, currentPrediction }; } -double PGDAttack::getAssignment( int index ) +double PGDAttack::getAssignment( int index ) { - return assignments[index]; + return _assignments[index]; } -bool PGDAttack::displayAdversarialExample() +bool PGDAttack::hasAdversarialExample() { - std::cout << "-----Starting PGD attack-----" << std::endl; - auto adversarial = _findAdvExample(); - torch::Tensor advInput = adversarial.first.to(torch::kDouble); - torch::Tensor advPred = adversarial.second.to(torch::kDouble); + PGD_LOG( "-----Starting PGD attack-----" ); + auto adversarial = findAdvExample(); + torch::Tensor advInput = adversarial.first.to( torch::kDouble ); + torch::Tensor advPred = adversarial.second.to( torch::kDouble ); bool isFooled = - _isWithinBounds( advInput, inputBounds ) && _isWithinBounds( advPred, outputBounds ); + isWithinBounds( advInput, _inputBounds ) && isWithinBounds( advPred, _outputBounds ); auto *example = advInput.data_ptr(); auto *prediction = advPred.data_ptr(); size_t outputSize = advPred.size( 1 ); - ASSERT( advInput.size( 1 ) == inputSize && outputSize == model.layerSizes.last() ); + ASSERT( advInput.size( 1 ) == _inputSize && outputSize == _model.getLayerSizes().last() ); if ( isFooled ) { _adversarialInput = new double[advInput.size( 1 )]; _adversarialOutput = new double[advPred.size( 1 )]; - std::copy( example, example + inputSize, _adversarialInput ); + std::copy( example, example + _inputSize, _adversarialInput ); std::copy( prediction, prediction + outputSize, _adversarialOutput ); } - - std::cout << "Input Lower Bounds : " << inputBounds.first.getContainer() << "\n"; - std::cout << "Input Upper Bounds : " << inputBounds.second.getContainer() << "\n"; + PGD_LOG( "Input Lower Bounds : \n" ); + for ( auto &bound : _inputBounds.first.getContainer() ) + PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); + PGD_LOG( "Input Upper Bounds : \n" ); + for ( auto &bound : _inputBounds.second.getContainer() ) + PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); + + PGD_LOG( "Adversarial Input:\n" ); std::cout << "Adversarial Input: \n"; for ( int i = 0; i < advInput.numel(); ++i ) { - std::cout << "x" << i << " = " << example[i] << "\n"; + PGD_LOG( "x%u=%.3lf", i, example[i] ); } - std::cout << "Output Lower Bounds : " << outputBounds.first.getContainer() << "\n"; - std::cout << "Output Upper Bounds : " << outputBounds.second.getContainer() << "\n"; + PGD_LOG( "Output Lower Bounds : \n" ); + for ( auto &bound : _outputBounds.first.getContainer() ) + PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); + PGD_LOG( "Output Upper Bounds : \n" ); + for ( auto &bound : _outputBounds.second.getContainer() ) + PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); + std::cout << "Adversarial Prediction: \n"; for ( int i = 0; i < advPred.numel(); ++i ) { - std::cout << "y" << i << " = " << prediction[i] << "\n"; + PGD_LOG( "y%u=%.3lf", i, prediction[i] ); } - std::cout << "Model fooled: " - << ( isFooled ? "Yes \n ------ PGD Attack Succeed ------" - : "No \n ------ PGD Attack Failed ------" ) - << "\n\n"; + + + if ( isFooled ) + { + PGD_LOG( "Model fooled: Yes \n ------ PGD Attack Succeed ------\n" ); + }else + PGD_LOG( "Model fooled: No \n ------ PGD Attack Failed ------\n" ); + if ( _adversarialInput ) - networkLevelReasoner->concretizeInputAssignment( assignments, _adversarialInput ); + networkLevelReasoner->concretizeInputAssignment( _assignments, _adversarialInput ); return isFooled; } diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 53ae48a7f4..b6ebde4cad 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -2,47 +2,76 @@ #define __PGD_h__ #include "CustomDNN.h" +#include "GlobalConfiguration.h" #undef Warning #include constexpr unsigned DEFAULT_NUM_ITER = 100; constexpr unsigned DEFAULT_NUM_RESTARTS = 3; +#define PGD_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "PGD: %s\n", x ) -constexpr unsigned INPUT = 0; -constexpr unsigned OUTPUT = 1; -constexpr unsigned RANGE = 1000.0f; - +/* + PGDAttack class implements the Projected Gradient Descent method for generating + adversarial examples for the network. + The model aim to find valid input to the network that result in outputs within output bounds + (SAT). +*/ class PGDAttack { public: PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ); - bool displayAdversarialExample(); - double getAssignment( int index ); + /* + Search for an adversarial example. Returns true if successful. + */ + bool hasAdversarialExample(); private: NLR::NetworkLevelReasoner *networkLevelReasoner; - torch::Device device; - torch::Tensor epsilon; - torch::Tensor InputExample; - CustomDNNImpl model; - unsigned iters; - unsigned restarts; - unsigned inputSize; - std::pair, Vector> inputBounds; - std::pair, Vector> outputBounds; - Map assignments; + torch::Device _device; + /* + The maximum permissible perturbation for each variable in the input vector, Defining + the scope of allowable changes to the input during the attack. + */ + torch::Tensor _epsilon; + torch::Tensor _inputExample; + CustomDNN _model; + unsigned _iters; + unsigned _restarts; + unsigned _inputSize; + std::pair, Vector> _inputBounds; + std::pair, Vector> _outputBounds; + Map _assignments; double *_adversarialInput; double *_adversarialOutput; + double getAssignment( int index ); + /* + Iteratively generates and refines adversarial examples, aiming to discover inputs that lead to + predictions outside the defined bounds, using gradient-based optimization. + */ + std::pair findAdvExample(); + /* + Generates a valid sample input and epsilon tensor for initializing the attack, + */ + std::pair generateSampleAndEpsilon(); + + /* + Checks if a given sample is within the valid bounds + */ + static bool isWithinBounds( const torch::Tensor &sample, + const std::pair, Vector> &bounds ); + /* + Get the bounds of each neuron in the network defining in the nlr. + */ + void getBounds( std::pair, Vector> &bounds, signed type ) const; + /* + Calculates the loss based on how far the network's outputs deviate from its bounds. + Assigns a higher loss to predictions that fall outside bounds. - std::pair _findAdvExample(); - std::pair _generateSampleAndEpsilon(); - static bool _isWithinBounds( const torch::Tensor &sample, - const std::pair, Vector> &bounds ); - void _getBounds( std::pair, Vector> &bounds, signed type ) const; - torch::Tensor _calculateLoss( const torch::Tensor &predictions ); - static torch::Device _getDevice(); + */ + torch::Tensor calculateLoss( const torch::Tensor &predictions ); + static torch::Device getDevice(); }; From a91dcf300e6e1181234ece72a9cf23a66528fb36 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 12 Nov 2024 11:40:47 +0200 Subject: [PATCH 46/69] add timeout --- maraboupy/MarabouCore.cpp | 6 +++++- src/configuration/Options.cpp | 3 +++ src/configuration/Options.h | 6 ++++++ src/engine/Engine.cpp | 29 +++++++++++++++++++++-------- src/engine/PGD.h | 3 ++- 5 files changed, 37 insertions(+), 10 deletions(-) diff --git a/maraboupy/MarabouCore.cpp b/maraboupy/MarabouCore.cpp index 1b81804703..95173ada7f 100644 --- a/maraboupy/MarabouCore.cpp +++ b/maraboupy/MarabouCore.cpp @@ -296,6 +296,7 @@ struct MarabouOptions , _timeoutInSeconds( Options::get()->getInt( Options::TIMEOUT ) ) , _splitThreshold( Options::get()->getInt( Options::CONSTRAINT_VIOLATION_THRESHOLD ) ) , _numSimulations( Options::get()->getInt( Options::NUMBER_OF_SIMULATIONS ) ) + , _attackTimeout( Options::get()->getInt( Options::ATTACK_TIMEOUT ) ) , _performLpTighteningAfterSplit( Options::get()->getBool( Options::PERFORM_LP_TIGHTENING_AFTER_SPLIT ) ) , _timeoutFactor( Options::get()->getFloat( Options::TIMEOUT_FACTOR ) ) @@ -311,7 +312,8 @@ struct MarabouOptions , _milpTighteningString( Options::get()->getString( Options::MILP_SOLVER_BOUND_TIGHTENING_TYPE ).ascii() ) , _lpSolverString( Options::get()->getString( Options::LP_SOLVER ).ascii() ) - , _produceProofs( Options::get()->getBool( Options::PRODUCE_PROOFS ) ){}; + , _produceProofs( Options::get()->getBool( Options::PRODUCE_PROOFS ) ) + , _runAttack( Options::get()->getBool( Options::RUN_ATTACK ) ){}; void setOptions() { @@ -356,6 +358,7 @@ struct MarabouOptions bool _dumpBounds; bool _performLpTighteningAfterSplit; bool _produceProofs; + bool _runAttack; unsigned _numWorkers; unsigned _numBlasThreads; unsigned _initialTimeout; @@ -365,6 +368,7 @@ struct MarabouOptions unsigned _timeoutInSeconds; unsigned _splitThreshold; unsigned _numSimulations; + unsigned _attackTimeout; float _timeoutFactor; float _preprocessorBoundTolerance; float _milpSolverTimeout; diff --git a/src/configuration/Options.cpp b/src/configuration/Options.cpp index bf3b9b913a..3e1bf24140 100644 --- a/src/configuration/Options.cpp +++ b/src/configuration/Options.cpp @@ -55,6 +55,8 @@ void Options::initializeDefaultValues() _boolOptions[DEBUG_ASSIGNMENT] = false; _boolOptions[PRODUCE_PROOFS] = false; _boolOptions[DO_NOT_MERGE_CONSECUTIVE_WEIGHTED_SUM_LAYERS] = false; + _boolOptions[RUN_ATTACK] = false; // todo? + /* Int options @@ -71,6 +73,7 @@ void Options::initializeDefaultValues() _intOptions[SEED] = 1; _intOptions[NUM_BLAS_THREADS] = 1; _intOptions[NUM_CONSTRAINTS_TO_REFINE_INC_LIN] = 30; + _intOptions[ATTACK_TIMEOUT] = 60; // todo? /* Float options diff --git a/src/configuration/Options.h b/src/configuration/Options.h index 4dd4f31fd5..a615286afa 100644 --- a/src/configuration/Options.h +++ b/src/configuration/Options.h @@ -83,6 +83,9 @@ class Options // logically-consecutive weighted sum layers into a single // weighted sum layer, to reduce the number of variables DO_NOT_MERGE_CONSECUTIVE_WEIGHTED_SUM_LAYERS, + + // Run adversarial attack before preprocess if the flag is true. + RUN_ATTACK, }; enum IntOptions { @@ -115,6 +118,9 @@ class Options // Maximal number of constraints to refine in incremental linearization NUM_CONSTRAINTS_TO_REFINE_INC_LIN, + + // Adversarial attack timeout in seconds + ATTACK_TIMEOUT, }; enum FloatOptions { diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 8beda932b7..b0d08cfc40 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1444,21 +1444,34 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - if ( _networkLevelReasoner ) + if ( _networkLevelReasoner && Options::RUN_ATTACK) { - std::cout << "start time attack: " << TimeUtils::now().ascii() << std::endl; - fflush( stdout ); + double timeoutForAttack = ( Options::ATTACK_TIMEOUT == 0 ? FloatUtils::infinity() : Options::ATTACK_TIMEOUT ); + ENGINE_LOG( Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); + ENGINE_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); + _pgdAttack = new PGDAttack(_networkLevelReasoner); if ( _pgdAttack->hasAdversarialExample() ) { - std::cout << "end time attack: " << TimeUtils::now().ascii() << std::endl; - fflush( stdout ); + ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); _exitCode = Engine::SAT; _isAttackSuccessful = true; return false; } - std::cout << "end time attack: " << TimeUtils::now().ascii() << std::endl; - fflush( stdout ); + ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); + if ( shouldExitDueToTimeout( timeoutForAttack ) ) // todo change to time from attack starting time + { + if ( _verbosity > 0 ) + { + printf( "\n\nEngine: quitting due to timeout...\n\n" ); + printf( "Final statistics:\n" ); + _statistics.print(); + } + + _exitCode = Engine::TIMEOUT; + _statistics.timeout(); + return false; + } } if ( preprocess ) @@ -2133,7 +2146,7 @@ void Engine::applySplit( const PiecewiseLinearCaseSplit &split ) else { ENGINE_LOG( - Stringf( c ).ascii() ); + Stringf( "x%u: upper bound set to %.3lf", variable, bound._value ).ascii() ); if ( _produceUNSATProofs && FloatUtils::lt( bound._value, _boundManager.getUpperBound( bound._variable ) ) ) { diff --git a/src/engine/PGD.h b/src/engine/PGD.h index b6ebde4cad..81af267512 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -25,6 +25,7 @@ class PGDAttack Search for an adversarial example. Returns true if successful. */ bool hasAdversarialExample(); + double getAssignment( int index ); private: @@ -45,7 +46,7 @@ class PGDAttack Map _assignments; double *_adversarialInput; double *_adversarialOutput; - double getAssignment( int index ); + /* Iteratively generates and refines adversarial examples, aiming to discover inputs that lead to predictions outside the defined bounds, using gradient-based optimization. From 192b414ad5107234d41e6becfb9138c995b0805b Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 12 Nov 2024 12:01:31 +0200 Subject: [PATCH 47/69] timeout --- src/engine/Engine.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index b0d08cfc40..46baebbd8d 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1444,22 +1444,30 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - if ( _networkLevelReasoner && Options::RUN_ATTACK) + if ( _networkLevelReasoner && Options::RUN_ATTACK ) { - double timeoutForAttack = ( Options::ATTACK_TIMEOUT == 0 ? FloatUtils::infinity() : Options::ATTACK_TIMEOUT ); - ENGINE_LOG( Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); - ENGINE_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); + double timeoutForAttack = + ( Options::ATTACK_TIMEOUT == 0 ? FloatUtils::infinity() : Options::ATTACK_TIMEOUT ); + ENGINE_LOG( + Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); + ENGINE_LOG( + Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); + timespec _startTime = TimeUtils::sampleMicro(); - _pgdAttack = new PGDAttack(_networkLevelReasoner); - if ( _pgdAttack->hasAdversarialExample() ) + _pgdAttack = new PGDAttack( _networkLevelReasoner ); + if ( _pgdAttack->hasAdversarialExample() ) // todo how to exit with timeout in hasAdversarialExample { - ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); + ENGINE_LOG( + Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); _exitCode = Engine::SAT; _isAttackSuccessful = true; return false; } ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); - if ( shouldExitDueToTimeout( timeoutForAttack ) ) // todo change to time from attack starting time + unsigned long timePassed = + TimeUtils::timePassed( _startTime, TimeUtils::sampleMicro() ); + if ( static_cast( timePassed ) / MICROSECONDS_TO_SECONDS > + timeoutForAttack ) { if ( _verbosity > 0 ) { From 57d184504fdb858f41db75ea97c7448a8bb32b5c Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 12 Nov 2024 15:06:37 +0200 Subject: [PATCH 48/69] timeout --- src/engine/CustomDNN.cpp | 1 - src/engine/Engine.cpp | 45 +++++++++++++++------------------------ src/engine/MarabouError.h | 1 + src/engine/PGD.cpp | 23 +++++++++++++++++--- src/engine/PGD.h | 9 +++++--- 5 files changed, 44 insertions(+), 35 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 249ae5702b..e6cbfe50dc 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -122,7 +122,6 @@ CustomDNN::CustomDNN( const NLR::NetworkLevelReasoner *nlr ) default: CUSTOM_DNN_LOG( "Unsupported layer type\n" ); throw MarabouError( MarabouError::DEBUGGING_ERROR ); - break; } } } diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 46baebbd8d..ca1a488386 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1446,39 +1446,28 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) initializeNetworkLevelReasoning(); if ( _networkLevelReasoner && Options::RUN_ATTACK ) { - double timeoutForAttack = - ( Options::ATTACK_TIMEOUT == 0 ? FloatUtils::infinity() : Options::ATTACK_TIMEOUT ); - ENGINE_LOG( - Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); - ENGINE_LOG( - Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); - timespec _startTime = TimeUtils::sampleMicro(); - - _pgdAttack = new PGDAttack( _networkLevelReasoner ); - if ( _pgdAttack->hasAdversarialExample() ) // todo how to exit with timeout in hasAdversarialExample + try { + ENGINE_LOG( + Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); + timespec _startTime = TimeUtils::sampleMicro(); + + _pgdAttack = new PGDAttack( _networkLevelReasoner ); + if ( _pgdAttack->runAttack() ) + { + ENGINE_LOG( + Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); + _exitCode = Engine::SAT; + _isAttackSuccessful = true; + return false; + } ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); - _exitCode = Engine::SAT; - _isAttackSuccessful = true; - return false; } - ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); - unsigned long timePassed = - TimeUtils::timePassed( _startTime, TimeUtils::sampleMicro() ); - if ( static_cast( timePassed ) / MICROSECONDS_TO_SECONDS > - timeoutForAttack ) + catch ( MarabouError &e ) { - if ( _verbosity > 0 ) - { - printf( "\n\nEngine: quitting due to timeout...\n\n" ); - printf( "Final statistics:\n" ); - _statistics.print(); - } - - _exitCode = Engine::TIMEOUT; - _statistics.timeout(); - return false; + ENGINE_LOG( + Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); } } diff --git a/src/engine/MarabouError.h b/src/engine/MarabouError.h index d70269426a..ef92c0524b 100644 --- a/src/engine/MarabouError.h +++ b/src/engine/MarabouError.h @@ -53,6 +53,7 @@ class MarabouError : public Error BOUNDS_NOT_UP_TO_DATE_IN_LP_SOLVER = 28, INVALID_LEAKY_RELU_SLOPE = 29, UNABLE_TO_RECONSTRUCT_SOLUTION_FOR_ELIMINATED_NEURONS = 30, + TIMEOUT = 31, // Error codes for Query Loader FILE_DOES_NOT_EXIST = 100, diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index a1d41657e0..8838539477 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,5 +1,7 @@ #include "PGD.h" + #include "InputQuery.h" + #include PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) @@ -36,7 +38,9 @@ torch::Device PGDAttack::getDevice() void PGDAttack::getBounds( std::pair, Vector> &bounds, const signed type ) const { - unsigned layerIndex = type == GlobalConfiguration::PdgBoundType::PGD_INPUT ? 0 : networkLevelReasoner->getNumberOfLayers() - 1; + unsigned layerIndex = type == GlobalConfiguration::PdgBoundType::PGD_INPUT + ? 0 + : networkLevelReasoner->getNumberOfLayers() - 1; const NLR::Layer *layer = networkLevelReasoner->getLayer( layerIndex ); for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) @@ -144,6 +148,12 @@ torch::Tensor PGDAttack::calculateLoss( const torch::Tensor &predictions ) std::pair PGDAttack::findAdvExample() { + double timeoutForAttack = + ( Options::ATTACK_TIMEOUT == 0 ? FloatUtils::infinity() : Options::ATTACK_TIMEOUT ); + PGD_LOG( Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); + PGD_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); + timespec startTime = TimeUtils::sampleMicro(); + torch::Tensor currentExample = _inputExample; torch::Tensor currentPrediction; torch::Tensor lowerBoundTensor = @@ -151,8 +161,14 @@ std::pair PGDAttack::findAdvExample() torch::Tensor upperBoundTensor = torch::tensor( _inputBounds.second.data(), torch::kFloat32 ).to( _device ); torch::Tensor delta = torch::zeros( _inputSize ).to( _device ).requires_grad_( true ); + for ( unsigned i = 0; i < _restarts; ++i ) { + unsigned long timePassed = TimeUtils::timePassed( startTime, TimeUtils::sampleMicro() ); + if ( static_cast( timePassed ) / MICROSECONDS_TO_SECONDS > timeoutForAttack ) + { + throw MarabouError( MarabouError::TIMEOUT, "Attack failed due to timeout" ); + } torch::optim::Adam optimizer( { delta }, torch::optim::AdamOptions() ); for ( unsigned j = 0; j < _iters; ++j ) { @@ -181,7 +197,7 @@ double PGDAttack::getAssignment( int index ) return _assignments[index]; } -bool PGDAttack::hasAdversarialExample() +bool PGDAttack::runAttack() { PGD_LOG( "-----Starting PGD attack-----" ); auto adversarial = findAdvExample(); @@ -234,7 +250,8 @@ bool PGDAttack::hasAdversarialExample() if ( isFooled ) { PGD_LOG( "Model fooled: Yes \n ------ PGD Attack Succeed ------\n" ); - }else + } + else PGD_LOG( "Model fooled: No \n ------ PGD Attack Failed ------\n" ); diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 81af267512..299e2a30d5 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -2,13 +2,13 @@ #define __PGD_h__ #include "CustomDNN.h" +#include "Options.h" +#include #include "GlobalConfiguration.h" #undef Warning #include -constexpr unsigned DEFAULT_NUM_ITER = 100; -constexpr unsigned DEFAULT_NUM_RESTARTS = 3; #define PGD_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "PGD: %s\n", x ) /* @@ -20,11 +20,14 @@ constexpr unsigned DEFAULT_NUM_RESTARTS = 3; class PGDAttack { public: + enum { + MICROSECONDS_TO_SECONDS = 1000000, +}; PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ); /* Search for an adversarial example. Returns true if successful. */ - bool hasAdversarialExample(); + bool runAttack(); double getAssignment( int index ); From 31c32ebb9756618ce5b7bd4825320b7561071529 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 12 Nov 2024 15:21:15 +0200 Subject: [PATCH 49/69] timeout --- src/engine/Engine.cpp | 3 +-- src/engine/PGD.cpp | 5 +++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index ca1a488386..37f3b12a82 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1444,13 +1444,12 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - if ( _networkLevelReasoner && Options::RUN_ATTACK ) + if ( _networkLevelReasoner && Options::get()->getBool(( Options::PRODUCE_PROOFS ) )) { try { ENGINE_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); - timespec _startTime = TimeUtils::sampleMicro(); _pgdAttack = new PGDAttack( _networkLevelReasoner ); if ( _pgdAttack->runAttack() ) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 8838539477..88c51b26d7 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -148,8 +148,9 @@ torch::Tensor PGDAttack::calculateLoss( const torch::Tensor &predictions ) std::pair PGDAttack::findAdvExample() { - double timeoutForAttack = - ( Options::ATTACK_TIMEOUT == 0 ? FloatUtils::infinity() : Options::ATTACK_TIMEOUT ); + double timeoutForAttack = ( Options::get()->getInt( Options::ATTACK_TIMEOUT ) == 0 + ? FloatUtils::infinity() + : Options::get()->getInt( Options::ATTACK_TIMEOUT ) ); PGD_LOG( Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); PGD_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); timespec startTime = TimeUtils::sampleMicro(); From 1099e15ecd53bbb184c0057c471424a33b560a85 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Thu, 14 Nov 2024 13:43:16 +0200 Subject: [PATCH 50/69] CUSTOM_LOG --- src/engine/CustomDNN.cpp | 2 -- src/engine/CustomDNN.h | 3 +-- src/engine/PGD.cpp | 2 -- src/engine/PGD.h | 6 +++--- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index e6cbfe50dc..400fbfcbe0 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,6 +1,4 @@ #include "CustomDNN.h" - -#include "TimeUtils.h" #include "Vector.h" diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index d1e6688de8..bf39b024ac 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -4,10 +4,9 @@ #include "NetworkLevelReasoner.h" #include - +#define CUSTOM_DNN_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "customDNN: %s\n", x ) #undef Warning #include -#define CUSTOM_DNN_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "customDNN: %s\n", x ) /* Custom differentiation function for max pooling, implementing the forward and backward propagation for diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 88c51b26d7..eb89891f33 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,7 +1,5 @@ #include "PGD.h" - #include "InputQuery.h" - #include PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 299e2a30d5..32a1d578b3 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -2,14 +2,14 @@ #define __PGD_h__ #include "CustomDNN.h" -#include "Options.h" -#include #include "GlobalConfiguration.h" +#include "Options.h" +#include +#define PGD_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "PGD: %s\n", x ) #undef Warning #include -#define PGD_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "PGD: %s\n", x ) /* PGDAttack class implements the Projected Gradient Descent method for generating From f54b12fd908c999e3f142be7a921b027d8d321fa Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 25 Nov 2024 12:05:39 +0200 Subject: [PATCH 51/69] add build torch flag --- CMakeLists.txt | 6 ++-- src/configuration/OptionParser.cpp | 8 +++++ src/engine/CustomDNN.h | 5 ++-- src/engine/Engine.cpp | 47 ++++++++++++++++++------------ src/engine/Engine.h | 6 ++-- src/engine/PGD.h | 5 ++-- 6 files changed, 50 insertions(+), 27 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b1f81ee563..a89890b49a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,7 +23,7 @@ option(RUN_PYTHON_TEST "Run Python API tests if building with Python" OFF) option(ENABLE_GUROBI "Enable use the Gurobi optimizer" OFF) option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" OFF) # Not available on Windows option(CODE_COVERAGE "Add code coverage" OFF) # Available only in debug mode - +option(BUILD_TORCH "Build libtorch" OFF) ################### ## Git variables ## ################### @@ -151,7 +151,7 @@ include_directories(SYSTEM ${ONNX_DIR}) ############# ## Pytorch ## ############# - +if (${BUILD_TORCH}) set(PYTORCH_VERSION 2.2.1) message(STATUS "Hi 4") find_package(Torch ${PYTORCH_VERSION} QUIET) @@ -169,7 +169,7 @@ if (NOT Torch_FOUND) endif() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}") list(APPEND LIBS ${TORCH_LIBRARIES}) - +endif () ############ ## Gurobi ## ############ diff --git a/src/configuration/OptionParser.cpp b/src/configuration/OptionParser.cpp index cd94bbc394..58c95bb2b1 100644 --- a/src/configuration/OptionParser.cpp +++ b/src/configuration/OptionParser.cpp @@ -137,6 +137,14 @@ void OptionParser::initialize() boost::program_options::bool_switch( &( ( *_boolOptions )[Options::PRODUCE_PROOFS] ) ) ->default_value( ( *_boolOptions )[Options::PRODUCE_PROOFS] ), "Produce proofs of UNSAT and check them" ) +#ifdef BUILD_TORCH + ( + "run-attack", + boost::program_options::bool_switch( &( ( *_boolOptions )[Options::RUN_ATTACK] ) ) + ->default_value( ( *_boolOptions )[Options::RUN_ATTACK] ), + "Enable PGD adversarial attack run" ) +#endif + #ifdef ENABLE_GUROBI #endif // ENABLE_GUROBI ; diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index bf39b024ac..e54710d633 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -1,8 +1,8 @@ +#ifdef BUILD_TORCH #ifndef __CustomDNN_h__ #define __CustomDNN_h__ #include "NetworkLevelReasoner.h" - #include #define CUSTOM_DNN_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "customDNN: %s\n", x ) #undef Warning @@ -64,4 +64,5 @@ class CustomDNN : public torch::nn::Module }; -#endif // __CustomDNN_h__ \ No newline at end of file +#endif // __CustomDNN_h__ +#endif \ No newline at end of file diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 37f3b12a82..adf970e06c 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -35,9 +35,10 @@ #include "Vector.h" #include - +#ifdef BUILD_TORCH #undef Warning #include +#endif Engine::Engine() @@ -1444,30 +1445,35 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) if ( _verbosity > 1 ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); - if ( _networkLevelReasoner && Options::get()->getBool(( Options::PRODUCE_PROOFS ) )) - { - try + if ( _networkLevelReasoner ) + if ( Options::get()->getBool( ( Options::PRODUCE_PROOFS ) ) ) { - ENGINE_LOG( - Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); +#ifdef BUILD_TORCH + try + { + ENGINE_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ) + .ascii() ); - _pgdAttack = new PGDAttack( _networkLevelReasoner ); - if ( _pgdAttack->runAttack() ) + _pgdAttack = new PGDAttack( _networkLevelReasoner ); + if ( _pgdAttack->runAttack() ) + { + ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ) + .ascii() ); + _exitCode = Engine::SAT; + _isAttackSuccessful = true; + return false; + } + ENGINE_LOG( + Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); + } + catch ( MarabouError &e ) { ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); - _exitCode = Engine::SAT; - _isAttackSuccessful = true; - return false; } - ENGINE_LOG( - Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); - } - catch ( MarabouError &e ) - { - ENGINE_LOG( - Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); +#endif } + { } if ( preprocess ) @@ -1785,17 +1791,22 @@ void Engine::extractSolution( InputQuery &inputQuery, Preprocessor *preprocessor variable = preprocessorInUse->getNewIndex( variable ); // Finally, set the assigned value +#ifdef BUILD_TORCH + if ( _isAttackSuccessful ) inputQuery.setSolutionValue( i, _pgdAttack->getAssignment( variable ) ); else inputQuery.setSolutionValue( i, _tableau->getValue( variable ) ); +#endif } else { +#ifdef BUILD_TORCH if ( _isAttackSuccessful ) inputQuery.setSolutionValue( i, _pgdAttack->getAssignment( i ) ); else inputQuery.setSolutionValue( i, _tableau->getValue( i ) ); +#endif } } diff --git a/src/engine/Engine.h b/src/engine/Engine.h index bf16ac56c5..79345be187 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -538,8 +538,10 @@ class Engine LinearExpression _heuristicCost; - PGDAttack *_pgdAttack; - bool _isAttackSuccessful = false; +#ifdef BUILD_TORCH + PGDAttack *_pgdAttack; + bool _isAttackSuccessful = false; +#endif /* Perform a simplex step: compute the cost function, pick the diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 32a1d578b3..62024761fb 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -1,6 +1,6 @@ +#ifdef BUILD_TORCH #ifndef __PGD_h__ #define __PGD_h__ - #include "CustomDNN.h" #include "GlobalConfiguration.h" #include "Options.h" @@ -79,4 +79,5 @@ class PGDAttack }; -#endif // __PGD_h__ +#endif +#endif \ No newline at end of file From 4e0b69d40f53be814910229801c5bf2ae55e0085 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 26 Nov 2024 17:32:09 +0200 Subject: [PATCH 52/69] ADD #ifdef BUILD_TORCH --- src/engine/CustomDNN.cpp | 5 +++-- src/engine/PGD.cpp | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 400fbfcbe0..6fe4f37bf1 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -1,6 +1,6 @@ #include "CustomDNN.h" #include "Vector.h" - +#ifdef BUILD_TORCH CustomMaxPool::CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) : _networkLevelReasoner( nlr ) @@ -221,4 +221,5 @@ std::vector CustomMaxPoolFunction::backward( torch::autograd::Aut const Vector& CustomDNN::getLayerSizes() const { return _layerSizes; -} \ No newline at end of file +} +#endif \ No newline at end of file diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index eb89891f33..5cbd4bc734 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,7 +1,7 @@ #include "PGD.h" #include "InputQuery.h" #include - +#ifdef BUILD_TORCH PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) : networkLevelReasoner( networkLevelReasoner ) , _device( torch::kCPU ) @@ -259,3 +259,4 @@ bool PGDAttack::runAttack() return isFooled; } +#endif \ No newline at end of file From 6b6711e4b98e8468bd0760fd8bcf0637c7882337 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 26 Nov 2024 17:43:07 +0200 Subject: [PATCH 53/69] CMakeLists.txt --- CMakeLists.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a89890b49a..3910fbba2f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required (VERSION 3.12) +cmake_minimum_required (VERSION 3.16) project(Marabou) set(MARABOU_VERSION 2.0.0) @@ -83,7 +83,7 @@ include_directories(SYSTEM ${CVC4_DIR} ${CVC4_DIR}/include) # Avoid using deprecated operations add_definitions(-DBOOST_NO_CXX98_FUNCTION_BASE) -set(BOOST_VERSION 1.67.0) +set(BOOST_VERSION 1.84.0) set(BOOST_DIR "${TOOLS_DIR}/boost-${BOOST_VERSION}") if (MSVC) set(BOOST_ROOT "${BOOST_DIR}/win_installed") @@ -182,7 +182,7 @@ if (${ENABLE_GUROBI}) add_compile_definitions(ENABLE_GUROBI) set(GUROBI_LIB1 "gurobi_c++") - set(GUROBI_LIB2 "gurobi95") + set(GUROBI_LIB2 "gurobi110") add_library(${GUROBI_LIB1} SHARED IMPORTED) set_target_properties(${GUROBI_LIB1} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi_c++.a) @@ -193,9 +193,9 @@ if (${ENABLE_GUROBI}) # MACOSx uses .dylib instead of .so for its Gurobi downloads. if (APPLE) - set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi95.dylib) + set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi110.dylib) else() - set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi95.so) + set_target_properties(${GUROBI_LIB2} PROPERTIES IMPORTED_LOCATION ${GUROBI_DIR}/lib/libgurobi110.so) endif () list(APPEND LIBS ${GUROBI_LIB2}) From 18f367d9af35b0bd5cfd1866d89cd620b4e8caac Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 26 Nov 2024 17:43:27 +0200 Subject: [PATCH 54/69] CMakeLists.txt --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3910fbba2f..40bd26491d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ option(RUN_SYSTEM_TEST "Run system tests on build" OFF) option(RUN_MEMORY_TEST "Run cxxtest testing with ASAN ON" ON) option(RUN_PYTHON_TEST "Run Python API tests if building with Python" OFF) option(ENABLE_GUROBI "Enable use the Gurobi optimizer" OFF) -option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" OFF) # Not available on Windows +option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" ON) # Not available on Windows option(CODE_COVERAGE "Add code coverage" OFF) # Available only in debug mode option(BUILD_TORCH "Build libtorch" OFF) ################### From 105a76930cc1759cf34b47c95b93a5efe6eed849 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 26 Nov 2024 17:48:32 +0200 Subject: [PATCH 55/69] CMakeLists.txt --- CMakeLists.txt | 3 --- 1 file changed, 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 40bd26491d..3dd3e3ca5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,7 +7,6 @@ add_definitions("-DMARABOU_VERSION=\"${MARABOU_VERSION}\"") set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD_REQUIRED ON) - ################## ## User options ## ################## @@ -351,8 +350,6 @@ target_compile_options(${MARABOU_LIB} PRIVATE ${RELEASE_FLAGS}) target_link_libraries(${MARABOU_EXE} ${MARABOU_LIB}) target_include_directories(${MARABOU_EXE} PRIVATE ${LIBS_INCLUDES}) - - ###################### ## Build Python API ## ###################### From 42cc2f637e17541481d7451b95c34ab6cda450dd Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 26 Nov 2024 17:49:24 +0200 Subject: [PATCH 56/69] CMakeLists.txt BUILD_TORCH ON --- CMakeLists.txt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 3dd3e3ca5a..aad7933eb5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ option(RUN_PYTHON_TEST "Run Python API tests if building with Python" OFF) option(ENABLE_GUROBI "Enable use the Gurobi optimizer" OFF) option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" ON) # Not available on Windows option(CODE_COVERAGE "Add code coverage" OFF) # Available only in debug mode -option(BUILD_TORCH "Build libtorch" OFF) +option(BUILD_TORCH "Build libtorch" ON) ################### ## Git variables ## ################### @@ -103,7 +103,6 @@ endif() set(LIBS_INCLUDES ${Boost_INCLUDE_DIRS}) list(APPEND LIBS ${Boost_LIBRARIES}) - ############## ## Protobuf ## ############## From a5a6ff6a770d43bfb7eb210e26ae8a2f97bdfb60 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Fri, 6 Dec 2024 10:10:25 +0200 Subject: [PATCH 57/69] CMakeLists.txt : set(TORCH_CXX_FLAGS "-Wno-error=array-bounds") fix ATTACK_LOG, call attack --- CMakeLists.txt | 37 +++++++++++++++++++---------------- src/configuration/Options.cpp | 2 +- src/engine/Engine.cpp | 2 +- src/engine/Marabou.cpp | 9 +++++---- src/engine/PGD.cpp | 4 ++-- 5 files changed, 29 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index aad7933eb5..24191db76b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,7 +20,7 @@ option(RUN_SYSTEM_TEST "Run system tests on build" OFF) option(RUN_MEMORY_TEST "Run cxxtest testing with ASAN ON" ON) option(RUN_PYTHON_TEST "Run Python API tests if building with Python" OFF) option(ENABLE_GUROBI "Enable use the Gurobi optimizer" OFF) -option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" ON) # Not available on Windows +option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" OFF) # Not available on Windows option(CODE_COVERAGE "Add code coverage" OFF) # Available only in debug mode option(BUILD_TORCH "Build libtorch" ON) ################### @@ -149,24 +149,27 @@ include_directories(SYSTEM ${ONNX_DIR}) ############# ## Pytorch ## ############# + if (${BUILD_TORCH}) -set(PYTORCH_VERSION 2.2.1) -message(STATUS "Hi 4") -find_package(Torch ${PYTORCH_VERSION} QUIET) -message(STATUS "Hi 1") -if (NOT Torch_FOUND) - message(STATUS "Hi 2") - set(PYTORCH_DIR "${TOOLS_DIR}/libtorch-${PYTORCH_VERSION}") - list(APPEND CMAKE_PREFIX_PATH ${PYTORCH_DIR}) - if(NOT EXISTS "${PYTORCH_DIR}") - message(STATUS "Hi 5") - execute_process(COMMAND ${TOOLS_DIR}/download_libtorch.sh ${PYTORCH_VERSION}) + message(STATUS "Using pytorch") + if (NOT DEFINED BUILD_TORCH) + set(BUILD_TORCH $ENV{TORCH_HOME}) endif() - set(Torch_DIR ${PYTORCH_DIR}/share/cmake/Torch) - find_package(Torch ${PYTORCH_VERSION} REQUIRED) -endif() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}") -list(APPEND LIBS ${TORCH_LIBRARIES}) + add_compile_definitions(BUILD_TORCH) + set(PYTORCH_VERSION 2.2.1) + find_package(Torch ${PYTORCH_VERSION} QUIET) + if (NOT Torch_FOUND) + set(PYTORCH_DIR "${TOOLS_DIR}/libtorch-${PYTORCH_VERSION}") + list(APPEND CMAKE_PREFIX_PATH ${PYTORCH_DIR}) + if(NOT EXISTS "${PYTORCH_DIR}") + execute_process(COMMAND ${TOOLS_DIR}/download_libtorch.sh ${PYTORCH_VERSION}) + endif() + set(Torch_DIR ${PYTORCH_DIR}/share/cmake/Torch) + find_package(Torch ${PYTORCH_VERSION} REQUIRED) + endif() + set(TORCH_CXX_FLAGS "-Wno-error=array-bounds") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${TORCH_CXX_FLAGS}") + list(APPEND LIBS ${TORCH_LIBRARIES}) endif () ############ ## Gurobi ## diff --git a/src/configuration/Options.cpp b/src/configuration/Options.cpp index 3e1bf24140..138352f824 100644 --- a/src/configuration/Options.cpp +++ b/src/configuration/Options.cpp @@ -55,7 +55,7 @@ void Options::initializeDefaultValues() _boolOptions[DEBUG_ASSIGNMENT] = false; _boolOptions[PRODUCE_PROOFS] = false; _boolOptions[DO_NOT_MERGE_CONSECUTIVE_WEIGHTED_SUM_LAYERS] = false; - _boolOptions[RUN_ATTACK] = false; // todo? + _boolOptions[RUN_ATTACK] = true; // todo? /* diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index adf970e06c..efca7ba06b 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1446,7 +1446,7 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); if ( _networkLevelReasoner ) - if ( Options::get()->getBool( ( Options::PRODUCE_PROOFS ) ) ) + if ( Options::get()->getBool( ( Options::RUN_ATTACK ) ) ) { #ifdef BUILD_TORCH try diff --git a/src/engine/Marabou.cpp b/src/engine/Marabou.cpp index d321da66ac..687bdac54f 100644 --- a/src/engine/Marabou.cpp +++ b/src/engine/Marabou.cpp @@ -222,12 +222,13 @@ void Marabou::solveQuery() struct timespec start = TimeUtils::sampleMicro(); unsigned timeoutInSeconds = Options::get()->getInt( Options::TIMEOUT ); - if (_engine->getExitCode() == Engine::ATTACK_SAT) - { - return; - } + if ( _engine->processInputQuery( _inputQuery ) ) { + if (_engine->getExitCode() == Engine::ATTACK_SAT) + { + return; + } _engine->solve( timeoutInSeconds ); if ( _engine->shouldProduceProofs() && _engine->getExitCode() == Engine::UNSAT ) _engine->certifyUNSATCertificate(); diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 5cbd4bc734..7be669782b 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -227,7 +227,7 @@ bool PGDAttack::runAttack() PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); PGD_LOG( "Adversarial Input:\n" ); - std::cout << "Adversarial Input: \n"; + PGD_LOG( "Adversarial Input: \n"); for ( int i = 0; i < advInput.numel(); ++i ) { PGD_LOG( "x%u=%.3lf", i, example[i] ); @@ -239,7 +239,7 @@ bool PGDAttack::runAttack() for ( auto &bound : _outputBounds.second.getContainer() ) PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); - std::cout << "Adversarial Prediction: \n"; + PGD_LOG( "Adversarial Prediction: \n"); for ( int i = 0; i < advPred.numel(); ++i ) { PGD_LOG( "y%u=%.3lf", i, prediction[i] ); From 174bb45017115ca548610536b0011594d2f1e946 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Fri, 6 Dec 2024 12:27:54 +0200 Subject: [PATCH 58/69] change PGD logging --- CMakeLists.txt | 1 + src/configuration/GlobalConfiguration.h | 2 +- src/engine/PGD.cpp | 41 ++++++++++++++++--------- src/engine/PGD.h | 7 +++-- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 24191db76b..f518105175 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -154,6 +154,7 @@ if (${BUILD_TORCH}) message(STATUS "Using pytorch") if (NOT DEFINED BUILD_TORCH) set(BUILD_TORCH $ENV{TORCH_HOME}) + add_definitions(-DBUILD_TORCH) endif() add_compile_definitions(BUILD_TORCH) set(PYTORCH_VERSION 2.2.1) diff --git a/src/configuration/GlobalConfiguration.h b/src/configuration/GlobalConfiguration.h index b2a83d4cb7..01fc927102 100644 --- a/src/configuration/GlobalConfiguration.h +++ b/src/configuration/GlobalConfiguration.h @@ -297,7 +297,7 @@ class GlobalConfiguration static const bool SCORE_TRACKER_LOGGING; static const bool CEGAR_LOGGING; static const bool CUSTOM_DNN_LOGGING; - static const bool PGD_LOG; + static const bool PGD_LOGGING; }; #endif // __GlobalConfiguration_h__ diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 7be669782b..c487ba274a 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,6 +1,6 @@ #include "PGD.h" #include "InputQuery.h" -#include +#include #ifdef BUILD_TORCH PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) : networkLevelReasoner( networkLevelReasoner ) @@ -196,6 +196,20 @@ double PGDAttack::getAssignment( int index ) return _assignments[index]; } +void PGDAttack::printValue(double value) { + if (std::isinf(value)) { + if (value < 0) { + PGD_LOG("-inf"); + } else { + PGD_LOG("inf"); + } + } else if (std::isnan(value)) { + PGD_LOG("nan"); + } else { + PGD_LOG(Stringf("%.3lf", value).ascii()); + } +} + bool PGDAttack::runAttack() { PGD_LOG( "-----Starting PGD attack-----" ); @@ -219,30 +233,29 @@ bool PGDAttack::runAttack() std::copy( example, example + _inputSize, _adversarialInput ); std::copy( prediction, prediction + outputSize, _adversarialOutput ); } - PGD_LOG( "Input Lower Bounds : \n" ); + PGD_LOG( "Input Lower Bounds : " ); for ( auto &bound : _inputBounds.first.getContainer() ) - PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); - PGD_LOG( "Input Upper Bounds : \n" ); + printValue(bound); + PGD_LOG( "Input Upper Bounds : " ); for ( auto &bound : _inputBounds.second.getContainer() ) - PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); + printValue(bound); - PGD_LOG( "Adversarial Input:\n" ); - PGD_LOG( "Adversarial Input: \n"); + PGD_LOG( "Adversarial Input:" ); for ( int i = 0; i < advInput.numel(); ++i ) { - PGD_LOG( "x%u=%.3lf", i, example[i] ); + PGD_LOG( Stringf("x%u=%.3lf", i, example[i] ).ascii()); } - PGD_LOG( "Output Lower Bounds : \n" ); + PGD_LOG( "Output Lower Bounds : " ); for ( auto &bound : _outputBounds.first.getContainer() ) - PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); - PGD_LOG( "Output Upper Bounds : \n" ); + printValue(bound); + PGD_LOG( "Output Upper Bounds : " ); for ( auto &bound : _outputBounds.second.getContainer() ) - PGD_LOG( Stringf( "%.3lf", bound ).ascii() ); + printValue(bound); - PGD_LOG( "Adversarial Prediction: \n"); + PGD_LOG( "Adversarial Prediction: "); for ( int i = 0; i < advPred.numel(); ++i ) { - PGD_LOG( "y%u=%.3lf", i, prediction[i] ); + PGD_LOG( Stringf("y%u=%.3lf", i, prediction[i] ).ascii()); } diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 62024761fb..c221c62daa 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -20,9 +20,9 @@ class PGDAttack { public: - enum { - MICROSECONDS_TO_SECONDS = 1000000, -}; + enum { + MICROSECONDS_TO_SECONDS = 1000000, + }; PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ); /* Search for an adversarial example. Returns true if successful. @@ -76,6 +76,7 @@ class PGDAttack */ torch::Tensor calculateLoss( const torch::Tensor &predictions ); static torch::Device getDevice(); + static void printValue( double value ); }; From 7f4565cc687497b34393c8a555a88c3afda5faf8 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Fri, 6 Dec 2024 12:28:31 +0200 Subject: [PATCH 59/69] ENGINE_LOGGING, CUSTOM_DNN_LOGGING, PGD_LOG=true --- src/configuration/GlobalConfiguration.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/configuration/GlobalConfiguration.cpp b/src/configuration/GlobalConfiguration.cpp index 1f2502a8da..e03902f955 100644 --- a/src/configuration/GlobalConfiguration.cpp +++ b/src/configuration/GlobalConfiguration.cpp @@ -130,7 +130,7 @@ const bool GlobalConfiguration::GUROBI_LOGGING = false; // Logging - note that it is enabled only in Debug mode const bool GlobalConfiguration::DNC_MANAGER_LOGGING = false; -const bool GlobalConfiguration::ENGINE_LOGGING = false; +const bool GlobalConfiguration::ENGINE_LOGGING = true; const bool GlobalConfiguration::TABLEAU_LOGGING = false; const bool GlobalConfiguration::SMT_CORE_LOGGING = false; const bool GlobalConfiguration::DANTZIGS_RULE_LOGGING = false; @@ -147,8 +147,8 @@ const bool GlobalConfiguration::ONNX_PARSER_LOGGING = false; const bool GlobalConfiguration::SOI_LOGGING = false; const bool GlobalConfiguration::SCORE_TRACKER_LOGGING = false; const bool GlobalConfiguration::CEGAR_LOGGING = false; -const bool GlobalConfiguration::CUSTOM_DNN_LOGGING = false; -const bool GlobalConfiguration::PGD_LOG = false; +const bool GlobalConfiguration::CUSTOM_DNN_LOGGING = true; +const bool GlobalConfiguration::PGD_LOGGING = true; const bool GlobalConfiguration::USE_SMART_FIX = false; const bool GlobalConfiguration::USE_LEAST_FIX = false; From 46011cf596c7add319871f1640e890ab40e51e64 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 11 Dec 2024 09:28:46 +0200 Subject: [PATCH 60/69] change model in PGD to std::unique_ptr _model. change PGDAttack *_pgdAttac in ENgine to std::unique_ptr --- src/engine/CustomDNN.cpp | 12 ++++++------ src/engine/Engine.cpp | 5 +++-- src/engine/Engine.h | 2 +- src/engine/PGD.cpp | 8 ++++---- src/engine/PGD.h | 2 +- 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 6fe4f37bf1..125665f02b 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -14,10 +14,10 @@ torch::Tensor CustomMaxPool::forward( torch::Tensor x ) const } void CustomDNN::setWeightsAndBiases( torch::nn::Linear &linearLayer, - const NLR::Layer *layer, - unsigned sourceLayer, - unsigned inputSize, - unsigned outputSize ) + const NLR::Layer *layer, + unsigned sourceLayer, + unsigned inputSize, + unsigned outputSize ) { Vector> layerWeights( outputSize, Vector( inputSize ) ); Vector layerBiases( outputSize ); @@ -73,7 +73,7 @@ void CustomDNN::weightedSum( unsigned i, const NLR::Layer *layer ) CustomDNN::CustomDNN( const NLR::NetworkLevelReasoner *nlr ) { - CUSTOM_DNN_LOG("----- Construct Custom Network -----" ); + CUSTOM_DNN_LOG( "----- Construct Custom Network -----" ); _networkLevelReasoner = nlr; _numberOfLayers = _networkLevelReasoner->getNumberOfLayers(); for ( unsigned i = 0; i < _numberOfLayers; i++ ) @@ -218,7 +218,7 @@ std::vector CustomMaxPoolFunction::backward( torch::autograd::Aut return { grad_input, torch::Tensor(), torch::Tensor() }; } -const Vector& CustomDNN::getLayerSizes() const +const Vector &CustomDNN::getLayerSizes() const { return _layerSizes; } diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index efca7ba06b..e3308d69a8 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -75,6 +75,7 @@ Engine::Engine() , _milpSolverBoundTighteningType( Options::get()->getMILPSolverBoundTighteningType() ) , _sncMode( false ) , _queryId( "" ) + , _pgdAttack( nullptr ) , _produceUNSATProofs( Options::get()->getBool( Options::PRODUCE_PROOFS ) ) , _groundBoundManager( _context ) , _UNSATCertificate( NULL ) @@ -1454,7 +1455,7 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) ENGINE_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ) .ascii() ); - _pgdAttack = new PGDAttack( _networkLevelReasoner ); + _pgdAttack = std::make_unique( _networkLevelReasoner ); if ( _pgdAttack->runAttack() ) { ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ) @@ -1469,7 +1470,7 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) catch ( MarabouError &e ) { ENGINE_LOG( - Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); + Stringf( "Error, Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); } #endif } diff --git a/src/engine/Engine.h b/src/engine/Engine.h index 79345be187..ae623e05e5 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -539,7 +539,7 @@ class Engine LinearExpression _heuristicCost; #ifdef BUILD_TORCH - PGDAttack *_pgdAttack; + std::unique_ptr_pgdAttack; bool _isAttackSuccessful = false; #endif diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index c487ba274a..6209f2b676 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -5,13 +5,13 @@ PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) : networkLevelReasoner( networkLevelReasoner ) , _device( torch::kCPU ) - , _model( CustomDNN( networkLevelReasoner ) ) + , _model( std::make_unique( networkLevelReasoner ) ) , _iters( GlobalConfiguration::PGD_DEFAULT_NUM_ITER ) , _restarts( GlobalConfiguration::PGD_NUM_RESTARTS ) , _adversarialInput( nullptr ) , _adversarialOutput( nullptr ) { - _inputSize = _model.getLayerSizes().first(); + _inputSize = _model->getLayerSizes().first(); getBounds( _inputBounds, GlobalConfiguration::PdgBoundType::PGD_INPUT ); getBounds( _outputBounds, GlobalConfiguration::PdgBoundType::PGD_OUTPUT ); std::pair variables = generateSampleAndEpsilon(); @@ -172,7 +172,7 @@ std::pair PGDAttack::findAdvExample() for ( unsigned j = 0; j < _iters; ++j ) { currentExample = currentExample + delta; - currentPrediction = _model.forward( currentExample ); + currentPrediction = _model->forward( currentExample ); if ( isWithinBounds( currentPrediction, _outputBounds ) ) { return { currentExample, currentPrediction }; @@ -223,7 +223,7 @@ bool PGDAttack::runAttack() auto *example = advInput.data_ptr(); auto *prediction = advPred.data_ptr(); size_t outputSize = advPred.size( 1 ); - ASSERT( advInput.size( 1 ) == _inputSize && outputSize == _model.getLayerSizes().last() ); + ASSERT( advInput.size( 1 ) == _inputSize && outputSize == _model->getLayerSizes().last() ); if ( isFooled ) { diff --git a/src/engine/PGD.h b/src/engine/PGD.h index c221c62daa..9fa55118ef 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -40,7 +40,7 @@ class PGDAttack */ torch::Tensor _epsilon; torch::Tensor _inputExample; - CustomDNN _model; + std::unique_ptr _model; unsigned _iters; unsigned _restarts; unsigned _inputSize; From 58723cc0e98c8c8f63a084dfe9e7a0f1a1156d49 Mon Sep 17 00:00:00 2001 From: idan0610 Date: Mon, 16 Dec 2024 13:50:49 +0200 Subject: [PATCH 61/69] Fix memory leak + change default for running pgd attack to false --- src/configuration/Options.cpp | 2 +- src/engine/Engine.cpp | 4 +-- src/engine/PGD.cpp | 53 ++++++++++++++++++++++++----------- src/engine/PGD.h | 2 ++ 4 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/configuration/Options.cpp b/src/configuration/Options.cpp index 138352f824..946dcc1364 100644 --- a/src/configuration/Options.cpp +++ b/src/configuration/Options.cpp @@ -55,7 +55,7 @@ void Options::initializeDefaultValues() _boolOptions[DEBUG_ASSIGNMENT] = false; _boolOptions[PRODUCE_PROOFS] = false; _boolOptions[DO_NOT_MERGE_CONSECUTIVE_WEIGHTED_SUM_LAYERS] = false; - _boolOptions[RUN_ATTACK] = true; // todo? + _boolOptions[RUN_ATTACK] = false; /* diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index e3308d69a8..6b4eb9a3eb 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1447,9 +1447,9 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) printInputBounds( inputQuery ); initializeNetworkLevelReasoning(); if ( _networkLevelReasoner ) +#ifdef BUILD_TORCH if ( Options::get()->getBool( ( Options::RUN_ATTACK ) ) ) { -#ifdef BUILD_TORCH try { ENGINE_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ) @@ -1472,8 +1472,8 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) ENGINE_LOG( Stringf( "Error, Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); } -#endif } +#endif { } diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 6209f2b676..04bb75a085 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -1,5 +1,7 @@ #include "PGD.h" + #include "InputQuery.h" + #include #ifdef BUILD_TORCH PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) @@ -19,6 +21,14 @@ PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) _epsilon = variables.second; } +PGDAttack::~PGDAttack() +{ + if ( _adversarialInput ) + delete[] _adversarialInput; + if ( _adversarialOutput ) + delete[] _adversarialOutput; +} + torch::Device PGDAttack::getDevice() { if ( torch::cuda::is_available() ) @@ -196,17 +206,26 @@ double PGDAttack::getAssignment( int index ) return _assignments[index]; } -void PGDAttack::printValue(double value) { - if (std::isinf(value)) { - if (value < 0) { - PGD_LOG("-inf"); - } else { - PGD_LOG("inf"); +void PGDAttack::printValue( double value ) +{ + if ( std::isinf( value ) ) + { + if ( value < 0 ) + { + PGD_LOG( "-inf" ); } - } else if (std::isnan(value)) { - PGD_LOG("nan"); - } else { - PGD_LOG(Stringf("%.3lf", value).ascii()); + else + { + PGD_LOG( "inf" ); + } + } + else if ( std::isnan( value ) ) + { + PGD_LOG( "nan" ); + } + else + { + PGD_LOG( Stringf( "%.3lf", value ).ascii() ); } } @@ -235,27 +254,27 @@ bool PGDAttack::runAttack() } PGD_LOG( "Input Lower Bounds : " ); for ( auto &bound : _inputBounds.first.getContainer() ) - printValue(bound); + printValue( bound ); PGD_LOG( "Input Upper Bounds : " ); for ( auto &bound : _inputBounds.second.getContainer() ) - printValue(bound); + printValue( bound ); PGD_LOG( "Adversarial Input:" ); for ( int i = 0; i < advInput.numel(); ++i ) { - PGD_LOG( Stringf("x%u=%.3lf", i, example[i] ).ascii()); + PGD_LOG( Stringf( "x%u=%.3lf", i, example[i] ).ascii() ); } PGD_LOG( "Output Lower Bounds : " ); for ( auto &bound : _outputBounds.first.getContainer() ) - printValue(bound); + printValue( bound ); PGD_LOG( "Output Upper Bounds : " ); for ( auto &bound : _outputBounds.second.getContainer() ) - printValue(bound); + printValue( bound ); - PGD_LOG( "Adversarial Prediction: "); + PGD_LOG( "Adversarial Prediction: " ); for ( int i = 0; i < advPred.numel(); ++i ) { - PGD_LOG( Stringf("y%u=%.3lf", i, prediction[i] ).ascii()); + PGD_LOG( Stringf( "y%u=%.3lf", i, prediction[i] ).ascii() ); } diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 9fa55118ef..58d55bb09b 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -24,6 +24,8 @@ class PGDAttack MICROSECONDS_TO_SECONDS = 1000000, }; PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ); + ~PGDAttack(); + /* Search for an adversarial example. Returns true if successful. */ From 36d5b710bd9cc2bf3517798159ed219a057dc55d Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 16 Dec 2024 16:01:40 +0200 Subject: [PATCH 62/69] remove vscode files , Marabou_LOG to LOG , sources.popBack(); in CustomDNN.cpp, ATTACK_SAT to SAT, --- .vscode/launch.json | 7 -- .vscode/settings.json | 99 ------------------- CMakeLists.txt | 2 +- src/basis_factorization/GaussianEliminator.h | 2 +- src/basis_factorization/LUFactorization.h | 2 +- .../SparseFTFactorization.h | 2 +- .../SparseGaussianEliminator.h | 2 +- .../SparseLUFactorization.h | 2 +- src/cegar/IncrementalLinearization.h | 2 +- src/common/Debug.h | 6 +- src/configuration/GlobalConfiguration.cpp | 2 +- src/configuration/Options.cpp | 2 +- src/engine/CDSmtCore.h | 2 +- src/engine/CustomDNN.cpp | 2 +- src/engine/CustomDNN.h | 22 +++-- src/engine/DantzigsRule.h | 2 +- src/engine/DnCManager.h | 2 +- src/engine/Engine.cpp | 14 +-- src/engine/Engine.h | 7 +- src/engine/IEngine.h | 1 - src/engine/InputQuery.cpp | 2 +- src/engine/Marabou.cpp | 10 +- src/engine/PGD.h | 8 +- src/engine/PLConstraintScoreTracker.h | 2 +- src/engine/ProjectedSteepestEdge.h | 2 +- src/engine/SmtCore.h | 2 +- src/engine/SumOfInfeasibilitiesManager.h | 2 +- src/engine/Tableau.h | 2 +- src/input_parsers/MpsParser.h | 2 +- src/input_parsers/OnnxParser.h | 2 +- src/nlr/IterativePropagator.h | 2 +- src/nlr/LPFormulator.h | 2 +- src/nlr/NetworkLevelReasoner.cpp | 2 +- src/query_loader/QueryLoader.h | 2 +- 34 files changed, 57 insertions(+), 167 deletions(-) delete mode 100644 .vscode/launch.json delete mode 100644 .vscode/settings.json diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 5c7247b40a..0000000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - // Use IntelliSense to learn about possible attributes. - // Hover to view descriptions of existing attributes. - // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [] -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index 1b10435680..0000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,99 +0,0 @@ -{ - "files.associations": { - "cctype": "cpp", - "clocale": "cpp", - "cmath": "cpp", - "csetjmp": "cpp", - "csignal": "cpp", - "cstdarg": "cpp", - "cstddef": "cpp", - "cstdio": "cpp", - "cstdlib": "cpp", - "cstring": "cpp", - "ctime": "cpp", - "cwchar": "cpp", - "cwctype": "cpp", - "*.ipp": "cpp", - "any": "cpp", - "array": "cpp", - "atomic": "cpp", - "strstream": "cpp", - "barrier": "cpp", - "bit": "cpp", - "*.tcc": "cpp", - "bitset": "cpp", - "cfenv": "cpp", - "charconv": "cpp", - "chrono": "cpp", - "cinttypes": "cpp", - "codecvt": "cpp", - "compare": "cpp", - "complex": "cpp", - "concepts": "cpp", - "condition_variable": "cpp", - "coroutine": "cpp", - "cstdint": "cpp", - "deque": "cpp", - "forward_list": "cpp", - "list": "cpp", - "map": "cpp", - "set": "cpp", - "string": "cpp", - "unordered_map": "cpp", - "unordered_set": "cpp", - "vector": "cpp", - "exception": "cpp", - "expected": "cpp", - "algorithm": "cpp", - "functional": "cpp", - "iterator": "cpp", - "memory": "cpp", - "memory_resource": "cpp", - "numeric": "cpp", - "optional": "cpp", - "random": "cpp", - "ratio": "cpp", - "regex": "cpp", - "source_location": "cpp", - "string_view": "cpp", - "system_error": "cpp", - "tuple": "cpp", - "type_traits": "cpp", - "utility": "cpp", - "rope": "cpp", - "slist": "cpp", - "format": "cpp", - "fstream": "cpp", - "future": "cpp", - "initializer_list": "cpp", - "iomanip": "cpp", - "iosfwd": "cpp", - "iostream": "cpp", - "istream": "cpp", - "latch": "cpp", - "limits": "cpp", - "mutex": "cpp", - "new": "cpp", - "numbers": "cpp", - "ostream": "cpp", - "ranges": "cpp", - "scoped_allocator": "cpp", - "semaphore": "cpp", - "shared_mutex": "cpp", - "span": "cpp", - "spanstream": "cpp", - "sstream": "cpp", - "stacktrace": "cpp", - "stdexcept": "cpp", - "stdfloat": "cpp", - "stop_token": "cpp", - "streambuf": "cpp", - "syncstream": "cpp", - "thread": "cpp", - "typeindex": "cpp", - "typeinfo": "cpp", - "valarray": "cpp", - "variant": "cpp" - }, - "C_Cpp.errorSquiggles": "disabled" -} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index f518105175..9358365ca6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -22,7 +22,7 @@ option(RUN_PYTHON_TEST "Run Python API tests if building with Python" OFF) option(ENABLE_GUROBI "Enable use the Gurobi optimizer" OFF) option(ENABLE_OPENBLAS "Do symbolic bound tighting using blas" OFF) # Not available on Windows option(CODE_COVERAGE "Add code coverage" OFF) # Available only in debug mode -option(BUILD_TORCH "Build libtorch" ON) +option(BUILD_TORCH "Build libtorch" OFF) ################### ## Git variables ## ################### diff --git a/src/basis_factorization/GaussianEliminator.h b/src/basis_factorization/GaussianEliminator.h index 6f93605ff6..2177021e55 100644 --- a/src/basis_factorization/GaussianEliminator.h +++ b/src/basis_factorization/GaussianEliminator.h @@ -19,7 +19,7 @@ #include "LUFactors.h" #define GAUSSIAN_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "GaussianEliminator: %s\n", x ) + LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "GaussianEliminator: %s\n", x ) class GaussianEliminator { diff --git a/src/basis_factorization/LUFactorization.h b/src/basis_factorization/LUFactorization.h index ae4befd5e7..400d53eb88 100644 --- a/src/basis_factorization/LUFactorization.h +++ b/src/basis_factorization/LUFactorization.h @@ -22,7 +22,7 @@ #include "List.h" #define LU_FACTORIZATION_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "LUFactorization: %s\n", x ) + LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "LUFactorization: %s\n", x ) class EtaMatrix; class LPElement; diff --git a/src/basis_factorization/SparseFTFactorization.h b/src/basis_factorization/SparseFTFactorization.h index b885cab4b2..906f5b205e 100644 --- a/src/basis_factorization/SparseFTFactorization.h +++ b/src/basis_factorization/SparseFTFactorization.h @@ -24,7 +24,7 @@ #include "Statistics.h" #define SFTF_FACTORIZATION_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseFTFactorization: %s\n", x ) + LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseFTFactorization: %s\n", x ) /* This class performs a sparse FT factorization of a given matrix. diff --git a/src/basis_factorization/SparseGaussianEliminator.h b/src/basis_factorization/SparseGaussianEliminator.h index fd6a061dce..48078b42d9 100644 --- a/src/basis_factorization/SparseGaussianEliminator.h +++ b/src/basis_factorization/SparseGaussianEliminator.h @@ -23,7 +23,7 @@ #include "Statistics.h" #define SGAUSSIAN_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "SparseGaussianEliminator: %s\n", x ) + LOG( GlobalConfiguration::GAUSSIAN_ELIMINATION_LOGGING, "SparseGaussianEliminator: %s\n", x ) class SparseGaussianEliminator { diff --git a/src/basis_factorization/SparseLUFactorization.h b/src/basis_factorization/SparseLUFactorization.h index 7d75ebe3c4..7b925fec48 100644 --- a/src/basis_factorization/SparseLUFactorization.h +++ b/src/basis_factorization/SparseLUFactorization.h @@ -22,7 +22,7 @@ #include "SparseLUFactors.h" #define BASIS_FACTORIZATION_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseLUFactorization: %s\n", x ) + LOG( GlobalConfiguration::BASIS_FACTORIZATION_LOGGING, "SparseLUFactorization: %s\n", x ) class EtaMatrix; class LPElement; diff --git a/src/cegar/IncrementalLinearization.h b/src/cegar/IncrementalLinearization.h index a188df3a77..bd0c4d6ef0 100644 --- a/src/cegar/IncrementalLinearization.h +++ b/src/cegar/IncrementalLinearization.h @@ -20,7 +20,7 @@ #include "Map.h" #define INCREMENTAL_LINEARIZATION_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::CEGAR_LOGGING, "IncrementalLinearization: %s\n", x ) + LOG( GlobalConfiguration::CEGAR_LOGGING, "IncrementalLinearization: %s\n", x ) class Engine; class InputQuery; diff --git a/src/common/Debug.h b/src/common/Debug.h index a6d9d67907..01bcb30288 100644 --- a/src/common/Debug.h +++ b/src/common/Debug.h @@ -26,8 +26,10 @@ #define DEBUG( x ) #endif +#undef LOG + #ifndef NDEBUG -#define MARABOU_LOG( x, f, y, ... ) \ +#define LOG( x, f, y, ... ) \ { \ if ( ( x ) ) \ { \ @@ -35,7 +37,7 @@ } \ } #else -#define MARABOU_LOG( x, f, y, ... ) \ +#define LOG( x, f, y, ... ) \ { \ } #endif diff --git a/src/configuration/GlobalConfiguration.cpp b/src/configuration/GlobalConfiguration.cpp index e03902f955..b6e0c545fe 100644 --- a/src/configuration/GlobalConfiguration.cpp +++ b/src/configuration/GlobalConfiguration.cpp @@ -78,7 +78,7 @@ const bool GlobalConfiguration::PREPROCESS_INPUT_QUERY = true; const bool GlobalConfiguration::PREPROCESSOR_ELIMINATE_VARIABLES = true; const bool GlobalConfiguration::PL_CONSTRAINTS_ADD_AUX_EQUATIONS_AFTER_PREPROCESSING = true; const bool GlobalConfiguration::NL_CONSTRAINTS_ADD_AUX_EQUATIONS_AFTER_PREPROCESSING = true; -const double GlobalConfiguration::PREPROCESSOR_ALMOST_FIXED_THRESHOLD = 0.000000001; +const double GlobalConfiguration::PREPROCESSOR_ALMOST_FIXED_THRESHOLD = 0.00001; const unsigned GlobalConfiguration::PREPROCESSSING_MAX_TIGHTEING_ROUND = 1000; diff --git a/src/configuration/Options.cpp b/src/configuration/Options.cpp index 946dcc1364..fe1a432cb4 100644 --- a/src/configuration/Options.cpp +++ b/src/configuration/Options.cpp @@ -73,7 +73,7 @@ void Options::initializeDefaultValues() _intOptions[SEED] = 1; _intOptions[NUM_BLAS_THREADS] = 1; _intOptions[NUM_CONSTRAINTS_TO_REFINE_INC_LIN] = 30; - _intOptions[ATTACK_TIMEOUT] = 60; // todo? + _intOptions[ATTACK_TIMEOUT] = 60; /* Float options diff --git a/src/engine/CDSmtCore.h b/src/engine/CDSmtCore.h index a352f2c6ec..8cbeebc5c0 100644 --- a/src/engine/CDSmtCore.h +++ b/src/engine/CDSmtCore.h @@ -76,7 +76,7 @@ #include "context/cdlist.h" #include "context/context.h" -#define SMT_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::SMT_CORE_LOGGING, "CDSmtCore: %s\n", x ) +#define SMT_LOG( x, ... ) LOG( GlobalConfiguration::SMT_CORE_LOGGING, "CDSmtCore: %s\n", x ) class EngineState; class Engine; diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 125665f02b..72ab094173 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -187,8 +187,8 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * for ( int i = sources.size() - 1; i >= 0; --i ) { const NLR::NeuronIndex &activationNeuron = sources.back(); - sources.popBack(); int index = static_cast( activationNeuron._neuron ); + sources.popBack(); sourceValues[i] = x.index( { 0, index } ); sourceIndices[i] = index; } diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index e54710d633..d62edc929d 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -2,15 +2,18 @@ #ifndef __CustomDNN_h__ #define __CustomDNN_h__ -#include "NetworkLevelReasoner.h" -#include -#define CUSTOM_DNN_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "customDNN: %s\n", x ) #undef Warning +#include "NetworkLevelReasoner.h" + #include +#include + +#define CUSTOM_DNN_LOG( x, ... ) \ + LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "customDNN: %s\n", x ) /* - Custom differentiation function for max pooling, implementing the forward and backward propagation for - the max pooling operation according to each variable's source layer as defined in the nlr. + Custom differentiation function for max pooling, implementing the forward and backward propagation + for the max pooling operation according to each variable's source layer as defined in the nlr. */ class CustomMaxPoolFunction : public torch::autograd::Function { @@ -42,15 +45,16 @@ class CustomDNN : public torch::nn::Module { public: static void setWeightsAndBiases( torch::nn::Linear &linearLayer, - const NLR::Layer *layer, - unsigned sourceLayer, - unsigned inputSize, - unsigned outputSize ); + const NLR::Layer *layer, + unsigned sourceLayer, + unsigned inputSize, + unsigned outputSize ); void weightedSum( unsigned i, const NLR::Layer *layer ); explicit CustomDNN( const NLR::NetworkLevelReasoner *networkLevelReasoner ); torch::Tensor forward( torch::Tensor x ); const Vector &getLayerSizes() const; + private: const NLR::NetworkLevelReasoner *_networkLevelReasoner; Vector _layerSizes; diff --git a/src/engine/DantzigsRule.h b/src/engine/DantzigsRule.h index b3fda42e77..5e57e28c24 100644 --- a/src/engine/DantzigsRule.h +++ b/src/engine/DantzigsRule.h @@ -19,7 +19,7 @@ #include "EntrySelectionStrategy.h" #define DANTZIG_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::DANTZIGS_RULE_LOGGING, "DantzigsRule: %s\n", x ) + LOG( GlobalConfiguration::DANTZIGS_RULE_LOGGING, "DantzigsRule: %s\n", x ) class String; diff --git a/src/engine/DnCManager.h b/src/engine/DnCManager.h index de0111c00c..e8e50cac39 100644 --- a/src/engine/DnCManager.h +++ b/src/engine/DnCManager.h @@ -25,7 +25,7 @@ #include #define DNC_MANAGER_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::DNC_MANAGER_LOGGING, "DnCManager: %s\n", x ) + LOG( GlobalConfiguration::DNC_MANAGER_LOGGING, "DnCManager: %s\n", x ) class DnCManager { diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 6b4eb9a3eb..3940f0b3f5 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -14,11 +14,15 @@ ** [[ Add lengthier description here ]] **/ -#include "Engine.h" +#ifdef BUILD_TORCH +#undef Warning +#include +#endif #include "AutoConstraintMatrixAnalyzer.h" #include "Debug.h" #include "DisjunctionConstraint.h" +#include "Engine.h" #include "EngineState.h" #include "InfeasibleQueryException.h" #include "InputQuery.h" @@ -35,11 +39,6 @@ #include "Vector.h" #include -#ifdef BUILD_TORCH -#undef Warning -#include -#endif - Engine::Engine() : _context() @@ -1470,7 +1469,8 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) catch ( MarabouError &e ) { ENGINE_LOG( - Stringf( "Error, Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); + Stringf( "Error, Adversarial attack end time: %f\n", TimeUtils::now() ) + .ascii() ); } } #endif diff --git a/src/engine/Engine.h b/src/engine/Engine.h index ae623e05e5..291975c159 100644 --- a/src/engine/Engine.h +++ b/src/engine/Engine.h @@ -48,7 +48,6 @@ #include "SymbolicBoundTighteningType.h" #include "UnsatCertificateNode.h" - #include #include @@ -58,7 +57,7 @@ class PGDAttack; #undef ERROR #endif -#define ENGINE_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::ENGINE_LOGGING, "Engine: %s\n", x ) +#define ENGINE_LOG( x, ... ) LOG( GlobalConfiguration::ENGINE_LOGGING, "Engine: %s\n", x ) class EngineState; class InputQuery; @@ -539,8 +538,8 @@ class Engine LinearExpression _heuristicCost; #ifdef BUILD_TORCH - std::unique_ptr_pgdAttack; - bool _isAttackSuccessful = false; + std::unique_ptr _pgdAttack; + bool _isAttackSuccessful = false; #endif /* diff --git a/src/engine/IEngine.h b/src/engine/IEngine.h index 387b50c3b3..9b9108b20a 100644 --- a/src/engine/IEngine.h +++ b/src/engine/IEngine.h @@ -48,7 +48,6 @@ class IEngine UNKNOWN = 3, TIMEOUT = 4, QUIT_REQUESTED = 5, - ATTACK_SAT = 6, NOT_DONE = 999, }; diff --git a/src/engine/InputQuery.cpp b/src/engine/InputQuery.cpp index 657a764d2f..877ed2738b 100644 --- a/src/engine/InputQuery.cpp +++ b/src/engine/InputQuery.cpp @@ -29,7 +29,7 @@ #include "SymbolicBoundTighteningType.h" #define INPUT_QUERY_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::INPUT_QUERY_LOGGING, "Input Query: %s\n", x ) + LOG( GlobalConfiguration::INPUT_QUERY_LOGGING, "Input Query: %s\n", x ) InputQuery::InputQuery() : _ensureSameSourceLayerInNLR( Options::get()->getSymbolicBoundTighteningType() == diff --git a/src/engine/Marabou.cpp b/src/engine/Marabou.cpp index 687bdac54f..053fa85380 100644 --- a/src/engine/Marabou.cpp +++ b/src/engine/Marabou.cpp @@ -57,7 +57,6 @@ Marabou::~Marabou() void Marabou::run() { - std::cout << "start run time: " << TimeUtils::now().ascii() << std::endl; struct timespec start = TimeUtils::sampleMicro(); prepareInputQuery(); @@ -70,8 +69,6 @@ void Marabou::run() if ( Options::get()->getBool( Options::EXPORT_ASSIGNMENT ) ) exportAssignment(); - - std::cout << "end run time: " << TimeUtils::now().ascii() << std::endl; } void Marabou::prepareInputQuery() @@ -225,7 +222,7 @@ void Marabou::solveQuery() if ( _engine->processInputQuery( _inputQuery ) ) { - if (_engine->getExitCode() == Engine::ATTACK_SAT) + if ( _engine->getExitCode() == Engine::SAT ) { return; } @@ -308,11 +305,6 @@ void Marabou::displayResults( unsigned long long microSecondsElapsed ) const printf( "\n" ); } } - else if (result == Engine::ATTACK_SAT) - { - resultString = "sat"; - printf( "sat\n" ); - } else if ( result == Engine::TIMEOUT ) { resultString = "TIMEOUT"; diff --git a/src/engine/PGD.h b/src/engine/PGD.h index 58d55bb09b..8a27b0ab9f 100644 --- a/src/engine/PGD.h +++ b/src/engine/PGD.h @@ -1,14 +1,14 @@ #ifdef BUILD_TORCH #ifndef __PGD_h__ #define __PGD_h__ +#undef Warning +#include #include "CustomDNN.h" -#include "GlobalConfiguration.h" #include "Options.h" #include -#define PGD_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "PGD: %s\n", x ) -#undef Warning -#include +#define PGD_LOG( x, ... ) LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "PGD: %s\n", x ) + /* diff --git a/src/engine/PLConstraintScoreTracker.h b/src/engine/PLConstraintScoreTracker.h index 6798074dd2..ab62333e6b 100644 --- a/src/engine/PLConstraintScoreTracker.h +++ b/src/engine/PLConstraintScoreTracker.h @@ -24,7 +24,7 @@ #include #define SCORE_TRACKER_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::SCORE_TRACKER_LOGGING, "PLConstraintScoreTracker: %s\n", x ) + LOG( GlobalConfiguration::SCORE_TRACKER_LOGGING, "PLConstraintScoreTracker: %s\n", x ) struct ScoreEntry { diff --git a/src/engine/ProjectedSteepestEdge.h b/src/engine/ProjectedSteepestEdge.h index c84ba9bac9..70b3265ef0 100644 --- a/src/engine/ProjectedSteepestEdge.h +++ b/src/engine/ProjectedSteepestEdge.h @@ -20,7 +20,7 @@ #include "SparseUnsortedList.h" #define PSE_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::PROJECTED_STEEPEST_EDGE_LOGGING, "Projected SE: %s\n", x ) + LOG( GlobalConfiguration::PROJECTED_STEEPEST_EDGE_LOGGING, "Projected SE: %s\n", x ) class ProjectedSteepestEdgeRule : public IProjectedSteepestEdgeRule { diff --git a/src/engine/SmtCore.h b/src/engine/SmtCore.h index 0274d475b6..ad1d61f8e9 100644 --- a/src/engine/SmtCore.h +++ b/src/engine/SmtCore.h @@ -28,7 +28,7 @@ #include -#define SMT_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::SMT_CORE_LOGGING, "SmtCore: %s\n", x ) +#define SMT_LOG( x, ... ) LOG( GlobalConfiguration::SMT_CORE_LOGGING, "SmtCore: %s\n", x ) class EngineState; class IEngine; diff --git a/src/engine/SumOfInfeasibilitiesManager.h b/src/engine/SumOfInfeasibilitiesManager.h index 43ba50e7b7..ccc67e9e1b 100644 --- a/src/engine/SumOfInfeasibilitiesManager.h +++ b/src/engine/SumOfInfeasibilitiesManager.h @@ -29,7 +29,7 @@ #include "T/stdlib.h" #include "Vector.h" -#define SOI_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::SOI_LOGGING, "SoIManager: %s\n", x ) +#define SOI_LOG( x, ... ) LOG( GlobalConfiguration::SOI_LOGGING, "SoIManager: %s\n", x ) class SumOfInfeasibilitiesManager { diff --git a/src/engine/Tableau.h b/src/engine/Tableau.h index 175efbe3c8..f5bf063f57 100644 --- a/src/engine/Tableau.h +++ b/src/engine/Tableau.h @@ -29,7 +29,7 @@ #include "SparseUnsortedList.h" #include "Statistics.h" -#define TABLEAU_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::TABLEAU_LOGGING, "Tableau: %s\n", x ) +#define TABLEAU_LOG( x, ... ) LOG( GlobalConfiguration::TABLEAU_LOGGING, "Tableau: %s\n", x ) class Equation; class ICostFunctionManager; diff --git a/src/input_parsers/MpsParser.h b/src/input_parsers/MpsParser.h index 31ebc529ba..06e3bf046f 100644 --- a/src/input_parsers/MpsParser.h +++ b/src/input_parsers/MpsParser.h @@ -20,7 +20,7 @@ #include "Map.h" #include "Set.h" -#define MPS_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::MPS_PARSER_LOGGING, "MpsParser: %s\n", x ) +#define MPS_LOG( x, ... ) LOG( GlobalConfiguration::MPS_PARSER_LOGGING, "MpsParser: %s\n", x ) class InputQuery; class String; diff --git a/src/input_parsers/OnnxParser.h b/src/input_parsers/OnnxParser.h index 4317411ea5..e6ce8035a5 100644 --- a/src/input_parsers/OnnxParser.h +++ b/src/input_parsers/OnnxParser.h @@ -25,7 +25,7 @@ #include "Vector.h" #include "onnx.proto3.pb.h" -#define ONNX_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::ONNX_PARSER_LOGGING, "OnnxParser: %s\n", x ) +#define ONNX_LOG( x, ... ) LOG( GlobalConfiguration::ONNX_PARSER_LOGGING, "OnnxParser: %s\n", x ) class OnnxParser diff --git a/src/nlr/IterativePropagator.h b/src/nlr/IterativePropagator.h index 0c3a593f89..7a7fba671a 100644 --- a/src/nlr/IterativePropagator.h +++ b/src/nlr/IterativePropagator.h @@ -27,7 +27,7 @@ namespace NLR { #define IterativePropagator_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "Iterativepropagator: %s\n", x ) + LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "Iterativepropagator: %s\n", x ) class IterativePropagator : public ParallelSolver { diff --git a/src/nlr/LPFormulator.h b/src/nlr/LPFormulator.h index 3d6d527360..9a12a9e617 100644 --- a/src/nlr/LPFormulator.h +++ b/src/nlr/LPFormulator.h @@ -31,7 +31,7 @@ namespace NLR { #define LPFormulator_LOG( x, ... ) \ - MARABOU_LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "LP Preprocessor: %s\n", x ) + LOG( GlobalConfiguration::PREPROCESSOR_LOGGING, "LP Preprocessor: %s\n", x ) class LPFormulator : public ParallelSolver { diff --git a/src/nlr/NetworkLevelReasoner.cpp b/src/nlr/NetworkLevelReasoner.cpp index f577b19960..2bb8f09a1c 100644 --- a/src/nlr/NetworkLevelReasoner.cpp +++ b/src/nlr/NetworkLevelReasoner.cpp @@ -34,7 +34,7 @@ #include -#define NLR_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::NETWORK_LEVEL_REASONER_LOGGING, "NLR: %s\n", x ) +#define NLR_LOG( x, ... ) LOG( GlobalConfiguration::NETWORK_LEVEL_REASONER_LOGGING, "NLR: %s\n", x ) namespace NLR { diff --git a/src/query_loader/QueryLoader.h b/src/query_loader/QueryLoader.h index 896aea5105..c079cd298d 100644 --- a/src/query_loader/QueryLoader.h +++ b/src/query_loader/QueryLoader.h @@ -19,7 +19,7 @@ #include "InputQuery.h" -#define QL_LOG( x, ... ) MARABOU_LOG( GlobalConfiguration::QUERY_LOADER_LOGGING, "QueryLoader: %s\n", x ) +#define QL_LOG( x, ... ) LOG( GlobalConfiguration::QUERY_LOADER_LOGGING, "QueryLoader: %s\n", x ) class QueryLoader { From ddb068d12a8c48ad102e318cba164e9113905cc0 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Mon, 16 Dec 2024 16:30:28 +0200 Subject: [PATCH 63/69] CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf5f7c56eb..eedb42fdba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,9 @@ * Added support for creating constraints using the overloaded syntax `<=`, `==` etc. in the Python backend. See `maraboupy/examples/7_PythonicAPI.py` for details. +* Added support for adversarial attacks to quickly produce a counterexample, in the case +* of satisfiable queries. + ## Version 1.0.0 * Initial versioned release From 77041b529cc4b02f55dcd04145419c4557a65d87 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 17 Dec 2024 13:20:04 +0200 Subject: [PATCH 64/69] PGD_LOGGING, CUSTOM_DNN_LOGGING = false --- src/configuration/GlobalConfiguration.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/configuration/GlobalConfiguration.cpp b/src/configuration/GlobalConfiguration.cpp index b6e0c545fe..e627fa4ee1 100644 --- a/src/configuration/GlobalConfiguration.cpp +++ b/src/configuration/GlobalConfiguration.cpp @@ -119,8 +119,8 @@ const unsigned GlobalConfiguration::MAX_ROUNDS_OF_BACKWARD_ANALYSIS = 10; const GlobalConfiguration::PdgBoundType GlobalConfiguration::PGD_BOUND_TYPE = GlobalConfiguration::PGD_INPUT; -const unsigned GlobalConfiguration::PGD_DEFAULT_NUM_ITER = 100; // todo run argument -const unsigned GlobalConfiguration::PGD_NUM_RESTARTS = 3; // todo run argument +const unsigned GlobalConfiguration::PGD_DEFAULT_NUM_ITER = 100; +const unsigned GlobalConfiguration::PGD_NUM_RESTARTS = 4; const double GlobalConfiguration::PGD_INPUT_RANGE = 1000; #ifdef ENABLE_GUROBI @@ -130,7 +130,7 @@ const bool GlobalConfiguration::GUROBI_LOGGING = false; // Logging - note that it is enabled only in Debug mode const bool GlobalConfiguration::DNC_MANAGER_LOGGING = false; -const bool GlobalConfiguration::ENGINE_LOGGING = true; +const bool GlobalConfiguration::ENGINE_LOGGING = false; const bool GlobalConfiguration::TABLEAU_LOGGING = false; const bool GlobalConfiguration::SMT_CORE_LOGGING = false; const bool GlobalConfiguration::DANTZIGS_RULE_LOGGING = false; @@ -147,8 +147,8 @@ const bool GlobalConfiguration::ONNX_PARSER_LOGGING = false; const bool GlobalConfiguration::SOI_LOGGING = false; const bool GlobalConfiguration::SCORE_TRACKER_LOGGING = false; const bool GlobalConfiguration::CEGAR_LOGGING = false; -const bool GlobalConfiguration::CUSTOM_DNN_LOGGING = true; -const bool GlobalConfiguration::PGD_LOGGING = true; +const bool GlobalConfiguration::CUSTOM_DNN_LOGGING = false; +const bool GlobalConfiguration::PGD_LOGGING = false; const bool GlobalConfiguration::USE_SMART_FIX = false; const bool GlobalConfiguration::USE_LEAST_FIX = false; From 8bba51863eaf03048692df6e931f05362dbef448 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 17 Dec 2024 14:25:26 +0200 Subject: [PATCH 65/69] Engine.cpp #ifdef BIULD_TORCH --- src/engine/CustomDNN.h | 4 ++-- src/engine/Engine.cpp | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index d62edc929d..05f2dfabcd 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -3,9 +3,9 @@ #define __CustomDNN_h__ #undef Warning -#include "NetworkLevelReasoner.h" - #include + +#include "NetworkLevelReasoner.h" #include #define CUSTOM_DNN_LOG( x, ... ) \ diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 3940f0b3f5..69f566be65 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -74,7 +74,9 @@ Engine::Engine() , _milpSolverBoundTighteningType( Options::get()->getMILPSolverBoundTighteningType() ) , _sncMode( false ) , _queryId( "" ) +#ifdef BUILD_TORCH , _pgdAttack( nullptr ) +#endif , _produceUNSATProofs( Options::get()->getBool( Options::PRODUCE_PROOFS ) ) , _groundBoundManager( _context ) , _UNSATCertificate( NULL ) From dbd57d594e13d39d964f8353b1522429f703f78b Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 17 Dec 2024 16:49:56 +0200 Subject: [PATCH 66/69] change attack time log --- src/engine/Engine.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 69f566be65..9951a4f5ee 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1453,25 +1453,30 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) { try { - ENGINE_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ) + std::string timeString = TimeUtils::now().ascii(); + ENGINE_LOG( Stringf( "Adversarial attack start time: %s\n", timeString.c_str() ) .ascii() ); _pgdAttack = std::make_unique( _networkLevelReasoner ); if ( _pgdAttack->runAttack() ) { - ENGINE_LOG( Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ) - .ascii() ); + timeString = TimeUtils::now().ascii(); + ENGINE_LOG( + Stringf( "Adversarial attack end time: %s\n", timeString.c_str() ) + .ascii() ); _exitCode = Engine::SAT; _isAttackSuccessful = true; return false; } - ENGINE_LOG( - Stringf( "Adversarial attack end time: %f\n", TimeUtils::now() ).ascii() ); + timeString = TimeUtils::now().ascii(); + ENGINE_LOG( Stringf( "Adversarial attack end time: %s\n", timeString.c_str() ) + .ascii() ); } catch ( MarabouError &e ) { + std::string timeString = TimeUtils::now().ascii(); ENGINE_LOG( - Stringf( "Error, Adversarial attack end time: %f\n", TimeUtils::now() ) + Stringf( "Error, Adversarial attack end time: %s\n", timeString.c_str() ) .ascii() ); } } From 88c90d5387d85076e400c98965fd4ca76b8dc2a4 Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Tue, 17 Dec 2024 17:27:52 +0200 Subject: [PATCH 67/69] change attack time log --- src/engine/PGD.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 04bb75a085..4fea810412 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -160,7 +160,6 @@ std::pair PGDAttack::findAdvExample() ? FloatUtils::infinity() : Options::get()->getInt( Options::ATTACK_TIMEOUT ) ); PGD_LOG( Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); - PGD_LOG( Stringf( "Adversarial attack start time: %f\n", TimeUtils::now() ).ascii() ); timespec startTime = TimeUtils::sampleMicro(); torch::Tensor currentExample = _inputExample; From d870652a1c3206f600c5b985fdd2e00aa96cb04c Mon Sep 17 00:00:00 2001 From: mayaswissa Date: Wed, 18 Dec 2024 13:57:50 +0200 Subject: [PATCH 68/69] change timeout attack error --- src/engine/Engine.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp index 9951a4f5ee..447f76381c 100644 --- a/src/engine/Engine.cpp +++ b/src/engine/Engine.cpp @@ -1472,12 +1472,16 @@ bool Engine::processInputQuery( InputQuery &inputQuery, bool preprocess ) ENGINE_LOG( Stringf( "Adversarial attack end time: %s\n", timeString.c_str() ) .ascii() ); } + catch ( MarabouError &e ) { std::string timeString = TimeUtils::now().ascii(); - ENGINE_LOG( - Stringf( "Error, Adversarial attack end time: %s\n", timeString.c_str() ) - .ascii() ); + ENGINE_LOG( Stringf( "Caught a MarabouError. Code: %u. Message: %s Adversarial " + "attack end time: %s\n", + e.getCode(), + e.getUserMessage(), + timeString.c_str() ) + .ascii() ); } } #endif From 725327f9e914c4640361b073b2373fe7b1632038 Mon Sep 17 00:00:00 2001 From: idan0610 Date: Tue, 11 Mar 2025 08:45:54 +0200 Subject: [PATCH 69/69] some bug fixes --- src/engine/CustomDNN.cpp | 66 +++++++++++++++++++--- src/engine/CustomDNN.h | 31 +++++++++- src/engine/DnCManager.cpp | 8 ++- src/engine/PGD.cpp | 28 ++++++--- src/engine/SumOfInfeasibilitiesManager.cpp | 15 ++++- src/input_parsers/TensorUtils.cpp | 4 +- src/input_parsers/TensorUtils.h | 16 +++--- 7 files changed, 138 insertions(+), 30 deletions(-) diff --git a/src/engine/CustomDNN.cpp b/src/engine/CustomDNN.cpp index 72ab094173..2744746dfc 100644 --- a/src/engine/CustomDNN.cpp +++ b/src/engine/CustomDNN.cpp @@ -2,6 +2,17 @@ #include "Vector.h" #ifdef BUILD_TORCH +CustomRelu::CustomRelu( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) + : _networkLevelReasoner( nlr ) + , _reluLayerIndex( layerIndex ) +{ +} + +torch::Tensor CustomRelu::forward( torch::Tensor x ) const +{ + return CustomReluFunction::apply( x, _networkLevelReasoner, _reluLayerIndex ); +} + CustomMaxPool::CustomMaxPool( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ) : _networkLevelReasoner( nlr ) , _maxLayerIndex( layerIndex ) @@ -91,7 +102,7 @@ CustomDNN::CustomDNN( const NLR::NetworkLevelReasoner *nlr ) break; case NLR::Layer::RELU: { - auto reluLayer = torch::nn::ReLU( torch::nn::ReLUOptions() ); + auto reluLayer = std::make_shared( _networkLevelReasoner, i ); _reluLayers.append( reluLayer ); register_module( "ReLU" + std::to_string( i ), reluLayer ); break; @@ -105,9 +116,9 @@ CustomDNN::CustomDNN( const NLR::NetworkLevelReasoner *nlr ) } case NLR::Layer::MAX: { - auto customMaxPoolLayer = std::make_shared( _networkLevelReasoner, i ); - _customMaxPoolLayers.append( customMaxPoolLayer ); - register_module( "maxPool" + std::to_string( i ), customMaxPoolLayer ); + auto maxPoolLayer = std::make_shared( _networkLevelReasoner, i ); + _maxPoolLayers.append( maxPoolLayer ); + register_module( "maxPool" + std::to_string( i ), maxPoolLayer ); break; } case NLR::Layer::SIGMOID: @@ -147,7 +158,7 @@ torch::Tensor CustomDNN::forward( torch::Tensor x ) reluIndex++; break; case NLR::Layer::MAX: - x = _customMaxPoolLayers[maxPoolIndex]->forward( x ); + x = _maxPoolLayers[maxPoolIndex]->forward( x ); maxPoolIndex++; break; case NLR::Layer::LEAKY_RELU: @@ -167,6 +178,45 @@ torch::Tensor CustomDNN::forward( torch::Tensor x ) return x; } +torch::Tensor CustomReluFunction::forward( torch::autograd::AutogradContext *ctx, + torch::Tensor x, + const NLR::NetworkLevelReasoner *nlr, + unsigned int layerIndex ) +{ + ctx->save_for_backward( { x } ); + + const NLR::Layer *layer = nlr->getLayer( layerIndex ); + torch::Tensor reluOutputs = torch::zeros( { 1, layer->getSize() } ); + torch::Tensor reluGradients = torch::zeros( { 1, layer->getSize() } ); + + for ( unsigned neuron = 0; neuron < layer->getSize(); ++neuron ) + { + auto sources = layer->getActivationSources( neuron ); + ASSERT( sources.size() == 1 ); + const NLR::NeuronIndex &sourceNeuron = sources.back(); + int index = static_cast( sourceNeuron._neuron ); + reluOutputs.index_put_( { 0, static_cast( neuron ) }, + torch::clamp_min( x.index( { 0, index } ), 0 ) ); + reluGradients.index_put_( { 0, static_cast( neuron ) }, x.index( { 0, index } ) > 0 ); + } + + ctx->saved_data["reluGradients"] = reluGradients; + + return reluOutputs; +} + +std::vector CustomReluFunction::backward( torch::autograd::AutogradContext *ctx, + std::vector grad_output ) +{ + auto saved = ctx->get_saved_variables(); + auto input = saved[0]; + + auto reluGradients = ctx->saved_data["reluGradients"].toTensor(); + auto grad_input = grad_output[0] * reluGradients[0]; + + return { grad_input, torch::Tensor(), torch::Tensor() }; +} + torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext *ctx, torch::Tensor x, const NLR::NetworkLevelReasoner *nlr, @@ -189,13 +239,13 @@ torch::Tensor CustomMaxPoolFunction::forward( torch::autograd::AutogradContext * const NLR::NeuronIndex &activationNeuron = sources.back(); int index = static_cast( activationNeuron._neuron ); sources.popBack(); - sourceValues[i] = x.index( { 0, index } ); - sourceIndices[i] = index; + sourceValues.index_put_( { i }, x.index( { 0, index } ) ); + sourceIndices.index_put_( { i }, index ); } maxOutputs.index_put_( { 0, static_cast( neuron ) }, torch::max( sourceValues ) ); argMaxOutputs.index_put_( { 0, static_cast( neuron ) }, - sourceIndices[torch::argmax( sourceValues )] ); + sourceIndices.index( { torch::argmax( sourceValues ) } ) ); } ctx->saved_data["argMaxOutputs"] = argMaxOutputs; diff --git a/src/engine/CustomDNN.h b/src/engine/CustomDNN.h index 05f2dfabcd..d78d4be5d4 100644 --- a/src/engine/CustomDNN.h +++ b/src/engine/CustomDNN.h @@ -11,6 +11,33 @@ #define CUSTOM_DNN_LOG( x, ... ) \ LOG( GlobalConfiguration::CUSTOM_DNN_LOGGING, "customDNN: %s\n", x ) +/* + Custom differentiation function for ReLU, implementing the forward and backward propagation + for the ReLU operation according to each variable's source layer as defined in the nlr. +*/ +class CustomReluFunction : public torch::autograd::Function +{ +public: + static torch::Tensor forward( torch::autograd::AutogradContext *ctx, + torch::Tensor x, + const NLR::NetworkLevelReasoner *nlr, + unsigned layerIndex ); + + static std::vector backward( torch::autograd::AutogradContext *ctx, + std::vector grad_output ); +}; + +class CustomRelu : public torch::nn::Module +{ +public: + CustomRelu( const NLR::NetworkLevelReasoner *nlr, unsigned layerIndex ); + torch::Tensor forward( torch::Tensor x ) const; + +private: + const NLR::NetworkLevelReasoner *_networkLevelReasoner; + unsigned _reluLayerIndex; +}; + /* Custom differentiation function for max pooling, implementing the forward and backward propagation for the max pooling operation according to each variable's source layer as defined in the nlr. @@ -58,10 +85,10 @@ class CustomDNN : public torch::nn::Module private: const NLR::NetworkLevelReasoner *_networkLevelReasoner; Vector _layerSizes; - Vector _reluLayers; + Vector> _reluLayers; Vector _leakyReluLayers; Vector _sigmoidLayers; - Vector> _customMaxPoolLayers; + Vector> _maxPoolLayers; Vector _linearLayers; Vector _layersOrder; unsigned _numberOfLayers; diff --git a/src/engine/DnCManager.cpp b/src/engine/DnCManager.cpp index 06f684dc43..44fa68ebdb 100644 --- a/src/engine/DnCManager.cpp +++ b/src/engine/DnCManager.cpp @@ -154,7 +154,13 @@ void DnCManager::solve() // Preprocess the input query and create an engine for each of the threads if ( !createEngines( numWorkers ) ) { - _exitCode = DnCManager::UNSAT; + if ( _baseEngine->getExitCode() == Engine::ExitCode::SAT ) + { + _exitCode = DnCManager::SAT; + _engineWithSATAssignment = _baseEngine; + } + else + _exitCode = DnCManager::UNSAT; return; } diff --git a/src/engine/PGD.cpp b/src/engine/PGD.cpp index 4fea810412..9185570ff6 100644 --- a/src/engine/PGD.cpp +++ b/src/engine/PGD.cpp @@ -4,6 +4,7 @@ #include #ifdef BUILD_TORCH + PGDAttack::PGDAttack( NLR::NetworkLevelReasoner *networkLevelReasoner ) : networkLevelReasoner( networkLevelReasoner ) , _device( torch::kCPU ) @@ -110,18 +111,18 @@ bool PGDAttack::isWithinBounds( const torch::Tensor &sample, double lower = bounds.first.get( i ); double upper = bounds.second.get( i ); - if ( std::isinf( lower ) && std::isinf( upper ) ) + if ( lower == FloatUtils::negativeInfinity() && upper == FloatUtils::infinity() ) { // If both bounds are infinite, any value is acceptable continue; } - else if ( std::isinf( lower ) ) + else if ( lower == FloatUtils::negativeInfinity() ) { // Only check upper bound if ( value > upper ) return false; } - else if ( std::isinf( upper ) ) + else if ( upper == FloatUtils::infinity() ) { // Only check lower bound if ( value < lower ) @@ -162,12 +163,14 @@ std::pair PGDAttack::findAdvExample() PGD_LOG( Stringf( "Adversarial attack timeout set to %f\n", timeoutForAttack ).ascii() ); timespec startTime = TimeUtils::sampleMicro(); - torch::Tensor currentExample = _inputExample; + torch::Tensor inputExample; + torch::Tensor currentExample; + torch::Tensor prevExample; torch::Tensor currentPrediction; torch::Tensor lowerBoundTensor = - torch::tensor( _inputBounds.first.data(), torch::kFloat32 ).to( _device ); + torch::tensor( _inputBounds.first.getContainer(), torch::kFloat32 ).to( _device ); torch::Tensor upperBoundTensor = - torch::tensor( _inputBounds.second.data(), torch::kFloat32 ).to( _device ); + torch::tensor( _inputBounds.second.getContainer(), torch::kFloat32 ).to( _device ); torch::Tensor delta = torch::zeros( _inputSize ).to( _device ).requires_grad_( true ); for ( unsigned i = 0; i < _restarts; ++i ) @@ -177,10 +180,19 @@ std::pair PGDAttack::findAdvExample() { throw MarabouError( MarabouError::TIMEOUT, "Attack failed due to timeout" ); } - torch::optim::Adam optimizer( { delta }, torch::optim::AdamOptions() ); + inputExample = torch::rand( _inputExample.sizes() ); + inputExample = inputExample * ( upperBoundTensor - lowerBoundTensor ) + lowerBoundTensor; + + torch::optim::Adam optimizer( { delta }, torch::optim::AdamOptions( 0.1 ) ); + for ( unsigned j = 0; j < _iters; ++j ) { - currentExample = currentExample + delta; + prevExample = currentExample; + currentExample = inputExample + delta; + if ( ( prevExample.defined() && currentExample.equal( prevExample ) ) || + !isWithinBounds( currentExample, _inputBounds ) ) + break; + currentPrediction = _model->forward( currentExample ); if ( isWithinBounds( currentPrediction, _outputBounds ) ) { diff --git a/src/engine/SumOfInfeasibilitiesManager.cpp b/src/engine/SumOfInfeasibilitiesManager.cpp index 606a059bb3..0cdd54e17e 100644 --- a/src/engine/SumOfInfeasibilitiesManager.cpp +++ b/src/engine/SumOfInfeasibilitiesManager.cpp @@ -192,8 +192,19 @@ void SumOfInfeasibilitiesManager::proposePhasePatternUpdateRandomly() } ); // First, pick a pl constraint whose cost component we will update. - unsigned index = (unsigned)T::rand() % _plConstraintsInCurrentPhasePattern.size(); - PiecewiseLinearConstraint *plConstraintToUpdate = _plConstraintsInCurrentPhasePattern[index]; + bool fixed = true; + PiecewiseLinearConstraint *plConstraintToUpdate; + while ( fixed ) + { + if ( _plConstraintsInCurrentPhasePattern.empty() ) + return; + + unsigned index = (unsigned)T::rand() % _plConstraintsInCurrentPhasePattern.size(); + plConstraintToUpdate = _plConstraintsInCurrentPhasePattern[index]; + fixed = plConstraintToUpdate->phaseFixed(); + if ( fixed ) + removeCostComponentFromHeuristicCost( plConstraintToUpdate ); + } // Next, pick an alternative phase. PhaseStatus currentPhase = _currentPhasePattern[plConstraintToUpdate]; diff --git a/src/input_parsers/TensorUtils.cpp b/src/input_parsers/TensorUtils.cpp index eab6aae7f9..d88719aff7 100644 --- a/src/input_parsers/TensorUtils.cpp +++ b/src/input_parsers/TensorUtils.cpp @@ -165,9 +165,9 @@ calculatePaddingNeeded( int inputSize, int filterSize, int stride, bool padFront Permutation reversePermutation( unsigned int size ) { Permutation result; - for ( unsigned int i = size - 1; i-- > 0; ) + for ( unsigned int i = size; i-- > 0; ) { result.append( i ); } return result; -} +} \ No newline at end of file diff --git a/src/input_parsers/TensorUtils.h b/src/input_parsers/TensorUtils.h index 295f8aac6c..3d46074856 100644 --- a/src/input_parsers/TensorUtils.h +++ b/src/input_parsers/TensorUtils.h @@ -55,6 +55,8 @@ TensorIndices unpackIndex( TensorShape shape, PackedTensorIndices packedIndex ); PackedTensorIndices packIndex( TensorShape shape, TensorIndices indices ); +unsigned int tensorSize( TensorShape shape ); + template T tensorLookup( Vector tensor, TensorShape shape, TensorIndices indices ) { return tensor[packIndex( shape, indices )]; @@ -77,20 +79,20 @@ Vector transposeTensor( Vector tensor, TensorShape shape, Permutation perm // NOTE this implementation is *very* inefficient. Eventually we might want to // switch to a similar implementation as NumPy arrays with internal strides etc. ASSERT( shape.size() == permutation.size() ); + ASSERT( tensorSize( shape ) == tensor.size() ); + TensorShape transposedShape = transposeVector( shape, permutation ); Vector result( tensor.size() ); - for ( PackedTensorIndices rawOutputIndex = 0; rawOutputIndex < tensor.size(); rawOutputIndex++ ) + for ( PackedTensorIndices rawInputIndex = 0; rawInputIndex < tensor.size(); rawInputIndex++ ) { - TensorIndices outputIndex = unpackIndex( transposedShape, rawOutputIndex ); - TensorIndices inputIndex = transposeVector( outputIndex, permutation ); - T value = tensorLookup( tensor, shape, inputIndex ); - result[rawOutputIndex] = value; + TensorIndices inputIndex = unpackIndex( shape, rawInputIndex ); + TensorIndices outputIndex = transposeVector( inputIndex, permutation ); + int rawOutputIndex = packIndex( transposedShape, outputIndex ); + result[rawOutputIndex] = tensor[rawInputIndex]; } return result; } -unsigned int tensorSize( TensorShape shape ); - // See https://github.com/onnx/onnx/blob/main/docs/Broadcasting.md#multidirectional-broadcasting TensorShape getMultidirectionalBroadcastShape( TensorShape shape1, TensorShape shape2 );