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 }