Python-ELMO is a Python library which offers an encapsulation of the binary tool ELMO, in order to manipulate it easily in Python and SageMath script.
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

manage.py 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. import os, shutil
  2. import re
  3. import inspect
  4. import subprocess
  5. def search_simulations(repository, criteria=lambda x:True, search_also_in_module=True):
  6. """ To search simulation classes in the 'repository' verifying the 'criteria' """
  7. projects = {}
  8. from .project_base import SimulationProject, write
  9. for root, repositories, files in os.walk(repository):
  10. for filename in files:
  11. if re.fullmatch(r'.*project.*\.py', filename):
  12. # Encapsulation the project
  13. complete_filename = root+'/'+filename
  14. globals = {
  15. #'__builtins__': {'__build_class__': __build_class__},
  16. 'SimulationProject': SimulationProject,
  17. 'write': write,
  18. }
  19. locals = {}
  20. # Read the project code
  21. with open(complete_filename, 'r') as _file:
  22. project = '\n'.join(_file.readlines())
  23. exec(project, globals, locals)
  24. # Extract the simulations
  25. for key, obj in locals.items():
  26. if inspect.isclass(obj) and issubclass(obj, SimulationProject):
  27. if criteria(obj):
  28. if key in projects:
  29. print('Warning! Multiplie simulation with the same name. Simulation ignored: {} in {}'.format(key, complete_filename[len(repository)+1:]))
  30. else:
  31. obj.set_project_directory(os.path.abspath(root))
  32. projects[key] = obj
  33. if search_also_in_module:
  34. module_path = os.path.dirname(os.path.abspath(__file__))
  35. module_projects = search_simulations(module_path+'/projects', criteria=lambda x:True, search_also_in_module=False)
  36. for key, project in module_projects.items():
  37. if key not in projects:
  38. projects[key] = project
  39. return projects
  40. class SimulationNotFoundError(Exception):
  41. pass
  42. class TooManySimulationsError(Exception):
  43. pass
  44. def get_simulation(repository, classname=None):
  45. """ Get a simulation class in the 'repository' with the specific 'classname' """
  46. criteria = lambda x: True
  47. if classname is not None:
  48. criteria = lambda x: x.__name__ == classname.strip()
  49. projects = search_simulations(repository, criteria)
  50. if len(projects) == 1:
  51. return list(projects.values())[0]
  52. elif len(projects) < 1:
  53. raise SimulationNotFoundError()
  54. else:
  55. raise TooManySimulationsError()
  56. def get_simulation_via_classname(classname):
  57. return get_simulation('.', classname)
  58. def create_simulation(repository, classname, verbose=True):
  59. """ Create a simulation class """
  60. try:
  61. os.makedirs(repository, exist_ok=False)
  62. except FileExistsError as err:
  63. raise FileExistsError('Error, a project with this repository already exists!') from err
  64. module_path = os.path.dirname(os.path.abspath(__file__))
  65. elmo_path = module_path+'/elmo'
  66. template_path = module_path+'/templates'
  67. project_path = repository
  68. ### Add contents in the project
  69. files_from_ELMO = [
  70. 'Examples/elmoasmfunctions.o',
  71. 'Examples/elmoasmfunctions.s',
  72. 'Examples/elmoasmfunctionsdef.h',
  73. 'Examples/DPATraces/MBedAES/vector.o',
  74. ]
  75. files_from_templates = [
  76. 'elmoasmfunctionsdef-extension.h',
  77. 'Makefile',
  78. 'project.c'
  79. ]
  80. for filename in files_from_ELMO:
  81. shutil.copy(elmo_path+'/'+filename, project_path)
  82. for filename in files_from_templates:
  83. shutil.copy(template_path+'/'+filename, project_path)
  84. shutil.copy(elmo_path+'/'+'Examples/DPATraces/MBedAES/MBedAES.ld', project_path+'/'+'project.ld')
  85. ### Create the project class
  86. with open(template_path+'/projectclass.py') as _source:
  87. code = ''.join(_source.readlines())
  88. code = code.replace('{{PROJECTCLASSNAME}}', classname)
  89. with open(project_path+'/'+'projectclass.py', 'w') as _dest:
  90. _dest.write(code)
  91. def execute_simulation(project, data=None):
  92. """ Execute a simulation with 'data' """
  93. # Make the compilation
  94. if False:
  95. print('Compiling binary...')
  96. # Adapt the project source
  97. with open('binaries/Frodo/frodo-base.c', 'r') as _src_file:
  98. content = _src_file.read()
  99. with open('binaries/Frodo/frodo.c', 'w') as _dst_file:
  100. _dst_file.write(content.replace('%NEED_TO_FILL%', str(n)))
  101. # Compile the project
  102. make_directory = 'projects/{}/{}'.format(project.get_project_directory(), project.get_make_directory())
  103. process = subprocess.Popen('make', shell=True, cwd=make_directory, executable='/bin/bash', stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  104. output, error = process.communicate()
  105. if error and ('error' in error.decode('latin-1')):
  106. print("Error to compile")
  107. print(error)
  108. raise Exception()
  109. # Save last compilation data
  110. global_variables[project_name] = {
  111. 'last_n': n,
  112. }
  113. # Generate the trace by launching ELMO
  114. command = './elmo {}/{}'.format(
  115. project.get_project_directory(),
  116. project.get_binary()
  117. )
  118. cwd = os.path.dirname(os.path.abspath(__file__))+'/elmo'
  119. process = subprocess.Popen(command, shell=True, cwd=cwd, executable='/bin/bash', stdout=subprocess.PIPE)
  120. output, error = process.communicate()
  121. # Return results
  122. return (
  123. output.decode('latin-1') if output else None,
  124. error.decode('latin-1') if error else None,
  125. )