Skip to content
Snippets Groups Projects
Commit bfe7a4e0 authored by Adam Welc's avatar Adam Welc
Browse files

Merged.

parents 9f062883 4ed8f0d5
Branches
No related tags found
No related merge requests found
......@@ -25,37 +25,100 @@ from os.path import join, sep, dirname
from argparse import ArgumentParser
import mx
import mx_gate
import mx_graal
import mx_jvmci
import os
import shutil
'''
This is the launchpad for all the functions available for building/running/testing/analyzing
FastR. Ideally this code would be completely VM agnostic, i.e., be able to build/run with a variety
of VMs without change. That is currently not feasible due to the requirement that building
must use an pre-existing VM and running (for performance testing) must use a Graal-enabled VM.
It would require separate build/run steps to finesse this. However, running under a standards
VM is supported by dynamically checking if the jvmci suite is available
'''
_fastr_suite = mx.suite('fastr')
_mx_jvmci = mx.suite("jvmci", fatalIfMissing=False)
def r_command_project():
return "com.oracle.truffle.r.engine"
class FakeJVMCI:
def get_vm(self):
# should only happen of jvmci vm selected
mx.abort('FakeJVMCI.get_vm called')
def r_command_class():
return r_command_project() + ".shell.RCommand"
def get_jvmci_jdk(self):
return mx.get_jdk()
def rscript_command_class():
return r_command_project() + ".shell.RscriptCommand"
def build(self, args):
return mx.build(args)
def rrepl_command_class():
return r_command_project() + ".repl.RREPLServer"
def mx_jvm():
'''
Check if the jvmci suite is available and if not return a fake one
that uses the standard vm
'''
if not _mx_jvmci:
return FakeJVMCI()
else:
return _mx_jvmci.extensions
def runR(args, className, nonZeroIsFatal=True, extraVmArgs=None, runBench=False, graal_vm='server'):
setREnvironment(graal_vm)
vmArgs = ['-cp', mx.classpath(r_command_project())]
vmArgs += ["-Drhome.path=" + _fastr_suite.dir]
_r_command_project = 'com.oracle.truffle.r.engine'
_command_class_dict = {'r': _r_command_project + ".shell.RCommand",
'rscript': _r_command_project + ".shell.RscriptCommand",
'rrepl': _r_command_project + "repl.RREPL"}
def runR(args, command, nonZeroIsFatal=True, extraVmArgs=None, jdk=None):
'''
This is the basic function that runs a FastR process. Args:
command: e.g. 'R', implicitly defines the entry class (can be None for AOT)
args: a list of command arguments
extraVmArgs: additional vm arguments
jdk: jdk (an mx.JDKConfig instance) to use
By default a non-zero return code will cause an mx.abort, unless nonZeroIsFatal=False
The assumption is that the VM is already built and available.
'''
setREnvironment()
if not jdk:
jdk = get_default_jdk()
vmArgs = ['-cp', mx.classpath(_r_command_project)]
vmArgs += ["-Drhome.path=" + _fastr_suite.dir]
# jvmci specific
vmArgs += ['-G:InliningDepthError=500', '-XX:JVMCINMethodSizeLimit=1000000']
if runBench == False:
if extraVmArgs is None or not '-da' in extraVmArgs:
# unless explicitly disabled we enable assertion checking
vmArgs += ['-ea', '-esa']
if extraVmArgs:
vmArgs += extraVmArgs
return mx_graal.run_vm(vmArgs + [className] + args, vm=graal_vm, nonZeroIsFatal=nonZeroIsFatal)
vmArgs = _sanitize_vmArgs(jdk, vmArgs)
if command:
vmArgs.append(_command_class_dict[command.lower()])
return mx.run_java(vmArgs + args, nonZeroIsFatal=nonZeroIsFatal, jdk=jdk)
def _sanitize_vmArgs(jdk, vmArgs):
'''
jdk/vm dependent analysis of vmArgs to remove those that are not appropriate for the
chosen jdk/vm. It is easier to allow clients to set anything they want and filter them
out here.
'''
if jdk.tag == 'jvmci':
vm = mx_jvm().get_vm()
else:
vm = None
xargs = []
i = 0
while i < len(vmArgs):
vmArg = vmArgs[i]
if vmArg.startswith('-G') or 'JVMCI' in vmArg:
if vm and vm == "original":
i = i + 1
continue
xargs.append(vmArg)
i = i + 1
return xargs
def _get_ldpaths(lib_env_name):
ldpaths = os.path.join(_fastr_suite.dir, 'etc', 'ldpaths')
......@@ -75,11 +138,11 @@ def _get_ldpaths(lib_env_name):
except subprocess.CalledProcessError:
mx.abort('error retrieving etc/ldpaths')
def setREnvironment(graal_vm):
def setREnvironment():
'''
If R is run via mx, then the library path will not be set, whereas if it is
run from 'bin/R' it will be, via etc/ldpaths. Except that in the latter case
we still need to add /usr/lib to so that JNR can resolve libc for RFFI.
on Darwin we still need to add /usr/lib to so that JNR can resolve libc for RFFI.
'''
osname = platform.system()
if osname == 'Darwin':
......@@ -95,16 +158,21 @@ def setREnvironment(graal_vm):
if osname == 'Darwin':
lib_value = lib_value + os.pathsep + '/usr/lib'
os.environ[lib_env] = lib_value
# For R sub-processes we need to set the DEFAULT_VM environment variable
os.environ['DEFAULT_VM'] = graal_vm
def _get_graal_vm():
def get_default_jdk():
'''
Check for the --vm global mx argument by checking mx.jvmci._vm.
Returns the (default) jdk under which to run.
N.B. The jvmci jdk actually comes in three variants and the choice
is controlled either by the DEFAULT_VM environment variable (recommended) or
the --vm global option to mx.
'''
return "server" if mx_jvmci._vm is None else mx_jvmci._vm
return mx_jvm().get_jvmci_jdk()
def rcommon(args, command, klass, extraVmArgs=None):
def rcommon(args, command, extraVmArgs=None, runner=runR):
'''
Common function for running either R, Rscript (or rrepl).
args are a list of strings that came after 'command' on the command line
'''
parser = ArgumentParser(prog='mx ' + command)
parser.add_argument('--J', dest='extraVmArgsList', action='append', help='extra Java VM arguments', metavar='@<args>')
ns, rargs = parser.parse_known_args(args)
......@@ -114,32 +182,32 @@ def rcommon(args, command, klass, extraVmArgs=None):
extraVmArgs = []
for e in ns.extraVmArgsList:
extraVmArgs += [x for x in shlex.split(e.lstrip('@'))]
graal_vm = _get_graal_vm()
return runR(rargs, klass, extraVmArgs=extraVmArgs, graal_vm=graal_vm)
return runner(rargs, command, extraVmArgs=extraVmArgs)
def rshell(args):
'''run R shell'''
return rcommon(args, 'R', r_command_class())
return rcommon(args, 'r')
def rscript(args):
'''run Rscript'''
return rcommon(args, 'Rscript', rscript_command_class())
return rcommon(args, 'rscript')
def rrepl(args, nonZeroIsFatal=True, extraVmArgs=None):
'''run R repl'''
return rcommon(args, "rrepl", rrepl_command_class(), extraVmArgs=['-DR:+Instrument'])
return rcommon(args, "rrepl", extraVmArgs=['-DR:+Instrument'])
def build(args):
'''FastR build'''
graal_vm = _get_graal_vm()
# Overridden in case we ever want to do anything non-standard
# workaround for Hotspot Mac OS X build problem
osname = platform.system()
if osname == 'Darwin':
os.environ['COMPILER_WARNINGS_FATAL'] = 'false'
os.environ['USE_CLANG'] = 'true'
os.environ['LFLAGS'] = '-Xlinker -lstdc++'
mx_jvmci.build(args, vm=graal_vm) # this calls mx.build
mx_jvm().build(args)
def pylint(args):
mx.pylint(['--primary'])
def _fastr_gate_runner(args, tasks):
# Until fixed, we call Checkstyle here and limit to primary
......@@ -178,7 +246,6 @@ mx_gate.add_gate_runner(_fastr_suite, _fastr_gate_runner)
def gate(args):
'''Run the R gate'''
# exclude findbugs until compliant
mx_gate.gate(args + ['-x', '-t', 'FindBugs,Checkheaders,Checkstyle,Distribution Overlap Check,BuildJavaWithEcj'])
......@@ -205,9 +272,7 @@ def _test_harness_body(args, vmArgs):
def test(args):
'''used for package installation/testing'''
parser = ArgumentParser(prog='r test')
vm = _get_graal_vm()
with mx_jvmci.VM(vm):
return mx.test(args, harness=_test_harness_body, parser=parser)
return mx.test(args, harness=_test_harness_body, parser=parser)
def _test_srcdir():
tp = 'com.oracle.truffle.r.test'
......@@ -266,10 +331,9 @@ def _junit_r_harness(args, vmArgs, junitArgs):
vmArgs += ['-G:InliningDepthError=500', '-XX:JVMCINMethodSizeLimit=1000000', '-Xmx4G']
graal_vm = _get_graal_vm()
setREnvironment(graal_vm)
return mx_graal.run_vm(vmArgs + junitArgs, vm=graal_vm, nonZeroIsFatal=False)
setREnvironment()
jdk = get_default_jdk()
return mx.run_java(vmArgs + junitArgs, nonZeroIsFatal=False, jdk=jdk)
def junit(args):
'''run R Junit tests'''
......@@ -445,7 +509,7 @@ def load_optional_suite(name, rev):
return opt_suite
_r_apptests_rev = 'a4c4be26fd6bbe650243298d676e628062e0de77'
_r_benchmarks_rev = '8015c2260bf971904a9bf7e49eceb974117cd514'
_r_benchmarks_rev = '72d997353aefb1a31e376d8c7a9bc3dfff8016cf'
def mx_post_parse_cmd_line(opts):
# load optional suites, r_apptests first so r_benchmarks can find it
......@@ -468,6 +532,7 @@ _commands = {
'junitsimple' : [junit_simple, ['options']],
'junitdefault' : [junit_default, ['options']],
'junitgate' : [junit_gate, ['options']],
'pylint' : [pylint, ['options']],
'unittest' : [unittest, ['options']],
'rbcheck' : [rbcheck, ['options']],
'rcmplib' : [rcmplib, ['options']],
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment