?

Log in

No account? Create an account

Previous Entry Share Next Entry
Исходный код расчетного модуля separator
evatutin

SEPARATOR.DPR



program separator;
{$APPTYPE CONSOLE}

uses
  Windows,
  SysUtils,
  Gerasim in 'Gerasim.pas',
  Forms,
  StdCtrls,
  ExtCtrls,
  Menus,
  Classes,
  SeparatorMain in 'SeparatorMain.pas';

begin
  SeparatorMainProc();
end.



SEPARATORMAIN.PAS


unit SeparatorMain;

interface

procedure SeparatorMainProc();

implementation

uses
  Windows, SysUtils, Gerasim, Forms, StdCtrls, ExtCtrls, Menus, Classes, Dialogs;

var
  FileName: String;
  XmlReader: TGerasimXmlIo;
  ErrorCode: TXmlReadErrorCode;
  RAG: TRandomAlgorithmsGenerator;
  RagParams: TRagParams;
  StartSeed: Integer;
  DM: TDrawManager;
  SmiSeparator: TSmiSeparator;
  MethodIndex: Integer;
  Method: TSeparationMethod;
  SeparationErrorResult: Boolean;
  OutFileWriter: TOutputDataCollector;
  CurrSeparationsCnt, TotalSeparationsCnt: Integer;
  {$IFDEF LogGen} TxtLog: TStringList; {$ENDIF}
  res: Integer;
  LastCheckpointTime, CurrTime: TDateTime;
  CheckpointFound: Boolean;
  CheckpointSS: Integer;

const
  DefaultSeparationParameters: TSeparationParameters = (GenerateLog: False);
  OutFileName = 'out';
  CheckpointFileName = 'sample.chk';
  CheckpointRandSeedFileName = 'seed.chk';
  ProgressFileName = 'fraction_done.txt';
  CheckpointInterval = 60*1000 { 1 минута } * 1;

{$IFDEF LogGen}
var
  Buf: String;
{$ENDIF}

procedure SaveLog();
const
  MAX_LEN = 1000;
var
  Len: Integer;
begin
  {$IFDEF LogGen}
  TxtLog.SaveToFile('separator_log.txt');

  SetLength(Buf, MAX_LEN);
  Len := GetTempPath(MAX_LEN, PChar(Buf));
  SetLength(Buf, Len);
  TxtLog.SaveToFile(Buf + 'separator_log.txt');
  {$ENDIF}
end;


procedure AddToLog(const Str: String);
begin
  {$IFDEF LogGen}
  TxtLog.Add(DateTimeToStr(Now) + ' ' + Str);
  SaveLog();
  {$ENDIF}
end;


procedure SaveProgressToFile(Progress: Double);
var
  Ftxt: Text;
begin
  {$I-}
  AssignFile(Ftxt, ProgressFileName);
  ReWrite(Ftxt);
  if IOResult() = 0 then begin
    Write(Ftxt, Progress);
    CloseFile(Ftxt);
  end;
end;


function IsTimeToCheckpoint(CurrTime, LastTime: TDateTime): Boolean;
var
  ct, lt: TTimeStamp;
begin
  ct := DateTimeToTimeStamp(CurrTime);
  lt := DateTimeToTimeStamp(LastTime);

  Result := (ct.Date - lt.Date)*24*60*60*1000 + (ct.Time - lt.Time) > CheckpointInterval;
end;


procedure SaveRandSeed();
var
  F: File;
begin
  AssignFile(F, CheckpointRandSeedFileName);
  ReWrite(F, 1);
  BlockWrite(F, StartSeed, SizeOf(StartSeed));
  CloseFile(F);
end;


procedure LoadRandSeed();
var
  F: File;
begin
  AssignFile(F, CheckpointRandSeedFileName);
  Reset(F, 1);
  BlockRead(F, StartSeed, SizeOf(StartSeed));
  CloseFile(F);
end;


procedure SeparatorMainProc();
var
  I, Xmax, Wmax: Integer;
