{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Running C++ in Notebooks\n\nHat tip to this discussion: https://www.kaggle.com/c/abstraction-and-reasoning-challenge/discussion/131230\n\nSince the Kaggle image has a the `gcc` compiler and `g++`, it is actually possible to run C++ code in Kaggle Notebooks.\n\nLet's see what version of `gcc` we have:","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true}},{"cell_type":"code","source":"!g++ -v","metadata":{"execution":{"iopub.status.busy":"2022-07-26T23:19:47.754291Z","iopub.execute_input":"2022-07-26T23:19:47.754953Z","iopub.status.idle":"2022-07-26T23:19:48.576113Z","shell.execute_reply.started":"2022-07-26T23:19:47.754892Z","shell.execute_reply":"2022-07-26T23:19:48.575103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"I've written a short test script that writes to a file called `submission.csv`. Let's take a look:","metadata":{}},{"cell_type":"markdown","source":"# 写C++的\n[参考链接](https://www.bilibili.com/read/cv14231336)","metadata":{}},{"cell_type":"code","source":"%%writefile CppHelloWorld.hpp\n\n#include <iostream>\n\nvoid printHelloWorld()\n\n{\n\nstd::cout << \"HelloWorld\\nHelloWorld\";\n\n}","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:03:30.296909Z","iopub.execute_input":"2022-07-27T00:03:30.297230Z","iopub.status.idle":"2022-07-27T00:03:30.305864Z","shell.execute_reply.started":"2022-07-27T00:03:30.297199Z","shell.execute_reply":"2022-07-27T00:03:30.305003Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%writefile CppHelloWorld.cpp\n\n#include \"CppHelloWorld.hpp\"\n\nint main()\n\n{\n\nprintHelloWorld();\n\nreturn 0;\n\n}","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:03:32.786471Z","iopub.execute_input":"2022-07-27T00:03:32.786831Z","iopub.status.idle":"2022-07-27T00:03:32.793637Z","shell.execute_reply.started":"2022-07-27T00:03:32.786792Z","shell.execute_reply":"2022-07-27T00:03:32.792674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%script bash\n\ng++ CppHelloWorld.cpp -std=c++11\n\n./a.out","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:03:36.334022Z","iopub.execute_input":"2022-07-27T00:03:36.334343Z","iopub.status.idle":"2022-07-27T00:03:37.021666Z","shell.execute_reply.started":"2022-07-27T00:03:36.334311Z","shell.execute_reply":"2022-07-27T00:03:37.020848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 写Cuda的1：简单Cpp测试","metadata":{}},{"cell_type":"code","source":"%%writefile add.cpp\n#include <iostream>\n#include <math.h>\n#include <sys/time.h>\n\n// function to add the elements of two arrays\nvoid add(int n, float *x, float *y)\n{\n  for (int i = 0; i < n; i++)\n      y[i] = x[i] + y[i];\n}\n\nint main(void)\n{\n  int N = 1<<25; // 30M elements\n\n  float *x = new float[N];\n  float *y = new float[N];\n\n  // initialize x and y arrays on the host\n  for (int i = 0; i < N; i++) {\n    x[i] = 1.0f;\n    y[i] = 2.0f;\n  }\n\n  struct timeval t1,t2;\n  double timeuse;\n  gettimeofday(&t1,NULL);\n  // Run kernel on 30M elements on the CPU\n  add(N, x, y);\n  gettimeofday(&t2,NULL);\n  timeuse = (t2.tv_sec - t1.tv_sec) + (double)(t2.tv_usec - t1.tv_usec)/1000.0;\n\n  std::cout << \"add(int, float*, float*) time: \" << timeuse << \"ms\" << std::endl;\n  // Check for errors (all values should be 3.0f)\n  float maxError = 0.0f;\n  for (int i = 0; i < N; i++)\n    maxError = fmax(maxError, fabs(y[i]-3.0f));\n  std::cout << \"Max error: \" << maxError << std::endl;\n\n  // Free memory\n  delete [] x;\n  delete [] y;\n\n  return 0;\n}","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:03:39.847379Z","iopub.execute_input":"2022-07-27T00:03:39.847731Z","iopub.status.idle":"2022-07-27T00:03:39.853794Z","shell.execute_reply.started":"2022-07-27T00:03:39.847698Z","shell.execute_reply":"2022-07-27T00:03:39.852838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%script bash\ng++ add.cpp -o add\n./add","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:03:43.148327Z","iopub.execute_input":"2022-07-27T00:03:43.148977Z","iopub.status.idle":"2022-07-27T00:03:44.477377Z","shell.execute_reply.started":"2022-07-27T00:03:43.148933Z","shell.execute_reply":"2022-07-27T00:03:44.476445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 写CUda:Cuda代码\n[参考链接](https://zhuanlan.zhihu.com/p/507678214)","metadata":{}},{"cell_type":"code","source":"%%writefile add.cu\n\n#include <iostream>\n#include <math.h>\n// Kernel function to add the elements of two arrays\n// __global__ 变量声明符，作用是将add函数变成可以在GPU上运行的函数\n// __global__ 函数被称为kernel，\n// 在 GPU 上运行的代码通常称为设备代码（device code），而在 CPU 上运行的代码是主机代码（host code）。\n__global__ \nvoid add(int n, float *x, float *y)\n{\n  for (int i = 0; i < n; i++)\n    y[i] = x[i] + y[i];\n}\n\nint main(void)\n{\n  int N = 1<<25;\n  float *x, *y;\n\n  // Allocate Unified Memory – accessible from CPU or GPU\n  // 内存分配，在GPU或者CPU上统一分配内存\n  cudaMallocManaged(&x, N*sizeof(float));\n  cudaMallocManaged(&y, N*sizeof(float));\n\n  // initialize x and y arrays on the host\n  for (int i = 0; i < N; i++) {\n    x[i] = 1.0f;\n    y[i] = 2.0f;\n  }\n\n  // Run kernel on 1M elements on the GPU\n  // execution configuration, 执行配置\n  add<<<1, 1>>>(N, x, y);\n\n  // Wait for GPU to finish before accessing on host\n  // CPU需要等待cuda上的代码运行完毕，才能对数据进行读取\n  cudaDeviceSynchronize();\n\n  // Check for errors (all values should be 3.0f)\n  float maxError = 0.0f;\n  for (int i = 0; i < N; i++)\n    maxError = fmax(maxError, fabs(y[i]-3.0f));\n  std::cout << \"Max error: \" << maxError << std::endl;\n\n  // Free memory\n  cudaFree(x);\n  cudaFree(y);\n  \n  return 0;\n}","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:05:06.003786Z","iopub.execute_input":"2022-07-27T00:05:06.004143Z","iopub.status.idle":"2022-07-27T00:05:06.011720Z","shell.execute_reply.started":"2022-07-27T00:05:06.004113Z","shell.execute_reply":"2022-07-27T00:05:06.010626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%script bash\nnvcc ./add.cu -o add_cuda \n./add_cuda","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:05:11.023280Z","iopub.execute_input":"2022-07-27T00:05:11.023672Z","iopub.status.idle":"2022-07-27T00:05:19.109442Z","shell.execute_reply.started":"2022-07-27T00:05:11.023633Z","shell.execute_reply":"2022-07-27T00:05:19.108645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%script bash\nnvprof ./add_cuda","metadata":{"execution":{"iopub.status.busy":"2022-07-27T00:05:29.567666Z","iopub.execute_input":"2022-07-27T00:05:29.568008Z","iopub.status.idle":"2022-07-27T00:05:36.268492Z","shell.execute_reply.started":"2022-07-27T00:05:29.567977Z","shell.execute_reply":"2022-07-27T00:05:36.267616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 其他代码参考","metadata":{}},{"cell_type":"code","source":"! head -n 20 ../input/codecuda/add.cpp","metadata":{"execution":{"iopub.status.busy":"2022-07-26T23:24:25.643806Z","iopub.execute_input":"2022-07-26T23:24:25.644246Z","iopub.status.idle":"2022-07-26T23:24:26.453117Z","shell.execute_reply.started":"2022-07-26T23:24:25.644207Z","shell.execute_reply":"2022-07-26T23:24:26.452096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! head -n 20 /kaggle/input/c-execution-example/test_c_code.cpp","metadata":{"execution":{"iopub.status.busy":"2022-07-26T23:19:48.578685Z","iopub.execute_input":"2022-07-26T23:19:48.579454Z","iopub.status.idle":"2022-07-26T23:19:49.383859Z","shell.execute_reply.started":"2022-07-26T23:19:48.579398Z","shell.execute_reply":"2022-07-26T23:19:49.382707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"This file can be uploaded in a dataset or written within the notebook!\n\nOk, let's run the code","metadata":{}},{"cell_type":"code","source":"import os\nimport pandas as pd\n\nos.system(\"g++ /kaggle/input/c-execution-example/test_c_code.cpp && ./a.out\")","metadata":{"execution":{"iopub.status.busy":"2022-07-26T23:19:49.385574Z","iopub.execute_input":"2022-07-26T23:19:49.385924Z","iopub.status.idle":"2022-07-26T23:19:50.173098Z","shell.execute_reply.started":"2022-07-26T23:19:49.385887Z","shell.execute_reply":"2022-07-26T23:19:50.171778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Here's the submission file:","metadata":{}},{"cell_type":"code","source":"submission = pd.read_csv(\"submission.csv\")\nsubmission","metadata":{"execution":{"iopub.status.busy":"2022-07-26T23:19:50.174803Z","iopub.execute_input":"2022-07-26T23:19:50.175157Z","iopub.status.idle":"2022-07-26T23:19:50.203307Z","shell.execute_reply.started":"2022-07-26T23:19:50.175120Z","shell.execute_reply":"2022-07-26T23:19:50.202235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}