Skip to content

Commit 4d066af

Browse files
Copilotbenaadams
andauthored
Add comprehensive GitHub Copilot instructions for int256 repository onboarding (#54)
* Initial plan * Add comprehensive .github/copilot-instructions.md for int256 repository onboarding Co-authored-by: benaadams <[email protected]> * tweak --------- Co-authored-by: copilot-swe-agent[bot] <[email protected]> Co-authored-by: benaadams <[email protected]> Co-authored-by: Ben Adams <[email protected]>
1 parent 89b62f5 commit 4d066af

File tree

1 file changed

+327
-0
lines changed

1 file changed

+327
-0
lines changed

.github/copilot-instructions.md

Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
# GitHub Copilot Instructions for Int256 Repository
2+
3+
## Project Overview
4+
5+
This repository contains **Nethermind.Int256**, a high-performance .NET library implementing 256-bit integer types for blockchain and cryptographic applications. The library provides both signed (`Int256`) and unsigned (`UInt256`) 256-bit integer implementations optimized for performance using hardware intrinsics and vectorization.
6+
7+
### Key Features
8+
- **High Performance**: Leverages SIMD instructions, vectorization, and hardware intrinsics
9+
- **Complete API**: Implements all standard arithmetic, bitwise, and comparison operations
10+
- **.NET Integration**: C# with .NET 9.0 target framework, full compatibility with .NET numeric interfaces and conversion patterns
11+
- **Cross-Platform**: Supports multiple architectures with optimized code paths
12+
- **Memory Efficient**: Struct-based design with minimal allocation overhead
13+
14+
15+
## General
16+
17+
- Make only high confidence suggestions when reviewing code changes.
18+
- Always use the latest version C#, currently C# 13 features.
19+
- Never change global.json unless explicitly asked to.
20+
- Never change package.json or package-lock.json files unless explicitly asked to.
21+
- Never change NuGet.config files unless explicitly asked to.
22+
- Always trim trailing whitespace, and do not have whitespace on otherwise empty lines.
23+
24+
**Any code you commit SHOULD compile, and new and existing tests related to the change SHOULD pass.**
25+
26+
You MUST make your best effort to ensure your changes satisfy those criteria before committing. If for any reason you were unable to build or test the changes, you MUST report that. You MUST NOT claim success unless all builds and tests pass as described above.
27+
28+
You MUST follow all code-formatting and naming conventions defined in [`.editorconfig`](/.editorconfig).
29+
30+
In addition to the rules enforced by `.editorconfig`, you SHOULD:
31+
32+
- Prefer file-scoped namespace declarations and single-line using directives; however do not change the type of namespace format in an existing file unless specifically asked.
33+
- Ensure that the final return statement of a method is on its own line.
34+
- Use pattern matching and switch expressions wherever possible.
35+
- Use `nameof` instead of string literals when referring to member names.
36+
- Always use `is null` or `is not null` instead of `== null` or `!= null`.
37+
- Trust the C# null annotations and don't add null checks when the type system says a value cannot be null.
38+
- Prefer `?.` if applicable (e.g. `scope?.Dispose()`).
39+
- Use `ObjectDisposedException.ThrowIf` where applicable.
40+
- When adding new unit tests, strongly prefer to add them to existing test code files rather than creating new code files.
41+
- If you add new code files, ensure they are listed in the csproj file (if other files in that folder are listed there) so they build.
42+
- When running tests, if possible use filters and check test run counts, or look at test logs, to ensure they actually ran.
43+
- Do not finish work with any tests commented out or disabled that were not previously commented out or disabled.
44+
- When writing tests, do not emit "Act", "Arrange" or "Assert" comments.
45+
- Copy existing style in nearby files for test method names and capitalization.
46+
- Provide code comments when helpful to explain why something is being done; however do not comment what is obvious and just a repeation of the code line.
47+
- Ensure that XML doc comments are created for any public APIs.
48+
- Do NOT use #regions.
49+
- Prefer low allocation and higher performance code.
50+
51+
---
52+
53+
54+
## Architecture and Core Components
55+
56+
### Core Types
57+
- **`UInt256`**: 256-bit unsigned integer (primary implementation)
58+
- **`Int256`**: 256-bit signed integer (wrapper around UInt256)
59+
- **`IInteger<T>`**: Common interface for integer operations
60+
- **`BigIntegerExtensions`**: Extensions for System.Numerics.BigInteger integration
61+
62+
### Internal Structure
63+
```csharp
64+
// UInt256 uses explicit layout with 4 ulong components
65+
[StructLayout(LayoutKind.Explicit)]
66+
public readonly struct UInt256
67+
{
68+
[FieldOffset(0)] public readonly ulong u0; // Least significant
69+
[FieldOffset(8)] public readonly ulong u1;
70+
[FieldOffset(16)] public readonly ulong u2;
71+
[FieldOffset(24)] public readonly ulong u3; // Most significant
72+
}
73+
```
74+
75+
### Performance Optimizations
76+
- **Hardware Intrinsics**: Uses `Vector256<T>` when available
77+
- **Conditional Compilation**: Hardware intrinsics can be disabled via `DOTNET_EnableHWIntrinsic=0`
78+
- **Unsafe Operations**: Leverages unsafe code for optimal performance
79+
- **Branch Optimization**: Minimizes conditional branches in hot paths
80+
81+
## Development Environment
82+
83+
### Requirements
84+
- **.NET 9.0 SDK** (specified in global.json)
85+
- **Visual Studio 2022** or **VS Code** with C# extension
86+
- **Git** for version control
87+
88+
### Project Structure
89+
```
90+
src/
91+
├── Nethermind.Int256/ # Core library
92+
│ ├── Int256.cs # Signed 256-bit integer
93+
│ ├── UInt256.cs # Unsigned 256-bit integer (main implementation)
94+
│ ├── IInteger.cs # Common interface
95+
│ └── BigIntegerExtensions.cs # BigInteger helpers
96+
├── Nethermind.Int256.Tests/ # Unit tests
97+
└── Nethermind.Int256.Benchmark/ # Performance benchmarks
98+
```
99+
100+
### Build Commands
101+
```bash
102+
# Restore dependencies
103+
dotnet restore
104+
105+
# Build (from src directory)
106+
dotnet build
107+
108+
# Run tests
109+
dotnet run -c Debug --project src/Nethermind.Int256.Tests
110+
111+
# Run benchmarks
112+
dotnet run -c Release --project src/Nethermind.Int256.Benchmark
113+
```
114+
115+
## Coding Standards and Conventions
116+
117+
### Code Style
118+
- **Latest C# Language Version**: Uses `<LangVersion>latest</LangVersion>`
119+
- **Nullable Reference Types**: Enabled throughout the project
120+
- **Unsafe Blocks**: Allowed for performance-critical sections
121+
- **Warnings as Errors**: `<TreatWarningsAsErrors>true</TreatWarningsAsErrors>`
122+
- **Formatting**: 4-space indentation for C# files, LF line endings, UTF-8 encoding
123+
- **Interface Naming**: Interfaces should begin with 'I' (e.g., `IInteger<T>`)
124+
- **Type Naming**: PascalCase for types, methods, and properties
125+
126+
### Naming Conventions
127+
- **Internal Fields**: Use `u0, u1, u2, u3` for UInt256 components (little-endian order)
128+
- **Constants**: Use PascalCase (e.g., `MaxValue`, `MinValue`)
129+
- **Static Readonly**: Use for compile-time constants
130+
- **Private Static**: Use `s_` prefix for static fields (e.g., `s_instanceRandom`)
131+
132+
### Performance Guidelines
133+
1. **Prefer Struct Operations**: Avoid boxing/unboxing
134+
2. **Use ReadOnlySpan<T>**: For byte array operations
135+
3. **Leverage Vector Operations**: When `Vector256<T>.IsSupported`
136+
4. **Minimize Allocations**: Use `Unsafe.SkipInit()` when appropriate
137+
5. **Branch Optimization**: Structure code to minimize conditional branches
138+
139+
### Memory Layout Considerations
140+
```csharp
141+
// Always consider endianness
142+
public UInt256(ReadOnlySpan<byte> bytes, bool isBigEndian)
143+
144+
// Use explicit field offsets for predictable layout
145+
[FieldOffset(0)] public readonly ulong u0; // Little-endian: LSB first
146+
```
147+
148+
## Testing Guidelines
149+
150+
### Test Organization
151+
- **Unit Tests**: Located in `Nethermind.Int256.Tests`
152+
- **Test Categories**: Organized by operation type (Binary, Unary, Ternary, Convertibles)
153+
- **Hardware Intrinsics Testing**: Tests run with both enabled and disabled intrinsics
154+
- **Template Pattern**: Uses `UInt256TestsTemplate<T>` for shared test logic
155+
- **FluentAssertions**: Uses FluentAssertions for readable test assertions
156+
- **NUnit Framework**: All tests use NUnit attributes and framework
157+
158+
### Test Naming
159+
```csharp
160+
[Test]
161+
public void OperationName_Scenario_ExpectedResult()
162+
{
163+
// Arrange, Act, Assert pattern
164+
// Use FluentAssertions for readable assertions
165+
result.Should().Be(expected);
166+
}
167+
168+
[TestCaseSource(typeof(BinaryOps), nameof(BinaryOps.TestCases))]
169+
public void Add((BigInteger A, BigInteger B) test)
170+
{
171+
// Use test case sources for comprehensive testing
172+
}
173+
```
174+
175+
### Test Data
176+
- **TestNumbers.cs**: Contains predefined test values and edge cases
177+
- **Comprehensive Coverage**: Tests include overflow, underflow, and boundary conditions
178+
- **Cross-Platform**: Tests verify behavior across different hardware configurations
179+
180+
### Writing New Tests
181+
When adding operations, ensure tests cover:
182+
1. **Basic Operations**: Normal cases with typical values
183+
2. **Edge Cases**: Zero, maximum/minimum values, overflow conditions
184+
3. **Conversion Tests**: To/from other numeric types
185+
4. **Performance Tests**: For critical path operations
186+
187+
## Performance Considerations
188+
189+
### Optimization Priorities
190+
1. **Hot Path Operations**: Arithmetic operations (+, -, *, /, %)
191+
2. **Comparison Operations**: Equality, less than, greater than
192+
3. **Bitwise Operations**: AND, OR, XOR, shifts
193+
4. **Conversion Operations**: To/from BigInteger, primitive types
194+
195+
### Hardware Intrinsics Usage
196+
```csharp
197+
if (Vector256<uint>.IsSupported)
198+
{
199+
// Use vectorized operations
200+
Unsafe.As<ulong, Vector256<uint>>(ref this.u0) = Vector256.Create(...);
201+
}
202+
else
203+
{
204+
// Fallback to scalar operations
205+
}
206+
```
207+
208+
### Memory Access Patterns
209+
- **Sequential Access**: Prefer when possible for cache efficiency
210+
- **Alignment**: Struct layout ensures proper alignment
211+
- **Avoid Indirection**: Direct field access over property chains
212+
213+
## Build and CI Process
214+
215+
### GitHub Actions Workflow
216+
- **Matrix Testing**: Tests against Debug/Release builds
217+
- **Hardware Intrinsics**: Tests with `DOTNET_EnableHWIntrinsic=0` and `=1`
218+
- **Cross-Platform**: Linux-based testing environment
219+
- **NuGet Publishing**: Automated on releases
220+
221+
### Local Development
222+
```bash
223+
# Run full test matrix locally
224+
DOTNET_EnableHWIntrinsic=0 dotnet run -c Debug --project src/Nethermind.Int256.Tests
225+
DOTNET_EnableHWIntrinsic=1 dotnet run -c Release --project src/Nethermind.Int256.Tests
226+
227+
# Run performance benchmarks
228+
dotnet run -c Release --project src/Nethermind.Int256.Benchmark
229+
```
230+
231+
### Benchmarking
232+
- **BenchmarkDotNet**: Uses BenchmarkDotNet for performance testing
233+
- **Hardware Variants**: Benchmarks test both with and without hardware intrinsics
234+
- **Baseline Comparisons**: Compare against System.Numerics.BigInteger where applicable
235+
236+
### Package Configuration
237+
- **Package ID**: `Nethermind.Numerics.Int256`
238+
- **Target Framework**: net9.0
239+
- **Dependencies**: Minimal (Microsoft.SourceLink.GitHub for debugging)
240+
241+
## Common Patterns and Examples
242+
243+
### Creating UInt256 Values
244+
```csharp
245+
// From primitive types
246+
UInt256 value1 = 42ul;
247+
UInt256 value2 = new UInt256(0x12345678, 0x9ABCDEF0, 0, 0);
248+
249+
// From byte array
250+
var bytes = new byte[32];
251+
UInt256 value3 = new UInt256(bytes, isBigEndian: true);
252+
253+
// From BigInteger
254+
BigInteger big = BigInteger.Parse("123456789012345678901234567890");
255+
UInt256 value4 = (UInt256)big;
256+
```
257+
258+
### Arithmetic Operations
259+
```csharp
260+
UInt256 a = 100;
261+
UInt256 b = 200;
262+
UInt256 sum = a + b;
263+
UInt256 product = a * b;
264+
bool isEqual = a == b;
265+
```
266+
267+
### Performance-Critical Code Patterns
268+
```csharp
269+
// Use in/out parameters to avoid copies
270+
public static void Add(in UInt256 left, in UInt256 right, out UInt256 result)
271+
272+
// Leverage hardware intrinsics when available
273+
if (Vector256<ulong>.IsSupported)
274+
{
275+
// Vectorized implementation
276+
}
277+
else
278+
{
279+
// Scalar fallback
280+
}
281+
282+
// Follow the IInteger<T> interface pattern for consistency
283+
public void Add(in T a, out T res)
284+
{
285+
// Implementation
286+
}
287+
```
288+
289+
## Contributing Guidelines
290+
291+
### License and Copyright
292+
- **License**: MIT License (see LICENSE file)
293+
- **Copyright**: Demerzel Solutions Limited
294+
295+
### Before Making Changes
296+
1. **Understand Performance Impact**: Profile changes affecting hot paths
297+
2. **Test Hardware Variants**: Ensure compatibility with/without intrinsics
298+
3. **Maintain API Compatibility**: Preserve existing public interfaces
299+
4. **Follow Existing Patterns**: Consistency with established code style
300+
301+
### Code Review Focus Areas
302+
- **Performance**: No regression in benchmark results
303+
- **Correctness**: Comprehensive test coverage
304+
- **Security**: Proper handling of edge cases and overflow
305+
- **Maintainability**: Clear, readable implementation
306+
307+
---
308+
309+
This library is a critical component for blockchain and cryptographic applications where performance and correctness are paramount. Always prioritize these concerns when making contributions.
310+
311+
## Quick Reference
312+
313+
### Key Files to Understand
314+
- `UInt256.cs` - Primary implementation with all core operations
315+
- `Int256.cs` - Signed wrapper around UInt256
316+
- `IInteger.cs` - Common interface defining operation patterns
317+
- `TestNumbers.cs` - Constants and edge cases for testing
318+
319+
### Common Operations Pattern
320+
```csharp
321+
// All operations follow this pattern for consistency and performance
322+
public void OperationName(in UInt256 other, out UInt256 result)
323+
{
324+
// Implementation using 'in' parameters to avoid copies
325+
// and 'out' parameters for results
326+
}
327+
```

0 commit comments

Comments
 (0)