// Construct a dynamic configuration descriptor // This really needs dynamic endpoint allocation etc uint32_t USBDeviceClass::sendConfiguration(uint32_t maxlen) { uint32_t total = 0; // Count and measure interfaces _dry_run = true; uint8_t interfaces = SendInterfaces(&total); _Pragma("pack(1)") ConfigDescriptor config = D_CONFIG((uint16_t)(total + sizeof(ConfigDescriptor)), interfaces); _Pragma("pack()") // Now send them _dry_run = false; if (maxlen == sizeof(ConfigDescriptor)) { sendControl(&config, sizeof(ConfigDescriptor)); return true; } total = 0; packMessages(true); sendControl(&config, sizeof(ConfigDescriptor)); SendInterfaces(&total); packMessages(false); return true; }
/// combine (per-process) messages Opm::DeferredLogger gatherDeferredLogger(const Opm::DeferredLogger& local_deferredlogger) { int num_messages = local_deferredlogger.messages_.size(); int int64_mpi_pack_size; MPI_Pack_size(1, MPI_INT64_T, MPI_COMM_WORLD, &int64_mpi_pack_size); int unsigned_int_mpi_pack_size; MPI_Pack_size(1, MPI_UNSIGNED, MPI_COMM_WORLD, &unsigned_int_mpi_pack_size); // store number of messages; int message_size = unsigned_int_mpi_pack_size; // store 1 int64 per message for flag message_size += num_messages*int64_mpi_pack_size; // store 2 unsigned ints per message for length of tag and length of text message_size += num_messages*2*unsigned_int_mpi_pack_size; for (const auto lm : local_deferredlogger.messages_) { int string_mpi_pack_size; MPI_Pack_size(lm.tag.size(), MPI_CHAR, MPI_COMM_WORLD, &string_mpi_pack_size); message_size += string_mpi_pack_size; MPI_Pack_size(lm.text.size(), MPI_CHAR, MPI_COMM_WORLD, &string_mpi_pack_size); message_size += string_mpi_pack_size; } // Pack local messages. std::vector<char> buffer(message_size); int offset = 0; packMessages(local_deferredlogger.messages_, buffer, offset); assert(offset == message_size); // Get message sizes and create offset/displacement array for gathering. int num_processes = -1; MPI_Comm_size(MPI_COMM_WORLD, &num_processes); std::vector<int> message_sizes(num_processes); MPI_Allgather(&message_size, 1, MPI_INT, message_sizes.data(), 1, MPI_INT, MPI_COMM_WORLD); std::vector<int> displ(num_processes + 1, 0); std::partial_sum(message_sizes.begin(), message_sizes.end(), displ.begin() + 1); // Gather. std::vector<char> recv_buffer(displ.back()); MPI_Allgatherv(buffer.data(), buffer.size(), MPI_PACKED, const_cast<char*>(recv_buffer.data()), message_sizes.data(), displ.data(), MPI_PACKED, MPI_COMM_WORLD); // Unpack. Opm::DeferredLogger global_deferredlogger; global_deferredlogger.messages_ = unpackMessages(recv_buffer, displ); return global_deferredlogger; }