From 53eb43d5903c9759fd2b628e8ba61855664723cd Mon Sep 17 00:00:00 2001 From: EnricoTrizio Date: Wed, 13 Nov 2024 14:38:59 +0100 Subject: [PATCH] Updated test notebook --- test_graphs/test_graph.ipynb | 278 +++++++++++++++++++++++++---------- 1 file changed, 204 insertions(+), 74 deletions(-) diff --git a/test_graphs/test_graph.ipynb b/test_graphs/test_graph.ipynb index a0c2fe2..fc36850 100644 --- a/test_graphs/test_graph.ipynb +++ b/test_graphs/test_graph.ipynb @@ -15,66 +15,14 @@ "cell_type": "code", "execution_count": 2, "metadata": {}, - "outputs": [], - "source": [ - "def test_get_data() -> torch_geometric.data.Batch:\n", - " # TODO: This is not a real test, but a helper function for other tests.\n", - " # Maybe should change its name.\n", - "\n", - " numbers = [8, 1, 1]\n", - " positions = np.array(\n", - " [\n", - " [[0.0, 0.0, 0.0], [0.07, 0.07, 0.0], [0.07, -0.07, 0.0]],\n", - " [[0.0, 0.0, 0.0], [-0.07, 0.07, 0.0], [0.07, 0.07, 0.0]],\n", - " [[0.0, 0.0, 0.0], [0.07, -0.07, 0.0], [0.07, 0.07, 0.0]],\n", - " [[0.0, 0.0, 0.0], [0.0, -0.07, 0.07], [0.0, 0.07, 0.07]],\n", - " [[0.0, 0.0, 0.0], [0.07, 0.0, 0.07], [-0.07, 0.0, 0.07]],\n", - " [[0.1, 0.0, 1.1], [0.17, 0.07, 1.1], [0.17, -0.07, 1.1]],\n", - " ],\n", - " dtype=np.float64\n", - " )\n", - " cell = np.identity(3, dtype=float) * 0.2\n", - " graph_labels = np.array([[[0]], [[1]]] * 3)\n", - " node_labels = np.array([[0], [1], [1]])\n", - " z_table = gdata.atomic.AtomicNumberTable.from_zs(numbers)\n", - "\n", - " config = [\n", - " gdata.atomic.Configuration(\n", - " atomic_numbers=numbers,\n", - " positions=positions[i],\n", - " cell=cell,\n", - " pbc=[True] * 3,\n", - " node_labels=node_labels,\n", - " graph_labels=graph_labels[i],\n", - " ) for i in range(0, 6)\n", - " ]\n", - " dataset = gdata.create_dataset_from_configurations(\n", - " config, z_table, 0.1, show_progress=False\n", - " )\n", - "\n", - " loader = gdata.GraphDataModule(\n", - " dataset,\n", - " lengths=(1.0,),\n", - " batch_size=10,\n", - " shuffle=False,\n", - " )\n", - " loader.setup()\n", - "\n", - " return next(iter(loader.train_dataloader()))" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "\u001b[1m\u001b[34m BASEDATA \u001b[0m: [ \u001b[32m1600\u001b[0m\u001b[36m 󰡷 \u001b[0m| [\u001b[32m6 9\u001b[0m]\u001b[36m 󰝨 \u001b[0m| \u001b[32m8.000000\u001b[0m\u001b[36m 󰳁 \u001b[0m]\n", - "\u001b[1m\u001b[34m TRAINING \u001b[0m: [ \u001b[32m1280\u001b[0m\u001b[36m 󰡷 \u001b[0m| \u001b[32m1600\u001b[0m\u001b[36m  \u001b[0m|\u001b[36m  \u001b[0m ]\n", - "\u001b[1m\u001b[34m VALIDATION \u001b[0m: [ \u001b[32m 320\u001b[0m\u001b[36m 󰡷 \u001b[0m| \u001b[32m1600\u001b[0m\u001b[36m  \u001b[0m|\u001b[36m  \u001b[0m ]\n", + "DictModule(dataset -> DictDataset( \"data_list\": 1600, \"z_table\": 2, \"cutoff\": 8.0 ),\n", + "\t\t train_loader -> DictLoader(length=0.8, batch_size=1600, shuffle=1),\n", + "\t\t valid_loader -> DictLoader(length=0.2, batch_size=1600, shuffle=0))\n", "Class 0 dataframe shape: (800, 24)\n", "Class 1 dataframe shape: (800, 24)\n", "\n", @@ -84,7 +32,7 @@ } ], "source": [ - "from mlcolvar.data.graph import GraphDataModule\n", + "from mlcolvar.data.graph.datamodule import GraphDataModule\n", "from mlcolvar.utils.io import create_dataset_from_trajectories\n", "\n", "dataset_graph = create_dataset_from_trajectories(\n", @@ -114,6 +62,73 @@ "datamodule_ff = DictModule(dataset_ff, lengths=[1])\n" ] }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "DictDataset( \"data_list\": 1600, \"z_table\": 2, \"cutoff\": 8.0 )" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dataset_graph" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [], + "source": [ + "# a = dataset_graph['z_table']\n", + "# new = []\n", + "# for i in a:\n", + "# new.append(int(i))\n", + "# new\n", + "\n", + "# dataset_graph['z_table'] = new\n" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[0.1000],\n", + " [0.1000],\n", + " [0.1000],\n", + " [0.1000],\n", + " [0.1000],\n", + " [0.1000],\n", + " [0.1000],\n", + " [0.1000],\n", + " [0.1000],\n", + " [0.1000]])" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import torch\n", + "d = {'a' : torch.zeros(10), 'b': 0.1}\n", + "\n", + "torch.tile(torch.Tensor([d['b']]), (len(d[\"a\"]), 1))" + ] + }, { "cell_type": "raw", "metadata": { @@ -129,27 +144,46 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "from mlcolvar.core.nn.graph.schnet import SchNetModel\n", "\n", "gnn_model = SchNetModel(n_out=1,\n", - " cutoff=dataset_graph.cutoff,\n", - " atomic_numbers=dataset_graph.atomic_numbers,\n", + " cutoff=dataset_graph['cutoff'],\n", + " atomic_numbers=dataset_graph['z_table'],\n", " n_bases=6,\n", " n_layers=2,\n", " n_filters=32,\n", " n_hidden_channels=32\n", - " )" + " )\n", + "\n", + "# gnn_model = SchNetModel(n_out=1,\n", + "# cutoff=dataset_graph.cutoff,\n", + "# atomic_numbers=dataset_graph.atomic_numbers,\n", + "# n_bases=6,\n", + "# n_layers=2,\n", + "# n_filters=32,\n", + "# n_hidden_channels=32\n", + "# )" ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/etrizio@iit.local/Bin/dev/mlcolvar/mlcolvar/cvs/supervised/deeptda_merged.py:137: SyntaxWarning: \"is\" with a literal. Did you mean \"==\"?\n", + " elif self.gnn_model._model_type is 'gnn':\n", + "/home/etrizio@iit.local/Bin/miniconda3/envs/graph_mlcolvar_test/lib/python3.9/site-packages/lightning/pytorch/utilities/parsing.py:198: Attribute 'gnn_model' is an instance of `nn.Module` and is already saved during checkpointing. It is recommended to ignore them using `self.save_hyperparameters(ignore=['gnn_model'])`.\n" + ] + } + ], "source": [ "from mlcolvar.cvs.supervised.deeptda_merged import DeepTDA\n", "\n", @@ -171,7 +205,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -182,13 +216,14 @@ "TPU available: False, using: 0 TPU cores\n", "IPU available: False, using: 0 IPUs\n", "HPU available: False, using: 0 HPUs\n", - "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n" + "LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]\n", + "/home/etrizio@iit.local/Bin/miniconda3/envs/graph_mlcolvar_test/lib/python3.9/site-packages/lightning/pytorch/trainer/connectors/data_connector.py:441: The 'train_dataloader' does not have many workers which may be a bottleneck. Consider increasing the value of the `num_workers` argument` to `num_workers=63` in the `DataLoader` to improve performance.\n" ] }, { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "e0076f9257964f20a2f2ac6afcedf085", + "model_id": "c4763e95534e4cd8a6b0c9ebe1b67465", "version_major": 2, "version_minor": 0 }, @@ -203,7 +238,8 @@ "name": "stderr", "output_type": "stream", "text": [ - "`Trainer.fit` stopped: `max_epochs=500` reached.\n" + "/home/etrizio@iit.local/Bin/miniconda3/envs/graph_mlcolvar_test/lib/python3.9/site-packages/lightning/pytorch/utilities/data.py:77: Trying to infer the `batch_size` from an ambiguous collection. The batch size we found is 2. To avoid any miscalculations, use `self.log(..., batch_size=batch_size)`.\n", + "`Trainer.fit` stopped: `max_epochs=5` reached.\n" ] } ], @@ -214,7 +250,7 @@ " logger=False,\n", " enable_checkpointing=False,\n", " accelerator='gpu',\n", - " max_epochs=500,\n", + " max_epochs=5,\n", " enable_model_summary=False, \n", " limit_val_batches=0\n", ")\n", @@ -224,7 +260,37 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 18, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[{'data_list': DataBatch(edge_index=[2, 53760], shifts=[53760, 3], unit_shifts=[53760, 3], positions=[8960, 3], cell=[3840, 3], node_attrs=[8960, 2], graph_labels=[1280, 1], n_system=[1280, 1], weight=[1280], batch=[8960], ptr=[1281]),\n", + " 'z_table': [tensor([6, 6, 6, ..., 6, 6, 6]),\n", + " tensor([9, 9, 9, ..., 9, 9, 9])],\n", + " 'cutoff': tensor([8., 8., 8., ..., 8., 8., 8.])}]" + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "datamodule_ff.setup()\n", + "\n", + "a = datamodule_ff.train_dataloader()\n", + "a.dataset['data']\n", + "\n", + "datamodule_graph.setup()\n", + "a = datamodule_graph.train_dataloader()\n", + "list(a)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -241,7 +307,7 @@ { "data": { "application/vnd.jupyter.widget-view+json": { - "model_id": "ac3b0642ca964c1c9dee0b977a5a4a7b", + "model_id": "11f48882960b460a937b3e7957080491", "version_major": 2, "version_minor": 0 }, @@ -265,7 +331,7 @@ " logger=False,\n", " enable_checkpointing=False,\n", " accelerator='gpu',\n", - " max_epochs=500,\n", + " max_epochs=5,\n", " enable_model_summary=False, \n", " limit_val_batches=0\n", ")\n", @@ -275,12 +341,12 @@ }, { "cell_type": "code", - "execution_count": 14, + "execution_count": 12, "metadata": {}, "outputs": [], "source": [ "loader = datamodule_graph\n", - "test = next(iter(loader.train_dataloader()))\n", + "test = next(iter(loader.train_dataloader()))['data_list']\n", "out_graph = model_graph(test)\n", "\n", "out_ff = model_ff(dataset_ff['data'])" @@ -288,12 +354,12 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 13, "metadata": {}, "outputs": [ { "data": { - "image/png": "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s7O1c+fOcI/ULSoqKnTjjTeqX79+Sk1N1fjx43XgwIFwj3VJPPLII4qKitL06dPDPUq3+vTTT/XjH/9YKSkpSkxM1NChQ/Xee++Fe6yQ6+zs1Ny5cwP+Xlq0aNF5/Z6d8xHRgXL77bfr9OnTevPNN9XQ0KDrrrtOt99+u7xeb7hH6xb//d//rUmTJumee+7R+++/r3feeUf/8i//Eu6xut2DDz54Xl+b3JPt379fXV1devrpp7V3714tXbpUq1at0s9//vNwjxYSzz//vMrKyjR//nzt2rVL1113nfLy8tTS0hLu0UJu69atKikp0fbt21VTU6OOjg6NHTtWJ0+eDPdo3aq+vl5PP/20rr322nCP0q2++OILjRw5Ur169dJrr72mffv26fHHH9dll10W7tFC7tFHH9XKlSv1y1/+Uh9++KEeffRRVVZWavny5aF5AitCff7555Yka9u2bfY+v99vSbJqamrCOFn36OjosK688krrV7/6VbhHuaReffVVKzMz09q7d68lyfr9738f7pEumcrKSisjIyPcY4TETTfdZJWUlNi3Ozs7rbS0NKuioiKMU10aLS0tliRr69at4R6l2xw/ftwaPHiwVVNTY/3jP/6jdd9994V7pG4za9Ysa9SoUeEe45LIz8+37r333oB9EyZMsAoLC0Py+BF7BSUlJUXf+c539Otf/1onT57U6dOn9fTTTys1NVXDhw8P93ght2vXLn366aeKjo7W9ddfr/79+2vcuHH64IMPwj1at2lubtbkyZP1n//5n+rdu3e4x7nkfD6fkpOTwz3GRWtvb1dDQ4Nyc3PtfdHR0crNzVVdXV0YJ7s0fD6fJEXEn+XXKSkpUX5+fsCfcaT67W9/qxEjRuiuu+5Samqqrr/+ej377LPhHqtb3HzzzaqtrdXBgwclSe+//75+97vfady4cSF5/B7x24wvRFRUlLZs2aLx48erX79+io6OVmpqqjZv3hyRl9o+/vhjSdKCBQv0xBNPaNCgQXr88cd1yy236ODBgxH3l59lWbr77rv105/+VCNGjNAnn3wS7pEuqY8++kjLly/XY489Fu5RLtof//hHdXZ2nvUt0i6XS/v37w/TVJdGV1eXpk+frpEjR+qaa64J9zjdYsOGDdq1a5fq6+vDPcol8fHHH2vlypUqKyvTz3/+c9XX1+tnP/uZ4uLiVFRUFO7xQmr27Nny+/3KzMxUTEyMOjs7tWTJEhUWFobk8XvcFZTZs2crKirqr2779++XZVkqKSlRamqq3n77be3cuVPjx4/XHXfcoc8++yzcp3Hezvd8u7q6JEm/+MUvVFBQoOHDh2vNmjWKiorSxo0bw3wW5+98z3f58uU6fvy4ysvLwz3yRTnf8/1Ln376qW699Vbdddddmjx5cpgmRyiUlJTogw8+0IYNG8I9SrdoamrSfffdp3Xr1ikhISHc41wSXV1duuGGG/Twww/r+uuv15QpUzR58mStWrUq3KOF3AsvvKB169Zp/fr12rVrl9auXavHHntMa9euDcnj97ivuv/888/1pz/96a+uufrqq/X2229r7Nix+uKLLwJ+9fPgwYNVXFys2bNnd/eoIXG+5/vOO+9o9OjRevvttzVq1Cj7WHZ2tnJzc7VkyZLuHjUkzvd8f/CDH2jTpk2Kioqy93d2diomJkaFhYUh+w+ku53v+cbFxUmSjh49qltuuUU5OTmqqqpSdHSP+/8YZ2lvb1fv3r31X//1XwGfOisqKlJra6tefvnl8A3XjUpLS/Xyyy9r27ZtysjICPc43eKll17SP/3TPykmJsbe19nZqaioKEVHR6utrS3gWCQYOHCgvv/97+tXv/qVvW/lypVavHixPv300zBOFnrp6emaPXu2SkpK7H2LFy/Wc889F5Krnz3uRzxXXHGFrrjiim9c9+WXX0rSWX+BR0dH21cbeoLzPd/hw4crPj5eBw4csAOlo6NDn3zyiQYOHNjdY4bM+Z7vsmXLtHjxYvv20aNHlZeXp+eff17Z2dndOWJIne/5Sn++cvK9733PvjoWCXEiSXFxcRo+fLhqa2vtQOnq6lJtba1KS0vDO1w3sCxL06ZN04svvqi33norYuNEksaMGaM9e/YE7LvnnnuUmZmpWbNmRVycSNLIkSPP+tj4wYMHe9Tfw+fryy+/POvvoZiYmNC9xobkrbYG+vzzz62UlBRrwoQJ1u7du60DBw5YDzzwgNWrVy9r9+7d4R6vW9x3333WlVdeab3++uvW/v37reLiYis1NdU6duxYuEfrdocPH47oT/EcOXLE+va3v22NGTPGOnLkiPXZZ5/ZWyTYsGGDFR8fb1VVVVn79u2zpkyZYiUlJVlerzfco4Xc1KlTLafTab311lsBf45ffvlluEe7JCL9Uzw7d+60YmNjrSVLlliHDh2y1q1bZ/Xu3dt67rnnwj1ayBUVFVlXXnmlVV1dbR0+fNj6zW9+Y11++eXWgw8+GJLHj9hAsSzLqq+vt8aOHWslJydb/fr1s3JycqxXX3013GN1m/b2duv++++3UlNTrX79+lm5ubnWBx98EO6xLolID5Q1a9ZYks65RYrly5dbAwYMsOLi4qybbrrJ2r59e7hH6hZf9+e4Zs2acI92SUR6oFiWZW3atMm65pprrPj4eCszM9N65plnwj1St/D7/dZ9991nDRgwwEpISLCuvvpq6xe/+IXV1tYWksfvce9BAQAAkS8yfogNAAAiCoECAACMQ6AAAADjECgAAMA4BAoAADAOgQIAAIxDoAAAAOMQKAAAwDgECgAAMA6BAgAAjEOgAAAA4xAoAADAOP8P6eO9dCrhrxkAAAAASUVORK5CYII=", + "image/png": "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2mtKT09XTEyMrrjiCk2YMCHUU+oSzc3NGjFihMLCwrRnz55QTydoPvnkE+Xn5ys5OVkxMTH6zne+o0ceeUQtLS2hnlqnWbFihYYMGaLo6Gilp6dr165doZ5S0JSUlOjmm2/WgAEDlJCQoAkTJujQoUOhnlaXefzxxxUWFqYZM2aEeipB9dlnn+mnP/2p4uPjFRMTo+HDh+v9998P9bSCoq2tTfPmzfP7O2rRokWX9Dt3LqZHBsqdd96ps2fP6u2331Ztba1uvPFG3XnnnfJ4PKGeWlD813/9lyZPnqz77rtPH3zwgd577z390z/9U6in1SUefvjhS/rK5O7u4MGDam9v17PPPqv9+/dr6dKlKisr0y9/+ctQT61TvPjiiyoqKtIjjzyi3bt368Ybb1RWVpYaGhpCPbWg2Lp1qwoKCrRjxw5VVlaqtbVV48aN0+nTp0M9taCrqanRs88+qxtuuCHUUwmqL7/8UqNGjVKfPn30xhtv6MCBA3rqqad0xRVXhHpqQfHEE09o1apV+vWvf60PP/xQTzzxhEpLS7V8+fKOn9TqYb744gtLkrVt2zbfPq/Xa0myKisrQziz4GhtbbWuvvpq6ze/+U2op9LlXn/9dSslJcXav3+/Jcn6wx/+EOopdanS0lIrOTk51NPoFLfccotVUFDge9zW1mYlJiZaJSUlIZxV12loaLAkWVu3bg31VILq5MmT1tChQ63Kykrr7//+760HHngg1FMKmtmzZ1ujR48O9TS6THZ2tnX//ff77Zs4caKVm5vb4XP2uDso8fHx+t73vqff/va3On36tM6ePatnn31WCQkJSktLC/X0Ot3u3bv12WefKTw8XDfddJMGDhyo8ePHa9++faGeWlDV19drypQp+o//+A/17ds31NMJiaamJsXFxYV6GpetpaVFtbW1yszM9O0LDw9XZmamqqurQzizrtPU1CRJPeLP85sUFBQoOzvb78+6p/rd736nkSNH6p577lFCQoJuuukmPf/886GeVtDceuutqqqq0uHDhyVJH3zwgX7/+99r/PjxHT5nt/htxoEICwvTli1bNGHCBA0YMEDh4eFKSEjQ5s2be+SttY8//liStGDBAj399NMaMmSInnrqKd122206fPhwj/wLz7Is3Xvvvfr5z3+ukSNH6pNPPgn1lLrcRx99pOXLl+vJJ58M9VQu25/+9Ce1tbWd9y3STqdTBw8eDNGsuk57e7tmzJihUaNG6frrrw/1dIJmw4YN2r17t2pqakI9lS7x8ccfa9WqVSoqKtIvf/lL1dTU6Be/+IWioqKUl5cX6ul1ujlz5sjr9SolJUURERFqa2vTkiVLlJub2+Fzdps7KHPmzFFYWNg3bgcPHpRlWSooKFBCQoLeffdd7dq1SxMmTNBdd92lzz//PNTLuGSXut729nZJ0q9+9Svl5OQoLS1Na9asUVhYmDZu3BjiVQTmUte8fPlynTx5UsXFxaGe8mW71DX/tc8++0y333677rnnHk2ZMiVEM0dnKSgo0L59+7Rhw4ZQTyVojh07pgceeEDr1q1TdHR0qKfTJdrb2/X9739fjz32mG666SZNnTpVU6ZMUVlZWainFhQvvfSS1q1bp/Xr12v37t1au3atnnzySa1du7bD5+w2X3X/xRdf6M9//vM3jrn22mv17rvvaty4cfryyy/9fs3z0KFDlZ+frzlz5gR7qp3iUtf73nvvacyYMXr33Xc1evRo37H09HRlZmZqyZIlwZ5qp7nUNf/oRz/Spk2bFBYW5tvf1tamiIgI5ebmXtZ/EF3tUtccFRUlSTp+/Lhuu+02ZWRkqLy8XOHh3eb/MS6qpaVFffv21X/+53/6ffosLy9PjY2NevXVV0M3uSArLCzUq6++qm3btik5OTnU0wmaV155Rf/wD/+giIgI3762tjaFhYUpPDxczc3Nfsd6gsGDB+uHP/yhfvOb3/j2rVq1SosXL9Znn30WwpkFR1JSkubMmaOCggLfvsWLF+uFF17o8J3QbvMjnquuukpXXXXVt4776quvJOm8v7jDw8N9dxu6g0tdb1pammw2mw4dOuQLlNbWVn3yyScaPHhwsKfZqS51zcuWLdPixYt9j48fP66srCy9+OKLSk9PD+YUO92lrln6y52TH/zgB767ZD0hTiQpKipKaWlpqqqq8gVKe3u7qqqqVFhYGNrJBYllWZo+fbpefvllvfPOOz06TiRp7Nix2rt3r9++++67TykpKZo9e3aPixNJGjVq1HkfHT98+HC3+3v5Un311Vfn/Z0UERFxea+7l/GmXSN98cUXVnx8vDVx4kRrz5491qFDh6yHHnrI6tOnj7Vnz55QTy8oHnjgAevqq6+23nzzTevgwYNWfn6+lZCQYJ04cSLUU+sSR48e7fGf4vn000+t7373u9bYsWOtTz/91Pr88899W0+wYcMGy2azWeXl5daBAwesqVOnWrGxsZbH4wn11IJi2rRplsPhsN555x2/P8uvvvoq1FPrMj39Uzy7du2yIiMjrSVLllhHjhyx1q1bZ/Xt29d64YUXQj21oMjLy7Ouvvpqq6Kiwjp69Kj13//939aVV15pPfzwwx0+Z48LFMuyrJqaGmvcuHFWXFycNWDAACsjI8N6/fXXQz2toGlpabEefPBBKyEhwRowYICVmZlp7du3L9TT6jK9IVDWrFljSbrg1lMsX77cGjRokBUVFWXdcsst1o4dO0I9paC52J/lmjVrQj21LtPTA8WyLGvTpk3W9ddfb9lsNislJcV67rnnQj2loPF6vdYDDzxgDRo0yIqOjrauvfZa61e/+pXV3Nzc4XN2m/egAACA3qNn/BAbAAD0KAQKAAAwDoECAACMQ6AAAADjECgAAMA4BAoAADAOgQIAAIxDoAAAAOMQKAAAwDgECgAAMA6BAgAAjEOgAAAA4/x/0Dmw4dKT15EAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -309,6 +375,70 @@ "plt.hist(out_ff.detach().squeeze())\n", "plt.show()" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "DataBatch(edge_index=[2, 53760], shifts=[53760, 3], unit_shifts=[53760, 3], positions=[8960, 3], cell=[3840, 3], node_attrs=[8960, 2], graph_labels=[1280, 1], n_system=[1280, 1], weight=[1280], batch=[8960], ptr=[1281])\n", + "DataBatch(edge_index=[2, 53760], shifts=[53760, 3], unit_shifts=[53760, 3], positions=[8960, 3], cell=[3840, 3], node_attrs=[8960, 2], graph_labels=[1280, 1], n_system=[1280, 1], weight=[1280], batch=[8960], ptr=[1281])\n", + "DataBatch(edge_index=[2, 53760], shifts=[53760, 3], unit_shifts=[53760, 3], positions=[8960, 3], cell=[3840, 3], node_attrs=[8960, 2], graph_labels=[1280, 1], n_system=[1280, 1], weight=[1280], batch=[8960], ptr=[1281])\n", + "DataBatch(edge_index=[2, 53760], shifts=[53760, 3], unit_shifts=[53760, 3], positions=[8960, 3], cell=[3840, 3], node_attrs=[8960, 2], graph_labels=[1280, 1], n_system=[1280, 1], weight=[1280], batch=[8960], ptr=[1281])" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "{'edge_index': tensor([[ 0, 0, 0, ..., 8959, 8959, 8959],\n", + " [ 1, 4, 5, ..., 8955, 8956, 8957]], device='cuda:0'), 'shifts': tensor([[0., 0., 0.],\n", + " [0., 0., 0.],\n", + " [0., 0., 0.],\n", + " ...,\n", + " [0., 0., 0.],\n", + " [0., 0., 0.],\n", + " [0., 0., 0.]], device='cuda:0'), 'unit_shifts': tensor([[0., 0., 0.],\n", + " [0., 0., 0.],\n", + " [0., 0., 0.],\n", + " ...,\n", + " [0., 0., 0.],\n", + " [0., 0., 0.],\n", + " [0., 0., 0.]], device='cuda:0'), 'positions': tensor([[-2.6081, -2.1008, 0.3736],\n", + " [-2.4060, -1.0921, -0.7459],\n", + " [-2.4521, -3.5211, 0.1885],\n", + " ...,\n", + " [-2.1364, -3.1386, 0.5862],\n", + " [-3.5091, -0.7473, -2.1322],\n", + " [-1.6128, -0.9524, -0.9889]], device='cuda:0'), 'cell': tensor([[100., 0., 0.],\n", + " [ 0., 100., 0.],\n", + " [ 0., 0., 100.],\n", + " ...,\n", + " [100., 0., 0.],\n", + " [ 0., 100., 0.],\n", + " [ 0., 0., 100.]], device='cuda:0'), 'node_attrs': tensor([[1., 0.],\n", + " [1., 0.],\n", + " [1., 0.],\n", + " ...,\n", + " [1., 0.],\n", + " [1., 0.],\n", + " [0., 1.]], device='cuda:0'), 'graph_labels': tensor([[0.],\n", + " [0.],\n", + " [0.],\n", + " ...,\n", + " [0.],\n", + " [0.],\n", + " [1.]], device='cuda:0'), 'n_system': tensor([[7.],\n", + " [7.],\n", + " [7.],\n", + " ...,\n", + " [7.],\n", + " [7.],\n", + " [7.]], device='cuda:0'), 'weight': tensor([1., 1., 1., ..., 1., 1., 1.], device='cuda:0'), 'batch': tensor([ 0, 0, 0, ..., 1279, 1279, 1279], device='cuda:0'), 'ptr': tensor([ 0, 7, 14, ..., 8946, 8953, 8960], device='cuda:0')}" + ] } ], "metadata": {