На главную страницу
Русский English
 


Поддержка
Форум
Техподдержка
Закрытый разделПерсональная

Авторизация

Запомнить меня на этом компьютере
  Забыли свой пароль?
  Регистрация



Поиск по сайту


Подписка

Изменение параметров

Hits 67409044
394
Hosts 3607153
190
Visitors 53561990
393

70


Главная / Поддержка / Форумы / Макро

Форум «Макро»

Версия для печати Версия для печати

Список форумов
Новые темы
Список тем
Поиск по форумам
Помощь
Войти
Регистрация

Сообщения 26 - 45 из 45
Начало | Пред. | 1 2 | След. | Конец 

Тема: «Rastr и python , работа с Rastr в python » в форуме: Макро   Просмотров: 12695
 
Александр Александров
Администратор
 
Всего сообщений: 659
Дата регистрации: 31.05.2008
Создано: 09.08.2024 09:08:28
 
 


Код

import sys
import win32com.client as c32
from win32com.client import WithEvents

if(sys.maxsize > 2**32):
    print("Python x64 and Rastr must be x64 ")
else:
    print("Python x32 and Rastr must be x32 ")
rastr = c32.Dispatch('astra.rastr­')  
class MyEvents:
    #C# proto: ( LogErrorCodes Code,  int Level, int StageId,  string TableName, int TableIndex,  string Description, string FormName)
    def OnLog (self, a1,a2,a3,a4,a5,a6,a7):
        print(f"{a1} : {a2} : {a3} :{a4} :{a5} :{a6} :{a7} !")
r_events = c32.WithEvents(rastr, MyEvents)
rastr.Load(1,r'C:Usersust­asDocumentsRastrWin3test-­rastrcx195.rg2','')
rastr.Printp('test')
rastr.rgm('')


 
Профиль
Наверх
Михаил Одинцов
Постоянный посетитель
 
Всего сообщений: 148
Дата регистрации: 22.07.2008
Создано: 12.08.2024 00:28:47
 
 
Спасибо большое! Помогло продвинуться, но недалеко

Изначально хочу написать код, который проводить расчёты ДУ параллельно, в нескольких потоках. Ну т.е. пользователь задает список rst, список scn и все это считается - снимаются графики изменения углов и напряжений. Т.к. один расчёт длится примерно час, то возникла идея распараллелить расчёты, например по числу логических процессоров (сейчас вручную запускаем 4-6 расчётов на Рустаб на одной машине и все это работает параллельно).

Ниже код, который параллелит расчёты. При вызове целевой функции Рустаб замечательно все считает, при вызове целевой функции в дочернем потоке вылезает ошибка "библиотека сжатия результатов недоступна" и расчет ДУ запускается только в EMS режиме без записи результатов. А при запуске в пуле потоков (в примере из 5 потоков), так вообще все разваливается, Растр только пишет в лог "Возникло неизвестное исключение", один только поток пытается что-то посчитать.

