Inspector: Serializing Blaze Matrix

28 views
Skip to first unread message

Lari Karam

unread,
Apr 28, 2020, 7:53:47 PM4/28/20
to actor-framework
Hey everyone,
I'm using Blaze library for matrices as a custom type and I'm trying to serialize it within the inspect function. I understand the principle on a simple custom class or struct but not on this library. I would like to think I'm understanding clearly what is happening but I don't. So any help would be appreciated.

So here is a simple Blaze serialization example which works:

blaze::DynamicMatrix<double, blaze::columnMajor> ma (5,5);
blaze
::randomize(ma);

std
::stringstream ss;
   
{
        blaze
::Archive<std::stringstream> archive(ss);
        archive
<< ma;
   
}
   
    blaze
::DynamicMatrix<double, blaze::columnMajor> mb (5, 5);
   
{
        blaze
::Archive<std::stringstream> archive(ss);
        archive
>> mb;
   
}

Now, after trying and looking over the forum and the web, I tried the following with no sucess:

typedef blaze::DynamicMatrix<double, blaze::columnMajor> Tensor

template <class Inspector>
typename std::enable_if<Inspector::reads_state,
                       
typename Inspector::result_type>::type
inspect
(Inspector& f, Tensor& A) {
    std
::stringstream ss;
   
{
        blaze
::Archive<std::stringstream> archive(ss);
        archive
<< A;
   
}
   
return f(meta::type_name("tensor"), ss.str());
}

template <class Inspector>
typename enable_if<Inspector::writes_state,
                   
typename Inspector::result_type>::type
inspect
(Inspector& f, Tensor& A){
   
Tensor B;
   
auto g = make_scope_gard([&]{
        std
::stringstream ss;
       
{
            blaze
::Archive<std::stringstream> archive(ss);
            archive
>> B;
       
}
   
});
   
return f(meta::type_name("tensor"), B);
}


//included this as in the custom_type#.cpp
class config : public actor_system_config {
public:
    config
() {
        add_message_type
<Tensor>("tensor");
   
}
};

