Skip to content

Commit

Permalink
Dotnet 6 version of ApplicationLauncher for ArcGeoSim
Browse files Browse the repository at this point in the history
  • Loading branch information
grospelliergilles committed Jan 17, 2025
1 parent c320416 commit 9277e63
Show file tree
Hide file tree
Showing 15 changed files with 2,953 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*~
obj
158 changes: 158 additions & 0 deletions csharp/ApplicationLauncher/Application.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
using System;
using System.Collections.Generic;
using System.IO;
using ApplicationLauncher;
using ApplicationConfiguration;

namespace Application
{
public interface ILoader {
ICollection<IAction> Load ();
bool EnableParallelMode { get; }
}

public enum ActionSequence { Continue, Stop, Loop, Abort };

public interface IAction
{
void Setup(ref Mono.Options.OptionSet opt_set);
bool Configure(); // return true on error while configuring
ActionSequence Run(string parameters);
string Name { get; }
}

public class Application : IAction
{
#region CONFIGURATIONS
private string APPLICATION_BINARY = null;
private ApplicationConfiguration.ApplicationConfiguration configuration;
#endregion

public Application(ApplicationConfiguration.ApplicationConfiguration configuration)
{
this.configuration = configuration;
// Disables that default variable (may be confusing for sequential run)
Environment.SetEnvironmentVariable ("ARCANE_PARALLEL_SERVICE", null);
}

public virtual void Setup(ref Mono.Options.OptionSet opt_set)
{
Env.CreateTag ("Run", "Default execution environment");
Env.CreateTag ("Simulation", "Simulation execution environment");
}

public virtual bool Configure()
{
bool has_error = false;
APPLICATION_BINARY = Path.Combine(Launcher.Options.binaryDir, configuration.Name + ".exe");
if (!File.Exists (APPLICATION_BINARY)) {
Logger.log(Logger.Channel.Error, "Cannot access Application executable in '{0}'", APPLICATION_BINARY);
has_error = true;
} else if (Launcher.Options.check_mode) {
Logger.log(Logger.Channel.Info,"Application found at location : " + APPLICATION_BINARY);
}

if (!ExecTools.isWindows () && Launcher.Options.libDir != null) {
string LD_LIBRARY_PATH = Launcher.Options.libDir;
Env.Export (Env.GetTag("Run"), "LD_LIBRARY_PATH", LD_LIBRARY_PATH);
}

if (configuration.ConfigLocation == ConfigLocation.ApplicationSide) {
string STDENV_PATH_SHR = Launcher.Options.binaryDir;
string STDENV_PATH_SHR_FILE = Path.Combine (STDENV_PATH_SHR, String.Format ("{0}.config", configuration.Name));
if (File.Exists (STDENV_PATH_SHR_FILE)) {
Env.Export (Env.GetTag ("Run"), "STDENV_PATH_SHR", STDENV_PATH_SHR);
} else if (Launcher.Options.check_mode) {
Logger.log (Logger.Channel.Error, "Standard config file '{0}' cannot be found", STDENV_PATH_SHR_FILE);
has_error = true;
} else {
Logger.log (Logger.Channel.Warning, "Standard config file '{0}' cannot be found", STDENV_PATH_SHR_FILE);
}
}

has_error |= configureVerboseRun ();
return has_error;
}

public virtual ActionSequence Run(string parameters)
{
Logger.log (Logger.Channel.Banner, "Simulation mode");
int? nproc = null;
if (configuration.EnableParallelMode) {
nproc = Launcher.Options.nb_proc;
} else {
if (Launcher.Options.nb_proc > 1)
throw new ApplicationLauncher.InternalException ("Illegal #proc on non-parallel application");
}
int res = runApplication (nproc, parameters, Env.GetTag ("Simulation"));

if (res != 0) {
Logger.log ("Simulation", "-------------------------------------------------------------");
Logger.log ("Simulation", "An errors occurs in simulation mode with : see log for details [{0}]", res);
throw new LauncherException ("An error occurs while running simulation");
}
return ActionSequence.Continue;
}

public string Name { get { return configuration.Name; } }

private bool configureVerboseRun()
{
if (Launcher.Options.verbose_run) {
Env.Export (Env.GetTag("Run"), "ARCANE_TRACE_TIMER", "TRUE");
} else {
Env.Export (Env.GetTag("Run"), "ARCANE_TRACE_TIMER", null);
}
return false;
}

public int runApplication(int? n, string arg, Env.Tag mainTag)
{
string cmd;
List<string> cmd_args = new List<string> ();

List<Env.Tag> tags = new List<Env.Tag> ();
tags.Add (mainTag);
tags.Add (Env.GetTag("Run"));

if (n != null) {
cmd = Launcher.Options.mpirun_path;
cmd_args.AddRange(Launcher.Options.mpirun_extra_options);
cmd_args.AddRange(ExecTools.toArgs( "-np", n ));
cmd_args.AddRange(ExecTools.toArgs( "-genv", "ARCANE_PARALLEL_SERVICE", "Mpi" ));
if (ExecTools.isWindows()) cmd_args.Add("-genvall");
cmd_args.Add(APPLICATION_BINARY);
cmd_args.Add (arg);
tags.Add (Env.GetTag("Mpi"));
} else {
cmd = APPLICATION_BINARY;
cmd_args.Add (arg);
tags.Add (Env.GetTag("Mpi"));
}

// Cleanup fatal file before running
foreach (FileInfo f in GetFatalFiles()) {
f.Delete ();
}

int res = ExecTools.ExecProcess (cmd, cmd_args.ToArray(), tags.ToArray());
/*
if (res == 0 && GetFatalFiles().Length > 0) {
// TODO: voir problème de fatal_6 en exécution parallèle
// fatal_6 en cas de STOP_FAILED (ex: erreur de validateurs même non fatal; voir src/ArcTem/ArcTemModule.cc)
logger.log(Logger.Channel.eError, "Fatal file detected : throws an error");
return -1;
} else {
return res;
}
*/
return res;
}

FileInfo[] GetFatalFiles() {
FileInfo[] fatal_files = new DirectoryInfo(Directory.GetCurrentDirectory()).GetFiles("fatal_*");
return fatal_files;
}
}
}