Вопрос такой, а вообще по технологии описанной выше можно ли добиться распараллеливания расчётов? В тестировании с расчётом УР такой подход работал(((

Код
import win32com.client
import os
import queue
import threading
import datetime
from concurrent.futures import ThreadPoolExecutor, wait, ALL_COMPLETED


# Класс для событий Растра
class Rastr_events:
    def __init__(self):
        self.txt = []
    #C# proto: ( LogErrorCodes Code,  int Level, int StageId,  string TableName, int TableIndex,  string Description, string FormName)
    def OnLog (self, a1,a2,a3,a4,a5,a6,a7):
        if a1 not in set([3, 4, 5, 6]):
            txt = f"{datetime.datetime.now(­).time()}: {threading.current_thread­().name}: {a1} : {a2} : {a3} :{a4} :{a5} :{a6} :{a7}"
            print(txt)
            self.txt.append(txt)
# Функция снятия картинок
def dynamic_draw(rastr, files_queue, path_rastr_shablon):
    rastr_event = win32com.client.WithEvent­s(rastr, Rastr_events)
    while not files_queue.empty():
        task_rastr = files_queue.get(block=Tru­e, timeout=None)
        # Загрузка файлов растр
        rastr.Load(1, task_rastr['file_rst'], path_rastr_shablon+"динам­ика.rst")
        rastr.Load(1, task_rastr['file_scn'], path_rastr_shablon+"сцена­рий.scn")
        if task_rastr['file_dfw'] is None:
            rastr.Load(1, path_rastr_shablon+"автом­атика.dfw", path_rastr_shablon + "автоматика.dfw")
        else:
            rastr.Load(1, task_rastr['file_dfw'], path_rastr_shablon+"автом­атика.dfw")
        rastr.Load(1, task_rastr['file_kpr'], path_rastr_shablon+"контр­-е величины.kpr")
        # Настройка параметров сохранения результатов
        com_dynamics = rastr.Tables("com_dynamic­s")
        com_dynamics.Cols("SnapMa­xCount").SetZ(0, 1)    # Максимальное кол-во слотов результатов
        com_dynamics.Cols("SnapAu­toLoad").SetZ(0, 1)    # Автозагрузка последнего результата
        com_dynamics.Cols("MaxRes­ultFiles").SetZ(0, 1)    # Максимальное количество файлов результатов
        com_dynamics.Cols("Period­Angle").SetZ(0, 1)    # Отображать углы в диапазоне +/-180
        com_dynamics.Cols("SnapPa­th").SetZ(0, task_rastr['save_path'])    # Выходной каталог результатов
        com_dynamics.Cols("SnapTe­mplate").SetZ(0, f'{task_rastr['num_sna']}­.sna')    # Шаблон имени выходного файла
        com_dynamics.Cols("Realti­meCSV").SetZ(0, 1)    # Выводить контролируемые величины в CSV
        com_dynamics.Cols("Tras")­.SetZ(0, task_rastr['Tras'])   # Время расчёта
        com_dynamics.Cols("Tras")­.SetZ(0, 0.1)  # Время расчёта поменьше

        dyn = rastr.FWDynamic()    # Получение интерфейса динамики
        print(f'{datetime.datetim­e.now().time()}: Поток {threading.current_thread­().name} начал работу над заданием {task_rastr['num_sna']}')­
        kod = dyn.Run()    # Расчёт ДУ с записью результатов
        if kod == 0:
            print(f'{datetime.datetim­e.now().time()}: Поток {threading.current_thread­().name} успешно посчитал задание №{task_rastr['num_sna']} ДУ с записью результатов')
        else:
            print(f'{datetime.datetim­e.now().time()}: Поток {threading.current_thread­().name} НЕуспешно посчитал задание №{task_rastr['num_sna']} ДУ с записью результатов')
        kod_ems = dyn.RunEMSmode()    # Расчёт ДУ без записи результатов
        if kod_ems == 0:
            print(f'{datetime.datetim­e.now().time()}: Поток {threading.current_thread­().name} успешно посчитал задание №{task_rastr['num_sna']} ДУ без записи результатов')
        else:
            print(f'{datetime.datetim­e.now().time()}: Поток {threading.current_thread­().name} НЕуспешно посчитал задание №{task_rastr['num_sna']} ДУ без записи результатов')
# Функция многопоточного расчета ДУ
def multi_thread(max_rastrs=2­, files_queue=None,path_ras­tr_shablon=''):
    if files_queue is not None:
        # Многопоточное снятие картинок ДУ
        with ThreadPoolExecutor(max_wo­rkers=max_rastrs) as executor:
            futures = [executor.submit(dynamic_­draw, win32com.client.Dispatch(­"Astra.Rastr"), files_queue, path_rastr_shablon,) for _ in range(max_rastrs)]
            done, not_done = wait(futures, return_when = ALL_COMPLETED)
# Определяем путь к шаблонам
try:
    path_rastr = win32com.client.Dispatch(­"WScript.Shell").RegRead(­"HKEY_CURRENT_USER\Softwa­re\RastrWin3\UserFolder")­
    path_rastr_shablon = path_rastr + '\SHABLON\'
except:
    path_rastr_shablon = 'C:\Users\Odintsov-MV\Doc­uments\RastrWin3\SHABLON\­'

# Задаем очереди заданий на расчет
queue_rastr = queue.Queue()
queue_rastr1 = queue.Queue()
queue_rastr5 = queue.Queue()
i = 1
i_max = 10   # Количество заданий на расчёт
while i <= i_max:
    task_rastr = {}
    task_rastr['file_rst'] = '***.rst'
    task_rastr['file_scn'] = '***.scn'
    task_rastr['file_dfw'] = path_rastr_shablon + 'автоматика.dfw'
    #task_rastr['file_kpr'] = "***.kpr"
    task_rastr['file_kpr'] = path_rastr_shablon + 'контр-е величины.kpr'
    task_rastr['save_path'] = '***'
    task_rastr['num_sna'] = i
    task_rastr['Tras'] = 0.1
    queue_rastr.put(task_rast­r) # Кладем задание на расчёт для запуска в главном потоке в очередь
    queue_rastr1.put(task_ras­tr)  # Кладем задание на расчёт для запуска в многопоточном (1 поток) режиме
    queue_rastr5.put(task_ras­tr)  # Кладем задание на расчёт для запуска в многопоточном (5 потоков) режиме
    i += 1

# Запускаем просто целевую функцию
rastr = win32com.client.Dispatch(­"Astra.Rastr")
print(f'{datetime.datetim­e.now().time()}: Запуск в главном потоке')
dynamic_draw(rastr, queue_rastr, path_rastr_shablon)

# Запускаем многопоточный расчёт с 1 потоком
# print(f'{datetime.datetim­e.now().time()}: Многопоточный запуск с 1 потоком')
# multi_thread(max_rastrs=1­, files_queue=queue_rastr1,­ path_rastr_shablon=path_r­astr_shablon)

# Запускаем многопоточный расчёт с 5 потоками
# print(f'{datetime.datetim­e.now().time()}: Многопоточный запуск с 5 потоками')
# multi_thread(max_rastrs=5­, files_queue=queue_rastr5,­ path_rastr_shablon=path_r­astr_shablon)
 
Профиль
Наверх
ale
Заслуженный посетитель
 
Всего сообщений: 304
Дата регистрации: 31.03.2009
Создано: 12.08.2024 08:06:30
 
 
Т.к. один расчёт длится примерно час......вот вначале с этого и надо начинать, а потом уже автоматизировать))) Час это явно перебор)
 
