Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
3c26199
starting import launcher handling
jafranc Oct 30, 2025
abfd58f
starting import launcher handling
jafranc Oct 30, 2025
99a2176
Merge remote-tracking branch 'origin/main' into jafranc/feat/trame-HP…
jafranc Nov 14, 2025
2d1c395
some more imports
jafranc Nov 17, 2025
46899b4
wip
jafranc Nov 18, 2025
e9dd40d
wip
jafranc Nov 19, 2025
218c735
wip
jafranc Nov 19, 2025
8a361d2
wip
jafranc Nov 19, 2025
cad9c39
wip
jafranc Nov 20, 2025
84f4452
start login backend
jafranc Nov 20, 2025
ce820e7
ssh login
jafranc Nov 21, 2025
727c927
Unlock runner
jafranc Nov 21, 2025
3dc8a83
wip
jafranc Nov 21, 2025
077e6fa
full PoC
jafranc Nov 21, 2025
19c04e3
wip
jafranc Nov 22, 2025
3eaabe9
authorship
jafranc Nov 25, 2025
d54f8b3
change host
jafranc Nov 27, 2025
c1a8395
wip
jafranc Nov 28, 2025
8596472
update versions f/ VFileUpload
jafranc Nov 28, 2025
db83e7a
another view
jafranc Dec 1, 2025
21b4492
new list update
jafranc Dec 1, 2025
6c50a55
loading files complete
jafranc Dec 2, 2025
4535890
first working v
jafranc Dec 2, 2025
46a328d
Merge branch 'jafranc/feat/trame-HPC-launcher' of https://github.com/…
jafranc Dec 2, 2025
0c437b0
start status
jafranc Dec 2, 2025
81c1fc5
nicer
jafranc Dec 2, 2025
6405533
job status track
jafranc Dec 2, 2025
c0a5364
kill jobs enable
jafranc Dec 3, 2025
4195ef8
working w/o copyback
jafranc Dec 3, 2025
8c04e46
regexp working
jafranc Dec 3, 2025
485446c
less cumbersome
jafranc Dec 3, 2025
51f112f
first attempt at copy back
jafranc Dec 3, 2025
7c43b0e
last details
jafranc Dec 3, 2025
1b01967
update regex
jafranc Dec 4, 2025
e2dca24
fixed comment section
jafranc Dec 4, 2025
6e3dfc4
start simulation progress
jafranc Dec 4, 2025
f3acd23
notes and cleanup
jafranc Dec 8, 2025
6510a41
alternate strat copy back
jafranc Dec 8, 2025
06c5fe9
yapf
jafranc Dec 10, 2025
66368fc
discard sim_status_view
jafranc Dec 10, 2025
30f67fb
import error
jafranc Dec 11, 2025
495070e
spliting up big block
jafranc Dec 16, 2025
4d705bf
continuig
jafranc Dec 17, 2025
c14d425
wip
jafranc Dec 24, 2025
80ebd8f
refactor cluster entries
jafranc Dec 29, 2025
5d88f14
correct update
jafranc Dec 29, 2025
4fe819b
wip
jafranc Dec 29, 2025
b85c76a
some fixes
jafranc Dec 29, 2025
b1ef3df
completion bars
jafranc Dec 30, 2025
1dd6f1b
fast clean up
jafranc Dec 30, 2025
b02fa3d
update
jafranc Dec 30, 2025
a3ae2fc
Headers and some typing
jafranc Dec 30, 2025
8108151
clean up and typing
jafranc Dec 30, 2025
0e62301
some typing
jafranc Dec 30, 2025
de77419
adjust install and pathing
jafranc Jan 6, 2026
7a5001d
Merge commit '168105c52cb1f313ebdcebc9050a480a8c94434d' into jafranc/…
jafranc Jan 6, 2026
f5f9a6c
sd works for external mesh
jafranc Jan 7, 2026
89273f0
simpler
jafranc Jan 7, 2026
50a8c10
with internal mesh too
jafranc Jan 7, 2026
bb2d3f8
beautify
jafranc Jan 7, 2026
d5bc8e4
init paths before copy
jafranc Jan 7, 2026
9a91327
Add .geos to file type filter in simulation view
jafranc Jan 8, 2026
7405c36
env and assets loading logique
jafranc Jan 8, 2026
a86428c
small fix
jafranc Jan 8, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/typing-check.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
# working-directory: ./${{ matrix.package-name }}
run: |
python -m pip install --upgrade pip
python -m pip install mypy ruff types-PyYAML types-pytz
python -m pip install mypy ruff types-PyYAML types-paramiko types-pytz

