diff --git a/.gitignore b/.gitignore index a56a314..50a3e55 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,7 @@ site .coverage runs dist +build/ +.venv/ +*.pyc *.egg-info diff --git a/docs/basic_faultinjection.md b/docs/basic_faultinjection.md index 49f2347..95fca56 100644 --- a/docs/basic_faultinjection.md +++ b/docs/basic_faultinjection.md @@ -4,7 +4,7 @@ For example, the following code perform a quantized random integer bit flip injection on LeNet. ```python title="Setup LeNet default fault injection" -from dataset.lenet_cifar import make_testloader, LeNet +from mrfi_dataset.lenet_cifar import make_testloader, LeNet from mrfi import MRFI, EasyConfig from mrfi.experiment import Acc_experiment, Acc_golden, BER_Acc_experiment diff --git a/docs/example_layerwise.md b/docs/example_layerwise.md index 3764c56..e39e7de 100644 --- a/docs/example_layerwise.md +++ b/docs/example_layerwise.md @@ -9,7 +9,7 @@ Additionally, if the GPU is available, the following code automatically uses CUD ```python import torch -from dataset.lenet_cifar import testset, Net +from mrfi_dataset.lenet_cifar import testset, Net from mrfi import MRFI, EasyConfig import sys diff --git a/experiments/lenet_FI_observe.py b/experiments/lenet_FI_observe.py index 75a4b00..184c5bc 100644 --- a/experiments/lenet_FI_observe.py +++ b/experiments/lenet_FI_observe.py @@ -1,4 +1,4 @@ -from dataset.lenet_cifar import make_testloader, LeNet +from mrfi_dataset.lenet_cifar import make_testloader, LeNet from mrfi import MRFI, EasyConfig from mrfi.experiment import observeFI_experiment, observeFI_experiment_plus import matplotlib.pyplot as plt diff --git a/experiments/lenet_basic_observe.ipynb b/experiments/lenet_basic_observe.ipynb index 37672df..1317b32 100644 --- a/experiments/lenet_basic_observe.ipynb +++ b/experiments/lenet_basic_observe.ipynb @@ -20,7 +20,7 @@ "import matplotlib.pyplot as plt\n", "import torch\n", "\n", - "from dataset.lenet_cifar import LeNet, make_testloader\n", + "from mrfi_dataset.lenet_cifar import LeNet, make_testloader\n", "from mrfi import MRFI, EasyConfig\n", "from mrfi.experiment import get_activation_info, get_weight_info" ] diff --git a/experiments/lenet_basic_observe.py b/experiments/lenet_basic_observe.py index 6d23d53..3035777 100644 --- a/experiments/lenet_basic_observe.py +++ b/experiments/lenet_basic_observe.py @@ -3,7 +3,7 @@ import matplotlib.pyplot as plt import torch -from dataset.lenet_cifar import LeNet, make_testloader +from mrfi_dataset.lenet_cifar import LeNet, make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import get_activation_info, get_weight_info diff --git a/experiments/lenet_float.py b/experiments/lenet_float.py index 6a3bb6e..0389600 100644 --- a/experiments/lenet_float.py +++ b/experiments/lenet_float.py @@ -1,4 +1,4 @@ -from dataset.lenet_cifar import make_testloader, Net +from mrfi_dataset.lenet_cifar import make_testloader, Net from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density import matplotlib.pyplot as plt diff --git a/experiments/lenet_layerwise.py b/experiments/lenet_layerwise.py index 9e6ea84..3c97a6d 100644 --- a/experiments/lenet_layerwise.py +++ b/experiments/lenet_layerwise.py @@ -1,5 +1,5 @@ import torch -from dataset.lenet_cifar import testset, Net +from mrfi_dataset.lenet_cifar import testset, Net from mrfi import MRFI, EasyConfig import sys diff --git a/experiments/lenet_scale_BER_Acc.py b/experiments/lenet_scale_BER_Acc.py index b5563e3..99bd46d 100644 --- a/experiments/lenet_scale_BER_Acc.py +++ b/experiments/lenet_scale_BER_Acc.py @@ -1,4 +1,4 @@ -from dataset.lenet_cifar import make_testloader, Net +from mrfi_dataset.lenet_cifar import make_testloader, Net from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density import matplotlib.pyplot as plt diff --git a/experiments/lenet_visualize.py b/experiments/lenet_visualize.py index 369730d..e862a71 100644 --- a/experiments/lenet_visualize.py +++ b/experiments/lenet_visualize.py @@ -1,4 +1,4 @@ -from dataset.lenet_cifar import make_testloader, LeNet, testset +from mrfi_dataset.lenet_cifar import make_testloader, LeNet, testset from mrfi import MRFI, EasyConfig from mrfi.experiment import get_activation_info, observeFI_experiment_plus, Acc_golden, Acc_experiment import matplotlib.pyplot as plt diff --git a/experiments/poisson_sample.py b/experiments/poisson_sample.py index b17929d..3367eb2 100644 --- a/experiments/poisson_sample.py +++ b/experiments/poisson_sample.py @@ -1,5 +1,5 @@ '''Compare speed of poisson_sample''' -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden from torchvision.models import resnet18 diff --git a/experiments/resnet18_BER_Acc.py b/experiments/resnet18_BER_Acc.py index 0d8226c..b507151 100644 --- a/experiments/resnet18_BER_Acc.py +++ b/experiments/resnet18_BER_Acc.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden, benchmark_range import matplotlib.pyplot as plt diff --git a/experiments/resnet18_activation.py b/experiments/resnet18_activation.py index 10b5522..6bfb7a1 100644 --- a/experiments/resnet18_activation.py +++ b/experiments/resnet18_activation.py @@ -1,7 +1,7 @@ ''' Conduct BER_Acc experiemnt on resnet18 with different datatype. ''' -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden, get_activation_info from torchvision.models import resnet18 diff --git a/experiments/resnet18_floatbit.py b/experiments/resnet18_floatbit.py index c3cff3a..a357e9b 100644 --- a/experiments/resnet18_floatbit.py +++ b/experiments/resnet18_floatbit.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden import matplotlib.pyplot as plt diff --git a/experiments/resnet18_pixelwise.py b/experiments/resnet18_pixelwise.py index 7c09f20..2574b47 100644 --- a/experiments/resnet18_pixelwise.py +++ b/experiments/resnet18_pixelwise.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import get_activation_info, observeFI_experiment_plus, Acc_experiment from torchvision.models import resnet18 diff --git a/experiments/resnet18_qbit.py b/experiments/resnet18_qbit.py index 65b600d..f88d59b 100644 --- a/experiments/resnet18_qbit.py +++ b/experiments/resnet18_qbit.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden import matplotlib.pyplot as plt diff --git a/experiments/resnet18_weight.py b/experiments/resnet18_weight.py index 17c5835..f09e65a 100644 --- a/experiments/resnet18_weight.py +++ b/experiments/resnet18_weight.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden, get_weight_info from torchvision.models import resnet18 diff --git a/experiments/torchvision_classify_activation.py b/experiments/torchvision_classify_activation.py index ad48ee3..ea3a976 100644 --- a/experiments/torchvision_classify_activation.py +++ b/experiments/torchvision_classify_activation.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import Acc_golden, Acc_experiment, get_activation_info from torchvision.models import alexnet diff --git a/experiments/vgg11_channelwise.py b/experiments/vgg11_channelwise.py index 9318fde..88e2f4b 100644 --- a/experiments/vgg11_channelwise.py +++ b/experiments/vgg11_channelwise.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import observeFI_experiment_plus, get_activation_info from torchvision.models import vgg11 diff --git a/experiments/vgg11_floatbit_cnt.py b/experiments/vgg11_floatbit_cnt.py index 9e6212c..f4f221e 100644 --- a/experiments/vgg11_floatbit_cnt.py +++ b/experiments/vgg11_floatbit_cnt.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from torchvision.models import vgg11 import torch diff --git a/experiments/vgg11_pixelwise.py b/experiments/vgg11_pixelwise.py index d526cb2..3a2dbaa 100644 --- a/experiments/vgg11_pixelwise.py +++ b/experiments/vgg11_pixelwise.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import get_activation_info, observeFI_experiment_plus, Acc_experiment from torchvision.models import vgg11 diff --git a/experiments/vgg11_speedtest.py b/experiments/vgg11_speedtest.py index 9a31d23..0ff785f 100644 --- a/experiments/vgg11_speedtest.py +++ b/experiments/vgg11_speedtest.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import Acc_experiment, Acc_golden from torchvision.models import vgg11 diff --git a/experiments/vgg11_spread.py b/experiments/vgg11_spread.py index b7f29b3..283cf75 100644 --- a/experiments/vgg11_spread.py +++ b/experiments/vgg11_spread.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import get_activation_info, observeFI_experiment_plus, Acc_experiment from torchvision.models import vgg11 diff --git a/experiments/vgg16_activation.py b/experiments/vgg16_activation.py index 85e0eab..2b78ebd 100644 --- a/experiments/vgg16_activation.py +++ b/experiments/vgg16_activation.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden, get_activation_info from torchvision.models import vgg16 diff --git a/experiments/vgg16_fixnum.py b/experiments/vgg16_fixnum.py index e1bfbcb..cfeae83 100644 --- a/experiments/vgg16_fixnum.py +++ b/experiments/vgg16_fixnum.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import Acc_golden, Acc_experiment from torchvision.models import vgg16 diff --git a/experiments/vgg16_floatbit_cnt.py b/experiments/vgg16_floatbit_cnt.py index 2b45f7e..613b775 100644 --- a/experiments/vgg16_floatbit_cnt.py +++ b/experiments/vgg16_floatbit_cnt.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from torchvision.models import vgg11 import torch diff --git a/experiments/vgg16_weight.py b/experiments/vgg16_weight.py index 880941f..6b4ed7f 100644 --- a/experiments/vgg16_weight.py +++ b/experiments/vgg16_weight.py @@ -1,5 +1,5 @@ -from dataset.imagenet import make_testloader +from mrfi_dataset.imagenet import make_testloader from mrfi import MRFI, EasyConfig from mrfi.experiment import BER_Acc_experiment, logspace_density, Acc_golden, get_weight_info from torchvision.models import vgg16 diff --git a/mrfi/mrfi.py b/mrfi/mrfi.py index c86cf88..3c2c4b3 100644 --- a/mrfi/mrfi.py +++ b/mrfi/mrfi.py @@ -335,7 +335,9 @@ def _FI_activation(config, act): modifier = named_functions[config.error_mode.method] modifier_args = config.error_mode.args.raw_dict - values = act.view(-1)[error_list] + error_idx = error_list.to(act.device) if isinstance(error_list, torch.Tensor) else error_list + + values = act.view(-1)[error_idx] if fi_quantization: quantization_method.quantize(values, **quantization_args) @@ -345,7 +347,7 @@ def _FI_activation(config, act): if fi_quantization: quantization_method.dequantize(fi_value, **quantization_args) - act.view(-1)[error_list] = fi_value + act.view(-1)[error_idx] = fi_value if layerwise_quantization: quantization_method.dequantize(act, **quantization_args) @@ -405,7 +407,9 @@ def _FI_weight(config, weight): modifier = named_functions[config.error_mode.method] modifier_args = config.error_mode.args.raw_dict - values = weight.view(-1)[error_list] + error_idx = error_list.to(weight.device) if isinstance(error_list, torch.Tensor) else error_list + + values = weight.view(-1)[error_idx] if fi_quantization: quantization_method.quantize(values, **quantization_args) @@ -415,7 +419,7 @@ def _FI_weight(config, weight): if fi_quantization: quantization_method.dequantize(fi_value, **quantization_args) - weight.view(-1)[error_list] = fi_value + weight.view(-1)[error_idx] = fi_value if layerwise_quantization: quantization_method.dequantize(weight, **quantization_args) @@ -518,7 +522,19 @@ def __init__(self, model: nn.Module, config: Union[str, EasyConfig]) -> None: if isinstance(config, EasyConfig): self.config = self.__expand_config(config) elif isinstance(config, str): - self.config = ConfigTree(_read_config(config), self) + treedict = self.__empty_configtree(self.model) + user_config = _read_config(config) + + def update_dict(d, u): + for k, v in u.items(): + if isinstance(v, dict) and isinstance(d.get(k, None), dict): + update_dict(d[k], v) + else: + d[k] = v + + update_dict(treedict, user_config) + self.config = ConfigTree(treedict, self) + self.__add_moduleconfig(self.config, self.model) else: raise TypeError(config) diff --git a/mrfi_dataset/__init__.py b/mrfi_dataset/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/dataset/cnn_exp.py b/mrfi_dataset/cnn_exp.py similarity index 85% rename from dataset/cnn_exp.py rename to mrfi_dataset/cnn_exp.py index 4e34a61..d8bf47a 100644 --- a/dataset/cnn_exp.py +++ b/mrfi_dataset/cnn_exp.py @@ -9,9 +9,16 @@ [transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5))]) -trainset = torchvision.datasets.CIFAR10(root='./_data', train=True, +try: + import os + datapath = os.environ['DATASETS'] + '/cifar10' +except Exception: + import os + datapath = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), '_data') + +trainset = torchvision.datasets.CIFAR10(root=datapath, train=True, download=False, transform=transform) -testset = torchvision.datasets.CIFAR10(root='./_data', train=False, +testset = torchvision.datasets.CIFAR10(root=datapath, train=False, download=False, transform=transform) classes = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck') @@ -101,14 +108,18 @@ def train(): print('Finished Training') - torch.save(net.state_dict(), 'cifar_vgg.pth') + import os + dir_path = os.path.dirname(os.path.realpath(__file__)) + torch.save(net.state_dict(), os.path.join(dir_path, 'cifar_vgg.pth')) def test(): device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu") net = Net() testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False) - net.load_state_dict(torch.load('cifar_vgg.pth')) + import os + dir_path = os.path.dirname(os.path.realpath(__file__)) + net.load_state_dict(torch.load(os.path.join(dir_path, 'cifar_vgg.pth'))) net.eval() correct = 0 diff --git a/dataset/imagenet.py b/mrfi_dataset/imagenet.py similarity index 94% rename from dataset/imagenet.py rename to mrfi_dataset/imagenet.py index 4213188..dcc571c 100644 --- a/dataset/imagenet.py +++ b/mrfi_dataset/imagenet.py @@ -17,6 +17,8 @@ testset = None def get_testset(folder = '~/dataset/val'): + import os + folder = os.path.expanduser(folder) global testset if testset is None: testset = datasets.ImageFolder(folder, tf) diff --git a/dataset/lenet_cifar.py b/mrfi_dataset/lenet_cifar.py similarity index 85% rename from dataset/lenet_cifar.py rename to mrfi_dataset/lenet_cifar.py index 46ac86f..10ce65b 100644 --- a/dataset/lenet_cifar.py +++ b/mrfi_dataset/lenet_cifar.py @@ -14,7 +14,8 @@ import os datapath = os.environ['DATASETS'] + '/cifar10' except Exception: - datapath = './_data' + import os + datapath = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), '_data') trainset = torchvision.datasets.CIFAR10(root=datapath, train=True, download=True, transform=transform) @@ -43,7 +44,9 @@ def __init__(self, trained = False): self.fc2 = nn.Linear(120,84) self.fc3 = nn.Linear(84,10) if trained: - self.load_state_dict(torch.load('./dataset/lenet_cifar10.pth')) + import os + dir_path = os.path.dirname(os.path.realpath(__file__)) + self.load_state_dict(torch.load(os.path.join(dir_path, 'lenet_cifar10.pth'))) def forward(self,x): x = F.max_pool2d(F.relu(self.conv1(x)),(2,2)) @@ -90,13 +93,17 @@ def train(): print('Finished Training') - torch.save(net.state_dict(), 'cifar10.pth') + import os + dir_path = os.path.dirname(os.path.realpath(__file__)) + torch.save(net.state_dict(), os.path.join(dir_path, 'cifar10.pth')) def test(): net=Net() testloader = torch.utils.data.DataLoader(testset, batch_size=4, shuffle=False) - net.load_state_dict(torch.load('cifar10.pth')) + import os + dir_path = os.path.dirname(os.path.realpath(__file__)) + net.load_state_dict(torch.load(os.path.join(dir_path, 'cifar10.pth'))) net.eval() correct = 0 diff --git a/dataset/lenet_cifar10.pth b/mrfi_dataset/lenet_cifar10.pth similarity index 100% rename from dataset/lenet_cifar10.pth rename to mrfi_dataset/lenet_cifar10.pth diff --git a/pyproject.toml b/pyproject.toml index d2c638d..31b5167 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,10 +22,10 @@ dependencies = [ "scipy", "torch>=1.9", ] -version = "2.0.0" +version = "2.1.0" [tool.setuptools] -packages = ["mrfi"] +packages = ["mrfi", "mrfi_dataset"] [project.urls] Homepage = "https://github.com/fffasttime/MRFI" diff --git a/readme.md b/readme.md index 9e316de..31fbdd5 100644 --- a/readme.md +++ b/readme.md @@ -47,7 +47,7 @@ The following code perform a quantized random integer bit flip injection on LeNe and find the relation between bit error rate (BER) and classification accuracy. ```python title="LeNet default fault injection" -from dataset.lenet_cifar import make_testloader, LeNet +from mrfi_dataset.lenet_cifar import make_testloader, LeNet from mrfi import MRFI, EasyConfig from mrfi.experiment import Acc_experiment, Acc_golden, BER_Acc_experiment diff --git a/test/test_addfunc.py b/test/test_addfunc.py index c2acdd2..fc795ad 100644 --- a/test/test_addfunc.py +++ b/test/test_addfunc.py @@ -3,7 +3,7 @@ sys.path.append('.') from mrfi import experiment import torch -from dataset.lenet_cifar import make_testloader, Net +from mrfi_dataset.lenet_cifar import make_testloader, Net from mrfi import MRFI, EasyConfig, load_package_functions, add_function class NoQuantization: diff --git a/test/test_experiment.py b/test/test_experiment.py index 31719df..a99f8bc 100644 --- a/test/test_experiment.py +++ b/test/test_experiment.py @@ -3,7 +3,7 @@ sys.path.append('.') from mrfi import experiment import torch -from dataset.lenet_cifar import make_testloader, Net +from mrfi_dataset.lenet_cifar import make_testloader, Net from mrfi import MRFI, EasyConfig def test_00():