Skip to content

Commit

Permalink
TL: added webapp for FCF relaxation
Browse files Browse the repository at this point in the history
  • Loading branch information
tlunet committed Jul 18, 2023
1 parent cdce7f9 commit 38b7874
Show file tree
Hide file tree
Showing 6 changed files with 163 additions and 4 deletions.
4 changes: 2 additions & 2 deletions FCF.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,5 @@
**blockOps)
parareal_fcf.plotGraph(N=nBlocks, K=nBlocks, figSize=(6.4*2, 4.8*2))
# parareal_fcf.plotGraphForOneBlock(N=nBlocks, K=nBlocks, plotBlock=4, plotIter=2, figSize=(6.4*2, 4.8*2))
parareal_fcf.plotSchedule(N=nBlocks, K=nBlocks, nProc=nBlocks, schedulerType="BLOCK-BY-BLOCK")

fig = parareal_fcf.plotSchedule(N=nBlocks, K=nBlocks, nProc=nBlocks, schedulerType="BLOCK-BY-BLOCK")
fig.show()
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@ that uses the [blockops] code for specific application and experiments. Currentl
https://jupyterhub.mat.tu-harburg.de/blockops/, and here is the current list of WebApp :

- [Accuracy (and stability) of general time-discretization on the Complex Plane](./accuracy)
- [Automatic Generation of Parareal Task Scheduling using different strategies](./pararealSchedule)
- [Automatic Generation of Task Scheduling for Parareal](./pararealSchedule)
- [Automatic Generation of Task Scheduling for Parareal with Overlap (MGRIT-FCF)](./pararealFCFSchedule)

The WebApps are currently under development : current could be improved, and other WebApp could also be added,
see the [demo WebApp](./demo) for an example.
Expand Down
3 changes: 2 additions & 1 deletion scripts/07_pararealSpeedup.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@
"(F - G) u_{n}^k + G * u_{n}^{k+1}",
propagator="F", predictor="G", F=F, G=G, I=I, name='Parareal')

parareal.plotSchedule(N, K, nProc=N, schedulerType='LOWEST-COST-FIRST')
fig = parareal.plotSchedule(N, K, nProc=N, schedulerType='LOWEST-COST-FIRST')
fig.show()
15 changes: 15 additions & 0 deletions scripts/08_pararealFCFSpeedup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from blockops import BlockOperator, BlockIteration

G = BlockOperator('G', cost=0.1)
F = BlockOperator('F', cost=1)
N = 8
K = 3

blockOps = dict(F=F, G=G)

parareal_fcf = BlockIteration(
update="(F-G)*F*u_{n-1}^k + G*u_{n}^{k+1}",
predictor="G", propagator="F", **blockOps)
fig = parareal_fcf.plotSchedule(
N=N, K=K, nProc=N, schedulerType="BLOCK-BY-BLOCK")
fig.show()
3 changes: 3 additions & 0 deletions web_apps/pararealFCFSchedule.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
## Documentation

... incoming ...
139 changes: 139 additions & 0 deletions web_apps/pararealFCFSchedule.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
from typing import Any

from dynamic_site.app import App, ResponseStages
from dynamic_site.stage import parameters as par
import dynamic_site.stage.stages as stages

from blockops import BlockOperator, BlockIteration

# ===================
# Documentation Stage
# ===================

s1_docs = stages.DocsStage(
"Quick Documentation",
r"""
Consider the block update formula of Parareal with overlap
(MGRIT with FCF relaxation) :
$$
u^{k+1}_{n+1} = F \circ F(u^{k}_{n-1}) + G(u^{k+1}_n) - G \circ F(u^{k}_{n-1})
$$
Define the number of blocks $N$ (time-intervals), the number of iterations $K$
(eventually different for each block), and the cost of $F$
and $G$.
Then choose a scheduler type :
- BLOCK-BY-BLOCK : uses $N$ processors, where each processor is dedicated
to one time block
- LOWEST-COST-FIRST : uses $N$ processors, and compute first the tasks
with lower cost
- OPTIMAL : eventually use more than $N$ processors to minimize the
overall computation time
""",
)

# ==============
# Settings Stage
# ==============

SCHEDULERS = ['LOWEST-COST-FIRST', 'OPTIMAL', 'BLOCK-BY-BLOCK']

pararealSettings = [
par.StrictlyPositiveInteger(
unique_id="nBlocks", name="$N$",
placeholder="Number of Blocks",
doc="Strictly positive integer",
optional=False,
),
par.FloatList(
unique_id="nIter", name="$K$",
placeholder="Number of Iterations",
doc="Number of iteration for each block (1 or N values)",
optional=False,
),
par.Float(
unique_id='costF', name='Computation time for $F$',
placeholder='Floating point number',
doc='Computation time for the fine solver',
optional=False
),
par.Float(
unique_id='costG', name='Computation time for $G$',
placeholder='Floating point number',
doc='Computation time for the coarse solver',
optional=False
),
par.Enumeration(
unique_id='schedulerType', name='Scheduler Type',
placeholder='',
doc='Type of scheduler use for Parareal',
optional=False,
choices=SCHEDULERS,
value='BLOCK-BY-BLOCK'
),
]

s1_settings = stages.SettingsStage(
"pararealSettings", "Parareal Settings", pararealSettings, False
)


# ===========
# Plots Stage
# ===========

s1_plot = stages.PlotsStage("Parareal FCF Schedule", None)

# ====================================================
# Accuracy App
# ====================================================
class PararealSchedule(App):
def __init__(self) -> None:
super().__init__(title="Parareal FCF Schedule")

def compute(self, response_data: dict[str, Any] | None) -> ResponseStages:

# Create a response, where stages will be added to
r = ResponseStages()

# Initial request
r.add_docs_stage(s1_docs)
if not response_data:
r.add_settings_stage(s1_settings)
r.add_plot_stage(s1_plot)
return r

# Convert parameters to correct types
pararealSettings = s1_settings.convert_to_types(
response_data["pararealSettings"]
)
# Add the settings with the set values
r.add_settings_stage(
s1_settings.copy_from_response(response_data["pararealSettings"])
)

G = BlockOperator('G', cost=pararealSettings['costG'])
F = BlockOperator('F', cost=pararealSettings['costF'])
N = pararealSettings['nBlocks']
K = [int(k) for k in pararealSettings['nIter']]
K = K[0] if len(K) == 1 else K

schedulerType = pararealSettings['schedulerType']

pararealFCF = BlockIteration(
"(F - G)*F u_{n-1}^k + G u_{n}^{k+1}",
propagator="F", predictor="G", F=F, G=G, name='PararealFCF')

fig = pararealFCF.plotSchedule(N, K, nProc=N, schedulerType=schedulerType)

# === Response ===

plot_stage = s1_plot.copy()
plot_stage.plot = fig.to_json()
r.add_plot_stage(plot_stage)

return r


0 comments on commit 38b7874

Please sign in to comment.