Provide more information on how to use blaze with custom data types

Issue #25 resolved
Hendrik Gossler created an issue

I would like to use blaze-lib together with an automatic differentiation library (more specifically: adept). A simple test with addition and subtraction of matrices using the custom data type (adouble instead of double) seems to work. However, multiplication generates compiler errors. From the comments in the NumericElementType.h file it seems as it should be in principle possible to get blaze working with custom types. It's just not very clear to me how this would be implemented. Can you give some advice or do you think that this would be too sophisticated and not worth the hassle? Thanks.

Comments (4)

  1. Klaus Iglberger

    Hi!

    Thanks for raising this issue. I sent you a message via the Bitbucket messaging system on November, 4th (i.e. within the 24h time frame that we set for ourselves to answer requests). It contains the suggestion to solve this problem quickly via email/message to enable you to continue and since this should not be a big issue. Writing the documentation will take longer, but this example could be a valuable input. Please check you inbox for the details.

    We will resolve this ticket once the documentation has been updated.

    Best regards,

    Klaus!

  2. Klaus Iglberger

    Summary

    We have improved the support for custom data types. Additionally, we have extended the tutorial with a section about the necessary step to adapt Blaze to custom data types (see below). The improvements are immediately available via cloning the Blaze repository and will be officially released in Blaze 2.6.

    Custom Data Types

    The Blaze library tries hard to make the use of custom data types as convenient, easy and intuitive as possible. However, unfortunately it is not possible to meet the requirements of all possible data types. Thus it might be necessary to provide Blaze with some additional information about the data type. The following sections give an overview of the necessary steps to enable the use of the hypothetical custom data type custom::double_t for vector and matrix operations. For example:

    blaze::DynamicVector<custom::double_t> a, b, c;
    // ... Resizing and initialization
    c = a + b;
    

    The Blaze library assumes that the custom::double_t data type provides operator+() for additions, operator-() for subtractions, operator*() for multiplications and operator/() for divisions. If any of these functions is missing it is necessary to implement the operator to perform the according operation. For this example we assume that the custom data type provides the four following functions instead of operators:

    namespace custom {
    
    double_t add ( const double_t& a, const double_t b );
    double_t sub ( const double_t& a, const double_t b );
    double_t mult( const double_t& a, const double_t b );
    double_t div ( const double_t& a, const double_t b );
    
    } // namespace custom
    

    The following implementations will satisfy the requirements of the Blaze library:

    inline custom::double_t operator+( const custom::double_t& a, const custom::double_t& b )
    {
       return add( a, b );
    }
    
    inline custom::double_t operator-( const custom::double_t& a, const custom::double_t& b )
    {
       return sub( a, b );
    }
    
    inline custom::double_t operator*( const custom::double_t& a, const custom::double_t& b )
    {
       return mult( a, b );
    }
    
    inline custom::double_t operator/( const custom::double_t& a, const custom::double_t& b )
    {
       return div( a, b );
    }
    

    Blaze will use all the information provided with these functions (for instance the return type) to properly handle the operations. In the rare case that the return type cannot be automatically determined from the operator it might be additionally necessary to provide a specialization of the following four Blaze class templates:

    namespace blaze {
    
    template<>
    struct AddTrait<custom::double_t,custom::double_t> {
       typedef custom::double_t  Type;
    };
    
    template<>
    struct SubTrait<custom::double_t,custom::double_t> {
       typedef custom::double_t  Type;
    };
    
    template<>
    struct MultTrait<custom::double_t,custom::double_t> {
       typedef custom::double_t  Type;
    };
    
    template<>
    struct DivTrait<custom::double_t,custom::double_t> {
       typedef custom::double_t  Type;
    };
    
    } // namespace blaze
    

    The same steps are necessary if several custom data types need to be combined (as for instance custom::double_t and custom::float_t). Note that in this case both permutations need to be taken into account:

    custom::double_t operator+( const custom::double_t& a, const custom::float_t& b );
    custom::double_t operator+( const custom::float_t& a, const custom::double_t& b );
    // ...
    

    Please note that only built-in data types apply for vectorization and thus custom data types cannot achieve maximum performance!

  3. Log in to comment