From 5214c6836e359887ea9638320c6290dca0bddbff Mon Sep 17 00:00:00 2001 From: Raphael Boige Date: Sat, 22 Apr 2023 19:49:06 +0200 Subject: [PATCH 01/55] feat: add sudoku --- README.md | 2 + docs/api/environments/sudoku.md | 8 + docs/env_anim/sudoku.gif | Bin 0 -> 39583 bytes docs/env_img/sudoku.png | Bin 0 -> 41100 bytes docs/environments/sudoku.md | 35 +++ examples/training.ipynb | 287 ++++++++++++++++-- jumanji/__init__.py | 2 + jumanji/environments/__init__.py | 1 + jumanji/environments/logic/sudoku/__init__.py | 16 + jumanji/environments/logic/sudoku/conftest.py | 27 ++ .../environments/logic/sudoku/constants.py | 28 ++ jumanji/environments/logic/sudoku/env.py | 204 +++++++++++++ jumanji/environments/logic/sudoku/env_test.py | 93 ++++++ .../environments/logic/sudoku/generator.py | 84 +++++ jumanji/environments/logic/sudoku/types.py | 45 +++ jumanji/environments/logic/sudoku/utils.py | 123 ++++++++ jumanji/environments/logic/sudoku/viewer.py | 167 ++++++++++ jumanji/training/configs/config.yaml | 2 +- jumanji/training/networks/__init__.py | 4 + jumanji/training/networks/sudoku/__init__.py | 13 + .../training/networks/sudoku/actor_critic.py | 95 ++++++ jumanji/training/networks/sudoku/random.py | 62 ++++ jumanji/training/setup_train.py | 14 + 23 files changed, 1280 insertions(+), 32 deletions(-) create mode 100644 docs/api/environments/sudoku.md create mode 100644 docs/env_anim/sudoku.gif create mode 100644 docs/env_img/sudoku.png create mode 100644 docs/environments/sudoku.md create mode 100644 jumanji/environments/logic/sudoku/__init__.py create mode 100644 jumanji/environments/logic/sudoku/conftest.py create mode 100644 jumanji/environments/logic/sudoku/constants.py create mode 100644 jumanji/environments/logic/sudoku/env.py create mode 100644 jumanji/environments/logic/sudoku/env_test.py create mode 100644 jumanji/environments/logic/sudoku/generator.py create mode 100644 jumanji/environments/logic/sudoku/types.py create mode 100644 jumanji/environments/logic/sudoku/utils.py create mode 100644 jumanji/environments/logic/sudoku/viewer.py create mode 100644 jumanji/training/networks/sudoku/__init__.py create mode 100644 jumanji/training/networks/sudoku/actor_critic.py create mode 100644 jumanji/training/networks/sudoku/random.py diff --git a/README.md b/README.md index fca9add9a..561e8592e 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,7 @@ RubiksCube Game2048 Minesweeper + Sudoku

