1 /*
2 * Copyright (c) 2025, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package org.openjdk.bench.valhalla.matrix;
24
25 import org.openjdk.jmh.annotations.Benchmark;
26 import org.openjdk.jmh.annotations.CompilerControl;
27 import org.openjdk.jmh.annotations.Setup;
28
29 import java.util.concurrent.ThreadLocalRandom;
30
31
32 public class Identity extends MatrixBase {
33
34 public static IdentityComplex[][] create_matrix_ref(int size) {
35 return new IdentityComplex[size][size];
36 }
37
38 public static Complex[][] create_matrix_int(int size) {
39 return new Complex[size][size];
40 }
41
42 public static abstract class RefState extends SizeState {
43 IdentityComplex[][] A;
44 IdentityComplex[][] B;
45
46 static void populate(IdentityComplex[][] m) {
47 int size = m.length;
48 for (int i = 0; i < size; i++) {
49 for (int j = 0; j < size; j++) {
50 m[i][j] = new IdentityComplex(ThreadLocalRandom.current().nextDouble(), ThreadLocalRandom.current().nextDouble());
51 }
52 }
53 }
54 }
55
56 public static abstract class IntState extends SizeState {
57 Complex[][] A;
58 Complex[][] B;
59
60 static void populate(Complex[][] m) {
61 int size = m.length;
62 for (int i = 0; i < size; i++) {
63 for (int j = 0; j < size; j++) {
64 m[i][j] = new IdentityComplex(ThreadLocalRandom.current().nextDouble(), ThreadLocalRandom.current().nextDouble());
65 }
66 }
67 }
68 }
69
70 public static class Ref_as_Ref extends RefState {
71 @Setup
72 public void setup() {
73 populate(A = create_matrix_ref(size));
74 populate(B = create_matrix_ref(size));
75 }
76 }
77
78 public static class Ref_as_Int extends IntState {
79 @Setup
80 public void setup() {
81 populate(A = create_matrix_ref(size));
82 populate(B = create_matrix_ref(size));
83 }
84 }
85
86 public static class Int_as_Int extends IntState {
87 @Setup
88 public void setup() {
89 populate(A = create_matrix_int(size));
90 populate(B = create_matrix_int(size));
91 }
92 }
93
94 @Benchmark
95 @CompilerControl(CompilerControl.Mode.DONT_INLINE)
96 public IdentityComplex[][] mult_ref_as_ref(Ref_as_Ref st) {
97 IdentityComplex[][] A = st.A;
98 IdentityComplex[][] B = st.B;
99 int size = st.size;
100 IdentityComplex[][] R = create_matrix_ref(size);
101 for (int i = 0; i < size; i++) {
102 for (int j = 0; j < size; j++) {
103 IdentityComplex s = new IdentityComplex(0,0);
104 for (int k = 0; k < size; k++) {
105 s = s.add(A[i][k].mul(B[k][j]));
106 }
107 R[i][j] = s;
108 }
109 }
110 return R;
111 }
112
113 @Benchmark
114 @CompilerControl(CompilerControl.Mode.DONT_INLINE)
115 public Complex[][] mult_ref_as_int(Ref_as_Int st) {
116 Complex[][] A = st.A;
117 Complex[][] B = st.B;
118 int size = st.size;
119 Complex[][] R = create_matrix_ref(size);
120 for (int i = 0; i < size; i++) {
121 for (int j = 0; j < size; j++) {
122 Complex s = new IdentityComplex(0,0);
123 for (int k = 0; k < size; k++) {
124 s = s.add(A[i][k].mul(B[k][j]));
125 }
126 R[i][j] = s;
127 }
128 }
129 return R;
130 }
131
132 @Benchmark
133 @CompilerControl(CompilerControl.Mode.DONT_INLINE)
134 public Complex[][] mult_int_as_int(Int_as_Int st) {
135 Complex[][] A = st.A;
136 Complex[][] B = st.B;
137 int size = st.size;
138 Complex[][] R = create_matrix_int(size);
139 for (int i = 0; i < size; i++) {
140 for (int j = 0; j < size; j++) {
141 Complex s = new IdentityComplex(0,0);
142 for (int k = 0; k < size; k++) {
143 s = s.add(A[i][k].mul(B[k][j]));
144 }
145 R[i][j] = s;
146 }
147 }
148 return R;
149 }
150
151 public interface Complex {
152 double re();
153 double im();
154 Complex add(Complex that);
155 Complex mul(Complex that);
156 }
157
158 public static class IdentityComplex implements Complex {
159
160 private final double re;
161 private final double im;
162
163 public IdentityComplex(double re, double im) {
164 this.re = re;
165 this.im = im;
166 }
167
168 @Override
169 public double re() { return re; }
170
171 @Override
172 public double im() { return im; }
173
174 @Override
175 public IdentityComplex add(Complex that) {
176 return new IdentityComplex(this.re + that.re(), this.im + that.im());
177 }
178
179 public IdentityComplex add(IdentityComplex that) {
180 return new IdentityComplex(this.re + that.re, this.im + that.im);
181 }
182
183 @Override
184 public IdentityComplex mul(Complex that) {
185 return new IdentityComplex(this.re * that.re() - this.im * that.im(),
186 this.re * that.im() + this.im * that.re());
187 }
188
189 public IdentityComplex mul(IdentityComplex that) {
190 return new IdentityComplex(this.re * that.re - this.im * that.im,
191 this.re * that.im + this.im * that.re);
192 }
193
194 }
195
196 }