Skip to content

Commit be6e401

Browse files
authored
Merge pull request #616 from stratika/fix/atomics/kernel_api
[fix] Atomic operations in OpenCL with the Kernel API
2 parents 5397e7d + 40166bc commit be6e401

File tree

6 files changed

+292
-32
lines changed

6 files changed

+292
-32
lines changed

tornado-drivers/opencl/src/main/java/uk/ac/manchester/tornado/drivers/opencl/graal/compiler/plugins/OCLGraphBuilderPlugins.java

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022, 2024 APT Group, Department of Computer Science,
2+
* Copyright (c) 2022, 2024-2025, APT Group, Department of Computer Science,
33
* School of Engineering, The University of Manchester. All rights reserved.
44
* Copyright (c) 2018, 2020, APT Group, Department of Computer Science,
55
* The University of Manchester. All rights reserved.
@@ -48,8 +48,6 @@
4848
import org.graalvm.compiler.core.common.memory.MemoryOrderMode;
4949
import org.graalvm.compiler.core.common.type.StampFactory;
5050
import org.graalvm.compiler.graph.Node;
51-
import org.graalvm.compiler.lir.Variable;
52-
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
5351
import org.graalvm.compiler.nodes.ConstantNode;
5452
import org.graalvm.compiler.nodes.FixedWithNextNode;
5553
import org.graalvm.compiler.nodes.PiNode;
@@ -81,9 +79,7 @@
8179
import uk.ac.manchester.tornado.api.exceptions.Debug;
8280
import uk.ac.manchester.tornado.api.exceptions.TornadoRuntimeException;
8381
import uk.ac.manchester.tornado.drivers.opencl.graal.OCLArchitecture;
84-
import uk.ac.manchester.tornado.drivers.opencl.graal.asm.OCLAssembler.OCLUnaryIntrinsic;
8582
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLKind;
86-
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLLIRStmt.AssignStmt;
8783
import uk.ac.manchester.tornado.drivers.opencl.graal.lir.OCLUnary;
8884
import uk.ac.manchester.tornado.drivers.opencl.graal.nodes.AtomicAddNodeTemplate;
8985
import uk.ac.manchester.tornado.drivers.opencl.graal.nodes.DecAtomicNode;
@@ -152,15 +148,31 @@ private static void registerAtomicCall(Registration r, JavaKind returnedJavaKind
152148
r.register(new InvocationPlugin("incrementAndGet", Receiver.class) {
153149
@Override
154150
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
155-
b.addPush(returnedJavaKind, b.append(new IncAtomicNode(receiver.get())));
151+
b.addPush(returnedJavaKind, b.append(new IncAtomicNode(receiver.get(), OCLUnary.AtomicOperator.INCREMENT_AND_GET)));
152+
return true;
153+
}
154+
});
155+
156+
r.register(new InvocationPlugin("getAndIncrement", Receiver.class) {
157+
@Override
158+
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
159+
b.addPush(returnedJavaKind, b.append(new IncAtomicNode(receiver.get(), OCLUnary.AtomicOperator.GET_AND_INCREMENT)));
156160
return true;
157161
}
158162
});
159163

160164
r.register(new InvocationPlugin("decrementAndGet", Receiver.class) {
161165
@Override
162166
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
163-
b.addPush(returnedJavaKind, b.append(new DecAtomicNode(receiver.get())));
167+
b.addPush(returnedJavaKind, b.append(new DecAtomicNode(receiver.get(), OCLUnary.AtomicOperator.DECREMENT_AND_GET)));
168+
return true;
169+
}
170+
});
171+
172+
r.register(new InvocationPlugin("getAndDecrement", Receiver.class) {
173+
@Override
174+
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
175+
b.addPush(returnedJavaKind, b.append(new DecAtomicNode(receiver.get(), OCLUnary.AtomicOperator.GET_AND_DECREMENT)));
164176
return true;
165177
}
166178
});
@@ -399,7 +411,6 @@ public boolean defaultHandler(GraphBuilderContext b, ResolvedJavaMethod targetMe
399411

400412
}
401413

402-
403414
PrintfNode printfNode = new PrintfNode(actualArgs);
404415
b.append(printfNode);
405416