76 changes: 76 additions & 0 deletions csharp/ApplicationLauncher/ApplicationConfiguration.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------

//
//This source code was auto-generated by MonoXSD
//
namespace ApplicationConfiguration {


/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlRootAttribute("application", Namespace="", IsNullable=false)]
public partial class ApplicationConfiguration {

private string nameField;

private ConfigLocation configLocationField;

private bool enableParallelModeField;

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public string Name {
get {
return this.nameField;
}
set {
this.nameField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public ConfigLocation ConfigLocation {
get {
return this.configLocationField;
}
set {
this.configLocationField = value;
}
}

/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Form=System.Xml.Schema.XmlSchemaForm.Unqualified)]
public bool EnableParallelMode {
get {
return this.enableParallelModeField;
}
set {
this.enableParallelModeField = value;
}
}
}

/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "0.0.0.0")]
[System.SerializableAttribute()]
public enum ConfigLocation {

/// <remarks/>
ApplicationSide,

/// <remarks/>
Local,
}
}
27 changes: 27 additions & 0 deletions csharp/ApplicationLauncher/ApplicationConfiguration.xsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:ags="http://www.ifpen.fr/ArcGeoSim/Common.xsd"
elementFormDefault="unqualified">

<!-- Fichier à transformer en objet C# via la commande
/soft/irsrvsoft1/expl/Mono/Mono_3.2.8/bin/xsd ApplicationConfiguration.xsd /c /l:CS /n:Application
-->

<xs:simpleType name="ConfigLocation" final="restriction" >
<xs:restriction base="xs:string">
<xs:enumeration value="ApplicationSide" />
<xs:enumeration value="Local" />
</xs:restriction>
</xs:simpleType>

