diff --git a/condor/eval.sbatch b/condor/eval.sbatch
new file mode 100644
index 0000000000000000000000000000000000000000..5e2882807a0a42ede6f765200926135a5c092a0b
--- /dev/null
+++ b/condor/eval.sbatch
@@ -0,0 +1,14 @@
+#!/bin/bash
+#SBATCH -p big
+#SBATCH --time=24:00:00
+#SBATCH --nodes=1
+#SBATCH --gres=gpu:8
+#SBATCH --cpus-per-task=20
+#SBATCH --mem=400G
+#SBATCH --job-name=eval
+#SBATCH --output=slurm.out
+
+eval "$(conda shell.bash hook)"
+conda activate pytorch
+
+vitrun --nproc_per_node=8 ${@}
\ No newline at end of file
diff --git a/condor/eval_run.submit b/condor/eval_run.submit
index 8be080e45f32e42086db63a9f621b66a73136f6b..802d850f8ccadaac83f419834ad6115333193fd8 100644
--- a/condor/eval_run.submit
+++ b/condor/eval_run.submit
@@ -40,8 +40,8 @@ Rank = CUDAClockMhz * CUDAComputeUnits
 request_GPUs   = $(gpus)
 # this needs to be specified for the AI@Surrey cluster if requesting a GPU
 +GPUMem          = 10000  
-request_CPUs   = 12
-request_memory = 80G
+request_CPUs   = 60
+request_memory = 300G
 
 #This job will complete in less than 1 hour
 +JobRunTime = 20
diff --git a/pil_img.png b/pil_img.png
new file mode 100644
index 0000000000000000000000000000000000000000..37e0865aaa6a0ce9e546c1da08d4501679db3afe
Binary files /dev/null and b/pil_img.png differ
diff --git a/test_dl.ipynb b/test_dl.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/vitookit/datasets/ffcv_transform.py b/vitookit/datasets/ffcv_transform.py
index 036b5933a48720ea48be09229cb40f9f801a6363..bc93642b350feea76691e44d51f72bbdebd23a89 100644
--- a/vitookit/datasets/ffcv_transform.py
+++ b/vitookit/datasets/ffcv_transform.py
@@ -35,6 +35,45 @@ from torch import nn
 IMAGENET_MEAN = np.array([0.485, 0.456, 0.406]) * 255
 IMAGENET_STD = np.array([0.229, 0.224, 0.225]) * 255
 
+
+@gin.configurable
+def SimplePipeline(img_size=224,scale=(0.2,1), ratio=(3.0/4.0, 4.0/3.0),blur=False):
+    image_pipeline = [
+            RandomResizedCropRGBImageDecoder((img_size, img_size), scale=scale,ratio=ratio),
+            RandomHorizontalFlip(),
+            NormalizeImage(IMAGENET_MEAN, IMAGENET_STD, np.float16),
+            ToTensor(), 
+            ToDevice(torch.device('cuda')),        
+            ToTorchImage(),
+            ]
+    if blur:
+        image_pipeline.append(transforms.GaussianBlur(3))
+    label_pipeline = [IntDecoder(), ToTensor(),ToDevice(torch.device('cuda'))]
+    # Pipeline for each data field
+    pipelines = {
+        'image': image_pipeline,
+        'label': label_pipeline
+    } 
+    return pipelines    
+
+@gin.configurable
+def ValPipeline(img_size=224,ratio= 224/256):
+    image_pipeline = [
+            CenterCropRGBImageDecoder((img_size, img_size), ratio),
+            NormalizeImage(IMAGENET_MEAN, IMAGENET_STD, np.float16),
+            ToTensor(), 
+            ToDevice(torch.device('cuda')),        
+            ToTorchImage(),
+            ]
+    label_pipeline = [IntDecoder(), ToTensor(),ToDevice(torch.device('cuda')),View(-1)]
+    # Pipeline for each data field
+    pipelines = {
+        'image': image_pipeline,
+        'label': label_pipeline
+    } 
+    return pipelines  
+
+
 @njit(parallel=False, fastmath=True, inline="always")
 def apply_cj(
     im,
@@ -363,19 +402,14 @@ def convolution(image: np.ndarray, kernel: list | tuple, output: np.ndarray) ->
 
     pad_y = (m_k - 1) // 2
     pad_x = (n_k - 1) // 2
-    sub_matrix = image[:m_k, :n_k]
-    # center region
+    output.fill(0)
     for i in range(y_strides):
         for j in range(x_strides):
             for c in range(c_i): # looping over the all channels
-                sub_matrix = image[i:i+m_k, j:j+n_k,c]
-                output[i+pad_y,j+pad_x, c] = np.sum(sub_matrix * kernel)
-    # no filter for the padding region
-    output[:pad_y] = image[:pad_y]
-    output[-pad_y:] = image[-pad_y:]
-    output[:, :pad_x] = image[:, :pad_x]
-    output[:, -pad_x:] = image[:, -pad_x:]
-    
+                for k_i in range(m_k):
+                    for k_j in range(n_k):
+                        output[i+pad_y,j+pad_x,c] += image[i+k_i,j+k_j,c] * kernel[k_i,k_j]
+              
     return output
 
 
@@ -409,20 +443,36 @@ class ThreeAugmentation(Operation):
                         + 0.1140 * images[i, ..., 2:3]
                     )
                 else:
