Перейти из форума на сайт.

НовостиФайловые архивы
ПоискАктивные темыТоп лист
ПравилаКто в on-line?
Вход Забыли пароль? Первый раз на этом сайте? Регистрация
Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)

Модерирует : ShIvADeSt

 Версия для печати • ПодписатьсяДобавить в закладки
Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330

Открыть новую тему     Написать ответ в эту тему

akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Обсуждаются все вопросы, связанные с программированием на ФОРТРАН, как общего так и конкретного характера.
Постарайтесь дать как можно больше информации о возникшей проблеме -- это в конце концов в ваших же интересах чтобы вам помогли...

прежде чем просить помощи в задании
платное решение задач

ресурсы этого топика
ссылка на подборку ресурсов, собранных посетителями этого форума
 
то, чем мы решили поделиться
ссылка на страничку программ etc собственного изготовления, которыми любезно делятся наши форумчане


если вам вдруг не отвечают или ответ вас не устраивает
и вообще полезно прочитать всем спрашивающим
 
просьба к пишущим и отвечающим все большие листинги оформлять тегом more
и отключать графические смайлики при размещении фортран-кода

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 18:11 14-01-2007 | Исправлено: akaGM, 09:47 01-03-2020
unni



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
akaGM, создал код по аналогии:
 
Код dll на Фортране...
 
Всё компилируется, но пока проверить работу не могу, поскольку мне ещё нужна одна сложная вещь. Функция CreateUserFunction() регистрирует в Mathcad пользовательскую функцию на Fortran, при этом функция будет вызываться в стиле C из Mathcad напрямую.
 
Для этого вторым параметром в функцию передаётся указатель на структуру такого вида:

Код:
 
// use this structure to create a function
#define MAX_ARGS        10
 
typedef LRESULT (* LPCFUNCTION ) ( void * const, const void * const, ... );
 
typedef struct tagFUNCTIONINFO {
    char *  lpstrName;
    char *  lpstrParameters;  
    char *  lpstrDescription;
    LPCFUNCTION lpfnMyCFunction;
    long unsigned int returnType;
    unsigned int nArgs;
    long unsigned int argType[MAX_ARGS];
} FUNCTIONINFO;
 

 
Как можно в Фортран задать такой вид структуры FUNCTIONINFO? Больше всего интересует поле LPCFUNCTION lpfnMyCFunction. И вообще, в Фортране возможно описание типа - указатель на функцию с переменным количеством аргументов?
 
Добавлено:
У меня там ошибка, описывать функцию CreateUserFunction() нужно так:
 

Код:
 
        ! const void * CreateUserFunction( HINSTANCE, FUNCTIONINFO * );
        integer( LPVOID ) function CreateUserFunction( hInstance, pFunctionInfo )  
         
            use ifwin  
             
            integer( HANDLE ), intent( in ) :: hInstance
            integer( LPVOID ), intent( in ) :: pFunctionInfo
             
        end function CreateUserFunction  
 

Я пока поставил заглушку LPVOID, а должен быть указатель на структуру FUNCTIONINFO. Может быть не обязательно иметь указатель на тип-функцию с переменным количеством параметров. Достаточно просто указатель на функцию в структуре поместить, но сама функция на Фортран должна быть написана так, как-будто это функция в стиле С.
 
Добавлено:
Вот новая реализация, я чуток дописал:
 
Исходник dll на Фортране
 
Проблема в том, что я пока не понял как указать в структуре, что я передаю указатель на функцию mcad_TestFunc1():
 

Код:
 
            Info_mcad_TestFunc1%lpstrName = "TestFunc1"C
            Info_mcad_TestFunc1%lpstrParameters = "(x) - parameter"C
            Info_mcad_TestFunc1%lpstrDescription = "Fortran test function"C
             
            !Info_mcad_TestFunc1%lpfnMyCFunction = ?
             
            Info_mcad_TestFunc1%returnType = 1            
            Info_mcad_TestFunc1%nArgs = 1
             
            Info_mcad_TestFunc1%argType(1) = 1
             
            pInfo => Info_mcad_TestFunc1
                   
            ! Регистрируем функции библиотеки (пользовательские)
            Res = CreateUserFunction( hinstDll, pInfo )
 

 