<xs:complexType name="ApplicationConfiguration">
<xs:sequence>
<xs:element name="Name" type="xs:string" />
<xs:element name="ConfigLocation" type="ConfigLocation" />
<xs:element name="EnableParallelMode" type="xs:boolean" />
</xs:sequence>
</xs:complexType>

<xs:element name="application" type="ApplicationConfiguration" />

</xs:schema>
14 changes: 14 additions & 0 deletions csharp/ApplicationLauncher/ApplicationLauncher.dotnet.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net6.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>disable</Nullable>
<Deterministic>True</Deterministic>
<GenerateAssemblyInfo>true</GenerateAssemblyInfo>
<SelfContained>true</SelfContained>
<PublishSingleFile>true</PublishSingleFile>
</PropertyGroup>

</Project>
62 changes: 62 additions & 0 deletions csharp/ApplicationLauncher/AssemblyResolver.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
using System;
using System.IO;
using System.Collections.Generic;
using System.Reflection;

namespace ApplicationLauncher
{
static class AssemblyResolver
{
public static void Initialize() {
Logger.log (Logger.Channel.DevDebug, "Initializing AssemblyResolver");
Assembly thisAssembly = Assembly.GetExecutingAssembly();
String thisPath = thisAssembly.Location;
String directory = Path.GetDirectoryName(thisPath);

AddDirectory (directory);

AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler( ResolveEventHandler );
}

static public void AddDirectory(string directory) {
if(!m_directories.Contains(directory))
m_directories.Add(directory);
}

private static Assembly ResolveEventHandler( Object sender, ResolveEventArgs args ){
Assembly newAssembly = null;
String newAssemblyName = null;

String[] onlyName = args.Name.Split(',');
if (onlyName.Length == 0)
return newAssembly;
else
newAssemblyName = onlyName [0];

try {
Assembly thisAssembly = Assembly.GetExecutingAssembly();
String thisPath = thisAssembly.Location;

foreach(String directory in m_directories)
{
String pathToManagedAssembly = Path.Combine(directory, onlyName[0] + ".dll");
if(File.Exists(pathToManagedAssembly)){
newAssembly = Assembly.LoadFile(pathToManagedAssembly);
break; // or continue if try a another path in m_directories list
}
}

if (newAssembly != null)
Logger.log (Logger.Channel.DevDebug, "Resolving assembly '{0}' with '{1}'", newAssemblyName, newAssembly.Location);
else
Logger.log (Logger.Channel.DevDebug, "Resolving assembly '{0}' failed", newAssemblyName);
} catch (Exception e) {
Logger.log(Logger.Channel.DevDebug, "Error while resolving assembly '{0}' : {1}", newAssemblyName, e.Message);
}
return newAssembly;
}

private static List<String> m_directories = new List<String>();
}
}

38 changes: 38 additions & 0 deletions csharp/ApplicationLauncher/ConfigurationReader.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using System;
using System.Text;
using System.Text.RegularExpressions;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using System.Xml.Schema;
using System.Xml.Serialization;
using System.Reflection;

namespace Application
{
public class ConfigurationReader
{
public static T Initialize<T> (Stream file)
where T : class, new()
{
string xsd_resource_name = "ApplicationLauncher.ApplicationConfiguration.xsd"; // with namespace
Assembly assembly = Assembly.GetExecutingAssembly ();

XmlReaderSettings settings = new XmlReaderSettings ();
using (Stream stream = assembly.GetManifestResourceStream(xsd_resource_name)) {
if (stream == null)
throw new ApplicationLauncher.InternalException (String.Format ("Cannot open resource '{0}'", xsd_resource_name));
XmlSchema schema = XmlSchema.Read (stream, null);
settings.Schemas.Add (schema);
}
settings.ValidationType = ValidationType.Schema;
settings.ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints | XmlSchemaValidationFlags.ReportValidationWarnings;

XmlSerializer serializer = new XmlSerializer (typeof(T));
using (XmlReader reader = XmlReader.Create(file, settings)) {
return serializer.Deserialize (reader) as T;
}
}
}
}

Loading

0 comments on commit 9277e63

Please sign in to comment.