-                    sigma = np.random.uniform(radius_min, radius_max)                    
-                    kernel = generate_gaussian_filter(sigma,filter_shape=(5, 5))
+                    sigma = np.random.uniform(radius_min, radius_max)      
+                    kernel_width = int(3 * sigma)
+                    if kernel_width % 2 == 0:
+                        kernel_width = kernel_width + 1  # make sure kernel width only sth 3,5,7 etc
+                    kernel = generate_gaussian_filter(sigma,filter_shape=(kernel_width, kernel_width))
                     convolution(images[i], kernel, dst[i])
                     
             return dst
-        randchoice.is_parallel = True        
+        randchoice.parallel = True
         return randchoice
 
     def declare_state_and_memory(self, previous_state: State) -> Tuple[State, Optional[AllocationQuery]]:
         # No updates to state or extra memory necessary!
         mem_alloc = AllocationQuery(previous_state.shape,dtype=previous_state.dtype)
-        return previous_state, mem_alloc
+        return replace(previous_state,jit_mode=True), mem_alloc
+
+class RandomChoice(nn.Module):
+    """Apply single transformation randomly picked from a list. This transform does not support torchscript."""
+
+    def __init__(self, transforms, p=None):
+        super().__init__()
+        self.transforms = transforms
+        self.p = p
 
+    def __call__(self, *args):
+        t = random.choices(self.transforms, weights=self.p)[0]
+        return t(*args)
 
+    def __repr__(self) -> str:
+        return f"{super().__repr__()}(p={self.p})"
 
 @gin.configurable
 def ThreeAugmentPipeline(img_size=224,scale=(0.08,1), color_jitter=None):
@@ -434,14 +484,20 @@ def ThreeAugmentPipeline(img_size=224,scale=(0.08,1), color_jitter=None):
             [   RandomResizedCropRGBImageDecoder((img_size, img_size), scale=scale,),
                 RandomHorizontalFlip(),]+
             # second_tfl
-            [   ThreeAugmentation(),] +
+            # [   ThreeAugmentation(),] +
             (   [RandomColorJitter(jitter_prob=1, brightness=color_jitter, contrast=color_jitter, saturation=color_jitter, hue=0, seed=None)] if color_jitter else []) +
             # final_tfl
             [
-                NormalizeImage(IMAGENET_MEAN, IMAGENET_STD, np.float16),
+                NormalizeImage(IMAGENET_MEAN, IMAGENET_STD, np.float32),
                 ToTensor(), 
                 # ToDevice(torch.device('cuda')),        
                 ToTorchImage(),
+                # ThreeAugmentation()                
+                RandomChoice([
+                    tfms.RandomSolarize(0,1),
+                    tfms.RandomGrayscale(1),
+                    tfms.GaussianBlur(7,sigma=(0.1,2)),
+                ])
             ])
     label_pipeline = [IntDecoder(), ToTensor(),View(-1)]
     # Pipeline for each data field
diff --git a/vitookit/datasets/transform.py b/vitookit/datasets/transform.py
index 24f877c932987a09d0cdb08036bc7f785d16e4ad..5d017f75cf4b5ca98de5782c834a9706a391ed9f 100644
--- a/vitookit/datasets/transform.py
+++ b/vitookit/datasets/transform.py
@@ -6,48 +6,6 @@ from torchvision import transforms
 import torch
 import gin
 
