Skip to content

Commit c593718

Browse files
authored
Merge pull request #23 from CosmologicalEmulators/develop
Develop
2 parents efb4f54 + eb7a8b4 commit c593718

File tree

7 files changed

+65
-29
lines changed

7 files changed

+65
-29
lines changed

Project.toml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "Capse"
22
uuid = "994f66c3-d2c7-4ba6-88fb-4a10f50800ba"
33
authors = ["marcobonici <bonici.marco@gmail.com>"]
4-
version = "0.2.3"
4+
version = "0.3.0"
55

66
[deps]
77
AbstractCosmologicalEmulators = "c83c1981-e5c4-4837-9eb8-c9b1572acfc6"
@@ -10,7 +10,7 @@ JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
1010
NPZ = "15e1cf62-19b3-5cfa-8e77-841668bca605"
1111

1212
[compat]
13-
AbstractCosmologicalEmulators = "0.3.3"
13+
AbstractCosmologicalEmulators = "0.4"
1414
Adapt = "3"
1515
JSON = "0.21"
1616
NPZ = "0.4"

docs/Project.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
44
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
55
NPZ = "15e1cf62-19b3-5cfa-8e77-841668bca605"
66
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
7+
SimpleChains = "de6bee2f-e2f4-4ec7-b6ed-219cc6f6e9e5"

docs/src/assets/postprocessing.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function postprocessing(input, output, Cℓemu)
2+
return output .* exp(input[1]-3.)
3+
end

docs/src/index.md

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ using JSON
77
using BenchmarkTools
88
using NPZ
99
using Capse
10+
using SimpleChains
11+
12+
mlpd = SimpleChain(
13+
static(6),
14+
TurboDense(tanh, 64),
15+
TurboDense(tanh, 64),
16+
TurboDense(tanh, 64),
17+
TurboDense(tanh, 64),
18+
TurboDense(tanh, 64),
19+
TurboDense(identity, 4999)
20+
)
21+
1022
default(palette = palette(:tab10))
1123
benchmark = BenchmarkTools.load("./assets/capse_benchmark.json")
1224
path_json = "./assets/nn_setup.json"
@@ -15,15 +27,16 @@ weights = rand(500000)
1527
ℓgrid = ones(2000)
1628
InMinMax_array = zeros(2,2000)
1729
OutMinMax_array = zeros(2,2000)
18-
npzwrite("./assets/l.npy", ℓgrid)
19-
npzwrite("./assets/weights.npy", weights)
20-
npzwrite("./assets/inminmax.npy", InMinMax_array)
21-
npzwrite("./assets/outminmax.npy", OutMinMax_array)
22-
weights_folder = "./assets/"
23-
Cℓ_emu = Capse.load_emulator(weights_folder)
30+
nn_setup = JSON.parsefile(path_json)
31+
emu = Capse.SimpleChainsEmulator(Architecture = mlpd, Weights = weights,
32+
Description = nn_setup)
33+
postprocessing(input, output, Cℓemu) = output .* exp(input[1]-3.)
34+
Cℓ_emu = Capse.CℓEmulator(TrainedEmulator = emu, ℓgrid=ℓgrid, InMinMax = InMinMax_array,
35+
OutMinMax = OutMinMax_array,
36+
Postprocessing = postprocessing)
2437
```
2538

26-
`Capse.jl` is a Julia package designed to emulate the computation of the CMB Angular Power Spectrum, with a speedup of several orders of magnitude.
39+
`Capse.jl` is a Julia package designed to emulate the computation of the CMB Angular Power Spectrum, with a speedup of several orders of magnitude compared to standard codes.
2740

2841
## Installation
2942

@@ -40,7 +53,7 @@ In order to be able to use `Capse.jl`, there two major steps that need to be per
4053
- Instantiating the emulators, e.g. initializing the Neural Network, its weight and biases and the quantities employed in pre and post-processing
4154
- Use the instantiated emulators to retrieve the spectra
4255

43-
In the reminder of this section we are showing how this can be done.
56+
In the reminder of this section we are showing how to do this.
4457

4558
### Instantiation
4659

@@ -52,10 +65,10 @@ Cℓ_emu = Capse.load_emulator(weights_folder);
5265

5366
where `weights_folder` is the path to the folder containing the files required to build up the network. Some of the trained emulators can be found on [Zenodo](https://zenodo.org/record/8187935) and we plan to release more of them there in the future.
5467

55-
It is possible to pass an additional argument to the previous function, which is used to choose between the two NN backed now available:
68+
It is possible to pass an additional argument to the previous function, which is used to choose between the two NN backend now available:
5669

5770
- [SimpleChains](https://github.com/PumasAI/SimpleChains.jl), which is taylored for small NN running on a CPU
58-
- [Lux](https://github.com/LuxDL/Lux.jl), which can run on a GPU
71+
- [Lux](https://github.com/LuxDL/Lux.jl), which can run both on CPUs and GPUs
5972

6073
`SimpleChains.jl` is faster expecially for small NN on the CPU. If you wanna use something running on a GPU, you should use `Lux.jl`, which can be done adding an additional argument to the `load_emulator` function, `Capse.LuxEmulator`
6174

@@ -69,17 +82,20 @@ Each trained emulator should be shipped with a description within the JSON file.
6982
Capse.get_emulator_description(Cℓ_emu)
7083
```
7184

