Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update in 2024/5/14 #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions MNSIM/Accuracy_Model/Crossbar_accuracy.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

class crossbar_accuracy():
def __init__(self, SimConfig_path):
#linqiiushi:add SimConfig_path(line below)
#SimConfig_path = os.path.abspath(os.path.join(os.getcwd(),'..','SimConfig',SimConfig_path))
self.SimConfig_path = SimConfig_path
xbar = crossbar(SimConfig_path)
print("Hardware config file is loaded:", SimConfig_path)
Expand Down
3 changes: 2 additions & 1 deletion MNSIM/Accuracy_Model/Weight_update.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def weight_update(SimConfig_path, weight, is_SAF=0, is_Variation=0, is_Rratio=0)
# print("Hardware config file is loaded:", SimConfig_path)
wu_config = cp.ConfigParser()
wu_config.read(SimConfig_path, encoding='UTF-8')
SAF_dist = list(map(int, wu_config.get('Device level', 'Device_SAF').split(',')))

SAF_dist = list(map(float, wu_config.get('Device level', 'Device_SAF').split(',')))
variation = float(wu_config.get('Device level', 'Device_Variation'))
device_level = int(wu_config.get('Device level', 'Device_Level'))
assert device_level >= 0, "NVM resistance level < 0"
Expand Down
26 changes: 25 additions & 1 deletion MNSIM/Area_Model/Model_Area.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from MNSIM.Hardware_Model.Tile import tile
from MNSIM.Hardware_Model.Buffer import buffer
from MNSIM.Hardware_Model.Adder import adder
#linqiushi modified
from MNSIM.Hardware_Model.Multiplier import multiplier
#linqiushi above
class Model_area():
def __init__(self, NetStruct, SimConfig_path, multiple=None, TCG_mapping=None):
self.NetStruct = NetStruct
Expand Down Expand Up @@ -70,6 +73,9 @@ def calculate_model_area(self): #Todo: Noc area
self.global_buf = buffer(SimConfig_path=self.SimConfig_path,buf_level=1,default_buf_size=self.graph.global_buf_size)
self.global_buf.calculate_buf_area()
self.global_add = adder(SimConfig_path=self.SimConfig_path,bitwidth=self.graph.global_adder_bitwidth)
#linqiushi modified
self.global_mul=multiplier(SimConfig_path=self.SimConfig_path,bitwidth=self.graph.global_multiplier_bitwidth)
#linqiushi above
self.global_add.calculate_adder_area()
for i in range(self.total_layer_num):
tile_num = self.graph.layer_tileinfo[i]['tilenum']
Expand Down Expand Up @@ -123,11 +129,29 @@ def model_area_output(self, module_information = 1, layer_information = 1):
for i in range(self.total_layer_num):
print("Layer", i, ":")
layer_dict = self.NetStruct[i][0][0]
#linqiushi modified
if layer_dict['type'] == 'element_sum':
print(" Hardware area (global accumulator):", self.global_add.adder_area*self.graph.global_adder_num+self.global_buf.buf_area, "um^2")
elif layer_dict['type']=='element_multiply':
print(" Hardware area (global accumulator):", self.global_mul.multiplier_area*self.graph.global_multiplier_num+self.global_buf.buf_area, "um^2")
else:
print(" Hardware area:", self.arch_area[i], "um^2")

#linqiushi above
#linqiushi modified
def area_output_CNNParted(self):
area_list=[]

for i in range(self.total_layer_num):
layer_dict = self.NetStruct[i][0][0]

