{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"colab_type": "text",
"id": "view-in-github"
},
"source": [
""
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "G4yBrceuFbf3"
},
"source": [
"# ColabFold/AlphaFold2 Notebook\n",
"\n",
"\n",
"\n",
"## ColabFold v1.5.3: AlphaFold2 using MMseqs2\n",
"\n",
"Easy to use protein structure and complex prediction using [AlphaFold2](https://www.nature.com/articles/s41586-021-03819-2) and [Alphafold2-multimer](https://www.biorxiv.org/content/10.1101/2021.10.04.463034v1). Sequence alignments/templates are generated through [MMseqs2](mmseqs.com) and [HHsearch](https://github.com/soedinglab/hh-suite). For more details, see bottom of the notebook, checkout the [ColabFold GitHub](https://github.com/sokrypton/ColabFold) and read our manuscript.\n",
"Old versions: [v1.4](https://colab.research.google.com/github/sokrypton/ColabFold/blob/v1.4.0/AlphaFold2.ipynb), [v1.5.1](https://colab.research.google.com/github/sokrypton/ColabFold/blob/v1.5.1/AlphaFold2.ipynb), [v1.5.2](https://colab.research.google.com/github/sokrypton/ColabFold/blob/v1.5.2/AlphaFold2.ipynb)\n",
"\n",
"[Mirdita M, Schütze K, Moriwaki Y, Heo L, Ovchinnikov S, Steinegger M. ColabFold: Making protein folding accessible to all.\n",
"*Nature Methods*, 2022](https://www.nature.com/articles/s41592-022-01488-1)\n",
"\n",
"-----------\n",
"\n",
"### News\n",
"- 2023/07/31: The ColabFold MSA server is back to normal. It was using older DB (UniRef30 2202/PDB70 220313) from 27th ~8:30 AM CEST to 31st ~11:10 AM CEST.\n",
"- 2023/06/12: New databases! UniRef30 updated to 2023_02 and PDB to 230517. We now use PDB100 instead of PDB70 (see [notes](#pdb100)).\n",
"- 2023/06/12: We introduced a new default pairing strategy: Previously, for multimer predictions with more than 2 chains, we only pair if all sequences taxonomically match (\"complete\" pairing). The new default \"greedy\" strategy pairs any taxonomically matching subsets."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"collapsed": true,
"id": "kOblAo-xetgx",
"jupyter": {
"outputs_hidden": true
},
"outputId": "fd5d6895-cd56-4678-8e88-cb82cca50871"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"jobname test_a5e17\n",
"sequence PIAQIHILEGRSDEQKETLIREVSEAISRSLDAPLTSVRVIITEMAKGHFGIGGELASK\n",
"length 59\n"
]
}
],
"source": [
"# @title Input protein sequence(s), then hit `Runtime` -> `Run all` { display-mode: \"form\" }\n",
"from google.colab import files\n",
"import os\n",
"import re\n",
"import hashlib\n",
"import random\n",
"\n",
"from sys import version_info\n",
"python_version = f\"{version_info.major}.{version_info.minor}\"\n",
"\n",
"def add_hash(x,y):\n",
" return x+\"_\"+hashlib.sha1(y.encode()).hexdigest()[:5]\n",
"\n",
"query_sequence = 'PIAQIHILEGRSDEQKETLIREVSEAISRSLDAPLTSVRVIITEMAKGHFGIGGELASK' #@param {type:\"string\"}\n",
"#@markdown - Use `:` to specify inter-protein chainbreaks for **modeling complexes** (supports homo- and hetro-oligomers). For example **PI...SK:PI...SK** for a homodimer\n",
"jobname = 'test' #@param {type:\"string\"}\n",
"# number of models to use\n",
"num_relax = 0 #@param [0, 1, 5] {type:\"raw\"}\n",
"#@markdown - specify how many of the top ranked structures to relax using amber\n",
"template_mode = \"none\" #@param [\"none\", \"pdb100\",\"custom\"]\n",
"#@markdown - `none` = no template information is used. `pdb100` = detect templates in pdb100 (see [notes](#pdb100)). `custom` - upload and search own templates (PDB or mmCIF format, see [notes](#custom_templates))\n",
"\n",
"use_amber = num_relax > 0\n",
"\n",
"# remove whitespaces\n",
"query_sequence = \"\".join(query_sequence.split())\n",
"\n",
"basejobname = \"\".join(jobname.split())\n",
"basejobname = re.sub(r'\\W+', '', basejobname)\n",
"jobname = add_hash(basejobname, query_sequence)\n",
"\n",
"# check if directory with jobname exists\n",
"def check(folder):\n",
" if os.path.exists(folder):\n",
" return False\n",
" else:\n",
" return True\n",
"if not check(jobname):\n",
" n = 0\n",
" while not check(f\"{jobname}_{n}\"): n += 1\n",
" jobname = f\"{jobname}_{n}\"\n",
"\n",
"# make directory to save results\n",
"os.makedirs(jobname, exist_ok=True)\n",
"\n",
"# save queries\n",
"queries_path = os.path.join(jobname, f\"{jobname}.csv\")\n",
"with open(queries_path, \"w\") as text_file:\n",
" text_file.write(f\"id,sequence\\n{jobname},{query_sequence}\")\n",
"\n",
"if template_mode == \"pdb100\":\n",
" use_templates = True\n",
" custom_template_path = None\n",
"elif template_mode == \"custom\":\n",
" custom_template_path = os.path.join(jobname,f\"template\")\n",
" os.makedirs(custom_template_path, exist_ok=True)\n",
" uploaded = files.upload()\n",
" use_templates = True\n",
" for fn in uploaded.keys():\n",
" os.rename(fn,os.path.join(custom_template_path,fn))\n",
"else:\n",
" custom_template_path = None\n",
" use_templates = False\n",
"\n",
"print(\"jobname\",jobname)\n",
"print(\"sequence\",query_sequence)\n",
"print(\"length\",len(query_sequence.replace(\":\",\"\")))\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"collapsed": true,
"id": "AzIKiDiCaHAn",
"jupyter": {
"outputs_hidden": true
},
"outputId": "5b6b9ab0-af96-45ef-c903-43ae13525af0"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"installing colabfold...\n",
"CPU times: user 114 ms, sys: 27.2 ms, total: 142 ms\n",
"Wall time: 42.9 s\n"
]
}
],
"source": [
"# @title Install dependencies { display-mode: \"form\" }\n",
"%%time\n",
"import os\n",
"USE_AMBER = use_amber\n",
"USE_TEMPLATES = use_templates\n",
"PYTHON_VERSION = python_version\n",
"\n",
"if not os.path.isfile(\"COLABFOLD_READY\"):\n",
" print(\"installing colabfold...\")\n",
" os.system(\"pip install -q --no-warn-conflicts 'colabfold[alphafold-minus-jax] @ git+https://github.com/sokrypton/ColabFold'\")\n",
" os.system(\"pip install --upgrade dm-haiku\")\n",
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/colabfold colabfold\")\n",
" os.system(\"ln -s /usr/local/lib/python3.*/dist-packages/alphafold alphafold\")\n",
" # patch for jax > 0.3.25\n",
" os.system(\"sed -i 's/weights = jax.nn.softmax(logits)/logits=jnp.clip(logits,-1e8,1e8);weights=jax.nn.softmax(logits)/g' alphafold/model/modules.py\")\n",
" os.system(\"touch COLABFOLD_READY\")\n",
"\n",
"if USE_AMBER or USE_TEMPLATES:\n",
" if not os.path.isfile(\"CONDA_READY\"):\n",
" print(\"installing conda...\")\n",
" os.system(\"wget -qnc https://github.com/conda-forge/miniforge/releases/latest/download/Mambaforge-Linux-x86_64.sh\")\n",
" os.system(\"bash Mambaforge-Linux-x86_64.sh -bfp /usr/local\")\n",
" os.system(\"mamba config --set auto_update_conda false\")\n",
" os.system(\"touch CONDA_READY\")\n",
"\n",
"if USE_TEMPLATES and not os.path.isfile(\"HH_READY\") and USE_AMBER and not os.path.isfile(\"AMBER_READY\"):\n",
" print(\"installing hhsuite and amber...\")\n",
" os.system(f\"mamba install -y -c conda-forge -c bioconda kalign2=2.04 hhsuite=3.3.0 openmm=7.7.0 python='{PYTHON_VERSION}' pdbfixer\")\n",
" os.system(\"touch HH_READY\")\n",
" os.system(\"touch AMBER_READY\")\n",
"else:\n",
" if USE_TEMPLATES and not os.path.isfile(\"HH_READY\"):\n",
" print(\"installing hhsuite...\")\n",
" os.system(f\"mamba install -y -c conda-forge -c bioconda kalign2=2.04 hhsuite=3.3.0 python='{PYTHON_VERSION}'\")\n",
" os.system(\"touch HH_READY\")\n",
" if USE_AMBER and not os.path.isfile(\"AMBER_READY\"):\n",
" print(\"installing amber...\")\n",
" os.system(f\"mamba install -y -c conda-forge openmm=7.7.0 python='{PYTHON_VERSION}' pdbfixer\")\n",
" os.system(\"touch AMBER_READY\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "C2_sh2uAonJH"
},
"outputs": [],
"source": [
"#@markdown ### MSA options (custom MSA upload, single sequence, pairing mode)\n",
"msa_mode = \"mmseqs2_uniref_env\" #@param [\"mmseqs2_uniref_env\", \"mmseqs2_uniref\",\"single_sequence\",\"custom\"]\n",
"pair_mode = \"unpaired_paired\" #@param [\"unpaired_paired\",\"paired\",\"unpaired\"] {type:\"string\"}\n",
"#@markdown - \"unpaired_paired\" = pair sequences from same species + unpaired MSA, \"unpaired\" = seperate MSA for each chain, \"paired\" - only use paired sequences.\n",
"\n",
"# decide which a3m to use\n",
"if \"mmseqs2\" in msa_mode:\n",
" a3m_file = os.path.join(jobname,f\"{jobname}.a3m\")\n",
"\n",
"elif msa_mode == \"custom\":\n",
" a3m_file = os.path.join(jobname,f\"{jobname}.custom.a3m\")\n",
" if not os.path.isfile(a3m_file):\n",
" custom_msa_dict = files.upload()\n",
" custom_msa = list(custom_msa_dict.keys())[0]\n",
" header = 0\n",
" import fileinput\n",
" for line in fileinput.FileInput(custom_msa,inplace=1):\n",
" if line.startswith(\">\"):\n",
" header = header + 1\n",
" if not line.rstrip():\n",
" continue\n",
" if line.startswith(\">\") == False and header == 1:\n",
" query_sequence = line.rstrip()\n",
" print(line, end='')\n",
"\n",
" os.rename(custom_msa, a3m_file)\n",
" queries_path=a3m_file\n",
" print(f\"moving {custom_msa} to {a3m_file}\")\n",
"\n",
"else:\n",
" a3m_file = os.path.join(jobname,f\"{jobname}.single_sequence.a3m\")\n",
" with open(a3m_file, \"w\") as text_file:\n",
" text_file.write(\">1\\n%s\" % query_sequence)"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"id": "ADDuaolKmjGW"
},
"outputs": [],
"source": [
"# @title { display-mode: \"form\" }\n",
"#@markdown ### Advanced settings\n",
"model_type = \"auto\" #@param [\"auto\", \"alphafold2_ptm\", \"alphafold2_multimer_v1\", \"alphafold2_multimer_v2\", \"alphafold2_multimer_v3\"]\n",
"#@markdown - if `auto` selected, will use `alphafold2_ptm` for monomer prediction and `alphafold2_multimer_v3` for complex prediction.\n",
"#@markdown Any of the mode_types can be used (regardless if input is monomer or complex).\n",
"num_recycles = \"3\" #@param [\"auto\", \"0\", \"1\", \"3\", \"6\", \"12\", \"24\", \"48\"]\n",
"#@markdown - if `auto` selected, will use `num_recycles=20` if `model_type=alphafold2_multimer_v3`, else `num_recycles=3` .\n",
"recycle_early_stop_tolerance = \"auto\" #@param [\"auto\", \"0.0\", \"0.5\", \"1.0\"]\n",
"#@markdown - if `auto` selected, will use `tol=0.5` if `model_type=alphafold2_multimer_v3` else `tol=0.0`.\n",
"relax_max_iterations = 200 #@param [0, 200, 2000] {type:\"raw\"}\n",
"#@markdown - max amber relax iterations, `0` = unlimited (AlphaFold2 default, can take very long)\n",
"pairing_strategy = \"greedy\" #@param [\"greedy\", \"complete\"] {type:\"string\"}\n",
"#@markdown - `greedy` = pair any taxonomically matching subsets, `complete` = all sequences have to match in one line.\n",
"\n",
"\n",
"#@markdown #### Sample settings\n",
"#@markdown - enable dropouts and increase number of seeds to sample predictions from uncertainty of the model.\n",
"#@markdown - decrease `max_msa` to increase uncertainity\n",
"max_msa = \"auto\" #@param [\"auto\", \"512:1024\", \"256:512\", \"64:128\", \"32:64\", \"16:32\"]\n",
"num_seeds = 1 #@param [1,2,4,8,16] {type:\"raw\"}\n",
"use_dropout = False #@param {type:\"boolean\"}\n",
"\n",
"num_recycles = None if num_recycles == \"auto\" else int(num_recycles)\n",
"recycle_early_stop_tolerance = None if recycle_early_stop_tolerance == \"auto\" else float(recycle_early_stop_tolerance)\n",
"if max_msa == \"auto\": max_msa = None\n",
"\n",
"#@markdown #### Save settings\n",
"save_all = False #@param {type:\"boolean\"}\n",
"save_recycles = False #@param {type:\"boolean\"}\n",
"save_to_google_drive = False #@param {type:\"boolean\"}\n",
"#@markdown - if the save_to_google_drive option was selected, the result zip will be uploaded to your Google Drive\n",
"dpi = 200 #@param {type:\"integer\"}\n",
"#@markdown - set dpi for image resolution\n",
"\n",
"if save_to_google_drive:\n",
" from pydrive.drive import GoogleDrive\n",
" from pydrive.auth import GoogleAuth\n",
" from google.colab import auth\n",
" from oauth2client.client import GoogleCredentials\n",
" auth.authenticate_user()\n",
" gauth = GoogleAuth()\n",
" gauth.credentials = GoogleCredentials.get_application_default()\n",
" drive = GoogleDrive(gauth)\n",
" print(\"You are logged into Google Drive and are good to go!\")\n",
"\n",
"#@markdown Don't forget to hit `Runtime` -> `Run all` after updating the form."
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 1000
},
"collapsed": true,
"id": "mbaIO9pWjaN0",
"jupyter": {
"outputs_hidden": true
},
"outputId": "9beb72b5-c2a3-4e28-a80e-f9583095f4ff"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Downloading alphafold2 weights to .: 100%|██████████| 3.47G/3.47G [02:40<00:00, 23.2MB/s]\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2023-12-07 22:02:42,821 Unable to initialize backend 'rocm': NOT_FOUND: Could not find registered platform with name: \"rocm\". Available platform names are: CUDA\n",
"2023-12-07 22:02:42,823 Unable to initialize backend 'tpu': INTERNAL: Failed to open libtpu.so: libtpu.so: cannot open shared object file: No such file or directory\n",
"2023-12-07 22:02:44,726 Running on GPU\n",
"2023-12-07 22:02:44,904 Found 4 citations for tools or databases\n",
"2023-12-07 22:02:44,904 Query 1/1: test_a5e17 (length 59)\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"COMPLETE: 100%|██████████| 150/150 [elapsed: 00:01 remaining: 00:00]\n"
]
},
{
"data": {
"image/png": "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8Pfff+O///0vZs2ahSlTpohyDkMxSTVA4w4F/yISERFZAmc3R7zVNxi/fnUQe3848coktbQU1GNrHqv7AchEigPAycmp0DtOubq6QiaTISEhQa88ISEBnp75d7hNmTIFffv2xeDBgwEAderUQVpaGj788ENMmjQJUmnpzxBlkmoAJxcumiIiImrbsyF+/eogju++iPSnmbCxk5u0PQX12JpDT6opyOVyNGzYENHR0ejWrRsAQKvVIjo6GiNGjMj3mKdPn+ZJRGWynMxYEExztysmqURERGSQWg2rwMPXBQnxj3BizyW06tbApO0x655UqQCIONxfVBEREQgPD0ejRo3QuHFjLF26FGlpabrV/v369UOlSpUwb948AECXLl2wePFiNGjQQDfcP2XKFHTp0kWXrJY2JqlERERkEIlEgtbdX8eWZXtx6JfTJk9SzZnwwsr84sYxRK9evZCUlISpU6dCpVKhfv362LVrl24xVXx8vF7P6eTJkyGRSDB58mTcvXsXbm5u6NKlC+bMmVP8xhtJIpiqD7cMUavVUCqV+Omf+bB3sjV1c4iIiEzu7/O3MaL1QshtrPHDtTmwcyyZuxIVZ4eA3PfvlJSUQudxii333M6rbkNiW/xzC8/USB7mY5JrMRX2pBrAJjsLNlmm6fImIiIyJ7UD3FG5mivu3HyA05FnERL2eomc52DSIqOPTXuSLmJLjCOINNwvxg4BZQ038yciIiKDSSQStO1WHwCwb/tZk7bFnGmlArQyER4WmKSyJ5WIiIiM0vadevhu8V6c2HcVT1KewVFpmilxrd0+ybdcrVADmFy6jSHRMEklIiIio1QL9ELVAA/cik3A4Z0X0bH3GyZpR0FTAsxhuF8rBSQijFsLFjj2bYGXTERERGJp9059AMB+DvnnSyMVRHtYGvakEhERkdHadquPdfN349Sh60h+mAbniobd+KagoXoxcLi/bGOSSkREREbz8XdD9de88ffFe/gz8gK69Gtq0PHFWb2fqyQT3eLSygCJCfZJLQ843E9ERETFkrvKf/+vZ03aDnOklQqiPSwNe1KJiIioWNp2rYc1s//A2SM38CjxCVzcHUv1/Oa8cIqMxySViIiIisW7akUEvu6DK6dv4+Dv59F9UPNSPb85b0HF1f3GY5JKRERExdb2nfq4cvo29v96ttSTVHPuSc2ZkyrCHacs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\n",
"text/plain": [
""
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"2023-12-07 22:02:47,182 Setting max_seq=512, max_extra_seq=5120\n"
]
},
{
"ename": "KeyboardInterrupt",
"evalue": "ignored",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m\u001b[0m in \u001b[0;36m\u001b[0;34m()\u001b[0m\n\u001b[1;32m 63\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 64\u001b[0m \u001b[0mdownload_alphafold_params\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mmodel_type\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mPath\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\".\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 65\u001b[0;31m results = run(\n\u001b[0m\u001b[1;32m 66\u001b[0m \u001b[0mqueries\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mqueries\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 67\u001b[0m \u001b[0mresult_dir\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mresult_dir\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/content/colabfold/batch.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(queries, result_dir, num_models, is_complex, num_recycles, recycle_early_stop_tolerance, model_order, num_ensemble, model_type, msa_mode, use_templates, custom_template_path, num_relax, relax_max_iterations, relax_tolerance, relax_stiffness, relax_max_outer_iterations, keep_existing_results, rank_by, pair_mode, pairing_strategy, data_dir, host_url, user_agent, random_seed, num_seeds, recompile_padding, zip_results, prediction_callback, save_single_representations, save_pair_representations, save_all, save_recycles, use_dropout, use_gpu_relax, stop_at_score, dpi, max_seq, max_extra_seq, pdb_hit_file, local_pdb_path, use_cluster_profile, feature_dict_callback, **kwargs)\u001b[0m\n\u001b[1;32m 1568\u001b[0m \u001b[0mfirst_job\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;32mFalse\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1569\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1570\u001b[0;31m results = predict_structure(\n\u001b[0m\u001b[1;32m 1571\u001b[0m \u001b[0mprefix\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mjobname\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1572\u001b[0m \u001b[0mresult_dir\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mresult_dir\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/content/colabfold/batch.py\u001b[0m in \u001b[0;36mpredict_structure\u001b[0;34m(prefix, result_dir, feature_dict, is_complex, use_templates, sequences_lengths, pad_len, model_type, model_runner_and_params, num_relax, relax_max_iterations, relax_tolerance, relax_stiffness, relax_max_outer_iterations, rank_by, random_seed, num_seeds, stop_at_score, prediction_callback, use_gpu_relax, save_all, save_single_representations, save_pair_representations, save_recycles)\u001b[0m\n\u001b[1;32m 419\u001b[0m \u001b[0;31m# predict\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 420\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mrecycles\u001b[0m \u001b[0;34m=\u001b[0m\u001b[0;31m \u001b[0m\u001b[0;31m\\\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 421\u001b[0;31m model_runner.predict(input_features,\n\u001b[0m\u001b[1;32m 422\u001b[0m \u001b[0mrandom_seed\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mseed\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 423\u001b[0m \u001b[0mreturn_representations\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mreturn_representations\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/content/alphafold/model/model.py\u001b[0m in \u001b[0;36mpredict\u001b[0;34m(self, feat, random_seed, return_representations, callback)\u001b[0m\n\u001b[1;32m 183\u001b[0m \u001b[0;31m# run\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 184\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msub_key\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mjax\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mrandom\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msplit\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mkey\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 185\u001b[0;31m \u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprev\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrun\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0msub_key\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msub_feat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprev\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 186\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 187\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mreturn_representations\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/content/alphafold/model/model.py\u001b[0m in \u001b[0;36mrun\u001b[0;34m(key, feat, prev)\u001b[0m\n\u001b[1;32m 163\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mk\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0masarray\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mv\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfloat16\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 164\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mx\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 165\u001b[0;31m \u001b[0mresult\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_jnp_to_np\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapply\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkey\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m{\u001b[0m\u001b[0;34m**\u001b[0m\u001b[0mfeat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"prev\"\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mprev\u001b[0m\u001b[0;34m}\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 166\u001b[0m \u001b[0mprev\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mpop\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\"prev\"\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 167\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mresult\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprev\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
" \u001b[0;31m[... skipping hidden 1 frame]\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/pjit.py\u001b[0m in \u001b[0;36mcache_miss\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 254\u001b[0m \u001b[0;34m@\u001b[0m\u001b[0mapi_boundary\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 255\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcache_miss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 256\u001b[0;31m outs, out_flat, out_tree, args_flat, jaxpr = _python_pjit_helper(\n\u001b[0m\u001b[1;32m 257\u001b[0m fun, infer_params_fn, *args, **kwargs)\n\u001b[1;32m 258\u001b[0m \u001b[0mexecutable\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_read_most_recent_pjit_call_executable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mjaxpr\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/pjit.py\u001b[0m in \u001b[0;36m_python_pjit_helper\u001b[0;34m(fun, infer_params_fn, *args, **kwargs)\u001b[0m\n\u001b[1;32m 165\u001b[0m \u001b[0mdispatch\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcheck_arg\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0marg\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 166\u001b[0m \u001b[0;32mtry\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 167\u001b[0;31m \u001b[0mout_flat\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mpjit_p\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbind\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs_flat\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 168\u001b[0m \u001b[0;32mexcept\u001b[0m \u001b[0mpxla\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mDeviceAssignmentMismatchError\u001b[0m \u001b[0;32mas\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 169\u001b[0m \u001b[0mfails\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0me\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/core.py\u001b[0m in \u001b[0;36mbind\u001b[0;34m(self, *args, **params)\u001b[0m\n\u001b[1;32m 2654\u001b[0m top_trace = (top_trace if not axis_main or axis_main.level < top_trace.level\n\u001b[1;32m 2655\u001b[0m else axis_main.with_cur_sublevel())\n\u001b[0;32m-> 2656\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mbind_with_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtop_trace\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2657\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2658\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/core.py\u001b[0m in \u001b[0;36mbind_with_trace\u001b[0;34m(self, trace, args, params)\u001b[0m\n\u001b[1;32m 386\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 387\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mbind_with_trace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtrace\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 388\u001b[0;31m \u001b[0mout\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mtrace\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mprocess_primitive\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrace\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfull_raise\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0margs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 389\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mmap\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mfull_lower\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mself\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmultiple_results\u001b[0m \u001b[0;32melse\u001b[0m \u001b[0mfull_lower\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 390\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/core.py\u001b[0m in \u001b[0;36mprocess_primitive\u001b[0;34m(self, primitive, tracers, params)\u001b[0m\n\u001b[1;32m 866\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 867\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mprocess_primitive\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprimitive\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtracers\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 868\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mprimitive\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mimpl\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0mtracers\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 869\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 870\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mprocess_call\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mself\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mprimitive\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mf\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtracers\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/pjit.py\u001b[0m in \u001b[0;36m_pjit_call_impl\u001b[0;34m(jaxpr, in_shardings, out_shardings, resource_env, donated_invars, name, keep_unused, inline, *args)\u001b[0m\n\u001b[1;32m 1210\u001b[0m has_explicit_sharding = _pjit_explicit_sharding(\n\u001b[1;32m 1211\u001b[0m in_shardings, out_shardings, None, None)\n\u001b[0;32m-> 1212\u001b[0;31m return xc._xla.pjit(name, f, call_impl_cache_miss, [], [], donated_argnums,\n\u001b[0m\u001b[1;32m 1213\u001b[0m \u001b[0mtree_util\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mdispatch_registry\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1214\u001b[0m _get_cpp_global_cache(has_explicit_sharding))(*args)\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/pjit.py\u001b[0m in \u001b[0;36mcall_impl_cache_miss\u001b[0;34m(*args_, **kwargs_)\u001b[0m\n\u001b[1;32m 1194\u001b[0m donated_invars, name, keep_unused, inline):\n\u001b[1;32m 1195\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mcall_impl_cache_miss\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs_\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs_\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1196\u001b[0;31m out_flat, compiled = _pjit_call_impl_python(\n\u001b[0m\u001b[1;32m 1197\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0min_shardings\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0min_shardings\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1198\u001b[0m \u001b[0mout_shardings\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mout_shardings\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresource_env\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mresource_env\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/pjit.py\u001b[0m in \u001b[0;36m_pjit_call_impl_python\u001b[0;34m(jaxpr, in_shardings, out_shardings, resource_env, donated_invars, name, keep_unused, inline, *args)\u001b[0m\n\u001b[1;32m 1127\u001b[0m resource_env.physical_mesh if resource_env is not None else None)\n\u001b[1;32m 1128\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1129\u001b[0;31m compiled = _pjit_lower(\n\u001b[0m\u001b[1;32m 1130\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0min_shardings\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_shardings\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mresource_env\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1131\u001b[0m \u001b[0mdonated_invars\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mkeep_unused\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0minline\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/pjit.py\u001b[0m in \u001b[0;36m_pjit_lower\u001b[0;34m(jaxpr, in_shardings, out_shardings, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1258\u001b[0m \u001b[0min_shardings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mSameDeviceAssignmentTuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0min_shardings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mda\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1259\u001b[0m \u001b[0mout_shardings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mSameDeviceAssignmentTuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout_shardings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mda\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1260\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0m_pjit_lower_cached\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0min_shardings\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_shardings\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1261\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1262\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/pjit.py\u001b[0m in \u001b[0;36m_pjit_lower_cached\u001b[0;34m(jaxpr, sdat_in_shardings, sdat_out_shardings, resource_env, donated_invars, name, keep_unused, inline, lowering_parameters)\u001b[0m\n\u001b[1;32m 1297\u001b[0m lowering_parameters=lowering_parameters)\n\u001b[1;32m 1298\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1299\u001b[0;31m return pxla.lower_sharding_computation(\n\u001b[0m\u001b[1;32m 1300\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mapi_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0min_shardings\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mout_shardings\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1301\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdonated_invars\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtuple\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mjaxpr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0min_avals\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/profiler.py\u001b[0m in \u001b[0;36mwrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 338\u001b[0m \u001b[0;32mdef\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 339\u001b[0m \u001b[0;32mwith\u001b[0m \u001b[0mTraceAnnotation\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mdecorator_kwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 340\u001b[0;31m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0margs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0mkwargs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 341\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 342\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mwrapper\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/pxla.py\u001b[0m in \u001b[0;36mlower_sharding_computation\u001b[0;34m(fun_or_jaxpr, api_name, fun_name, in_shardings, out_shardings, donated_invars, global_in_avals, keep_unused, inline, devices_from_context, lowering_parameters)\u001b[0m\n\u001b[1;32m 2029\u001b[0m \u001b[0msemantic_out_shardings\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mSemanticallyEqualShardings\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mout_shardings\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2030\u001b[0m (module, keepalive, host_callbacks, unordered_effects, ordered_effects,\n\u001b[0;32m-> 2031\u001b[0;31m \u001b[0mnreps\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtuple_args\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mshape_poly_state\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0m_cached_lowering_to_hlo\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 2032\u001b[0m \u001b[0mclosed_jaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mapi_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfun_name\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mbackend\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0msemantic_in_shardings\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2033\u001b[0m \u001b[0msemantic_out_shardings\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mda_object\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/pxla.py\u001b[0m in \u001b[0;36m_cached_lowering_to_hlo\u001b[0;34m(closed_jaxpr, api_name, fun_name, backend, semantic_in_shardings, semantic_out_shardings, da_object, donated_invars, name_stack, all_default_mem_kind, lowering_parameters)\u001b[0m\n\u001b[1;32m 1830\u001b[0m \u001b[0;34m\"Finished jaxpr to MLIR module conversion {fun_name} in {elapsed_time} sec\"\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1831\u001b[0m fun_name=str(name_stack), event=dispatch.JAXPR_TO_MLIR_MODULE_EVENT):\n\u001b[0;32m-> 1832\u001b[0;31m lowering_result = mlir.lower_jaxpr_to_module(\n\u001b[0m\u001b[1;32m 1833\u001b[0m \u001b[0mmodule_name\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1834\u001b[0m \u001b[0mclosed_jaxpr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mlower_jaxpr_to_module\u001b[0;34m(module_name, jaxpr, ordered_effects, backend_or_name, platforms, axis_context, name_stack, donated_args, replicated_args, arg_shardings, result_shardings, arg_names, result_names, num_replicas, num_partitions, all_default_mem_kind, lowering_parameters)\u001b[0m\n\u001b[1;32m 804\u001b[0m \u001b[0mattrs\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m\"mhlo.num_partitions\"\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mi32_attr\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum_partitions\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 805\u001b[0m \u001b[0mreplace_tokens_with_dummy\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mlowering_parameters\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace_tokens_with_dummy\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m--> 806\u001b[0;31m lower_jaxpr_to_fun(\n\u001b[0m\u001b[1;32m 807\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m\"main\"\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mordered_effects\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mpublic\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mTrue\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 808\u001b[0m \u001b[0mcreate_tokens\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mreplace_tokens_with_dummy\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mlower_jaxpr_to_fun\u001b[0;34m(ctx, name, jaxpr, effects, create_tokens, public, replace_tokens_with_dummy, replicated_args, arg_shardings, result_shardings, use_sharding_annotations, input_output_aliases, num_output_tokens, api_name, arg_names, result_names, arg_memory_kinds, result_memory_kinds)\u001b[0m\n\u001b[1;32m 1211\u001b[0m \u001b[0mcallee_name_stack\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mname_stack\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mextend\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mutil\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mwrap_name\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mapi_name\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1212\u001b[0m \u001b[0mconsts\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mir_constants\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxla\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcanonicalize_dtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconsts\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1213\u001b[0;31m out_vals, tokens_out = jaxpr_subcomp(\n\u001b[0m\u001b[1;32m 1214\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mreplace\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mname_stack\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0mcallee_name_stack\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mtokens_in\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1215\u001b[0m consts, *args, dim_var_values=dim_var_values)\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mjaxpr_subcomp\u001b[0;34m(ctx, jaxpr, tokens, consts, dim_var_values, *args)\u001b[0m\n\u001b[1;32m 1429\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplatforms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1430\u001b[0m \u001b[0;31m# Classic, single-platform lowering\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1431\u001b[0;31m \u001b[0mans\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrule_ctx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mrule_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0meqn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1432\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1433\u001b[0m ans = lower_multi_platform(rule_ctx, str(eqn), rules,\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mf_lowered\u001b[0;34m(ctx, *args, **params)\u001b[0m\n\u001b[1;32m 1626\u001b[0m \u001b[0;31m# TODO(frostig,mattjj): check ctx.avals_out against jaxpr avals out?\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1627\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1628\u001b[0;31m out, tokens = jaxpr_subcomp(\n\u001b[0m\u001b[1;32m 1629\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodule_context\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtokens_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_ir_consts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconsts\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1630\u001b[0m *map(wrap_singleton_ir_values, args), dim_var_values=ctx.dim_var_values)\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mjaxpr_subcomp\u001b[0;34m(ctx, jaxpr, tokens, consts, dim_var_values, *args)\u001b[0m\n\u001b[1;32m 1429\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplatforms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1430\u001b[0m \u001b[0;31m# Classic, single-platform lowering\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1431\u001b[0;31m \u001b[0mans\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrule_ctx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mrule_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0meqn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1432\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1433\u001b[0m ans = lower_multi_platform(rule_ctx, str(eqn), rules,\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/lax/control_flow/loops.py\u001b[0m in \u001b[0;36m_while_lowering\u001b[0;34m(ctx, cond_jaxpr, body_jaxpr, cond_nconsts, body_nconsts, *args)\u001b[0m\n\u001b[1;32m 1670\u001b[0m body_consts = [mlir.ir_constants(xla.canonicalize_dtype(x))\n\u001b[1;32m 1671\u001b[0m for x in body_jaxpr.consts]\n\u001b[0;32m-> 1672\u001b[0;31m new_z, tokens_out = mlir.jaxpr_subcomp(body_ctx, body_jaxpr.jaxpr,\n\u001b[0m\u001b[1;32m 1673\u001b[0m tokens_in, body_consts, *(y + z), dim_var_values=ctx.dim_var_values)\n\u001b[1;32m 1674\u001b[0m \u001b[0mout_tokens\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0mtokens_out\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0meff\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0meff\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mbody_effects\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mjaxpr_subcomp\u001b[0;34m(ctx, jaxpr, tokens, consts, dim_var_values, *args)\u001b[0m\n\u001b[1;32m 1429\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplatforms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1430\u001b[0m \u001b[0;31m# Classic, single-platform lowering\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1431\u001b[0;31m \u001b[0mans\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrule_ctx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mrule_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0meqn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1432\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1433\u001b[0m ans = lower_multi_platform(rule_ctx, str(eqn), rules,\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mf_lowered\u001b[0;34m(ctx, *args, **params)\u001b[0m\n\u001b[1;32m 1626\u001b[0m \u001b[0;31m# TODO(frostig,mattjj): check ctx.avals_out against jaxpr avals out?\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1627\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1628\u001b[0;31m out, tokens = jaxpr_subcomp(\n\u001b[0m\u001b[1;32m 1629\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mmodule_context\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mtokens_in\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0m_ir_consts\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mconsts\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1630\u001b[0m *map(wrap_singleton_ir_values, args), dim_var_values=ctx.dim_var_values)\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mjaxpr_subcomp\u001b[0;34m(ctx, jaxpr, tokens, consts, dim_var_values, *args)\u001b[0m\n\u001b[1;32m 1429\u001b[0m \u001b[0;32mif\u001b[0m \u001b[0mlen\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mctx\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mplatforms\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m==\u001b[0m \u001b[0;36m1\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1430\u001b[0m \u001b[0;31m# Classic, single-platform lowering\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1431\u001b[0;31m \u001b[0mans\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mrule\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrule_ctx\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m*\u001b[0m\u001b[0mrule_inputs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0;34m**\u001b[0m\u001b[0meqn\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mparams\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 1432\u001b[0m \u001b[0;32melse\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1433\u001b[0m ans = lower_multi_platform(rule_ctx, str(eqn), rules,\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/lax/control_flow/loops.py\u001b[0m in \u001b[0;36m_while_lowering\u001b[0;34m(ctx, cond_jaxpr, body_jaxpr, cond_nconsts, body_nconsts, *args)\u001b[0m\n\u001b[1;32m 1632\u001b[0m \u001b[0mmlir\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mir_constants\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mxla\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mcanonicalize_dtype\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mcond_jaxpr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mconsts\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1633\u001b[0m ]\n\u001b[0;32m-> 1634\u001b[0;31m ((pred,),), _ = mlir.jaxpr_subcomp(\n\u001b[0m\u001b[1;32m 1635\u001b[0m \u001b[0mcond_ctx\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1636\u001b[0m \u001b[0mcond_jaxpr\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mjaxpr\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m/usr/local/lib/python3.10/dist-packages/jax/_src/interpreters/mlir.py\u001b[0m in \u001b[0;36mjaxpr_subcomp\u001b[0;34m(ctx, jaxpr, tokens, consts, dim_var_values, *args)\u001b[0m\n\u001b[1;32m 1313\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfunc_op\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1314\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m-> 1315\u001b[0;31m def jaxpr_subcomp(ctx: ModuleContext, jaxpr: core.Jaxpr,\n\u001b[0m\u001b[1;32m 1316\u001b[0m \u001b[0mtokens\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mTokenSet\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 1317\u001b[0m \u001b[0mconsts\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0mSequence\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mSequence\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0mir\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mValue\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m,\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mKeyboardInterrupt\u001b[0m: "
]
}
],
"source": [
"#@title Run Prediction\n",
"display_images = True #@param {type:\"boolean\"}\n",
"\n",
"import sys\n",
"import warnings\n",
"warnings.simplefilter(action='ignore', category=FutureWarning)\n",
"from Bio import BiopythonDeprecationWarning\n",
"warnings.simplefilter(action='ignore', category=BiopythonDeprecationWarning)\n",
"from pathlib import Path\n",
"from colabfold.download import download_alphafold_params, default_data_dir\n",
"from colabfold.utils import setup_logging\n",
"from colabfold.batch import get_queries, run, set_model_type\n",
"from colabfold.plot import plot_msa_v2\n",
"\n",
"import os\n",
"import numpy as np\n",
"try:\n",
" K80_chk = os.popen('nvidia-smi | grep \"Tesla K80\" | wc -l').read()\n",
"except:\n",
" K80_chk = \"0\"\n",
" pass\n",
"if \"1\" in K80_chk:\n",
" print(\"WARNING: found GPU Tesla K80: limited to total length < 1000\")\n",
" if \"TF_FORCE_UNIFIED_MEMORY\" in os.environ:\n",
" del os.environ[\"TF_FORCE_UNIFIED_MEMORY\"]\n",
" if \"XLA_PYTHON_CLIENT_MEM_FRACTION\" in os.environ:\n",
" del os.environ[\"XLA_PYTHON_CLIENT_MEM_FRACTION\"]\n",
"\n",
"from colabfold.colabfold import plot_protein\n",
"from pathlib import Path\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# For some reason we need that to get pdbfixer to import\n",
"if use_amber and f\"/usr/local/lib/python{python_version}/site-packages/\" not in sys.path:\n",
" sys.path.insert(0, f\"/usr/local/lib/python{python_version}/site-packages/\")\n",
"\n",
"def input_features_callback(input_features):\n",
" if display_images:\n",
" plot_msa_v2(input_features)\n",
" plt.show()\n",
" plt.close()\n",
"\n",
"def prediction_callback(protein_obj, length,\n",
" prediction_result, input_features, mode):\n",
" model_name, relaxed = mode\n",
" if not relaxed:\n",
" if display_images:\n",
" fig = plot_protein(protein_obj, Ls=length, dpi=150)\n",
" plt.show()\n",
" plt.close()\n",
"\n",
"result_dir = jobname\n",
"log_filename = os.path.join(jobname,\"log.txt\")\n",
"setup_logging(Path(log_filename))\n",
"\n",
"queries, is_complex = get_queries(queries_path)\n",
"model_type = set_model_type(is_complex, model_type)\n",
"\n",
"if \"multimer\" in model_type and max_msa is not None:\n",
" use_cluster_profile = False\n",
"else:\n",
" use_cluster_profile = True\n",
"\n",
"download_alphafold_params(model_type, Path(\".\"))\n",
"results = run(\n",
" queries=queries,\n",
" result_dir=result_dir,\n",
" use_templates=use_templates,\n",
" custom_template_path=custom_template_path,\n",
" num_relax=num_relax,\n",
" msa_mode=msa_mode,\n",
" model_type=model_type,\n",
" num_models=5,\n",
" num_recycles=num_recycles,\n",
" relax_max_iterations=relax_max_iterations,\n",
" recycle_early_stop_tolerance=recycle_early_stop_tolerance,\n",
" num_seeds=num_seeds,\n",
" use_dropout=use_dropout,\n",
" model_order=[1,2,3,4,5],\n",
" is_complex=is_complex,\n",
" data_dir=Path(\".\"),\n",
" keep_existing_results=False,\n",
" rank_by=\"auto\",\n",
" pair_mode=pair_mode,\n",
" pairing_strategy=pairing_strategy,\n",
" stop_at_score=float(100),\n",
" prediction_callback=prediction_callback,\n",
" dpi=dpi,\n",
" zip_results=False,\n",
" save_all=save_all,\n",
" max_msa=max_msa,\n",
" use_cluster_profile=use_cluster_profile,\n",
" input_features_callback=input_features_callback,\n",
" save_recycles=save_recycles,\n",
" user_agent=\"colabfold/google-colab-main\",\n",
")\n",
"results_zip = f\"{jobname}.result.zip\"\n",
"os.system(f\"zip -r {results_zip} {jobname}\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "KK7X9T44pWb7"
},
"outputs": [],
"source": [
"#@title Display 3D structure {run: \"auto\"}\n",
"import py3Dmol\n",
"import glob\n",
"import matplotlib.pyplot as plt\n",
"from colabfold.colabfold import plot_plddt_legend\n",
"from colabfold.colabfold import pymol_color_list, alphabet_list\n",
"rank_num = 1 #@param [\"1\", \"2\", \"3\", \"4\", \"5\"] {type:\"raw\"}\n",
"color = \"lDDT\" #@param [\"chain\", \"lDDT\", \"rainbow\"]\n",
"show_sidechains = False #@param {type:\"boolean\"}\n",
"show_mainchains = False #@param {type:\"boolean\"}\n",
"\n",
"tag = results[\"rank\"][0][rank_num - 1]\n",
"jobname_prefix = \".custom\" if msa_mode == \"custom\" else \"\"\n",
"pdb_filename = f\"{jobname}/{jobname}{jobname_prefix}_unrelaxed_{tag}.pdb\"\n",
"pdb_file = glob.glob(pdb_filename)\n",
"\n",
"def show_pdb(rank_num=1, show_sidechains=False, show_mainchains=False, color=\"lDDT\"):\n",
" model_name = f\"rank_{rank_num}\"\n",
" view = py3Dmol.view(js='https://3dmol.org/build/3Dmol.js',)\n",
" view.addModel(open(pdb_file[0],'r').read(),'pdb')\n",
"\n",
" if color == \"lDDT\":\n",
" view.setStyle({'cartoon': {'colorscheme': {'prop':'b','gradient': 'roygb','min':50,'max':90}}})\n",
" elif color == \"rainbow\":\n",
" view.setStyle({'cartoon': {'color':'spectrum'}})\n",
" elif color == \"chain\":\n",
" chains = len(queries[0][1]) + 1 if is_complex else 1\n",
" for n,chain,color in zip(range(chains),alphabet_list,pymol_color_list):\n",
" view.setStyle({'chain':chain},{'cartoon': {'color':color}})\n",
"\n",
" if show_sidechains:\n",
" BB = ['C','O','N']\n",
" view.addStyle({'and':[{'resn':[\"GLY\",\"PRO\"],'invert':True},{'atom':BB,'invert':True}]},\n",
" {'stick':{'colorscheme':f\"WhiteCarbon\",'radius':0.3}})\n",
" view.addStyle({'and':[{'resn':\"GLY\"},{'atom':'CA'}]},\n",
" {'sphere':{'colorscheme':f\"WhiteCarbon\",'radius':0.3}})\n",
" view.addStyle({'and':[{'resn':\"PRO\"},{'atom':['C','O'],'invert':True}]},\n",
" {'stick':{'colorscheme':f\"WhiteCarbon\",'radius':0.3}})\n",
" if show_mainchains:\n",
" BB = ['C','O','N','CA']\n",
" view.addStyle({'atom':BB},{'stick':{'colorscheme':f\"WhiteCarbon\",'radius':0.3}})\n",
"\n",
" view.zoomTo()\n",
" return view\n",
"\n",
"show_pdb(rank_num, show_sidechains, show_mainchains, color).show()\n",
"if color == \"lDDT\":\n",
" plot_plddt_legend().show()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "11l8k--10q0C"
},
"outputs": [],
"source": [
"#@title Plots {run: \"auto\"}\n",
"from IPython.display import display, HTML\n",
"import base64\n",
"from html import escape\n",
"\n",
"# see: https://stackoverflow.com/a/53688522\n",
"def image_to_data_url(filename):\n",
" ext = filename.split('.')[-1]\n",
" prefix = f'data:image/{ext};base64,'\n",
" with open(filename, 'rb') as f:\n",
" img = f.read()\n",
" return prefix + base64.b64encode(img).decode('utf-8')\n",
"\n",
"pae = image_to_data_url(os.path.join(jobname,f\"{jobname}{jobname_prefix}_pae.png\"))\n",
"cov = image_to_data_url(os.path.join(jobname,f\"{jobname}{jobname_prefix}_coverage.png\"))\n",
"plddt = image_to_data_url(os.path.join(jobname,f\"{jobname}{jobname_prefix}_plddt.png\"))\n",
"display(HTML(f\"\"\"\n",
"\n",
"
\n",
"
Plots for {escape(jobname)}
\n",
" \n",
" \n",
" \n",
"
\n",
"\"\"\"))\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {
"cellView": "form",
"id": "33g5IIegij5R"
},
"outputs": [],
"source": [
"#@title Package and download results\n",
"#@markdown If you are having issues downloading the result archive, try disabling your adblocker and run this cell again. If that fails click on the little folder icon to the left, navigate to file: `jobname.result.zip`, right-click and select \\\"Download\\\" (see [screenshot](https://pbs.twimg.com/media/E6wRW2lWUAEOuoe?format=jpg&name=small)).\n",
"\n",
"if msa_mode == \"custom\":\n",
" print(\"Don't forget to cite your custom MSA generation method.\")\n",
"\n",
"files.download(f\"{jobname}.result.zip\")\n",
"\n",
"if save_to_google_drive == True and drive:\n",
" uploaded = drive.CreateFile({'title': f\"{jobname}.result.zip\"})\n",
" uploaded.SetContentFile(f\"{jobname}.result.zip\")\n",
" uploaded.Upload()\n",
" print(f\"Uploaded {jobname}.result.zip to Google Drive with ID {uploaded.get('id')}\")"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "UGUBLzB3C6WN",
"pycharm": {
"name": "#%% md\n"
}
},
"source": [
"# Instructions \n",
"**Quick start**\n",
"1. Paste your protein sequence(s) in the input field.\n",
"2. Press \"Runtime\" -> \"Run all\".\n",
"3. The pipeline consists of 5 steps. The currently running step is indicated by a circle with a stop sign next to it.\n",
"\n",
"**Result zip file contents**\n",
"\n",
"1. PDB formatted structures sorted by avg. pLDDT and complexes are sorted by pTMscore. (unrelaxed and relaxed if `use_amber` is enabled).\n",
"2. Plots of the model quality.\n",
"3. Plots of the MSA coverage.\n",
"4. Parameter log file.\n",
"5. A3M formatted input MSA.\n",
"6. A `predicted_aligned_error_v1.json` using [AlphaFold-DB's format](https://alphafold.ebi.ac.uk/faq#faq-7) and a `scores.json` for each model which contains an array (list of lists) for PAE, a list with the average pLDDT and the pTMscore.\n",
"7. BibTeX file with citations for all used tools and databases.\n",
"\n",
"At the end of the job a download modal box will pop up with a `jobname.result.zip` file. Additionally, if the `save_to_google_drive` option was selected, the `jobname.result.zip` will be uploaded to your Google Drive.\n",
"\n",
"**MSA generation for complexes**\n",
"\n",
"For the complex prediction we use unpaired and paired MSAs. Unpaired MSA is generated the same way as for the protein structures prediction by searching the UniRef100 and environmental sequences three iterations each.\n",
"\n",
"The paired MSA is generated by searching the UniRef100 database and pairing the best hits sharing the same NCBI taxonomic identifier (=species or sub-species). We only pair sequences if all of the query sequences are present for the respective taxonomic identifier.\n",
"\n",
"**Using a custom MSA as input**\n",
"\n",
"To predict the structure with a custom MSA (A3M formatted): (1) Change the `msa_mode`: to \"custom\", (2) Wait for an upload box to appear at the end of the \"MSA options ...\" box. Upload your A3M. The first fasta entry of the A3M must be the query sequence without gaps.\n",
"\n",
"It is also possilbe to proide custom MSAs for complex predictions. Read more about the format [here](https://github.com/sokrypton/ColabFold/issues/76).\n",
"\n",
"As an alternative for MSA generation the [HHblits Toolkit server](https://toolkit.tuebingen.mpg.de/tools/hhblits) can be used. After submitting your query, click \"Query Template MSA\" -> \"Download Full A3M\". Download the A3M file and upload it in this notebook.\n",
"\n",
"**PDB100** \n",
"\n",
"As of 23/06/08, we have transitioned from using the PDB70 to a 100% clustered PDB, the PDB100. The construction methodology of PDB100 differs from that of PDB70.\n",
"\n",
"The PDB70 was constructed by running each PDB70 representative sequence through [HHblits](https://github.com/soedinglab/hh-suite) against the [Uniclust30](https://uniclust.mmseqs.com/). On the other hand, the PDB100 is built by searching each PDB100 representative structure with [Foldseek](https://github.com/steineggerlab/foldseek) against the [AlphaFold Database](https://alphafold.ebi.ac.uk).\n",
"\n",
"To maintain compatibility with older Notebook versions and local installations, the generated files and API responses will continue to be named \"PDB70\", even though we're now using the PDB100.\n",
"\n",
"**Using custom templates** \n",
"\n",
"To predict the structure with a custom template (PDB or mmCIF formatted): (1) change the `template_mode` to \"custom\" in the execute cell and (2) wait for an upload box to appear at the end of the \"Input Protein\" box. Select and upload your templates (multiple choices are possible).\n",
"\n",
"* Templates must follow the four letter PDB naming with lower case letters.\n",
"\n",
"* Templates in mmCIF format must contain `_entity_poly_seq`. An error is thrown if this field is not present. The field `_pdbx_audit_revision_history.revision_date` is automatically generated if it is not present.\n",
"\n",
"* Templates in PDB format are automatically converted to the mmCIF format. `_entity_poly_seq` and `_pdbx_audit_revision_history.revision_date` are automatically generated.\n",
"\n",
"If you encounter problems, please report them to this [issue](https://github.com/sokrypton/ColabFold/issues/177).\n",
"\n",
"**Comparison to the full AlphaFold2 and AlphaFold2 Colab**\n",
"\n",
"This notebook replaces the homology detection and MSA pairing of AlphaFold2 with MMseqs2. For a comparison against the [AlphaFold2 Colab](https://colab.research.google.com/github/deepmind/alphafold/blob/main/notebooks/AlphaFold.ipynb) and the full [AlphaFold2](https://github.com/deepmind/alphafold) system read our [paper](https://www.nature.com/articles/s41592-022-01488-1).\n",
"\n",
"**Troubleshooting**\n",
"* Check that the runtime type is set to GPU at \"Runtime\" -> \"Change runtime type\".\n",
"* Try to restart the session \"Runtime\" -> \"Factory reset runtime\".\n",
"* Check your input sequence.\n",
"\n",
"**Known issues**\n",
"* Google Colab assigns different types of GPUs with varying amount of memory. Some might not have enough memory to predict the structure for a long sequence.\n",
"* Your browser can block the pop-up for downloading the result file. You can choose the `save_to_google_drive` option to upload to Google Drive instead or manually download the result file: Click on the little folder icon to the left, navigate to file: `jobname.result.zip`, right-click and select \\\"Download\\\" (see [screenshot](https://pbs.twimg.com/media/E6wRW2lWUAEOuoe?format=jpg&name=small)).\n",
"\n",
"**Limitations**\n",
"* Computing resources: Our MMseqs2 API can handle ~20-50k requests per day.\n",
"* MSAs: MMseqs2 is very precise and sensitive but might find less hits compared to HHblits/HMMer searched against BFD or MGnify.\n",
"* We recommend to additionally use the full [AlphaFold2 pipeline](https://github.com/deepmind/alphafold).\n",
"\n",
"**Description of the plots**\n",
"* **Number of sequences per position** - We want to see at least 30 sequences per position, for best performance, ideally 100 sequences.\n",
"* **Predicted lDDT per position** - model confidence (out of 100) at each position. The higher the better.\n",
"* **Predicted Alignment Error** - For homooligomers, this could be a useful metric to assess how confident the model is about the interface. The lower the better.\n",
"\n",
"**Bugs**\n",
"- If you encounter any bugs, please report the issue to https://github.com/sokrypton/ColabFold/issues\n",
"\n",
"**License**\n",
"\n",
"The source code of ColabFold is licensed under [MIT](https://raw.githubusercontent.com/sokrypton/ColabFold/main/LICENSE). Additionally, this notebook uses the AlphaFold2 source code and its parameters licensed under [Apache 2.0](https://raw.githubusercontent.com/deepmind/alphafold/main/LICENSE) and [CC BY 4.0](https://creativecommons.org/licenses/by-sa/4.0/) respectively. Read more about the AlphaFold license [here](https://github.com/deepmind/alphafold).\n",
"\n",
"**Acknowledgments**\n",
"- We thank the AlphaFold team for developing an excellent model and open sourcing the software.\n",
"\n",
"- [KOBIC](https://kobic.re.kr) and [Söding Lab](https://www.mpinat.mpg.de/soeding) for providing the computational resources for the MMseqs2 MSA server.\n",
"\n",
"- Richard Evans for helping to benchmark the ColabFold's Alphafold-multimer support.\n",
"\n",
"- [David Koes](https://github.com/dkoes) for his awesome [py3Dmol](https://3dmol.csb.pitt.edu/) plugin, without whom these notebooks would be quite boring!\n",
"\n",
"- Do-Yoon Kim for creating the ColabFold logo.\n",
"\n",
"- A colab by Sergey Ovchinnikov ([@sokrypton](https://twitter.com/sokrypton)), Milot Mirdita ([@milot_mirdita](https://twitter.com/milot_mirdita)) and Martin Steinegger ([@thesteinegger](https://twitter.com/thesteinegger)).\n"
]
}
],
"metadata": {
"accelerator": "GPU",
"colab": {
"gpuType": "T4",
"include_colab_link": true,
"machine_shape": "hm",
"provenance": []
},
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.10"
}
},
"nbformat": 4,
"nbformat_minor": 4
}