Skip to content

Commit 6b832b2

Browse files
GCI108 PreferAppendLeft fix: change rule number (97->108), resolve conflicts
Co-authored-by: DataLabGroupe-CreditAgricole <[email protected]>
2 parents 64ab276 + 0765859 commit 6b832b2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+1185
-89
lines changed

CHANGELOG.md

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,37 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99

1010
### Added
1111

12-
- Add rule GCI 97 Prefer Append Left
12+
- [#381](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/381) Add rule GCI 108 Prefer Append Left
1313
- [#400](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/400) Add rule GCI535 - Prefer usage of Intl.NumberFormat
1414

1515
### Changed
1616

1717
### Deleted
1818

19+
## [2.4.0] - 2025-07-20
20+
21+
### Added
22+
23+
- [#390](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/390) Added rule GCI106 : Detect scalar sqrt usage in loops and suggest vectorized alternatives
24+
- [#389](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/389) Add rule GCI105, Add a rule on Python String Concatenation
25+
- [#388](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/388) Added rule GCI104 on Torch Tensor types
26+
- [#387](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/387) Add rule GCI103, add specifications for a new rule on iteration method for dict in Python
27+
- [#386](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/386) Add rule GCI102, recommending the use of pinned memory for the dataloader when transferring data from the CPU to the GPU.
28+
- [#385](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/385) Add rule GCI101, Added documentation for the rule : disables bias in convolutional layers preceding Batch Normalization.
29+
- [#384](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/384) Add specifications for rule GCI100, this rule is specific to Python because it's based on the `PyTorch` library, a library used for Deep Learning.
30+
- [#379](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/379) Add rule GCI99 Avoid CSV Format, this rule is designed for Python but it can be implemented in other languages. The rule suggests using more efficient formats like Feather or Parquet instead of CSV.
31+
- [#401](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/401) Add rule GCI98 for Java. Don't catch RuntimeException. They represent a problem in the program that should be fixed, not handled
32+
33+
## [2.3.0] - 2025-07-08
34+
35+
### Added
36+
37+
- [#400](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/400) Add rule GCI535 - Prefer usage of Intl.NumberFormat
38+
- [#382](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/382) Add specifications for rule GCI96, this rule is specific to Python because it's based on the `pandas` library, a library used for data.
39+
- [#383](https://github.com/green-code-initiative/creedengo-rules-specifications/pull/383) Add specifications for rule GCI97, this rule concerns the different ways of squaring a value.
40+
41+
### Deleted
42+
1943
- [#58](https://github.com/green-code-initiative/creedengo-php/issues/58) Deprecation of GCI66 rule for PHP
2044
- deletion of deprecated PHP GCI34 rule
2145

@@ -420,7 +444,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
420444

421445
## Comparison List
422446

423-
[unreleased](https://github.com/green-code-initiative/creedengo-rules-specifications/compare/2.2.3...HEAD)
447+
[unreleased](https://github.com/green-code-initiative/creedengo-rules-specifications/compare/2.4.0...HEAD)
448+
[2.4.0](https://github.com/green-code-initiative/creedengo-rules-specifications/compare/2.3.0...2.4.0)
449+
[2.3.0](https://github.com/green-code-initiative/creedengo-rules-specifications/compare/2.2.3...2.3.0)
424450
[2.2.3](https://github.com/green-code-initiative/creedengo-rules-specifications/compare/2.2.2...2.2.3)
425451
[2.2.2](https://github.com/green-code-initiative/creedengo-rules-specifications/compare/2.2.1...2.2.2)
426452
[2.2.1](https://github.com/green-code-initiative/creedengo-rules-specifications/compare/2.2.0...2.2.1)

RULES.md

Lines changed: 79 additions & 70 deletions
Large diffs are not rendered by default.

src/main/rules/GCI100/GCI100.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"title": "DATA/AI PyTorch - Wrap PyTorch Inference in `torch.no_grad()`",
3+
"type": "CODE_SMELL",
4+
"status": "ready",
5+
"remediation": {
6+
"func": "Constant/Issue",
7+
"constantCost": "10min"
8+
},
9+
"tags": [
10+
"creedengo",
11+
"eco-design",
12+
"performance",
13+
"memory",
14+
"ai",
15+
"PyTorch"
16+
],
17+
"defaultSeverity": "Minor"
18+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
This rule is specific to Python because it's related to PyTorch library, which is widely used for deep learning and machine learning tasks in Python.
2+
3+
Using a PyTorch model in evaluation mode without wrapping inference in `torch.no_grad()` leads to unnecessary gradient tracking, which increases memory usage and energy consumption. This rule applies specifically to PyTorch, but aligns with general energy efficiency and eco-design principles: avoid performing unnecessary computations.
4+
5+
== Non Compliant Code Example
6+
7+
[source,python]
8+
----
9+
model.eval()
10+
for inputs in dataloader:
11+
outputs = model(inputs)
12+
----
13+
14+
In this case, PyTorch still tracks gradients even though no backward pass is needed.
15+
16+
== Compliant Solution
17+
18+
[source,python]
19+
----
20+
model.eval()
21+
with torch.no_grad():
22+
for inputs in dataloader:
23+
outputs = model(inputs)
24+
----
25+
26+
Using `torch.no_grad()` disables gradient computation during inference, saving memory and computational resources.
27+
28+
== Relevance Analysis
29+
30+
Local experiments were conducted to assess the carbon emissions associated with inference with and without `torch.no_grad()`.
31+
32+
=== Configuration
33+
34+
* Processor: Intel(R) Core(TM) Ultra 5 135U, 2100 MHz, 12 cores, 14 logical processors
35+
* RAM: 16 GB
36+
* CO₂ Emissions Measurement: https://mlco2.github.io/codecarbon/[CodeCarbon]
37+
* Framework: PyTorch 2.1
38+
39+
=== Context
40+
41+
We benchmarked inference using a small convolutional neural network on batches of random tensors. Two configurations were compared:
42+
* Inference with gradient tracking (default)
43+
* Inference using `torch.no_grad()`
44+
45+
=== Impact Analysis
46+
47+
We begin by analyzing RAM and GPU memory usage. The graph below shows the memory consumption during inference, with and without torch.no_grad():
48+
49+
image::memory.png[]
50+
51+
As expected, using torch.no_grad() significantly reduces memory usage. This effect is especially noticeable on GPU, since it no longer needs to store intermediate values required for gradient computation.
52+
53+
The blue shaded area represents the range of memory or emissions observed across multiple batch iterations during a single epoch.
54+
55+
Next, we compare the carbon emissions generated in both cases:
56+
57+
image::emissions.png[]
58+
59+
While the difference in emissions is less dramatic than for memory usage, it remains meaningful. This is because most of the energy consumption comes from matrix operations, which are computationally expensive — and torch.no_grad() helps avoid some unnecessary overhead.
60+
61+
== Conclusion
62+
63+
The rule is relevant. Wrapping inference in `torch.no_grad()`:
64+
- Reduces energy consumption
65+
- Improves inference performance
66+
- Prevents memory waste
67+
68+
This practice is essential in any production or evaluation setting involving PyTorch models.
69+
70+
== References
71+
72+
* https://pytorch.org/docs/stable/generated/torch.no_grad.html
73+
36.7 KB
Loading
73.1 KB
Loading

src/main/rules/GCI101/GCI101.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"title": "AI Disable bias in convolutional layers when it's followed by a batch norm layer",
3+
"type": "CODE_SMELL",
4+
"status": "ready",
5+
"remediation": {
6+
"func": "Constant/Issue",
7+
"constantCost": "10min"
8+
},
9+
"tags": [
10+
"creedengo",
11+
"eco-design",
12+
"performance",
13+
"memory",
14+
"ai",
15+
"convolutional"
16+
],
17+
"defaultSeverity": "Minor"
18+
}
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
This rule is specific to Deep Learning architectures built with convolutional layers followed by Batch Normalization.
2+
3+
Using a bias term in a convolutional layer that is immediately followed by a Batch Normalization (BatchNorm) layer is redundant and unnecessary. In such cases, the bias added by the convolution is effectively canceled out during the normalization process, as BatchNorm subtracts the mean and applies its own learnable affine transformation. As a result, the bias from the convolutional layer has no practical effect on the model's output. Removing it reduces the number of parameters—improving model efficiency slightly in terms of memory usage and emissions—while maintaining or even slightly improving training accuracy.
4+
5+
== Non Compliant Code Example
6+
7+
[source,python]
8+
----
9+
nn.Sequential(
10+
nn.Conv2d(in_channels, out_channels, kernel_size, bias=True),
11+
nn.BatchNorm2d(out_channels),
12+
nn.ReLU()
13+
)
14+
----
15+
16+
In this example, a convolutional layer includes a bias term, which is unnecessary when immediately followed by a BatchNorm layer.
17+
18+
== Compliant Solution
19+
20+
[source,python]
21+
----
22+
nn.Sequential(
23+
nn.Conv2d(in_channels, out_channels, kernel_size, bias=False),
24+
nn.BatchNorm2d(out_channels),
25+
nn.ReLU()
26+
)
27+
----
28+
29+
Since `BatchNorm2d` normalizes and shifts the output using learnable parameters, the bias from the preceding convolution becomes redundant.
30+
31+
== Relevance Analysis
32+
33+
Local experiments were conducted to assess the impact of disabling bias in convolutional layers followed by BatchNorm.
34+
35+
=== Configuration
36+
37+
* Processor: Intel(R) Xeon(R) CPU 3.80GHz
38+
* RAM: 64GB
39+
* GPU: NVIDIA Quadro RTX 6000
40+
* CO₂ Emissions Measurement: https://mlco2.github.io/codecarbon/[CodeCarbon]
41+
* Framework: PyTorch
42+
43+
=== Context
44+
45+
Two models were trained under identical settings:
46+
- One with `bias=True` in convolutional layers preceding BatchNorm
47+
- One with `bias=False`
48+
49+
The following metrics were compared:
50+
- Training time per epoch
51+
- GPU memory usage
52+
- Parameter count
53+
- Training and test accuracy
54+
- CO₂ emissions per epoch
55+
56+
=== Impact Analysis
57+
58+
image::convresult.png[]
59+
60+
- **Training Time:** Nearly identical (~30 seconds/epoch) between configurations.
61+
- **Memory Usage:** lower for the "Without Bias" model in terms of reserved GPU memory.
62+
- **Training Accuracy:** We can see that there's no significant difference in training accuracy between the two models, with both converging to similar values.
63+
- **Test Accuracy:** Final accuracy remained the same for both models, confirming no negative impact.
64+
- **Parameter Count:**
65+
- With Bias: 155,850
66+
- Without Bias: 155,626
67+
This shows a real reduction in parameters.
68+
- **Emissions:** Emissions per epoch were fractionally lower without bias, due to a leaner architecture and reduced operations.
69+
70+
== Conclusion
71+
72+
Disabling bias in convolutional layers followed by BatchNorm:
73+
74+
- Reduces the parameter count
75+
- Optimizes memory and emissions
76+
- Maintains accuracy
77+
78+
== References
79+
80+
Credit : https://github.com/AghilesAzzoug/GreenPyData
81+
- https://arxiv.org/pdf/1502.03167
82+
- https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html
225 KB
Loading

src/main/rules/GCI102/GCI102.json

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
{
2+
"title": "AI Use pinned memory on DataLoader when using GPU",
3+
"type": "CODE_SMELL",
4+
"status": "ready",
5+
"remediation": {
6+
"func": "Constant/Issue",
7+
"constantCost": "10min"
8+
},
9+
"tags": [
10+
"creedengo",
11+
"eco-design",
12+
"performance",
13+
"memory",
14+
"ai",
15+
"pytorch"
16+
],
17+
"defaultSeverity": "Minor"
18+
}

0 commit comments

Comments
 (0)