Нужно вот тут что-то дописать: !Info_mcad_TestFunc1%lpfnMyCFunction = ?
 
Ещё интересно было бы узнать как объявить функцию как cdelc:

Код:
 
integer (4) function mcad_TestFunc1( ReturnValue, Arg0 )
 
    use ifwin
    use mcadincl
     
    implicit none
     
    type ( COMPLEXSCALAR ), intent( out ) :: ReturnValue
    type ( COMPLEXSCALAR ), intent( in ) :: Arg0
     
    ReturnValue%Re = Arg0%Re
    ReturnValue%Im = Arg0%Im
   
    ! Инициализируем значение функции признаком успешного завершения
    ! работы (см. The Developer's Reference в справке Mathcad)
    mcad_TestFunc1 = 0
     
end function mcad_TestFunc1
 

Всего записей: 31 | Зарегистр. 12-09-2006 | Отправлено: 14:33 18-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
unni

Цитата:
Как можно в Фортран задать такой вид структуры FUNCTIONINFO?

через STRUCTURE, что является аналогом сишной struct
или через определение нового типа при помощи TYPE
 

Цитата:
И вообще, в Фортране возможно описание типа - указатель на функцию с переменным количеством аргументов?

насчёт переменного числа аргументов я не уверен, но вроде нельзя...
 

Цитата:
Ещё интересно было бы узнать как объявить функцию как cdelc:

integer (4) function mcad_TestFunc1( ReturnValue, Arg0 )  
!DEC$ ATTRIBUTES C :: mcad_TestFunc1

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 20:05 18-08-2012 | Исправлено: akaGM, 20:06 18-08-2012
unni



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Да, я уже кое-что нашёл и на счёт переменного числа аргументов.  
 
Шаблон dll на Фортране
 
Этот код формирует такие ошибки:

Код:
 
1>------ Build started: Project: SimpleDll, Configuration: Debug Win32 ------
1>Compiling with Intel(R) Visual Fortran Compiler XE 12.0.1.127 [IA-32]...
1>SimpleDll.f90
1>D:\Projects\Fortran\Projects\SimpleDll\SimpleDll.f90(8): error #8262: The passed-object dummy argument must be dummy data object with the same declared type as the type being defined.   [ARGLIST]
1>D:\Projects\Fortran\Projects\SimpleDll\SimpleDll.f90(233): error #6460: This is not a field name that is defined in the encompassing structure.   [LPFNMYCFUNCTION]
1>D:\Projects\Fortran\Projects\SimpleDll\SimpleDll.f90(233): error #6404: This name does not have a type, and must have an explicit type.   [MCAD_TESTFUNC1]
1>D:\Projects\Fortran\Projects\SimpleDll\SimpleDll.f90(233): error #6796: The variable must have the TARGET attribute or be a subobject of an object with the TARGET attribute, or it must have the POINTER attribute.   [MCAD_TESTFUNC1]
1>compilation aborted for D:\Projects\Fortran\Projects\SimpleDll\SimpleDll.f90 (code 1)
1>
1>Build log written to  "file://D:\Projects\Fortran\Projects\SimpleDll\Debug\BuildLog.htm"
1>SimpleDll - 5 error(s), 0 warning(s)
 

 
Пока я не понял в чём проблема.
 
Здесь рассказано об указателях на функции, но я не уверен, что эти указатели - это именно адреса в памяти:
How to work with function pointers in Fortran in scientific programs
 
А вот здесь рассказано про то как передавать переменное число параметров:
Variadic function
 
Буду думать. Видать Фортран не приспособлен для такого рода работы как я хочу - передавать указатели на функции с переменным числом параметров между dll на С и Фортран.

Всего записей: 31 | Зарегистр. 12-09-2006 | Отправлено: 20:21 18-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
unni
/очень злобно/
вот я захотел тебе помочь и скопировал твой код себе...
для начала мне приходится избавляться от твоих дедов морозов...
ты на свой код в браузере сам смотрел?
в шапке именно для тебя написано:
Цитата:
просьба к пишущим и отвечающим все большие листинги оформлять тегом [more] и отключать графические смайлики при размещении фортран-кода

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 22:35 18-08-2012
unni



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
akaGM можно было заметить, что в двух предыдущих случаях я их отключал. В последнем забыл.
 
Вот новый код, который я смог скомпилировать. Начал его тестировать. Библиотека загружается, CreateUserFunction() вызывается:
 
Пример dll на фортране
 
Результат компиляции:

Код:
 
1>------ Rebuild All started: Project: SimpleDll, Configuration: Debug Win32 ------
1>Deleting intermediate files and output files for project 'SimpleDll', configuration 'Debug|Win32'.
1>Compiling with Intel(R) Visual Fortran Compiler XE 12.0.1.127 [IA-32]...
1>SimpleDll.f90
1>Linking...
1>Embedding manifest...
1>
1>Build log written to  "file://D:\Projects\Fortran\Projects\SimpleDll\Debug\BuildLog.htm"
1>SimpleDll - 0 error(s), 0 warning(s)
========== Rebuild All: 1 succeeded, 0 failed, 0 skipped ==========
 

 
Но я этого добился тем, что включил код функции mcad_TestFunc1() в модуль и добавил модификатор nopass в описание поля-указателя:  
 
procedure ( LPCFUNCTION ), nopass, pointer :: lpfnMyCFunction
 
Пока я это сделал чтобы вообще что-то скомпилировалось. Работу проверяю в Си-программе, которая эмулирует работу CreateUserFunction().
 
Вот экран при отладке, когда фортран-dll вызывает CreateUserFunction() из mcaduser.dll:
 

 
Можно заметить, что каким-то чудом название функции попало в С-программу ("TestFunc1"). У меня есть большие сомнения, что я правильно заполнил поля с типом char * . Вряд ли это просто как character (256) можно записывать. По идее, все поля с текстом должны быть указателями. Я пока не знаю как это записать правильно. Возможно моё описание структуры в Фортране не адекватно такому же описанию в Си, от чего все другие поля по факту (при отладке) равны нулю.

Всего записей: 31 | Зарегистр. 12-09-2006 | Отправлено: 22:50 18-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
unni
молодец
 
честно говоря, ты тут уже больше меня знаешь...
но я могу быть ещё хорошим "дежурным дураком" (было такое понятие на ранних стадиях агиле программинг)
 
два совета:
 
1) заполняя поля сharacter(256) для сей, не забывай приписывать сзади char(0)
2) найди в опциях компилятора аналог /align:rec1byte для избежания изменения размера структур...
в сях, кстати, тоже надо pack(1) включить...

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 23:08 18-08-2012
unni



