55import warnings
66from abc import ABC , abstractmethod
77from contextlib import contextmanager
8+ from datetime import datetime
89from urllib import parse as urlparser
910
1011__all__ = ['ClamsApp' ]
@@ -44,6 +45,14 @@ class ClamsApp(ABC):
4445 'name' : 'pretty' , 'type' : 'boolean' , 'choices' : None , 'default' : False , 'multivalued' : False ,
4546 'description' : 'The JSON body of the HTTP response will be re-formatted with 2-space indentation' ,
4647 },
48+ {
49+ 'name' : 'runningTime' , 'type' : 'boolean' , 'choices' : None , 'default' : False , 'multivalued' : False ,
50+ 'description' : 'The running time of the app will be recorded in the view metadata' ,
51+ },
52+ {
53+ 'name' : 'hwFetch' , 'type' : 'boolean' , 'choices' : None , 'default' : False , 'multivalued' : False ,
54+ 'description' : 'The hardware information (architecture, GPU and vRAM) will be recorded in the view metadata' ,
55+ },
4756 ]
4857
4958 # this key is used to store users' raw input params in the parameter dict
@@ -136,6 +145,7 @@ def annotate(self, mmif: Union[str, dict, Mmif], **runtime_params: List[str]) ->
136145 refined = self ._refine_params (** runtime_params )
137146 self .logger .debug (f"Refined parameters: { refined } " )
138147 pretty = refined .get ('pretty' , False )
148+ t = datetime .now ()
139149 with warnings .catch_warnings (record = True ) as ws :
140150 annotated = self ._annotate (mmif , ** refined )
141151 if ws :
@@ -144,6 +154,27 @@ def annotate(self, mmif: Union[str, dict, Mmif], **runtime_params: List[str]) ->
144154 warnings_view = annotated .new_view ()
145155 self .sign_view (warnings_view , refined )
146156 warnings_view .metadata .warnings = issued_warnings
157+ td = datetime .now () - t
158+ runningTime = refined .get ('runningTime' , False )
159+ hwFetch = refined .get ('hwFetch' , False )
160+ runtime_recs = {}
161+ if hwFetch :
162+ import platform , shutil , subprocess
163+ runtime_recs ['architecture' ] = platform .machine ()
164+ # runtime_recs['processor'] = platform.processor() # this only works on Windows
165+ runtime_recs ['cuda' ] = []
166+ if shutil .which ('nvidia-smi' ):
167+ for gpu in subprocess .run (['nvidia-smi' , '--query-gpu=name,memory.total' , '--format=csv,noheader' ],
168+ stdout = subprocess .PIPE ).stdout .decode ('utf-8' ).strip ().split ('\n ' ):
169+ name , mem = gpu .split (', ' )
170+ runtime_recs ['cuda' ].append (f'{ name } ({ mem } )' )
171+ for annotated_view in annotated .views :
172+ if annotated_view .metadata .app == self .metadata .identifier :
173+ if runningTime :
174+ annotated_view .metadata .set_additional_property ('appRunningTime' , str (td ))
175+ if len (runtime_recs ) > 0 :
176+ annotated_view .metadata .set_additional_property ('appRunningHardware' , runtime_recs )
177+
147178 return annotated .serialize (pretty = pretty , sanitize = True )
148179
149180 @abstractmethod
0 commit comments