72-
After loading a trained emulator, feed it some input parameters `x` in order to get the emulated $C_\ell$'s
85+
!!! warning
86+
87+
Cosmological parameters must be fed to `Capse.jl` with **arrays**. It is the user
88+
responsability to check the right ordering, by reading the output of the
89+
`get_emulator_description` method.
90+
91+
After loading a trained emulator, feed it some input parameters `x` in order to get the
92+
emulated $C_\ell$'s
7393

7494
```julia
7595
x = rand(6) # generate some random input
7696
Capse.get_Cℓ(x, Cℓ_emu) #compute the Cℓ's
7797
```
7898

79-
!!! warning
80-
81-
In this moment the API is **not** stable: we need to pass the input cosmological parameters in an hardcoded way. We are working to add a more stable and flexible API.
82-
8399
Using `SimpleChains.jl`, we obtain a mean execution time of 45 microseconds
84100

85101
```@example tutorial
@@ -94,24 +110,26 @@ benchmark[1]["Capse"]["Lux"] # hide
94110

95111
`SimpleChains.jl` is about 2 times faster than `Lux.jl` and they give the same result up to floating point precision.
96112

97-
This benchmarks have been performed locally, with a 12th Gen Intel® Core™ i7-1260P.
113+
These benchmarks have been performed locally, with a 12th Gen Intel® Core™ i7-1260P.
98114

99115
Considering that a high-precision settings calculation performed with [`CAMB`](https://github.com/cmbant/CAMB) on the same machine requires around 60 seconds, `Capse.jl` is 5-6 order of magnitudes faster.
100116

101117
### Authors
102118

103-
- Marco Bonici, INAF - Institute of Space Astrophysics and Cosmic Physics (IASF), Milano
119+
- Marco Bonici, PostDoctoral researcher at Waterloo Center for Astrophysics
104120
- Federico Bianchini, PostDoctoral researcher at Stanford
105121
- Jaime Ruiz-Zapatero, PhD Student at Oxford
122+
- Marius Millea, Researcher at UC Davis and Berkeley Center for Cosmological Physics
106123

107124
## Contributing
108125

109-
Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.
126+
Pull requests are welcome. For major changes, please open an issue first to discuss what you
127+
would like to change.
110128

111129
Please make sure to update tests as appropriate.
112130

113131
### License
114132

115133
`Capse.jl` is licensed under the MIT "Expat" license; see
116-
[LICENSE](https://github.com/CosmologicalEmulators/Effort.jl/blob/main/LICENSE) for
117-
the full license text.
134+
[LICENSE](https://github.com/CosmologicalEmulators/Effort.jl/blob/main/LICENSE) for the full
135+
license text.

src/Capse.jl

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,13 +24,16 @@ It contains:
2424
2525
- `InMinMax::AbstractMatrix`, the `Matrix` used for the MinMax normalization of the input features
2626
27-
- O`utMinMax::AbstractMatrix`, the `Matrix` used for the MinMax normalization of the output features
27+
- `OutMinMax::AbstractMatrix`, the `Matrix` used for the MinMax normalization of the output features
28+
29+
- `Postprocessing::Function`, the `Function` used for the postprocessing of the NN output
2830
"""
2931
@kwdef mutable struct CℓEmulator <: AbstractCℓEmulators
3032
TrainedEmulator::AbstractTrainedEmulators
3133
ℓgrid::AbstractVector
3234
InMinMax::AbstractMatrix
3335
OutMinMax::AbstractMatrix
36+
Postprocessing::Function
3437
end
3538

3639
Adapt.@adapt_structure CℓEmulator
@@ -45,7 +48,7 @@ function get_Cℓ(input_params, Cℓemu::AbstractCℓEmulators)
4548
maximin_input!(input, Cℓemu.InMinMax)
4649
output = Array(run_emulator(input, Cℓemu.TrainedEmulator))
4750
inv_maximin_output!(output, Cℓemu.OutMinMax)
48-
return output .* exp(input_params[1]-3.)
51+
return Cℓemu.Postprocessing(input_params, output, Cℓemu)
4952
end
5053

5154
"""
@@ -73,19 +76,25 @@ The following keyword arguments are used to specify the name of the files used t
7376
- `inminmax_file`, default `inminmax.npy`
7477
- `outminmax_file`, default `outminmax.npy`
7578
- `nn_setup_file`, default `nn_setup.json`
76-
If the corresponding file in the folder you are trying to load have different names, just change the default values.
79+
- `postprocessing_file`, default `postprocessing.jl`
80+
If the corresponding file in the folder you are trying to load have different names,
81+
change the default values accordingly.
7782
"""
7883
function load_emulator(path::String, emu = SimpleChainsEmulator,
7984
ℓ_file = "l.npy", weights_file = "weights.npy", inminmax_file = "inminmax.npy",
80-
outminmax_file = "outminmax.npy", nn_setup_file = "nn_setup.json")
85+
outminmax_file = "outminmax.npy", nn_setup_file = "nn_setup.json",
86+
postprocessing_file = "postprocessing.jl")
8187
NN_dict = parsefile(path*nn_setup_file)
8288
= npzread(path*ℓ_file)
89+
include(path*postprocessing_file)
90+
#we assume there is a postprocessing() function in the postprocessing_file
8391

8492
weights = npzread(path*weights_file)
8593
trained_emu = Capse.init_emulator(NN_dict, weights, emu)
8694
Cℓ_emu = Capse.CℓEmulator(TrainedEmulator = trained_emu, ℓgrid = ℓ,
8795
InMinMax = npzread(path*inminmax_file),
88-
OutMinMax = npzread(path*outminmax_file))
96+
OutMinMax = npzread(path*outminmax_file),
97+
Postprocessing = postprocessing)
8998
return Cℓ_emu
9099
end
91100

test/emu/postprocessing.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
function postprocessing(input, output, Cℓemu)
2+
return output .* exp(input[1]-3.)
3+
end

test/runtests.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@ npzwrite("emu/inminmax.npy", inminmax)
2424
npzwrite("emu/outminmax.npy", outminmax)
2525
emu = Capse.SimpleChainsEmulator(Architecture = mlpd, Weights = weights)
2626

27+
postprocessing(input, output, Cℓemu) = output .* exp(input[1]-3.)
28+
2729
capse_emu = Capse.CℓEmulator(TrainedEmulator = emu, ℓgrid=ℓ_test, InMinMax = inminmax,
28-
OutMinMax = outminmax)
30+
OutMinMax = outminmax, Postprocessing = postprocessing)
2931
capse_loaded_emu = Capse.load_emulator("emu/")
3032

3133
@testset "Capse tests" begin
@@ -35,6 +37,6 @@ capse_loaded_emu = Capse.load_emulator("emu/")
3537
output_vec = Capse.get_Cℓ(cosmo_vec, capse_emu)
3638
@test isapprox(output_vec[:,1], output)
3739
@test ℓ_test == Capse.get_ℓgrid(capse_emu)
38-
@test_logs (:warn, "We do not know which parameters were included in the emulators training space. Use this trained emulator with caution!") Capse.get_emulator_description(capse_emu)
40+
@test_logs (:warn, "No emulator description present!") Capse.get_emulator_description(capse_emu)
3941
@test Capse.get_Cℓ(cosmo_vec, capse_emu) == Capse.get_Cℓ(cosmo_vec, capse_loaded_emu)
4042
end

0 commit comments

Comments
 (0)