# standard Job preamble, the only thing you'll typically 
# want to change in these first few lines is the "name" field
# to whatever you want, and the "namespace" field to match
# your project name
apiVersion: batch/v1
kind: Job
metadata:
  name: grid-search-batch-size
  namespace: 2265846lproject
# this is where you define the content of the Job
spec:
  # this controls how many times the pod created to run the container defined
  # below will be restarted if an error occurs. By default the container will
  # be restarted up to 6 times which probably isn't what you want!
  backoffLimit: 0
  template:        
    metadata:
      name: grid-search-batch-size
    spec:
      # in the "containers:" section you define the container(s) that
      # will run inside the Pod itself. Usually you'll just need one. 
      containers:
        # set a name for the container, which will be visible in the
        # CLI/web interface
      - name: job-container  
        # specify the image this container will be created from. 
        # in this example, we'll use the official NVIDIA Tensorflow images
        # from DockerHub (https://hub.docker.com/r/tensorflow/tensorflow)
        # these are handy because they come with Python included and optional
        # GPU support, controlled by tags. The tag "2.0.0-gpu-py3" used here
        # means we're getting:
        # - Tensorflow 2.0.0
        # - GPU support (CUDA libraries etc)
        # - Python 3
        image: lindronics/honours_project:v2
        
        command: 
          - "python3"
          - "nfs/honours_project/models/classification/gridsearch_batchsize.py"
          - "nfs/train.txt"
          - "nfs/test.txt"
          - "nfs/out"
          - "100"
        
        resources:
          # these are the hardware resources the container needs 
          # as a minimum in order to run. the pod won't be scheduled
          # (started) until enough resources become free to satisfy
          # these limits. You should set these high enough to ensure 
          # your job can run as intended, but if you make them too high
          # it could mean a longer wait before it can be started
          requests:
            # the "m" suffix here means "millicores", so 1 physical CPU
            # core = 1000m. this container requests 2000m = 2 physical cores
            cpu: "4000m" 
            # memory units are also defined by a suffix. typically this will
            # be "Mi" or "Gi" as appropriate
            memory: "32Gi"
            # GPUs are slightly different as they're not natively supported
            # by Kubernetes. This indicates that the container requires 1 
            # GPU in order to run
            nvidia.com/gpu: 1 
          # the limits section is identical to the requests section in its
          # structure, but rather than defining the minimum required resources 
          # for the container, it defines thresholds which if exceeded may lead
          # to the container being killed. e.g. say if this container had a 
          # memory leak in whatever code it was executing, it would become liable
          # to be killed once the memory usage went past 8 gigabytes.
          # The GPU limit is less important than the others because if you request
          # one GPU, the cluster will only allocate a single GPU to your container, 
          # and the others will not be visible to code inside it
          limits:
            cpu: "8000m" 
            memory: "32Gi"
            nvidia.com/gpu: 1 
        # this says "mount the external volume 'nfs-access' at the location /nfs
        # inside this container"
        volumeMounts:
        - mountPath: /nfs
          name: nfs-access
        # example of defining an environment variable and its value, so that they
        # will be visible inside this container
        env:
        - name: PYTHONPATH
          value: "/nfs/honours_project"
      # this defines a volume called nfs-access which corresponds to your cluster
      # filespace. 
      volumes:
      - name: nfs-access
        persistentVolumeClaim: 
          claimName: 2265846lvol1claim # XXX edit this!
      # in some cases you will want to run your job on a node with a specific type of
      # GPU. the nodeSelector section allows you to do this. The compute nodes each
      # have an annotation indicating the type of GPU they contain. The 2 lines below
      # tell the Kubernetes scheduler that this job must be scheduled on a node
      # where the value of the "node-role.ida/gpu2080ti" annotation is true, i.e. on
      # a node with RTX 2080 Ti GPUs. To do the equivalent for the RTX Titan nodes, 
      # change "gpu2080ti" to "gputitan"
      nodeSelector:
        node-role.ida/gpu2080ti: "true"
      # determines what Kubernetes will do if the container inside the 
      # pod fails to start or crashes. This just tells it to give up
      # without retrying.
      restartPolicy: Never
    