package io.synor.compute;

/**
 * Options for 2D convolution operations.
 */
public class Conv2dOptions {
    private final int[] stride;
    private final int[] padding;
    private final Precision precision;
    private final ProcessorType processor;

    private Conv2dOptions(Builder builder) {
        this.stride = builder.stride;
        this.padding = builder.padding;
        this.precision = builder.precision;
        this.processor = builder.processor;
    }

    public int[] getStride() {
        return stride.clone();
    }

    public int[] getPadding() {
        return padding.clone();
    }

    public Precision getPrecision() {
        return precision;
    }

    public ProcessorType getProcessor() {
        return processor;
    }

    public static Builder builder() {
        return new Builder();
    }

    public static class Builder {
        private int[] stride = {1, 1};
        private int[] padding = {0, 0};
        private Precision precision = Precision.FP32;
        private ProcessorType processor = ProcessorType.AUTO;

        public Builder stride(int stride) {
            this.stride = new int[]{stride, stride};
            return this;
        }

        public Builder stride(int strideH, int strideW) {
            this.stride = new int[]{strideH, strideW};
            return this;
        }

        public Builder padding(int padding) {
            this.padding = new int[]{padding, padding};
            return this;
        }

        public Builder padding(int padH, int padW) {
            this.padding = new int[]{padH, padW};
            return this;
        }

        public Builder precision(Precision precision) {
            this.precision = precision;
            return this;
        }

        public Builder processor(ProcessorType processor) {
            this.processor = processor;
            return this;
        }

        public Conv2dOptions build() {
            return new Conv2dOptions(this);
        }
    }
}
