С Новым годом! Форум программистов, компьютерный форум, киберфорум
OpenMP
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.50/8: Рейтинг темы: голосов - 8, средняя оценка - 4.50
0 / 0 / 0
Регистрация: 07.11.2017
Сообщений: 21
1

Чтение одного и того же файла несколькими потоками на Fortran. Вызов процедур Fortran из C++, используя OpenMP

02.02.2022, 09:57. Показов 1571. Ответов 2

Author24 — интернет-сервис помощи студентам
С помощью "OpenMP" на C++ я создаю несколько потоков, каждый их которых вызывает некие одинаковые процедуры на Фортране, которые работают с одними и теми же файлами (не изменяют их! только читают). Так вот, у меня постоянно возникают ошибки чтения файла (то формат данных в файле не тот, то ещё что-нибудь). Но если я то же самое буду делать, но в однопоточном режиме, то всё нормально работает, никаких ошибок нет. Так вот, я и подумал, что, может быть, в Фортране нельзя один и тот же файл одновременно читать несколькими потоками? Ну, или что-то в этом роде. Я не знаю Фортрана, но приходится его подключать к C++, по ходу и разбираюсь. Помогите, пожалуйста...
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.02.2022, 09:57
Ответы с готовыми решениями:

Есть задача на чтение из файла и обработку двумерного массива в Fortran, написал на C++, надо написать на fortran
#include <iostream> #include <fstream> #include <string> /* Составить программу для...

Чтение из файла (Fortran 77)
Здравствуйте. Казалось таким простым заданием, но Fortran меня убивает. Нужно просто открыть файл...

OpenMP, Windows, Fortran
Решил вначале попробовать на персональном компьютере (4 ядра) библиотеку OpenMP. Нашел прямо в...

Не удается распараллелить цикл через OpenMP в Fortran
Здравствуйте! Пытаюсь распараллелить цикл do в Фортране (Inteal Parallel Studio поверх MSVS) на 6...

2
693 / 303 / 99
Регистрация: 04.07.2014
Сообщений: 846
08.02.2022, 00:32 2
Лучший ответ Сообщение было отмечено Abaris как решение

Решение

Abaris, видимо стоит включить режим телепата. Что-то подсказывает что у вас фиксированы юниты при открытии файлов. Вот минимальный пример:

CMakeLisits.txt:
Код
cmake_minimum_required(VERSION 3.16)
project(example_omp_fortran_from_c++ LANGUAGES C CXX Fortran)

find_package(OpenMP REQUIRED)

set(CMAKE_Fortran_FLAGS "${CMAKE_Fortran_FLAGS} -fno-underscoring")


add_executable(exam "main.cpp" "myfun.f95")
target_link_libraries(exam OpenMP::OpenMP_C OpenMP::OpenMP_CXX OpenMP::OpenMP_Fortran)
set_property(TARGET exam PROPERTY CXX_STANDARD 17)
main.cpp:
C++
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
#include <stdio.h>
#include <chrono>
#include <thread>
 
#include <omp.h>
 
#include "myfun.h"
 
int main() {
    using namespace std::chrono_literals;
 
    myfun_write_example_file();
 
    myfun_open_file();
 
    const int N = 10;
    double x[N], y[N], z[N];
 
    #pragma omp parallel for
    for(int i = 0; i < N; i++) {
        myfun_read_line(&x[i], &y[i], &z[i]);
        std::this_thread::sleep_for(100ms);
    }
 
    for(int i=0; i < N; i++) {
        printf("%i %f %f %f\n", i, x[i], y[i], z[i]);
    }
 
    myfun_close_file();
}
myfun,f95
Fortran
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
subroutine myfun_open_file()
    open(unit=13, file="myfun.txt", status="old")
end subroutine
 
subroutine myfun_close_file()
    close(unit=13)
end subroutine
 
subroutine myfun_read_line(x, y, z)
    real*8 :: x, y, z
    read(13,*) x, y, z
end subroutine
 