I get the following error:
/usr/local/include/blaze/math/serialization/MatrixSerializer.h: In instantiation of void blaze::MatrixSerializer::serialize(Archive&, const blaze::Matrix<MT, SO>&) [with Archive = caf::deserializer; MT = blaze::DynamicMatrix<double, true>; bool SO = true]’:
/usr/local/include/blaze/math/serialization/MatrixSerializer.h:1258:4:   required from void blaze::serialize(Archive&, const blaze::Matrix<MT, SO>&) [with Archive = caf::deserializer; MT = blaze::DynamicMatrix<double, true>; bool SO = true]’
/usr/local/include/caf/detail/delegate_serialize.hpp:65:12:   required from decltype (caf::serialize(proc, x)) caf::detail::delegate_serialize(Processor&, U&) [with Processor = caf::deserializer; U = blaze::DynamicMatrix<double, true>; decltype (caf::serialize(proc, x)) = void]’
/usr/local/include/caf/data_processor.hpp:403:31:   required from typename std::enable_if<((! std::is_empty<T>::value) && caf::detail::has_serialize<T>::value), caf::error>::type caf::data_processor<Derived>::apply(T&) [with T = blaze::DynamicMatrix<double, true>; Derived = caf::deserializer; typename std::enable_if<((! std::is_empty<T>::value) && caf::detail::has_serialize<T>::value), caf::error>::type = caf::error]’
/usr/local/include/caf/data_processor.hpp:267:16:   required from caf::error caf::data_processor<Derived>::fill_range(T&, size_t) [with T = std::vector<blaze::DynamicMatrix<double, true>, std::allocator<blaze::DynamicMatrix<double, true> > >; Derived = caf::deserializer; size_t = long unsigned int]’
/usr/local/include/caf/data_processor.hpp:309:58:   required from static typename std::enable_if<((! D::reads_state) && (! caf::detail::is_byte_sequence<T>::value)), caf::error>::type caf::data_processor<Derived>::apply_sequence(D&, T&) [with D = caf::deserializer; T = std::vector<blaze::DynamicMatrix<double, true>, std::allocator<blaze::DynamicMatrix<double, true> > >; Derived = caf::deserializer; typename std::enable_if<((! D::reads_state) && (! caf::detail::is_byte_sequence<T>::value)), caf::error>::type = caf::error]’
/usr/local/include/caf/data_processor.hpp:351:26:   required from typename std::enable_if<((caf::detail::is_iterable<T>::value && (! caf::detail::has_serialize<T>::value)) && (! caf::detail::is_inspectable<Derived, T>::value)), caf::error>::type caf::data_processor<Derived>::apply(T&) [with T = std::vector<blaze::DynamicMatrix<double, true>, std::allocator<blaze::DynamicMatrix<double, true> > >; Derived = caf::deserializer; typename std::enable_if<((caf::detail::is_iterable<T>::value && (! caf::detail::has_serialize<T>::value)) && (! caf::detail::is_inspectable<Derived, T>::value)), caf::error>::type = caf::error]’
/usr/local/include/caf/data_processor.hpp:501:18:   required from caf::data_processor<Derived>::operator()(Ts&& ...) [with Ts = {std::vector<blaze::DynamicMatrix<double, true>, std::allocator<blaze::DynamicMatrix<double, true> > >&}; Derived = caf::deserializer]::<lambda(auto:6&&)> [with auto:6 = std::vector<blaze::DynamicMatrix<double, true>, std::allocator<blaze::DynamicMatrix<double, true> > >&]’
/usr/local/include/caf/data_processor.hpp:508:11:   required from caf::error caf::data_processor<Derived>::operator()(Ts&& ...) [with Ts = {std::vector<blaze::DynamicMatrix<double, true>, std::allocator<blaze::DynamicMatrix<double, true> > >&}; Derived = caf::deserializer]’
/usr/local/include/caf/detail/type_erased_value_impl.hpp:79:18:   required from caf::error caf::detail::type_erased_value_impl< <template-parameter-1-1> >::load(caf::deserializer&) [with T = std::vector<blaze::DynamicMatrix<double, true>, std::allocator<blaze::DynamicMatrix<double, true> > >]’
/usr/local/include/caf/detail/type_erased_value_impl.hpp:78:9:   required from here
/usr/local/include/blaze/math/serialization/MatrixSerializer.h:363:8: error: no match for operator!’ (operand type is caf::deserializer’)
 
363 |    if( !archive ) {
     
|        ^~~~~~~~


Any pointer, reference or help would be much appreciated.

cheers
Lari

Dominik Charousset

unread,
Apr 29, 2020, 2:35:15 AM4/29/20
to actor-f...@googlegroups.com
Hi!

The serialization bit looks ok. I’m not familiar with blaze, so I don’t know if there’s a more efficient way than serializing into a string. However, if you write a string on one end, you have to read a string on the other.

I would try something along the lines of this snippet:

```
template <class Inspector>
typename enable_if<Inspector::writes_state,
typename Inspector::result_type>::type
inspect(Inspector& f, Tensor& A){
std::string buf;
auto load = [&]() -> caf::error {
// try-catch?
blaze::Archive<std::stringstream> archive(buf);
archive >> A;
// verify that the string got consumed / A is valid?
return caf::none;
};
return f(meta::type_name("tensor"), buf, caf::meta::load_callback(load));
}
```

This deserializes a string and then calls `load` to restore the Tensor from that string. The callback returns a caf::error to indicate deserialization errors (or a default-constructed error / none to indicate success).

Hope that helps.

Dominik
> --
> You received this message because you are subscribed to the Google Groups "actor-framework" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to actor-framewo...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/actor-framework/1f503145-79c7-464c-b787-d7a2e6f9a92a%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages