f2py - автоматическая многопоточность?

В настоящее время я работаю над кодом Python, и для увеличения скорости я использовал f2py для переноса некоторого существующего кода Fortran. Все работает хорошо и скорость просто потрясающая. Однако я обнаружил, что код теперь работает в нескольких потоках (согласно htop), что я нигде не указывал (может быть, это делается внутри f2py?).

Вот команда, которую я использую для создания модуля:

f2py --f90exec="gfortran" --f90flags="" --noopt \
$(ACMLLIB) $(FFTLIB) $(ACMLINC) $(FFTINC) -c -m fmod myCode.f90

где переменные $(ACMLLIB) $(FFTLIB) $(ACMLINC) и $(FFTINC) — это пути к библиотекам.

Похоже, когда я запускаю скрипт, он использует все ядра, которые может найти. У меня нет проблем с этим, но я хочу, по крайней мере, иметь возможность контролировать это - как я могу это сделать, например. установка количества потоков?

Я подозреваю, что это как-то связано с опцией -pthread здесь:

....

компиляция исходников C

Компилятор C: x86_64-linux-gnu-gcc -pthread -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fno-strict-aliasing -Wdate-time -D_FORTIFY_SOURCE=2 -g -fstack-protector-strong -Wformat -Werror=формат-безопасность -fPIC

....

Это часть массивного вывода после того, как я скомпилировал модуль Fortran. Я понятия не имею, как с этим справиться.


person rammelmueller    schedule 21.03.2017    source источник
comment
Что производит потоки? Часть Python? Фортран часть? Что именно выполняется параллельно? Это не должно происходить само по себе, пожалуйста, покажите какой-нибудь код.   -  person Vladimir F    schedule 22.03.2017
comment
Я не знаю, что именно производит распараллеливание и/или что выполняется параллельно. Когда я открываю htop в терминале, а затем запускаю код, он показывает, что все 4 потока моей машины заняты. Как я могу проверить, какая часть выполняется параллельно?   -  person rammelmueller    schedule 22.03.2017
comment
Расследуя. Извините, не могу сказать больше, ничего не видя.   -  person Vladimir F    schedule 22.03.2017
comment
Весь код сюда не влезет. Какую часть вам нужно увидеть? Что я делаю, так это беру существующую чистую версию Python (которая показывает активность только в одном потоке) и заменяю одну функцию версией Fortran. Я получаю большое ускорение, и результаты точно такие же, но я вижу активность в 4 потоках. OpenMP не использовался (и никаких флагов тоже).   -  person rammelmueller    schedule 22.03.2017
comment
Из того, что я вижу, это должно быть на фортране.   -  person rammelmueller    schedule 22.03.2017


Ответы (2)


ACML, математическая библиотека AMD (теперь уже выведенная из эксплуатации), может использовать несколько ядер, см. http://developer.amd.com/tools-and-sdks/archive/compute/amd-core-math-library-acml/acml-product-features/

Вот, скорее всего, почему вы видите. Здесь есть копия документов: https://engineering.ucsb.edu/~stefan/acml.pdf, где упоминается использование переменной среды OMP_NUM_THREADS для управления количеством используемых ядер/потоков. Это стандартная переменная среды OpenMP.

person Pierre de Buyl    schedule 22.03.2017
comment
да, я использую ACML (планирую изменить это в будущем, но пока этого достаточно..), но я не указывал явным образом какие-либо элементы OMP в своем коде. Выполняется ли это внутренними процедурами ACML? - person rammelmueller; 22.03.2017
comment
Да, это можно сделать самостоятельно. Очень правдоподобное объяснение. - person Vladimir F; 22.03.2017
comment
Однако установка OMP_NUM_THREADS и компиляция ничего не меняют. - person rammelmueller; 22.03.2017
comment
Кроме того, когда я удаляю все подпрограммы ACML и компилирую без привязки библиотеки, кажется, что она по-прежнему работает на нескольких ядрах. - person rammelmueller; 22.03.2017
comment
Насколько мне известно, gfortran не будет использовать многопоточные операции, если его об этом не попросят. Питона точно не будет. На данный момент возможно, что проблема связана с информацией, которую мы не можем догадаться из вашей полной информации SciPy/NumPy/системы/платформы сборки. - person Pierre de Buyl; 22.03.2017
comment
Кстати, OMP_NUM_THREADS нужно установить для выполнения, а не для компиляции. Либо export OMP_NUM_THREADS=1 затем выполнить, либо OMP_NUM_THREADS=1 python my_code.py - person Pierre de Buyl; 22.03.2017
comment
Да, я установил все при компиляции, а также во время выполнения. Кажется, ничего не меняется. Я работаю над Ubuntu 16.04 (4.4.0-66-generic), использую numpy v1.11.0, f2py v2, Python 2.7.12 и использую gfortran v5.4.0 20160609 для компиляции модуля Fortran. Есть ли что-то еще, что вам нужно знать? - person rammelmueller; 22.03.2017
comment
Какая установка NumPy? NumPy на основе MKL может выполнять многопоточность для линейной алгебры. - person Pierre de Buyl; 22.03.2017
comment
Кроме того, что такое библиотеки FFT? На что ваш код тратит большую часть своего времени? - person Pierre de Buyl; 22.03.2017
comment
FFT - это fftw3, насколько я знаю, я не использую Numpy на основе MKL, в этом случае я бы увидел такое же поведение в чистой версии Python, верно? Кроме того, я попытался запустить его без вызовов FFT, и все же несколько ядер показывают активность. - person rammelmueller; 22.03.2017
comment
У меня нет предположений, извините. Не видя кода, я не смогу помочь дальше. - person Pierre de Buyl; 22.03.2017
comment
Справедливо. Я как бы не хочу публиковать код публично, часть Фортрана сделана кем-то другим, не знаю, как они к этому отнесутся. Спасибо за усилия, хотя! Я (надеюсь) вернусь с ответом. - person rammelmueller; 22.03.2017
comment
На самом деле проблема в ACML. Я переключился только на LAPACK, и теперь все в порядке. Спасибо еще раз. - person rammelmueller; 22.03.2017
comment
FFTW3 также может использовать несколько потоков самостоятельно. Зависит от того, как вы его инициализируете. - person Vladimir F; 22.03.2017

Было бы неплохо иметь возможность устанавливать количество потоков f2py через переменную среды или что-то в этом роде. Я немного поискал, но не смог найти никакой информации об этом.

Однако, если вы работаете в Linux, скажем, вы можете использовать утилиту командной строки taskset, которая позволяет привязать ваш процесс (любой процесс) к определенному ядру процессора или набору ядер процессора. Это немного грубо, но я думаю, что это выполнит то, что вам нужно.

Для получения дополнительной информации см., например, здесь: http://xmodulo.com/run-program-process-specific-cpu-cores-linux.html

person Alex L    schedule 21.03.2017
comment
Хорошо, я посмотрю на это .. Спасибо! Раздражает, однако, что это не может контролироваться .. - person rammelmueller; 22.03.2017
comment
Я не говорю, что это точно невозможно — просто я не смог найти, как это сделать. Если есть список рассылки f2py или что-то в этом роде, это может быть еще одним хорошим местом, где можно спросить. - person Alex L; 22.03.2017