Skip to content

Commit e8b5f08

Browse files
authored
switch to native complex numbers (#367)
* rework glas * add const * use native complex numbers * remove complex and update sum * fix style
1 parent 4e82864 commit e8b5f08

File tree

18 files changed

+287
-332
lines changed

18 files changed

+287
-332
lines changed

benchmarks/glas/gemm_bench.d

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,33 @@
22
/+ dub.json:
33
{
44
"name": "gemm_bench",
5-
"dependencies": {"mir": {"path": "../.."}, "cblas": "~>0.1.0"},
5+
"dependencies": {"mir": {"path": "../.."}, "cblas": "~>1.0.0"},
66
"dflags-ldc": ["-mcpu=native"],
7+
"libs": ["blas"],
78
"lflags": ["-L./"]
89
}
910
+/
1011
import std.math;
1112
import std.traits;
1213
import std.datetime;
1314
import std.conv;
14-
import std.complex;
1515
import std.algorithm.comparison;
1616
import std.stdio;
1717
import std.exception;
1818
import std.getopt;
1919
import mir.ndslice;
2020
import mir.glas;
21+
import mir.internal.utility : isComplex;
2122

2223
alias C = float;
2324
//alias C = double;
24-
//alias C = Complex!float;
25-
//alias C = Complex!double;
25+
//alias C = cfloat;
26+
//alias C = cdouble;
2627
alias A = C;
2728
alias B = C;
2829

2930
void main(string[] args)
3031
{
31-
auto glas = new GlasContext;
3232
size_t m = 1000;
3333
size_t n = size_t.max;
3434
size_t k = size_t.max;
@@ -60,28 +60,26 @@ void main(string[] args)
6060

6161
d[] = c[];
6262

63-
static if(is(C : Complex!F, F))
63+
static if(isComplex!C)
6464
{
65-
C alpha = C(3, 7);
66-
C beta = C(2, 5);
65+
C alpha = 3 + 7i;
66+
C beta = 2 + 5i;
6767
}
6868
else
6969
{
7070
C alpha = 3;
7171
C beta = 2;
7272
}
7373

74-
7574
auto nsecsBLAS = double.max;
7675

77-
7876
foreach(_; 0..count) {
7977
StopWatch sw;
8078
sw.start;
81-
static if(!(is(C == real) || is(C : Complex!real) || is(C : long)))
79+
static if(!(is(C == real) || is(C == creal) || is(C : long)))
8280
{
8381
static import cblas;
84-
static if(is(C : Complex!E, E))
82+
static if(isComplex!C)
8583
cblas.gemm(
8684
cblas.Order.RowMajor,
8785
cblas.Transpose.NoTrans,
@@ -128,7 +126,7 @@ void main(string[] args)
128126
{
129127
StopWatch sw;
130128
sw.start;
131-
glas.gemm(alpha, a, b, beta, c);
129+
gemm(alpha, a, b, beta, c);
132130
sw.stop;
133131
auto newns = sw.peek.to!Duration.total!"nsecs".to!double;
134132
//writefln("_GLAS (single thread) : %5s GFLOPS", (m * n * k * 2) / newns);
@@ -147,10 +145,9 @@ void fillRNG(T)(Slice!(2, T*) sl)
147145
import std.random;
148146
foreach(ref e; sl.byElement)
149147
{
150-
static if(is(T : Complex!F, F))
148+
static if(isComplex!T)
151149
{
152-
e.re = cast(F) uniform(-100, 100);
153-
e.im = cast(F) uniform(-100, 100);
150+
e = uniform(-100, 100) + uniform(-100, 100) * 1i;
154151
}
155152
else
156153
{

benchmarks/glas/gemm_report.d

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22
/+ dub.json:
33
{
44
"name": "gemm_report",
5-
"dependencies": {"mir": {"path": "../.."}, "cblas": "~>0.2.0"},
5+
"dependencies": {"mir": {"path": "../.."}, "cblas": "~>1.0.0"},
66
"lflags": ["-L./"],
77
"libs": ["blas"],
8-
"dflags-ldc": ["-mcpu=native", "-singleobj"],
8+
"dflags-ldc": ["-mcpu=native"],
99
}
1010
+/
1111
//"lflags": ["-L/opt/intel/mkl/lib"],
@@ -19,18 +19,18 @@ import std.math;
1919
import std.traits;
2020
import std.datetime;
2121
import std.conv;
22-
import std.complex;
2322
import std.algorithm.comparison;
2423
import std.stdio;
2524
import std.exception;
2625
import std.getopt;
2726
import mir.ndslice;
2827
import mir.glas;
28+
import mir.internal.utility : isComplex;
2929

3030
alias C = float;
3131
//alias C = double;
32-
//alias C = Complex!float;
33-
//alias C = Complex!double;
32+
//alias C = cfloat;
33+
//alias C = cdouble;
3434
alias A = C;
3535
alias B = C;
3636

@@ -41,7 +41,6 @@ size_t[] reportValues = [
4141

4242
void main(string[] args)
4343
{
44-
auto glas = new GlasContext;
4544
size_t count = 6;
4645
auto helpInformation =
4746
getopt(args,
@@ -69,10 +68,10 @@ void main(string[] args)
6968

7069
d[] = c[];
7170

72-
static if(is(C : Complex!F, F))
71+
static if(isComplex!C)
7372
{
74-
C alpha = C(3, 7);
75-
C beta = C(2, 5);
73+
C alpha = 3 + 7i;
74+
C beta = 2 + 5i;
7675
}
7776
else
7877
{
@@ -85,10 +84,10 @@ void main(string[] args)
8584
foreach(_; 0..count) {
8685
StopWatch sw;
8786
sw.start;
88-
static if(!(is(C == real) || is(C : Complex!real) || is(C : long)))
87+
static if(!(is(C == real) || is(C == creal) || is(C : long)))
8988
{
9089
static import cblas;
91-
static if(is(C : Complex!E, E))
90+
static if(isComplex!C)
9291
cblas.gemm(
9392
cblas.Order.RowMajor,
9493
cblas.Transpose.NoTrans,
@@ -137,7 +136,7 @@ void main(string[] args)
137136
{
138137
StopWatch sw;
139138
sw.start;
140-
glas.gemm(alpha, a, b, beta, c);
139+
gemm(alpha, a, b, beta, c);
141140
sw.stop;
142141
auto newns = sw.peek.to!Duration.total!"nsecs".to!double;
143142
//writefln("_GLAS (single thread) : %5s GFLOPS", (m * n * k * 2) / newns);
@@ -154,10 +153,9 @@ void fillRNG(T)(Slice!(2, T*) sl)
154153
import std.random;
155154
foreach(ref e; sl.byElement)
156155
{
157-
static if(is(T : Complex!F, F))
156+
static if(isComplex!T)
158157
{
159-
e.re = cast(F) uniform(-100, 100);
160-
e.im = cast(F) uniform(-100, 100);
158+
e = uniform(-100, 100) + uniform(-100, 100) * 1i;
161159
}
162160
else
163161
{

benchmarks/glas/symm_bench.d

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -2,33 +2,33 @@
22
/+ dub.json:
33
{
44
"name": "symm_bench",
5-
"dependencies": {"mir": {"path": "../.."}, "cblas": "~>0.1.0"},
5+
"dependencies": {"mir": {"path": "../.."}, "cblas": "~>1.0.0"},
66
"dflags-ldc": ["-mcpu=native"],
7+
"libs": ["blas"],
78
"lflags": ["-L./"]
89
}
910
+/
1011
import std.math;
1112
import std.traits;
1213
import std.datetime;
1314
import std.conv;
14-
import std.complex;
1515
import std.algorithm.comparison;
1616
import std.stdio;
1717
import std.exception;
1818
import std.getopt;
1919
import mir.ndslice;
2020
import mir.glas;
21+
import mir.internal.utility : isComplex;
2122

2223
alias C = float;
2324
//alias C = double;
24-
//alias C = Complex!float;
25-
//alias C = Complex!double;
25+
//alias C = cfloat;
26+
//alias C = cdouble;
2627
alias A = C;
2728
alias B = C;
2829

2930
void main(string[] args)
3031
{
31-
auto glas = new GlasContext;
3232
size_t m = 1000;
3333
size_t n = size_t.max;
3434
size_t k = size_t.max;
@@ -59,28 +59,26 @@ void main(string[] args)
5959

6060
d[] = c[];
6161

62-
static if(is(C : Complex!F, F))
62+
static if(isComplex!C)
6363
{
64-
C alpha = C(3, 7);
65-
C beta = C(2, 5);
64+
C alpha = 3 + 7i;
65+
C beta = 2 + 5i;
6666
}
6767
else
6868
{
6969
C alpha = 3;
7070
C beta = 2;
7171
}
7272

73-
7473
auto nsecsBLAS = double.max;
7574

76-
7775
foreach(_; 0..count) {
7876
StopWatch sw;
7977
sw.start;
80-
static if(!(is(C == real) || is(C : Complex!real) || is(C : long)))
78+
static if(!(is(C == real) || is(C == creal) || is(C : long)))
8179
{
8280
static import cblas;
83-
static if(is(C : Complex!E, E))
81+
static if(isComplex!C)
8482
cblas.symm(
8583
cblas.Order.RowMajor,
8684
cblas.Side.Left,
@@ -125,7 +123,7 @@ void main(string[] args)
125123
{
126124
StopWatch sw;
127125
sw.start;
128-
glas.symm(Side.left, Uplo.lower, alpha, a, b, beta, c);
126+
symm(Side.left, Uplo.lower, alpha, a, b, beta, c);
129127
sw.stop;
130128
auto newns = sw.peek.to!Duration.total!"nsecs".to!double;
131129
//writefln("_GLAS (single thread) : %5s GFLOPS", (m * n * m * 2) / newns);
@@ -148,10 +146,9 @@ void fillRNG(T)(Slice!(2, T*) sl)
148146
import std.random;
149147
foreach(ref e; sl.byElement)
150148
{
151-
static if(is(T : Complex!F, F))
149+
static if(isComplex!T)
152150
{
153-
e.re = cast(F) uniform(-100, 100);
154-
e.im = cast(F) uniform(-100, 100);
151+
e = uniform(-100, 100) + uniform(-100, 100) * 1i;
155152
}
156153
else
157154
{

source/mir/glas/common.d

Lines changed: 1 addition & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -9,53 +9,6 @@ Authors: Ilya Yaroshenko
99
+/
1010
module mir.glas.common;
1111

12-
/++
13-
GLAS Context
14-
15-
Note: `GlasContext` is single thread for now.
16-
+/
17-
struct GlasContext
18-
{
19-
import mir.internal.memory;
20-
import mir.glas.internal.context;
21-
static import cpuid.unified;
22-
import core.sync.mutex;
23-
24-
private
25-
{
26-
void[] _memory;
27-
}
28-
29-
nothrow @nogc:
30-
31-
~this()
32-
{
33-
release;
34-
}
35-
36-
/// Returns: reused unaligned memory chunk
37-
nothrow @nogc void[] memory(size_t size)
38-
{
39-
if (_memory.length < size)
40-
{
41-
auto f = _memory.length << 1;
42-
if (f > size)
43-
size = f;
44-
if (_memory !is null)
45-
deallocate(_memory);
46-
_memory = alignedAllocate(size, 4096);
47-
}
48-
return _memory[0 .. size];
49-
}
50-
51-
/// Releases memory.
52-
void release()
53-
{
54-
if (_memory !is null)
55-
deallocate(_memory);
56-
}
57-
}
58-
5912
/++
6013
Uplo specifies whether a matrix is an upper or lower triangular matrix.
6114
+/
@@ -153,10 +106,7 @@ package mixin template prefix3()
153106
enum PB = CB ? 2 : 1;
154107
enum PC = CC ? 2 : 1;
155108

156-
static if (is(C : Complex!F, F))
157-
alias T = F;
158-
else
159-
alias T = C;
109+
alias T = realType!C;
160110
static assert(!isComplex!T);
161111
}
162112

0 commit comments

Comments
 (0)