Search in sources :

Example 1 with PoolingType

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());
}
Also used : PoolingType(org.apache.sysml.runtime.matrix.data.LibMatrixDNN.PoolingType) MatrixObject(org.apache.sysml.runtime.controlprogram.caching.MatrixObject) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException)

Example 2 with PoolingType

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());
}
Also used : ConvolutionParameters(org.apache.sysml.runtime.matrix.data.ConvolutionParameters) PoolingType(org.apache.sysml.runtime.matrix.data.LibMatrixDNN.PoolingType) MatrixBlock(org.apache.sysml.runtime.matrix.data.MatrixBlock) DMLRuntimeException(org.apache.sysml.runtime.DMLRuntimeException)

Aggregations

DMLRuntimeException (org.apache.sysml.runtime.DMLRuntimeException)2 PoolingType (org.apache.sysml.runtime.matrix.data.LibMatrixDNN.PoolingType)2 MatrixObject (org.apache.sysml.runtime.controlprogram.caching.MatrixObject)1 ConvolutionParameters (org.apache.sysml.runtime.matrix.data.ConvolutionParameters)1 MatrixBlock (org.apache.sysml.runtime.matrix.data.MatrixBlock)1