🔒 Closed [advanced c++] automatically activate features just by including headers

Status
Not open for further replies.

nnivx

Enthusiast
Just like the title says. Pero mukhang madali lang diba?
Note: this tutorial requires minimal knowledge of templates and average C++ skills.

Scenario:

May header ka na "math.h" and "simd.h" (SIMD is You do not have permission to view the full content of this post. Log in or register now.).
When you include "math.h" sa cpp mo for example, you get the default implementation mathematical functions.. useful for everyday use.

Pero kunyari yung program mo eh deep neural networks, image processing or ray tracing and kailagan mo ng Fast Math™ in certain areas. Wouldn't it be great if you could:
Code:
#include "simd.h"
#include "math.h"
And automatically magiging simd yung mga supported functions sa math.h!! Sounds easy--just use some macros and viola.
But remember... dapat may default implementation sa mga hindi supported functions... um
simd.h
Code:
#define HAS_SIMD_AXPY
template <template <class> typename V, typename T>
inline constexpr V<T> axpy(T a, const V<T>& x, const V<T>& y) { /* simd code*/ }
math.h
Code:
#ifndef HAS_SIMD_AXPY
template <template <class> typename V, typename T>
inline constexpr V<T> axpy(T a, const V<T>& x, const V<T>& y) { /* basic code */ }
#endif
*if your head already aches from these, there's a good chance that you'd have a hard time following what proceeds

Pero mas gusto ko ng template sorcery. I don't fancy macros kasi preprocessor siya and hindi siya kasing elegant ng pag-solve sa problems using the features of the language itself.​

My solution: template metaprogramming

First you need 3 files: in addition to math.h and simd.h, we need common.h
common.h
Code:
#include <iostream> // just for testing

template <bool>
struct use_simd {
    static constexpr bool value = false;
};

template <typename T, bool UseSIMD>
struct _foo;
math.h
Code:
#include "common.h"

template <typename T>
struct _foo<T, false> {
    void operator()(T package) {
        std::cout << package << ": not using simd" << std::endl;
    }
};

template <typename T>
void foo(T package) {
    _foo<T, use_simd<true>::value>()(package);
}
simd.h
Code:
#include "common.h"

template <>
struct use_simd<true> {
    static constexpr bool value = true;
};

template <typename T>
struct _foo<T, true> {
    void operator()(T package) {
        std::cout << package << ": using simd!!" << std::endl;
    }
};
If you haven't went full wtf yet, good. You can try compiling this with g++6.3 and --std=c++14

If you just include math.h and call foo(5), you'll see that you're using default implementation... but when you include simd.h before* math.h, suddenly you're using SIMD!! (no, not really lol)
* actually no, hindi kailangan -before- basta nasa scope yung simd specializations

***
Hahaba pa 'to kung susubukan kong i-explain, iwan ko na lang sa mga kayang intindihin yan^^ Sasagutin ko nalang mga specific questions para straight to the point (mag pprogram pa ako, haha). Marami pang tricks with partial specialization, SFINAE and TMP in general.

I'm leaving the *.h and *.cpp files in the attachment I actually used to test this.. kagagawa ko lang kanina kasi :) Hindi ko sure kung anong idiom ang tawag dito, mamaya try ko i-post sa StackOverflow XD
 

Attachments

Status
Not open for further replies.

About this Thread

  • 4
    Replies
  • 766
    Views
  • 4
    Participants
Last reply from:
RMrhaine

Trending Topics

Online now

Members online
1,009
Guests online
1,233
Total visitors
2,242

Forum statistics

Threads
2,273,906
Posts
28,952,291
Members
1,234,983
Latest member
Ryu Kali
Back
Top