if layer_dict['type'] == 'element_sum':
area_list.append(self.global_add.adder_area*self.graph.global_adder_num+self.global_buf.buf_area)
elif layer_dict['type']=='element_multiply':
area_list.append(self.global_mul.multiplier_area*self.graph.global_multiplier_num+self.global_buf.buf_area)
else:
area_list.append(self.arch_area[i])
return area_list
#linqiushi above
if __name__ == '__main__':
test_SimConfig_path = os.path.join(os.path.dirname(os.path.dirname(os.getcwd())), "SimConfig.ini")
test_weights_file_path = os.path.join(os.path.dirname(os.path.dirname(os.getcwd())),
Expand Down
97 changes: 97 additions & 0 deletions MNSIM/Hardware_Model/Multiplier.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#linqiushi modified
#!/usr/bin/python
#-*-coding:utf-8-*-
import configparser as cp
import os
import math
test_SimConfig_path = os.path.join(os.path.dirname(os.path.dirname(os.getcwd())),"SimConfig.ini")
#Default SimConfig file path: MNSIM_Python/SimConfig.ini


class multiplier(object):
def __init__(self, SimConfig_path, bitwidth = None):
# frequency unit: MHz
multiplier_config = cp.ConfigParser()
multiplier_config.read(SimConfig_path, encoding='UTF-8')
self.multiplier_tech = int(multiplier_config.get('Digital module', 'Multiplier_Tech'))
self.multiplier_area = float(multiplier_config.get('Digital module', 'Multiplier_Area'))
self.multiplier_power = float(multiplier_config.get('Digital module', 'Multiplier_Power'))
if bitwidth is None:
self.multiplier_bitwidth = 8
else:
self.multiplier_bitwidth = bitwidth
assert self.multiplier_bitwidth > 0
self.multiplier_frequency = float(multiplier_config.get('Digital module', 'Digital_Frequency'))
if self.multiplier_frequency is None:
self.multiplier_frequency = 100
assert self.multiplier_frequency > 0
self.multiplier_latency = 1.0/self.multiplier_frequency
self.multiplier_energy = 0
self.calculate_multiplier_power()

def calculate_multiplier_area(self):
# unit: um^2
if self.multiplier_area == 0:
multiplier_area_dict = {130: 10*14*130*130/1e6, #ref: Implementation of an Efficient 14-Transistor Full multiplier (.18μm technology) Using DTMOS 2.5e-9
65: 1.42,#10*14*65*65/1e6,
55: 10*14*55*55/1e6,
45: 10*14*45*45/1e6,
28: 10*14*28*28/1e6
}
# TODO: add circuits simulation results
if self.multiplier_tech <= 28:
self.multiplier_area = multiplier_area_dict[28] * self.multiplier_bitwidth
elif self.multiplier_tech <= 45:
self.multiplier_area = multiplier_area_dict[45] * self.multiplier_bitwidth
elif self.multiplier_tech <= 55:
self.multiplier_area = multiplier_area_dict[55] * self.multiplier_bitwidth
elif self.multiplier_tech <= 65:
self.multiplier_area = multiplier_area_dict[65] * self.multiplier_bitwidth
else:
self.multiplier_area = multiplier_area_dict[130] * self.multiplier_bitwidth

def calculate_multiplier_power(self):
# unit: W
if self.multiplier_power == 0:
multiplier_power_dict = {130: 2.5e-9,
65: 3e-7,
55: 2.5e-9,
45: 2.5e-9,
28: 2.5e-9
}
# TODO: add circuits simulation results
if self.multiplier_tech <= 28:
self.multiplier_power = multiplier_power_dict[28] * self.multiplier_bitwidth
elif self.multiplier_tech <= 45:
self.multiplier_power = multiplier_power_dict[45] * self.multiplier_bitwidth
elif self.multiplier_tech <= 55:
self.multiplier_power = multiplier_power_dict[55] * self.multiplier_bitwidth
elif self.multiplier_tech <= 65:
self.multiplier_power = multiplier_power_dict[65] * self.multiplier_bitwidth
else:
self.multiplier_power = multiplier_power_dict[130] * self.multiplier_bitwidth

def calculate_multiplier_energy(self):
assert self.multiplier_power >= 0
assert self.multiplier_latency >= 0
self.multiplier_energy = self.multiplier_latency * self.multiplier_power

def multiplier_output(self):
print("multiplier_area:", self.multiplier_area, "um^2")
print("multiplier_bitwidth:", self.multiplier_bitwidth, "bit")
print("multiplier_power:", self.multiplier_power, "W")
print("multiplier_latency:", self.multiplier_latency, "ns")
print("multiplier_energy:", self.multiplier_energy, "nJ")

def multiplier_test():
print("load file:",test_SimConfig_path)
_multiplier = multiplier(test_SimConfig_path)
_multiplier.calculate_multiplier_area()
_multiplier.calculate_multiplier_power()
_multiplier.calculate_multiplier_energy()
_multiplier.multiplier_output()


if __name__ == '__main__':
multiplier_test()
#linqiushi above
1 change: 1 addition & 0 deletions MNSIM/Hardware_Model/Tile.py
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ def calculate_tile_read_power_fast(self, max_column=0, max_row=0, max_PE=0, max_
if layer_type == 'pooling':
self.tile_pooling.calculate_Pooling_power()
self.tile_pooling_read_power = self.tile_pooling.Pooling_power

elif layer_type == 'conv' or layer_type == 'fc':
self.calculate_PE_read_power_fast(max_column=max_column, max_row=max_row, max_group=max_group,
SimConfig_path=SimConfig_path, default_inbuf_size = default_inbuf_size)
Expand Down
69 changes: 69 additions & 0 deletions MNSIM/Interface/Imagenet.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
#-*-coding:utf-8-*-
# import multiprocessing
# multiprocessing.set_start_method('spawn', True)
import os

import torch.utils.data as Data
import torchvision
import torchvision.transforms as Transforms

TRAIN_BATCH_SIZE = 128
TRAIN_NUM_WORKERS = 0
TEST_BATCH_SIZE = 100
TEST_NUM_WORKERS = 0

#ImageNet_PATH needs to be changed
def get_dataloader(ImageNet_PATH='/share/linqiushi-nfs', batch_size=64, workers=3, pin_memory=True):

traindir = os.path.join(ImageNet_PATH, 'Imagenet-train/ILSVRC2012_img_train')
valdir = os.path.join(ImageNet_PATH, 'Imagenet-value')
print('traindir = ',traindir)
print('valdir = ',valdir)

normalizer = Transforms.Normalize(mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])

train_dataset = torchvision.datasets.ImageFolder(
traindir,
Transforms.Compose([
Transforms.RandomResizedCrop(224),
Transforms.RandomHorizontalFlip(),
Transforms.ToTensor(),
normalizer
])
)

val_dataset = torchvision.datasets.ImageFolder(
valdir,
Transforms.Compose([
Transforms.Resize(256),
Transforms.CenterCrop(224),
Transforms.ToTensor(),
normalizer
])
)
print('train_dataset = ',len(train_dataset))
print('val_dataset = ',len(val_dataset))

train_loader = Data.DataLoader(
train_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=workers,
pin_memory=pin_memory,
sampler=None
)
val_loader = Data.DataLoader(
val_dataset,
batch_size=batch_size,
shuffle=True,
num_workers=workers,
pin_memory=pin_memory
)
return train_loader, val_loader

if __name__ == '__main__':
train_loader, test_loader = get_dataloader()
print(len(train_loader))
print(len(test_loader))
print('this is the Imagenet100 dataset, output shape is 224x224x3')
8 changes: 8 additions & 0 deletions MNSIM/Interface/alg_test_training_entrance.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
assert 0

print(f'args is {args}')

# dataloader
dataset_module = import_module(f'MNSIM.Interface.{args.dataset}')
train_loader, test_loader = dataset_module.get_dataloader()
Expand All @@ -39,13 +40,18 @@
num_classes = 10
elif args.dataset.endswith('cifar100'):
num_classes = 100
elif args.dataset.endswith('Imagenet'):
num_classes=1000
else:
assert 0, f'unknown dataset'

net = net_module.get_net(cate = args.net, num_classes = num_classes)

# train
train_module = import_module(f'MNSIM.Interface.{args.train}')
device = torch.device(f'cuda:{args.gpu}' if torch.cuda.is_available() else 'cpu')
print(torch.cuda.get_device_properties(1).total_memory)
print(torch.cuda.memory_allocated(1))
print(f'run on device {device}')
# weights
if args.weight is not None:
Expand All @@ -54,6 +60,8 @@
# net.load_state_dict(torch.load(args.weight))
if args.mode == 'train':
train_module.train_net(net, train_loader, test_loader, device, args.prefix)


if args.mode == 'test':
assert args.weight
# net.load_change_weights(torch.load(args.weight))
Expand Down
5 changes: 3 additions & 2 deletions MNSIM/Interface/cifar10.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@
import torchvision
import torchvision.transforms as Transforms

TRAIN_BATCH_SIZE = 128
TRAIN_BATCH_SIZE = 256
TRAIN_NUM_WORKERS = 0
TEST_BATCH_SIZE = 100
TEST_BATCH_SIZE = 256
TEST_NUM_WORKERS = 0

def get_dataloader():
Expand All @@ -20,6 +20,7 @@ def get_dataloader():
transform = Transforms.Compose([
Transforms.Pad(padding = 4),
Transforms.RandomCrop(32),
#Transforms.Resize((224,224)),
Transforms.RandomHorizontalFlip(),
Transforms.ToTensor(),
])
Expand Down
Loading