Профиль
Наверх
Александр Александров
Администратор
 
Всего сообщений: 659
Дата регистрации: 31.05.2008
Создано: 12.08.2024 12:56:24
 
 
Цитата
Т.к. один расчёт длится примерно час......вот вначале с этого и надо начинать, а потом уже автоматизировать))) Час это явно перебор)@

– Поддерживаю.


По расчёту с помощью потоков, скорее всего хорошо не получится. Причина в том, что проблема в одном потоке, приводит к проблемам во всех остальных.

Как можно сделать, или как это устроено в БарсМДП.
1) Есть утилита запуска процесса расчёта и оформления результатов – УР
2) Есть сервис расчёта, понимающий команды управляющего сервиса – СР
3) Есть управляющий сервис ПРОЦЕССОВ расчета – УС
4) Есть простой UI для УС, позволяющий загрузить файл, выбрать объём расчетов, проследить/остановить/зап­устить процесс расчёта.

Через UI, определяется объём задачи для УС.
УС дробит её на подзадачи и раздаёт СР.
СР при получении задачи запускает УР, по завершении отчитывается СР о результатах.
УС агрегирует результаты в общий отчёт по результатам расчётов.

Сейчас подобный подход позволяет ежедневно рассчитывать МДП на 17 сечениях на 24 интервала планирования (408 расчётов МДП), за время менее 20 мин. При использовании 5 серверов с СР с 10 процессорами на каждом.
 
Профиль
Наверх
Михаил Одинцов
Постоянный посетитель
 
Всего сообщений: 148
Дата регистрации: 22.07.2008
Создано: 12.08.2024 15:18:35
 
 
Цитата
Т.к. один расчёт длится примерно час......вот вначале с этого и надо начинать, а потом уже автоматизировать))) Час это явно перебор)


Я работаю в проектной организации, мы делаем СВЭ/СВМ, верифицированные модели ДУ мы получаем от ОДУ в рамках бизнес-процессов по приказу 1195, регулирующему разработку СВМ/СВЭ. Так что формально я не имею права вносить изменения в модель, кроме объектов вводимых в рамках СВМ, потом эти модели мы отправляем обратно в ОДУ. Никто из СЭР не возьмет на себя ответственность и скажет что можно убрать половину присланной ими модели, зато потом в случае чего легко понапишет замечаний, что модель не такая.