- name: Typing check with mypy
# working-directory: ./${{ matrix.package-name }}
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ MANIFEST
*.manifest
*.spec

#env
.env

# Installer logs
pip-log.txt
pip-delete-this-directory.txt
Expand Down
16 changes: 15 additions & 1 deletion geos-trame/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,21 @@ Build and install the Vue components
cd vue-components
npm i
npm run build
cd -
cd ..

then configure the .env

sh configure.sh

this will generate a `dotenv` environement file defining useful path to trame,

.. code-block:: console

cat .env
TEMPLATE_DIR=/path/to/geosPythonPackages/geos-trame/src/geos/trame/io/jinja_t
ASSETS_DIR=/path/to/geosPythonPackages/geos-trame/src/geos/trame/assets

those will have lower precedence than local environement variables if defined

Install the application

Expand Down
4 changes: 4 additions & 0 deletions geos-trame/configure.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh

echo "TEMPLATE_DIR=${PWD}/src/geos/trame/app/io/jinja_t/" >> ${PWD}/src/geos/trame/assets/.env
echo "ASSETS_DIR=${PWD}/src/geos/trame/assets/" >> ${PWD}/src/geos/trame/assets/.env
13 changes: 7 additions & 6 deletions geos-trame/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,19 @@ keywords = [
]