tornado-drivers/opencl/src/main/java/uk/ac/manchester/tornado/drivers/opencl/graal/lir/OCLUnary.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* This file is part of Tornado: A heterogeneous programming framework:
33
* https://github.com/beehive-lab/tornadovm
44
*
5-
* Copyright (c) 2013-2022, 2024, APT Group, Department of Computer Science,
5+
* Copyright (c) 2013-2022, 2024-2025, APT Group, Department of Computer Science,
66
* The University of Manchester. All rights reserved.
77
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
88
*
@@ -116,14 +116,20 @@ public String toString() {
116116
}
117117
}
118118

119-
public static class IntrinsicAtomicInc extends UnaryConsumer {
119+
public enum AtomicOperator {
120+
INCREMENT_AND_GET, GET_AND_INCREMENT, DECREMENT_AND_GET, GET_AND_DECREMENT
121+
}
122+
123+
public static class IntrinsicAtomicOperator extends UnaryConsumer {
120124

121125
private static final String arrayName = OCLArchitecture.atomicSpace.getName();
122126
private int index;
127+
private final AtomicOperator atomicOperator;
123128

124-
public IntrinsicAtomicInc(OCLUnaryOp opcode, LIRKind lirKind, Value value, int index) {
129+
public IntrinsicAtomicOperator(OCLUnaryOp opcode, LIRKind lirKind, Value value, int index, AtomicOperator atomicOperator) {
125130
super(opcode, lirKind, value);
126131
this.index = index;
132+
this.atomicOperator = atomicOperator;
127133
}
128134

129135
@Override
@@ -133,7 +139,21 @@ public void emit(OCLCompilationResultBuilder crb, OCLAssembler asm) {
133139

134140
@Override
135141
public String toString() {
136-
return String.format("%s(&%s[%s])", opcode.toString(), arrayName, index);
142+
switch (atomicOperator) {
143+
case INCREMENT_AND_GET -> {
144+
return String.format("%s(&%s[%s]) + %d", opcode.toString(), arrayName, index, 1);
145+
}
146+
case DECREMENT_AND_GET -> {
147+
return String.format("%s(&%s[%s]) - %d", opcode.toString(), arrayName, index, 1);
148+
}
149+
case GET_AND_INCREMENT -> {
150+
return String.format("%s(&%s[%s])", opcode.toString(), arrayName, index);
151+
}
152+
case GET_AND_DECREMENT -> {
153+
return String.format("%s(&%s[%s])", opcode.toString(), arrayName, index);
154+
}
155+
}
156+
return "";
137157
}
138158
}
139159

tornado-drivers/opencl/src/main/java/uk/ac/manchester/tornado/drivers/opencl/graal/nodes/DecAtomicNode.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, APT Group, Department of Computer Science,
2+
* Copyright (c) 2020, 2025, APT Group, Department of Computer Science,
33
* The University of Manchester. All rights reserved.
44
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
55
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -10,7 +10,7 @@
1010
*
1111
* This code is distributed in the hope that it will be useful, but WITHOUT
1212
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1414
* version 2 for more details (a copy is included in the LICENSE file that
1515
* accompanied this code).
1616
*
@@ -44,10 +44,12 @@ public class DecAtomicNode extends NodeAtomic implements LIRLowerable {
4444

4545
@Input
4646
ValueNode atomicNode;
47+
OCLUnary.AtomicOperator atomicOperator;
4748

48-
public DecAtomicNode(ValueNode atomicValue) {
49+
public DecAtomicNode(ValueNode atomicValue, OCLUnary.AtomicOperator atomicOperator) {
4950
super(TYPE, StampFactory.forKind(JavaKind.Int));
5051
this.atomicNode = atomicValue;
52+
this.atomicOperator = atomicOperator;
5153
}
5254

5355
private void generateExpressionForOpenCL2_0(NodeLIRBuilderTool generator) {
@@ -73,11 +75,12 @@ private void generateExpressionForOpenCL1_0(NodeLIRBuilderTool generator) {
7375

7476
int indexFromGlobal = atomicIntegerNode.getIndexFromGlobalMemory();
7577

76-
OCLUnary.IntrinsicAtomicInc intrinsicAtomicAdd = new OCLUnary.IntrinsicAtomicInc( //
78+
OCLUnary.IntrinsicAtomicOperator intrinsicAtomicAdd = new OCLUnary.IntrinsicAtomicOperator( //
7779
OCLAssembler.OCLUnaryIntrinsic.ATOMIC_DEC, //
7880
tool.getLIRKind(stamp), //
7981
generator.operand(atomicNode), //
80-
indexFromGlobal);
82+
indexFromGlobal, //
83+
atomicOperator);
8184

8285
OCLLIRStmt.AssignStmt assignStmt = new OCLLIRStmt.AssignStmt(result, intrinsicAtomicAdd);
8386
tool.append(assignStmt);

tornado-drivers/opencl/src/main/java/uk/ac/manchester/tornado/drivers/opencl/graal/nodes/IncAtomicNode.java

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2020, APT Group, Department of Computer Science,
2+
* Copyright (c) 2020, 2025, APT Group, Department of Computer Science,
33
* The University of Manchester. All rights reserved.
44
* Copyright (c) 2009, 2017, Oracle and/or its affiliates. All rights reserved.
55
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -10,7 +10,7 @@
1010
*
1111
* This code is distributed in the hope that it will be useful, but WITHOUT
1212
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1414
* version 2 for more details (a copy is included in the LICENSE file that
1515
* accompanied this code).
1616
*
@@ -44,10 +44,12 @@ public class IncAtomicNode extends NodeAtomic implements LIRLowerable {
4444

4545
@Input
4646
ValueNode atomicNode;
47+
OCLUnary.AtomicOperator atomicOperator;
4748

48-
public IncAtomicNode(ValueNode atomicValue) {
49+
public IncAtomicNode(ValueNode atomicValue, OCLUnary.AtomicOperator atomicOperator) {
4950
super(TYPE, StampFactory.forKind(JavaKind.Int));
5051
this.atomicNode = atomicValue;
52+
this.atomicOperator = atomicOperator;
5153
}
5254

5355
@Override
@@ -78,11 +80,12 @@ private void generateExpressionForOpenCL1_0(NodeLIRBuilderTool generator) {
7880

7981
int indexFromGlobal = atomicIntegerNode.getIndexFromGlobalMemory();
8082

81-
OCLUnary.IntrinsicAtomicInc intrinsicAtomicAdd = new OCLUnary.IntrinsicAtomicInc( //
83+
OCLUnary.IntrinsicAtomicOperator intrinsicAtomicAdd = new OCLUnary.IntrinsicAtomicOperator( //
8284
OCLAssembler.OCLUnaryIntrinsic.ATOMIC_INC, //
8385
tool.getLIRKind(stamp), //
8486
generator.operand(atomicNode), //
85-
indexFromGlobal);
87+
indexFromGlobal, //
88+
atomicOperator);
8689

8790
OCLLIRStmt.AssignStmt assignStmt = new OCLLIRStmt.AssignStmt(result, intrinsicAtomicAdd);
8891
tool.append(assignStmt);

tornado-drivers/opencl/src/main/java/uk/ac/manchester/tornado/drivers/opencl/graal/phases/TornadoAtomicsScheduling.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2023, APT Group, Department of Computer Science,
2+
* Copyright (c) 2023, 2025, APT Group, Department of Computer Science,
33
* The University of Manchester. All rights reserved.
44
* Copyright (c) 2009-2023, Oracle and/or its affiliates. All rights reserved.
55
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -10,7 +10,7 @@
1010
*
1111
* This code is distributed in the hope that it will be useful, but WITHOUT
1212
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13-
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
1414
* version 2 for more details (a copy is included in the LICENSE file that
1515
* accompanied this code).
1616
*
@@ -28,7 +28,7 @@
2828
import org.graalvm.compiler.debug.DebugContext;
2929
import org.graalvm.compiler.graph.Node;
3030
import org.graalvm.compiler.graph.iterators.NodeIterable;
31-
import org.graalvm.compiler.nodes.EndNode;
31+
import org.graalvm.compiler.nodes.FixedNode;
3232
import org.graalvm.compiler.nodes.FixedWithNextNode;
3333
import org.graalvm.compiler.nodes.GraphState;
3434
import org.graalvm.compiler.nodes.StartNode;
@@ -77,7 +77,7 @@ private void fixStartWithNext(StructuredGraph graph, TornadoAtomicIntegerNode at
7777

7878
if (first != null && !(first instanceof StartNode)) {
7979
first.replaceAtPredecessor(startNode);
80-
startNode.setNext((EndNode) first);
80+
startNode.setNext((FixedNode) first);
8181
}
8282
}
8383

0 commit comments

Comments
 (0)