Во-первых, если удастся распараллелить расчёты, то проще их считать параллельно, чем экивалентировать модель и потом сравнивать эквивалентированную и исходную модель.
Во-вторых длч расчета некоторых крупных станций или межсистемных сечений просто не получится сделать маленькую модель.
Во-третьих, даже если расчет идет 10 минут, то распараллеливание все равно даст ощутимы прирост к результатам.
 
Профиль
Наверх
Михаил Одинцов
Постоянный посетитель
 
Всего сообщений: 148
Дата регистрации: 22.07.2008
Создано: 12.08.2024 15:41:37
 
 
Цитата
Как можно сделать, или как это устроено в БарсМДП.
1) Есть утилита запуска процесса расчёта и оформления результатов – УР
2) Есть сервис расчёта, понимающий команды управляющего сервиса – СР
3) Есть управляющий сервис ПРОЦЕССОВ расчета – УС
4) Есть простой UI для УС, позволяющий загрузить файл, выбрать объём расчетов, проследить/остановить/зап­­устить процесс расчёта.


Да, я понимаю примерно что это примено то, к чему в идеале все должно прийти со временем.


Цитата
Через UI, определяется объём задачи для УС.
УС дробит её на подзадачи и раздаёт СР.
СР при получении задачи запускает УР, по завершении отчитывается СР о результатах.
УС агрегирует результаты в общий отчёт по результатам расчётов.

Здесь Вы пишете про УР и статическую устойчивость только, ЭМПП (ДУ) БАРС МДП не считает? Просто тот же код, что я привел выше, я сначала запускал для расчётов УР, и там все вроде стабильно работало (думаю и для утяжеления сработает, но еще не тестировал, для режимов и статики проблема длительности расчётов не стоит остро, как с ДУ). Поэтому я и подумал, что есть проблема именно с библиотекой сжатия данных Рустаба.

Потоки были выбранны просто из-за удобства, т.к. проще было реализовать распределение задач между потоками. Попробую считать ЭМПП в разных процессах, может случится чудо и все там будет работать.
 
Профиль
Наверх
ale
Заслуженный посетитель
 
Всего сообщений: 304
Дата регистрации: 31.03.2009
Создано: 12.08.2024 15:58:27
 
 
Разве есть запрет на внесение изменений? С улыбкой Никто же не говорит о конкрентной попилке модели. Все в руках расчетчика, если человек понимает, что как и где должно считать и работать, то можно сделать под себя модель. Надеяться на то, что кто-то предоставит и оно будет конфеткой, не совсем правильно)
 
Профиль
Наверх
Александр Александров
Администратор
 
Всего сообщений: 659
Дата регистрации: 31.05.2008
Создано: 12.08.2024 16:05:40
 
 
Цитата

Вы пишете про УР и статическую устойчивость только, ЭМПП (ДУ) БАРС МДП не считает?

- считает, только в другом ОДУ и на меньшем числе сечений.


 
Профиль
Наверх
Евгений Машалов
Администратор

 
Всего сообщений: 1059
Дата регистрации: 23.04.2007
Создано: 12.08.2024 23:49:20
 
 
1. Бибилиотеки сжатия результатов на запись уже нет. Она интегрирована унутрь в рамках импортозамещения dll и COM.
2. Полагаю что submit вызывает Dispatch на каждый поток ? Эта многопоточность для девочек иногда делает странные вещи. Но я бы создавал растр уже внутри потока, а не передавал его из основного. Есть такое, знаете STA, и оно желает чтобы объект создавался в апартменте потока, а не передавался откуда-то. И я бы даже может использовал ProcessPool, как советует Александр.
3. У меня на с++ клиент в 16 потоков жарит будь здоров. Написан по всем правилам COM, никаких вроде проблем.
 
Профиль
Наверх
Константин
Заглянувший
 
Всего сообщений: 3
Дата регистрации: 13.08.2024
Создано: 13.08.2024 17:26:57
 
 
1) Подскажите, пожалуйста, какую библиотеку вы используете для организации и управления потоками в С++?
2) Еще интересует реализация доступа к событиям OnLog на С++, если возможно.
 
Профиль
Наверх
Евгений Машалов
Администратор

 
Всего сообщений: 1059
Дата регистрации: 23.04.2007
Создано: 13.08.2024 18:52:22
 
 
1. stl/tbb
2. вполне стандартная
 
Профиль
Наверх
Константин
Заглянувший
 
