Skip to content

Commit

Permalink
Merge pull request #22 from arghdos/spyJac-working
Browse files Browse the repository at this point in the history
Fix sub-kernel wrapper generation & test
  • Loading branch information
Nick Curtis authored Jan 17, 2019
2 parents 48990ba + 9e102f3 commit 1cdd67b
Show file tree
Hide file tree
Showing 36 changed files with 1,285 additions and 687 deletions.
29 changes: 16 additions & 13 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,22 +13,23 @@ language: python
matrix:
include:
- python: "3.6"
env: ISFLAKE="0" PYJAC_TEST_LANGS="opencl"
env: PYJAC_TEST_LANGS="opencl"
- python: "3.6"
env: ISFLAKE="0" PYJAC_TEST_LANGS="c"
env: PYJAC_TEST_LANGS="c"
- python: "3.6"
env: ISFLAKE="0" PYJAC_TEST_LANGS="opencl" PYJAC_RXN_SORTING="simd"
env: PYJAC_TEST_LANGS="c" PYJAC_RXN_SORTING="simd"
- python: "3.6"
env: ISFLAKE="0" PYJAC_TEST_LANGS="c" PYJAC_RXN_SORTING="simd"
env: PYJAC_TEST_LANGS="opencl" RUN_LONG_TESTS="1"
- python: "3.6"
env: PYJAC_TEST_LANGS="opencl" RUN_LONG_TESTS="1" PYJAC_UNIQUE_POINTERS="1"
- python: "3.6"
env: PYJAC_TEST_LANGS="c" RUN_LONG_TESTS="1"
- python: "3.6"
env: PYJAC_TEST_LANGS="c" RUN_LONG_TESTS="1" PYJAC_UNIQUE_POINTERS="1"
- python: "3.6"
env: ISFLAKE="1"

# global env
env:
global:
- PRIORITY=500
- LLV=5.0

# additional packages
addons:
apt:
sources:
Expand Down Expand Up @@ -66,7 +67,7 @@ before_install:
- conda config --add channels conda-forge
- conda config --add channels cantera
# create env
- conda create -y -n test-environment python=$TRAVIS_PYTHON_VERSION llvmdev clangdev cantera ocl-icd islpy pyyaml scipy pyopencl numpy Cython pytables flake8 pep8-naming pocl adept
- conda create -y -n test-environment python=$TRAVIS_PYTHON_VERSION llvmdev clangdev cantera ocl-icd=*=h14c3975_1001 islpy pyyaml scipy pyopencl numpy Cython pytables flake8 pep8-naming pocl adept=*=he6fcbdd_3
- source activate test-environment
# get vendor dir
- export OCL_ICD_VENDORS=$CONDA_PREFIX/etc/OpenCL/vendors
Expand All @@ -89,8 +90,10 @@ before_script:
- export TMPDIR=$TRAVIS_BUILD_DIR/working/
# run test
script:
if [[ "$ISFLAKE" == "0" ]]; then
nosetests -a '!verylong' -s --with-timer;
if [[ -z "$ISFLAKE" && -z "$RUN_LONG_TESTS" ]]; then
nosetests -A 'not fullkernel and not verylong' -s --with-timer;
elif [[ -z "$ISFLAKE" && -n "$RUN_LONG_TESTS" ]]; then
nosetests -A 'fullkernel' -s --with-timer;
else
python -m flake8 pyjac/ --count;
fi
2 changes: 1 addition & 1 deletion MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ recursive-include pyjac/core *.py
recursive-include pyjac/functional_tester *.py *.yaml
recursive-include pyjac/loopy_utils *.py *.in
recursive-include pyjac/libgen *.py
recursive-include pyjac/kernel_utils *.py *.in *.h *.c *.oclh *.ocl
recursive-include pyjac/kernel_utils *.py *.in *.hpp *.cpp *.oclh *.ocl
recursive-include pyjac/performance_tester *.py
recursive-include pyjac/pywrap *.py *.in
recursive-include pyjac/tests *.py *.inp * .cti *.in *.yaml
Expand Down
42 changes: 39 additions & 3 deletions docs/driver_functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ enable conversion to/from the calling code's state variables to pyJac's state-ve

.. _work-size:

========================
Specifying the Work-Size
========================
==========
Work Sizes
==========

In pyJac, the work-size is defined as the total number of separate (potentially
vectorized) evaluations of the chemical kinetic properties / source rates / Jacobian
Expand Down Expand Up @@ -123,6 +123,42 @@ For vectorized execution, the shape of the arrays changes slightly to
where the `vector_width` is typically 2--8 for CPUs and MICs, and 64--1024 for GPUs
(note: this corresponds to the block-size in CUDA).

==========================
Coupling to external codes
==========================

One downside of pyJac's data-storage format is that it requires each OpenMP thread
/ OpenCL work-group to be passed the **addresses to the beginning of the arrays
that contain memory for the entire set of threads / work-groups.** In code this
might look something like this:

```
double* phi = (double*)malloc(work_size * (N_s + 1) * sizeof(double));
double* dphi = (double*)malloc(work_size * (N_s + 1) * sizeof(double));
double* rwk = (double*)malloc(work_size * kernel.requiredMemorySize());
// populate state vector
// copy temperatures
memcpy(&phi[0], &T[0], work_size * sizeof(double));
...
// call source rates
species_rates(0, phi, dphi, rwk);
```

However, many codes operate on local-copies of the state vector array, e.g.:

```
double phi[N_s];
double dphi[N_s];
double* rwk = (double*)malloc(kernel.requiredMemorySize());
//populate state vector
phi[0] = T;
...
species_rates(0, phi, dphi, rwk);
```

For this sort of code, you may supply the `-up` or `--unique_pointers` flag to the
command line interface of pyJac.


=====================
Lockstep-based driver
Expand Down
19 changes: 16 additions & 3 deletions pyjac/core/array_creator.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ def _should_split(self, array):
"""

return len(array.shape) >= 2 or self.is_simd
return len(array.shape) >= 1 or self.is_simd

def split_and_vec_axes(self, array):
"""
Expand Down Expand Up @@ -169,6 +169,19 @@ def split_and_vec_axes(self, array):

return split_axis, vec_axis

def grow_axis(self, array):
"""
Returns
-------
grow_axis: int
The integer index of the axis corresponding to the initial conditions,
see :ref:`vector_split`
"""
if self._should_split(array):
# the grow axis is one IFF it's a F-ordered deep-split
return 1 if self.data_order == 'F' else 0
return 0

def split_shape(self, array):
"""
Returns the array shape that would result from splitting the supplied array
Expand Down Expand Up @@ -202,7 +215,7 @@ def split_shape(self, array):
vector_width = None
if self._should_split(array):
# the grow axis is one IFF it's a F-ordered deep-split
grow_axis = 1 if self.data_order == 'F' else 0
grow_axis = self.grow_axis(array)
split_axis, vec_axis = self.split_and_vec_axes(array)
vector_width = self.depth if self.depth else self.width
assert vector_width
Expand Down Expand Up @@ -612,7 +625,7 @@ def initial_condition_dimension_vars(loopy_opts, test_size, is_driver_kernel=Fal
The initial condition dimension size variables
"""

if isinstance(test_size, int) or loopy_opts.work_size:
if isinstance(test_size, int) or loopy_opts.unique_pointers:
return []
if is_driver_kernel:
return [work_size, problem_size]
Expand Down
Loading

0 comments on commit 1cdd67b

Please sign in to comment.