2013-05-14 12 views
8

Pracuję nad projektem Pythona, który używa cython i c, aby przyspieszyć operacje wrażliwe na czas. W kilku naszych procedurach cytonowych używamy openmp, aby jeszcze bardziej przyspieszyć operację, jeśli dostępne są wolne rdzenie.Programowe testowanie obsługi OpenMP ze skryptu konfiguracyjnego Pythona

Prowadzi to do nieco irytującej sytuacji w systemie OS X, ponieważ domyślny kompilator dla najnowszych wersji systemu operacyjnego (llvm/clang w wersji 10.7 i 10.8) nie obsługuje OpenMP. Nasze rozwiązanie typu "stopgap" polega na informowaniu ludzi o ustawieniu gcc jako kompilatora podczas kompilacji. Chcielibyśmy zrobić to programowo, ponieważ klang może budować wszystko inne bez problemów.

Teraz kompilacja nie powiedzie się z powodu następującego błędu:

clang: error: linker command failed with exit code 1 (use -v to see invocation) 
error: Command "cc -bundle -undefined dynamic_lookup -L/usr/local/lib -L/usr/local/opt/sqlite/lib build/temp.macosx-10.8-x86_64-2.7/yt/utilities/lib/geometry_utils.o -lm -o yt/utilities/lib/geometry_utils.so -fopenmp" failed with exit status 1 

Odpowiednia część naszego skryptu instalacyjnego wygląda następująco:

config.add_extension("geometry_utils", 
     ["yt/utilities/lib/geometry_utils.pyx"], 
     extra_compile_args=['-fopenmp'], 
     extra_link_args=['-fopenmp'], 
     libraries=["m"], depends=["yt/utilities/lib/fp_utils.pxd"]) 

Pełne plik setup.py jest here.

Czy istnieje sposób programowego testowania obsługi OpenMP z poziomu skryptu instalacyjnego?

Odpowiedz

0

udało mi się uzyskać tej pracy, sprawdzając, czy program testowy kompiluje:

import os, tempfile, subprocess, shutil  

# see http://openmp.org/wp/openmp-compilers/ 
omp_test = \ 
r""" 
#include <omp.h> 
#include <stdio.h> 
int main() { 
#pragma omp parallel 
printf("Hello from thread %d, nthreads %d\n", omp_get_thread_num(), omp_get_num_threads()); 
} 
""" 

def check_for_openmp(): 
    tmpdir = tempfile.mkdtemp() 
    curdir = os.getcwd() 
    os.chdir(tmpdir) 

    filename = r'test.c' 
    with open(filename, 'w', 0) as file: 
     file.write(omp_test) 
    with open(os.devnull, 'w') as fnull: 
     result = subprocess.call(['cc', '-fopenmp', filename], 
           stdout=fnull, stderr=fnull) 

    os.chdir(curdir) 
    #clean up 
    shutil.rmtree(tmpdir) 

    return result 
+0

Te dni nasze rozwiązanie jest nieco bardziej skomplikowany, ale sprawia, że ​​korzystanie z tej samej podstawowej idei: skompilować program testowy i zobacz, czy to działa poprawnie. Łączymy się i testujemy, aby być pewnym. Zobacz https://github.com/astropy/astropy-helpers/blob/master/astropy_helpers/openmp_helpers.py – ngoldbaum

Powiązane problemy