提交 47d59f97 authored 作者: Frederic's avatar Frederic

Make cudnn_available() use nvcc

上级 a47b7df0
......@@ -1526,7 +1526,96 @@ def gcc_llvm():
gcc_llvm.is_llvm = None
class GCC_compiler(object):
class Compiler(object):
"""
Meta compiler that offer some generic function
"""
@staticmethod
def _try_compile_tmp(src_code, tmp_prefix='', flags=(),
try_run=False, output=False, compiler=None):
"""Try to compile (and run) a test program.
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 True, returns a (compile_status, run_status) pair.
If output is there, we append the stdout and stderr to the output.
"""
if not compiler:
return False
flags = list(flags)
compilation_ok = True
run_ok = False
out, err = None, None
try:
fd, path = tempfile.mkstemp(suffix='.c', prefix=tmp_prefix)
exe_path = path[:-2]
try:
# Python3 compatibility: try to cast Py3 strings as Py2 strings
try:
src_code = b(src_code)
except Exception:
pass
os.write(fd, src_code)
os.close(fd)
fd = None
out, err, p_ret = output_subprocess_Popen(
[compiler, path, '-o', exe_path] + flags)
if p_ret != 0:
compilation_ok = False
elif try_run:
out, err, p_ret = output_subprocess_Popen([exe_path])
run_ok = (p_ret == 0)
finally:
try:
if fd is not None:
os.close(fd)
finally:
os.remove(path)
os.remove(exe_path)
except OSError, e:
compilation_ok = False
if not try_run and not output:
return compilation_ok
elif not try_run and output:
return (compilation_ok, out, err)
elif not output:
return (compilation_ok, run_ok)
else:
return (compilation_ok, run_ok, out, err)
@staticmethod
def _try_flags(flag_list, preambule="", body="",
try_run=False, output=False, compiler=None):
'''
Try to compile a dummy file with these flags.
Returns True if compilation was successful, False if there
were errors.
'''
if not compiler:
return False
code = b("""
%(preambule)s
int main(int argc, char** argv)
{
%(body)s
return 0;
}
""" % locals())
return Compiler._try_compile_tmp(code, tmp_prefix='try_flags_',
flags=flag_list, try_run=try_run,
output=output, compiler=compiler)
class GCC_compiler(Compiler):
# The equivalent flags of --march=native used by g++.
march_flags = None
......@@ -1791,86 +1880,15 @@ class GCC_compiler(object):
@staticmethod
def try_compile_tmp(src_code, tmp_prefix='', flags=(),
try_run=False, output=False):
"""Try to compile (and run) a test program.
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 True, returns a (compile_status, run_status) pair.
If output is there, we append the stdout and stderr to the output.
"""
if not theano.config.cxx:
return False
flags = list(flags)
compilation_ok = True
run_ok = False
out, err = None, None
try:
fd, path = tempfile.mkstemp(suffix='.c', prefix=tmp_prefix)
exe_path = path[:-2]
try:
# Python3 compatibility: try to cast Py3 strings as Py2 strings
try:
src_code = b(src_code)
except Exception:
pass
os.write(fd, src_code)
os.close(fd)
fd = None
out, err, p_ret = output_subprocess_Popen(
[theano.config.cxx, path, '-o', exe_path] + flags)
if p_ret != 0:
compilation_ok = False
elif try_run:
out, err, p_ret = output_subprocess_Popen([exe_path])
run_ok = (p_ret == 0)
finally:
try:
if fd is not None:
os.close(fd)
finally:
os.remove(path)
os.remove(exe_path)
except OSError, e:
compilation_ok = False
if not try_run and not output:
return compilation_ok
elif not try_run and output:
return (compilation_ok, out, err)
elif not output:
return (compilation_ok, run_ok)
else:
return (compilation_ok, run_ok, out, err)
return Compiler._try_compile_tmp(src_code, tmp_prefix, flags,
try_run, output,
theano.config.cxx)
@staticmethod
def try_flags(flag_list, preambule="", body="",
try_run=False, output=False):
'''
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 = b("""
%(preambule)s
int main(int argc, char** argv)
{
%(body)s
return 0;
}
""" % locals())
return GCC_compiler.try_compile_tmp(code, tmp_prefix='try_flags_',
flags=flag_list, try_run=try_run,
output=output)
return Compiler._try_flags(flag_list, preambule, body, try_run, output,
theano.config.cxx)
@staticmethod
def compile_str(module_name, src_code, location=None,
......
......@@ -58,7 +58,7 @@ if ((err = cudnnCreate(&_handle)) != CUDNN_STATUS_SUCCESS) {
# default gpu, not the one selected by the user. If mixed
# GPU are installed or if the GPUs are configured in
# exclusive mode, this cause bad detection.
comp, out, err = gof.cmodule.GCC_compiler.try_flags(
comp, out, err = NVCC_compiler.try_flags(
["-l", "cudnn", "-I" + os.path.dirname(__file__),
"-I" + os.path.join(theano.config.cuda.root, 'include'),
"-L" + os.path.join(theano.config.cuda.root, 'lib64')],
......
......@@ -12,6 +12,7 @@ from theano.gof import local_bitwidth
from theano.gof.cc import hash_from_file
from theano.gof.cmodule import (std_libs, std_lib_dirs,
std_include_dirs, dlimport,
Compiler,
get_lib_extension)
from theano.compat.python2x import any
from theano.misc.windows import output_subprocess_Popen
......@@ -126,7 +127,20 @@ def add_standard_rpath(rpath):
rpath_defaults.append(rpath)
class NVCC_compiler(object):
class NVCC_compiler(Compiler):
@staticmethod
def try_compile_tmp(src_code, tmp_prefix='', flags=(),
try_run=False, output=False):
return Compiler._try_compile_tmp(src_code, tmp_prefix, flags,
try_run, output,
nvcc_path)
@staticmethod
def try_flags(flag_list, preambule="", body="",
try_run=False, output=False):
return Compiler._try_flags(flag_list, preambule, body, try_run, output,
nvcc_path)
@staticmethod
def version_str():
return "nvcc " + nvcc_version
......
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论