Skip to content

Commit

Permalink
Updates:
Browse files Browse the repository at this point in the history
 - Add type checking when calling dace programs
 - Save SDFG to .dacecache folder
 - Various instrumentation updates and refactors
 - Improve stability of CUDA streams
 - Better layout for scopes in xdot
  • Loading branch information
tbennun committed May 10, 2019
1 parent 86e4f47 commit ef85d9d
Show file tree
Hide file tree
Showing 64 changed files with 9,346 additions and 943 deletions.
1 change: 1 addition & 0 deletions .clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
BasedOnStyle: Google
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -159,3 +159,5 @@ sdaccel_timeline_*

# Miscellaneous
*~

perfdata.db
114 changes: 114 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
# Docker image. You can delete this line if you're not using Docker
image: python:3-stretch

variables:
GIT_SUBMODULE_STRATEGY: recursive

setup_dace:
stage: build
tags:
- linux
script:
- echo "Reverting configuration to defaults"
- rm -f ~/.dace.conf
- echo "Clearing binary cache"
- rm -rf .dacecache tests/.dacecache
- echo "Installing additional dependencies"
- pip3 install --upgrade --user tensorflow-gpu
- echo "Installing DaCe"
- pip3 install --upgrade --user .


test_linux_cpu:
stage: test
tags:
- intel
- linux
script:
- export DACE_debugprint=1
- tests/gemm_test.sh

test_linux_cuda:
stage: test
tags:
- cuda
- linux
script:
- export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
- export PATH=/usr/local/cuda/bin:$PATH
- export CUDA_ROOT=/usr/local/cuda
- export DACE_debugprint=1
- tests/cuda_test.sh


test_mpihello:
stage: test
tags:
- intel
- linux
- mpi
script:
- cd tests/
- PATH=$PATH:/opt/mpich3.2.11/bin xvfb-run python3 ../scripts/diode --optscript mpihello_test_opt.py --headless --local


test_mpihello2:
stage: test
tags:
- intel
- linux
- mpi
script:
- cd tests/
- PATH=$PATH:/opt/mpich3.2.11/bin xvfb-run python3 ../scripts/diode --optscript mpihello2_test_opt.py --headless --local


test_filter:
stage: test
tags:
- intel
- linux
script:
- cd tests/
- xvfb-run python3 ../scripts/diode --optscript filter_test_opt.py --headless --local


test_spmv:
stage: test
tags:
- intel
- linux
script:
- cd tests/
- xvfb-run python3 ../scripts/diode --optscript spmv_test_opt.py --headless --local


test_simple_stencil:
stage: test
tags:
- intel
- linux
script:
- cd tests/
- xvfb-run python3 ../scripts/diode --optscript simple_stencil_test_opt.py --headless --local

test_all:on-schedule:
only:
- schedules
stage: test
tags:
- intel
- linux
script:
- export LD_LIBRARY_PATH=/usr/local/cuda/lib64:$LD_LIBRARY_PATH
- export PATH=/usr/local/cuda/bin:/opt/mpich3.2.11/bin:/opt/Xilinx/SDx/2018.2/bin:$PATH
- export CUDA_ROOT=/usr/local/cuda
- NOSTATUSBAR=1 xvfb-run ./test_all.sh

test_xilinx:
stage: test
tags:
- xilinx
script:
- export PATH=/opt/Xilinx/SDx/2018.2/bin:$PATH
- xvfb-run tests/xilinx_test.sh 0
69 changes: 55 additions & 14 deletions dace/codegen/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
import dace
from dace.frontend import operations
from dace.frontend.python import ndarray
from dace import symbolic, types
from dace import symbolic, types, data as dt
from dace.config import Config
from dace.codegen import codegen
from dace.codegen.codeobject import CodeObject
Expand Down Expand Up @@ -174,32 +174,62 @@ def _construct_args(self, *args, **kwargs):
'("program(A=a,B=b)"), but not both')

# Argument construction
sig = []
sig = self._sdfg.signature_arglist(with_types=False)
typedict = self._sdfg.arglist()
if len(kwargs) > 0:
# Construct mapping from arguments to signature
sig = self._sdfg.signature_arglist(with_types=False)
arglist = []
argtypes = []
argnames = []
for a in sig:
try:
arglist.append(kwargs[a])
argtypes.append(typedict[a])
argnames.append(a)
except KeyError:
raise KeyError("Missing kernel argument \"{}\"".format(a))
raise KeyError("Missing program argument \"{}\"".format(a))
elif len(args) > 0:
arglist = list(args)
argtypes = [typedict[s] for s in sig]
argnames = sig
sig = []
else:
arglist = []
argtypes = []
argnames = []
sig = []

