I created a processor manager that compiles the same functions with different compilation options into different object files. In order for my code to have access to the same functions in different object files, I need to give the functions in each object file a different name.
In C (or C ++), I would do something similar in the header file for function declarations.
typedef float MyFuncType(float a); MyFuncType myfunc_SSE2, myfunc_SSE41, myfunc_AVX, myfunc_AVX2, myfunc_AVX512
But now I need function templates for declarations. My real code is now more like this
//kernel.h template <typename TYPE, unsigned N, typename VALUES> void foo_SSE2(int32_t *buffer, VALUES & v); template <typename TYPE, unsigned N, typename VALUES> void foo_SSE41(int32_t *buffer, VALUES & v); ... template <typename TYPE, unsigned N, typename VALUES> void foo_AVX512(int32_t *buffer, VALUES & v); #if INSTRSET == 2 // SSE2 #define FUNCNAME foo_SSE2 #elif INSTRSET == 5 // SSE4.1 #define FUNCNAME foo_SSE41 ... #if INSTRSET == 9 // AVX512 #define FUNCNAME foo_AVX512 #endif
These are only ads in the header file. Function definitions are in a separate source file, which is compiled into another object file for each function name. The definitions look something like this.
//kernel.cpp
Then i will compile this
gcc -c -O3 -msse2 kernel.cpp -o kernel_sse2.o gcc -c -O3 -msse4.1 kernel.cpp -o kernel_sse41.o ... gcc -c -O3 -mavx512f kernel.cpp -o kernel_avx512.o gcc -O3 main.cpp kernel_sse2.o kernel_sse41.o ... kernel_avx512.o
The main.cpp file is another source file that must know function declarations so that the linker can associate them with definitions in other object files. Looks like this
void dispatch(void) { int iset = instrset_detect(); if (iset >= 9) { fp_float1 = &foo_AVX512<float,1>; } else if (iset >= 8) { fp_float1 = &foo_AVX2<float,1>; } ... else if (iset >= 2) { fp_float1 = &foo_SSE2<float,1>; } } int main(void) { dispatch(); fp_float1(buffer, values); }
But in my kernel.h file, it is annoying (and error prone) to repeat this for every change to the function name. I want something like the following (which, as I know, does not work).
template <typename TYPE, unsigned N, typename VALUES> typedef void foo(int32_t *buffer, VALUES & v); foo foo_SSE2, foo_SSE41, foo_SSE_AVX, foo_AVX2, foo_AVX512
Is there an ideal way to do this that separates declarations and definitions and allows me to simply rename identical declarations of template functions?