subroutine myfun_write_example_file
    integer :: i
    real*8 :: x, y, z
 
    open(unit=14, file="myfun.txt", status="replace")
    do i=1,10
        x = i * 0.01;
        y = i * 0.01 + 1.0;
        z = i * 0.01 + 2.0;
        write(14,*) x, y, z
    end do
    close(unit=14)
end subroutine
myfun,h:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef MYFUN_H
#define MYFUN_H
 
#ifdef __cplusplus
extern "C" {
#endif
 
void myfun_open_file();
 
void myfun_close_file();
 
void myfun_read_line(double *x, double *y, double *z);
 
void myfun_write_example_file();
 
#ifdef __cplusplus
}
#endif
 
#endif
Пример сгенерированного файла

Код
   9.9999997764825821E-003   1.0099999904632568        2.0099999904632568     
   1.9999999552965164E-002   1.0199999809265137        2.0199999809265137     
   2.9999999329447746E-002   1.0299999713897705        2.0299999713897705     
   3.9999999105930328E-002   1.0399999618530273        2.0399999618530273     
   4.9999997019767761E-002   1.0499999523162842        2.0499999523162842     
   5.9999998658895493E-002   1.0599999427795410        2.0599999427795410     
   7.0000000298023224E-002   1.0700000524520874        2.0699999332427979     
   7.9999998211860657E-002   1.0800000429153442        2.0799999237060547     
   8.9999996125698090E-002   1.0900000333786011        2.0899999141693115     
   9.9999994039535522E-002   1.1000000238418579        2.0999999046325684
Пример результата работы:

Код
0 0.030000 1.030000 2.030000
1 0.080000 1.080000 2.080000
2 0.100000 1.100000 2.100000
3 0.010000 1.010000 2.010000
4 0.050000 1.050000 2.050000
5 0.090000 1.090000 2.090000
6 0.040000 1.040000 2.040000
7 0.070000 1.070000 2.070000
8 0.020000 1.020000 2.020000
9 0.060000 1.060000 2.060000
Обратите внимание на:
- строки перепутаны, т.к. порядок чтения строк и порядок обработки итераций цикла разный.
- я открыл файл только один раз, но доступен он из всех потоков.

Видимо аналогичное происходит и у вас, и возможно это ещё усугубляется несколькими открытиями/закрытиями файла.

Так что совет только один. В одном потоке прочитайте данные, в других их обработайте.
2
0 / 0 / 0
Регистрация: 07.11.2017
Сообщений: 21
08.02.2022, 04:12  [ТС] 3
Да, там действительно везде эти "юниты" фиксированы, везде какое-то конкретное число пишется. Я тоже подумал, что из-за этого, и теперь вы меня в этом убедили. Спасибо! Я просто Фортран не знаю, и не стал приводить код, так как подумал, что могу что-нибудь по не знанию не относящееся к вопросу привести... Да и решил, что это общий вопрос без привязки к конкретному коду.
0
08.02.2022, 04:12
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
08.02.2022, 04:12
Помогаю со студенческими работами здесь

Как перекомпилировать код из Fortran 77 в Fortran 90/95?
Добрый день! У меня есть exe-файл, написанный на Fortran 77 для Windows XP 32-bit. На моём...

Fortran Compaque Visual Fortran, линковщик
Доброго времени суток! После установки CVF создаю простейший проект, компиляция проходит...

Чтение из файла, запись в файл и работа с TList несколькими потоками
Есть задача, основная часть работы которой сводится к алгоритму: 1. Прочитать из текстового...

Перевод кода с Fortran 7.7 на Fortran 6.6
Добрый вечер! Помогите Пожалуйста перевести программу с Fortran 7.7 на Fortran 6.6: program...

Генерация случайных чисел несколькими потоками - OpenMP
необходимо реализовать генерацию случайных чисел с использованием нескольких потоков и выполнить...

Fortran: вызов массива из подпрограммы
Доброе время суток! Мне нужно дописать старую программу для расчета некоторых величин. Программа...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
3
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru