# -*- coding: utf-8 -*-
################################ Begin license #################################
# Copyright (C) Laboratory of Imaging technologies,
# Faculty of Electrical Engineering,
# University of Ljubljana.
#
# This file is part of PyXOpto.
#
# PyXOpto is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# PyXOpto is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with PyXOpto. If not, see <https://www.gnu.org/licenses/>.
################################# End license ##################################
import os
import sys
__version__ = '0.2.2'
VERBOSE = False
''' Verbose reporting. '''
if 'PYXOPTO_VERBOSE' in os.environ and os.environ['PYXOPTO_VERBOSE']:
VERBOSE = bool(os.environ['PYXOPTO_VERBOSE'])
if VERBOSE:
print('Initializing PyXOpto {}'.format(__version__))
os.environ['PYOPENCL_COMPILER_OUTPUT'] = '1'
ROOT_PATH = os.path.dirname(os.path.abspath(__file__))
''' The package directory. '''
PICKLE_PROTOCOL = 4
''' Default pickle protocol of the package. '''
DATA_PATH = os.path.join(ROOT_PATH, 'data')
''' Main data storage directory. '''
BIN_PATH = os.path.join(ROOT_PATH, 'bin')
''' Directory of binary/executable files. '''
PRIMES_PATH = os.path.join(DATA_PATH, 'primes')
''' Location of OpenCL random number generator seeds. '''
SRC_PATH = os.path.join(ROOT_PATH, 'src')
''' Location of compilable source code. '''
USER_TMP_PATH = os.path.join(ROOT_PATH, 'tmp')
''' Temporary data path. '''
MCBASE_PATH = os.path.join(ROOT_PATH, 'mcbase')
''' Root directory of MC base. '''
MCCYL_PATH = os.path.join(ROOT_PATH, 'mccyl')
''' Root directory of MC Cyl. '''
MCML_PATH = os.path.join(ROOT_PATH, 'mcml')
''' Root directory of MC ML. '''
MCVOX_PATH = os.path.join(ROOT_PATH, 'mcvox')
''' Root directory of MC VOX. '''
UTIL_PATH = os.path.join(ROOT_PATH, 'util')
''' Root directory of MC utilities. '''
USER_PATH = os.path.join(os.path.expanduser('~'), '.xopto', 'pyxopto')
''' Root path of user data storage. '''
if 'PYXOPTO_USER_PATH' in os.environ and os.environ['PYXOPTO_USER_PATH']:
USER_PATH = str(os.environ['PYXOPTO_USER_PATH'])
USER_DATA_PATH = os.path.join(USER_PATH, 'data')
''' User directory for precalculated data. '''
USER_BIN_PATH = os.path.join(USER_PATH, 'bin')
''' User directory for built libraries or executables. '''
USER_TMP_PATH = os.path.join(USER_PATH, 'tmp')
''' User directory for temporary data. '''
USER_BUILD_PATH = os.path.join(USER_PATH, 'build')
''' User directory for build. '''
USER_PRIMES_PATH = os.path.join(USER_DATA_PATH, 'primes')
''' User directory for RNG primes. '''
[docs]def fulfills_min(requirement: str) -> bool:
'''
Checks if this version of PyXOpto fulfills the minimum required version.
Parameters
----------
required: str
Required version as a string, e.g. "0.2.1".
Returns
-------
fulfills: bool
Returns True if PyXOpto fulfills the requirement, else False.
Note
----
PyXOpto version is composed of three numbers (major, minor, patch), e.g.
"0.2.0".
'''
this_version = [int(item) for item in __version__.split('.')]
for index, item in enumerate(requirement.split('.')):
item = item.strip()
if index >= len(this_version):
break
if item == '*':
continue
if this_version[index] < int(item):
return False
return True
[docs]def make_user_dirs():
'''
Create all the user directories for data, binary and temporary files.
'''
for dir in (USER_DATA_PATH, USER_BIN_PATH, USER_TMP_PATH,
USER_BUILD_PATH, USER_PRIMES_PATH):
if not os.path.isdir(dir):
try:
os.makedirs(dir)
except OSError:
pass
make_user_dirs()
[docs]def rebuild(envvars: dict = None, verbose: bool = False):
'''
Rebuilds all the external dependencies of xopto (rng).
Parameters
----------
envvars: dict
Additional environmental variables for the build process.
verbose: bool
Enables verbose output.
Examples
--------
Build with default settings and external library installation paths.
>>> import xopto
>>> xopto.rebuild()
Compiling rng.cpp ...
Linking rng.o ...
Moving rng64.so to xopto/bin ...
Cleanup ...
All done.
>>>
'''
from xopto.util import build
import platform
if not os.path.isdir(USER_BIN_PATH):
try:
os.makedirs(USER_BIN_PATH)
except OSError:
pass
if not os.path.isdir(USER_BUILD_PATH):
try:
os.makedirs(USER_BUILD_PATH)
except OSError:
pass
env = None
if envvars is not None:
for key in envvars:
os.environ[key] = envvars[key]
env = dict(os.environ)
srclist=[os.path.join(ROOT_PATH, 'src', 'rng', 'rng.cpp')]
inclist = [os.path.join(ROOT_PATH, 'src', 'rng')]
moveto = USER_BIN_PATH
os_num_bits = build.os_bits()
if platform.system() == 'Linux':
build_target = 'rng{}.so'.format(os_num_bits)
build.build_so_dll(
srclist=srclist,
inclist=inclist,
target=build_target, moveto=moveto,
envvars=envvars, cwd=USER_BUILD_PATH,
verbose=verbose
)
elif platform.system() == 'Windows':
build_target = 'rng{}.dll'.format(os_num_bits)
build.build_so_dll(
srclist=srclist,
inclist=inclist,
target=build_target, moveto=moveto,
envvars=envvars, cwd=USER_BUILD_PATH,
verbose=verbose
)
else:
raise RuntimeError('Rebuild supported only on Linux and Windows OS!')
[docs]def rebuild_(envvars: dict = None):
'''
Rebuilds all the external dependencies of xopto (rng).
Parameters
----------
envvars: dict
Additional environmental variables for the build process.
Examples
--------
Build with default settings and external library installation paths.
>>> import xopto
>>> xopto.rebuild()
Compiling rng.cpp ...
Linking rng.o ...
Moving rng64.so to xopto/bin ...
Cleanup ...
All done.
>>>
'''
import subprocess
import platform
import math
import sys
if os.path.isdir(BIN_PATH):
try:
os.makedirs(BIN_PATH)
except OSError:
pass
env = None
if envvars is not None:
for key in envvars:
os.environ[key] = envvars[key]
env = dict(os.environ)
if platform.system() == 'Linux':
cwd = os.path.join(ROOT_PATH, SRC_PATH, 'rng')
if math.log(sys.maxsize)/math.log(2) > 32:
proc = subprocess.Popen(
['./build64.sh'], cwd=cwd, env=env,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
proc = subprocess.Popen(
['./build32.sh'], cwd=cwd, env=env,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in proc.stdout:
if isinstance(line, bytes):
line = line.decode('utf8')
sys.stdout.write(line)
elif platform.system() == 'Windows':
cwd = os.path.join(ROOT_PATH, SRC_PATH, 'rng')
cwd = cwd.replace('/', '\\')
if math.log(sys.maxsize)/math.log(2) > 32:
proc = subprocess.Popen(
['build64.bat', 'exit'], cwd=cwd, shell=True,
env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
else:
proc = subprocess.Popen(
['build32.bat', 'exit'], cwd=cwd, shell=True,
env=env, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
for line in proc.stdout:
if isinstance(line, bytes):
line = line.decode('utf8')
sys.stdout.write(line)
else:
raise RuntimeError('Rebuild supported only on Linux and Windows OS!')