ispc icon indicating copy to clipboard operation
ispc copied to clipboard

Function and structure templates

Open mmp opened this issue 12 years ago • 6 comments

It would be useful to be able to write functions parameterized by type. (Though ideally without the full complexity of C++ templates!)

mmp avatar Sep 25 '11 13:09 mmp

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;
    }
}

nnevatie avatar Jun 25 '19 07:06 nnevatie

That's an interesting way of doing meta-programming. Thanks for linking Jinja!

dbabokin avatar Jun 26 '19 01:06 dbabokin

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.

Lectem avatar Mar 06 '20 15:03 Lectem

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.

dbabokin avatar Feb 03 '22 06:02 dbabokin

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

dbabokin avatar Mar 03 '23 23:03 dbabokin

Function specializations are added in #2595

aneshlya avatar Aug 17 '23 16:08 aneshlya