public static void SetEnvironmentVariables() { var rhome = Environment.GetEnvironmentVariable("R_HOME"); var currentPath = Environment.GetEnvironmentVariable("PATH"); switch (NativeUtility.GetPlatform()) { case PlatformID.Win32NT: Environment.SetEnvironmentVariable("PATH", FindRPathFromRegistry() + Path.PathSeparator + currentPath); break; case PlatformID.MacOSX: if (string.IsNullOrEmpty(rhome)) { Environment.SetEnvironmentVariable("R_HOME", "/Library/Frameworks/R.framework/Resources"); } Environment.SetEnvironmentVariable("PATH", "/Library/Frameworks/R.framework/Libraries" + Path.PathSeparator + currentPath); break; case PlatformID.Unix: if (string.IsNullOrEmpty(rhome)) { Environment.SetEnvironmentVariable("R_HOME", "/usr/lib/R"); } // TODO: cater for cases where user has build R from source and installed to e.g. /usr/local/lib Environment.SetEnvironmentVariable("PATH", "/usr/lib" + Path.PathSeparator + currentPath); break; } }
public void TestUsingDefaultRPackages() { // This test was designed to look at a symptom observed alongside the issue https://github.com/rdotnet/rdotnet/issues/127 SetUpTest(); var engine = this.Engine; var se = engine.Evaluate("set.seed"); if (NativeUtility.GetPlatform() == PlatformID.Win32NT) { Assert.True(engine.Evaluate("Sys.which('R.dll')").AsCharacter()[0].Length > 0); Assert.True(engine.Evaluate("Sys.which('RBLAS.dll')").AsCharacter()[0].Length > 0); } string[] expected = { "base", "methods", "utils", "grDevices", "graphics", "stats" }; var loadedDlls = engine.Evaluate("getLoadedDLLs()").AsList(); string[] dllnames = loadedDlls.Select(x => x.AsCharacter().ToArray()[0]).ToArray(); IEnumerable <string> query = from x in expected.Intersect(dllnames) select x; Assert.Equal(expected, query.ToArray()); se = engine.Evaluate("set.seed(0)"); se = engine.Evaluate("blah <- rnorm(4)"); }
/// <summary> /// Initializes a new instance of the <see cref="MultiCatchmentCompositeObjectiveEvaluator" /> class. /// </summary> /// <param name="objDefn"> The objective definition. </param> private RCompositeObjectiveEvaluator(RexpObjectiveDefinition objDefn) { objectiveDefinition = objDefn; string pathToRDynLib = objDefn.DirectoryForRLibrary; string rhome = Environment.GetEnvironmentVariable("R_HOME"); if (!Directory.Exists(pathToRDynLib)) { REngine.SetEnvironmentVariables(); } else { if (string.IsNullOrEmpty(rhome)) { var plat = NativeUtility.GetPlatform(); switch (plat) { case PlatformID.Win32NT: if (string.IsNullOrEmpty(rhome)) { rhome = Path.Combine(pathToRDynLib, @"..\.."); // Assume R more recent than 2.12 : binaries under bin\x64 for instance; folder containing 'bin' is R_HOME Log.WarnFormat("R_HOME environment variable not set. Setting R_HOME = {0}", rhome); } break; case PlatformID.Unix: Log.Debug("R init: detected Unix platform"); if (String.IsNullOrEmpty(rhome)) { throw new Exception("R_HOME environment variable is not set"); } break; default: throw new NotSupportedException(string.Format("Platform not supported: {0}", plat)); } } Log.Debug("R init: R_HOME = " + rhome); REngine.SetEnvironmentVariables(pathToRDynLib, rhome); } Log.Debug("R init: creating R engine"); rEngine = REngine.GetInstance(dll: null, initialize: false, parameter: null, device: null); Log.Debug("R init: initialising R engine"); StartupParameter rStartParams = new StartupParameter { Quiet = true, SaveAction = StartupSaveAction.NoSave, Slave = false, Interactive = true, Verbose = false, LoadInitFile = true, LoadSiteFile = true, RestoreAction = StartupRestoreAction.NoRestore, NoRenviron = false }; rEngine.Initialize(rStartParams); Log.Debug("Created rEngine: " + rEngine.ToString()); }
private void SetCstackChecking() { // Don't do any stack checking, see R Exts, '8.1.5 Threading issues', // https://rdotnet.codeplex.com/discussions/462947 // https://rdotnet.codeplex.com/workitem/115 WriteInt32("R_CStackLimit", -1); switch (NativeUtility.GetPlatform()) { case PlatformID.MacOSX: case PlatformID.Unix: WriteInt32("R_SignalHandlers", 0); // RInside does this for non-WIN32. break; } }
internal void Install(REngine engine, StartupParameter parameter) { this.engine = engine; switch (NativeUtility.GetPlatform()) { case PlatformID.Win32NT: SetupWindowsDevice(parameter); break; case PlatformID.MacOSX: case PlatformID.Unix: SetupUnixDevice(); break; } }
/// <summary> /// Creates the command line arguments corresponding to the specified startup parameters /// </summary> /// <param name="parameter"></param> /// <returns></returns> /// <remarks>While not obvious from the R documentation, it seems that command line arguments need to be passed /// to get the startup parameters taken into account. Passing the StartupParameter to the API seems not to work as expected. /// While this function may appear like an oddity to a reader, it proved necessary to the initialisation of the R engine /// after much trial and error.</remarks> public static string[] BuildRArgv(StartupParameter parameter) { var platform = NativeUtility.GetPlatform(); var argv = new List <string>(); argv.Add("rdotnet_app"); // Not sure whether I should add no-readline //[MarshalAs(UnmanagedType.Bool)] //public bool R_Quiet; if (parameter.Quiet && !parameter.Interactive) { argv.Add("--quiet"); // --quite --interactive to R embedded crashed... } //[MarshalAs(UnmanagedType.Bool)] //public bool R_Slave; if (parameter.Slave) { argv.Add("--slave"); } //[MarshalAs(UnmanagedType.Bool)] //public bool R_Interactive; if (platform != PlatformID.Win32NT) // RTerm.exe --help shows no such option; Unix only. { if (parameter.Interactive) { argv.Add("--interactive"); } } //[MarshalAs(UnmanagedType.Bool)] //public bool R_Verbose; if (parameter.Verbose) { argv.Add("--verbose"); } //[MarshalAs(UnmanagedType.Bool)] //public bool LoadSiteFile; if (!parameter.LoadSiteFile) { argv.Add("--no-site-file"); } //[MarshalAs(UnmanagedType.Bool)] //public bool LoadInitFile; if (!parameter.LoadInitFile) { argv.Add("--no-init-file"); } //[MarshalAs(UnmanagedType.Bool)] //public bool DebugInitFile; //if (parameter.Quiet) argv.Add("--quiet"); //public StartupRestoreAction RestoreAction; //public StartupSaveAction SaveAction; //internal UIntPtr vsize; //internal UIntPtr nsize; //internal UIntPtr max_vsize; //internal UIntPtr max_nsize; //internal UIntPtr ppsize; //[MarshalAs(UnmanagedType.Bool)] //public bool NoRenviron; if (parameter.NoRenviron) { argv.Add("--no-environ"); } switch (parameter.SaveAction) { case StartupSaveAction.NoSave: argv.Add("--no-save"); break; case StartupSaveAction.Save: argv.Add("--save"); break; } switch (parameter.RestoreAction) { case StartupRestoreAction.NoRestore: argv.Add("--no-restore-data"); break; case StartupRestoreAction.Restore: argv.Add("--restore"); break; } if (parameter.MaxMemorySize == (Environment.Is64BitProcess ? ulong.MaxValue : uint.MaxValue)) { // This creates a nasty crash if using the default MaxMemorySize. found out in Rdotnet workitem 72 // do nothing } else { if (platform == PlatformID.Win32NT) // On unix, otherwise led to https://rdotnet.codeplex.com/workitem/137 { argv.Add("--max-mem-size=" + parameter.MaxMemorySize); } } argv.Add("--max-ppsize=" + parameter.StackSize); return(argv.ToArray()); }
/// <summary> /// Initialize this REngine object. Only the first call has an effect. Subsequent calls to this function are ignored. /// </summary> /// <param name="parameter">The optional startup parameters</param> /// <param name="device">The optional character device to use for the R engine</param> /// <param name="setupMainLoop">if true, call the functions to initialise the embedded R</param> public void Initialize(StartupParameter parameter = null, ICharacterDevice device = null, bool setupMainLoop = true) { // Console.WriteLine("REngine.Initialize start"); if (this.isRunning) { return; } // Console.WriteLine("REngine.Initialize, after isRunning checked as false"); this.parameter = parameter ?? new StartupParameter(); this.adapter = new CharacterDeviceAdapter(device ?? DefaultDevice); // Disabling the stack checking here, to try to avoid the issue on Linux. // The disabling used to be here around end Nov 2013. Was moved later in this // function to cater for disabling on Windows, @ rev 305, however this may have // re-broken on Linux. so we may need to call it twice. SetCstackChecking(); // Console.WriteLine("Initialize-SetCstackChecking; R_CStackLimit value is " + GetDangerousInt32("R_CStackLimit")); if (!setupMainLoop) { this.isRunning = true; return; } string[] R_argv = BuildRArgv(this.parameter); //string[] R_argv = new[]{"rdotnet_app", "--interactive", "--no-save", "--no-restore-data", "--max-ppsize=50000"}; //rdotnet_app --quiet --interactive --no-save --no-restore-data --max-mem-size=18446744073709551615 --max-ppsize=50000 GetFunction <R_setStartTime>()(); int R_argc = R_argv.Length; // Console.WriteLine("Initialize-R_setStartTime; R_CStackLimit value is " + GetDangerousInt32("R_CStackLimit")); if (NativeUtility.GetPlatform() == PlatformID.Win32NT) { // Attempted Fix for https://rdotnet.codeplex.com/workitem/110; not working // Tried to make sure that the command line options are taken into account. They are NOT effectively so via Rf_initialize_R only. // The problem is that cmdlineoptions assumes it is called by RGui.exe or RTerm.exe, and overrides R_HOME // GetFunction<R_set_command_line_arguments>()(R_argc, R_argv); // GetFunction<cmdlineoptions>()(R_argc, R_argv); } var status = GetFunction <Rf_initialize_R>()(R_argc, R_argv); if (status != 0) { throw new Exception("A call to Rf_initialize_R returned a non-zero; status=" + status); } // Console.WriteLine("Initialize-Rf_initialize_R; R_CStackLimit value is " + GetDangerousInt32("R_CStackLimit")); SetCstackChecking(); // following in RInside: may not be needed. //GetFunction<R_ReplDLLinit> () (); //this.parameter.Interactive = true; this.adapter.Install(this, this.parameter); //Console.WriteLine("Initialize-adapter installation; R_CStackLimit value is " + GetDangerousInt32("R_CStackLimit")); switch (NativeUtility.GetPlatform()) { case PlatformID.Win32NT: GetFunction <R_SetParams_Windows>("R_SetParams")(ref this.parameter.start); break; case PlatformID.MacOSX: case PlatformID.Unix: GetFunction <R_SetParams_Unix>("R_SetParams")(ref this.parameter.start.Common); //Console.WriteLine("Initialize-R_SetParams_Unix; R_CStackLimit value is " + GetDangerousInt32("R_CStackLimit")); break; } GetFunction <setup_Rmainloop>()(); //Console.WriteLine("Initialize-after setup_Rmainloop; R_CStackLimit value is " + GetDangerousInt32("R_CStackLimit")); // See comments in the first call to SetCstackChecking in this function as to why we (may) need it twice. SetCstackChecking(); this.isRunning = true; //Console.WriteLine("Initialize-just before leaving; R_CStackLimit value is " + GetDangerousInt32("R_CStackLimit")); // Partial Workaround (hopefully temporary) for https://rdotnet.codeplex.com/workitem/110 if (NativeUtility.GetPlatform() == PlatformID.Win32NT) { Evaluate(string.Format("invisible(memory.limit({0}))", (this.parameter.MaxMemorySize / 1048576UL))); } }