Newbie
Редактировать | Профиль | Сообщение | ICQ | Цитировать | Сообщить модератору
Добил, работает :) Причём не только в Mathcad, но и в SMath Studio. В общем-то меня интересовала работа именно в SMath Studio, где с помощью специального плагина можно подключать Mathcad библиотеки.
 
Есть однако несколько минусов. Пока шаблон интерфейса для функции жёсткий, т.е. если нужно будет подключить другую функцию, с другим количеством параметров или типов, то нужно будет специально для неё описывать свой интерфейс. Ещё я не победил простое описание сишных строк, прошлось пока через указатели извернуться.
 
Вот исходник:  
 
Шаблон Mathcad User Dll на Fortran
 
В этом примере в библиотеке находится функция на фортране TestFunc1(), которая работает просто как эхо - возвращает комплексное число, которое было передано в качестве аргумента.  
 
Особая прелесть использования фортрана в данном случае состоит в том, что встроенный тип double complex совпадает со структурой COMPLEXSCALAR. Т.е. это делает прозрачным комплексные вычисления в отличие от исходников на других языках.
 
Вот как выглядит отладка кода при вызове функции из Mathcad 15:
 

 
Пока для примитивных функций сойдёт. Главное, что вообще работает такой подход.

Всего записей: 31 | Зарегистр. 12-09-2006 | Отправлено: 02:17 19-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
unni
Ну а я что говорил?
Цитата:
молодец
будешь теперь местным спецом по связям с общественностью мат-пакетами...
я в своё время хотел также с матлабом замутить, но так и остановился на файлообмене...
главное, чтоб скорострельности и гибкости такого подхода хватало...
 
и вот ещё интересно, в каком подполье ты
Цитата:
Всего записей: 25 | Зарегистр. 12-09-2006
ровно 6 лет просидел :)
 
удачи

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 02:48 19-08-2012
BagaBaga

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Интересный (по крайней мере для меня) фактик:
скачал демку Intel Fortran под Win, скомпилировал модель. Так вот, при запуске и под виндой появляется та же самая ошибка чтения (что и под линуксом).
FPS4 это нормально компилирует, а исполняемый файл читает без ошибок.
Таким образом, хотя ifort и компилирует с опцией /fpscomp:all (вроде как для полной совместимости с FPS4), дело именно в компиляторе (точнее, что файл создавался программой, откомпилированной с другим компилятором).

Всего записей: 463 | Зарегистр. 14-11-2005 | Отправлено: 23:18 19-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
BagaBaga
ну выложи где-нито свой многострадальный файл и скажи чтО в нём предполагаемо живёт...

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 23:28 19-08-2012
BagaBaga

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Вот образец бинарного файла (осторожно, 80 Мб):
http://vestnik.mstu.edu.ru/a/mod4
 
В двух словах - сначала идёт небольшой заголовок (4*1024 байт, записывалось как real*4), затем метка GLOBAL MODEL, затем значения типа real*4 (описание , что же эта цифирь значит как раз и указано в заголовке).
 
Если важно (думаю - нет), величины в СГС/СГСМ/СГСЭ
PS
Более "нормальное" описание дам чуть позже - я блок ввода-вывода исполльзовал как "чёрный ящик", полезу в код уточнять реализацию, чтобы не соврать.

Всего записей: 463 | Зарегистр. 14-11-2005 | Отправлено: 21:28 20-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
а поменьше или пожать для теста нельзя было?
 
Добавлено:

Цитата:
 сначала идёт небольшой заголовок (4*1024 байт, записывалось как real*4), затем метка GLOBAL MODEL
ну не знаю, не знаю...
"GLOBAL MODEL" начинается в файле со смещения ff0 (4080), что не соответствует 4*1024
разница в 16 байт или 4 риала, как объяснишь?

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 02:07 21-08-2012
BagaBaga

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Тем, что я заврался: метка модели входит в состав первой (информационной) записи, и состоит из 4х байт - 'GLOB' (один реал) 'AL M' (второй реал) 'ODEL ' (третий реал) плюс ещё один реал (в котором в формате real*4 записана версия файла данных модели). Так что теперь всё сходится.
 
>а поменьше или пожать для теста нельзя было?  
Виноват. По-меньше под рукой не было (правда, там размер от сетки зависит, и другие не сильно меньше). А пожать как-то не сообразил (хотя жмётся ровно в два раза Если нужно - и ещё не позно - могу выложить и пожатый).

Всего записей: 463 | Зарегистр. 14-11-2005 | Отправлено: 09:45 22-08-2012 | Исправлено: BagaBaga, 09:46 22-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
BagaBaga
ну хорошо...
прочитал я информационный заголовок, в нём какие-нибудь поля надо выделять?
и что дальше с оставшимися 76 МБ делать?

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 11:22 22-08-2012
BagaBaga

