ispc
ispc copied to clipboard
Function and structure templates
It would be useful to be able to write functions parameterized by type. (Though ideally without the full complexity of C++ templates!)
For now, you can use e.g. Jinja (http://jinja.pocoo.org/) for generating ISPC code using a fully-featured template language:
{% set TYPES = ['int8', 'int'] %}
{% for T in TYPES %}
export void square_{{T}}(
uniform const {{T}} input[],
uniform {{T}} output[],
uniform const int count
)
{
foreach (i = 0 ... count)
{
const {{T}} v = input[i];
output[i] = v * v;
}
}
{% endfor %}
Rendered with j2 square.j2 -o square.ispc
:
export void square_int8(
uniform const int8 input[],
uniform int8 output[],
uniform const int count
)
{
foreach (i = 0 ... count)
{
const int8 v = input[i];
output[i] = v * v;
}
}
export void square_int(
uniform const int input[],
uniform int output[],
uniform const int count
)
{
foreach (i = 0 ... count)
{
const int v = input[i];
output[i] = v * v;
}
}
That's an interesting way of doing meta-programming. Thanks for linking Jinja!
I'd really like to have some kind of template functions too, or some "pure" function attribute.
I encountered a few cases where I had to duplicate functions not only per floating point type (float
vs double
) but also varying
vs uniform
.
My use case is when trying to do an accurate summation, where the inside loop needs to be done both with inside the foreach
and the final reduction.
For example:
inline void kadd(float& sum, float& c, float input) {
const float y = input - c;
const float t = sum + y;
c = (t - sum) - y;
sum = t;
}
inline void kadd(uniform float& sum, uniform float& c, uniform float input) {
const uniform float y = input - c;
const uniform float t = sum + y;
c = (t - sum) - y;
sum = t;
}
export uniform float sum_kahan_f(const uniform float array[], uniform ptrdiff_t count) {
float sum = 0, error = 0;
foreach(i = 0 ... count) {
kadd(sum, error, array[i]);
}
uniform float finalsum = 0;
uniform float finalerr = reduce_add(error);
foreach_active(instance) {
kadd(finalsum, finalerr, extract(sum, instance));
}
return finalsum + finalerr;
}
It would be awesome if the kadd
function could be marked as pure and be generated either as full varying or full uniform, instead of having to duplicate it.
Note I can not use reduce_add
here due to the fact it's not precise enough.
Now add the double
version, and you have 4 times the kadd
function.
I think structure and function templates should go together. I've changed the title of the issue to address both.
The feature is targeted for the next release.
In #2393 support for function templates was added. It's not complete and it's in "technical preview" state, meaning that we'd like to have some time for user feedback and evaluation before we finalize the definition of templates semantics. The key unknown is the definition of semantics wrt variability. The part borrow from C++ is pretty stable. The things not yet completed for function templates:
- non-type parameters
- default parameters
- function specializations
Function specializations are added in #2595