# Type checking
for a, arg, atype in zip(argnames, arglist, argtypes):
if not isinstance(arg, np.ndarray) and isinstance(atype, dt.Array):
raise TypeError(
'Passing an object (type %s) to an array in argument "%s"'
% (type(arg).__name__, a))
if isinstance(arg, np.ndarray) and not isinstance(atype, dt.Array):
raise TypeError(
'Passing an array to a scalar (type %s) in argument "%s"' %
(atype.dtype.ctype, a))
if not isinstance(atype, dt.Array) and not isinstance(
arg, atype.dtype.type):
print('WARNING: Casting scalar argument "%s" from %s to %s' %
(a, type(arg).__name__, atype.dtype.type))

# Retain only the element datatype for upcoming checks and casts
argtypes = [t.dtype.type for t in argtypes]

sdfg = self._sdfg

# As in compilation, add symbols used in array sizes to parameters
symparams = {}
symtypes = {}
for symname in sdfg.undefined_symbols(False):
# Ignore arguments (as they may not be symbols but constants,
# see below)
if symname in sdfg.arg_types: continue
try:
symval = symbolic.symbol(symname)
symparams[symname] = symval.get()
symtypes[symname] = symval.dtype.type
except UnboundLocalError:
try:
symparams[symname] = kwargs[symname]
Expand All @@ -208,29 +238,35 @@ def _construct_args(self, *args, **kwargs):

arglist.extend(
[symparams[k] for k in sorted(symparams.keys()) if k not in sig])
argtypes.extend(
[symtypes[k] for k in sorted(symtypes.keys()) if k not in sig])

# Obtain SDFG constants
constants = sdfg.constants

# Remove symbolic constants from arguments
callparams = tuple(
arg for arg in arglist if not symbolic.issymbolic(arg) or (
(arg, atype) for arg, atype in zip(arglist, argtypes)
if not symbolic.issymbolic(arg) or (
hasattr(arg, 'name') and arg.name not in constants))

# Replace symbols with their values
callparams = tuple(
symbolic.eval(arg) if symbolic.issymbolic(arg, constants) else arg
for arg in callparams)
(atype(symbolic.eval(arg)),
atype) if symbolic.issymbolic(arg, constants) else (arg, atype)
for arg, atype in callparams)

# Replace arrays with their pointers
newargs = tuple(
ctypes.c_void_p(arg.__array_interface__['data'][0]) if (isinstance(
arg, ndarray.ndarray) or isinstance(arg, np.ndarray)) else arg
for arg in callparams)
(ctypes.c_void_p(arg.__array_interface__['data'][0]),
atype) if (isinstance(arg, ndarray.ndarray)
or isinstance(arg, np.ndarray)) else (arg, atype)
for arg, atype in callparams)

newargs = tuple(types._FFI_CTYPES[type(arg)](arg)
if type(arg) in types._FFI_CTYPES else arg
for arg in newargs)
newargs = tuple(types._FFI_CTYPES[atype](arg) if (
atype in types._FFI_CTYPES
and not isinstance(arg, ctypes.c_void_p)) else arg
for arg, atype in newargs)

self._lastargs = newargs
return self._lastargs
Expand Down Expand Up @@ -269,10 +305,12 @@ def unique_flags(flags):
return set(re.findall(pattern, flags))


def generate_program_folder(code_objects: List[CodeObject], out_path):
def generate_program_folder(sdfg, code_objects: List[CodeObject],
out_path: str):
""" Writes all files required to configure and compile the DaCe program
into the specified folder.
@param sdfg: The SDFG to generate the program folder for.
@param code_objects: List of generated code objects.
@param out_path: The folder in which the build files should be written.
@return: Path to the program folder.
Expand Down Expand Up @@ -322,6 +360,9 @@ def generate_program_folder(code_objects: List[CodeObject], out_path):
# Copy snapshot of configuration script
Config.save(os.path.join(out_path, "dace.conf"))

# Save the SDFG itself
sdfg.save(os.path.join(out_path, "program.sdfg"))

return out_path


Expand Down
7 changes: 4 additions & 3 deletions dace/codegen/cppunparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -303,9 +303,10 @@ def _Assign(self, t):
self.dispatch_lhs_tuple(target.elts)
target = target.elts[0]

if not isinstance(target,
ast.Subscript) and not self.locals.is_defined(
target.id, self._indent):
if not isinstance(
target,
(ast.Subscript, ast.Attribute)) and not self.locals.is_defined(
target.id, self._indent):
self.locals.define(target.id, t.lineno, self._indent)
self.write('auto ')
self.dispatch(target)
Expand Down
Loading

0 comments on commit ef85d9d

Please sign in to comment.