void test_parcel_serialization(hpx::parcelset::parcel outp, int out_archive_flags, bool zero_copy) { // serialize data std::vector<hpx::serialization::serialization_chunk> out_chunks; std::size_t arg_size = get_archive_size(outp, out_archive_flags, zero_copy ? &out_chunks : nullptr); std::vector<char> out_buffer; out_buffer.resize(arg_size + HPX_PARCEL_SERIALIZATION_OVERHEAD); { // create an output archive and serialize the parcel hpx::serialization::output_archive archive( out_buffer, out_archive_flags, zero_copy ? &out_chunks : nullptr); archive << outp; arg_size = archive.bytes_written(); } out_buffer.resize(arg_size); // deserialize data hpx::parcelset::parcel inp; { // create an input archive and deserialize the parcel hpx::serialization::input_archive archive( out_buffer, arg_size, &out_chunks); archive >> inp; } // make sure the parcel has been de-serialized properly HPX_TEST_EQ(outp.source_id(), inp.source_id()); HPX_TEST_EQ(outp.destination_locality(), inp.destination_locality()); HPX_TEST_EQ(outp.start_time(), inp.start_time()); hpx::actions::base_action *outact = outp.get_action(); hpx::actions::base_action *inact = inp.get_action(); HPX_TEST_EQ(outact->get_component_type(), inact->get_component_type()); HPX_TEST_EQ(outact->get_action_name(), inact->get_action_name()); HPX_TEST_EQ(int(outact->get_action_type()), int(inact->get_action_type())); HPX_TEST_EQ(outact->get_parent_locality_id(), inact->get_parent_locality_id()); HPX_TEST_EQ(outact->get_parent_thread_id(), inact->get_parent_thread_id()); HPX_TEST_EQ(outact->get_parent_thread_phase(), inact->get_parent_thread_phase()); HPX_TEST_EQ(int(outact->get_thread_priority()), int(inact->get_thread_priority())); HPX_TEST_EQ(int(outact->get_thread_stacksize()), int(inact->get_thread_stacksize())); HPX_TEST_EQ(outact->get_parent_thread_phase(), inact->get_parent_thread_phase()); std::unique_ptr<hpx::actions::continuation> outcont = outp.get_continuation(); std::unique_ptr<hpx::actions::continuation> incont = inp.get_continuation(); HPX_TEST_EQ(outcont->get_continuation_name(), incont->get_continuation_name()); HPX_TEST_EQ(outcont->get_id(), incont->get_id()); //// invoke action encapsulated in inp //naming::address const* inaddrs = pin.get_destination_addrs(); //hpx::threads::thread_init_data data; //inact->get_thread_init_data(inaddrs[0].address_, data); //data.func(hpx::threads::wait_signaled); }
double benchmark_serialization(std::size_t data_size, std::size_t iterations, bool continuation, bool zerocopy) { hpx::naming::id_type const here = hpx::find_here(); hpx::naming::address addr(hpx::get_locality(), hpx::components::component_invalid, reinterpret_cast<boost::uint64_t>(&test_function)); // compose archive flags #ifdef BOOST_BIG_ENDIAN std::string endian_out = hpx::get_config_entry("hpx.parcel.endian_out", "big"); #else std::string endian_out = hpx::get_config_entry("hpx.parcel.endian_out", "little"); #endif unsigned int out_archive_flags = 0U; if (endian_out == "little") out_archive_flags |= hpx::serialization::endian_little; else if (endian_out == "big") out_archive_flags |= hpx::serialization::endian_big; else { HPX_ASSERT(endian_out =="little" || endian_out == "big"); } std::string array_optimization = hpx::get_config_entry("hpx.parcel.array_optimization", "1"); if (boost::lexical_cast<int>(array_optimization) == 0) { out_archive_flags |= hpx::serialization::disable_array_optimization; out_archive_flags |= hpx::serialization::disable_data_chunking; } else { std::string zero_copy_optimization = hpx::get_config_entry("hpx.parcel.zero_copy_optimization", "1"); if (boost::lexical_cast<int>(zero_copy_optimization) == 0) { out_archive_flags |= hpx::serialization::disable_data_chunking; } } // create argument for action std::vector<double> data; data.resize(data_size); hpx::serialization::serialize_buffer<double> buffer(data.data(), data.size(), hpx::serialization::serialize_buffer<double>::reference); // create a parcel with/without continuation hpx::parcelset::parcel outp; if (continuation) { outp = hpx::parcelset::parcel(here, addr, new hpx::actions::transfer_action<test_action>( hpx::threads::thread_priority_normal, buffer), new hpx::actions::typed_continuation<int>(here)); } else { outp = hpx::parcelset::parcel(here, addr, new hpx::actions::transfer_action<test_action>( hpx::threads::thread_priority_normal, buffer)); } outp.set_parcel_id(hpx::parcelset::parcel::generate_unique_id()); outp.set_source(here); std::vector<hpx::serialization::serialization_chunk>* chunks = 0; if (zerocopy) chunks = new std::vector<hpx::serialization::serialization_chunk>(); boost::uint32_t dest_locality_id = outp.get_destination_locality_id(); hpx::util::high_resolution_timer t; for (std::size_t i = 0; i != iterations; ++i) { std::size_t arg_size = get_archive_size(outp, out_archive_flags, chunks); std::vector<char> out_buffer; out_buffer.resize(arg_size + HPX_PARCEL_SERIALIZATION_OVERHEAD); { // create an output archive and serialize the parcel hpx::serialization::output_archive archive( out_buffer, out_archive_flags, dest_locality_id, chunks); archive << outp; arg_size = archive.bytes_written(); } hpx::parcelset::parcel inp; { // create an input archive and deserialize the parcel hpx::serialization::input_archive archive( out_buffer, arg_size, chunks); archive >> inp; } if (chunks) chunks->clear(); } return t.elapsed(); }