begin
  try
    {$IFDEF LogGen}
    TxtLog := TStringList.Create();
    {$ENDIF}

    AddToLog('Separator started with command line "' + GetCommandLine() + '"');

    OutFileWriter := TOutputDataCollector.Create();

    { Удаление старого файла с прогрессом - иначе при старте с checkpoint'а возможны прыжки процента выполнения }
    if FileExists(ProgressFileName) then
      DeleteFile(ProgressFileName);

    { Получение имени файла }
    case ParamCount() of
      0: FileName := 'in';
      1: FileName := ParamStr(1);
      else begin
        AddToLog('Command line error: must be "separator.exe <file_name>.xml" or "separator.exe"');
        Halt(Integer(ecCommandLineError));
      end;
    end;

    { Загрузка файла с исходными данными для расчета }
    XmlReader := TGerasimXmlIo.Create();
    ErrorCode := XmlReader.ReadXml(FileName);
    if ErrorCode <> ecNone then begin
      AddToLog('Error reading xml-file. Error code ' + IntToStr(Integer(ErrorCode)));
      Halt(Integer(ErrorCode));
    end;

    CurrSeparationsCnt := 0;
    with XmlReader do
      TotalSeparationsCnt := SampleSize * (XmaxTo - XmaxFrom + 1) * (YmaxTo - YmaxFrom + 1) * (WmaxTo - WmaxFrom + 1);

    { Загрузка методов }
    MM := TMethodsManager.Create();
    MM.Options := MM.Options + [opPatientDllLoading];
    MM.LoadMethods('');     { Методы ищем в той же папке, где exe'шник - ограничение BOINC }

    AddToLog('Methods loaded successfully');

    { Определение индекса метода, который будет использоваться при построении разбиений }
    if XmlReader.MethodName = 'b' then begin
      MethodIndex := MM.BaranovIndex;
      Method := smBaranovVatutin;
    end else if XmlReader.MethodName = 'p' then begin
      MethodIndex := MM.PsmIndex;
      Method := smPSM;
    end else if XmlReader.MethodName = 'ab' then begin
      MethodIndex := MM.AdjacentBaranovIndex;
      Method := smAdjacentBaranov;
    end else if XmlReader.MethodName = 'bf' then begin
      MethodIndex := MM.BruteForceIndex;
      Method := smBruteForce;
    end else if XmlReader.MethodName = 'rs1000' then begin
      MethodIndex := MM.RandomSearch1000Index;
      Method := smRandomSearch1000;
    end else if XmlReader.MethodName = 'rs10000' then begin
      MethodIndex := MM.RandomSearch10000Index;
      Method := smRandomSearch10000;
    end else begin
      AddToLog('Unknown method: ' + XmlReader.MethodName);
      Halt(Integer(ecUnknownMethod));
    end;

    { Проведение экспериментов }
    { Параметры генератора случайных алгоритмов }
    RagParams := DefaultRagParams;
    RagParams.MaxVertexesCnt := XmlReader.N;
    RagParams.TotalLogCndsCnt := XmlReader.RagTotalX;
    RagParams.TotalMicroOpsCnt := XmlReader.RagTotalY;

    StartSeed := XmlReader.StartSeed;

    { DrawManager }
    DM := TDrawManager.Create(nil, 100, 100, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil, nil);

    SmiSeparator := TSmiSeparator.Create(DM);

    { checkpoint }
    LastCheckpointTime := Now();

    { Проверка наличия предыдущего checkpoint'а }
    CheckpointFound := False;
    try
      if FileExists(CheckpointFileName) and FileExists(CheckpointRandSeedFileName) then begin
        OutFileWriter.LoadFromFile(CheckpointFileName);
        LoadRandSeed();

        CheckpointSS := OutFileWriter.HighIndex() + 1;
        CheckpointFound := True;
        CurrSeparationsCnt := CheckpointSS;

        AddToLog('Checkpoint file found and successfully loaded');
      end else
        AddToLog('Checkpoint file not found');
    except
      on Exception do begin
        AddToLog('Exception during checkpoint file loading');
        CheckpointFound := False;
        OutFileWriter.Clear();
      end;
    end;

    AddToLog('Start processing sample of random algorithms');

    for I := 1 to XmlReader.SampleSize do begin

      { Если найден и загружен checkpoint, алгоритм не генерируем, а просто пропускаем несколько алгоритмов в выборке без генерации }
      if not CheckpointFound then begin
        RagParams.RandSeed := StartSeed;
        RAG := TRandomAlgorithmsGenerator.Create(RagParams, DM.CS);

        { Генерация случайного алгоритма }
        StartSeed := RAG.BuildRandomAlgorithm();

        { Передача алгоритма DrawManager'у }
        DM.LoadFromRag(RAG.FiguresArr);

        RAG.Free();

        SmiSeparator.PrepareToSeparation();
        SmiSeparator.LoadParameters(DefaultSeparationParameters);

        AddToLog('Ready for separations of algorithm ' + IntToStr(I));
      end;

      for Xmax := XmlReader.XmaxFrom to XmlReader.XmaxTo do
        // for Ymax := ToDo...
          for Wmax := XmlReader.WmaxFrom to XmlReader.WmaxTo do begin

            { checkpoint - пропускаем несколько итераций }
            if CheckpointFound then begin
              Dec(CheckpointSS);
              if CheckPointSS = 0 then begin
                CheckpointFound := False;
                AddToLog(IntToStr(CheckPointSS) + ' separations skiped');
              end;
              continue;
            end;

            { Значения ограничений }
            TechnologicalLimits.MicroCmdsCntMax_W := Wmax;
            TechnologicalLimits.LogCndsCntMax_X := Xmax;

            { Построение разбиения }
            SeparationErrorResult := not SmiSeparator.BuildSeparation(MM.Items[MethodIndex]);

            OutFileWriter.AddDataItem(
                RagParams.RandSeed,
                SeparationErrorResult,
                Method,
                XmlReader.N,
                Xmax,
                High(Integer),
                Wmax,
                SmiSeparator.SeparationResults.SubAlgsCnt,
                SmiSeparator.SeparationResults.RepeatedLogCnds_X,
                SmiSeparator.SeparationResults.RepeatedMicroOps_Y,
                SmiSeparator.SeparationResults.NetworkComplexity,
                SmiSeparator.SeparationResults.InterblockTraffic,
                SmiSeparator.SeparationResults.WeightFuncValue
            );

            SmiSeparator.FreeMethodResources(MM.Items[MethodIndex]);

            { Уведомление о прогрессе }
            Inc(CurrSeparationsCnt);

            SaveProgressToFile(CurrSeparationsCnt/TotalSeparationsCnt);

            { Не нужно ли сделать checkpoint? }
            CurrTime := Now();
            if IsTimeToCheckpoint(CurrTime, LastCheckpointTime) then begin
              OutFileWriter.SaveToFile(CheckpointFileName);
              SaveRandSeed();
              LastCheckpointTime := Now();

              AddToLog('Checkpoint complited successfully');
            end;
          end;

      SmiSeparator.FreeAlgorithmResources();
    end;

    AddToLog('Resources freeing: SmiSeparator, DM, XmlReader');

    SmiSeparator.Free();
    DM.Free();
    XmlReader.Free();

    OutFileWriter.SaveToFile(OutFileName);
    OutFileWriter.Free();

    AddToLog('Results saved successfully');

    { Удаление файлов checkpoint'а }
    if FileExists(CheckpointFileName) then
      DeleteFile(CheckpointFileName);

    if FileExists(CheckpointRandSeedFileName) then
      DeleteFile(CheckpointRandSeedFileName);

    AddToLog('Separator finished successfully');
  except
    on E: Exception do begin
      AddToLog('Unknown exception with message: ' + E.Message);
      Halt(Integer(ecUnknownException));
    end;
  end;
end;


end.


Ватутин Э.И., Валяев С.Ю. Расчетный модуль для построения разбиений параллельных алгоритмов логического управления с использованием добровольных распределенных вычислений // Свидетельство о государственной регистрации программы для ЭВМ № 2013618013 от 28.08.13.

13-Separator