slang icon indicating copy to clipboard operation
slang copied to clipboard

Generic functions with array types

Open jarble opened this issue 3 years ago • 2 comments

Is it possible to define generic functions in Slang with array types?

I want to define a function that concatenates two arrays of any size, but this would require generics:

T3 array_concat<T1,T2,T3>(T1 a1, T2 a2)
{
  T3 result;
  for(int i = 0; i < length(a1), i++){
    result[i] = a1[i];
  }
  for(int j = 0; j < length(a2);j++){
    result[j] = a2[j + length(a1)];
  }
  return result;
}

vec4 example_use(vec2 a, vec2 b){
  return array_concat(a,b);
}

jarble avatar Sep 24 '20 18:09 jarble

The operation you are trying to write there wouldn't work today, although I see what you mean.

You can write functions that operate generically over vectors of different sizes, but you need them to have both an explicit parameter for the element type of the array, and a generic value parameter for the element count:

T getElementAtIndex<T, let N : int>(vector<T,N> v, int index)
{
    return v[index];
}

The same basic idea could in theory apply to your array_concat example (which is really more of a vector_concat):

vector<T, N+M> concat<T, let N : int, let M : int>(vector<T,N> left, vector<T,M> right)
{ ... }

The main reason the function isn't possible today is the N+M in the result type. Right now the Slang compiler can only handle it when the arguments to a generic (or the sizes of an array, etc.) are either true compile-time constants (e.g., 10 or 99) or are direct references to a generic value parameter (e.g., N or M in this example). A more complicated expression using generic value parameters, like N+M or even just N+1 is not (yet) supported.

Out of curiosity, what is the problem you are working on that needs this concat sort of function? In the worst case, you can just write explicit overloads for a few sizes:

vector<T,2> concat<T>(T left, T right); { ... }
vector<T,3> concat<T>(vector<T,2> left, T right) { ... }
vector<T,3> concast<T>(T left, vector<T,2> right) { ... }
vector<T,4> concat<T>(vector<T,3> left, T right) { ... }
vector<T,4> concast<T>(T left, vector<T,3> right) { ... }
vector<T,4> concat<T>(vector<T,2> left, vector<T,2> right) { ... }

I believe those cases would cover all of what you'd need, given that Slang currently only supports vectors of 2-4 elements.

tangent-vector avatar Sep 24 '20 18:09 tangent-vector

@tfoleyNV Generics would also be useful for operations involving matrices: for instance, I'd want to define a function that performs Gaussian elimination on a matrix of any size. I'm not sure if this is possible yet, due to the compiler's current limitations.

jarble avatar Sep 24 '20 19:09 jarble

This is supported now. You can now define functions like

vector<T, N+M> concat<T, let N : int, let M : int>(vector<T,N> left, vector<T,M> right)
{ ... }

csyonghe avatar Apr 05 '23 20:04 csyonghe