-
Notifications
You must be signed in to change notification settings - Fork 0
/
run.py
182 lines (152 loc) · 7.08 KB
/
run.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#!/usr/bin/env python3
import os
import sys
import argparse
import subprocess
import platform
import signal
# Set constants
WEBGLITCH_PATH = '/Users/matthew/Documents/msc/final_proj/WebGlitch/'
WEBGLITCH_RUNNER_PATH = '/Users/matthew/Documents/msc/final_proj/WebGlitchRunner/'
DENO_PATH = '/Users/matthew/Documents/msc/final_proj/deno/target/x86_64-unknown-linux-gnu/debug/deno'
CHROME_PATH = "/Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary"
FIREFOX_PATH = "/Applications/Firefox Nightly.app/Contents/MacOS/firefox"
MACOS_INTERCEPTORS = "DYLD_INSERT_LIBRARIES=/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/16/lib/darwin/libclang_rt.asan_osx_dynamic.dylib"
LINUX_INTERCEPTORS = 'LD_PRELOAD=/usr/lib/gcc/x86_64-linux-gnu/11/libasan.so'
# DON'T CHANGE THESE
REPORTS_PATH = WEBGLITCH_RUNNER_PATH + 'reports/'
HEADER_PATH = WEBGLITCH_RUNNER_PATH + 'headers/'
CONCATENATED_NAME = WEBGLITCH_RUNNER_PATH + 'concatenated.js'
PUPPETEER_SCRIPT_PATH= WEBGLITCH_PATH + "rsrcs/js/puppeteer.js"
SERVER_DIRECTORY = WEBGLITCH_PATH + 'rsrcs/html'
SUPPORTED_BROWSERS = ['chrome', 'firefox']
SUPPORTED_RUNTIMES = ['dawn', 'wgpu']
PORT = 8080
HTTP_SERVER_CMD = f'npx http-server {SERVER_DIRECTORY} -p {PORT}'
# Detect OS type
OSTYPE = platform.system().lower()
server_process = None
if 'darwin' in OSTYPE:
OS_DIR = 'macos'
INTERCEPTORS = MACOS_INTERCEPTORS
TIMEOUT_CMD = 'gtimeout'
WGPU_BACKEND = 'DENO_WEBGPU_BACKEND=metal'
os.environ['MTL_DEBUG_LAYER'] = '1'
elif 'windows' in OSTYPE:
OS_DIR = 'windows'
WGPU_BACKEND = 'DENO_WEBGPU_BACKEND=dx12'
TIMEOUT_CMD=""
INTERCEPTORS=""
else:
OS_DIR = 'linux'
INTERCEPTORS = LINUX_INTERCEPTORS
TIMEOUT_CMD = 'timeout'
WGPU_BACKEND = 'DENO_WEBGPU_BACKEND=vulkan'
os.environ['VK_INSTANCE_LAYERS'] = 'VK_LAYER_KHRONOS_validation'
# Set common environment variables
os.environ['DAWN_DEBUG_BREAK_ON_ERROR'] = '1'
# Function to search for specific lines in a file
def search_errors_enabled_disabled(input_file, output_file):
with open(input_file, 'r') as infile, open(output_file, 'w') as outfile:
for line in infile:
if 'Errors enabled' in line or 'Errors disabled' in line:
outfile.write(line)
# def signal_handler(sig, frame):
# if server_process is not None and server_process.poll() is None:
# server_process.terminate()
# sys.exit(0)
# signal.signal(signal.SIGINT, signal_handler)
def main():
# Parse command-line arguments
parser = argparse.ArgumentParser(description='Process WebGPU programs.')
parser.add_argument('-b', '--backend', required=True, choices=['all', 'dawn', 'wgpu', 'chrome', 'firefox', 'all_runtimes', 'all_browsers'], help='WebGPU implementation to run on')
parser.add_argument('-o', '--output', required=True, help='WebGPU program to run')
args = parser.parse_args()
backend = args.backend
FILEPATH = args.output
# Check if FILEPATH exists
if not os.path.isfile(FILEPATH):
print(f"Error: WebGPU program '{FILEPATH}' does not exist.")
sys.exit(1)
PLATFORM_MAPPINGS = {
'dawn': {
'header_path': 'dawnHeader.js',
'cmd': [TIMEOUT_CMD, '300s', 'env', INTERCEPTORS, 'node', CONCATENATED_NAME]
},
'wgpu': {
'header_path': 'denoHeader.js',
'cmd': [TIMEOUT_CMD, '300s', 'env', WGPU_BACKEND, DENO_PATH, 'run', '--allow-read', '--unstable-webgpu', '--allow-write', CONCATENATED_NAME]
},
'chrome': {
'cmd': ['node', PUPPETEER_SCRIPT_PATH, FILEPATH],
'path': CHROME_PATH,
'browser_type': "chrome"
},
'firefox': {
'cmd': ['node', PUPPETEER_SCRIPT_PATH, FILEPATH],
'path': FIREFOX_PATH,
'browser_type': "firefox"
}
}
# Create reports directories if they do not exist
for platform in (SUPPORTED_BROWSERS + SUPPORTED_RUNTIMES):
os.makedirs(os.path.join(REPORTS_PATH, platform, OS_DIR), exist_ok=True)
# Extract filename and file number
FILENAME = os.path.basename(FILEPATH)
FILENUMBER = os.path.splitext(FILENAME)[0]
if backend == 'all':
platforms_to_run = SUPPORTED_BROWSERS + SUPPORTED_RUNTIMES
elif backend == 'all_browsers':
platforms_to_run = SUPPORTED_BROWSERS
elif backend == 'all_runtimes':
platforms_to_run = SUPPORTED_RUNTIMES
elif backend in (SUPPORTED_BROWSERS + SUPPORTED_RUNTIMES):
platforms_to_run = [backend]
else:
print(f'Unsupported backend: {backend}')
sys.exit(1)
# if any(platform in SUPPORTED_BROWSERS for platform in platforms_to_run):
# try:
# if 'windows' in OSTYPE:
# server_process = subprocess.Popen(['cmd', '/c', HTTP_SERVER_CMD], shell=True)
# else:
# server_process = subprocess.Popen(HTTP_SERVER_CMD, shell=True, executable='/bin/bash')
# except subprocess.CalledProcessError as e:
# print(f"Failed to start http-server on port {port}: {e}")
# print("Continuing regardless...")
try:
for platform in platforms_to_run:
if platform in SUPPORTED_RUNTIMES:
with open(CONCATENATED_NAME, 'w') as outfile:
with open(os.path.join(HEADER_PATH, PLATFORM_MAPPINGS[platform]['header_path']), 'r') as headerfile:
outfile.write(headerfile.read())
with open(FILEPATH, 'r') as infile:
outfile.write(infile.read())
if platform in SUPPORTED_BROWSERS:
os.environ['EXECUTABLE_PATH'] = PLATFORM_MAPPINGS[platform]['path']
os.environ['BROWSER'] = PLATFORM_MAPPINGS[platform]['browser_type']
else: # remove browser-specific code
current_dir = os.path.dirname(os.path.abspath(__file__))
comment_out_script_path = current_dir + '/commentOut.py'
subprocess.run(['python3', comment_out_script_path, CONCATENATED_NAME], check=True)
print("Running using " + platform + "...")
LOG_FILE_NAME = os.path.join(REPORTS_PATH, platform, OS_DIR, f'{FILENUMBER}.log')
search_errors_enabled_disabled(FILEPATH, LOG_FILE_NAME)
# Build the command with environment variables inline
with open(LOG_FILE_NAME, 'a') as logfile:
process = subprocess.run(PLATFORM_MAPPINGS[platform]['cmd'], stdout=logfile, stderr=subprocess.STDOUT, timeout=300)
exit_code = process.returncode
logfile.write(f"Exit code: {exit_code}\n")
# Delete the concatenated file
if platform in SUPPORTED_RUNTIMES:
os.remove(CONCATENATED_NAME)
os.environ.pop('EXECUTABLE_PATH', None)
os.environ.pop('BROWSER', None)
except Exception as e:
print(f"Error: {e}")
# finally:
# if server_process is not None and server_process.poll() is None:
# print("Terminating http-server...")
# server_process.terminate()
if __name__ == "__main__":
main()