Skip to content

Commit 1b36a64

Browse files
committed
Added new PSO-based optimization tests.
1 parent 907732f commit 1b36a64

File tree

2 files changed

+203
-1
lines changed

2 files changed

+203
-1
lines changed

Src/ILGPU.Algorithms.Tests/Configurations.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
ArrayExtensionTests
22
GroupExtensionTests
3-
HistogramTests
3+
HistogramTests
44
InitializeTests
5+
OptimizationTests
56
RadixSortExtensionTests
67
RandomTests
78
ReductionExtensionTests
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,201 @@
1+
// ---------------------------------------------------------------------------------------
2+
// ILGPU Algorithms
3+
// Copyright (c) 2023 ILGPU Project
4+
// www.ilgpu.net
5+
//
6+
// File: OptimizationTests.cs
7+
//
8+
// This file is part of ILGPU and is distributed under the University of Illinois Open
9+
// Source License. See LICENSE.txt for details.
10+
// ---------------------------------------------------------------------------------------
11+
12+
#if NET7_0_OR_GREATER
13+
using ILGPU.Algorithms.Optimization;
14+
using ILGPU.Algorithms.Optimization.Optimizers;
15+
using ILGPU.Algorithms.Random;
16+
using ILGPU.Algorithms.Vectors;
17+
#endif
18+
19+
using ILGPU.Runtime;
20+
using ILGPU.Tests;
21+
using System.Linq;
22+
using System.Numerics;
23+
using Xunit;
24+
using Xunit.Abstractions;
25+
26+
#pragma warning disable CA1034
27+
#pragma warning disable CA1819
28+
#pragma warning disable xUnit1026
29+
30+
namespace ILGPU.Algorithms.Tests
31+
{
32+
public abstract partial class OptimizationTests : TestBase
33+
{
34+
protected OptimizationTests(ITestOutputHelper output, TestContext testContext)
35+
: base(output, testContext)
36+
{ }
37+
38+
#if NET7_0_OR_GREATER
39+
40+
#region Objectives
41+
42+
public readonly record struct DistanceF32x2(float Constant) :
43+
IOptimizationFunction<Float32x2, float, float>
44+
{
45+
public float Evaluate(
46+
LongIndex1D index,
47+
Index1D dimension,
48+
SingleVectorView<Float32x2> positionView)
49+
{
50+
float result = 0;
51+
for (Index1D i = 0; i < dimension; ++i)
52+
{
53+
var vec = positionView[i];
54+
var dist = vec - Float32x2.FromScalar(Constant);
55+
result += dist.X * dist.X + dist.Y * dist.Y;
56+
}
57+
return result / dimension;
58+
}
59+
60+
public bool CurrentIsBetter(float current, float proposed) =>
61+
current <= proposed;
62+
}
63+
64+
#endregion
65+
66+
#region MemberData
67+
68+
public record OptimizerConfig<TElementType>(
69+
int NumIterations,
70+
int NumParticles,
71+
int NumDimensions,
72+
TElementType[] BestPositions,
73+
TElementType[] Parameters);
74+
75+
public static TheoryData<
76+
object,
77+
object,
78+
object,
79+
object,
80+
object,
81+
object,
82+
object,
83+
object,
84+
object> TestData =>
85+
new TheoryData<
86+
object,
87+
object,
88+
object,
89+
object,
90+
object,
91+
object,
92+
object,
93+
object,
94+
object>
95+
{
96+
{
97+
new OptimizerConfig<float>(
98+
32,
99+
64,
100+
4,
101+
new float[] { 0.0f, 0.0f, 0.0f, 0.0f},
102+
new float[] { PSO.Omega, PSO.PhiG, PSO.PhiP }),
103+
new DistanceF32x2(1.3f),
104+
0.0f,
105+
2.0f,
106+
float.MaxValue,
107+
4e-4f,
108+
0.0001f,
109+
default(Float32x2),
110+
default(XorShift64Star)
111+
},
112+
{
113+
new OptimizerConfig<float>(
114+
512,
115+
2048,
116+
6,
117+
new float[] { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f},
118+
new float[] { PSO.Omega, PSO.PhiG, PSO.PhiP }),
119+
new DistanceF32x2(4.7f),
120+
0.0f,
121+
20.0f,
122+
float.MaxValue,
123+
1e-5f,
124+
1e-6f,
125+
default(Float32x2),
126+
default(XorShift128Plus)
127+
},
128+
};
129+
130+
#endregion
131+
132+
[SkippableTheory()]
133+
[MemberData(nameof(TestData))]
134+
public void ParticleSwarmOptimization<
135+
TFunc,
136+
TNumericType,
137+
TElementType,
138+
TEvalType,
139+
TRandom>(
140+
OptimizerConfig<TElementType> optimizerConfig,
141+
TFunc function,
142+
TElementType lower,
143+
TElementType upper,
144+
TEvalType best,
145+
TEvalType expected,
146+
TEvalType delta,
147+
TNumericType _,
148+
TRandom __)
149+
where TNumericType : unmanaged, IVectorType<TNumericType, TElementType>
150+
where TElementType : unmanaged, INumber<TElementType>
151+
where TEvalType : unmanaged, INumber<TEvalType>
152+
where TRandom : unmanaged, IRandomProvider<TRandom>
153+
where TFunc : struct,
154+
IOptimizationFunction<TNumericType, TElementType, TEvalType>
155+
{
156+
// Skip larger problems on the CPU
157+
Skip.If(
158+
Accelerator.AcceleratorType == AcceleratorType.CPU &&
159+
optimizerConfig.NumIterations * optimizerConfig.NumParticles > 2048);
160+
161+
const int Seed = 24404699;
162+
using var pso = new PSO<
163+
TNumericType,
164+
TElementType,
165+
TEvalType,
166+
TRandom>(
167+
Accelerator,
168+
optimizerConfig.NumParticles,
169+
optimizerConfig.NumDimensions);
170+
using var stream = Accelerator.CreateStream();
171+
172+
var random = new System.Random(Seed);
173+
using var optimizer = pso.CreateOptimizer(stream, random, function);
174+
175+
// Load config
176+
var lowerRange = Enumerable.Repeat(lower, pso.Dimension).ToArray();
177+
var upperRange = Enumerable.Repeat(upper, pso.Dimension).ToArray();
178+
pso.LoadBounds(stream, lowerRange, upperRange);
179+
pso.LoadParameters(stream, optimizerConfig.Parameters);
180+
181+
// Optimize and wait for results
182+
var result = optimizer.OptimizeToCPUAsync(
183+
stream,
184+
optimizerConfig.BestPositions,
185+
best,
186+
optimizerConfig.NumIterations);
187+
stream.Synchronize();
188+
189+
// Check result
190+
Assert.True(
191+
result.Result - delta <= expected,
192+
"Invalid result");
193+
}
194+
#endif
195+
}
196+
}
197+
198+
#pragma warning restore xUnit1026
199+
#pragma warning restore CA1034
200+
#pragma warning restore CA1819
201+

0 commit comments

Comments
 (0)