Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
hysop
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Container Registry
Model registry
Operate
Environments
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
particle_methods
hysop
Merge requests
!34
Add custom opencl
Code
Review changes
Check out branch
Download
Patches
Plain diff
Merged
Add custom opencl
add-custom-opencl
into
master
Overview
0
Commits
12
Pipelines
3
Changes
1
Merged
EXT Jean-Matthieu Etancelin
requested to merge
add-custom-opencl
into
master
2 years ago
Overview
0
Commits
12
Pipelines
3
Changes
1
Expand
Add a custom operator implementation on OpenCL Backend.
User can give the OpenCL code snippet to be used within an OpenCL ElementwiseKernel.
0
0
Merge request reports
Viewing commit
faaeb1eb
Prev
Next
Show latest version
1 file
+
0
−
2
Inline
Compare changes
Side-by-side
Inline
Show whitespace changes
Show one file at a time
faaeb1eb
fix
· faaeb1eb
EXT Jean-Matthieu Etancelin
authored
2 years ago
hysop/operator/tests/test_custom.py
0 → 100644
+
179
−
0
Options
"""
Test custom operator.
"""
from
hysop.constants
import
HYSOP_REAL
from
hysop.testsenv
import
__ENABLE_LONG_TESTS__
,
__HAS_OPENCL_BACKEND__
from
hysop.testsenv
import
opencl_failed
,
iter_clenv
from
hysop.tools.contexts
import
printoptions
from
hysop.tools.types
import
check_instance
,
first_not_None
from
hysop.tools.numpywrappers
import
npw
from
hysop.tools.io_utils
import
IO
from
hysop
import
Field
,
Box
from
hysop.operators
import
CustomOperator
from
hysop.constants
import
Implementation
class
TestCustom
(
object
):
@classmethod
def
setup_class
(
cls
,
enable_extra_tests
=
__ENABLE_LONG_TESTS__
,
enable_debug_mode
=
False
):
IO
.
set_default_path
(
'
/tmp/hysop_tests/test_custom
'
)
if
enable_debug_mode
:
cls
.
size_min
=
15
cls
.
size_max
=
16
else
:
cls
.
size_min
=
23
cls
.
size_max
=
87
cls
.
enable_extra_tests
=
enable_extra_tests
cls
.
enable_debug_mode
=
enable_debug_mode
@classmethod
def
teardown_class
(
cls
):
pass
def
perform_tests
(
self
):
self
.
_test
(
dim
=
3
,
dtype
=
HYSOP_REAL
)
@staticmethod
def
__analytic_init
(
data
,
coords
,
component
):
(
x
,
y
,
z
)
=
coords
data
[...]
=
(
x
**
2
)
*
npw
.
sin
(
y
)
*
npw
.
exp
(
z
)
for
_
in
range
(
1
,
6
):
data
[...]
+=
(
x
**
2
)
*
npw
.
sin
(
y
)
*
npw
.
exp
(
z
*
_
)
@staticmethod
def
__analytic_python
(
F
):
TestCustom
.
__analytic_init
(
F
.
data
[
0
],
F
.
compute_mesh_coords
,
0
)
__analytic_opencl
=
"""
int3 i_xyz = get_Fi_xyz(i);
double3 xyz = (double3)(F_mesh.local_mesh.xmin.x+i_xyz.x*F_mesh.dx.x,
F_mesh.local_mesh.xmin.y+i_xyz.y*F_mesh.dx.y,
F_mesh.local_mesh.xmin.z+i_xyz.z*F_mesh.dx.z);
double Fi = xyz.x*xyz.x*sin(xyz.y)*exp(xyz.z);
for(int k=1; k<6;k++) Fi += xyz.x*xyz.x*sin(xyz.y)*exp(xyz.z*k);
F[i] = Fi;
"""
def
_test
(
self
,
dim
,
dtype
,
size_min
=
None
,
size_max
=
None
):
enable_extra_tests
=
self
.
enable_extra_tests
size_min
=
first_not_None
(
size_min
,
self
.
size_min
)
size_max
=
first_not_None
(
size_max
,
self
.
size_max
)
shape
=
tuple
(
npw
.
random
.
randint
(
low
=
size_min
,
high
=
size_max
+
1
,
size
=
dim
).
tolist
())
domain
=
Box
(
length
=
(
1
,)
*
dim
)
F
=
Field
(
domain
=
domain
,
name
=
'
F
'
,
dtype
=
dtype
,
nb_components
=
1
)
print
(
'
>Testing all implementations:
'
)
implementations
=
CustomOperator
.
implementations
()
variables
=
{
F
:
shape
}
def
iter_impl
(
impl
):
base_kwds
=
dict
(
invars
=
(),
outvars
=
(
F
,),
variables
=
variables
,
implementation
=
impl
,
name
=
'
custom_{}
'
.
format
(
str
(
impl
).
lower
()))
if
impl
is
Implementation
.
PYTHON
:
msg
=
'
*Python:
'
print
(
msg
,
end
=
'
'
)
yield
CustomOperator
(
func
=
self
.
__analytic_python
,
**
base_kwds
)
print
()
elif
impl
is
Implementation
.
OPENCL
:
msg
=
'
*OpenCL:
'
print
(
msg
)
for
cl_env
in
iter_clenv
():
print
(
'
*platform {}, device {}:
'
.
format
(
cl_env
.
platform
.
name
.
strip
(),
cl_env
.
device
.
name
.
strip
()),
end
=
'
'
)
yield
CustomOperator
(
cl_env
=
cl_env
,
func
=
self
.
__analytic_opencl
,
**
base_kwds
)
print
()
else
:
msg
=
'
Unknown implementation to test {}.
'
.
format
(
impl
)
raise
NotImplementedError
(
msg
)
print
(
'
\n
Testing {}D Custom Operator: dtype={} shape={}
'
.
format
(
dim
,
dtype
.
__name__
,
shape
))
Fref
=
None
for
impl
in
implementations
:
for
op
in
iter_impl
(
impl
):
op
=
op
.
build
()
dF
=
op
.
get_output_discrete_field
(
F
)
if
(
Fref
is
None
):
dF
.
initialize
(
self
.
__analytic_init
)
Fref
=
tuple
(
data
.
get
().
handle
.
copy
()
for
data
in
dF
.
data
)
op
.
apply
()
Fout
=
tuple
(
data
.
get
().
handle
.
copy
()
for
data
in
dF
.
data
)
self
.
_check_output
(
impl
,
op
,
Fref
,
Fout
)
@classmethod
def
_check_output
(
cls
,
impl
,
op
,
Fref
,
Fout
):
check_instance
(
Fref
,
tuple
,
values
=
npw
.
ndarray
)
check_instance
(
Fout
,
tuple
,
values
=
npw
.
ndarray
,
size
=
len
(
Fref
))
msg0
=
'
Reference field {} is not finite.
'
for
(
i
,
field
)
in
enumerate
(
Fref
):
iname
=
'
F{}
'
.
format
(
i
)
mask
=
npw
.
isfinite
(
field
)
if
not
mask
.
all
():
print
()
print
(
field
)
print
()
print
(
field
[
~
mask
])
print
()
msg
=
msg0
.
format
(
iname
)
raise
ValueError
(
msg
)
for
i
,
(
fout
,
fref
)
in
enumerate
(
zip
(
Fout
,
Fref
)):
iname
=
'
{}{}
'
.
format
(
'
F
'
,
i
)
assert
fout
.
dtype
==
fref
.
dtype
,
iname
assert
fout
.
shape
==
fref
.
shape
,
iname
eps
=
npw
.
finfo
(
fout
.
dtype
).
eps
dist
=
npw
.
abs
(
fout
-
fref
)
dinf
=
npw
.
max
(
dist
)
deps
=
int
(
npw
.
ceil
(
dinf
/
eps
))
if
(
deps
<
1000
):
print
(
'
{}eps,
'
.
format
(
deps
),
end
=
'
'
)
continue
has_nan
=
npw
.
any
(
npw
.
isnan
(
fout
))
has_inf
=
npw
.
any
(
npw
.
isinf
(
fout
))
print
()
print
()
print
(
'
Test output comparisson for {} failed for component {}:
'
.
format
(
iname
,
i
))
print
(
'
*has_nan: {}
'
.
format
(
has_nan
))
print
(
'
*has_inf: {}
'
.
format
(
has_inf
))
print
(
'
*dinf={} ({} eps)
'
.
format
(
dinf
,
deps
))
print
()
msg
=
'
Test failed for {} on component {} for implementation {}.
'
.
format
(
iname
,
i
,
impl
)
raise
RuntimeError
(
msg
)
def
test
(
self
):
self
.
_test
(
3
,
HYSOP_REAL
)
def
perform_tests
(
self
):
self
.
test
()
if
__name__
==
'
__main__
'
:
TestCustom
.
setup_class
(
enable_extra_tests
=
False
,
enable_debug_mode
=
False
)
test
=
TestCustom
()
with
printoptions
(
threshold
=
10000
,
linewidth
=
240
,
nanstr
=
'
nan
'
,
infstr
=
'
inf
'
,
formatter
=
{
'
float
'
:
lambda
x
:
'
{:>6.2f}
'
.
format
(
x
)}):
test
.
perform_tests
()
TestCustom
.
teardown_class
()
Loading