use of org.apache.sysml.runtime.matrix.data.LibMatrixDNN.PoolingType in project incubator-systemml by apache.
the class ConvolutionGPUInstruction method processInstruction.
@Override
public void processInstruction(ExecutionContext ec) {
if (instOpcode.equalsIgnoreCase("bias_add") || instOpcode.equalsIgnoreCase("bias_multiply")) {
processBiasInstruction(instOpcode, ec);
return;
} else if (instOpcode.equalsIgnoreCase("relu_backward")) {
processReLUBackwardInstruction(ec);
return;
} else if (instOpcode.equalsIgnoreCase("channel_sums")) {
processChannelSumsInstruction(ec);
return;
}
GPUStatistics.incrementNoOfExecutedGPUInst();
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);
if (instOpcode.equalsIgnoreCase("conv2d")) {
MatrixObject image = getMatrixInputForGPUInstruction(ec, _input1.getName());
MatrixObject filter = getMatrixInputForGPUInstruction(ec, _input2.getName());
if (image.getNumRows() != N || image.getNumColumns() != C * H * W)
throw new DMLRuntimeException("Incorrect dimensions for image in conv2d");
if (filter.getNumRows() != K || filter.getNumColumns() != C * R * S)
throw new DMLRuntimeException("Incorrect dimensions for filter in conv2d");
MatrixObject out = getDenseMatrixOutputForGPUInstruction(ec, _output.getName(), N, K * P * Q);
LibMatrixCuDNN.conv2d(ec.getGPUContext(0), getExtendedOpcode(), image, filter, out, N, C, H, W, K, R, S, pad_h, pad_w, stride_h, stride_w, P, Q, _intermediateMemoryBudget);
} else if (instOpcode.equalsIgnoreCase("conv2d_bias_add")) {
MatrixObject image = getMatrixInputForGPUInstruction(ec, _input1.getName());
MatrixObject bias = getMatrixInputForGPUInstruction(ec, _input2.getName());
MatrixObject filter = getMatrixInputForGPUInstruction(ec, _input3.getName());
if (image.getNumRows() != N || image.getNumColumns() != C * H * W)
throw new DMLRuntimeException("Incorrect dimensions for image in conv2d");
if (filter.getNumRows() != K || filter.getNumColumns() != C * R * S)
throw new DMLRuntimeException("Incorrect dimensions for filter in conv2d");
MatrixObject out = getDenseMatrixOutputForGPUInstruction(ec, _output.getName(), N, K * P * Q);
LibMatrixCuDNN.conv2dBiasAdd(ec.getGPUContext(0), getExtendedOpcode(), image, bias, filter, out, N, C, H, W, K, R, S, pad_h, pad_w, stride_h, stride_w, P, Q, _intermediateMemoryBudget);
} else if (instOpcode.equalsIgnoreCase("conv2d_backward_filter")) {
MatrixObject image = getMatrixInputForGPUInstruction(ec, _input1.getName());
MatrixObject dout = getMatrixInputForGPUInstruction(ec, _input2.getName());
if (image.getNumRows() != N || image.getNumColumns() != C * H * W)
throw new DMLRuntimeException("Incorrect dimensions for image in conv2d_backward_filter");
if (dout.getNumRows() != N || dout.getNumColumns() != K * P * Q)
throw new DMLRuntimeException("Incorrect dimensions for dout in conv2d_backward_filter: " + dout.getNumRows() + " != " + N + " || " + dout.getNumColumns() + " != " + K * P * Q);
MatrixObject out = getDenseMatrixOutputForGPUInstruction(ec, _output.getName(), K, C * R * S);
LibMatrixCuDNN.conv2dBackwardFilter(ec.getGPUContext(0), getExtendedOpcode(), image, dout, out, N, C, H, W, K, R, S, pad_h, pad_w, stride_h, stride_w, P, Q, _intermediateMemoryBudget);
// TODO: For now always copy the device data to host
// ec.gpuCtx.copyDeviceToHost(outputBlock);
} else if (instOpcode.equalsIgnoreCase("conv2d_backward_data")) {
MatrixObject filter = getMatrixInputForGPUInstruction(ec, _input1.getName());
MatrixObject dout = getMatrixInputForGPUInstruction(ec, _input2.getName());
if (filter.getNumRows() != K || filter.getNumColumns() != C * R * S)
throw new DMLRuntimeException("Incorrect dimensions for filter in convolution_backward_data");
if (dout.getNumRows() != N || dout.getNumColumns() != K * P * Q)
throw new DMLRuntimeException("Incorrect dimensions for dout in conv2d_backward_data: " + dout.getNumRows() + " != " + N + " || " + dout.getNumColumns() + " != " + K * P * Q);
MatrixObject out = getDenseMatrixOutputForGPUInstruction(ec, _output.getName(), N, C * H * W);
LibMatrixCuDNN.conv2dBackwardData(ec.getGPUContext(0), getExtendedOpcode(), filter, dout, out, N, C, H, W, K, R, S, pad_h, pad_w, stride_h, stride_w, P, Q, _intermediateMemoryBudget);
} else if (instOpcode.equalsIgnoreCase("maxpooling") || instOpcode.equalsIgnoreCase("avgpooling")) {
MatrixObject image = getMatrixInputForGPUInstruction(ec, _input1.getName());
if (image.getNumRows() != N || image.getNumColumns() != C * H * W)
throw new DMLRuntimeException("Incorrect dimensions for image in maxpooling: " + image.getNumRows() + " != " + N + " || " + image.getNumColumns() + " != " + C * H * W);
MatrixObject out = getDenseMatrixOutputForGPUInstruction(ec, _output.getName(), N, C * P * Q);
PoolingType poolType = instOpcode.equalsIgnoreCase("maxpooling") ? PoolingType.MAX : PoolingType.AVG;
LibMatrixCuDNN.pooling(ec.getGPUContext(0), getExtendedOpcode(), image, out, N, C, H, W, K, R, S, pad_h, pad_w, stride_h, stride_w, P, Q, poolType, _intermediateMemoryBudget);
} else if (instOpcode.equalsIgnoreCase("maxpooling_backward") || instOpcode.equalsIgnoreCase("avgpooling_backward")) {
MatrixObject image = getMatrixInputForGPUInstruction(ec, _input1.getName());
MatrixObject dout = getMatrixInputForGPUInstruction(ec, _input2.getName());
MatrixObject maxPoolOutput = _input3 != null ? getMatrixInputForGPUInstruction(ec, _input3.getName()) : null;
if (dout.getNumRows() != N || dout.getNumColumns() != C * P * Q)
throw new DMLRuntimeException("Incorrect dimensions for dout in maxpooling_backward");
if (image.getNumRows() != N || image.getNumColumns() != C * H * W)
throw new DMLRuntimeException("Incorrect dimensions for image in maxpooling_backward: " + image.getNumRows() + " != " + N + " || " + image.getNumColumns() + " != " + K * P * Q);
MatrixObject out = getDenseMatrixOutputForGPUInstruction(ec, _output.getName(), N, C * H * W);
PoolingType poolType = instOpcode.equalsIgnoreCase("maxpooling_backward") ? PoolingType.MAX : PoolingType.AVG;
LibMatrixCuDNN.poolingBackward(ec.getGPUContext(0), getExtendedOpcode(), image, dout, maxPoolOutput, out, N, C, H, W, K, R, S, pad_h, pad_w, stride_h, stride_w, P, Q, poolType, _intermediateMemoryBudget);
} else {
throw new DMLRuntimeException("Unsupported GPU context for " + instOpcode);
}
// release inputs/outputs
ec.releaseMatrixInputForGPUInstruction(_input1.getName());
boolean isPool = instOpcode.equalsIgnoreCase("maxpooling") || instOpcode.equalsIgnoreCase("avgpooling");
boolean isPoolBackward = instOpcode.equalsIgnoreCase("maxpooling_backward") || instOpcode.equalsIgnoreCase("avgpooling_backward");
if (!isPool)
ec.releaseMatrixInputForGPUInstruction(_input2.getName());
if (instOpcode.equalsIgnoreCase("conv2d_bias_add") || (isPoolBackward && _input3 != null))
ec.releaseMatrixInputForGPUInstruction(_input3.getName());
ec.releaseMatrixOutputForGPUInstruction(_output.getName());
}
use of org.apache.sysml.runtime.matrix.data.LibMatrixDNN.PoolingType in project incubator-systemml by apache.
the class ConvolutionCPInstruction method processInstruction.
@Override
public void processInstruction(ExecutionContext ec) {
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;
} else if (instOpcode.equalsIgnoreCase("channel_sums")) {
processChannelSumsInstruction(ec);
return;
}
// acquire inputs
MatrixBlock outputBlock = null;
MatrixBlock matBlock = instOpcode.equalsIgnoreCase("avgpooling_backward") ? null : ec.getMatrixInput(input1.getName(), getExtendedOpcode());
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") || instOpcode.equalsIgnoreCase("avgpooling")) {
if (matBlock.isEmpty()) {
outputBlock = new MatrixBlock(N, C * P * Q, true);
} else {
outputBlock = new MatrixBlock(N, C * P * Q, false).allocateBlock();
PoolingType poolType = (instOpcode.equalsIgnoreCase("maxpooling") || instOpcode.equalsIgnoreCase("relu_maxpooling")) ? PoolingType.MAX : PoolingType.AVG;
if (instOpcode.equalsIgnoreCase("relu_maxpooling"))
params.minValForMaxPoolOperations = 0;
LibMatrixDNN.pooling(matBlock, outputBlock, params, poolType);
}
} else if (instOpcode.equalsIgnoreCase("maxpooling_backward") || instOpcode.equalsIgnoreCase("relu_maxpooling_backward") || instOpcode.equalsIgnoreCase("avgpooling_backward")) {
MatrixBlock dout = ec.getMatrixInput(_in2.getName(), getExtendedOpcode());
boolean isEmpty = instOpcode.equalsIgnoreCase("avgpooling_backward") ? dout.isEmpty() : (matBlock.isEmpty() || dout.isEmpty());
if (isEmpty) {
outputBlock = new MatrixBlock(N, C * H * W, true);
} else {
outputBlock = new MatrixBlock(N, C * H * W, false).allocateBlock();
PoolingType poolType = (instOpcode.equalsIgnoreCase("maxpooling_backward") || instOpcode.equalsIgnoreCase("relu_maxpooling_backward")) ? PoolingType.MAX : PoolingType.AVG;
boolean performReLUBackward = instOpcode.equalsIgnoreCase("relu_maxpooling_backward");
if (performReLUBackward)
params.minValForMaxPoolOperations = 0;
LibMatrixDNN.poolingBackward(matBlock, dout, outputBlock, params, performReLUBackward, poolType);
}
ec.releaseMatrixInput(_in2.getName(), getExtendedOpcode());
} else if (instOpcode.equalsIgnoreCase("conv2d")) {
resetNumThreads(params, C * R * S, P * Q, matBlock.getNonZeros() / (matBlock.getNumRows() * matBlock.getNumColumns()));
MatrixBlock filter = ec.getMatrixInput(_in2.getName(), getExtendedOpcode());
if (filter.isEmpty() || matBlock.isEmpty()) {
outputBlock = new MatrixBlock(N, K * P * Q, true);
} else {
boolean sparse = matBlock.isUltraSparse(false) && params.bias == null && matBlock.getInMemorySize() < MatrixBlock.estimateSizeDenseInMemory(N, K * P * Q);
outputBlock = new MatrixBlock(N, K * P * Q, sparse).allocateBlock();
if (params.enableNative && !isFilterSparse(filter) && !matBlock.isInSparseFormat())
LibMatrixNative.conv2d(matBlock, filter, outputBlock, params);
else
LibMatrixDNN.conv2d(matBlock, filter, outputBlock, params);
}
ec.releaseMatrixInput(_in2.getName(), getExtendedOpcode());
} else if (instOpcode.equalsIgnoreCase("conv2d_bias_add")) {
resetNumThreads(params, C * R * S, P * Q, matBlock.getNonZeros() / (matBlock.getNumRows() * matBlock.getNumColumns()));
MatrixBlock filter = ec.getMatrixInput(_in3.getName(), getExtendedOpcode());
MatrixBlock bias = ec.getMatrixInput(_in2.getName(), getExtendedOpcode());
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 = new MatrixBlock(N, K * P * Q, false).allocateBlock();
for (int n = 0; n < params.N; n++) ConvolutionUtils.fillBias(bias, outputBlock.getDenseBlockValues(), n, n + 1, params.N, params.K, params.P * params.Q);
} else {
outputBlock = new MatrixBlock(N, K * P * Q, false).allocateBlock();
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(), getExtendedOpcode());
ec.releaseMatrixInput(_in2.getName(), getExtendedOpcode());
} else if (instOpcode.equalsIgnoreCase("conv2d_backward_filter")) {
MatrixBlock dout = ec.getMatrixInput(_in2.getName(), getExtendedOpcode());
if (dout.isEmpty() || matBlock.isEmpty()) {
outputBlock = new MatrixBlock(K, C * R * S, true);
} else {
outputBlock = new MatrixBlock(K, C * R * S, false).allocateBlock();
if (params.enableNative && !matBlock.isInSparseFormat() && !dout.isInSparseFormat())
LibMatrixNative.conv2dBackwardFilter(matBlock, dout, outputBlock, params);
else
LibMatrixDNN.conv2dBackwardFilter(matBlock, dout, outputBlock, params);
}
ec.releaseMatrixInput(_in2.getName(), getExtendedOpcode());
} else if (instOpcode.equalsIgnoreCase("conv2d_backward_data")) {
MatrixBlock dout = ec.getMatrixInput(_in2.getName(), getExtendedOpcode());
if (dout.isEmpty() || matBlock.isEmpty()) {
outputBlock = new MatrixBlock(N, C * H * W, true);
} else {
outputBlock = new MatrixBlock(N, C * H * W, false).allocateBlock();
if (params.enableNative && !isFilterSparse(matBlock) && !dout.isInSparseFormat())
LibMatrixNative.conv2dBackwardData(matBlock, dout, outputBlock, params);
else
LibMatrixDNN.conv2dBackwardData(matBlock, dout, outputBlock, params);
}
ec.releaseMatrixInput(_in2.getName(), getExtendedOpcode());
} else {
throw new DMLRuntimeException("Unsupported op code " + instOpcode);
}
// release inputs/outputs
if (!instOpcode.equalsIgnoreCase("avgpooling_backward"))
ec.releaseMatrixInput(input1.getName(), getExtendedOpcode());
ec.setMatrixOutput(getOutputVariableName(), outputBlock, getExtendedOpcode());
}
Aggregations