Skip to content

Commit

Permalink
Merge pull request #23 from kleis-technology/feature/trusted-lib-ademe
Browse files Browse the repository at this point in the history
feature/trusted lib ademe
  • Loading branch information
pevab authored Nov 26, 2024
2 parents 3d99f2f + f3c2f4e commit b561460
Show file tree
Hide file tree
Showing 69 changed files with 2,053 additions and 1,690 deletions.
43 changes: 19 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -260,35 +260,30 @@ but nothing stops you from assessing as many virtual machines as you want.
The ambition of Cloud Assess is to offer a library of *transparent*,
*PCR-compliant* and *executable* LCA models in the sector of digital services.
More precisely, this work builds on the
existing [PCR](https://codde.fr/wp-content/uploads/2023/01/referentiel_rcp_datacenter_services_cloud.pdf)
for data center and cloud services.
The PCR defines 11 functional units, covering the hosting infrastructure (physical datacenter) up to
more abstract FUs, e.g., Software Services.
Cloud Assess aims at covering all functional units, but also FU that are not explicitly
covered by the PCR

| PCR No. | Functional Unit | Status |
|---------|-----------------------|-------------|
| 1 | Datacenter | in progress |
| 2 | Physical server | in progress |
| 3 | Storage | in progress |
| 4 | Network equipment | in progress |
| 5 | Computing resource | in progress |
| 6 | Virtual machine ||
| 7 | Database | in progress |
| 8 | Block storage | in progress |
| 9 | Platform as a Service | planned |
| 10 | Function as a Service | planned |
| 11 | Software as a Service | planned |
new PCR (to be published soon) for data center and cloud services.
The PCR defines 7 functional units, covering the hosting infrastructure (physical datacenter) up to
more abstract ones, e.g., virtual machines.
Cloud Assess aims at covering all functional units, but also FU that are not explicitly covered by the PCR

| PCR No. | Functional Unit | Model | API endpoint |
|---------|--------------------|-------|--------------|
| 1 | Datacenter | n/a | n/a |
| 2 | Physical server || planned |
| 3 | Storage || planned |
| 4 | Network equipment || planned |
| 5 | Computing resource || planned |
| 6 | Virtual machine |||
| 7 | Block storage || planned |

These models are specified under the folder `trusted_library`.

The library also contains intermediate/generic models, e.g.,

| Functional unit | Status |
|----------------------------|--------|
| Pool of servers ||
| Pool of network equipments ||
| Functional unit | Model |
|----------------------------|-------|
| Pool of servers ||
| Pool of storage equipments ||
| Pool of network equipments ||

which can be used for specific purposes, e.g., a mail service running on a dedicated infrastructure.

Expand Down
6 changes: 3 additions & 3 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ plugins {
}

group = "org.cloud_assess"
version = "1.7.3"
version = "1.7.4"

java {
sourceCompatibility = JavaVersion.VERSION_17
Expand All @@ -30,7 +30,7 @@ repositories {
}

dependencies {
val lcaacVersion = "1.7.3"
val lcaacVersion = "1.7.10"
implementation("ch.kleis.lcaac:core:$lcaacVersion")
implementation("ch.kleis.lcaac:grammar:$lcaacVersion")

Expand Down Expand Up @@ -62,7 +62,7 @@ tasks.withType<KotlinCompile> {
}

tasks.withType<Test> {
useJUnitPlatform() {
useJUnitPlatform {
excludeTags("Performance")
}
}
Expand Down
6 changes: 3 additions & 3 deletions openapi/api.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -192,13 +192,10 @@ components:
type: object
required:
- id
- service_level
- meta
properties:
id:
type: string
service_level:
$ref: '#/components/schemas/QuantityDimensionlessDto'
meta:
type: object
default: { }
Expand Down Expand Up @@ -233,6 +230,7 @@ components:
required:
- id
- pool_id
- quantity
- ram
- storage
- vcpu
Expand All @@ -242,6 +240,8 @@ components:
type: string
pool_id:
type: string
quantity:
$ref: '#/components/schemas/QuantityDimensionlessDto'
ram:
$ref: '#/components/schemas/QuantityMemoryDto'
storage:
Expand Down
12 changes: 12 additions & 0 deletions samples/virtual_machines.http
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ Content-Type: application/json
{
"id": "vm-01",
"pool_id": "client_vm",
"quantity": {
"amount": 1.0,
"unit": "u"
},
"ram": {
"amount": 4.0,
"unit": "GB"
Expand All @@ -30,6 +34,10 @@ Content-Type: application/json
{
"id": "vm-02",
"pool_id": "client_vm",
"quantity": {
"amount": 1.0,
"unit": "u"
},
"ram": {
"amount": 16.0,
"unit": "GB"
Expand All @@ -50,6 +58,10 @@ Content-Type: application/json
{
"id": "vm-03",
"pool_id": "client_vm",
"quantity": {
"amount": 1.0,
"unit": "u"
},
"ram": {
"amount": 8.0,
"unit": "GB"
Expand Down
6 changes: 2 additions & 4 deletions src/main/kotlin/org/cloud_assess/service/PoolService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,14 @@ class PoolService(
TimeUnitsDto.hour -> "${pools.period.amount} hour"
}
val cases = pools.pools.associate {
val serviceLevel = when (it.serviceLevel.unit) {
DimensionlessUnitsDto.u -> "${it.serviceLevel.amount} u"
}
// TODO: swagger: remove service level
val content = """
process __main__ {
products {
1 u __main__
}
inputs {
$period service from service(pool_id = "${it.id}", service_level = $serviceLevel)
$period service from service(id = "${it.id}")
}
}
""".trimIndent()
Expand Down
10 changes: 10 additions & 0 deletions src/main/kotlin/org/cloud_assess/service/VirtualMachineService.kt
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@ import ch.kleis.lcaac.core.lang.expression.*
import ch.kleis.lcaac.core.lang.register.DataKey
import ch.kleis.lcaac.core.lang.register.DataSourceRegister
import ch.kleis.lcaac.core.lang.value.DataValue
import ch.kleis.lcaac.core.lang.value.QuantityValue
import ch.kleis.lcaac.core.lang.value.RecordValue
import ch.kleis.lcaac.core.lang.value.UnitValue
import ch.kleis.lcaac.core.math.basic.BasicNumber
import ch.kleis.lcaac.core.math.basic.BasicOperations
import ch.kleis.lcaac.core.prelude.Prelude
import org.cloud_assess.dto.*
import org.cloud_assess.model.ResourceAnalysis
import org.springframework.beans.factory.annotation.Value
Expand Down Expand Up @@ -112,6 +115,7 @@ class VirtualMachineService(
"ram_size" to localEval(vm.ram.toDataExpression()),
"storage_size" to localEval(vm.storage.toDataExpression()),
"vcpu_size" to localEval(vm.vcpu.toDataExpression()),
"quantity" to localEval(vm.quantity.toDataExpression()),
)
)
}
Expand Down Expand Up @@ -144,4 +148,10 @@ class VirtualMachineService(
VCPUUnitsDto.vCPU -> EQuantityScale(BasicNumber(this.amount), EDataRef("vCPU"))
}
}

private fun QuantityDimensionlessDto.toDataExpression(): DataExpression<BasicNumber> {
return when(this.unit) {
DimensionlessUnitsDto.u -> EQuantityScale(BasicNumber(this.amount), EDataRef("u"))
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class CloudAssessApplicationTest(
val pools = PoolListDto(
period = QuantityTimeDto(1.0, TimeUnitsDto.hour),
pools = listOf(
DtoFixture.poolDto("client_vm", 1.0)
DtoFixture.poolDto("client_vm")
)
)

Expand All @@ -48,7 +48,7 @@ class CloudAssessApplicationTest(
val pool = actual[id]!!
assertThat(pool.period).isEqualTo(QuantityTimeDto(1.0, TimeUnitsDto.hour))
val gwp = pool.contribution(Indicator.GWP)
assertThat(gwp.amount.value).isCloseTo( 5.71403, Percentage.withPercentage(1e-3))
assertThat(gwp.amount.value).isCloseTo(7.5770786, Percentage.withPercentage(1e-3))
assertThat(gwp.unit).isEqualTo(
UnitValue<BasicNumber>(
UnitSymbol.of("kg CO2-Eq"),
Expand Down Expand Up @@ -78,7 +78,7 @@ class CloudAssessApplicationTest(
val vm = actual[id]!!
assertThat(vm.period).isEqualTo(QuantityTimeDto(1.0, TimeUnitsDto.hour))
val gwp = vm.contribution(Indicator.GWP)
assertThat(gwp.amount.value).isCloseTo(0.971400, Percentage.withPercentage(1e-3))
assertThat(gwp.amount.value).isCloseTo(2.458826278, Percentage.withPercentage(1e-3))
assertThat(gwp.unit).isEqualTo(
UnitValue<BasicNumber>(
UnitSymbol.of("kg CO2-Eq"),
Expand Down
15 changes: 9 additions & 6 deletions src/test/kotlin/org/cloud_assess/fixtures/DtoFixture.kt
Original file line number Diff line number Diff line change
Expand Up @@ -93,21 +93,16 @@ class DtoFixture {
return PoolListDto(
period = quantityHour(1.0),
pools = listOf(
poolDto("client_vm", 1.0),
poolDto("client_vm"),
)
)
}

fun poolDto(
id: String = "client_vm",
serviceLevel: Double = 1.0,
): PoolDto {
return PoolDto(
id = id,
serviceLevel = QuantityDimensionlessDto(
amount = serviceLevel,
unit = DimensionlessUnitsDto.u,
),
meta = mapOf(
"region" to "FR",
),
Expand All @@ -133,6 +128,7 @@ class DtoFixture {
return VirtualMachineDto(
id = id,
poolId = poolId,
quantity = quantityDimensionless(1.0),
ram = quantityMemory(ram),
storage = quantityMemory(storage),
vcpu = quantityVCPU(vcpu),
Expand All @@ -146,6 +142,13 @@ class DtoFixture {
return QuantityVCPUDto(amount, VCPUUnitsDto.vCPU)
}

private fun quantityDimensionless(amount: Double = 1.0): QuantityDimensionlessDto {
return QuantityDimensionlessDto(
amount,
DimensionlessUnitsDto.u,
)
}

private fun quantityMemory(amount: Double = 10.0): QuantityMemoryDto {
return QuantityMemoryDto(
amount,
Expand Down
4 changes: 4 additions & 0 deletions src/test/kotlin/org/cloud_assess/fixtures/QuantityFixture.kt
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,9 @@ class QuantityFixture {
BasicNumber(1.0),
UnitValue(UnitSymbol.of("kg"), 1.0, Dimension.of("mass"))
)
val oneUnit = QuantityValue(
BasicNumber(1.0),
UnitValue(UnitSymbol.of("u"), 1.0, Dimension.None)
)
}
}
4 changes: 4 additions & 0 deletions trusted_library/00-globals/globals.lca
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
variables {
timewindow = 1 hour
maintenance_intensity = 0 man * working_day / month
}
26 changes: 21 additions & 5 deletions trusted_library/units.lca → trusted_library/00-globals/units.lca
Original file line number Diff line number Diff line change
@@ -1,3 +1,23 @@
unit week {
symbol = "week"
alias_for = 7 day
}

unit working_day {
symbol = "working_day"
alias_for = 7 hour
}

unit man {
symbol = "man"
dimension = "man"
}

unit month {
symbol = "month"
alias_for = 30 day
}

unit kW {
symbol = "kW"
alias_for = 1000 W
Expand Down Expand Up @@ -27,12 +47,8 @@ unit KB {
alias_for = 1e-3 GB
}

unit core {
symbol = "core"
dimension = "core"
}

unit vCPU {
symbol = "vCPU"
dimension = "vCPU"
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
process mutualized_pool_fn {
labels {
phase = "embodied"
}
params {
dc_id = "dc-01"
lc_step = "manufacturing"
}

variables {
dt = 1 hour
mutualized_pool_id = "mutualized"
dc = lookup dc_inventory match ( id = dc_id )
internal_power = sum( server_inventory match ( pool_id = mutualized_pool_id, dc_id = dc_id ), quantity * power )
+ sum( network_inventory match ( pool_id = mutualized_pool_id, dc_id = dc_id ), quantity * power )
+ sum( storage_inventory match ( pool_id = mutualized_pool_id, dc_id = dc_id ), quantity * power )
available_power = ( dc.reserved_power / dc.power_usage_effectiveness ) - internal_power
}
products {
available_power * dt mutualized_pool
}
inputs {
dt mutualized_server_pool from mutualized_server_pool( dc_id = dc_id, lc_step = lc_step ) match ( phase = "embodied" )
dt mutualized_network_pool from mutualized_network_pool( dc_id = dc_id, lc_step = lc_step ) match ( phase = "embodied" )
dt mutualized_storage_pool from mutualized_storage_pool( dc_id = dc_id, lc_step = lc_step ) match ( phase = "embodied" )
}
}

process mutualized_pool_fn {
labels {
phase = "use"
}
params {
dc_id = "dc-01"
}

variables {
dt = 1 hour
internal_pool_id = "mutualized"
dc = lookup dc_inventory match ( id = dc_id )
internal_power = sum( server_inventory match ( pool_id = internal_pool_id, dc_id = dc_id ), quantity * power )
+ sum( network_inventory match ( pool_id = internal_pool_id, dc_id = dc_id ), quantity * power )
+ sum( storage_inventory match ( pool_id = internal_pool_id, dc_id = dc_id ), quantity * power )
available_power = ( dc.reserved_power / dc.power_usage_effectiveness ) - internal_power
}
products {
available_power * dt mutualized_pool
}
inputs {
dt mutualized_server_pool from mutualized_server_pool( dc_id = dc_id ) match ( phase = "use" )
dt mutualized_network_pool from mutualized_network_pool( dc_id = dc_id ) match ( phase = "use" )
dt mutualized_storage_pool from mutualized_storage_pool( dc_id = dc_id ) match ( phase = "use" )
}
}
Loading

0 comments on commit b561460

Please sign in to comment.