use of org.apache.sysml.runtime.matrix.data.ConvolutionParameters in project incubator-systemml by apache.
the class ConvolutionOp method inferOutputCharacteristics.
@Override
protected long[] inferOutputCharacteristics(MemoTable memo) {
// [numRows, numCols, NNZ]
long[] ret = new long[3];
if (op == ConvOp.BIAS_ADD || op == ConvOp.BIAS_MULTIPLY) {
MatrixCharacteristics[] mc = memo.getAllInputStats(getInput());
ret[0] = mc[0].rowsKnown() ? mc[0].getRows() : -1;
ret[1] = mc[0].colsKnown() ? mc[0].getCols() : -1;
ret[2] = -1;
return (ret[0] > 0 && ret[1] > 0) ? ret : null;
}
ConvolutionParameters params;
try {
params = parseInput();
} catch (DMLRuntimeException e) {
throw new RuntimeException(e);
}
switch(op) {
case MAX_POOLING:
{
// input
long N = getInput().get(0)._dim1;
ret[0] = N;
ret[1] = getExtractedVal(params.C, params.P, params.Q);
ret[2] = -1;
break;
}
case DIRECT_CONV2D:
{
// input, filter
long N = getInput().get(0)._dim1;
ret[0] = N;
ret[1] = getExtractedVal(params.K, params.P, params.Q);
ret[2] = -1;
break;
}
case DIRECT_CONV2D_BACKWARD_FILTER:
{
// input, dout
ret[0] = params.K;
ret[1] = getExtractedVal(params.C, params.R, params.S);
ret[2] = -1;
break;
}
case MAX_POOLING_BACKWARD:
{
// input, dout
ret[0] = getInput().get(0)._dim1;
ret[1] = getInput().get(0)._dim2;
ret[2] = -1;
break;
}
case DIRECT_CONV2D_BACKWARD_DATA:
{
// filter, dout
long N = getInput().get(1)._dim1;
ret[0] = N;
ret[1] = getExtractedVal(params.C, params.H, params.W);
ret[2] = -1;
break;
}
default:
throw new RuntimeException("Unsupported op:" + op.name());
}
if (LOG.isDebugEnabled() && (ret[0] <= 0 || ret[1] <= 0)) {
LOG.debug("Unknown dimensions for ConvolutionOp in inferOutputCharacteristics:" + op.name() + " " + ret[0] + " " + ret[1] + " img_dim=[" + params.N + " " + params.C + " " + params.H + " " + params.W + "]" + " filter_dim=[" + params.K + " " + params.C + " " + params.H + " " + params.W + "]" + " output_feature_map=[" + params.P + " " + params.Q + "] stride=[" + params.stride_h + " " + params.stride_w + "]" + " pad=[" + params.pad_h + " " + params.pad_w + "]");
}
//safe return (create entry only if at least dims known)
return (ret[0] > 0 && ret[1] > 0) ? ret : null;
}
use of org.apache.sysml.runtime.matrix.data.ConvolutionParameters in project incubator-systemml by apache.
the class ConvolutionSPInstruction method processInstruction.
@Override
public void processInstruction(ExecutionContext ec) throws DMLRuntimeException {
SparkExecutionContext sec = (SparkExecutionContext) ec;
if (instOpcode.equalsIgnoreCase("conv2d") || instOpcode.equalsIgnoreCase("conv2d_bias_add") || instOpcode.equalsIgnoreCase("maxpooling") || instOpcode.equalsIgnoreCase("relu_maxpooling")) {
String rddVar = input1.getName();
int numRowsPerBlock = 1;
JavaPairRDD<MatrixIndexes, MatrixBlock> inputRDD = reblockAsRectangularMatrices(sec, rddVar, numRowsPerBlock);
MatrixCharacteristics mcRdd = sec.getMatrixCharacteristics(rddVar);
// ------------------------------------
// TODO: Handle large filters > 2G
Broadcast<MatrixBlock> filterBroadcast = null;
Broadcast<MatrixBlock> biasBroadcast = null;
if (instOpcode.equalsIgnoreCase("conv2d")) {
filterBroadcast = getBroadcast(sec, _in2.getName());
} else if (instOpcode.equalsIgnoreCase("conv2d_bias_add")) {
filterBroadcast = getBroadcast(sec, _in3.getName());
biasBroadcast = getBroadcast(sec, _in2.getName());
}
// ------------------------------------
int pad_h = getScalarInput(ec, _padding, 0);
int pad_w = getScalarInput(ec, _padding, 1);
int stride_h = getScalarInput(ec, _stride, 0);
int stride_w = getScalarInput(ec, _stride, 1);
// int N = getScalarInput(ec, _input_shape, 0);
int C = getScalarInput(ec, _input_shape, 1);
int H = getScalarInput(ec, _input_shape, 2);
int W = getScalarInput(ec, _input_shape, 3);
int K = getScalarInput(ec, _filter_shape, 0);
int R = getScalarInput(ec, _filter_shape, 2);
int S = getScalarInput(ec, _filter_shape, 3);
int P = (int) ConvolutionUtils.getP(H, R, stride_h, pad_h);
int Q = (int) ConvolutionUtils.getQ(W, S, stride_w, pad_w);
ConvolutionParameters params = new ConvolutionParameters(numRowsPerBlock, C, H, W, K, R, S, stride_h, stride_w, pad_h, pad_w, 1);
boolean enableNativeBLAS = NativeHelper.isNativeLibraryLoaded();
JavaPairRDD<MatrixIndexes, MatrixBlock> out = inputRDD.mapPartitionsToPair(new RDDConv2dMapMMFunction(filterBroadcast, params, instOpcode, biasBroadcast, mcRdd.getRows(), enableNativeBLAS), true);
//put output RDD handle into symbol table
sec.setRDDHandleForVariable(output.getName(), out);
sec.addLineageRDD(output.getName(), rddVar);
// TODO: Handle nnz
long nnz = -1;
long numCols = ((long) K) * ((long) P) * ((long) Q);
if (instOpcode.equalsIgnoreCase("maxpooling") || instOpcode.equalsIgnoreCase("relu_maxpooling")) {
numCols = ((long) C) * ((long) P) * ((long) Q);
}
if (numCols > Integer.MAX_VALUE) {
throw new DMLRuntimeException("The current operator doesnot support large outputs.");
}
sec.setMetaData(output.getName(), new MatrixFormatMetaData(new MatrixCharacteristics(mcRdd.getRows(), numCols, numRowsPerBlock, (int) numCols, nnz), OutputInfo.BinaryBlockOutputInfo, InputInfo.BinaryBlockInputInfo));
} else {
throw new DMLRuntimeException("Not implemented: " + instOpcode);
}
}
use of org.apache.sysml.runtime.matrix.data.ConvolutionParameters in project incubator-systemml by apache.
the class ConvolutionCPInstruction method processInstruction.
@Override
public void processInstruction(ExecutionContext ec) throws DMLRuntimeException {
if (instOpcode.equalsIgnoreCase("bias_add")) {
processBiasAddInstruction(ec);
return;
} else if (instOpcode.equalsIgnoreCase("bias_multiply")) {
processBiasMultiplyInstruction(ec);
return;
} else if (instOpcode.equalsIgnoreCase("relu_backward")) {
processReluBackwardInstruction(ec);
return;
}
// acquire inputs
MatrixBlock outputBlock = null;
MatrixBlock matBlock = ec.getMatrixInput(input1.getName());
int pad_h = getScalarInput(ec, _padding, 0);
int pad_w = getScalarInput(ec, _padding, 1);
int stride_h = getScalarInput(ec, _stride, 0);
int stride_w = getScalarInput(ec, _stride, 1);
int N = getScalarInput(ec, _input_shape, 0);
int C = getScalarInput(ec, _input_shape, 1);
int H = getScalarInput(ec, _input_shape, 2);
int W = getScalarInput(ec, _input_shape, 3);
int K = getScalarInput(ec, _filter_shape, 0);
int R = getScalarInput(ec, _filter_shape, 2);
int S = getScalarInput(ec, _filter_shape, 3);
int P = (int) ConvolutionUtils.getP(H, R, stride_h, pad_h);
int Q = (int) ConvolutionUtils.getQ(W, S, stride_w, pad_w);
ConvolutionParameters params = new ConvolutionParameters(N, C, H, W, K, R, S, stride_h, stride_w, pad_h, pad_w, _numThreads);
params.enableNative = NativeHelper.isNativeLibraryLoaded();
if (instOpcode.equalsIgnoreCase("maxpooling") || instOpcode.equalsIgnoreCase("relu_maxpooling")) {
if (matBlock.isEmpty()) {
outputBlock = new MatrixBlock(N, C * P * Q, true);
} else {
outputBlock = getDenseOutputBlock(N, C * P * Q);
if (instOpcode.equalsIgnoreCase("maxpooling"))
Arrays.fill(outputBlock.getDenseBlock(), -Double.MAX_VALUE);
LibMatrixDNN.maxpooling(matBlock, outputBlock, params);
}
} else if (instOpcode.equalsIgnoreCase("maxpooling_backward") || instOpcode.equalsIgnoreCase("relu_maxpooling_backward")) {
MatrixBlock dout = ec.getMatrixInput(_in2.getName());
if (matBlock.isEmpty() || dout.isEmpty()) {
outputBlock = new MatrixBlock(N, C * H * W, true);
} else {
outputBlock = getDenseOutputBlock(N, C * H * W);
if (instOpcode.equalsIgnoreCase("maxpooling_backward"))
LibMatrixDNN.maxpoolingBackward(matBlock, dout, outputBlock, params, false);
else
LibMatrixDNN.maxpoolingBackward(matBlock, dout, outputBlock, params, true);
}
ec.releaseMatrixInput(_in2.getName());
} else if (instOpcode.equalsIgnoreCase("conv2d")) {
MatrixBlock filter = ec.getMatrixInput(_in2.getName());
if (filter.isEmpty() || matBlock.isEmpty()) {
outputBlock = new MatrixBlock(N, K * P * Q, true);
} else {
outputBlock = getDenseOutputBlock(N, K * P * Q);
if (params.enableNative && !isFilterSparse(filter) && !matBlock.isInSparseFormat())
LibMatrixNative.conv2d(matBlock, filter, outputBlock, params);
else
LibMatrixDNN.conv2d(matBlock, filter, outputBlock, params);
}
ec.releaseMatrixInput(_in2.getName());
} else if (instOpcode.equalsIgnoreCase("conv2d_bias_add")) {
MatrixBlock filter = ec.getMatrixInput(_in3.getName());
MatrixBlock bias = ec.getMatrixInput(_in2.getName());
if (bias.getNumRows() != params.K || bias.getNumColumns() != 1) {
throw new DMLRuntimeException("Incorrect shape of bias matrix: [" + bias.getNumRows() + " " + bias.getNumColumns() + "]. " + "Expected: [" + params.K + ", 1]");
}
boolean isOutputConvEmpty = filter.isEmpty() || matBlock.isEmpty();
if (isOutputConvEmpty && bias.isEmpty()) {
// bias_add(empty mb, empty mb) = empty mb
outputBlock = new MatrixBlock(N, K * P * Q, true);
} else if (isOutputConvEmpty && !bias.isEmpty()) {
// Add bias to empty output block
// bias_add(empty mb, bias)
outputBlock = getDenseOutputBlock(N, K * P * Q);
for (int n = 0; n < params.N; n++) ConvolutionUtils.fillBias(bias, outputBlock.getDenseBlock(), n, n + 1, params.N, params.K, params.P * params.Q);
} else {
outputBlock = getDenseOutputBlock(N, K * P * Q);
if (!bias.isEmpty()) {
// Handle situation where both input and filter are non empty, but bias is empty
params.bias = bias;
}
if (params.enableNative && !isFilterSparse(filter) && !matBlock.isInSparseFormat())
LibMatrixNative.conv2d(matBlock, filter, outputBlock, params);
else
LibMatrixDNN.conv2d(matBlock, filter, outputBlock, params);
}
ec.releaseMatrixInput(_in3.getName());
ec.releaseMatrixInput(_in2.getName());
} else if (instOpcode.equalsIgnoreCase("conv2d_backward_filter")) {
MatrixBlock dout = ec.getMatrixInput(_in2.getName());
if (dout.isEmpty() || matBlock.isEmpty()) {
outputBlock = new MatrixBlock(K, C * R * S, true);
} else {
outputBlock = getDenseOutputBlock(K, C * R * S);
if (params.enableNative && !matBlock.isInSparseFormat() && !dout.isInSparseFormat())
LibMatrixNative.conv2dBackwardFilter(matBlock, dout, outputBlock, params);
else
LibMatrixDNN.conv2dBackwardFilter(matBlock, dout, outputBlock, params);
}
ec.releaseMatrixInput(_in2.getName());
} else if (instOpcode.equalsIgnoreCase("conv2d_backward_data")) {
MatrixBlock dout = ec.getMatrixInput(_in2.getName());
if (dout.isEmpty() || matBlock.isEmpty()) {
outputBlock = new MatrixBlock(N, C * H * W, true);
} else {
outputBlock = getDenseOutputBlock(N, C * H * W);
if (params.enableNative && !isFilterSparse(matBlock) && !dout.isInSparseFormat())
LibMatrixNative.conv2dBackwardData(matBlock, dout, outputBlock, params);
else
LibMatrixDNN.conv2dBackwardData(matBlock, dout, outputBlock, params);
}
ec.releaseMatrixInput(_in2.getName());
} else {
throw new DMLRuntimeException("Unsupported op code " + instOpcode);
}
// release inputs/outputs
ec.releaseMatrixInput(input1.getName());
ec.setMatrixOutput(getOutputVariableName(), outputBlock);
}
use of org.apache.sysml.runtime.matrix.data.ConvolutionParameters in project incubator-systemml by apache.
the class ConvolutionOp method refreshSizeInformation.
@Override
public void refreshSizeInformation() {
if (op == ConvOp.BIAS_ADD || op == ConvOp.BIAS_MULTIPLY) {
Hop input1 = getInput().get(0);
setDim1(input1.getDim1());
setDim2(input1.getDim2());
return;
}
ConvolutionParameters params;
try {
params = parseInput();
} catch (DMLRuntimeException e) {
throw new RuntimeException(e);
}
switch(op) {
case MAX_POOLING:
{
// input
long N = getInput().get(0)._dim1;
_dim1 = N;
_dim2 = getExtractedVal(params.C, params.P, params.Q);
// cannot infer stats
_nnz = -1;
break;
}
case MAX_POOLING_BACKWARD:
{
// input, dout
_dim1 = getInput().get(0)._dim1;
_dim2 = getInput().get(0)._dim2;
_nnz = -1;
break;
}
case DIRECT_CONV2D:
{
// input, filter
long N = getInput().get(0)._dim1;
_dim1 = N;
_dim2 = getExtractedVal(params.K, params.P, params.Q);
// cannot infer stats
_nnz = -1;
break;
}
case DIRECT_CONV2D_BACKWARD_DATA:
{
// filter, dout
long N = getInput().get(1)._dim1;
_dim1 = N;
_dim2 = getExtractedVal(params.C, params.H, params.W);
// cannot infer stats
_nnz = -1;
break;
}
case DIRECT_CONV2D_BACKWARD_FILTER:
{
// input, dout
_dim1 = params.K;
_dim2 = getExtractedVal(params.C, params.R, params.S);
// cannot infer stats
_nnz = -1;
break;
}
default:
throw new RuntimeException("The sizes are not refreshed for " + op.name());
}
if (LOG.isDebugEnabled() && (_dim1 <= 0 || _dim2 <= 0)) {
LOG.debug("Unknown dimensions for ConvolutionOp in refreshSizeInformation:" + op.name() + " " + _dim1 + " " + _dim2 + " img_dim=[" + params.N + " " + params.C + " " + params.H + " " + params.W + "]" + " filter_dim=[" + params.K + " " + params.C + " " + params.H + " " + params.W + "]" + " output_feature_map=[" + params.P + " " + params.Q + "] stride=[" + params.stride_h + " " + params.stride_w + "]" + " pad=[" + params.pad_h + " " + params.pad_w + "]");
}
}
Aggregations