| import os, shutil | import os, shutil | ||||
| import re | import re | ||||
| from .manage import create_simulation | |||||
| print('Creation of a new simulation project...') | print('Creation of a new simulation project...') | ||||
| ### Create the repository of the projects | ### Create the repository of the projects | ||||
| if search(repository): | if search(repository): | ||||
| print('Illegal characters detected! Please enter a name with only the following characters : a-z, A-Z, 0-9, ".", "-", "_" and "/".') | print('Illegal characters detected! Please enter a name with only the following characters : a-z, A-Z, 0-9, ".", "-", "_" and "/".') | ||||
| else: | else: | ||||
| try: | |||||
| os.makedirs(global_path+'/'+repository, exist_ok=False) | |||||
| project_repository = repository | |||||
| except FileExistsError: | |||||
| print('Error, a project with this repository already exists!') | |||||
| project_repository = repository | |||||
| project_path = global_path+'/'+repository | project_path = global_path+'/'+repository | ||||
| ### Add contents in the project | |||||
| files_from_ELMO = [ | |||||
| 'Examples/elmoasmfunctions.o', | |||||
| 'Examples/elmoasmfunctions.s', | |||||
| 'Examples/elmoasmfunctionsdef.h', | |||||
| 'Examples/DPATraces/MBedAES/vector.o', | |||||
| ] | |||||
| files_from_templates = [ | |||||
| 'elmoasmfunctionsdef-extension.h', | |||||
| 'Makefile', | |||||
| 'project.c' | |||||
| ] | |||||
| for filename in files_from_ELMO: | |||||
| shutil.copy('elmo/'+filename, project_path) | |||||
| for filename in files_from_templates: | |||||
| shutil.copy('templates/'+filename, project_path) | |||||
| shutil.copy('elmo/'+'Examples/DPATraces/MBedAES/MBedAES.ld', project_path+'/'+'project.ld') | |||||
| ### Create the project class | |||||
| with open('templates/projectclass.py') as _source: | |||||
| code = ''.join(_source.readlines()) | |||||
| code = code.replace('{{PROJECTCLASSNAME}}', project_classname) | |||||
| with open(project_path+'/'+'projectclass.py', 'w') as _dest: | |||||
| _dest.write(code) | |||||
| project_path = create_simulation(project_path, classname) | |||||
| print('') | print('') | ||||
| print('Creation complete !') | print('Creation complete !') | ||||
| print(' - Project repository: {}'.format(os.path.abspath(project_path))) | |||||
| print(' - Project class "{}" in {}'.format(project_classname, os.path.abspath(project_path+'/'+'projectclass.py'))) | |||||
| print(' - Linker script: {}'.format(os.path.abspath(project_path+'/'+'project.ld'))) | |||||
| print(' - Project repository: {}'.format(project_path)) | |||||
| print(' - Project class "{}" in {}'.format(project_classname, project_path+'/projectclass.py')) | |||||
| print(' - Linker script: {}'.format(project_path+'/project.ld'))) | |||||
| print('') | print('') | ||||
| print('Please don\'t to compile the project with the present Makefile before using it!') | print('Please don\'t to compile the project with the present Makefile before using it!') |
| from .project_reader import Project | |||||
| reader = ProjectReader() | |||||
| projects = reader.get_projects() | |||||
| for key, project in projects.items(): | |||||
| globals()[key] = project |
| from servicethread import PermanentServiceThread | |||||
| import socket | |||||
| class ListeningThread(PermanentServiceThread): | |||||
| def __init__(self, host, port, threadclass, **kwargs): | |||||
| super().__init__() | |||||
| self.hostname = host | |||||
| self.port = port | |||||
| self.threadclass = threadclass | |||||
| self.kwargs = kwargs | |||||
| def execute(self): | |||||
| self.tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||||
| self.tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |||||
| self.tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) | |||||
| # self.tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_ATTACH_REUSEPORT_CBPF, 1) | |||||
| self.tcpsock.bind((self.hostname, self.port)) | |||||
| self.tcpsock.listen(5) | |||||
| print('[port][%s] Listening' % self.port) | |||||
| while self.is_running(): | |||||
| try: | |||||
| (clientsocket, (ip, port)) = self.tcpsock.accept() | |||||
| print('[port][{}] Accepted: {} <=> {}'.format( | |||||
| self.port, | |||||
| clientsocket.getsockname(), | |||||
| clientsocket.getpeername(), | |||||
| )) | |||||
| newthread = self.threadclass(ip, port, clientsocket, **self.kwargs) | |||||
| newthread.start() | |||||
| except socket.timeout: | |||||
| pass | |||||
| def stop(self): | |||||
| super().stop() | |||||
| clientsocker = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||||
| clientsocker.connect( (self.hostname, self.port) ) | |||||
| self.tcpsock.close() | |||||
| print('[port][%s] Stop listening' % self.port) |
| import inspect | import inspect | ||||
| import subprocess | import subprocess | ||||
| def search_simulations(repository, criteria=lambda x:True, search_also_in_module=True): | |||||
| def search_simulations_in_repository(repository, criteria=lambda x:True): | |||||
| """ To search simulation classes in the 'repository' verifying the 'criteria' """ | """ To search simulation classes in the 'repository' verifying the 'criteria' """ | ||||
| projects = {} | projects = {} | ||||
| obj.set_project_directory(os.path.abspath(root)) | obj.set_project_directory(os.path.abspath(root)) | ||||
| projects[key] = obj | projects[key] = obj | ||||
| if search_also_in_module: | |||||
| module_path = os.path.dirname(os.path.abspath(__file__)) | |||||
| module_projects = search_simulations(module_path+'/projects', criteria=lambda x:True, search_also_in_module=False) | |||||
| for key, project in module_projects.items(): | |||||
| if key not in projects: | |||||
| projects[key] = project | |||||
| return projects | return projects | ||||
| def search_simulations_in_module(criteria=lambda x:True): | |||||
| module_path = os.path.dirname(os.path.abspath(__file__)) | |||||
| projects_path = module_path+'/projects' | |||||
| return search_simulations_in_repository(projects_path, criteria) | |||||
| def search_simulations(repository, criteria=lambda x:True): | |||||
| projects = search_simulations_in_repository(repositories, criteria) | |||||
| module_projects = search_simulations_in_module | |||||
| for key, project in module_projects.items(): | |||||
| if key not in projects: | |||||
| projects[key] = project | |||||
| return projects | |||||
| class SimulationNotFoundError(Exception): | class SimulationNotFoundError(Exception): | ||||
| pass | pass | ||||
| def get_simulation_via_classname(classname): | def get_simulation_via_classname(classname): | ||||
| return get_simulation('.', classname) | return get_simulation('.', classname) | ||||
| def create_simulation(repository, classname, verbose=True): | |||||
| def create_simulation(repository, classname): | |||||
| """ Create a simulation class """ | """ Create a simulation class """ | ||||
| try: | try: | ||||
| os.makedirs(repository, exist_ok=False) | os.makedirs(repository, exist_ok=False) | ||||
| code = code.replace('{{PROJECTCLASSNAME}}', classname) | code = code.replace('{{PROJECTCLASSNAME}}', classname) | ||||
| with open(project_path+'/'+'projectclass.py', 'w') as _dest: | with open(project_path+'/'+'projectclass.py', 'w') as _dest: | ||||
| _dest.write(code) | _dest.write(code) | ||||
| return os.path.abspath(project_path) | |||||
| def execute_simulation(project, data=None): | def execute_simulation(project, data=None): | ||||
| """ Execute a simulation with 'data' """ | """ Execute a simulation with 'data' """ |
| from project_base import SimulationProject | |||||
| import os, re | |||||
| import inspect | |||||
| PROJECTS_REPOSITORY = 'projects' | |||||
| class ProjectReader: | |||||
| def __init__(self): | |||||
| pass | |||||
| def get_projects(self): | |||||
| projects = {} | |||||
| for root, repositories, files in os.walk(PROJECTS_REPOSITORY): | |||||
| for filename in files: | |||||
| if re.fullmatch(r'.*project.*\.py', filename): | |||||
| # Encapsulation the project | |||||
| complete_filename = root+'/'+filename | |||||
| globals = { | |||||
| #'__builtins__': {'__build_class__': __build_class__}, | |||||
| 'SimulationProject': SimulationProject, | |||||
| } | |||||
| locals = {} | |||||
| # Read the project code | |||||
| with open(complete_filename, 'r') as _file: | |||||
| project = '\n'.join(_file.readlines()) | |||||
| exec(project, globals, locals) | |||||
| # Extract the simulations | |||||
| for key, obj in locals.items(): | |||||
| if inspect.isclass(obj) and issubclass(obj, SimulationProject): | |||||
| if key in projects: | |||||
| print('Warning! Multiplie simulation with the same name. Simulation ignored: {} in {}'.format(key, complete_filename[len(PROJECTS_REPOSITORY)+1:])) | |||||
| else: | |||||
| obj.set_project_directory(root[len(PROJECTS_REPOSITORY)+1:]) | |||||
| projects[key] = obj | |||||
| return projects | |||||
| def get_project_classes(self): | |||||
| return self.get_projects().values() |
| ### In this file is defined a Python class to manipulate the simualtion project. | |||||
| ### - This class must be inherited from th class 'SimulationProject' (no need to import it) | |||||
| ### - You can use here the function "write(input_file, uint, nb_bits=16)" | |||||
| ### to write an integer of 'nb_bits' bits in the 'input_file' (no need to import it too). | |||||
| ### To get this simulation class in Python scripts, please use the functions in manage.py as | |||||
| ### - search_simulations(repository) | |||||
| ### - get_simulation(repository, classname=None) | |||||
| ### - get_simulation_via_classname(classname) | |||||
| class KyberNTTSimulation(SimulationProject): | class KyberNTTSimulation(SimulationProject): | ||||
| @classmethod | @classmethod | ||||
| def get_binary(cl): | def get_binary(cl): |
| from listeningthread import ListeningThread | |||||
| from executorthread import ExecutorThread | |||||
| from .servicethread import ListeningThread | |||||
| from .executorthread import ExecutorThread | |||||
| def do_main_program(projects): | def do_main_program(projects): | ||||
| global thread, stop | global thread, stop | ||||
| stop = False | stop = False | ||||
| # Information | # Information | ||||
| from project_reader import ProjectReader | |||||
| reader = ProjectReader() | |||||
| projects = {sc.get_project_label(): sc for sc in reader.get_project_classes()} | |||||
| print('Available projects: %s' % list(projects.keys())) | |||||
| from .manage import search_simulations | |||||
| projects = {sc.get_project_label(): sc for sc in search_simulations_in_module().values()} | |||||
| print('Available module projects: %s' % list(projects.keys())) | |||||
| print('') | print('') | ||||
| # Execute | # Execute |
| self._is_running = False | self._is_running = False | ||||
| class ListeningThread(PermanentServiceThread): | |||||
| def __init__(self, host, port, threadclass, **kwargs): | |||||
| super().__init__() | |||||
| self.hostname = host | |||||
| self.port = port | |||||
| self.threadclass = threadclass | |||||
| self.kwargs = kwargs | |||||
| def execute(self): | |||||
| self.tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||||
| self.tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) | |||||
| self.tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) | |||||
| # self.tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_ATTACH_REUSEPORT_CBPF, 1) | |||||
| self.tcpsock.bind((self.hostname, self.port)) | |||||
| self.tcpsock.listen(5) | |||||
| print('[port][%s] Listening' % self.port) | |||||
| while self.is_running(): | |||||
| try: | |||||
| (clientsocket, (ip, port)) = self.tcpsock.accept() | |||||
| print('[port][{}] Accepted: {} <=> {}'.format( | |||||
| self.port, | |||||
| clientsocket.getsockname(), | |||||
| clientsocket.getpeername(), | |||||
| )) | |||||
| newthread = self.threadclass(ip, port, clientsocket, **self.kwargs) | |||||
| newthread.start() | |||||
| except socket.timeout: | |||||
| pass | |||||
| def stop(self): | |||||
| super().stop() | |||||
| clientsocker = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | |||||
| clientsocker.connect( (self.hostname, self.port) ) | |||||
| self.tcpsock.close() | |||||
| print('[port][%s] Stop listening' % self.port) |
| ### In this file is defined a Python class to manipulate the simualtion project. | |||||
| ### - This class must be inherited from th class 'SimulationProject' (no need to import it) | |||||
| ### - You can use the function "write(input_file, uint, nb_bits=16)" | |||||
| ### to write an integer of 'nb_bits' bits in the 'input_file'. | |||||
| ### To get this simulation class in Python scripts, please use the functions in manage.py as | |||||
| ### - search_simulations(repository) | |||||
| ### - get_simulation(repository, classname=None) | |||||
| ### - get_simulation_via_classname(classname) | |||||
| class {{PROJECTCLASSNAME}}(SimulationProject): | class {{PROJECTCLASSNAME}}(SimulationProject): | ||||
| @classmethod | @classmethod | ||||
| def get_binary(cl): | def get_binary(cl): |