def _build(self, tmpdir): # File names cn, on, ln = 'tmp.c', 'tmp.o', platform_libname('tmp') # Write the source code out with open(os.path.join(tmpdir, cn), 'w') as f: f.write(self.src) # Compile cmd = [ self._cc, '-std=c99', # Enable C99 support '-Ofast', # Optimise, incl. -ffast-math '-march=native', # Use CPU-specific instructions '-fopenmp', # Enable OpenMP support '-fPIC', # Position-independent code for shared lib '-c', '-o', on, cn ] call_capture_output(cmd, cwd=tmpdir) # Link cmd = [ self._cc, '-shared', # Create a shared library '-fopenmp', # Required for OpenMP '-o', ln, on, ] call_capture_output(cmd, cwd=tmpdir) return ln
def build(self, src): # Compute a digest of the current processor, compiler, and source ckey = digest(self.proc, self.version, self.cmd, src) # Attempt to load the library from the cache mod = self._cache_loadlib(ckey) # Otherwise, we need to compile the kernel if not mod: # Create a scratch directory tmpidx = next(self._dir_seq) tmpdir = tempfile.mkdtemp(prefix=f'pyfr-{tmpidx}-') try: # Compile and link the source into a shared library cname, lname = 'tmp.c', platform_libname('tmp') # Write the source code out with open(os.path.join(tmpdir, cname), 'w') as f: f.write(src) # Invoke the compiler call_capture_output(self.cc_cmd(cname, lname), cwd=tmpdir) # Determine the fully qualified library name lpath = os.path.join(tmpdir, lname) # Add it to the cache and load mod = self._cache_set_and_loadlib(ckey, lpath) finally: # Unless we're debugging delete the scratch directory if 'PYFR_DEBUG_OMP_KEEP_LIBS' not in os.environ: rm(tmpdir) return OpenMPCompilerModule(mod)
def _build(self, tmpdir): # File names cn, on, ln = 'tmp.c', 'tmp.o', platform_libname('tmp') # Write the source code out with open(os.path.join(tmpdir, cn), 'w') as f: f.write(self._src) # Compile cmd = [self._cc, '-std=c99', # Enable C99 support '-Ofast', # Optimise, incl. -ffast-math '-march=native', # Use CPU-specific instructions '-fopenmp', # Enable OpenMP support '-fPIC', # Position-independent code for shared lib '-c', '-o', on, cn] call_capture_output(cmd, cwd=tmpdir) # Link cmd = [self._cc, '-shared', # Create a shared library '-fopenmp', # Required for OpenMP '-o', ln, on,] call_capture_output(cmd, cwd=tmpdir) return ln
def _build(self): # File names cn, on, ln = 'tmp.c', 'tmp.o', platform_libname('tmp') # Write the source code out with open(cn, 'w') as f: f.write(self._src) # Compile cmd = [self._cc, '-std=c99', # Enable C99 support '-Ofast', # Optimise, incl. -ffast-math '-march=native', # Use CPU-specific instructions '-fopenmp', # Enable OpenMP support '-fPIC', # Position-independent code for shared lib '-c', '-o', on, cn] out = subprocess.check_call(cmd, stderr=subprocess.STDOUT) # Link cmd = [self._cc, '-shared', # Create a shared library '-fopenmp', # Required for OpenMP '-o', ln, on,] out = subprocess.check_output(cmd, stderr=subprocess.STDOUT) return ln
def __init__(self, libname=None): libname = libname or platform_libname('cublas') try: lib = CDLL(libname) except OSError: raise RuntimeError('Unable to load CUBLAS') # cublasCreate self.cublasCreate = lib.cublasCreate_v2 self.cublasCreate.argtypes = [POINTER(c_void_p)] self.cublasCreate.errcheck = self._errcheck # cublasDestroy self.cublasDestroy = lib.cublasDestroy_v2 self.cublasDestroy.argtypes = [c_void_p] self.cublasDestroy.errcheck = self._errcheck # cublasSetStream self.cublasSetStream = lib.cublasSetStream_v2 self.cublasSetStream.argtypes = [c_void_p, c_void_p] self.cublasSetStream.errcheck = self._errcheck # cublasDgemm self.cublasDgemm = lib.cublasDgemm_v2 self.cublasDgemm.argtypes = [ c_void_p, c_int, c_int, c_int, c_int, c_int, POINTER(c_double), c_void_p, c_int, c_void_p, c_int, POINTER(c_double), c_void_p, c_int ] self.cublasDgemm.errcheck = self._errcheck # cublasSgemm self.cublasSgemm = lib.cublasSgemm_v2 self.cublasSgemm.argtypes = [ c_void_p, c_int, c_int, c_int, c_int, c_int, POINTER(c_float), c_void_p, c_int, c_void_p, c_int, POINTER(c_float), c_void_p, c_int ] self.cublasSgemm.errcheck = self._errcheck # cublasDnrm2 self.cublasDnrm2 = lib.cublasDnrm2_v2 self.cublasDnrm2.argtypes = [ c_void_p, c_int, c_void_p, c_int, POINTER(c_double) ] self.cublasDnrm2.errcheck = self._errcheck # cublasSnrm2 self.cublasSnrm2 = lib.cublasSnrm2_v2 self.cublasSnrm2.argtypes = [ c_void_p, c_int, c_void_p, c_int, POINTER(c_float) ] self.cublasSnrm2.errcheck = self._errcheck
def _cache_loadlib(self): # If caching is disabled then return if 'PYFR_DEBUG_OMP_DISABLE_CACHE' in os.environ: return # Otherwise, check the cache else: # Determine the cached library name clname = platform_libname(self.digest) # Attempt to load the library try: return CDLL(os.path.join(self.cachedir, clname)) except OSError: return
def __init__(self, src, cfg): # Find GCC (or a compatible alternative) self.cc = cfg.getpath('backend-openmp', 'cc', 'cc') # User specified compiler flags self.cflags = shlex.split(cfg.get('backend-openmp', 'cflags', '')) # Get the processor string proc = platform.processor() # Get the compiler version string version = call_capture_output([self.cc, '-v']) # Get the base compiler command strig cmd = self.cc_cmd(None, None) # Compute a digest of the current processor, compiler, and source self.digest = digest(proc, version, cmd, src) # Attempt to load the library from the cache self.mod = self._cache_loadlib() # Otherwise, we need to compile the kernel if not self.mod: # Create a scratch directory tmpidx = next(self._dir_seq) tmpdir = tempfile.mkdtemp(prefix='pyfr-{0}-'.format(tmpidx)) try: # Compile and link the source into a shared library cname, lname = 'tmp.c', platform_libname('tmp') # Write the source code out with open(os.path.join(tmpdir, cname), 'w') as f: f.write(src) # Invoke the compiler call_capture_output(self.cc_cmd(cname, lname), cwd=tmpdir) # Determine the fully qualified library name lpath = os.path.join(tmpdir, lname) # Add it to the cache and load self.mod = self._cache_set_and_loadlib(lpath) finally: # Unless we're debugging delete the scratch directory if 'PYFR_DEBUG_OMP_KEEP_LIBS' not in os.environ: rm(tmpdir)
def __init__(self, libname=None): libname = libname or platform_libname('clBLAS') try: lib = CDLL(libname) except OSError: raise RuntimeError('Unable to load clBLAS') # clblasSetup self.clblasSetup = lib.clblasSetup self.clblasSetup.argtypes = [] self.clblasSetup.errcheck = self._errcheck # clblasTeardown self.clblasTeardown = lib.clblasTeardown self.clblasTeardown.argtypes = [] self.clblasTeardown.restype = None # clblasSgemm self.clblasSgemm = lib.clblasSgemm self.clblasSgemm.argtypes = [ c_int, c_int, c_int, c_size_t, c_size_t, c_size_t, c_float, c_void_p, c_size_t, c_size_t, c_void_p, c_size_t, c_size_t, c_float, c_void_p, c_size_t, c_size_t, c_uint, POINTER(c_void_p), c_uint, POINTER(c_void_p), POINTER(c_void_p) ] self.clblasSgemm.errcheck = self._errcheck # clblasDgemm self.clblasDgemm = lib.clblasDgemm self.clblasDgemm.argtypes = [ c_int, c_int, c_int, c_size_t, c_size_t, c_size_t, c_double, c_void_p, c_size_t, c_size_t, c_void_p, c_size_t, c_size_t, c_double, c_void_p, c_size_t, c_size_t, c_uint, POINTER(c_void_p), c_uint, POINTER(c_void_p), POINTER(c_void_p) ] self.clblasDgemm.errcheck = self._errcheck
def _cache_set_and_loadlib(self, lpath): # If caching is disabled then just load the library as-is if 'PYFR_DEBUG_OMP_DISABLE_CACHE' in os.environ: return CDLL(lpath) # Otherwise, move the library into the cache and load else: # Determine the cached library name and path clname = platform_libname(self.digest) clpath = os.path.join(self.cachedir, clname) try: # Ensure the cache directory exists os.makedirs(self.cachedir, exist_ok=True) # Attempt to move the library to cache dir mv(lpath, clpath) # If an exception is raised, load from the original path except OSError: return CDLL(lpath) # Otherwise, load from the cache dir else: return CDLL(clpath)
def _cache_set_and_loadlib(self, ckey, lpath): # If caching is disabled then just load the library as-is if 'PYFR_DEBUG_OMP_DISABLE_CACHE' in os.environ: return CDLL(lpath) # Otherwise, move the library into the cache and load else: # Determine the cached library name and path clname = platform_libname(ckey) clpath = os.path.join(self.cachedir, clname) ctpath = os.path.join(self.cachedir, str(uuid.uuid4())) try: # Ensure the cache directory exists os.makedirs(self.cachedir, exist_ok=True) # Perform a two-phase move to get the library in place mv(lpath, ctpath) mv(ctpath, clpath) # If an exception is raised, load from the original path except OSError: return CDLL(lpath) # Otherwise, load from the cache dir else: return CDLL(clpath)
def _cache_set_and_loadlib(self, lpath): # If caching is disabled then just load the library as-is if 'PYFR_DEBUG_OMP_DISABLE_CACHE' in os.environ: return CDLL(lpath) # Otherwise, move the library into the cache and load else: # Determine the cached library name and path clname = platform_libname(self.digest) clpath = os.path.join(self.cachedir, clname) ctpath = os.path.join(self.cachedir, str(uuid.uuid4())) try: # Ensure the cache directory exists os.makedirs(self.cachedir, exist_ok=True) # Perform a two-phase move to get the library in place mv(lpath, ctpath) mv(ctpath, clpath) # If an exception is raised, load from the original path except OSError: return CDLL(lpath) # Otherwise, load from the cache dir else: return CDLL(clpath)