# Data structures¶

This chapter describes the data structures that are critical to the high performance operation of the OpenCL/CUDA kernels.

Some data structures will have a pythonic browser-editor class, however, for highest possible performance, it might be necessary to edit them directly.

This description will also come handy when writing new OpenCL kernels

## sampling_point_list¶

`sampling_point_list`

is a list of coordinates of points/pixels/samples
for the `handybeam.sampler_point_list.SamplerPointList`

class, and the `handybeam.propagators.cxyz.CXYZ`

propagator.

Again, the usage is best described by implemented code:

in `_handybeam1kernel_clist.cl`

:

```
unsigned int sampling_point_pointer=3*sampling_point_idx;
float pixel_x_coordinate=(float)sampling_point_list[sampling_point_pointer+0];
float pixel_y_coordinate=(float)sampling_point_list[sampling_point_pointer+1];
float pixel_z_coordinate=(float)sampling_point_list[sampling_point_pointer+2];
```

in `clist.py`

:

```
sampling_point_list=np.zeros((0, 3), dtype=np.float32),
```

## p - the pressure field¶

The `p`

or `field`

data structure is used for storing complex-valued pressure field.

Todo

refactor to make it clear that there can be several types of field information used:

- complex-valued field - pressure at given frequency
- real-valued field - real pressure in given time instant
- real-valued field - absolute field intensity, could be in decibels re 20uPa

At this time, it is most relevant to note that the data is a flat list of values. For each ‘pixel’ of the field (as in `sampling_point_list`

) there is one value.

Note that currently, the value complex (two single-precision floats) but it could be made to be real or log-scale, half precision, or double precision later on.

from C/OpenCL/CUDA side it looks like this:

in `_handybeam1kernel_clist`

:

```
unsigned int output_pointer_base = 2 * sampling_point_idx ; // address in the buffer to use
// The factor of (uint)2 comes from the fact that I need to store both imaginary and real parts.
cl_field[output_pointer_base+0] = pressure_re; // store real-part of the complex pressure value
cl_field[output_pointer_base+1] = pressure_im; // store imaginary-part of the complex pressure value
```

from the python side, it looks like this:

in `clist.py`

:

```
sampling_point_count = sampling_point_list.shape[0]
field = np.zeros((sampling_point_count), dtype=np.complex64)
```

Back to Welcome

**Licence** (documentation): Creative Commons CC BY-NC-SA 4.0

**Licence** (source code): Apache 2.0

This project has received funding from the European Union’s Horizon 2020 research and innovation programme under grant agreement No 737087.

This project has received funding from Ultrahaptics.