Beispiel #1
0
std::vector<debug_log> debug_logs(GLuint count)
{
  auto max_message_size = 0;
  glGetIntegerv(GL_MAX_DEBUG_MESSAGE_LENGTH, &max_message_size);

  std::vector<GLenum>  sources      (count);
  std::vector<GLenum>  types        (count);
  std::vector<GLuint>  ids          (count);
  std::vector<GLenum>  severities   (count);
  std::vector<GLsizei> message_sizes(count);
  std::vector<GLchar>  message_data (count * max_message_size);
  auto real_count = glGetDebugMessageLog(count, static_cast<GLsizei>(message_data.size()), &sources[0], &types[0], &ids[0], &severities[0], &message_sizes[0], &message_data[0]);
  sources      .resize(real_count);
  types        .resize(real_count);
  ids          .resize(real_count);
  severities   .resize(real_count);
  message_sizes.resize(real_count);

  std::vector<std::string> messages(real_count);
  auto current_message = message_data.begin();
  for (size_t i = 0; i < message_sizes.size(); ++i)
  {
    messages[i] = std::string(current_message, current_message + message_sizes[i] - 1);
    current_message = current_message + message_sizes[i];
  }

  std::vector<debug_log> debug_logs(real_count);
  for (unsigned i = 0; i < real_count; i++)
    debug_logs[i] = debug_log{sources[i], types[i], ids[i], severities[i], messages[i], nullptr};
  return debug_logs;
}
    /// 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;
    }