gpu-compute, mem-ruby, configs: Add GCN3 ISA support to GPU model
[gem5.git] / src / gpu-compute / static_register_manager_policy.cc
1 /*
2 * Copyright (c) 2016 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * For use for simulation and test purposes only
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
16 *
17 * 3. Neither the name of the copyright holder nor the names of its
18 * contributors may be used to endorse or promote products derived from this
19 * software without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 *
33 * Authors: Mark Wyse
34 */
35
36 #include "gpu-compute/static_register_manager_policy.hh"
37
38 #include "config/the_gpu_isa.hh"
39 #include "debug/GPURename.hh"
40 #include "gpu-compute/compute_unit.hh"
41 #include "gpu-compute/pool_manager.hh"
42 #include "gpu-compute/scalar_register_file.hh"
43 #include "gpu-compute/shader.hh"
44 #include "gpu-compute/vector_register_file.hh"
45 #include "gpu-compute/wavefront.hh"
46
47 StaticRegisterManagerPolicy::StaticRegisterManagerPolicy()
48 {
49 }
50
51 void
52 StaticRegisterManagerPolicy::exec()
53 {
54 }
55
56 int
57 StaticRegisterManagerPolicy::mapVgpr(Wavefront* w, int vgprIndex)
58 {
59 panic_if((vgprIndex >= w->reservedVectorRegs)
60 || (w->reservedVectorRegs < 0),
61 "VGPR index %d is out of range: VGPR range=[0,%d]",
62 vgprIndex, w->reservedVectorRegs);
63
64 // add the offset from where the VGPRs of the wavefront have been assigned
65 int physicalVgprIndex = w->startVgprIndex + vgprIndex;
66
67 panic_if(!((w->startVgprIndex <= physicalVgprIndex) &&
68 (w->startVgprIndex + w->reservedVectorRegs - 1)
69 >= physicalVgprIndex),
70 "Invalid VGPR index %d\n", physicalVgprIndex);
71
72 // calculate physical VGPR index
73 return physicalVgprIndex % w->computeUnit->vrf[w->simdId]->numRegs();
74 }
75
76 int
77 StaticRegisterManagerPolicy::mapSgpr(Wavefront* w, int sgprIndex)
78 {
79 panic_if(!((sgprIndex < w->reservedScalarRegs)
80 && (w->reservedScalarRegs > 0)),
81 "SGPR index %d is out of range: SGPR range=[0,%d]\n",
82 sgprIndex, w->reservedScalarRegs);
83
84 // add the offset from where the SGPRs of the wavefront have been assigned
85 int physicalSgprIndex = w->startSgprIndex + sgprIndex;
86
87 panic_if(!((w->startSgprIndex <= physicalSgprIndex) &&
88 (w->startSgprIndex + w->reservedScalarRegs - 1)
89 >= physicalSgprIndex),
90 "Invalid SGPR index %d\n", physicalSgprIndex);
91
92 // calculate physical SGPR index
93 return physicalSgprIndex % w->computeUnit->srf[w->simdId]->numRegs();
94 }
95
96 bool
97 StaticRegisterManagerPolicy::canAllocateVgprs(int simdId, int nWfs,
98 int demandPerWf)
99 {
100 return cu->registerManager->vrfPoolMgrs[simdId]->
101 canAllocate(nWfs, demandPerWf);
102 }
103
104 bool
105 StaticRegisterManagerPolicy::canAllocateSgprs(int simdId, int nWfs,
106 int demandPerWf)
107 {
108 return cu->registerManager->srfPoolMgrs[simdId]->
109 canAllocate(nWfs, demandPerWf);
110 }
111
112 void
113 StaticRegisterManagerPolicy::allocateRegisters(Wavefront *w, int vectorDemand,
114 int scalarDemand)
115 {
116 uint32_t allocatedSize = 0;
117 w->startVgprIndex = cu->registerManager->vrfPoolMgrs[w->simdId]->
118 allocateRegion(vectorDemand, &allocatedSize);
119 w->reservedVectorRegs = allocatedSize;
120 cu->vectorRegsReserved[w->simdId] += w->reservedVectorRegs;
121 panic_if(cu->vectorRegsReserved[w->simdId] > cu->numVecRegsPerSimd,
122 "VRF[%d] has been overallocated %d > %d\n",
123 w->simdId, cu->vectorRegsReserved[w->simdId],
124 cu->numVecRegsPerSimd);
125
126 if (scalarDemand) {
127 w->startSgprIndex = cu->registerManager->srfPoolMgrs[w->simdId]->
128 allocateRegion(scalarDemand, &allocatedSize);
129 w->reservedScalarRegs = allocatedSize;
130 cu->scalarRegsReserved[w->simdId] += w->reservedScalarRegs;
131 panic_if(cu->scalarRegsReserved[w->simdId] > cu->numScalarRegsPerSimd,
132 "SRF[%d] has been overallocated %d > %d\n",
133 w->simdId, cu->scalarRegsReserved[w->simdId],
134 cu->numScalarRegsPerSimd);
135 }
136 }
137
138 void
139 StaticRegisterManagerPolicy::freeRegisters(Wavefront *w)
140 {
141 // free the vector registers of the completed wavefront
142 w->computeUnit->vectorRegsReserved[w->simdId] -= w->reservedVectorRegs;
143 // free the scalar registers of the completed wavefront
144 w->computeUnit->scalarRegsReserved[w->simdId] -= w->reservedScalarRegs;
145
146 panic_if(w->computeUnit->vectorRegsReserved[w->simdId] < 0,
147 "Freeing VRF[%d] registers left %d registers reserved\n",
148 w->simdId,
149 w->computeUnit->vectorRegsReserved[w->simdId]);
150 panic_if(w->computeUnit->scalarRegsReserved[w->simdId] < 0,
151 "Freeing SRF[%d] registers left %d registers reserved\n",
152 w->simdId,
153 w->computeUnit->scalarRegsReserved[w->simdId]);
154
155 int endIndex = (w->startVgprIndex + w->reservedVectorRegs - 1) %
156 w->computeUnit->vrf[w->simdId]->numRegs();
157
158 w->computeUnit->registerManager->vrfPoolMgrs[w->simdId]->
159 freeRegion(w->startVgprIndex, endIndex);
160
161 // mark/pre-mark all registers as not busy
162 for (int i = 0; i < w->reservedVectorRegs; i++) {
163 uint32_t physVgprIdx = mapVgpr(w, i);
164 w->computeUnit->vrf[w->simdId]->markReg(physVgprIdx, false);
165 }
166
167 w->reservedVectorRegs = 0;
168 w->startVgprIndex = 0;
169
170 endIndex = (w->startSgprIndex + w->reservedScalarRegs - 1) %
171 w->computeUnit->srf[w->simdId]->numRegs();
172 w->computeUnit->registerManager->srfPoolMgrs[w->simdId]->
173 freeRegion(w->startSgprIndex, endIndex);
174
175 // mark/pre-mark all registers as not busy
176 for (int i = 0; i < w->reservedScalarRegs; i++) {
177 uint32_t physSgprIdx = mapSgpr(w, i);
178 w->computeUnit->srf[w->simdId]->markReg(physSgprIdx, false);
179 }
180
181 w->reservedScalarRegs = 0;
182 w->startSgprIndex = 0;
183 }
184
185 void
186 StaticRegisterManagerPolicy::regStats()
187 {
188 }