Ошибка при передаче (приеме данных) массива сериализации с использованием MPI. NET (v1.4) - PullRequest
1 голос
/ 09 января 2020

Иногда я получаю следующее сообщение об ошибке при получении сериализованного массива с текущей версией MPI (v1.4):

Unhandled exception: System.Runtime.Serialization.SerializationException: The end of the stream was reached before processing was completed.
at System.Runtime.Serialization.Formatters.Binary .__ BinaryParser.Run ()
at System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize (HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize (Stream serializationStream, HeaderHandler handler, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
at MPI.BinaryFormatterSerializer.Deserialize [T] (Stream stream)
at MPI.Serialization.ReceiveLarge [T] (Communicator comm, Int32 source, Int32 tag, T & value, CompletedStatus & status)
at MPI.Communicator.Receive [T] (Int32 source, Int32 tag, T & value, CompletedStatus & status)
at MPI.Communicator.Receive [T] (Int32 source, Int32 tag, T & value)
at MPI.Communicator.Receive [T] (Int32 source, Int32 tag)

Спорадически означает, что ошибка всегда содержит блок получения моего кода в строка кода "SendList receiveList = comm.Receive (0, 2);" но всегда происходит в разное время. Иногда MPI удается передать 50% данных, иногда только 30% или только 10%. Я тестировал свою программу на разных компьютерах, но ошибка всегда одинакова. Все работало со старой версией MPI (v1.0). Мне пришлось обновиться до новой версии, потому что только с этим возможна отладка x64 в Visual Studio 2019 (со старой версией MPI отладка x64 всегда останавливается).

Угадай: Из-за сообщение об ошибке, это должно быть как-то связано с десериализацией данных. На мой взгляд, данные не были полностью переданы. Для других данных (меньшего размера и разных типов), которые я отправляю без сериализации через MPI (не показано в коде ниже), нет ошибки.

Вопрос: Как я могу решить проблему или обойти это?

Коротко обо мне: Извините за плохой английский sh, я использовал переводчик Google, я не обученный программист, и, следовательно, мне не хватает базовых знаний. Я бы сам отнесся к себе как к начинающему, который немного чему-то научил.

Вот мой код для отправки:

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Runtime.Serialization;

namespace Calculator.Helper
{
    public static class MPISender
    {
        public static void SendPolygonParts(ICommunicator comm, Polygon[] polygonParts, int i, bool isLast)
        {
            SendList sendObject = new SendList(polygonParts, isLast);

            try
            {
                if (i != 0)
                    comm.Send(sendObject, i - 1, 2);

                else
                    comm.Send(sendObject, 0, 2);
            }

            catch (SerializationException se)
            {
                if (i != 0)
                    Logger.Error(string.Format(CultureInfo.CurrentCulture, "Senden des Polygonpaketes Nr. {0} an Node/Soket/Core {1} nicht erfolgreich.", i, i - 1));

                else if (i == 0 && polygonParts.Length == 0)
                    Logger.Error(string.Format(CultureInfo.CurrentCulture, "Senden des leeren Polygonpaketes von der Node/Soket/Core {0} ({2}) an die Hauptnode war nicht erfolgreich. Fehler: {1}", comm.Rank, se, comm.ProcessorName));

                else if (i == 0 && polygonParts.Length != 0)
                    Logger.Error(string.Format(CultureInfo.CurrentCulture, "Senden des durch die Locherkennung analysierten Polygonpaketes mit {1} Polygonen von der Node/Soket/Core {0} ({2}) an die Hauptnode war nicht erfolgreich.", comm.Rank, polygonParts.Length, comm.ProcessorName));
            }
        }
    }
}



using System;

namespace Calculator.MpiCommunication
{
    [Serializable]
    public class SendList
    {
        public bool IsLast { get; private set; }

        private Polygon[] polygonList;

        public Polygon[] GetPolygonList()
        {
            return polygonList;
        }

        private void SetPolygonList(Polygon[] value)
        {
            polygonList = value;
        }

        public SendList(Polygon[] liste, bool isLast)
        {
            SetPolygonList(liste);
            IsLast = isLast;
        }
    }
}

Вот мой код получить:

using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Windows.Forms;

namespace Calculator
{
    internal static class NativeMethods
    {
        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool AttachConsole(int ProcessId);

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool AllocConsole();

        [DllImport("kernel32.dll", SetLastError = true)]
        [return: MarshalAs(UnmanagedType.Bool)]
        internal static extern bool FreeConsole();
    }

    static class Program
    {
        [STAThread]
        static void Main(string[] args)
        {
            using (new MpiEnvironment(ref args))
            {
                ICommunicator comm = MpiEnvironment.Communicator;
                if (comm.Rank == 0) 
                {
                     more code.......
                }
                else
                {
                    while (comm.Receive<int>(0, 0) == 0) 
                    {
                        Polygon[] polygons = Array.Empty<Polygon>();
                        bool isNotLast = true;
                        while (isNotLast)
                        {
                            SendList receivedList = comm.Receive<SendList>(0, 2);
                            List<Polygon> polygonsList = polygons == null ? new List<Polygon>() : polygons.ToList(); 
                            polygonsList.AddRange(receivedList.GetPolygonList()); 
                            isNotLast = !receivedList.IsLast;
                            polygons = polygonsList.ToArray();
                        }

                        more code....

                        break; // beende die while-schleife
                    }
                    Application.Exit();
                }
            }
        }
    }
}

Надеюсь, я предоставил всю необходимую информацию. Пожалуйста, помогите мне, я не знаю, что делать дальше.

Спасибо.

...