dependencies = [
"typing-extensions==4.12.2",
"trame==3.6.5",
"trame-vuetify==2.7.1",
"trame-vuetify==3.1.0",
"trame-code==1.0.1",
"trame-server==3.2.3",
"trame-client==3.5.0",
"trame-client==3.11.2",
"trame-simput==2.4.3",
"trame-vtk>=2.8.14",
"trame-vtk==2.10.0",
"matplotlib==3.9.4",
"trame-matplotlib==2.0.3",
"trame-components==2.4.2",
"python-dotenv>=1.2.1",
"mpld3<0.5.11",
"paramiko==4.0.0",
"xsdata==24.5",
"xsdata-pydantic[lxml]==24.5",
"pyvista==0.45.2",
Expand All @@ -50,7 +51,7 @@ dependencies = [
"funcy==2.0",
"pytz==2025.2",
"typing_inspect==0.9.0",
"typing_extensions>=4.12",
"typing_extensions>=4.15.0",
"PyYAML",
]

Expand Down Expand Up @@ -92,7 +93,7 @@ include-package-data = true
# include = ['geos-trame*']

[tool.setuptools.package-data]
"*" = ["*.js", "*.css"]
"*" = ["*.js", "*.css","assets/*","*.jinja","*.json",".env"]

[tool.pytest.ini_options]
addopts = [
Expand Down
42 changes: 23 additions & 19 deletions geos-trame/src/geos/trame/app/core.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright 2023-2024 TotalEnergies.
# SPDX-FileContributor: Lionel Untereiner, Jacques Franc

# ignore context collapsing as it is clearer this way
# ruff: noqa: SIM117
from trame.ui.vuetify3 import VAppLayout
from trame.decorators import TrameApp
from trame.widgets import html, simput
Expand All @@ -24,6 +25,9 @@
from geos.trame.app.ui.viewer.viewer import DeckViewer
from geos.trame.app.components.alertHandler import AlertHandler

from geos.trame.app.io.simulation import Simulation
from geos.trame.app.ui.simulation_view import define_simulation_view

import sys


Expand All @@ -38,10 +42,12 @@ def __init__( self, server: Server, file_name: str ) -> None:
self.deckEditor: DeckEditor | None = None
self.timelineEditor: TimelineEditor | None = None
self.deckInspector: DeckInspector | None = None
self.simulationLauncher: Simulation | None = None
self.server = server
server.enable_module( module )

self.state.input_file = file_name
self.state.user_id = None

# TODO handle hot_reload

Expand All @@ -67,6 +73,9 @@ def __init__( self, server: Server, file_name: str ) -> None:
self.region_viewer = RegionViewer()
self.well_viewer = WellViewer( 5, 5 )

######## Simulation runner
self.simulation = Simulation( server=server )

# Data loader
self.data_loader = DataLoader( self.tree, self.region_viewer, self.well_viewer, trame_server=server )

Expand Down Expand Up @@ -177,24 +186,6 @@ def build_ui( self ) -> None:
):
vuetify.VIcon( "mdi-content-save-outline" )

with html.Div(
style=
"height: 100%; width: 300px; display: flex; align-items: center; justify-content: space-between;",
v_if=( "tab_idx == 1", ),
):
vuetify.VBtn(
"Run",
style="z-index: 1;",
)
vuetify.VBtn(
"Kill",
style="z-index: 1;",
)
vuetify.VBtn(
"Clear",
style="z-index: 1;",
)

# input file editor
with vuetify.VCol( v_show=( "tab_idx == 0", ), classes="flex-grow-1 pa-0 ma-0" ):
if self.tree.input_file is not None:
Expand All @@ -208,3 +199,16 @@ def build_ui( self ) -> None:
"The file " + self.state.input_file + " cannot be parsed.",
file=sys.stderr,
)

with vuetify.VCol( v_show=( "tab_idx == 1" ), classes="flex-grow-1 pa-0 ma-0" ):
if self.simulation is not None:
define_simulation_view( self.server )
else:
self.ctrl.on_add_error(
"Error",
"The execution context " + self.state.exec_context + " is not consistent.",
)
print(
"The execution context " + self.state.exec_context + " is not consistent.",
file=sys.stderr,
)
97 changes: 97 additions & 0 deletions geos-trame/src/geos/trame/app/io/hpc_tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
from geos.trame.app.io.ssh_tools import SimulationConstant


class SuggestDecomposition:

def __init__( self, selected_cluster: SimulationConstant, n_unknowns: int, job_type: str = 'cpu' ) -> None:
"""Initialize the decomposition hinter for HPC."""
self.selected_cluster: SimulationConstant = selected_cluster
self.n_unknowns: int = n_unknowns
self.job_type: str = job_type #TODO should be an enum
self.sd: list[ dict ] = []

@staticmethod
def compute( n_unknowns: int,
memory_per_unknown_bytes: int,
node_memory_gb: int,
cores_per_node: int,
min_unknowns_per_rank: int = 10000,
strong_scaling: bool = True ) -> list[ dict ]:
"""Suggests node/rank distribution for a cluster computation.

Parameters:
- n_unknowns: total number of unknowns
- memory_per_unknown_bytes: estimated memory per unknown
- node_memory_gb: available memory per node
- cores_per_node: cores available per node
- min_unknowns_per_rank: minimum for efficiency
- strong_scaling: True if problem size is fixed

Note:
- 10,000-100,000 unknowns per rank is often a sweet spot for many PDE solvers
- Use power-of-2 decompositions when possible (helps with communication patterns)
- For 3D problems, try to maintain cubic subdomains (minimizes surface-to-volume ratio, reducing communication)
- Don't oversubscribe: avoid using more ranks than provide parallel efficiency

"""
# Memory constraint
node_memory_bytes = node_memory_gb * 1e9
max_unknowns_per_node = int( 0.8 * node_memory_bytes / memory_per_unknown_bytes )

