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.Fork; 28 import org.openjdk.jmh.annotations.Setup; 29 30 import java.util.concurrent.ThreadLocalRandom; 31 32 @Fork(value = 3, jvmArgsAppend = {"--enable-preview"}) 33 public class Value extends MatrixBase { 34 35 public static ValueComplex[][] create_matrix_val(int size) { 36 return new ValueComplex[size][size]; 37 } 38 39 public static Complex[][] create_matrix_int(int size) { 40 return new Complex[size][size]; 41 } 42 43 public static abstract class ValState extends SizeState { 44 ValueComplex[][] A; 45 ValueComplex[][] B; 46 47 static void populate(ValueComplex[][] m) { 48 int size = m.length; 49 for (int i = 0; i < size; i++) { 50 for (int j = 0; j < size; j++) { 51 m[i][j] = new ValueComplex(ThreadLocalRandom.current().nextDouble(), ThreadLocalRandom.current().nextDouble()); 52 } 53 } 54 } 55 } 56 57 public static abstract class IntState extends SizeState { 58 Complex[][] A; 59 Complex[][] B; 60 61 static void populate(Complex[][] m) { 62 int size = m.length; 63 for (int i = 0; i < size; i++) { 64 for (int j = 0; j < size; j++) { 65 m[i][j] = new ValueComplex(ThreadLocalRandom.current().nextDouble(), ThreadLocalRandom.current().nextDouble()); 66 } 67 } 68 } 69 } 70 71 public static class Val_as_Val extends ValState { 72 @Setup 73 public void setup() { 74 populate(A = create_matrix_val(size)); 75 populate(B = create_matrix_val(size)); 76 } 77 } 78 79 public static class Val_as_Int extends IntState { 80 @Setup 81 public void setup() { 82 populate(A = create_matrix_val(size)); 83 populate(B = create_matrix_val(size)); 84 } 85 } 86 87 public static class Int_as_Int extends IntState { 88 @Setup 89 public void setup() { 90 populate(A = create_matrix_int(size)); 91 populate(B = create_matrix_int(size)); 92 } 93 } 94 95 @Benchmark 96 @CompilerControl(CompilerControl.Mode.DONT_INLINE) 97 public ValueComplex[][] mult_val_as_val(Val_as_Val st) { 98 ValueComplex[][] A = st.A; 99 ValueComplex[][] B = st.B; 100 int size = st.size; 101 ValueComplex[][] R = create_matrix_val(size); 102 for (int i = 0; i < size; i++) { 103 for (int j = 0; j < size; j++) { 104 ValueComplex s = new ValueComplex(0,0); 105 for (int k = 0; k < size; k++) { 106 s = s.add(A[i][k].mul(B[k][j])); 107 } 108 R[i][j] = s; 109 } 110 } 111 return R; 112 } 113 114 @Benchmark 115 @CompilerControl(CompilerControl.Mode.DONT_INLINE) 116 public Complex[][] mult_val_as_int(Val_as_Int st) { 117 Complex[][] A = st.A; 118 Complex[][] B = st.B; 119 int size = st.size; 120 Complex[][] R = create_matrix_val(size); 121 for (int i = 0; i < size; i++) { 122 for (int j = 0; j < size; j++) { 123 Complex s = new ValueComplex(0,0); 124 for (int k = 0; k < size; k++) { 125 s = s.add(A[i][k].mul(B[k][j])); 126 } 127 R[i][j] = s; 128 } 129 } 130 return R; 131 } 132 133 @Benchmark 134 @CompilerControl(CompilerControl.Mode.DONT_INLINE) 135 public Complex[][] mult_int_as_int(Int_as_Int st) { 136 Complex[][] A = st.A; 137 Complex[][] B = st.B; 138 int size = st.size; 139 Complex[][] R = create_matrix_int(size); 140 for (int i = 0; i < size; i++) { 141 for (int j = 0; j < size; j++) { 142 Complex s = new ValueComplex(0,0); 143 for (int k = 0; k < size; k++) { 144 s = s.add(A[i][k].mul(B[k][j])); 145 } 146 R[i][j] = s; 147 } 148 } 149 return R; 150 } 151 152 public interface Complex { 153 double re(); 154 double im(); 155 Complex add(Complex that); 156 Complex mul(Complex that); 157 } 158 159 public static value class ValueComplex implements Complex { 160 161 private final double re; 162 private final double im; 163 164 public ValueComplex(double re, double im) { 165 this.re = re; 166 this.im = im; 167 } 168 169 @Override 170 public double re() { return re; } 171 172 @Override 173 public double im() { return im; } 174 175 @Override 176 public ValueComplex add(Complex that) { 177 return new ValueComplex(this.re + that.re(), this.im + that.im()); 178 } 179 180 public ValueComplex add(ValueComplex that) { 181 return new ValueComplex(this.re + that.re, this.im + that.im); 182 } 183 184 @Override 185 public ValueComplex mul(Complex that) { 186 return new ValueComplex(this.re * that.re() - this.im * that.im(), 187 this.re * that.im() + this.im * that.re()); 188 } 189 190 public ValueComplex mul(ValueComplex that) { 191 return new ValueComplex(this.re * that.re - this.im * that.im, 192 this.re * that.im + this.im * that.re); 193 } 194 195 } 196 197 }