提交 d29aac44 authored 作者: Pascal Lamblin's avatar Pascal Lamblin

Refactor code for trying to compile/run some code

上级 1308dcf2
......@@ -1484,37 +1484,51 @@ class GCC_compiler(object):
return cxxflags
@staticmethod
def try_flags(flag_list):
'''
Try to compile a dummy file with these flags.
def try_compile_tmp(src_code, tmp_prefix='', flags=(), try_run=False):
"""Try to compile (and run) a test program.
Returns True if compilation was successful, False if there
were errors.
'''
This is useful in various occasions, to check if libraries
or compilers are behaving as expected.
If try_run is True, the src_code is assumed to be executable,
and will be run.
If try_run is False, returns the compilation status.
If try_run is False, returns a (compile_status, run_status) pair.
"""
if not theano.config.cxx:
return False
rval = True
flags = list(flags)
compilation_ok = True
try:
code = """
int main(int argc, char** argv)
{
return 0;
}
"""
fd, path = tempfile.mkstemp(suffix='.c', prefix='try_flags_')
fd, path = tempfile.mkstemp(suffix='.c', prefix=tmp_prefix)
exe_path = path[:-2]
dummy_stdin = open(os.devnull)
try:
os.write(fd, code)
os.write(fd, src_code)
os.close(fd)
fd = None
proc = call_subprocess_Popen(['g++', path] + flag_list,
proc = call_subprocess_Popen(
['g++', path, '-o', exe_path] + flags,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=dummy_stdin.fileno())
proc.wait()
if proc.returncode != 0:
rval = False
compilation_ok = False
elif try_run:
# Try to execute the program
run_ok = False
try:
proc = call_subprocess_Popen([exe_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=dummy_stdin.fileno())
proc.wait()
run_ok = (proc.returncode == 0)
finally:
os.remove(exe_path)
finally:
del dummy_stdin
try:
......@@ -1522,9 +1536,34 @@ class GCC_compiler(object):
os.close(fd)
finally:
os.remove(path)
except OSError, e:
rval = False
return rval
compilation_ok = False
if not try_run:
return compilation_ok
else:
return (compilation_ok, run_ok)
@staticmethod
def try_flags(flag_list):
'''
Try to compile a dummy file with these flags.
Returns True if compilation was successful, False if there
were errors.
'''
if not theano.config.cxx:
return False
code = """
int main(int argc, char** argv)
{
return 0;
}
"""
return GCC_compiler.try_compile_tmp(code, tmp_prefix='try_flags_',
flags=flag_list, try_run=False)
@staticmethod
def compile_str(module_name, src_code, location=None,
......
......@@ -12,18 +12,15 @@ __contact__ = "theano-dev <theano-dev@googlegroups.com>"
__docformat__ = "restructuredtext en"
import logging
import os
import subprocess
import tempfile
import warnings
import theano
from theano import config
from theano.misc.windows import call_subprocess_Popen
import theano.gof.cc
from theano.gof import graph
from theano.gof import utils
from theano.gof.cmodule import GCC_compiler
from theano.gof.fg import FunctionGraph
......@@ -770,42 +767,22 @@ class OpenMPOp(Op):
@staticmethod
def test_gxx_support():
default_openmp = True
try:
code = """
#include <omp.h>
int main( int argc, const char* argv[] )
{
int res[10];
for(int i=0; i < 10; i++){
res[i] = i;
}
}
"""
fd, path = tempfile.mkstemp(suffix='.c', prefix='test_omp_')
dummy_stdin = open(os.devnull)
try:
os.write(fd, code)
os.close(fd)
fd = None
proc = call_subprocess_Popen(['g++', '-fopenmp', path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=dummy_stdin.fileno())
proc.wait()
if proc.returncode != 0:
default_openmp = False
finally:
del dummy_stdin
# Ensure `fd` is closed before we remove the temporary file.
try:
if fd is not None:
os.close(fd)
finally:
os.remove(path)
except OSError, e:
return False
code = """
#include <omp.h>
int main( int argc, const char* argv[] )
{
int res[10];
for(int i=0; i < 10; i++){
res[i] = i;
}
}
"""
default_openmp = GCC_compiler.try_compile_tmp(
code=code,
tmp_prefix='test_omp_',
flags=['-fopenmp'],
try_run=False)
return default_openmp
def update_self_openmp(self):
......
......@@ -3,14 +3,11 @@
There is no standard name or location for this header, so we just insert it
ourselves into the C code
"""
import os
import tempfile
import textwrap
import subprocess
import sys
from theano import config
from theano.misc.windows import call_subprocess_Popen
from theano.gof.cmodule import GCC_compiler
def detect_macos_sdot_bug():
......@@ -65,61 +62,19 @@ def detect_macos_sdot_bug():
return 0;
}
""")
try:
fd, path = tempfile.mkstemp(suffix='.c',
prefix='detect_macos_sdot_bug_')
exe_path = path[:-2]
dummy_stdin = open(os.devnull)
compilation_failed = False
try:
os.write(fd, test_code)
os.close(fd)
fd = None
proc = call_subprocess_Popen(
['g++', path, '-o', exe_path] + flags,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=dummy_stdin.fileno())
proc.wait()
if proc.returncode != 0:
# We were not able to compile
compilation_failed = True
else:
# Try to execute the program
try:
proc = call_subprocess_Popen([exe_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=dummy_stdin.fileno())
proc.wait()
detect_macos_sdot_bug.tested = True
if proc.returncode != 0:
# The bug is present
detect_macos_sdot_bug.present = True
else:
detect_macos_sdot_bug.present = False
finally:
os.remove(exe_path)
finally:
del dummy_stdin
try:
if fd is not None:
os.close(fd)
finally:
os.remove(path)
except OSError, e:
compilation_failed = True
compilation_ok, run_ok = GCC_compiler.try_compile_tmp(test_code,
tmp_prefix='detect_macos_sdot_bug_', flags=flags, try_run=True)
detect_macos_sdot_bug.tested = True
# If compilation failed, we consider there is a bug,
# and the fix does not work
if compilation_failed:
detect_macos_sdot_bug.tested = True
if not compilation_ok:
detect_macos_sdot_bug.present = True
return True
if not detect_macos_sdot_bug.present:
if run_ok:
detect_macos_sdot_bug.present = False
return False
# Else, try a simple fix
......@@ -145,56 +100,14 @@ def detect_macos_sdot_bug():
return 0;
}
""")
try:
fd, path = tempfile.mkstemp(suffix='.c',
prefix='detect_macos_sdot_bug_testfix_')
exe_path = path[:-2]
dummy_stdin = open(os.devnull)
compilation_failed = False
try:
os.write(fd, test_fix_code)
os.close(fd)
fd = None
proc = call_subprocess_Popen(
['g++', path, '-o', exe_path] + flags,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=dummy_stdin.fileno())
proc.wait()
if proc.returncode != 0:
# We were not able to compile
compilation_failed = True
print >> sys.stderr, ("ERROR: Failed to compile tentative fix "
"for bug in BLAS shipped with Mac OS X")
print >> sys.stderr, "command line was:", ' '.join(
['g++', path, '-o', exe_path] + flags)
print >> sys.stderr, "error was:"
for l in proc.stderr:
print >> sys.stderr, l
else:
# Try to execute the program
try:
proc = call_subprocess_Popen([exe_path],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=dummy_stdin.fileno())
proc.wait()
if proc.returncode == 0:
# The fix is working
detect_macos_sdot_bug.fix_works = True
finally:
os.remove(exe_path)
finally:
del dummy_stdin
try:
if fd is not None:
os.close(fd)
finally:
os.remove(path)
except OSError, e:
compilation_failed = True
compilation_fix_ok, run_fix_ok = GCC_compiler.try_compile_tmp(
test_fix_code,
tmp_prefix='detect_macos_sdot_bug_testfix_',
flags=flags,
try_run=True)
detect_macos_sdot_bug.fix_works = run_fix_ok
return detect_macos_sdot_bug.present
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论