# Compute minimum nodes needed
min_nodes = max( 1, ( n_unknowns + max_unknowns_per_node - 1 ) // max_unknowns_per_node )

# Determine ranks per node
unknowns_per_node = n_unknowns // min_nodes
unknowns_per_rank = max( min_unknowns_per_rank, unknowns_per_node // cores_per_node )

# Calculate total ranks needed
n_ranks = max( 1, n_unknowns // unknowns_per_rank )

# Distribute across nodes
ranks_per_node = min( cores_per_node, ( n_ranks + min_nodes - 1 ) // min_nodes )
n_nodes = ( n_ranks + ranks_per_node - 1 ) // ranks_per_node

return [
{
'id':1,
'nodes': n_nodes,
'ranks_per_node': ranks_per_node,
'total_ranks': n_nodes * ranks_per_node,
'unknowns_per_rank': n_unknowns // ( n_nodes * ranks_per_node )
},
{
'id':2,
'nodes': n_nodes * 2,
'ranks_per_node': ranks_per_node // 2,
'total_ranks': n_nodes * ranks_per_node,
'unknowns_per_rank': n_unknowns // ( n_nodes * ranks_per_node )
},
]

def get_sd( self ) -> list[ dict ]:
"""Get the suggested decomposition popoulated."""
if self.job_type == 'cpu' and self.selected_cluster: #make it an enum
self.sd = SuggestDecomposition.compute( self.n_unknowns, 64, self.selected_cluster.mem_per_node,
self.selected_cluster.cores_per_node )
self.sd = [{**item,'label': f"{self.selected_cluster.name} : {item['nodes']} x {item['ranks_per_node']}"} for item in self.sd ]
else:
self.sd = [
{
'id': -1,
'label':'No: 0x0',
'nodes': 0,
'ranks_per_node': 0,
'total_ranks': 0,
'unknowns_per_rank': 0
},
]
# elif job_type == 'gpu':
# selected_cluster['n_nodes']*selected_cluster['gpu']['per_node']

return self.sd

# def to_list( self ) -> list[ str ]:
# """Pretty printer to list of string for display in UI."""
# sd = self.get_sd()
# return [ f"{self.selected_cluster.name} : {sd_item['nodes']} x {sd_item['ranks_per_node']}" for sd_item in sd ]
15 changes: 15 additions & 0 deletions geos-trame/src/geos/trame/app/io/jinja_t/local_copyback.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
#SBATCH --job-name="{{ job_name }}"
#SBATCH --ntasks={{ ntasks }}
#SBATCH --partition={{ partition }}
#SBATCH --comment={{ comment_gr }}
#SBACTH --account={{ account }}
#SBATCH --nodes={{ nodes }}
#SBATCH --time={{ time | default('00:10:00') }}
#SBATCH --mem={{ mem }}
#SBATCH --output=job_GEOS_%j.out
#SBATCH --error=job_GEOS_%j.err
#SBATCH --dependency=afterok:{{ dep_job_id }}

srun tar cfz {{ dep_job_id }}.tgz Outputs_{{ dep_job_id }}/ log_{{ dep_job_id }}.out
srun mkdir -p {{ target_dl_path }} && mv -v {{ dep_job_id }}.tgz {{ target_dl_path }}
27 changes: 27 additions & 0 deletions geos-trame/src/geos/trame/app/io/jinja_t/local_slurm.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/sh
#SBATCH --job-name="{{ job_name }}"
#SBATCH --ntasks={{ ntasks }}
#SBATCH --partition={{ partition }}
#SBATCH --comment={{ comment_gr }}
#SBACTH --account={{ account }}
#SBATCH --nodes={{ nodes }}
#SBATCH --time={{ time | default('00:10:00') }}
#SBATCH --mem={{ mem }}
#SBATCH --output=job_GEOS_%j.out
#SBATCH --error=job_GEOS_%j.err

ulimit -s unlimited
ulimit -c unlimited

module purge
module use {{ geos_module }}
module load {{ geos_load_list }}

export HDF5_USE_FILE_LOCKING=FALSE
export OMP_NUM_THREADS=1
export EXEC={{ geos_path }}

srun --hint=nomultithread \
-n {{ ntasks }} ${EXEC} \
-o Outputs_${SLURM_JOBID} \
-i {{ input_file | default('geosDeck.xml') }} | tee Outputs_${SLURM_JOBID}/log_${SLURM_JOBID}.out
15 changes: 15 additions & 0 deletions geos-trame/src/geos/trame/app/io/jinja_t/p4_copyback.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
#SBATCH --job-name="{{ job_name }}"
#SBATCH --ntasks={{ ntasks }}
#SBATCH --partition={{ partition }}
#SBATCH --comment={{ comment_gr }}
#SBACTH --account={{ account }}
#SBATCH --nodes={{ nodes }}
#SBATCH --time={{ time | default('00:10:00') }}
#SBATCH --mem={{ mem }}
#SBATCH --output=job_GEOS_%j.out
#SBATCH --err=job_GEOS_%j.err
#SBATCH --dependency=afterok:{{ dep_job_id }}

srun tar cfz {{ dep_job_id }}.tgz Outputs_{{ dep_job_id }}/ log_{{ dep_job_id }}.out
srun mkdir -p {{ target_dl_path }} && mv -v {{ dep_job_id }}.tgz {{ target_dl_path }}
27 changes: 27 additions & 0 deletions geos-trame/src/geos/trame/app/io/jinja_t/p4_slurm.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#!/bin/sh
#SBATCH --job-name="{{ job_name }}"
#SBATCH --ntasks={{ ntasks }}
#SBATCH --partition={{ partition }}
#SBATCH --comment={{ comment_gr }}
#SBACTH --account={{ account }}
#SBATCH --nodes={{ nodes }}
#SBATCH --time={{ time | default('00:10:00') }}
#SBATCH --mem={{ mem }}
#SBATCH --output=job_GEOS_%j.out
#SBATCH --error=job_GEOS_%j.err

ulimit -s unlimited
ulimit -c unlimited

module purge
module use {{ geos_module }}
module load {{ geos_load_list }}

export HDF5_USE_FILE_LOCKING=FALSE
export OMP_NUM_THREADS=1
export EXEC={{ geos_path }}

srun --mpi=pmix_v3 --hint=nomultithread \
-n {{ ntasks }} ${EXEC} \
-o Outputs_${SLURM_JOBID} \
-i {{ input_file | default('geosDeck.xml') }} | tee log_${SLURM_JOBID}.out
15 changes: 15 additions & 0 deletions geos-trame/src/geos/trame/app/io/jinja_t/pine_copyback.jinja
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#!/bin/sh
#SBATCH --job-name="{{ job_name }}"
#SBATCH --ntasks={{ ntasks }}
#SBATCH --partition={{ partition }}
#SBATCH --comment={{ comment_gr }}
#SBACTH --account={{ account }}
#SBATCH --nodes={{ nodes }}
#SBATCH --time={{ time | default('00:10:00') }}
#SBATCH --mem={{ mem }}
#SBATCH --output=job_GEOS_%j.out
#SBATCH --error=job_GEOS_%j.err
#SBATCH --dependency=afterok:{{ dep_job_id }}

srun tar cfz {{ dep_job_id }}.tgz Outputs_{{ dep_job_id }}/ log_{{ dep_job_id }}.out
srun mkdir -p {{ target_dl_path }} && mv -v {{ dep_job_id }}.tgz {{ target_dl_path }}
Loading
Loading