Full Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
Извиняюсь за молчание - я пока сам пытаюсь расковырять это дело "ручками". Описание заголовка, если интересно, прячу под катом (но оно большое).
Подробнее...
Программа работает с т.н. "логическими файлами" (я так понимаю, это удачный или не очень перевод фортрановского logical unit) внутри одного mod4. Т.е есть массив, который говорит (числовым кодом), какой параметр в каком "куске" лежит, плюс, там три момента - прошедший, настоящий, будущий (рассчитываемый). Чтобы сократить количество операций ввода-вывода (есть "прошлые значения", "настоящие значения", и те, которые только что вычислены), то есть массив соответствий, куда прописывается метка для данных ("прошедшие" просто меткой переводятся в свободные, "настоящие" в "прошедшие", т.е. не надо перезаписывать кусок, а "рассчитанные" - пишутся "по-честному").  
Собственно, я пытаюсь в память прочитать значения с позиций, прописанных в этом заголовке (а для начала пытаюсь понять, почему такая "адресация" вдруг перестала работать в Intel Fortran)...

Всего записей: 463 | Зарегистр. 14-11-2005 | Отправлено: 16:13 22-08-2012 | Исправлено: BagaBaga, 16:23 22-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
BagaBaga
не...
описание я ниасилю, тока конкретику...
типа:
Цитата:
Собственно, я пытаюсь в память прочитать значения с позиций, прописанных в этом заголовке
с какой, сколько?
 

Цитата:
а для начала пытаюсь понять, почему такая "адресация" вдруг перестала работать в Intel Fortran
да всё там работает, даже с дефолтной компиляцией...
"на, бабка, трахайся сама" :)

Код:
implicit none
 
  integer*4, parameter :: FP = 100
  integer*4, parameter :: N = 1024
  integer*4, parameter :: SIZEBUF = 4*N
  real*4 headBuf(N)
  character*1 modelLabel(12)
  real*4 fileVersion
 
  equivalence (headBuf(N-3), modelLabel)
  equivalence (headBuf(N), fileVersion)
 
  open(FP, file='mod4.bin', status='old', form='binary')
 
  read(FP) headBuf
 
  close(FP)
 
  write(*,*) modelLabel
  write(*,*) fileVersion
 
end

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 17:19 22-08-2012 | Исправлено: akaGM, 01:59 23-08-2012
belsen85

Newbie
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
такой вопрос - как можно отследить какие участки кода в фортране, занимают больше всего времени?

Всего записей: 26 | Зарегистр. 11-07-2012 | Отправлено: 20:12 24-08-2012
adasiko



Advanced Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
belsen85
воспользоваться профилировкой, но это уже зависит от используемого инструментария

Всего записей: 1807 | Зарегистр. 30-06-2008 | Отправлено: 20:29 24-08-2012
akaGM

Platinum Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
belsen85
глянь профайлеры и ссылки вот здесь:
http://forum.ru-board.com/topic.cgi?forum=33&topic=11984#1

Всего записей: 24102 | Зарегистр. 06-12-2002 | Отправлено: 20:56 24-08-2012
Igorr

Silver Member
Редактировать | Профиль | Сообщение | Цитировать | Сообщить модератору
belsen85
Можно воспользоваться функциями времени и записывать временные точки отслеживания в файл.

Всего записей: 2003 | Зарегистр. 01-05-2002 | Отправлено: 21:20 24-08-2012
Открыть новую тему     Написать ответ в эту тему

Страницы: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330

Компьютерный форум Ru.Board » Компьютеры » Прикладное программирование » Вопросы программирования на FORTRAN (ФОРТРАН)


Реклама на форуме Ru.Board.

Powered by Ikonboard "v2.1.7b" © 2000 Ikonboard.com
Modified by Ru.B0ard
© Ru.B0ard 2000-2024

BitCoin: 1NGG1chHtUvrtEqjeerQCKDMUi6S6CG4iC

Рейтинг.ru