@@ -81,6 +82,7 @@ problems. | πŸ”’ Game2048 | Logic | `Game2048-v0` | [code](https://github.com/instadeepai/jumanji/tree/main/jumanji/environments/logic/game_2048/) | [doc](https://instadeepai.github.io/jumanji/environments/game_2048/) | | πŸ’£ Minesweeper | Logic | `Minesweeper-v0` | [code](https://github.com/instadeepai/jumanji/tree/main/jumanji/environments/logic/minesweeper/) | [doc](https://instadeepai.github.io/jumanji/environments/minesweeper/) | | 🎲 RubiksCube | Logic | `RubiksCube-v0`
`RubiksCube-partly-scrambled-v0` | [code](https://github.com/instadeepai/jumanji/tree/main/jumanji/environments/logic/rubiks_cube/) | [doc](https://instadeepai.github.io/jumanji/environments/rubiks_cube/) | +| ✏️ Sudoku | Logic | `Sudoku-v0` | [code](https://github.com/instadeepai/jumanji/tree/main/jumanji/environments/logic/sudoku/) | [doc](https://instadeepai.github.io/jumanji/environments/sudoku/) | | πŸ“¦ BinPack (3D BinPacking Problem) | Packing | `BinPack-v1` | [code](https://github.com/instadeepai/jumanji/tree/main/jumanji/environments/packing/bin_pack/) | [doc](https://instadeepai.github.io/jumanji/environments/bin_pack/) | | 🏭 JobShop (Job Shop Scheduling Problem) | Packing | `JobShop-v0` | [code](https://github.com/instadeepai/jumanji/tree/main/jumanji/environments/packing/job_shop/) | [doc](https://instadeepai.github.io/jumanji/environments/job_shop/) | | πŸŽ’ Knapsack | Packing | `Knapsack-v1` | [code](https://github.com/instadeepai/jumanji/tree/main/jumanji/environments/packing/knapsack/) | [doc](https://instadeepai.github.io/jumanji/environments/knapsack/) | diff --git a/docs/api/environments/sudoku.md b/docs/api/environments/sudoku.md new file mode 100644 index 000000000..489e363cd --- /dev/null +++ b/docs/api/environments/sudoku.md @@ -0,0 +1,8 @@ +::: jumanji.environments.logic.sudoku.env.Sudoku + selection: + members: + - __init__ + - reset + - step + - observation_spec + - action_spec diff --git a/docs/env_anim/sudoku.gif b/docs/env_anim/sudoku.gif new file mode 100644 index 0000000000000000000000000000000000000000..b47a7689f2b67a7a2608675e72cfa288a9555745 GIT binary patch literal 39583 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%0A-_TXjENV#MW!(-6xRLhG z#qVvJns*A-RX;nXRFv1I^HNzvmi=TaUvHD5U`3_YXSK_Q3G^bS+7ov|>9cGGWApa3 z&!tA>-3|ZHm^VDmAE--n$*uY+H9pTW%k06&JZIglxqa#bF`1LjZWhLYd{Ql3Z5bb4 z2n!iy$$pzd{L3+}FCUf=9NjPTXoOCU)2INb{whn#k}K= zdh9lBoH;(^JwdeU1Iw8l$GhYtnfN*fh!c^7qzkgj*Sxa_B#);}vq*9$a!;#uPw$?9 zn}Jdhpkvgd`pjs*ddNxh_T0B; z8AN--_;s>m{3=W@R(_Gr#sqtIT5VL`_btsgT_6b;%@#-siVNJN zQt4Y%Z(3#A%V)Y6^Z*Pqc52c-K zmaIrn(W#eKYZG_SX`L&()B<=Qv~iZNknLn_8p`N5Z__%Ye!BwXRhGy*S*F#ZPIg3N zvwrDxib^n)hgwWFE313UR%cX2C8G5M+|8d+=hEL3U0bmD`u5ryL*&vkbya~moXH1afqmP^U9dJx5Il%^ThVrz^ei$ z+DB|!?l-6^6jYi!7xS1W-k7J1{|STd5+E=trIw0%cZQg1tW1*~t-^dm-%Xb%oEe+F z-g$FMOhi+(xnYs4zx%0lRUci8;_qG^_6ha$NqKmLv>(`F^dFkZ^GMAHwFH9 z$wBkre?oVC*qSrE_>ONc+Q4H`rL1oy9Hp}Br+9g6=1 z?uVkl`G6n2FZiF>erfMX-s!&QClrta0CM$i2E1EmR`=4MpA44^w06kb4!&DB^v}DM zV99tC8vW*<=H2n5qE)Aer3L@&)VyZqZVe~*cON6q#owuAcr(S$OpG+)@UW5+% + +

+ +We provide here a Jax JIT-able implementation of the +[Sudoku](https://en.wikipedia.org/wiki/Sudoku) puzzle game. + + +## Observation +The observation given to the agent consists of: + + +- `board`: jax array (int32) of shape (9,9): + empty cells are represented by -1, and filled cells are represented by 0-8. +- `action_mask`: jax array (bool) of shape (9,9,9): + indicates which actions are valid. + + + +## Action +The action space is a `MultiDiscreteArray` of integer values representing coordinates of the square +to explore and the digits to write in the cell, e.g. `[3, 6, 8]` for writing the digit `9` +the cell located on the third row and sixth column. + + +## Reward +The reward is `1` at the end of the episode if the board is correctly solved, and `0` in every +other case. + + +## Registered Versions πŸ“– +- `Sudoku-v0`, the classic [game](https://en.wikipedia.org/wiki/Sudoku) on +a 9x9 grid. diff --git a/examples/training.ipynb b/examples/training.ipynb index 4ac1e146c..18d39ae83 100644 --- a/examples/training.ipynb +++ b/examples/training.ipynb @@ -4,89 +4,314 @@ "cell_type": "code", "execution_count": 1, "metadata": { - "collapsed": true, - "jupyter": { - "outputs_hidden": true - } + "tags": [] + }, + "outputs": [], + "source": [ + "# pip install -e ../" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "tags": [] }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Note: you may need to restart the kernel to use updated packages.\n" + "env: JAX_PLATFORMS=cpu\n" ] } ], "source": [ - "%pip install --quiet -U pip -r ../requirements/requirements-training.txt ../." + "%env JAX_PLATFORMS=cpu" ] }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 26, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "WARNING:jax._src.lib.xla_bridge:No GPU/TPU found, falling back to CPU. (Set TF_CPP_MIN_LOG_LEVEL=0 and rerun for more info.)\n" - ] - } - ], + "outputs": [], "source": [ "import warnings\n", + "\n", "warnings.filterwarnings(\"ignore\")\n", "\n", - "from jumanji.training.train import train\n", - "from hydra import compose, initialize" + "from hydra import compose, initialize\n", + "\n", + "from jumanji.training.train import train" ] }, { "cell_type": "code", - "execution_count": 17, + "execution_count": 27, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, "outputs": [], "source": [ - "env = \"maze\" # @param ['bin_pack', 'cleaner', 'connector', 'cvrp', 'game_2048', 'job_shop', 'knapsack', 'maze', 'minesweeper', 'rubiks_cube', 'snake', 'tsp']\n", - "agent = \"random\" # @param ['random', 'a2c']" + "env = \"sudoku\" # @param ['bin_pack', 'cleaner', 'connector', 'cvrp', 'game_2048', 'job_shop', 'knapsack', 'maze', 'minesweeper', 'rubiks_cube', 'snake', \"sudoku\", 'tsp']\n", + "agent = \"a2c\" # @param ['random', 'a2c']" ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 28, "metadata": { "collapsed": false, "jupyter": { "outputs_hidden": false - } + }, + "tags": [] }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'agent': 'a2c', 'seed': 0, 'logger': {'type': 'terminal', 'save_checkpoint': True, 'name': '${agent}_${env.name}'}, 'env': {'name': 'sudoku', 'registered_version': 'Sudoku-v0', 'network': {'num_channels': 32, 'policy_layers': [64, 64], 'value_layers': [128, 128]}, 'training': {'num_epochs': 100, 'num_learner_steps_per_epoch': 500, 'n_steps': 20, 'total_batch_size': 128}, 'evaluation': {'eval_total_batch_size': 200, 'greedy_eval_total_batch_size': 200}, 'a2c': {'normalize_advantage': False, 'discount_factor': 0.997, 'bootstrapping_factor': 0.95, 'l_pg': 1.0, 'l_td': 1.0, 'l_en': 0.01, 'learning_rate': 0.0004}}}" + ] + }, + "execution_count": 28, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "with initialize(version_base=None, config_path=\"../jumanji/training/configs\"):\n", - " cfg = compose(config_name=\"config.yaml\", overrides=[f\"env={env}\", f\"agent={agent}\", \"logger.type=terminal\", \"logger.save_checkpoint=true\"])\n", + " cfg = compose(\n", + " config_name=\"config.yaml\",\n", + " overrides=[\n", + " f\"env={env}\",\n", + " f\"agent={agent}\",\n", + " \"logger.type=terminal\",\n", + " \"logger.save_checkpoint=true\",\n", + " ],\n", + " )\n", "cfg" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 29, + "metadata": { + "tags": [] + }, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:root:agent: a2c\n", + "seed: 0\n", + "logger:\n", + " type: terminal\n", + " save_checkpoint: true\n", + " name: ${agent}_${env.name}\n", + "env:\n", + " name: sudoku\n", + " registered_version: Sudoku-v0\n", + " network:\n", + " num_channels: 32\n", + " policy_layers:\n", + " - 64\n", + " - 64\n", + " value_layers:\n", + " - 128\n", + " - 128\n", + " training:\n", + " num_epochs: 100\n", + " num_learner_steps_per_epoch: 500\n", + " n_steps: 20\n", + " total_batch_size: 128\n", + " evaluation:\n", + " eval_total_batch_size: 200\n", + " greedy_eval_total_batch_size: 200\n", + " a2c:\n", + " normalize_advantage: false\n", + " discount_factor: 0.997\n", + " bootstrapping_factor: 0.95\n", + " l_pg: 1.0\n", + " l_td: 1.0\n", + " l_en: 0.01\n", + " learning_rate: 0.0004\n", + "\n", + "INFO:root:{'devices': [CpuDevice(id=0)]}\n", + "INFO:root:Experiment: a2c_sudoku.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "board (1, 9, 9)\n", + "embedding (1, 800)\n", + "(1, 9, 9, 9)\n", + "board (1, 9, 9)\n", + "embedding (1, 800)\n", + "(1, 9, 9, 9)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:root:Starting logger.\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "board (1, 9, 9)\n", + "embedding (1, 800)\n", + "(1, 9, 9, 9)\n", + "Tracedwith\n", + "Tracedwith\n", + "Tracedwith Tracedwith Tracedwith\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:root:Eval Stochastic >> Env Steps: 0.00e+00 | Episode Length: 31.815 | Episode Return: 0.000 | Time: 1.501\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "board (1, 9, 9)\n", + "embedding (1, 800)\n", + "(1, 9, 9, 9)\n", + "Tracedwith\n", + "Tracedwith\n", + "Tracedwith Tracedwith Tracedwith\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:root:Eval Greedy >> Env Steps: 0.00e+00 | Episode Length: 34.000 | Episode Return: 0.000 | Time: 0.827\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "board (128, 9, 9)\n", + "embedding (128, 800)\n", + "(128, 9, 9, 9)\n", + "Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0\n", + "Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0\n", + "Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0 Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0 Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0\n", + "board (128, 9, 9)\n", + "embedding (128, 800)\n", + "(128, 9, 9, 9)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:root:Train >> Env Steps: 0.00e+00 | Advantage: -0.000 | Critic Loss: 0.000 | Entropy: 3.029 | Entropy Loss: -3.029 | Policy Loss: -0.000 | Steps Per Second: 4,394 | Time: 291.278 | Total Loss: -0.030 | Value: 0.000\n", + "INFO:root:Eval Stochastic >> Env Steps: 1.28e+06 | Episode Length: 31.475 | Episode Return: 0.000 | Time: 0.211\n", + "INFO:root:Eval Greedy >> Env Steps: 1.28e+06 | Episode Length: 32.000 | Episode Return: 0.000 | Time: 0.001\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "board (128, 9, 9)\n", + "embedding (128, 800)\n", + "(128, 9, 9, 9)\n", + "Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0\n", + "Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0\n", + "Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0 Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0 Tracedwith with\n", + " val = Tracedwith\n", + " batch_dim = 0\n", + "board (128, 9, 9)\n", + "embedding (128, 800)\n", + "(128, 9, 9, 9)\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "INFO:root:Saving checkpoint...\n", + "INFO:root:Checkpoint saved at 'training_state'.\n", + "INFO:root:Closing logger...\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[29], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mtrain\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcfg\u001b[49m\u001b[43m)\u001b[49m\n", + "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/hydra/main.py:79\u001b[0m, in \u001b[0;36mmain..main_decorator..decorated_main\u001b[0;34m(cfg_passthrough)\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(task_function)\n\u001b[1;32m 77\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdecorated_main\u001b[39m(cfg_passthrough: Optional[DictConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[1;32m 78\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m cfg_passthrough \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m---> 79\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtask_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcfg_passthrough\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 80\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 81\u001b[0m args_parser \u001b[38;5;241m=\u001b[39m get_args_parser()\n", + "File \u001b[0;32m~/workspace/jumanji/jumanji/training/train.py:105\u001b[0m, in \u001b[0;36mtrain\u001b[0;34m(cfg, log_compiles)\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[38;5;66;03m# Training\u001b[39;00m\n\u001b[1;32m 104\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m train_timer:\n\u001b[0;32m--> 105\u001b[0m training_state, metrics \u001b[38;5;241m=\u001b[39m \u001b[43mepoch_fn\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtraining_state\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 106\u001b[0m logger\u001b[38;5;241m.\u001b[39mwrite(\n\u001b[1;32m 107\u001b[0m data\u001b[38;5;241m=\u001b[39mutils\u001b[38;5;241m.\u001b[39mfirst_from_device(metrics),\n\u001b[1;32m 108\u001b[0m label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtrain\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 109\u001b[0m env_steps\u001b[38;5;241m=\u001b[39menv_steps,\n\u001b[1;32m 110\u001b[0m )\n", + " \u001b[0;31m[... skipping hidden 1 frame]\u001b[0m\n", + "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/jax/_src/api.py:2256\u001b[0m, in \u001b[0;36m_cpp_pmap..cache_miss\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 2254\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(top_trace, core\u001b[38;5;241m.\u001b[39mEvalTrace):\n\u001b[1;32m 2255\u001b[0m execute \u001b[38;5;241m=\u001b[39m pxla\u001b[38;5;241m.\u001b[39mxla_pmap_impl_lazy(fun_, \u001b[38;5;241m*\u001b[39mtracers, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparams)\n\u001b[0;32m-> 2256\u001b[0m out \u001b[38;5;241m=\u001b[39m map_bind_continuation(\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mtracers\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[1;32m 2257\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 2258\u001b[0m out \u001b[38;5;241m=\u001b[39m map_bind_continuation(\n\u001b[1;32m 2259\u001b[0m pxla\u001b[38;5;241m.\u001b[39mxla_pmap_p\u001b[38;5;241m.\u001b[39mprocess(top_trace, fun_, tracers, params))\n", + "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/jax/_src/profiler.py:314\u001b[0m, in \u001b[0;36mannotate_function..wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 311\u001b[0m \u001b[38;5;129m@wraps\u001b[39m(func)\n\u001b[1;32m 312\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrapper\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 313\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m TraceAnnotation(name, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mdecorator_kwargs):\n\u001b[0;32m--> 314\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 315\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapper\n", + "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/jax/interpreters/pxla.py:2071\u001b[0m, in \u001b[0;36mExecuteReplicated.__call__\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 2069\u001b[0m out_bufs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_with_tokens(input_bufs)\n\u001b[1;32m 2070\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2071\u001b[0m out_bufs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mxla_executable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute_sharded_on_local_devices\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2072\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_bufs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2073\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m dispatch\u001b[38;5;241m.\u001b[39mneeds_check_special():\n\u001b[1;32m 2074\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m bufs \u001b[38;5;129;01min\u001b[39;00m out_bufs:\n", + "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + ] + } + ], "source": [ "train(cfg)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -105,7 +330,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.15" + "version": "3.10.9" } }, "nbformat": 4, diff --git a/jumanji/__init__.py b/jumanji/__init__.py index 53bd1438d..858d8fe01 100644 --- a/jumanji/__init__.py +++ b/jumanji/__init__.py @@ -42,6 +42,8 @@ kwargs={"time_limit": 20, "generator": partly_scrambled_rubiks_cube_generator}, ) +# Sudoku - the standard Sudoku puzzle with grid of size 9x9. +register(id="Sudoku-v0", entry_point="jumanji.environments:Sudoku") ### # Packing Environments diff --git a/jumanji/environments/__init__.py b/jumanji/environments/__init__.py index 68e66834b..bf72e6e42 100644 --- a/jumanji/environments/__init__.py +++ b/jumanji/environments/__init__.py @@ -18,6 +18,7 @@ from jumanji.environments.logic.game_2048.env import Game2048 from jumanji.environments.logic.minesweeper import Minesweeper from jumanji.environments.logic.rubiks_cube import RubiksCube +from jumanji.environments.logic.sudoku import Sudoku from jumanji.environments.packing import bin_pack, job_shop, knapsack from jumanji.environments.packing.bin_pack.env import BinPack from jumanji.environments.packing.job_shop.env import JobShop diff --git a/jumanji/environments/logic/sudoku/__init__.py b/jumanji/environments/logic/sudoku/__init__.py new file mode 100644 index 000000000..7f2bcfdf9 --- /dev/null +++ b/jumanji/environments/logic/sudoku/__init__.py @@ -0,0 +1,16 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from jumanji.environments.logic.sudoku.env import Sudoku +from jumanji.environments.logic.sudoku.types import Observation, State diff --git a/jumanji/environments/logic/sudoku/conftest.py b/jumanji/environments/logic/sudoku/conftest.py new file mode 100644 index 000000000..592f83b24 --- /dev/null +++ b/jumanji/environments/logic/sudoku/conftest.py @@ -0,0 +1,27 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import jax +import jax.numpy as jnp +import pytest + +from jumanji.environments.logic.sudoku.env import Sudoku +from jumanji.environments.logic.sudoku.generator import DummyGenerator +from jumanji.environments.logic.sudoku.types import State + + +@pytest.fixture +def sudoku_env() -> Sudoku: + """Fixture for a default sudoku environment with 10 rows and columns, and 10 mines.""" + return Sudoku(generator=DummyGenerator()) diff --git a/jumanji/environments/logic/sudoku/constants.py b/jumanji/environments/logic/sudoku/constants.py new file mode 100644 index 000000000..def31a100 --- /dev/null +++ b/jumanji/environments/logic/sudoku/constants.py @@ -0,0 +1,28 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +BOARD_WIDTH: int = 9 + + +BOX_IDX = [ + [0, 1, 2, 9, 10, 11, 18, 19, 20], + [27, 28, 29, 36, 37, 38, 45, 46, 47], + [54, 55, 56, 63, 64, 65, 72, 73, 74], + [3, 4, 5, 12, 13, 14, 21, 22, 23], + [30, 31, 32, 39, 40, 41, 48, 49, 50], + [57, 58, 59, 66, 67, 68, 75, 76, 77], + [6, 7, 8, 15, 16, 17, 24, 25, 26], + [33, 34, 35, 42, 43, 44, 51, 52, 53], + [60, 61, 62, 69, 70, 71, 78, 79, 80], +] diff --git a/jumanji/environments/logic/sudoku/env.py b/jumanji/environments/logic/sudoku/env.py new file mode 100644 index 000000000..04679f3d8 --- /dev/null +++ b/jumanji/environments/logic/sudoku/env.py @@ -0,0 +1,204 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Any, Optional, Sequence, Tuple + +import chex +import jax +import jax.numpy as jnp +import matplotlib + +from jumanji import Environment, specs +from jumanji.environments.logic.sudoku.constants import BOARD_WIDTH +from jumanji.environments.logic.sudoku.generator import DummyGenerator, Generator + +# from jumanji.environments.logic.sudoku.specs import ObservationSpec +from jumanji.environments.logic.sudoku.types import Observation, State +from jumanji.environments.logic.sudoku.utils import ( + apply_action, + update_action_mask, + validate_board, +) +from jumanji.environments.logic.sudoku.viewer import SudokuViewer +from jumanji.types import TimeStep, restart, termination, transition +from jumanji.viewer import Viewer + + +class Sudoku(Environment[State]): + """A JAX implementation of the sudoku game. + + - observation: `Observation` + - board: jax array (int32) of shape (9,9): + empty cells are represented by -1, and filled cells are represented by 0-8. + - action_mask: jax array (bool) of shape (9,9,9): + indicates which actions are valid. + + - action: + multi discrete array containing the square to write a digit, and the digits + to input. + + - reward: jax array (float32): + 1 at the end of the episode if the board is valid + 0 otherwise + + + - state: `State` + - board: jax array (int32) of shape (9,9): + empty cells are represented by -1, and filled cells are represented by 0-8. + + - action_mask: jax array (bool) of shape (9,9,9): + indicates which actions are valid (empty cells and valid digits). + + - key: jax array (int32) of shape (2,) used for seeding initial sudoku + configuration. + + ```python + from jumanji.environments import Sudoku + env = Sudoku() + key = jax.random.key(0) + state, timestep = jax.jit(env.reset)(key) + env.render(state) + action = env.action_spec().generate_value() + state, timestep = jax.jit(env.step)(state, action) + env.render(state) + ``` + """ + + def __init__( + self, + generator: Optional[Generator] = None, + viewer: Optional[Viewer[State]] = None, + ): + if generator is None: + generator = DummyGenerator() + + if viewer is None: + viewer = SudokuViewer() + + self._viewer = viewer + self._generator = generator + + def __repr__(self) -> str: + return f"Sudoku(grid_size={BOARD_WIDTH}x{BOARD_WIDTH})" + + def reset(self, key: chex.PRNGKey) -> Tuple[State, TimeStep]: + state = self._generator(key) + obs = Observation(board=state.board, action_mask=state.action_mask) + timestep = restart(observation=obs) + return state, timestep + + def step( + self, state: State, action: chex.Array + ) -> Tuple[State, TimeStep[Observation]]: + # check if action is valid + invalid = state.action_mask[action[0], action[1], action[2]] == 0 + updated_board = apply_action(action=action, board=state.board) + updated_action_mask = update_action_mask( + action_mask=state.action_mask, board=updated_board + ).astype(bool) + + winning = validate_board(updated_board) + # creating next state + next_state = State( + board=updated_board, action_mask=updated_action_mask, key=state.key + ) + + no_actions_avalaible = updated_action_mask.sum() == 0 + + # computing terminal condition + done = invalid | winning | no_actions_avalaible + reward = winning * 1.0 + + observation = Observation(board=updated_board, action_mask=updated_action_mask) + + timestep = jax.lax.cond( + done, + termination, + transition, + reward, + observation, + ) + + return next_state, timestep + + def observation_spec(self) -> specs.Spec[Observation]: + """Returns the observation spec containing the board and action_mask arrays. + + Returns: + Spec containing all the specifications for all the `Observation` fields: + - board: BoundedArray (jnp.int8) of shape (9,9). + - action_mask: BoundedArray (bool) of shape (9,9,9). + """ + + board = specs.BoundedArray( + shape=(BOARD_WIDTH, BOARD_WIDTH), + minimum=-1, + maximum=BOARD_WIDTH, + dtype=jnp.int32, + name="board", + ) + + action_mask = specs.BoundedArray( + shape=(BOARD_WIDTH, BOARD_WIDTH, BOARD_WIDTH), + dtype=bool, + minimum=0, + maximum=1, + name="action_mask", + ) + + return specs.Spec( + Observation, "ObservationSpec", board=board, action_mask=action_mask + ) + + def action_spec(self) -> specs.MultiDiscreteArray: + """Returns the action spec. An action is composed of 3 integers: the row index, + the column index and the value to be placed in the cell. + + Returns: + action_spec: `MultiDiscreteArray` object. + """ + return specs.MultiDiscreteArray( + num_values=jnp.array([BOARD_WIDTH, BOARD_WIDTH, BOARD_WIDTH], int), + name="action", + dtype=jnp.int32, + ) + + def render(self, state: State) -> Any: + """Renders the current state of the sudoku. + + Args: + state: the current state to be rendered. + """ + return self._viewer.render(state=state) + + def animate( + self, + states: Sequence[State], + interval: int = 200, + save_path: Optional[str] = None, + ) -> matplotlib.animation.FuncAnimation: + """Creates an animated gif of the board based on the sequence of states. + + Args: + states: a list of `State` objects representing the sequence of states. + interval: the delay between frames in milliseconds, default to 200. + save_path: the path where the animation file should be saved. If it is None, the plot + will not be saved. + + Returns: + animation.FuncAnimation: the animation object that was created. + """ + return self._viewer.animate( + states=states, interval=interval, save_path=save_path + ) diff --git a/jumanji/environments/logic/sudoku/env_test.py b/jumanji/environments/logic/sudoku/env_test.py new file mode 100644 index 000000000..328abe145 --- /dev/null +++ b/jumanji/environments/logic/sudoku/env_test.py @@ -0,0 +1,93 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + + +import chex +import jax +import matplotlib.animation +import matplotlib.pyplot as plt +import pytest +import pytest_mock +from jax import numpy as jnp + +from jumanji.environments.logic.sudoku.env import Sudoku +from jumanji.environments.logic.sudoku.types import State +from jumanji.testing.env_not_smoke import check_env_does_not_smoke +from jumanji.testing.pytrees import assert_is_jax_array_tree +from jumanji.types import TimeStep + + +def test_sudoku__reset(sudoku_env: Sudoku) -> None: + """Validates the jitted reset of the environment.""" + reset_fn = jax.jit(sudoku_env.reset) + key = jax.random.PRNGKey(0) + state, timestep = reset_fn(key) + assert isinstance(timestep, TimeStep) + assert isinstance(state, State) + + assert jnp.array_equal(state.board, timestep.observation.board) + # Check that the state is made of DeviceArrays, this is false for the non-jitted + # reset function since unpacking random.split returns numpy arrays and not device arrays. + assert_is_jax_array_tree(state) + + +def test_sudoku__step(sudoku_env: Sudoku) -> None: + """Validates the jitted step of the environment.""" + chex.clear_trace_counter() + step_fn = chex.assert_max_traces(sudoku_env.step, n=2) + step_fn = jax.jit(step_fn) + key = jax.random.PRNGKey(0) + state, timestep = jax.jit(sudoku_env.reset)(key) + # For this board, this action will be a non-mined square + action = sudoku_env.action_spec().generate_value() + next_state, next_timestep = step_fn(state, action) + + # Check that the state has changed + assert not jnp.array_equal(next_state.board, state.board) + assert jnp.array_equal(next_state.board, next_timestep.observation.board) + + # Check that the state is made of DeviceArrays, this is false for the non-jitted + # step function since unpacking random.split returns numpy arrays and not device arrays. + assert_is_jax_array_tree(next_state) + + next_next_state, next_next_timestep = step_fn(next_state, action) + + # Check that the state has changed, since we took the same action twice + assert jnp.array_equal(next_next_state.board, next_next_timestep.observation.board) + + +def test_sudoku__does_not_smoke(sudoku_env: Sudoku) -> None: + """Test that we can run an episode without any errors.""" + check_env_does_not_smoke(env=sudoku_env) + + +def test_sudoku__render(monkeypatch: pytest.MonkeyPatch, sudoku_env: Sudoku) -> None: + """Check that the render method builds the figure but does not display it.""" + monkeypatch.setattr(plt, "show", lambda fig: None) + state, timestep = jax.jit(sudoku_env.reset)(jax.random.PRNGKey(0)) + sudoku_env.render(state) + sudoku_env.close() + action = sudoku_env.action_spec().generate_value() + state, timestep = jax.jit(sudoku_env.step)(state, action) + sudoku_env.render(state) + sudoku_env.close() + + +def test_sudoku_animation( + sudoku_env: Sudoku, mocker: pytest_mock.MockerFixture +) -> None: + """Check that the animation method creates the animation correctly.""" + states = mocker.MagicMock() + animation = sudoku_env.animate(states) + assert isinstance(animation, matplotlib.animation.Animation) diff --git a/jumanji/environments/logic/sudoku/generator.py b/jumanji/environments/logic/sudoku/generator.py new file mode 100644 index 000000000..d04a3d9e8 --- /dev/null +++ b/jumanji/environments/logic/sudoku/generator.py @@ -0,0 +1,84 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License.i + +import abc + +import chex +import jax.numpy as jnp +import numpy as np + +from jumanji.environments.logic.sudoku.constants import BOARD_WIDTH +from jumanji.environments.logic.sudoku.types import State +from jumanji.environments.logic.sudoku.utils import update_action_mask + + +class Generator(abc.ABC): + @abc.abstractmethod + def __call__(self, key: chex.PRNGKey) -> State: + """Call method responsible for generating a new state. + + Args: + key: jax random key for any stochasticity used in the instance + generation process. + + Returns: + A Sudoku State. + """ + pass + + +# class CSVGenerator(Generator): +# def __init__(self, data_path: Path): +# self.data_path = data_path +# board = np.loadtxt(self.data_path, delimiter=",") +# action_mask = np.ma.make_mask(board) +# board = jnp.array(board, dtype=jnp.int8) - 1 +# action_mask = jnp.array(action_mask, dtype=jnp.int8) +# action_mask = 1 - jnp.expand_dims(action_mask, -1).repeat(BOARD_WIDTH, axis=-1) +# action_mask = update_action_mask(action_mask, board) + +# self.state = State(board=board, action_mask=action_mask) + +# def __call__(self, key: PRNGKey): +# return self.state + + +class DummyGenerator(Generator): + def __init__( + self, + ): + board = jnp.array( + [ + [7, 8, 0, 4, 0, 0, 1, 2, 0], + [6, 0, 0, 0, 7, 5, 0, 0, 9], + [0, 0, 0, 6, 0, 1, 0, 7, 8], + [0, 0, 7, 0, 4, 0, 2, 6, 0], + [0, 0, 1, 0, 5, 0, 9, 3, 0], + [9, 0, 4, 0, 6, 0, 0, 0, 5], + [0, 7, 0, 3, 0, 0, 0, 1, 2], + [1, 2, 0, 0, 0, 7, 4, 0, 0], + [0, 4, 9, 2, 0, 6, 0, 0, 7], + ] + ) + + action_mask = np.ma.make_mask(board) + board = jnp.array(board, dtype=jnp.int32) - 1 + action_mask = jnp.array(action_mask, dtype=jnp.int32) + action_mask = 1 - jnp.expand_dims(action_mask, -1).repeat(BOARD_WIDTH, axis=-1) + action_mask = update_action_mask(action_mask, board).astype(bool) + self._board = board + self._action_mask = action_mask + + def __call__(self, key: chex.PRNGKey): + return State(board=self._board, action_mask=self._action_mask, key=key) diff --git a/jumanji/environments/logic/sudoku/types.py b/jumanji/environments/logic/sudoku/types.py new file mode 100644 index 000000000..f1fdd3221 --- /dev/null +++ b/jumanji/environments/logic/sudoku/types.py @@ -0,0 +1,45 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import TYPE_CHECKING, NamedTuple + +import chex + +if TYPE_CHECKING: + from dataclasses import dataclass +else: + from chex import dataclass + + +@dataclass +class State: + """ + board: 2D-array of integers representing the board. + action_mask: 3D-array of booleans that indicates valid actions. + key: random key used for auto-reset. + """ + + board: chex.Array # (board_size, board_size) + action_mask: chex.Array # (board_size, board_size, board_size) + key: chex.PRNGKey # # (2,). + + +class Observation(NamedTuple): + """ + board: 2D-array of integers representing the board. + action_mask: 3D-array of booleans that indicates valid actions. + """ + + board: chex.Array # (board_size, board_size) + action_mask: chex.Array # (board_size, board_size, board_size) diff --git a/jumanji/environments/logic/sudoku/utils.py b/jumanji/environments/logic/sudoku/utils.py new file mode 100644 index 000000000..3d1b5e19b --- /dev/null +++ b/jumanji/environments/logic/sudoku/utils.py @@ -0,0 +1,123 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import chex +import jax +import jax.numpy as jnp + +from jumanji.environments.logic.sudoku.constants import BOARD_WIDTH, BOX_IDX + +# def create_board_csv(): +# board = [ +# [7, 8, 0, 4, 0, 0, 1, 2, 0], +# [6, 0, 0, 0, 7, 5, 0, 0, 9], +# [0, 0, 0, 6, 0, 1, 0, 7, 8], +# [0, 0, 7, 0, 4, 0, 2, 6, 0], +# [0, 0, 1, 0, 5, 0, 9, 3, 0], +# [9, 0, 4, 0, 6, 0, 0, 0, 5], +# [0, 7, 0, 3, 0, 0, 0, 1, 2], +# [1, 2, 0, 0, 0, 7, 4, 0, 0], +# [0, 4, 9, 2, 0, 6, 0, 0, 7], +# ] +# np.savetxt("test_puzzle.csv", board, delimiter=",") + + +# def create_board_csv(): +# board = [ +# [0, 0, 0, 8, 0, 1, 0, 0, 0], +# [0, 0, 0, 0, 0, 0, 0, 4, 3], +# [5, 0, 0, 0, 0, 0, 0, 0, 0], +# [0, 0, 0, 0, 7, 0, 8, 0, 0], +# [0, 0, 0, 0, 0, 0, 1, 0, 0], +# [0, 2, 0, 0, 3, 0, 0, 0, 0], +# [6, 0, 0, 0, 0, 0, 0, 7, 5], +# [0, 0, 3, 4, 0, 0, 0, 0, 0], +# [0, 0, 0, 2, 0, 0, 6, 0, 0], +# ] +# np.savetxt("test_puzzle.csv", board, delimiter=",") + +# solved_board = [ +# [2, 3, 7, 8, 4, 1, 5, 6, 9], +# [1, 8, 6, 7, 9, 5, 2, 4, 3], +# [5, 9, 4, 3, 2, 6, 7, 1, 8], +# [3, 1, 5, 6, 7, 4, 8, 9, 2], +# [4, 6, 9, 5, 8, 2, 1, 3, 7], +# [7, 2, 8, 1, 3, 9, 4, 5, 6], +# [6, 4, 2, 9, 1, 8, 3, 7, 5], +# [8, 5, 3, 4, 6, 7, 9, 2, 1], +# [9, 7, 1, 2, 5, 3, 6, 8, 4], +# ] + +# np.savetxt("test_solution.csv", solved_board, delimiter=",") + + +def apply_action(action: chex.Array, board: chex.Array) -> chex.Array: + return board.at[action[0], action[1]].set(action[2]) + + +def validate_board(board: chex.Array) -> chex.Array: + """Checks that every row, column and 3x3 boxes includes all figures. + + Args: + board: The sudoku board. + + Returns: + condition: A `bool` indicator that validates a solution or rejects it. + """ + + def _validate_row(row: chex.Array) -> chex.Array: + condition = jnp.nonzero(row, size=BOARD_WIDTH)[0] == jnp.arange(BOARD_WIDTH) + return condition.all() + + condition_rows = jax.vmap(_validate_row)(board).all() + condition_columns = jax.vmap(_validate_row)(board.T).all() + condition_boxes = jax.vmap(_validate_row)(jnp.array(BOX_IDX)).all() + + return condition_rows & condition_columns & condition_boxes + + +def update_action_mask(action_mask: chex.Array, board: chex.Array) -> chex.Array: + """Updates the action mask according to the current board state. + + Args: + action_mask: The action mask. + board: The sudoku board. + + Returns: + The updated action mask. + """ + row_mask = 1 - jax.nn.one_hot(board, BOARD_WIDTH).any(axis=1) * 1 + column_mask = 1 - jax.nn.one_hot(board.T, BOARD_WIDTH).any(axis=1) * 1 + + boxes = board.reshape(BOARD_WIDTH**2).take(jnp.array(BOX_IDX)) + box_mask = 1 - jax.nn.one_hot(boxes, BOARD_WIDTH).any(axis=1) * 1 + + boxes_action_mask = action_mask.reshape(BOARD_WIDTH**2, BOARD_WIDTH)[ + jnp.array(BOX_IDX) + ] + boxes_action_mask *= box_mask.reshape(BOARD_WIDTH, 1, BOARD_WIDTH) + + action_mask = ( + action_mask.reshape(BOARD_WIDTH**2, BOARD_WIDTH) + .at[jnp.array(BOX_IDX)] + .set(boxes_action_mask) + .reshape(BOARD_WIDTH, BOARD_WIDTH, BOARD_WIDTH) + ) + action_mask *= row_mask.reshape(BOARD_WIDTH, 1, BOARD_WIDTH) + action_mask *= column_mask.reshape(1, BOARD_WIDTH, BOARD_WIDTH) + board_mask = (board == -1) * 1 + + action_mask *= board_mask.reshape(BOARD_WIDTH, BOARD_WIDTH, 1) + + return action_mask diff --git a/jumanji/environments/logic/sudoku/viewer.py b/jumanji/environments/logic/sudoku/viewer.py new file mode 100644 index 000000000..ecc239495 --- /dev/null +++ b/jumanji/environments/logic/sudoku/viewer.py @@ -0,0 +1,167 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Optional, Sequence, Tuple + +import matplotlib +import matplotlib.animation as animation +import matplotlib.pyplot as plt + +import jumanji +from jumanji.environments.logic.sudoku.constants import BOARD_WIDTH +from jumanji.environments.logic.sudoku.env import State +from jumanji.viewer import Viewer + + +class SudokuViewer(Viewer[State]): + def __init__( + self, + name: str = "Sudoku", + ) -> None: + self._name = name + self._animation: Optional[animation.Animation] = None + + def render( + self, + state: State, + save_path: Optional[str] = None, + ax: Optional[plt.Axes] = None, + ) -> None: + self._clear_display() + + if ax is None: + fig, ax = plt.subplots(figsize=(6, 6)) + plt.title(f"{self._name}") + else: + fig = ax.figure + ax.clear() + self._draw(ax, state) + ax.text( + -0.5, -0.5, f"Remaining actions: {state.action_mask.sum()}", fontsize=14 + ) + self._display_human(fig) + + def _draw_board(self, ax: plt.Axes) -> None: + # Draw the square box that delimits the board. + ax.axis("off") + lines = [] + + _linewidth = 2.5 + ax.plot([0, 0], [0, BOARD_WIDTH], "-k", lw=_linewidth) + ax.plot([0, BOARD_WIDTH], [BOARD_WIDTH, BOARD_WIDTH], "-k", lw=_linewidth) + ax.plot([BOARD_WIDTH, BOARD_WIDTH], [BOARD_WIDTH, 0], "-k", lw=_linewidth) + ax.plot([BOARD_WIDTH, 0], [0, 0], "-k", lw=_linewidth) + for i in range(1, BOARD_WIDTH): + if i % int(BOARD_WIDTH**0.5) == 0: + _linewidth = 2.5 + else: + _linewidth = 1 + + hline = matplotlib.lines.Line2D( + [0, BOARD_WIDTH], [i, i], color="k", linewidth=_linewidth + ) + vline = matplotlib.lines.Line2D( + [i, i], [0, BOARD_WIDTH], color="k", linewidth=_linewidth + ) + + lines.append(hline) + lines.append(vline) + + for line in lines: + ax.add_line(line) + + def animate( + self, + states: Sequence[State], + interval: int = 500, + save_path: Optional[str] = None, + ) -> animation.FuncAnimation: + fig, ax = plt.subplots(figsize=(6, 6)) + plt.title(f"{self._name}") + + def make_frame(state_index: int) -> None: + state = states[state_index] + self.render(state, ax=ax) + + _animation = animation.FuncAnimation( + fig, make_frame, frames=len(states), interval=interval, blit=False + ) + + if save_path: + _animation.save(save_path) + + return _animation + + def _get_fig_ax(self) -> Tuple[plt.Figure, plt.Axes]: + exists = plt.fignum_exists(self._name) + if exists: + fig = plt.figure(self._name) + ax = fig.get_axes()[0] + else: + fig = plt.figure( + self._name, + figsize=(6, 6), + ) + fig.set_tight_layout({"pad": False, "w_pad": 0.0, "h_pad": 0.0}) + if not plt.isinteractive(): + fig.show() + ax = fig.add_subplot() + return fig, ax + + def close(self) -> None: + plt.close(self._name) + + def _draw(self, ax: plt.Axes, state: State) -> None: + ax.clear() + self._draw_board(ax) + self._draw_figures(ax, state) + + def _draw_figures(self, ax, state: State) -> None: + """Loop over the different cells and draws corresponding shapes in the ax object.""" + board = state.board + board_shape = board.shape + + for i in range(board_shape[0]): + for j in range(board_shape[1]): + x_pos = j + 0.5 + y_pos = board_shape[0] - i - 0.5 + element = board[i, j] + if element != -1: + ax.text( + x_pos, + y_pos, + element + 1, + horizontalalignment="center", + verticalalignment="center", + fontsize=16, + ) + + return + + def _display_human(self, fig: plt.Figure) -> None: + if plt.isinteractive(): + # Required to update render when using Jupyter Notebook. + fig.canvas.draw() + if jumanji.environments.is_colab(): + plt.show(self._name) + else: + # Required to update render when not using Jupyter Notebook. + fig.canvas.draw_idle() + fig.canvas.flush_events() + + def _clear_display(self) -> None: + if jumanji.environments.is_colab(): + import IPython.display + + IPython.display.clear_output(True) diff --git a/jumanji/training/configs/config.yaml b/jumanji/training/configs/config.yaml index 34d88409c..79ee4e830 100644 --- a/jumanji/training/configs/config.yaml +++ b/jumanji/training/configs/config.yaml @@ -1,6 +1,6 @@ defaults: - _self_ - - env: snake # [bin_pack, cleaner, connector, cvrp, game_2048, job_shop, knapsack, maze, minesweeper, rubiks_cube, snake, tsp] + - env: snake # [bin_pack, cleaner, connector, cvrp, game_2048, job_shop, knapsack, maze, minesweeper, rubiks_cube, snake, sudoku, tsp] agent: random # [random, a2c] diff --git a/jumanji/training/networks/__init__.py b/jumanji/training/networks/__init__.py index 0b24bb2fe..82a67e102 100644 --- a/jumanji/training/networks/__init__.py +++ b/jumanji/training/networks/__init__.py @@ -56,5 +56,9 @@ make_actor_critic_networks_snake, ) from jumanji.training.networks.snake.random import make_random_policy_snake +from jumanji.training.networks.sudoku.actor_critic import ( + make_actor_critic_networks_sudoku, +) +from jumanji.training.networks.sudoku.random import make_random_policy_sudoku from jumanji.training.networks.tsp.actor_critic import make_actor_critic_networks_tsp from jumanji.training.networks.tsp.random import make_random_policy_tsp diff --git a/jumanji/training/networks/sudoku/__init__.py b/jumanji/training/networks/sudoku/__init__.py new file mode 100644 index 000000000..21db9ec1c --- /dev/null +++ b/jumanji/training/networks/sudoku/__init__.py @@ -0,0 +1,13 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. diff --git a/jumanji/training/networks/sudoku/actor_critic.py b/jumanji/training/networks/sudoku/actor_critic.py new file mode 100644 index 000000000..000e666d8 --- /dev/null +++ b/jumanji/training/networks/sudoku/actor_critic.py @@ -0,0 +1,95 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from typing import Sequence + +import chex +import haiku as hk +import jax +import jax.numpy as jnp +import numpy as np + +from jumanji.environments.logic.sudoku import Observation, Sudoku +from jumanji.environments.logic.sudoku.constants import BOARD_WIDTH +from jumanji.training.networks.actor_critic import ( + ActorCriticNetworks, + FeedForwardNetwork, +) +from jumanji.training.networks.parametric_distribution import ( + FactorisedActionSpaceParametricDistribution, +) + + +def make_actor_critic_networks_sudoku( + sudoku: Sudoku, + num_channels: int, + policy_layers: Sequence[int], + value_layers: Sequence[int], +) -> ActorCriticNetworks: + """Make actor-critic networks for the `Sudoku` environment.""" + num_actions = sudoku.action_spec().num_values + parametric_action_distribution = FactorisedActionSpaceParametricDistribution( + action_spec_num_values=np.asarray(num_actions) + ) + + policy_network = make_sudoku_cnn( + num_outputs=int(np.prod(num_actions)), + mlp_units=policy_layers, + conv_n_channels=num_channels, + ) + value_network = make_sudoku_cnn( + num_outputs=1, + mlp_units=value_layers, + conv_n_channels=num_channels, + ) + return ActorCriticNetworks( + policy_network=policy_network, + value_network=value_network, + parametric_action_distribution=parametric_action_distribution, + ) + + +def make_sudoku_cnn( + num_outputs: int, + mlp_units: Sequence[int], + conv_n_channels: int, +) -> FeedForwardNetwork: + def network_fn(observation: Observation) -> chex.Array: + torso = hk.Sequential( + [ + hk.Conv2D(conv_n_channels, (2, 2), 2), + jax.nn.relu, + hk.Conv2D(conv_n_channels, (2, 2), 1), + jax.nn.relu, + hk.Flatten(), + ] + ) + embedding = torso(observation.board[..., None] / BOARD_WIDTH - 0.5) + + head = hk.nets.MLP((*mlp_units, num_outputs), activate_final=False) + if num_outputs == 1: + value = jnp.squeeze(head(embedding), axis=-1) + return value + else: + logits = head(embedding) + logits = logits.reshape(-1, BOARD_WIDTH, BOARD_WIDTH, BOARD_WIDTH) + + logits = jnp.where( + observation.action_mask, logits, jnp.finfo(jnp.float32).min + ) + + return logits.reshape(observation.action_mask.shape[0], -1) + + init, apply = hk.without_apply_rng(hk.transform(network_fn)) + return FeedForwardNetwork(init=init, apply=apply) diff --git a/jumanji/training/networks/sudoku/random.py b/jumanji/training/networks/sudoku/random.py new file mode 100644 index 000000000..ff858d9c1 --- /dev/null +++ b/jumanji/training/networks/sudoku/random.py @@ -0,0 +1,62 @@ +# Copyright 2022 InstaDeep Ltd. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import chex +import jax +import jax.numpy as jnp + +from jumanji.environments.logic.sudoku import Sudoku +from jumanji.training.networks.masked_categorical_random import ( + ObservationWithActionMask, + make_masked_categorical_random_ndim, +) +from jumanji.training.networks.protocols import RandomPolicy + +# def make_random_policy_sudoku() -> RandomPolicy: +# """Make random policy for the `Sudoku` environment.""" + +# def vmap_random_policy_sudoku( +# observation: ObservationWithActionMask, +# key: chex.PRNGKey, +# ) -> chex.Array: +# keys = jax.random.split(key, observation.action_mask.shape[0]) + +# return jax.vmap(random_policy_sudoku)(observation, keys) + +# return vmap_random_policy_sudoku + + +# def random_policy_sudoku( +# observation: ObservationWithActionMask, +# key: chex.PRNGKey, +# ) -> chex.Array: +# raveled_mask = observation.action_mask.ravel() +# idx = jax.random.choice( +# key, +# jnp.arange(len(raveled_mask)), +# shape=(1,), +# p=raveled_mask / raveled_mask.sum(), +# )[0] +# unravel_idx = jnp.unravel_index(idx, observation.action_mask.shape) +# action = jnp.stack(unravel_idx) + +# return action +def make_random_policy_sudoku(sudoku: Sudoku) -> RandomPolicy: + """Make random policy for the `Sudoku` environment.""" + + action_spec_num_values = sudoku.action_spec().num_values + + return make_masked_categorical_random_ndim( + action_spec_num_values=action_spec_num_values + ) diff --git a/jumanji/training/setup_train.py b/jumanji/training/setup_train.py index fb4cf3634..4c8d87506 100644 --- a/jumanji/training/setup_train.py +++ b/jumanji/training/setup_train.py @@ -35,6 +35,7 @@ Minesweeper, RubiksCube, Snake, + Sudoku, ) from jumanji.training import networks from jumanji.training.agents.a2c import A2CAgent @@ -158,6 +159,9 @@ def _setup_random_policy( # noqa: CCR001 elif cfg.env.name == "game_2048": assert isinstance(env.unwrapped, Game2048) random_policy = networks.make_random_policy_game_2048() + elif cfg.env.name == "sudoku": + assert isinstance(env.unwrapped, Sudoku) + random_policy = networks.make_random_policy_sudoku(sudoku=env.unwrapped) elif cfg.env.name == "cleaner": assert isinstance(env.unwrapped, Cleaner) random_policy = networks.make_random_policy_cleaner() @@ -241,6 +245,7 @@ def _setup_actor_critic_neworks( # noqa: CCR001 policy_layers=cfg.env.network.policy_layers, value_layers=cfg.env.network.value_layers, ) + elif cfg.env.name == "rubiks_cube": assert isinstance(env.unwrapped, RubiksCube) actor_critic_networks = networks.make_actor_critic_networks_rubiks_cube( @@ -249,6 +254,15 @@ def _setup_actor_critic_neworks( # noqa: CCR001 step_count_embed_dim=cfg.env.network.step_count_embed_dim, dense_layer_dims=cfg.env.network.dense_layer_dims, ) + + elif cfg.env.name == "sudoku": + assert isinstance(env.unwrapped, Sudoku) + actor_critic_networks = networks.make_actor_critic_networks_sudoku( + sudoku=env.unwrapped, + num_channels=cfg.env.network.num_channels, + policy_layers=cfg.env.network.policy_layers, + value_layers=cfg.env.network.value_layers, + ) elif cfg.env.name == "minesweeper": assert isinstance(env.unwrapped, Minesweeper) actor_critic_networks = networks.make_actor_critic_networks_minesweeper( From 1c139a450da7d7977a1139586ab9f55308ec77ca Mon Sep 17 00:00:00 2001 From: Raphael Boige Date: Thu, 27 Apr 2023 20:02:58 +0200 Subject: [PATCH 02/55] feat: make generator configurable and add puzzles data --- examples/training.ipynb | 143 +++++------------- jumanji/__init__.py | 14 +- .../logic/sudoku/data/10000_mixed_puzzles.npy | Bin 0 -> 810128 bytes .../logic/sudoku/data/10_easy_puzzles.npy | Bin 0 -> 8228 bytes jumanji/environments/logic/sudoku/env.py | 4 +- .../environments/logic/sudoku/generator.py | 67 ++++++-- 6 files changed, 108 insertions(+), 120 deletions(-) create mode 100644 jumanji/environments/logic/sudoku/data/10000_mixed_puzzles.npy create mode 100644 jumanji/environments/logic/sudoku/data/10_easy_puzzles.npy diff --git a/examples/training.ipynb b/examples/training.ipynb index 18d39ae83..e56af69b8 100644 --- a/examples/training.ipynb +++ b/examples/training.ipynb @@ -13,7 +13,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": { "tags": [] }, @@ -32,7 +32,7 @@ }, { "cell_type": "code", - "execution_count": 26, + "execution_count": 9, "metadata": { "collapsed": false, "jupyter": { @@ -53,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 27, + "execution_count": 10, "metadata": { "collapsed": false, "jupyter": { @@ -69,7 +69,7 @@ }, { "cell_type": "code", - "execution_count": 28, + "execution_count": 11, "metadata": { "collapsed": false, "jupyter": { @@ -81,10 +81,10 @@ { "data": { "text/plain": [ - "{'agent': 'a2c', 'seed': 0, 'logger': {'type': 'terminal', 'save_checkpoint': True, 'name': '${agent}_${env.name}'}, 'env': {'name': 'sudoku', 'registered_version': 'Sudoku-v0', 'network': {'num_channels': 32, 'policy_layers': [64, 64], 'value_layers': [128, 128]}, 'training': {'num_epochs': 100, 'num_learner_steps_per_epoch': 500, 'n_steps': 20, 'total_batch_size': 128}, 'evaluation': {'eval_total_batch_size': 200, 'greedy_eval_total_batch_size': 200}, 'a2c': {'normalize_advantage': False, 'discount_factor': 0.997, 'bootstrapping_factor': 0.95, 'l_pg': 1.0, 'l_td': 1.0, 'l_en': 0.01, 'learning_rate': 0.0004}}}" + "{'agent': 'a2c', 'seed': 0, 'logger': {'type': 'terminal', 'save_checkpoint': True, 'name': '${agent}_${env.name}'}, 'env': {'name': 'sudoku', 'registered_version': 'Sudoku-very-easy-v0', 'network': {'num_channels': 32, 'policy_layers': [64, 64], 'value_layers': [128, 128]}, 'training': {'num_epochs': 100, 'num_learner_steps_per_epoch': 500, 'n_steps': 20, 'total_batch_size': 128}, 'evaluation': {'eval_total_batch_size': 200, 'greedy_eval_total_batch_size': 200}, 'a2c': {'normalize_advantage': False, 'discount_factor': 0.997, 'bootstrapping_factor': 0.95, 'l_pg': 1.0, 'l_td': 1.0, 'l_en': 0.01, 'learning_rate': 0.0004}}}" ] }, - "execution_count": 28, + "execution_count": 11, "metadata": {}, "output_type": "execute_result" } @@ -105,7 +105,7 @@ }, { "cell_type": "code", - "execution_count": 29, + "execution_count": null, "metadata": { "tags": [] }, @@ -122,7 +122,7 @@ " name: ${agent}_${env.name}\n", "env:\n", " name: sudoku\n", - " registered_version: Sudoku-v0\n", + " registered_version: Sudoku-very-easy-v0\n", " network:\n", " num_channels: 32\n", " policy_layers:\n", @@ -156,12 +156,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "board (1, 9, 9)\n", - "embedding (1, 800)\n", - "(1, 9, 9, 9)\n", - "board (1, 9, 9)\n", - "embedding (1, 800)\n", - "(1, 9, 9, 9)\n" + "(9, 9)\n", + "(9, 9)\n" ] }, { @@ -175,123 +171,68 @@ "name": "stdout", "output_type": "stream", "text": [ - "board (1, 9, 9)\n", - "embedding (1, 800)\n", - "(1, 9, 9, 9)\n", - "Tracedwith\n", - "Tracedwith\n", - "Tracedwith Tracedwith Tracedwith\n" + "(9, 9)\n", + "(9, 9)\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "INFO:root:Eval Stochastic >> Env Steps: 0.00e+00 | Episode Length: 31.815 | Episode Return: 0.000 | Time: 1.501\n" + "INFO:root:Eval Stochastic >> Env Steps: 0.00e+00 | Episode Length: 10.660 | Episode Return: 0.000 | Time: 1.882\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "board (1, 9, 9)\n", - "embedding (1, 800)\n", - "(1, 9, 9, 9)\n", - "Tracedwith\n", - "Tracedwith\n", - "Tracedwith Tracedwith Tracedwith\n" + "(9, 9)\n", + "(9, 9)\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "INFO:root:Eval Greedy >> Env Steps: 0.00e+00 | Episode Length: 34.000 | Episode Return: 0.000 | Time: 0.827\n" + "INFO:root:Eval Greedy >> Env Steps: 0.00e+00 | Episode Length: 10.695 | Episode Return: 0.000 | Time: 1.582\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "board (128, 9, 9)\n", - "embedding (128, 800)\n", - "(128, 9, 9, 9)\n", - "Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0\n", - "Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0\n", - "Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0 Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0 Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0\n", - "board (128, 9, 9)\n", - "embedding (128, 800)\n", - "(128, 9, 9, 9)\n" + "(9, 9)\n", + "(9, 9)\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "INFO:root:Train >> Env Steps: 0.00e+00 | Advantage: -0.000 | Critic Loss: 0.000 | Entropy: 3.029 | Entropy Loss: -3.029 | Policy Loss: -0.000 | Steps Per Second: 4,394 | Time: 291.278 | Total Loss: -0.030 | Value: 0.000\n", - "INFO:root:Eval Stochastic >> Env Steps: 1.28e+06 | Episode Length: 31.475 | Episode Return: 0.000 | Time: 0.211\n", - "INFO:root:Eval Greedy >> Env Steps: 1.28e+06 | Episode Length: 32.000 | Episode Return: 0.000 | Time: 0.001\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "board (128, 9, 9)\n", - "embedding (128, 800)\n", - "(128, 9, 9, 9)\n", - "Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0\n", - "Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0\n", - "Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0 Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0 Tracedwith with\n", - " val = Tracedwith\n", - " batch_dim = 0\n", - "board (128, 9, 9)\n", - "embedding (128, 800)\n", - "(128, 9, 9, 9)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "INFO:root:Saving checkpoint...\n", - "INFO:root:Checkpoint saved at 'training_state'.\n", - "INFO:root:Closing logger...\n" - ] - }, - { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[0;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[0;32mIn[29], line 1\u001b[0m\n\u001b[0;32m----> 1\u001b[0m \u001b[43mtrain\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcfg\u001b[49m\u001b[43m)\u001b[49m\n", - "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/hydra/main.py:79\u001b[0m, in \u001b[0;36mmain..main_decorator..decorated_main\u001b[0;34m(cfg_passthrough)\u001b[0m\n\u001b[1;32m 76\u001b[0m \u001b[38;5;129m@functools\u001b[39m\u001b[38;5;241m.\u001b[39mwraps(task_function)\n\u001b[1;32m 77\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mdecorated_main\u001b[39m(cfg_passthrough: Optional[DictConfig] \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;01mNone\u001b[39;00m) \u001b[38;5;241m-\u001b[39m\u001b[38;5;241m>\u001b[39m Any:\n\u001b[1;32m 78\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m cfg_passthrough \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m---> 79\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mtask_function\u001b[49m\u001b[43m(\u001b[49m\u001b[43mcfg_passthrough\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 80\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 81\u001b[0m args_parser \u001b[38;5;241m=\u001b[39m get_args_parser()\n", - "File \u001b[0;32m~/workspace/jumanji/jumanji/training/train.py:105\u001b[0m, in \u001b[0;36mtrain\u001b[0;34m(cfg, log_compiles)\u001b[0m\n\u001b[1;32m 103\u001b[0m \u001b[38;5;66;03m# Training\u001b[39;00m\n\u001b[1;32m 104\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m train_timer:\n\u001b[0;32m--> 105\u001b[0m training_state, metrics \u001b[38;5;241m=\u001b[39m \u001b[43mepoch_fn\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtraining_state\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 106\u001b[0m logger\u001b[38;5;241m.\u001b[39mwrite(\n\u001b[1;32m 107\u001b[0m data\u001b[38;5;241m=\u001b[39mutils\u001b[38;5;241m.\u001b[39mfirst_from_device(metrics),\n\u001b[1;32m 108\u001b[0m label\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtrain\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[1;32m 109\u001b[0m env_steps\u001b[38;5;241m=\u001b[39menv_steps,\n\u001b[1;32m 110\u001b[0m )\n", - " \u001b[0;31m[... skipping hidden 1 frame]\u001b[0m\n", - "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/jax/_src/api.py:2256\u001b[0m, in \u001b[0;36m_cpp_pmap..cache_miss\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 2254\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(top_trace, core\u001b[38;5;241m.\u001b[39mEvalTrace):\n\u001b[1;32m 2255\u001b[0m execute \u001b[38;5;241m=\u001b[39m pxla\u001b[38;5;241m.\u001b[39mxla_pmap_impl_lazy(fun_, \u001b[38;5;241m*\u001b[39mtracers, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mparams)\n\u001b[0;32m-> 2256\u001b[0m out \u001b[38;5;241m=\u001b[39m map_bind_continuation(\u001b[43mexecute\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mtracers\u001b[49m\u001b[43m)\u001b[49m)\n\u001b[1;32m 2257\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m 2258\u001b[0m out \u001b[38;5;241m=\u001b[39m map_bind_continuation(\n\u001b[1;32m 2259\u001b[0m pxla\u001b[38;5;241m.\u001b[39mxla_pmap_p\u001b[38;5;241m.\u001b[39mprocess(top_trace, fun_, tracers, params))\n", - "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/jax/_src/profiler.py:314\u001b[0m, in \u001b[0;36mannotate_function..wrapper\u001b[0;34m(*args, **kwargs)\u001b[0m\n\u001b[1;32m 311\u001b[0m \u001b[38;5;129m@wraps\u001b[39m(func)\n\u001b[1;32m 312\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21mwrapper\u001b[39m(\u001b[38;5;241m*\u001b[39margs, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mkwargs):\n\u001b[1;32m 313\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m TraceAnnotation(name, \u001b[38;5;241m*\u001b[39m\u001b[38;5;241m*\u001b[39mdecorator_kwargs):\n\u001b[0;32m--> 314\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 315\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m wrapper\n", - "File \u001b[0;32m~/miniconda3/envs/qdaxpy310/lib/python3.10/site-packages/jax/interpreters/pxla.py:2071\u001b[0m, in \u001b[0;36mExecuteReplicated.__call__\u001b[0;34m(self, *args)\u001b[0m\n\u001b[1;32m 2069\u001b[0m out_bufs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_call_with_tokens(input_bufs)\n\u001b[1;32m 2070\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m-> 2071\u001b[0m out_bufs \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mxla_executable\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mexecute_sharded_on_local_devices\u001b[49m\u001b[43m(\u001b[49m\n\u001b[1;32m 2072\u001b[0m \u001b[43m \u001b[49m\u001b[43minput_bufs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[1;32m 2073\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m dispatch\u001b[38;5;241m.\u001b[39mneeds_check_special():\n\u001b[1;32m 2074\u001b[0m \u001b[38;5;28;01mfor\u001b[39;00m bufs \u001b[38;5;129;01min\u001b[39;00m out_bufs:\n", - "\u001b[0;31mKeyboardInterrupt\u001b[0m: " + "2023-04-27 19:43:08.152712: E external/org_tensorflow/tensorflow/compiler/xla/service/slow_operation_alarm.cc:65] Constant folding an instruction is taking > 1s:\n", + "\n", + " pad.62 (displaying the full instruction incurs a runtime overhead. Raise your logging level to 4 or above).\n", + "\n", + "This isn't necessarily a bug; constant-folding is inherently a trade-off between compilation time and speed at runtime. XLA has some guards that attempt to keep constant folding from taking too long, but fundamentally you'll always be able to come up with an input program that takes a long time.\n", + "\n", + "If you'd like to file a bug, run with envvar XLA_FLAGS=--xla_dump_to=/tmp/foo and attach the results.\n", + "2023-04-27 19:43:08.153041: E external/org_tensorflow/tensorflow/compiler/xla/service/slow_operation_alarm.cc:133] The operation took 1.374108821s\n", + "Constant folding an instruction is taking > 1s:\n", + "\n", + " pad.62 (displaying the full instruction incurs a runtime overhead. Raise your logging level to 4 or above).\n", + "\n", + "This isn't necessarily a bug; constant-folding is inherently a trade-off between compilation time and speed at runtime. XLA has some guards that attempt to keep constant folding from taking too long, but fundamentally you'll always be able to come up with an input program that takes a long time.\n", + "\n", + "If you'd like to file a bug, run with envvar XLA_FLAGS=--xla_dump_to=/tmp/foo and attach the results.\n", + "INFO:root:Train >> Env Steps: 0.00e+00 | Advantage: 0.000 | Critic Loss: 0.000 | Entropy: 1.596 | Entropy Loss: -1.596 | Policy Loss: -0.000 | Steps Per Second: 4,025 | Time: 317.950 | Total Loss: -0.016 | Value: -0.000\n", + "INFO:root:Eval Stochastic >> Env Steps: 1.28e+06 | Episode Length: 10.580 | Episode Return: 0.000 | Time: 0.068\n", + "INFO:root:Eval Greedy >> Env Steps: 1.28e+06 | Episode Length: 10.615 | Episode Return: 0.000 | Time: 0.030\n", + "INFO:root:Train >> Env Steps: 1.28e+06 | Advantage: -0.000 | Critic Loss: 0.000 | Entropy: 1.595 | Entropy Loss: -1.595 | Policy Loss: -0.000 | Steps Per Second: 3,807 | Time: 336.170 | Total Loss: -0.016 | Value: -0.000\n", + "INFO:root:Eval Stochastic >> Env Steps: 2.56e+06 | Episode Length: 10.620 | Episode Return: 0.000 | Time: 0.066\n", + "INFO:root:Eval Greedy >> Env Steps: 2.56e+06 | Episode Length: 10.700 | Episode Return: 0.000 | Time: 0.029\n", + "INFO:root:Train >> Env Steps: 2.56e+06 | Advantage: -0.000 | Critic Loss: 0.000 | Entropy: 1.595 | Entropy Loss: -1.595 | Policy Loss: -0.000 | Steps Per Second: 4,026 | Time: 317.880 | Total Loss: -0.016 | Value: 0.000\n", + "INFO:root:Eval Stochastic >> Env Steps: 3.84e+06 | Episode Length: 10.665 | Episode Return: 0.000 | Time: 0.066\n", + "INFO:root:Eval Greedy >> Env Steps: 3.84e+06 | Episode Length: 10.670 | Episode Return: 0.000 | Time: 0.029\n" ] } ], diff --git a/jumanji/__init__.py b/jumanji/__init__.py index 858d8fe01..4e4c34cef 100644 --- a/jumanji/__init__.py +++ b/jumanji/__init__.py @@ -14,6 +14,7 @@ from jumanji.env import Environment from jumanji.environments.logic.rubiks_cube import generator as rubik_generator +from jumanji.environments.logic.sudoku import generator as sudoku_generator from jumanji.registration import make, register, registered_environments from jumanji.version import __version__ @@ -42,9 +43,20 @@ kwargs={"time_limit": 20, "generator": partly_scrambled_rubiks_cube_generator}, ) -# Sudoku - the standard Sudoku puzzle with grid of size 9x9. +# Sudoku - the standard Sudoku puzzle with grid of size 9x9. By default 10000 puzzles +# of mixed difficulties are set for reset. register(id="Sudoku-v0", entry_point="jumanji.environments:Sudoku") +# Sudoku - the standard Sudoku puzzle with grid of size 9x9. Only 10 very easy puzzles +# are set for reset, they all have 70/81 cells filled. +very_easy_sudoku_generator = sudoku_generator.DatabaseGenerator(level="very-easy") +register( + id="Sudoku-very-easy-v0", + entry_point="jumanji.environments:Sudoku", + kwargs={"generator": very_easy_sudoku_generator}, +) + + ### # Packing Environments ### diff --git a/jumanji/environments/logic/sudoku/data/10000_mixed_puzzles.npy b/jumanji/environments/logic/sudoku/data/10000_mixed_puzzles.npy new file mode 100644 index 0000000000000000000000000000000000000000..e1f09326ce2ea77fc7c7b1d7b267cedb58ce2e6b GIT binary patch literal 810128 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
X$0%}`#PtNxBnjS1YGXuLwZz3*Zeg6!z~Ro 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

Kaq> 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