PyXMake Developer Guide  1.0
PyXMake
D:/03_Workspaces/01_Eclipse/pyx_core/PyXMake/VTL/ssh_ifort.py
1 # -*- coding: utf-8 -*-
2 # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 # % PyXMake - Build environment for PyXMake %
4 # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
5 """
6 Triple-use minimum working example for PyXMake. This script can be
7 executed in three different ways in varying levels of accessibility
8 
9 @note: Compile Fortran source on the institute cluster.
10  Uses main function
11 
12 @version: 1.0
13 ----------------------------------------------------------------------------------------------
14 @requires:
15  - PyXMake
16  - SSH key
17 
18 @author: garb_ma [DLR-FA,STM Braunschweig]
19 ----------------------------------------------------------------------------------------------
20 """
21 import os, sys
22 import argparse
23 import posixpath
24 
25 try:
26  import PyXMake as _
27 except ImportError:
28  # Script is executed as a plug-in
29  sys.path.insert(0,os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
30 finally:
31  from PyXMake.Build import Make as pyx #@UnresolvedImport
32  from PyXMake.Tools import Utility #@UnresolvedImport
33  from PyXMake import VTL #@UnresolvedImport
34 
35 # Predefined script local variables
36 __user = os.getenv("username")
37 __mcd_cluster_dev = posixpath.join(Utility.AsDrive("home",posixpath.sep),__user,"mcodac")
38 __mcd_cluster_incpath = posixpath.join(__mcd_cluster_dev,"include")
39 __mcd_cluster_libpath = posixpath.join(__mcd_cluster_dev,"lib")
40 
41 try:
42  # Import PyCODAC to build library locally during setup.
43  from PyCODAC.Tools.Utility import GetPyCODACPath
44  # Import and set local path to PyCODAC
45  __mcd_core_path = os.path.join(GetPyCODACPath(),"Core")
46 except ImportError:
47  # This script is not executed as plug-in
48  __mcd_core_path = ""
49 except:
50  # Something else went wrong.
51  from PyXMake.Tools import ErrorHandling
52  ErrorHandling.InputError(20)
53 
54 def main(
55  # Mandatory arguments
56  BuildID, user, key,
57  # Build MCODAC by default
58  files=VTL.GetSourceCode(0),
59  command=VTL.GetBuildCommand(5),
60  # Resource paths
61  source=os.path.join(__mcd_core_path,"src"),
62  include=[posixpath.join(__mcd_cluster_incpath, x) for x in VTL.GetIncludeDirectory(__mcd_core_path, 0, 4, "x64")],
63  make=__mcd_cluster_dev,
64  link=[posixpath.join(__mcd_cluster_libpath,"libinterpx64.a"),
65  posixpath.join(__mcd_cluster_libpath,"libpchipx64.a"),
66  posixpath.join(__mcd_cluster_libpath,"libbbeamx64.a"),
67  posixpath.join(__mcd_cluster_libpath,"libmueslix64.a"),
68  posixpath.join(__mcd_cluster_libpath,"libdispmodulex64.a"),
69  posixpath.join(__mcd_cluster_libpath,"libtomsx64.a")],
70  # Bash environment scripts
71  environment = VTL.GetEnvironment(0),
72  # Architecture, verbose and scratch directory (on host)
73  architecture="x64", scratch=VTL.Scratch, verbosity=0,
74  # Activate / deactivate incremental compilation. Does deactivate pre-processing.
75  incremental = False,
76  # Host and port number. Access DLR's institute cluster by default.
77  host="129.247.54.37", port=22,
78  # Additional keyword arguments
79  **kwargs):
80  """
81  Main function to execute the script.
82  """
83  # Evaluate input parameters
84  envlist = list([]); envlist.append(environment); envlist = list(Utility.ArbitraryFlattening(envlist))
85  makelist = list([]); makelist.append(make); makelist = list(Utility.ArbitraryFlattening(makelist))
86  precommand= kwargs.get("precommand",""); replace = kwargs.get('replace', False)
87  # Remote build using SSH connection.
88  SSHBuild = pyx.SSH(BuildID, files, scratch=scratch, arch=architecture, verbose=verbosity, incremental=incremental)
89  # Combine source code using wrapper module
90  if not incremental:
91  SSHBuild.Wrapper(BuildID)
92  SSHBuild.SourcePath(source)
93  SSHBuild.AddIncludePath(include)
94  # Load environments successively (if given)
95  for x in envlist:
96  SSHBuild.Environment(bash=x)
97  try:
98  # Module & library path are not relative to each other
99  SSHBuild.OutputPath(modulepath=makelist[0], libpath=makelist[1])
100  except:
101  # Module & library path are relative to each other.
102  SSHBuild.OutputPath(modulepath=posixpath.join(makelist[0],"include"), libpath=posixpath.join(makelist[0],"lib"))
103  if isinstance(replace,dict):
104  SSHBuild.Preprocessing(precommand,inend='.for', outend='.f90', replace=replace)
105  # Activate / deactivate incremental compilation & linking
106  elif incremental:
107  SSHBuild.Preprocessing(copyfiles=files)
108  else:
109  SSHBuild.Preprocessing(precommand,inend='.for', outend='.f90')
110  SSHBuild.Build(command, linkedIn=link)
111  SSHBuild.Settings(user, key, host, port)
112  SSHBuild.create(**kwargs)
113 
114 if __name__ == "__main__":
115 # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
116 # % Access command line inputs %
117 # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
118  parser = argparse.ArgumentParser(description="Build a static Fortran library remotely on the institute cluster")
119  parser.add_argument("user", metavar="user", nargs=1, help="Current user for SSH connection")
120  parser.add_argument("key", metavar="key", nargs=1, help="Path to private SSH key")
121 
122  try:
123  _ = sys.argv[1]
124  args, _ = parser.parse_known_args()
125  except:
126  pass
127 
128  try:
129  # SSH key informations
130  user = args.user[0]
131  key = args.key[0]
132  except:
133  # Default settings. Retain pristine version of this script and build all static Fortran libraries associated with MCODAC.
134  user =__user
135  key = os.path.join(Utility.AsDrive("C"),"Users",user,"Keys","Putty","id_rsa")
136 
137  # Build BoxBeam; Define files to be processed for BoxBeam
138  box_source = os.path.join(__mcd_core_path,"external","boxbeam")
139  box_make = [posixpath.join(__mcd_cluster_dev,"include","boxbeam"), posixpath.join(__mcd_cluster_dev,"lib")]
140  main('bbeam', user, key, files=VTL.GetSourceCode(1), source=box_source, include=[], make=box_make, link=[])
141 
142  # Build DispModule; Define files to be processed for DispModule
143  disp_source=os.path.join(__mcd_core_path,"external","dispmodule","Fortran90","Src")
144  disp_make = [posixpath.join(__mcd_cluster_dev,"include","dispmodule"), posixpath.join(__mcd_cluster_dev,"lib")]
145  main("dispmodule" , user, key, files=VTL.GetSourceCode(5), command=VTL.GetBuildCommand(5, "free"), source=disp_source,
146  include=[], make=disp_make, link=[], incremental=True)
147 
148  # Compile all low-level external libraries used by MCODAC using Intel Fortran.
149  # Files to be processed by low-level libraries
150  BuildIDs = [os.path.splitext(x)[0].lower() for x in VTL.GetSourceCode(6)]
151  for BuildID in BuildIDs:
152  srcfile = [x for x in VTL.GetSourceCode(6) if x.startswith(BuildID)]
153  # Mixed format compilation
154  style = "fixed"; combine=False
155  if not BuildID.endswith("790"):
156  style = "free"; combine=True
157  # Define files to be processed for TOMS
158  toms_source = os.path.join(__mcd_core_path,"external","toms")
159  make = [posixpath.join(__mcd_cluster_dev,"include","toms"),posixpath.join(__mcd_cluster_dev,"lib")]
160  # Wrap the original source code and put all subroutines & functions in a module
161  main(BuildID, user, key, files=srcfile, command=VTL.GetBuildCommand(5, style+" -DPYX_WRAPPER"), make=make,
162  combine=combine, source=toms_source, include=[], libs=[], link=[])
163 
164  # Name mangling without changing the original source code. Rename procedures to avoid conflicts in final software.
165  pchip_replace = {'FUNCTION RAND ( R )':'FUNCTION RAND ( R ) BIND(C, NAME="pchip_rand")',
166  'subroutine timestamp ( )':'subroutine timestamp ( ) BIND(C, NAME="pchip_timestamp")'}
167 
168  # Compile all low-level external libraries used by MCODAC using Intel Fortran.
169  # Files to be processed by low-level libraries
170  BuildIDs = [os.path.splitext(x)[0].lower() for x in VTL.GetSourceCode(7)]
171  for BuildID in BuildIDs:
172  srcfile = [x for x in VTL.GetSourceCode(7) if x.startswith(BuildID)]
173  # Define files to be processed for NMS, PCHIP, SLATEC & INTERP
174  source = os.path.join(__mcd_core_path,"external",BuildID)
175  if BuildID == "pchip":
176  main(BuildID, user, key, files=srcfile, command=VTL.GetBuildCommand(5, "free"),
177  source=source, include=[], link=[],
178  precommand="fpp -P", replace=pchip_replace)
179  else:
180  main(BuildID, user, key, files=srcfile, command=VTL.GetBuildCommand(5, "free"), source=source, include=[], link=[])
181 
182  # Build MCODAC (default settings)
183  main('mcd_core', user, key)
184  else:
185  # This is not implemented yet.
186  raise NotImplementedError
187 
188  # Finish
189  print("==================================")
190  print("Finished")
191  print("==================================")
192  sys.exit()
Module containing basic functionalities defined for convenience.
Definition: __init__.py:1
def main(BuildID, user, key, files=VTL.GetSourceCode(0), command=VTL.GetBuildCommand(5), source=os.path.join(__mcd_core_path,"src"), include=[posixpath.join(__mcd_cluster_incpath, x) for x in VTL.GetIncludeDirectory(__mcd_core_path, 0, 4, "x64")], make=__mcd_cluster_dev, link=[posixpath.join(__mcd_cluster_libpath,"libinterpx64.a"), posixpath, join, __mcd_cluster_libpath, libpchipx64, a, posixpath, join, __mcd_cluster_libpath, libbbeamx64, a, posixpath, join, __mcd_cluster_libpath, libmueslix64, a, posixpath, join, __mcd_cluster_libpath, libdispmodulex64, a, posixpath, join, __mcd_cluster_libpath, libtomsx64, a, environment=VTL.GetEnvironment(0), architecture="x64", scratch=VTL.Scratch, verbosity=0, incremental=False, host="129.247.54.37", port=22, kwargs)
Definition: ssh_ifort.py:79
Module containing all relevant modules and scripts associated with the building process.
Definition: __init__.py:1