Всего сообщений: 3
Дата регистрации: 13.08.2024
Создано: 14.08.2024 13:26:59
 
 
И все это реализовано на VC++ с его возможностями импорта библиотеки? А возможно без танца с бубном (без импорта) подключиться событиям OnLog?
 
Профиль
Наверх
Евгений Машалов
Администратор

 
Всего сообщений: 1059
Дата регистрации: 23.04.2007
Создано: 14.08.2024 19:54:48
 
 
Я прочитал два раза и не понял с бубном это на голом API (у вас там чего ? MiniGW поди), или с import/ATL ? На самом деле разница-то не очень большая... Anyway, consider snippet
 
Профиль
Наверх
Константин
Заглянувший
 
Всего сообщений: 3
Дата регистрации: 13.08.2024
Создано: 19.08.2024 10:35:18
 
 
Спасибо!
Но пока не разобрался как это реализовать при позднем связывании без #import.
 
Профиль
Наверх
Евгений Машалов
Администратор

 
Всего сообщений: 1059
Дата регистрации: 23.04.2007
Создано: 19.08.2024 11:16:34
 
 
Как раз обработка событий и возможна только через позднее связываниие: обратите внимание на то что Advice делается на IDispatch, и он может быть реализован без import, почему я и дал линк на msdn про чистый API. Такой подход, конечно, имеет основное преимущество - клиент в меньшей степени зависит от изменений сервера. Но это о-о-ч-ч-чч-ень медленно, и Вам захочется early binding прямо сразу. ATL позволяет делать оба два, если что, почти одновременно.
 
Профиль
Наверх
Михаил Одинцов
Постоянный посетитель
 
Всего сообщений: 148
Дата регистрации: 22.07.2008
Создано: 20.08.2024 13:58:35
 
 
Цитата
1. Бибилиотеки сжатия результатов на запись уже нет. Она интегрирована унутрь в рамках импортозамещения dll и COM.
2. Полагаю что submit вызывает Dispatch на каждый поток ? Эта многопоточность для девочек иногда делает странные вещи. Но я бы создавал растр уже внутри потока, а не передавал его из основного. Есть такое, знаете STA, и оно желает чтобы объект создавался в апартменте потока, а не передавался откуда-то. И я бы даже может использовал ProcessPool, как советует Александр.
3. У меня на с++ клиент в 16 потоков жарит будь здоров. Написан по всем правилам COM, никаких вроде проблем.

Спасибо за советы, будем пробовать.
А по п.1 с какой версии библиотека была внутрь интегрирована?
 
Профиль
Наверх
Евгений Машалов
Администратор

 
Всего сообщений: 1059
Дата регистрации: 23.04.2007
Создано: 20.08.2024 15:43:39
 
 
https://rastrwin.ru/rastr­/modification.php
 
Профиль
Наверх
Евгений Машалов
Администратор

 
Всего сообщений: 1059
Дата регистрации: 23.04.2007
Создано: 12.09.2024 23:32:41
 
 
Тем временем

Пользователь добавил изображение
 
Профиль
Наверх
Иван Ведерников
Посетитель
 
Всего сообщений: 27
Дата регистрации: 06.11.2018
Создано: 03.10.2024 14:01:35
 
 
Добрый день!
На компе установлены версии растра 2.5.0.6052 и 2.9.1.6580.

К какому Com объекту происходит
подключение? и как подключаться к разным версиям?

rastr = win32com.client.Dispatch(­'Astra.Rastr')
 
Профиль
Наверх
Станислав Богданов
Модератор
 
Всего сообщений: 61
Дата регистрации: 11.10.2012
Создано: 03.10.2024 15:14:05
 
 
Отмечу что это разные битности версий, 2.5 - x86, 2.9.1 - x64.
Для этого вам необходимо иметь 2 питона x64,x86, каждый из них будет запускать соответствующую версию Astra.

Две версии Rastrwin одной битности установить нельзя, вернее работать будет последняя из установленных.
 
Профиль
Наверх


Сообщения 26 - 45 из 45
Начало | Пред. | 1 2 | След. | Конец 

Читают тему
гостей: 2, пользователей: 0, из них скрытых: 0


Список форумов
Новые темы
Список тем
Поиск по форумам
Помощь
Войти
Регистрация







Программный комплекс «RasrWin»
Программный комплекс «RastrWin»
© «RastrWin», 1988-2019