def build_dataset(dataset_name, root='root', transform=None, split='test', download=True, annotation_file=None,
                  language='en', task='zeroshot_classification', cupl=False, wds_cache_dir=None, **kwargs):
    """
    Main function to use in order to build a dataset instance,

    dataset_name: str
        name of the dataset

    root: str
        root folder where the dataset is downloaded and stored. can be shared among datasets.

    transform: torchvision transform applied to images

    split: str
        split to use, depending on the dataset can have different options.
        In general, `train` and `test` are available.
        For specific splits, please look at the corresponding dataset.

    annotation_file: str or None
        only for datasets with captions (used for retrieval) such as COCO
        and Flickr.
    """
    current_folder = os.path.dirname(__file__)
    if task in ('zeroshot_classification', 'linear_probe'):  # Only load templates and classnames if we have to
        classnames, templates = _load_classnames_and_classification_templates(dataset_name, current_folder, language)
    else:
        classnames, templates = None, None

    with open(os.path.join(current_folder, 'cupl_prompts.json'), 'r') as f:
        cupl_prompts = json.load(f)
    templates_cupl = None

    train = (split == 'train')
    if dataset_name == 'cifar10':
        ds = CIFAR10(root=root, train=train, transform=transform, download=download, **kwargs)
    elif dataset_name == 'cifar100':
        ds = CIFAR100(root=root, train=train, transform=transform, download=download, **kwargs)
    elif dataset_name == 'imagenet1k':
        if not os.path.exists(root):
            os.makedirs(root, exist_ok=True)
            call(
                f'wget https://image-net.org/data/ILSVRC/2012/ILSVRC2012_devkit_t12.tar.gz --output-document={root}/ILSVRC2012_devkit_t12.tar.gz',
                shell=True)
            call(
                f'wget https://image-net.org/data/ILSVRC/2012/ILSVRC2012_img_val.tar --output-document={root}/ILSVRC2012_img_val.tar',
                shell=True)

        ds = ImageNet(root=root, split='train' if train else 'val', transform=transform, **kwargs)
        # use classnames from OpenAI
        ds.classes = classnames['imagenet1k']
        templates_cupl = cupl_prompts['imagenet1k']
    elif dataset_name == 'imagenet1k-unverified':
        split = 'train' if train else 'val'
        ds = ImageFolder(root=os.path.join(root, split), transform=transform, **kwargs)
        # use classnames from OpenAI
        ds.classes = classnames['imagenet1k']
        templates_cupl = cupl_prompts['imagenet1k']
    elif dataset_name == 'imagenetv2':
        assert split == 'test', f'Only test split available for {dataset_name}'
        os.makedirs(root, exist_ok=True)
        ds = imagenetv2.ImageNetV2Dataset(variant='matched-frequency', transform=transform, location=root)
        ds.classes = classnames['imagenet1k']
        templates_cupl = cupl_prompts['imagenet1k']
    elif dataset_name == 'imagenet_sketch':
        assert split == 'test', f'Only test split available for {dataset_name}'
        # Downloadable from https://drive.google.com/open?id=1Mj0i5HBthqH1p_yeXzsg22gZduvgoNeA
        if not os.path.exists(root):
            # Automatic download
            print('Downloading imagenet_sketch...')
            if not has_gdown():
                print('GDown is needed to download the dataset. Please install it via `pip install gdown`')
                sys.exit(1)
            # Download ImageNet-Sketch.zip
            call('gdown --id 1Mj0i5HBthqH1p_yeXzsg22gZduvgoNeA', shell=True)
            assert os.path.exists('ImageNet-Sketch.zip')
            # Unzip and move to `root`
            call('unzip ImageNet-Sketch.zip', shell=True)
            call(f'mv sketch {root}', shell=True)
        ds = ImageFolder(root=root, transform=transform, **kwargs)
        ds.classes = classnames['imagenet1k']
        templates_cupl = cupl_prompts['imagenet1k']
    elif dataset_name == 'imagenet-a':
        assert split == 'test', f'Only test split available for {dataset_name}'
        # Downloadable from https://people.eecs.berkeley.edu/~hendrycks/imagenet-a.tar
        if not os.path.exists(root):
            print('Downloading imagenet-a...')
            call('wget https://people.eecs.berkeley.edu/~hendrycks/imagenet-a.tar', shell=True)
            # Untar and move to `root`
            call('tar xvf imagenet-a.tar', shell=True)
            call(f'mv imagenet-a {root}', shell=True)
        ds = ImageFolder(root=root, transform=transform, **kwargs)
        ds.classes = classnames['imagenet1k']
        imagenet_a_wnids = ['n01498041', 'n01531178', 'n01534433', 'n01558993', 'n01580077', 'n01614925', 'n01616318',
                            'n01631663', 'n01641577', 'n01669191', 'n01677366', 'n01687978', 'n01694178', 'n01698640',
                            'n01735189', 'n01770081', 'n01770393', 'n01774750', 'n01784675', 'n01819313', 'n01820546',
                            'n01833805', 'n01843383', 'n01847000', 'n01855672', 'n01882714', 'n01910747', 'n01914609',
                            'n01924916', 'n01944390', 'n01985128', 'n01986214', 'n02007558', 'n02009912', 'n02037110',
                            'n02051845', 'n02077923', 'n02085620', 'n02099601', 'n02106550', 'n02106662', 'n02110958',
                            'n02119022', 'n02123394', 'n02127052', 'n02129165', 'n02133161', 'n02137549', 'n02165456',
                            'n02174001', 'n02177972', 'n02190166', 'n02206856', 'n02219486', 'n02226429', 'n02231487',
                            'n02233338', 'n02236044', 'n02259212', 'n02268443', 'n02279972', 'n02280649', 'n02281787',
                            'n02317335', 'n02325366', 'n02346627', 'n02356798', 'n02361337', 'n02410509', 'n02445715',
                            'n02454379', 'n02486410', 'n02492035', 'n02504458', 'n02655020', 'n02669723', 'n02672831',
                            'n02676566', 'n02690373', 'n02701002', 'n02730930', 'n02777292', 'n02782093', 'n02787622',
                            'n02793495', 'n02797295', 'n02802426', 'n02814860', 'n02815834', 'n02837789', 'n02879718',
                            'n02883205', 'n02895154', 'n02906734', 'n02948072', 'n02951358', 'n02980441', 'n02992211',
                            'n02999410', 'n03014705', 'n03026506', 'n03124043', 'n03125729', 'n03187595', 'n03196217',
                            'n03223299', 'n03250847', 'n03255030', 'n03291819', 'n03325584', 'n03355925', 'n03384352',
                            'n03388043', 'n03417042', 'n03443371', 'n03444034', 'n03445924', 'n03452741', 'n03483316',
                            'n03584829', 'n03590841', 'n03594945', 'n03617480', 'n03666591', 'n03670208', 'n03717622',
                            'n03720891', 'n03721384', 'n03724870', 'n03775071', 'n03788195', 'n03804744', 'n03837869',
                            'n03840681', 'n03854065', 'n03888257', 'n03891332', 'n03935335', 'n03982430', 'n04019541',
                            'n04033901', 'n04039381', 'n04067472', 'n04086273', 'n04099969', 'n04118538', 'n04131690',
                            'n04133789', 'n04141076', 'n04146614', 'n04147183', 'n04179913', 'n04208210', 'n04235860',
                            'n04252077', 'n04252225', 'n04254120', 'n04270147', 'n04275548', 'n04310018', 'n04317175',
                            'n04344873', 'n04347754', 'n04355338', 'n04366367', 'n04376876', 'n04389033', 'n04399382',
                            'n04442312', 'n04456115', 'n04482393', 'n04507155', 'n04509417', 'n04532670', 'n04540053',
                            'n04554684', 'n04562935', 'n04591713', 'n04606251', 'n07583066', 'n07695742', 'n07697313',
                            'n07697537', 'n07714990', 'n07718472', 'n07720875', 'n07734744', 'n07749582', 'n07753592',
                            'n07760859', 'n07768694', 'n07831146', 'n09229709', 'n09246464', 'n09472597', 'n09835506',
                            'n11879895', 'n12057211', 'n12144580', 'n12267677']
        imagenet_a_mask = [wnid in set(imagenet_a_wnids) for wnid in all_imagenet_wordnet_ids]
        ds.classes = [cl for cl, mask in zip(ds.classes, imagenet_a_mask) if mask]
    elif dataset_name == 'imagenet-r':
        assert split == 'test', f'Only test split available for {dataset_name}'
        # downloadable from https://people.eecs.berkeley.edu/~hendrycks/imagenet-r.tar
        if not os.path.exists(root):
            print('Downloading imagenet-r...')
            call('wget https://people.eecs.berkeley.edu/~hendrycks/imagenet-r.tar', shell=True)
            # Untar and move to `root`
            call('tar xvf imagenet-r.tar', shell=True)
            call(f'mv imagenet-r {root}', shell=True)
        imagenet_r_wnids = {'n01443537', 'n01484850', 'n01494475', 'n01498041', 'n01514859', 'n01518878', 'n01531178',
                            'n01534433', 'n01614925', 'n01616318', 'n01630670', 'n01632777', 'n01644373', 'n01677366',
                            'n01694178', 'n01748264', 'n01770393', 'n01774750', 'n01784675', 'n01806143', 'n01820546',
                            'n01833805', 'n01843383', 'n01847000', 'n01855672', 'n01860187', 'n01882714', 'n01910747',
                            'n01944390', 'n01983481', 'n01986214', 'n02007558', 'n02009912', 'n02051845', 'n02056570',
                            'n02066245', 'n02071294', 'n02077923', 'n02085620', 'n02086240', 'n02088094', 'n02088238',
                            'n02088364', 'n02088466', 'n02091032', 'n02091134', 'n02092339', 'n02094433', 'n02096585',
                            'n02097298', 'n02098286', 'n02099601', 'n02099712', 'n02102318', 'n02106030', 'n02106166',
                            'n02106550', 'n02106662', 'n02108089', 'n02108915', 'n02109525', 'n02110185', 'n02110341',
                            'n02110958', 'n02112018', 'n02112137', 'n02113023', 'n02113624', 'n02113799', 'n02114367',
                            'n02117135', 'n02119022', 'n02123045', 'n02128385', 'n02128757', 'n02129165', 'n02129604',
                            'n02130308', 'n02134084', 'n02138441', 'n02165456', 'n02190166', 'n02206856', 'n02219486',
                            'n02226429', 'n02233338', 'n02236044', 'n02268443', 'n02279972', 'n02317335', 'n02325366',
                            'n02346627', 'n02356798', 'n02363005', 'n02364673', 'n02391049', 'n02395406', 'n02398521',
                            'n02410509', 'n02423022', 'n02437616', 'n02445715', 'n02447366', 'n02480495', 'n02480855',
                            'n02481823', 'n02483362', 'n02486410', 'n02510455', 'n02526121', 'n02607072', 'n02655020',
                            'n02672831', 'n02701002', 'n02749479', 'n02769748', 'n02793495', 'n02797295', 'n02802426',
                            'n02808440', 'n02814860', 'n02823750', 'n02841315', 'n02843684', 'n02883205', 'n02906734',
                            'n02909870', 'n02939185', 'n02948072', 'n02950826', 'n02951358', 'n02966193', 'n02980441',
                            'n02992529', 'n03124170', 'n03272010', 'n03345487', 'n03372029', 'n03424325', 'n03452741',
                            'n03467068', 'n03481172', 'n03494278', 'n03495258', 'n03498962', 'n03594945', 'n03602883',
                            'n03630383', 'n03649909', 'n03676483', 'n03710193', 'n03773504', 'n03775071', 'n03888257',
                            'n03930630', 'n03947888', 'n04086273', 'n04118538', 'n04133789', 'n04141076', 'n04146614',
                            'n04147183', 'n04192698', 'n04254680', 'n04266014', 'n04275548', 'n04310018', 'n04325704',
                            'n04347754', 'n04389033', 'n04409515', 'n04465501', 'n04487394', 'n04522168', 'n04536866',
                            'n04552348', 'n04591713', 'n07614500', 'n07693725', 'n07695742', 'n07697313', 'n07697537',
                            'n07714571', 'n07714990', 'n07718472', 'n07720875', 'n07734744', 'n07742313', 'n07745940',
                            'n07749582', 'n07753275', 'n07753592', 'n07768694', 'n07873807', 'n07880968', 'n07920052',
                            'n09472597', 'n09835506', 'n10565667', 'n12267677'}
        imagenet_r_mask = [wnid in imagenet_r_wnids for wnid in all_imagenet_wordnet_ids]
        ds = ImageFolder(root=root, transform=transform, **kwargs)
        ds.classes = classnames['imagenet1k']
        ds.classes = [cl for cl, mask in zip(ds.classes, imagenet_r_mask) if mask]
    elif dataset_name == 'imagenet-o':
        assert split == 'test', f'Only test split available for {dataset_name}'
        # downloadable from https://people.eecs.berkeley.edu/~hendrycks/imagenet-o.tar
        if not os.path.exists(root):
            print('Downloading imagenet-o...')
            call('wget https://people.eecs.berkeley.edu/~hendrycks/imagenet-o.tar', shell=True)
            # Untar and move to `root`
            call('tar xvf imagenet-o.tar', shell=True)
            call(f'mv imagenet-o {root}', shell=True)
        ds = ImageFolder(root=root, transform=transform, **kwargs)
        ds.classes = classnames['imagenet1k']
        imagenet_o_wnids = ['n01443537', 'n01704323', 'n01770081', 'n01784675', 'n01819313', 'n01820546', 'n01910747',
                            'n01917289', 'n01968897', 'n02074367', 'n02317335', 'n02319095', 'n02395406', 'n02454379',
                            'n02606052', 'n02655020', 'n02666196', 'n02672831', 'n02730930', 'n02777292', 'n02783161',
                            'n02786058', 'n02787622', 'n02791270', 'n02808304', 'n02817516', 'n02841315', 'n02865351',
                            'n02877765', 'n02892767', 'n02906734', 'n02910353', 'n02916936', 'n02948072', 'n02965783',
                            'n03000134', 'n03000684', 'n03017168', 'n03026506', 'n03032252', 'n03075370', 'n03109150',
                            'n03126707', 'n03134739', 'n03160309', 'n03196217', 'n03207743', 'n03218198', 'n03223299',
                            'n03240683', 'n03271574', 'n03291819', 'n03297495', 'n03314780', 'n03325584', 'n03344393',
                            'n03347037', 'n03372029', 'n03376595', 'n03388043', 'n03388183', 'n03400231', 'n03445777',
                            'n03457902', 'n03467068', 'n03482405', 'n03483316', 'n03494278', 'n03530642', 'n03544143',
                            'n03584829', 'n03590841', 'n03598930', 'n03602883', 'n03649909', 'n03661043', 'n03666591',
                            'n03676483', 'n03692522', 'n03706229', 'n03717622', 'n03720891', 'n03721384', 'n03724870',
                            'n03729826', 'n03733131', 'n03733281', 'n03742115', 'n03786901', 'n03788365', 'n03794056',
                            'n03804744', 'n03814639', 'n03814906', 'n03825788', 'n03840681', 'n03843555', 'n03854065',
                            'n03857828', 'n03868863', 'n03874293', 'n03884397', 'n03891251', 'n03908714', 'n03920288',
                            'n03929660', 'n03930313', 'n03937543', 'n03942813', 'n03944341', 'n03961711', 'n03970156',
                            'n03982430', 'n03991062', 'n03995372', 'n03998194', 'n04005630', 'n04023962', 'n04033901',
                            'n04040759', 'n04067472', 'n04074963', 'n04116512', 'n04118776', 'n04125021', 'n04127249',
                            'n04131690', 'n04141975', 'n04153751', 'n04154565', 'n04201297', 'n04204347', 'n04209133',
                            'n04209239', 'n04228054', 'n04235860', 'n04243546', 'n04252077', 'n04254120', 'n04258138',
                            'n04265275', 'n04270147', 'n04275548', 'n04330267', 'n04332243', 'n04336792', 'n04347754',
                            'n04371430', 'n04371774', 'n04372370', 'n04376876', 'n04409515', 'n04417672', 'n04418357',
                            'n04423845', 'n04429376', 'n04435653', 'n04442312', 'n04482393', 'n04501370', 'n04507155',
                            'n04525305', 'n04542943', 'n04554684', 'n04557648', 'n04562935', 'n04579432', 'n04591157',
                            'n04597913', 'n04599235', 'n06785654', 'n06874185', 'n07615774', 'n07693725', 'n07695742',
                            'n07697537', 'n07711569', 'n07714990', 'n07715103', 'n07716358', 'n07717410', 'n07718472',
                            'n07720875', 'n07742313', 'n07745940', 'n07747607', 'n07749582', 'n07753275', 'n07753592',
                            'n07754684', 'n07768694', 'n07836838', 'n07871810', 'n07873807', 'n07880968', 'n09229709',
                            'n09472597', 'n12144580', 'n12267677', 'n13052670']
        imagenet_o_mask = [wnid in set(imagenet_o_wnids) for wnid in all_imagenet_wordnet_ids]
        ds.classes = [cl for cl, mask in zip(ds.classes, imagenet_o_mask) if mask]
    elif dataset_name == 'objectnet':
        assert split == 'test', f'Only test split available for {dataset_name}'
        # downloadable from https://objectnet.dev/downloads/objectnet-1.0.zip or https://www.dropbox.com/s/raw/cxeztdtm16nzvuw/objectnet-1.0.zip
        if not os.path.exists(root):
            print('Downloading objectnet...')
            call('wget https://objectnet.dev/downloads/objectnet-1.0.zip', shell=True)
            # Untar and move to `root`
            call('UNZIP_DISABLE_ZIPBOMB_DETECTION=TRUE unzip -P objectnetisatestset objectnet-1.0.zip', shell=True)
            os.makedirs(root)
            call(f'mv objectnet-1.0 {root}', shell=True)
            call(f'cp {root}/objectnet-1.0/mappings/* {root}', shell=True)
        ds = objectnet.ObjectNetDataset(root=root, transform=transform)
    elif dataset_name == 'voc2007':
        ds = voc2007.PASCALVoc2007Cropped(root=root, set='train' if train else 'test', transform=transform,
                                          download=download, **kwargs)
    elif dataset_name == 'voc2007_multilabel':
        ds = voc2007.PASCALVoc2007(root=root, set='train' if train else 'test', transform=transform, download=download,
                                   **kwargs)
    elif dataset_name == 'mscoco_captions':
        # https://github.com/mehdidc/retrieval_annotations/releases/tag/1.0.0(annotations)
        if split == 'train':
            archive_name = 'train2014.zip'
        elif split in ('val', 'test'):
            archive_name = 'val2014.zip'
        else:
            raise ValueError(f'split should be train or val or test for `{dataset_name}`')
        root_split = os.path.join(root, archive_name.replace('.zip', ''))
        if not os.path.exists(root_split):
            print(f'Downloading mscoco_captions {archive_name}...')
            if not os.path.exists(os.path.join(root, archive_name)):
                call(f'wget http://images.cocodataset.org/zips/{archive_name} --output-document={root}/{archive_name}',
                     shell=True)
            call(f'unzip {root}/{archive_name} -d {root}', shell=True)
        if not annotation_file:
            annotation_file = f'{root}/coco_{split}_karpathy.json'
        if language == 'cn':
            annotation_file = f'{root}/coco-cn_{split}.json'
            root_split = root
            print(annotation_file)
        if not os.path.exists(annotation_file):
            call(
                f'wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/coco_{split}_karpathy.json --output-document={annotation_file}',
                shell=True)
        ds = CocoCaptions(root=root_split, annFile=annotation_file, transform=transform,
                          target_transform=pre_caption, **kwargs)
    elif dataset_name == 'multilingual_mscoco_captions':
        from clip_benchmark.datasets import multilingual_mscoco
        if (language not in multilingual_mscoco.SUPPORTED_LANGUAGES):
            raise ValueError('Unsupported language for multilingual_ms_coco:', language)

        def get_archive_name(target_split):
            if target_split == 'train':
                return 'train2014.zip'
            elif target_split in ('val', 'test'):
                return 'val2014.zip'
            else:
                raise ValueError(f'split should be train or val or test for `{dataset_name}`')

        def download_mscoco_split(target_split):
            archive_name = get_archive_name(target_split)
            root_split = os.path.join(root, archive_name.replace('.zip', ''))
            if not os.path.exists(root_split):
                print(f'Downloading mscoco_captions {archive_name}...')
                if not os.path.exists(os.path.join(root, archive_name)):
                    call(
                        f'wget http://images.cocodataset.org/zips/{archive_name} --output-document={root}/{archive_name}',
                        shell=True)
                call(f'unzip {root}/{archive_name} -d {root}', shell=True)

                # The multilingual MS-COCO uses images from various splits

        for target_split in ['train', 'val', 'test']:
            download_mscoco_split(target_split)

        annotation_file = os.path.join(root, multilingual_mscoco.CAPTIONS_FILE_NAME.format(language))
        # if (os.path.exists(annotation_file) == False):
        multilingual_mscoco.create_annotation_file(root, language)

        ds = multilingual_mscoco.Multilingual_MSCOCO(root=root, ann_file=annotation_file, transform=transform, **kwargs)
    elif dataset_name == 'flickr30k':
        # downloadable from https://www.kaggle.com/datasets/adityajn105/flickr30k
        # https://github.com/mehdidc/retrieval_annotations/releases/tag/1.0.0(annotations)
        # `kaggle datasets download -d adityajn105/flickr30k`
        if not os.path.exists(root):
            # Automatic download
            print('Downloading flickr30k...')
            if not has_kaggle():
                print('Kaggle is needed to download the dataset. Please install it via `pip install kaggle`')
                sys.exit(1)
            call('kaggle datasets download -d adityajn105/flickr30k', shell=True)
            call(f'unzip flickr30k.zip', shell=True)
            call(f'mv Images {root}', shell=True)
            call(f'mv captions.txt {root}', shell=True)
        if not annotation_file:
            annotation_file = f'{root}/flickr30k_{split}_karpathy.txt'
        if not os.path.exists(annotation_file):
            # Download Flickr30K Karpathy test set
            annotation_file = f'{root}/flickr30k_{split}_karpathy.txt'
            call(
                f'wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/flickr30k_{split}_karpathy.txt --output-document={annotation_file}',
                shell=True)
        if language == 'cn':
            annotation_file = f'{root}/flickr30k_cn_{split}.txt'
            print(annotation_file)
        ds = flickr.Flickr(root=f'{root}/Images', ann_file=annotation_file, transform=transform,
                           target_transform=pre_caption, **kwargs)
    elif dataset_name == 'flickr8k':
        # downloadable from https://www.kaggle.com/datasets/adityajn105/flickr8k
        # `kaggle datasets download -d adityajn105/flickr8k`
        # https://github.com/mehdidc/retrieval_annotations/releases/tag/1.0.0(annotations)
        if not os.path.exists(root):
            # Automatic download
            print('Downloading flickr8k...')
            if not has_kaggle():
                print('Kaggle is needed to download the dataset. Please install it via `pip install kaggle`')
                sys.exit(1)
            call('kaggle datasets download -d adityajn105/flickr8k', shell=True)
            call(f'unzip flickr8k.zip', shell=True)
            call(f'mv Images {root}', shell=True)
            call(f'mv captions.txt {root}', shell=True)
        if not annotation_file:
            annotation_file = f'{root}/flickr8k_{split}_karpathy.txt'
        if not os.path.exists(annotation_file):
            # Download Flickr8K Karpathy test set
            annotation_file = f'{root}/flickr8k_{split}_karpathy.txt'
            call(
                f'wget https://github.com/mehdidc/retrieval_annotations/releases/download/1.0.0/flickr8k_{split}_karpathy.txt --output-document={annotation_file}',
                shell=True)
        ds = flickr.Flickr(root=root, ann_file=annotation_file, transform=transform, **kwargs)
    elif dataset_name == 'food101':
        ds = Food101(root=root, split='train' if train else 'test', transform=transform, download=download, **kwargs)
        # we use the default class names, we just  replace "_" by spaces
        # to delimit words
        ds.classes = [cl.replace('_', ' ') for cl in ds.classes]
    elif dataset_name == 'sun397':
        warnings.warn(
            f'split argument ignored for `{dataset_name}`, there are no pre-defined train/test splits for this dataset')
        # we use the default class names, we just  replace "_" and "/" by spaces
        # to delimit words
        ds = SUN397(root=root, transform=transform, download=download, **kwargs)
        ds.classes = [cl.replace('_', ' ').replace('/', ' ') for cl in ds.classes]
    elif dataset_name == 'cars':
        ds = StanfordCars(root=root, split='train' if train else 'test', transform=transform, download=download,
                          **kwargs)
    elif dataset_name == 'fgvc_aircraft':
        ds = FGVCAircraft(root=root, annotation_level='variant', split='train' if train else 'test',
                          transform=transform, download=download, **kwargs)
    elif dataset_name == 'dtd':
        ds = DTD(root=root, split='train' if train else 'test', transform=transform, download=download, **kwargs)
    elif dataset_name == 'pets':
        ds = OxfordIIITPet(root=root, split='train' if train else 'test', target_types='category', transform=transform,
                           download=download, **kwargs)
    elif dataset_name == 'caltech101':
        warnings.warn(
            f'split argument ignored for `{dataset_name}`, there are no pre-defined train/test splits for this dataset')
        # broken download link (can't download google drive), fixed by this PR https://github.com/pytorch/vision/pull/5645
        # also available in "vtab/caltech101" using VTAB splits, we advice to use VTAB version rather than this one
        # since in this one (torchvision) there are no pre-defined test splits
        ds = caltech101.Caltech101(root=root, target_type='category', transform=transform, download=download, **kwargs)
        ds.classes = classnames['caltech101']
    elif dataset_name == 'flowers':
        ds = Flowers102(root=root, split='train' if train else 'test', transform=transform, download=download, **kwargs)
        # class indices started by 1 until it was fixed in  a  PR (#TODO link of the PR)
        # if older torchvision version, fix it using a target transform that decrements label index
        # TODO figure out minimal torchvision version needed instead of decrementing
        if ds[0][1] == 1:
            ds.target_transform = lambda y: y - 1
        ds.classes = classnames['flowers']
    elif dataset_name == 'birdsnap':
        ds = BirdsnapV2(root=root, split='train' if train else 'test', transform=transform, **kwargs)
        # ds.classes = ds.classes
    elif dataset_name == 'mnist':
        ds = MNIST(root=root, train=train, transform=transform, download=download, **kwargs)
        ds.classes = classnames['mnist']
    elif dataset_name == 'stl10':
        ds = STL10(root=root, split='train' if train else 'test', transform=transform, download=download, **kwargs)
    elif dataset_name == 'eurosat':
        warnings.warn(
            f'split argument ignored for `{dataset_name}`, there are no pre-defined train/test splits for this dataset')
        ds = EuroSAT(root=root, transform=transform, download=download, **kwargs)
        ds.classes = classnames['eurosat']
    elif dataset_name == 'gtsrb':
        ds = GTSRB(root=root, split='train' if train else 'test', transform=transform, download=download, **kwargs)
        ds.classes = classnames['gtsrb']
    elif dataset_name == 'country211':
        ds = Country211(root=root, split='train' if train else 'test', transform=transform, download=download, **kwargs)
        ds.classes = classnames['country211']
    elif dataset_name == 'pcam':
        # Dead link. Fixed by this PR on torchvision https://github.com/pytorch/vision/pull/5645
        # TODO figure out minimal torchvision version needed
        ds = PCAM(root=root, split='train' if train else 'test', transform=transform, download=download, **kwargs)
        ds.classes = classnames['pcam']
    elif dataset_name == 'renderedsst2':
        ds = RenderedSST2(root=root, split='train' if train else 'test', transform=transform, download=download,
                          **kwargs)
    elif dataset_name == 'fer2013':
        # Downloadable from  https://www.kaggle.com/datasets/msambare/fer2013
        # `kaggle datasets download -d msambare/fer2013`
        if not os.path.exists(root):
            # Automatic download
            print('Downloading fer2013...')
            if not has_kaggle():
                print('Kaggle is needed to download the dataset. Please install it via `pip install kaggle`')
                sys.exit(1)
            call('kaggle datasets download -d msambare/fer2013', shell=True)
            call(f'unzip fer2013.zip -d {root}', shell=True)
        root = os.path.join(root, 'train' if train else 'test')
        ds = ImageFolder(root=root, transform=transform)
        ds.classes = classnames['fer2013']
    elif dataset_name.startswith('tfds/'):
        # TFDS datasets support using `timm` and `tensorflow_datasets`
        prefix, *name_list = dataset_name.split('/')
        name = '/'.join(name_list)
        ds = build_tfds_dataset(name, download=download, split=split, data_dir=root, transform=transform)
    elif dataset_name.startswith('vtab/'):
        # VTAB datasets support using `tensorflow_datasets` and `task_adaptation`
        prefix, *name_list = dataset_name.split('/')
        name = '/'.join(name_list)
        ds = build_vtab_dataset(name, download=download, split=split, data_dir=root, transform=transform,
                                classnames=classnames)
    elif dataset_name.startswith('wds/'):
        # WebDataset support using `webdataset` library
        name = dataset_name.split('/', 1)[1]
        ds = build_wds_dataset(name, transform=transform, split=split, data_dir=root, cache_dir=wds_cache_dir)
        return ds
    elif dataset_name == 'dummy':
        ds = Dummy()
    else:
        raise ValueError(f'Unsupported dataset: {dataset_name}.')

    if cupl:
        ds.templates = templates_cupl
    else:
        ds.templates = templates

    return ds

    Main function to use in order to build a dataset instance,

    dataset_name: str
        name of the dataset

    root: str
        root folder where the dataset is downloaded and stored. can be shared among datasets.

    transform: torchvision transform applied to images

    split: str
        split to use, depending on the dataset can have different options.
        In general, `train` and `test` are available.
        For specific splits, please look at the corresponding dataset.

    annotation_file: str or None
        only for datasets with captions (used for retrieval) such as COCO
        and Flickr.
    
clip_benchmark/clip_benchmark/datasets/builder.py