Skip to content

Commit 712bdb8

Browse files
committed
Merge branch 'release-2.0.x'
2 parents fac6c96 + ef69fd3 commit 712bdb8

385 files changed

Lines changed: 23874 additions & 6535 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
DPCPP_VERSION=intel-llvm/nightly-2023-09-22-rk

.github/deps/gfx-linux-public.env

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
GFX_DRIVER_VERSION=linux-latest
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
GFX_DRIVER_VERSION=windows-101.4826
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
## Copyright 2023 Intel Corporation
2+
## SPDX-License-Identifier: Apache-2.0
3+
4+
PrintDebugSettings=1
5+
NEOReadDebugKeys=1
6+
7+
# Run it on single tile (disable implicit scaling)
8+
EnableImplicitScaling=0
9+
10+
# Force native SIMD width for PVC
11+
IGC_ForceOCLSIMDWidth=16

.github/scripts/run-benchmarks.sh

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/bin/bash -xe
2+
3+
## Copyright 2023 Intel Corporation
4+
## SPDX-License-Identifier: Apache-2.0
5+
6+
BENCHMARK_DEVICE=$1
7+
case "$BENCHMARK_DEVICE" in
8+
"CPU" | "GPU")
9+
echo "Going to run benchmarks on $BENCHMARK_DEVICE device"
10+
;;
11+
12+
*)
13+
echo "$BENCHMARK_DEVICE is not valid device, please use CPU or GPU"
14+
exit 1
15+
;;
16+
esac
17+
18+
SOURCE_ROOT=$GITHUB_WORKSPACE
19+
PROJECT_NAME="Open VKL"
20+
BENCHMARK_FLAGS="--benchmark_repetitions=5 --benchmark_min_time=10"
21+
22+
23+
24+
################################# PLEASE READ ##################################
25+
#
26+
# Note that suites and subsuites must exist in the database _before_ attempting
27+
# insertion of results. This is intentional! You should think carefully about
28+
# your [suite -> subsuite -> benchmark] hierarchy and definitions. These should
29+
# be stable over time (especially for suites and subsuites) to facilitate
30+
# long-term comparisons.
31+
#
32+
# These can be inserted using the benchmark client, through the "ls"
33+
# and "insert subsuite" commands. Ask for help if you have questions.
34+
#
35+
################################# PLEASE READ ###################################
36+
37+
initContext() {
38+
if [ -z "$HAVE_CONTEXT" ]; then
39+
HAVE_CONTEXT=1
40+
benny insert code_context "${PROJECT_NAME}" ${SOURCE_ROOT} --save-json code_context.json
41+
benny insert run_context ${BENNY_SYSTEM_TOKEN} ./code_context.json --save-json run_context.json
42+
fi
43+
}
44+
45+
46+
SUITE_NAME="ExampleRenderers"
47+
48+
initContext
49+
50+
SUBSUITE_NAME="StructuredVolume"
51+
SUBSUITE_REGEX="structured_regular"
52+
./bin/vklBenchmark${BENCHMARK_DEVICE} ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json
53+
benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json
54+
55+
SUBSUITE_NAME="VDBVolume"
56+
SUBSUITE_REGEX="vdb"
57+
./bin/vklBenchmark${BENCHMARK_DEVICE} ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json
58+
benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json
59+
60+
SUBSUITE_NAME="UnstructuredVolume"
61+
SUBSUITE_REGEX="unstructured"
62+
./bin/vklBenchmark${BENCHMARK_DEVICE} ${BENCHMARK_FLAGS} --benchmark_filter=${SUBSUITE_REGEX} --benchmark_out=results-${SUITE_NAME}-${SUBSUITE_NAME}.json
63+
benny insert googlebenchmark ./run_context.json ${SUITE_NAME} ${SUBSUITE_NAME} ./results-${SUITE_NAME}-${SUBSUITE_NAME}.json
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
#!/bin/bash -xe
2+
## Copyright 2023 Intel Corporation
3+
## SPDX-License-Identifier: Apache-2.0
4+
5+
# These tests are to verify if rendered image is correct for big volume size on PVC.
6+
# `time` command used here is just to see what is total execution time (for roughly estimation).
7+
8+
IMG_DIFF_TOOL=$STORAGE_PATH/tools/img_diff/img_diff
9+
10+
# Enable persistent JIT cache
11+
export SYCL_CACHE_PERSISTENT=1
12+
export SYCL_CACHE_DIR=./jit_cache
13+
14+
# dim = 2048^3*sizeof(float) for float give us 32GB of vol. size
15+
dim=2048
16+
17+
time ./bin/vklExamplesGPU -renderer density_pathtracer_gpu -batch -printStats -spp 50 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
18+
time ./bin/vklExamplesGPU -renderer ray_march_iterator_gpu -batch -printStats -spp 2 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
19+
time ./bin/vklExamplesGPU -renderer hit_iterator_renderer_gpu -batch -printStats -spp 2 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
20+
time ./bin/vklExamplesGPU -renderer interval_iterator_debug_gpu -batch -printStats -spp 2 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
21+
22+
# Run cpu examples to get reference images
23+
time ./bin/vklExamplesCPU -renderer density_pathtracer -batch -printStats -spp 50 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
24+
time ./bin/vklExamplesCPU -renderer ray_march_iterator -batch -printStats -spp 2 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
25+
time ./bin/vklExamplesCPU -renderer hit_iterator_renderer -batch -printStats -spp 2 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
26+
time ./bin/vklExamplesCPU -renderer interval_iterator_debug -batch -printStats -spp 2 -framebufferSize 1024 1024 -gridDimensions $dim $dim $dim
27+
28+
# Compare images generated by GPU examples vs CPU examples
29+
$IMG_DIFF_TOOL density_pathtracer.pfm density_pathtracer_gpu.pfm
30+
$IMG_DIFF_TOOL ray_march_iterator.pfm ray_march_iterator_gpu.pfm 0.0001
31+
$IMG_DIFF_TOOL hit_iterator_renderer.pfm hit_iterator_renderer_gpu.pfm 0.00005
32+
$IMG_DIFF_TOOL interval_iterator_debug.pfm interval_iterator_debug_gpu.pfm 0.00003
Lines changed: 242 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,242 @@
1+
## Copyright 2023 Intel Corporation
2+
## SPDX-License-Identifier: Apache-2.0
3+
4+
import subprocess
5+
import os
6+
import platform
7+
import sys
8+
import signal
9+
from threading import Timer
10+
11+
# Flag for enabling additional verbose debug info
12+
debug_enabled = True
13+
14+
# Representation of output which goes to console.
15+
# It consist of stdout & stderr.
16+
class Output(object):
17+
stdout: str
18+
stderr: str
19+
def __init__(self, stdout:str, stderr:str):
20+
self.stdout = stdout
21+
self.stderr = stderr
22+
23+
# By default we can get string from instance of this class
24+
# which will return merged stdout with stderr.
25+
def __str__(self):
26+
return self.stdout + self.stderr
27+
28+
class TestCommandTool:
29+
def run(self, cmd, timeout, cwd = os.getcwd(), test_env = os.environ.copy(), print_output = True):
30+
exit_code = 0
31+
proc = subprocess.Popen(cmd, shell=True, cwd=cwd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=None, universal_newlines=True, env=test_env)
32+
33+
# This variable we use to pass value back from
34+
# Timer callback function - _kill.
35+
timeout_flag_wrapper = {'timeout_occured': False}
36+
37+
# We use timer to not hang forever on
38+
# proc.communicate(), in case of timeout
39+
# _kill method will kill process and
40+
# it will return from proc.communicate()
41+
# immediately.
42+
timer = Timer(timeout, self._kill, [proc, timeout_flag_wrapper], {})
43+
timer.start()
44+
stdout, stderr = proc.communicate()
45+
timer.cancel()
46+
exit_code = proc.poll()
47+
48+
if timeout_flag_wrapper["timeout_occured"]:
49+
exit_code = 124
50+
stderr += "=K=> Timeout expired, process was killed."
51+
52+
output = Output(stdout, stderr)
53+
if print_output:
54+
print(output, flush=True)
55+
56+
return (exit_code, output)
57+
58+
def _kill(self, proc_to_kill, timeout_flag_wrapper):
59+
timeout_flag_wrapper["timeout_occured"] = True
60+
pid = proc_to_kill.pid
61+
# Windows
62+
if platform.system() == 'Windows':
63+
proc = subprocess.Popen(['taskkill', '/F', '/T', '/PID', str(pid)], shell=True)
64+
proc.wait()
65+
# Linux
66+
else:
67+
proc = subprocess.Popen('pkill -TERM -P '+ str(pid), shell=True)
68+
proc.wait()
69+
70+
class OpenVKLTestCase:
71+
renderer:str = None
72+
volume_type:str = None
73+
max_mse:float = None
74+
spp:int = None
75+
extra_gpu_args:str = None
76+
77+
__gpu_exit_code:int = None
78+
__gpu_output:Output = None
79+
80+
__cpu_exit_code:int = None
81+
__cpu_output:Output = None
82+
83+
__diff_exit_code:int = None
84+
__diff_output:Output = None
85+
86+
def __init__(self, renderer : str, volume_type : str, extra_gpu_args : str = ''):
87+
self.renderer = renderer
88+
self.volume_type = volume_type
89+
self.max_mse = 0.000001
90+
self.spp = 2
91+
self.extra_gpu_args = extra_gpu_args
92+
93+
# For this particular case we need to set higher MSE treshold
94+
if renderer == "hit_iterator_renderer" and volume_type == "structuredRegular":
95+
self.max_mse = 0.000015
96+
97+
# For density pathtracer we want more spp to get picutre closer to final image
98+
if renderer == "density_pathtracer":
99+
self.spp = 50
100+
101+
def __print_debug(self, msg:str):
102+
if debug_enabled:
103+
print(msg)
104+
105+
def __get_example_cpu_binary_string(self) -> str:
106+
if platform.system() == 'Windows':
107+
return "vklExamplesCPU.exe"
108+
else:
109+
return "./vklExamplesCPU"
110+
111+
def __get_example_gpu_binary_string(self) -> str:
112+
if platform.system() == 'Windows':
113+
return "vklExamplesGPU.exe"
114+
else:
115+
return "./vklExamplesGPU"
116+
117+
def __get_common_params(self) -> str:
118+
return "-batch -framebufferSize 1024 1024"
119+
120+
def get_name(self) -> str:
121+
return "%s-%s%s" % (self.renderer, self.volume_type, self.extra_gpu_args)
122+
123+
def get_result(self) -> int:
124+
return self.__gpu_exit_code + self.__cpu_exit_code + self.__diff_exit_code
125+
126+
def print_error_outputs(self):
127+
# Print output only for commands where exit code != 0
128+
if self.__gpu_exit_code != 0:
129+
print("#!# GPU cmd output:")
130+
print(self.__gpu_output)
131+
132+
if self.__cpu_exit_code != 0:
133+
print("#!# CPU cmd output:")
134+
print(self.__cpu_output)
135+
136+
if self.__diff_exit_code != 0:
137+
print("#!# DIFF cmd output:")
138+
print(self.__diff_output)
139+
140+
def get_MSE(self) -> float:
141+
stdout = self.__diff_output.stdout
142+
# MSE can't be negative and this is how we're returning error
143+
if (len(stdout) == 0) or (":" not in stdout):
144+
return -1.0
145+
return float(stdout.splitlines()[0].split(": ")[1])
146+
147+
def execute(self, img_diff_tool_path:str):
148+
# Default timeout - 60 secs for each command
149+
timeout = 60
150+
151+
# Execute GPU example
152+
gpu_run_cmd = "%s -renderer %s_gpu %s -volumeType %s -spp %d %s" % (self.__get_example_gpu_binary_string(), self.renderer, self.__get_common_params(), self.volume_type, self.spp, self.extra_gpu_args)
153+
self.__print_debug("## Executing: '%s', with timeout: %d" % (gpu_run_cmd, timeout))
154+
self.__gpu_exit_code, self.__gpu_output = TestCommandTool().run(gpu_run_cmd, timeout)
155+
156+
# Execute CPU example
157+
cpu_run_cmd = "%s -renderer %s %s -volumeType %s -spp %d" % (self.__get_example_cpu_binary_string(), self.renderer, self.__get_common_params(), self.volume_type, self.spp)
158+
self.__print_debug("## Executing: '%s', with timeout: %d" % (cpu_run_cmd, timeout))
159+
self.__cpu_exit_code, self.__cpu_output = TestCommandTool().run(cpu_run_cmd, timeout)
160+
161+
# Rename generated images to new name pattern "renderer-volume_type" instead of "renderer"
162+
# so all images can be stored in the same directory. That way we can avoid overriding output image
163+
# by different volume types executions.
164+
src_gpu_file_path = os.path.join(os.getcwd(), "%s_gpu.pfm" % self.renderer)
165+
dst_gpu_file_path = os.path.join(os.getcwd(), "%s-gpu.pfm" % (self.get_name()))
166+
os.rename(src_gpu_file_path, dst_gpu_file_path)
167+
168+
src_cpu_file_path = os.path.join(os.getcwd(), "%s.pfm" % self.renderer)
169+
dst_cpu_file_path = os.path.join(os.getcwd(), "%s-cpu.pfm" % (self.get_name()))
170+
os.rename(src_cpu_file_path, dst_cpu_file_path)
171+
172+
# Calculate difference between GPU & CPU generated image
173+
img_diff_cmd = "%s %s %s %.10f" % (img_diff_tool_path, dst_gpu_file_path, dst_cpu_file_path, self.max_mse)
174+
self.__print_debug("## Executing: '%s', with timeout: %d" % (img_diff_cmd, timeout))
175+
self.__diff_exit_code, self.__diff_output = TestCommandTool().run(img_diff_cmd, timeout)
176+
177+
self.__print_debug("## MSE: %.10f" % self.get_MSE())
178+
self.__print_debug("## Exit codes: %d %d %d" % (self.__gpu_exit_code, self.__cpu_exit_code, self.__diff_exit_code))
179+
180+
def main():
181+
if len(sys.argv) <= 1:
182+
print("#!## [ERROR] First argument must contain path to diff_tool");
183+
return 2
184+
185+
img_diff_tool_path = sys.argv[1]
186+
test_cases = []
187+
188+
# generate test cases
189+
renderer_list = ["density_pathtracer", "ray_march_iterator", "interval_iterator_debug", "hit_iterator_renderer"]
190+
volume_type_list = ["structuredRegular", "structuredSpherical", "unstructured", "particle", "amr", "vdb"]
191+
for renderer in renderer_list:
192+
for volume_type in volume_type_list:
193+
test_cases.append(OpenVKLTestCase(renderer, volume_type))
194+
195+
if volume_type == "structuredRegular":
196+
test_cases.append(OpenVKLTestCase(renderer, volume_type, "-deviceOnlySharedBuffers"))
197+
198+
# execute test cases
199+
for test_case in test_cases:
200+
test_case.execute(img_diff_tool_path)
201+
202+
# print summary & analyze results
203+
print()
204+
print("######################################### SUMMARY ##########################################")
205+
print()
206+
207+
failed_test_cases = []
208+
# For any more advanced table formatting external library should be used
209+
# or external class should be created.
210+
fixed_width_row_format = "%-5s %-7s %-65s %s"
211+
print(fixed_width_row_format % ("####", "Result", "Test case name", "MSE value"))
212+
print("--------------------------------------------------------------------------------------------")
213+
for test_case in test_cases:
214+
result = test_case.get_result()
215+
if result != 0:
216+
log_prefix = "#!##"
217+
result_str = "[FAIL]"
218+
failed_test_cases.append(test_case)
219+
else:
220+
log_prefix = "####"
221+
result_str = "[PASS]"
222+
print(fixed_width_row_format % (log_prefix, result_str, test_case.get_name(), "%.10f" % test_case.get_MSE()))
223+
224+
total_count = len(test_cases)
225+
fail_count = len(failed_test_cases)
226+
pass_count = total_count - fail_count
227+
228+
print()
229+
if fail_count == 0:
230+
print("#### All test cases PASSED (passrate: %d/%d)" % (pass_count, total_count))
231+
return 0
232+
233+
print("#!## Some test cases FAILED (passrate: %d/%d)" % (pass_count, total_count))
234+
print()
235+
# Print output from failed tests
236+
for test_case in failed_test_cases:
237+
print("#!## '%s' failure details:" % test_case.get_name())
238+
test_case.print_error_outputs()
239+
return 1
240+
241+
if __name__ == "__main__":
242+
sys.exit(main())

0 commit comments

Comments
 (0)