-from ffcv.transforms import ToTensor, ToDevice, ToTorchImage, NormalizeImage,RandomHorizontalFlip,View
-from ffcv.fields.decoders import IntDecoder, RandomResizedCropRGBImageDecoder, SimpleRGBImageDecoder, CenterCropRGBImageDecoder
-
-IMAGENET_MEAN = np.array([0.485, 0.456, 0.406]) * 255
-IMAGENET_STD = np.array([0.229, 0.224, 0.225]) * 255
-
-@gin.configurable
-def SimplePipeline(img_size=224,scale=(0.2,1), ratio=(3.0/4.0, 4.0/3.0),blur=False):
-    image_pipeline = [
-            RandomResizedCropRGBImageDecoder((img_size, img_size), scale=scale,ratio=ratio),
-            RandomHorizontalFlip(),
-            NormalizeImage(IMAGENET_MEAN, IMAGENET_STD, np.float16),
-            ToTensor(), 
-            ToDevice(torch.device('cuda')),        
-            ToTorchImage(),
-            ]
-    if blur:
-        image_pipeline.append(transforms.GaussianBlur(3))
-    label_pipeline = [IntDecoder(), ToTensor(),ToDevice(torch.device('cuda'))]
-    # Pipeline for each data field
-    pipelines = {
-        'image': image_pipeline,
-        'label': label_pipeline
-    } 
-    return pipelines    
-
-@gin.configurable
-def ValPipeline(img_size=224,ratio= 224/256):
-    image_pipeline = [
-            CenterCropRGBImageDecoder((img_size, img_size), ratio),
-            NormalizeImage(IMAGENET_MEAN, IMAGENET_STD, np.float16),
-            ToTensor(), 
-            ToDevice(torch.device('cuda')),        
-            ToTorchImage(),
-            ]
-    label_pipeline = [IntDecoder(), ToTensor(),ToDevice(torch.device('cuda')),View(-1)]
-    # Pipeline for each data field
-    pipelines = {
-        'image': image_pipeline,
-        'label': label_pipeline
-    } 
-    return pipelines  
 
 class PermutePatch(object):
     """
diff --git a/vitookit/evaluation/eval_cls_ffcv.py b/vitookit/evaluation/eval_cls_ffcv.py
index 70a79f0645280dda6fffc0507d2f83c60317ed7b..e9d399e444dcfdcb9183162b93e563f2906ae6d4 100644
--- a/vitookit/evaluation/eval_cls_ffcv.py
+++ b/vitookit/evaluation/eval_cls_ffcv.py
@@ -25,25 +25,22 @@ import math
 import sys
 import copy
 import scipy.io as scio
-from vitookit.datasets.ffcv_transform import ThreeAugmentPipeline
-from vitookit.datasets.transform import ValPipeline, three_augmentation
+from vitookit.datasets.ffcv_transform import *
 from vitookit.utils.helper import *
 from vitookit.utils import misc
 from vitookit.models.build_model import build_model
-from vitookit.datasets import build_dataset
 import wandb
 
 from pathlib import Path
 from typing import Iterable, Optional
 from torch.nn import functional as F
 
-from timm.models import create_model
+
 from timm.loss import LabelSmoothingCrossEntropy, SoftTargetCrossEntropy
 from timm.scheduler import create_scheduler
 from timm.optim import create_optimizer
 from timm.utils import NativeScaler, get_state_dict, ModelEma, accuracy
-from timm.data import Mixup, create_transform
-from timm.data.constants import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD
+from timm.data import Mixup
 from timm.layers import trunc_normal_
 
 from ffcv import Loader
diff --git a/vitookit/evaluation/eval_linear_ffcv.py b/vitookit/evaluation/eval_linear_ffcv.py
index 143b6a8f7fa58120aa56fad70d9265dbdeb781bf..bbdb9f8e41afb6a674d807bdb2bfdf6f8a7419cf 100644
--- a/vitookit/evaluation/eval_linear_ffcv.py
+++ b/vitookit/evaluation/eval_linear_ffcv.py
@@ -19,7 +19,7 @@ import os
 import time
 from pathlib import Path
 
-import torch
+
 import torch.backends.cudnn as cudnn
 import wandb
 from vitookit.models.build_model import build_model
@@ -30,7 +30,7 @@ from vitookit.utils.helper import aug_parse, load_pretrained_weights, restart_fr
 from timm.models.layers import trunc_normal_
 
 from vitookit.utils.lars import LARS
-from vitookit.datasets.transform import SimplePipeline, ValPipeline
+from vitookit.datasets.ffcv_transform import SimplePipeline, ValPipeline
 from ffcv import Loader
 from ffcv.loader import OrderOption
 
@@ -126,7 +126,7 @@ def main(args):
     print('job dir: {}'.format(os.path.dirname(os.path.realpath(__file__))))
     print("{}".format(args).replace(', ', ',\n'))
 
-    
+    import torch
     device = torch.device(args.device)
 
     # fix the seed for reproducibility
diff --git a/vitookit/utils/helper.py b/vitookit/utils/helper.py
index 69c4fdf8f88cf259d2838d166a955ece526a7a4a..6eb89d34caed54147076ad52817fc6968338f512 100644
--- a/vitookit/utils/helper.py
+++ b/vitookit/utils/helper.py
@@ -24,7 +24,7 @@ def bool_flag(s):
 def aug_parse(parser: argparse.ArgumentParser):
     import yaml
     parser.add_argument('--no_resume',default=False,action='store_true',help="")
-    parser.add_argument('--cfgs', nargs='+',
+    parser.add_argument('--cfgs', nargs='+', default=[],
                         help='<Required> Config files *.gin.', required=False)
     parser.add_argument('--gin', nargs='+', 
                         help='Overrides config values. e.g. --gin "section.option=value"')