1 //******************************************************************************
2 //
3 // File: Unsigned16BitIntegerMatrixBuf.java
4 // Package: edu.rit.mp.buf
5 // Unit: Class edu.rit.mp.buf.Unsigned16BitIntegerMatrixBuf
6 //
7 // This Java source file is copyright (C) 2009 by Alan Kaminsky. All rights
8 // reserved. For further information, contact the author, Alan Kaminsky, at
9 // ark@cs.rit.edu.
10 //
11 // This Java source file is part of the Parallel Java Library ("PJ"). PJ is free
12 // software; you can redistribute it and/or modify it under the terms of the GNU
13 // General Public License as published by the Free Software Foundation; either
14 // version 3 of the License, or (at your option) any later version.
15 //
16 // PJ is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18 // A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 //
20 // Linking this library statically or dynamically with other modules is making a
21 // combined work based on this library. Thus, the terms and conditions of the GNU
22 // General Public License cover the whole combination.
23 //
24 // As a special exception, the copyright holders of this library give you
25 // permission to link this library with independent modules to produce an
26 // executable, regardless of the license terms of these independent modules, and
27 // to copy and distribute the resulting executable under terms of your choice,
28 // provided that you also meet, for each linked independent module, the terms
29 // and conditions of the license of that module. An independent module is a module
30 // which is not derived from or based on this library. If you modify this library,
31 // you may extend this exception to your version of the library, but you are not
32 // obligated to do so. If you do not wish to do so, delete this exception
33 // statement from your version.
34 //
35 // A copy of the GNU General Public License is provided in the file gpl.txt. You
36 // may also obtain a copy of the GNU General Public License on the World Wide
37 // Web at http://www.gnu.org/licenses/gpl.html.
38 //
39 //******************************************************************************
40 package edu.rit.mp.buf;
41
42 import java.nio.ByteBuffer;
43 import java.nio.ShortBuffer;
44
45 import edu.rit.mp.Buf;
46 import edu.rit.mp.Unsigned16BitIntegerBuf;
47 import edu.rit.pj.reduction.IntegerOp;
48 import edu.rit.pj.reduction.Op;
49 import edu.rit.util.Arrays;
50 import edu.rit.util.Range;
51
52 /**
53 * Class Unsigned16BitIntegerMatrixBuf provides a buffer for a matrix of
54 * unsigned 16-bit integer items sent or received using the Message Protocol
55 * (MP). The matrix row and column strides may be 1 or greater than 1. While an
56 * instance of class Unsigned16BitIntegerMatrixBuf may be constructed directly,
57 * normally you will use a factory method in class {@linkplain
58 * edu.rit.mp.Unsigned16BitIntegerBuf Unsigned16BitIntegerBuf}. See that class
59 * for further information.
60 *
61 * @author Alan Kaminsky
62 * @version 05-Apr-2009
63 */
64 public class Unsigned16BitIntegerMatrixBuf
65 extends Unsigned16BitIntegerBuf {
66
67 // Hidden data members.
68 int[][] myMatrix;
69 Range myRowRange;
70 Range myColRange;
71 int myLowerRow;
72 int myRowCount;
73 int myRowStride;
74 int myLowerCol;
75 int myColCount;
76 int myColStride;
77
78 // Exported constructors.
79 /**
80 * Construct a new unsigned 16-bit integer matrix buffer. It is assumed that
81 * the rows and columns of <code>theMatrix</code> are allocated and that each
82 * row of <code>theMatrix</code> has the same number of columns.
83 *
84 * @param theMatrix Matrix.
85 * @param theRowRange Range of rows to include.
86 * @param theColRange Range of columns to include.
87 */
88 public Unsigned16BitIntegerMatrixBuf(int[][] theMatrix,
89 Range theRowRange,
90 Range theColRange) {
91 super(theRowRange.length() * theColRange.length());
92 myMatrix = theMatrix;
93 myRowRange = theRowRange;
94 myColRange = theColRange;
95 myLowerRow = theRowRange.lb();
96 myRowCount = theRowRange.length();
97 myRowStride = theRowRange.stride();
98 myLowerCol = theColRange.lb();
99 myColCount = theColRange.length();
100 myColStride = theColRange.stride();
101 }
102
103 // Exported operations.
104 /**
105 * {@inheritDoc}
106 *
107 * Obtain the given item from this buffer.
108 * <P>
109 * The <code>get()</code> method must not block the calling thread; if it does,
110 * all message I/O in MP will be blocked.
111 */
112 public int get(int i) {
113 return myMatrix[i2r(i) * myRowStride + myLowerRow][i2c(i) * myColStride + myLowerCol];
114 }
115
116 /**
117 * {@inheritDoc}
118 *
119 * Store the given item in this buffer.
120 * <P>
121 * The <code>put()</code> method must not block the calling thread; if it does,
122 * all message I/O in MP will be blocked.
123 */
124 public void put(int i,
125 int item) {
126 myMatrix[i2r(i) * myRowStride + myLowerRow][i2c(i) * myColStride + myLowerCol] = item;
127 }
128
129 /**
130 * {@inheritDoc}
131 *
132 * Copy items from the given buffer to this buffer. The number of items
133 * copied is this buffer's length or <code>theSrc</code>'s length, whichever is
134 * smaller. If <code>theSrc</code> is this buffer, the <code>copy()</code> method
135 * does nothing.
136 * @exception ClassCastException (unchecked exception) Thrown if
137 * <code>theSrc</code>'s item data type is not the same as this buffer's item
138 * data type.
139 */
140 public void copy(Buf theSrc) {
141 if (theSrc == this) {
142 } else if (theSrc instanceof Unsigned16BitIntegerMatrixBuf) {
143 Unsigned16BitIntegerMatrixBuf src
144 = (Unsigned16BitIntegerMatrixBuf) theSrc;
145 Arrays.copy(src.myMatrix, src.myRowRange, src.myColRange,
146 this.myMatrix, this.myRowRange, this.myColRange);
147 } else {
148 Unsigned16BitIntegerBuf.defaultCopy((Unsigned16BitIntegerBuf) theSrc, this);
149 }
150 }
151
152 /**
153 * {@inheritDoc}
154 *
155 * Create a buffer for performing parallel reduction using the given binary
156 * operation. The results of the reduction are placed into this buffer.
157 * @exception ClassCastException (unchecked exception) Thrown if this
158 * buffer's element data type and the given binary operation's argument data
159 * type are not the same.
160 */
161 public Buf getReductionBuf(Op op) {
162 return new Unsigned16BitIntegerMatrixReductionBuf(myMatrix, myRowRange, myColRange, (IntegerOp) op);
163 }
164
165 // Hidden operations.
166 /**
167 * {@inheritDoc}
168 *
169 * Send as many items as possible from this buffer to the given byte buffer.
170 * <P>
171 * The <code>sendItems()</code> method must not block the calling thread; if it
172 * does, all message I/O in MP will be blocked.
173 */
174 protected int sendItems(int i,
175 ByteBuffer buffer) {
176 ShortBuffer shortbuffer = buffer.asShortBuffer();
177 int n = 0;
178 int r = i2r(i);
179 int row = r * myRowStride + myLowerRow;
180 int c = i2c(i);
181 int col = c * myColStride + myLowerCol;
182 int ncols = Math.min(myColCount - c, shortbuffer.remaining());
183 while (r < myRowCount && ncols > 0) {
184 int[] myMatrix_row = myMatrix[row];
185 while (c < ncols) {
186 shortbuffer.put((short) myMatrix_row[col]);
187 ++c;
188 col += myColStride;
189 }
190 n += ncols;
191 ++r;
192 row += myRowStride;
193 c = 0;
194 col = myLowerCol;
195 ncols = Math.min(myColCount, shortbuffer.remaining());
196 }
197 buffer.position(buffer.position() + 2 * n);
198 return n;
199 }
200
201 /**
202 * {@inheritDoc}
203 *
204 * Receive as many items as possible from the given byte buffer to this
205 * buffer.
206 * <P>
207 * The <code>receiveItems()</code> method must not block the calling thread; if
208 * it does, all message I/O in MP will be blocked.
209 */
210 protected int receiveItems(int i,
211 int num,
212 ByteBuffer buffer) {
213 ShortBuffer shortbuffer = buffer.asShortBuffer();
214 num = Math.min(num, shortbuffer.remaining());
215 int n = 0;
216 int r = i2r(i);
217 int row = r * myRowStride + myLowerRow;
218 int c = i2c(i);
219 int col = c * myColStride + myLowerCol;
220 int ncols = Math.min(myColCount - c, num);
221 while (r < myRowCount && ncols > 0) {
222 int[] myMatrix_row = myMatrix[row];
223 for (c = 0; c < ncols; ++c) {
224 myMatrix_row[col] = shortbuffer.get() & 0xFFFF;
225 col += myColStride;
226 }
227 num -= ncols;
228 n += ncols;
229 ++r;
230 row += myRowStride;
231 col = myLowerCol;
232 ncols = Math.min(myColCount, num);
233 }
234 buffer.position(buffer.position() + 2 * n);
235 return n;
236 }
237
238 /**
239 * Convert the given buffer index to a row index.
240 */
241 int i2r(int i) {
242 return myColCount == 0 ? i : i / myColCount;
243 }
244
245 /**
246 * Convert the given buffer index to a column index.
247 */
248 int i2c(int i) {
249 return myColCount == 0 ? 0 : i % myColCount;
250 }
251
252 }