diff --git a/.github/workflows/deploy-docs-to-azure.yaml b/.github/workflows/deploy-docs-to-azure.yaml new file mode 100644 index 000000000..e4b560752 --- /dev/null +++ b/.github/workflows/deploy-docs-to-azure.yaml @@ -0,0 +1,31 @@ +name: Codeflash Docs Publish to Azure Static Web Apps + +on: + push: + branches: + - main + paths: + - 'docs/**' + - '.github/workflows/deploy-docs-to-azure.yaml' + workflow_dispatch: + +jobs: + build_and_deploy_job: + if: github.event_name == 'push' || (github.event_name == 'pull_request' && github.event.action != 'closed') + runs-on: ubuntu-latest + name: Build and Deploy Job + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - name: Build And Deploy + id: builddeploy + uses: Azure/static-web-apps-deploy@v1 + with: + azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN }} + repo_token: ${{ secrets.GITHUB_TOKEN }} # Used for GitHub integrations (i.e. PR comments) + action: "upload" + ###### Repository/Build Configurations ###### + app_location: "docs" # App source code path relative to repository root + output_location: "build" # Built app content directory, relative to app_location - optional + ###### End of Repository/Build Configurations ###### diff --git a/.github/workflows/unit-tests.yaml b/.github/workflows/unit-tests.yaml new file mode 100644 index 000000000..a1e7da8ea --- /dev/null +++ b/.github/workflows/unit-tests.yaml @@ -0,0 +1,41 @@ +name: unit-tests + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +jobs: + unit-tests: + strategy: + fail-fast: false + matrix: + python-version: [3.9.18, 3.10.13, 3.11.6, 3.12.1, 3.13.0] + continue-on-error: true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + python-version: ${{ matrix.python-version }} + version: "0.5.30" + - name: install poetry as a tool + run: uv tool install poetry + + - name: install dependencies + run: uvx poetry install --with dev + + - name: Unit tests + run: uvx poetry run pytest tests/ --cov --cov-report=xml + + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + if: matrix.python-version == '3.12.1' + with: + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/docs/.gitignore b/docs/.gitignore new file mode 100644 index 000000000..b083ed4f9 --- /dev/null +++ b/docs/.gitignore @@ -0,0 +1,21 @@ +# Dependencies +/node_modules + +# Production +/build + +# Generated files +.docusaurus +.cache-loader + +# Misc +.DS_Store +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +npm-debug.log* +yarn-debug.log* +yarn-error.log* diff --git a/docs/README.md b/docs/README.md new file mode 100644 index 000000000..03fa70727 --- /dev/null +++ b/docs/README.md @@ -0,0 +1,29 @@ +# Website + +This website is built using [Docusaurus](https://docusaurus.io/), a modern static website generator. + +### Installation + +``` +$ npm install +``` + +### Local Development + +``` +$ npm run start +``` + +This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. + +### Build + +``` +$ npm run build +``` + +This command generates static content into the `build` directory and can be served using any static contents hosting service. + +### Deployment + +Deployment is done automatically via GitHub Actions when the Pull Request changes are merged to the `main` branch. diff --git a/docs/babel.config.js b/docs/babel.config.js new file mode 100644 index 000000000..e00595dae --- /dev/null +++ b/docs/babel.config.js @@ -0,0 +1,3 @@ +module.exports = { + presets: [require.resolve('@docusaurus/core/lib/babel/preset')], +}; diff --git a/docs/docs/configuration.md b/docs/docs/configuration.md new file mode 100644 index 000000000..5208fb99c --- /dev/null +++ b/docs/docs/configuration.md @@ -0,0 +1,60 @@ +--- +sidebar_position: 5 +--- + +# Manual Configuration + +Codeflash is installed and configured on a per-project basis. +`codeflash init` should guide you through the configuration process, but if you need to manually configure Codeflash or set advanced settings, you can do so by editing the `pyproject.toml` file in the root directory of your project. + +## Configuration Options +Codeflash config looks like the following +```toml +[tool.codeflash] +module-root = "my_module" +tests-root = "tests" +test-framework = "pytest" +formatter-cmds = ["black $file"] +# optional configuration +ignore-paths = ["my_module/build/"] +pytest-cmd = "pytest" +disable-imports-sorting = false +disable-telemetry = false +``` +All file paths are relative to the directory of the `pyproject.toml` file. + +Required Options: +- `module-root`: The Python module you want Codeflash to optimize going forward. Only code under this directory will be optimized. It should also have an `__init__.py` file to make the module importable. +- `tests-root`: The directory where your tests are located. Codeflash will use this directory to discover existing tests as well as generate new tests. +- `test-framework`: The test framework you use for your project. Codeflash supports `pytest` and `unittest`. + +Optional Configuration: +- `ignore-paths`: A list of paths withing the `module-root` to ignore when optimizing code. Codeflash will not optimize code in these paths. Useful for ignoring build directories or other generated code. You can also leave this empty if not needed. +- `pytest-cmd`: The command to run your tests. Defaults to `pytest`. You can specify extra commandline arguments here for pytest. +- `formatter-cmds`: The command line to run your code formatter or linter. Defaults to `["black $file"]`. In the command line `$file` refers to the current file being optimized. The assumption with using tools here is that they overwrite the same file and returns a zero exit code. You can also specify multiple tools here that run in a chain as a toml array. You can also disable code formatting by setting this to `["disabled"]`. + - `ruff` - A recommended way to run ruff linting and formatting is `["ruff check --exit-zero --fix $file", "ruff format $file"]`. To make `ruff check --fix` return a 0 exit code please add a `--exit-zero` argument. +- `disable-imports-sorting`: By default, codeflash uses isort to organize your imports before creating suggestions. You can disable this by setting this field to `true`. This could be useful if you don't sort your imports or while using linters like ruff that sort imports too. +- `disable-telemetry`: Disable telemetry data collection. Defaults to `false`. Set this to `true` to disable telemetry data collection. Codeflash collects anonymized telemetry data to understand how users are using Codeflash and to improve the product. Telemetry does not collect any code data. + +## Example Configuration +Here's an example project with the following structure: +```text +acme-project/ +|- foo_module/ +| |- __init__.py +| |- foo.py +| |- main.py +|- tests/ +| |- __init__.py +| |- test_script.py +|- pyproject.toml +``` + +Here's a sample `pyproject.toml` file for the above project: +```toml +[tool.codeflash] +module-root = "foo_module" +tests-root = "tests" +test-framework = "pytest" # or "unittest" +ignore-paths = [] +``` diff --git a/docs/docs/getting-started/_category_.json b/docs/docs/getting-started/_category_.json new file mode 100644 index 000000000..52b54bbbc --- /dev/null +++ b/docs/docs/getting-started/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Getting Started", + "position": 2, + "collapsed": false +} diff --git a/docs/docs/getting-started/codeflash-github-actions.md b/docs/docs/getting-started/codeflash-github-actions.md new file mode 100644 index 000000000..426d9c32a --- /dev/null +++ b/docs/docs/getting-started/codeflash-github-actions.md @@ -0,0 +1,125 @@ +--- +sidebar_position: 2 +--- + +# Automate Optimization of Pull Requests + + +Codeflash can automatically optimize your code when new pull requests are opened. + +To be able to scan new code for performance optimizations, Codeflash requires a GitHub action workflow to +be installed which runs the Codeflash optimization logic on every new pull request. +If the action workflow finds an optimization, it communicates with the Codeflash GitHub +App through our secure servers and asks it to suggest new changes to the pull request. + +This is the most useful way of using Codeflash, where you set it up once and all your new code gets optimized. +So setting this up is highly recommended. + +## Prerequisites +- You have a Codeflash API key. If you don't have one, you can generate one from the [Codeflash Webapp](https://app.codeflash.ai/). Make sure you generate the API key with the right GitHub account that has access to the repository you want to optimize. +- You have completed [local installation](/getting-started/local-installation) steps and have a Python project with a `pyproject.toml` file that is configured with Codeflash. If you haven't configured Codeflash for your project yet, you can do so by running `codeflash init` in the root directory of your project. + +## Add the Codeflash GitHub Actions workflow + +### Guided setup + +To add the Codeflash GitHub Actions workflow to your repository, you can run the following command in your project directory: + +```bash +codeflash init-actions +``` + +This will walk you through the process of adding the Codeflash GitHub Actions workflow to your repository. + +### All Set up! + +Open a new PR to your GitHub project, and you will now see a new actions workflow for Codeflash run. If it finds an optimization, +codeflash-ai bot will comment on your repo with the optimization suggestions. + +### Manual Installation (optional) +If you prefer to install the GitHub actions manually, follow the steps below - + +#### Add the workflow file +Create a new file in your repository at `.github/workflows/codeflash-optimize.yaml` with the following contents: + + +```yaml title=".github/workflows/codeflash-optimize.yaml" +name: Codeflash + +on: + pull_request: + workflow_dispatch: + +jobs: + optimize: + name: Optimize new code in this PR + if: ${{ github.actor != 'codeflash-ai[bot]' }} + runs-on: ubuntu-latest + env: + CODEFLASH_API_KEY: ${{ secrets.CODEFLASH_API_KEY }} + CODEFLASH_PR_NUMBER: ${{ github.event.number }} + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + # TODO: Replace the following with your project's Python installation method + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: '3.11' + # TODO: Replace the following with your project's dependency installation method + - name: Install Project Dependencies + run: | + python -m pip install --upgrade pip + # TODO: Replace the following with your project setup method + pip install -r requirements.txt + pip install codeflash + - name: Run Codeflash to optimize code + id: optimize_code + run: | + codeflash +``` +You would need to fill in the `#TODO`s in the file above to make it work. Please commit this file to your repository. +If you use a particular Python package manager like Poetry or uv, some helpful configurations are provided below. + +#### Config with different Python package managers + +The yaml config above is a basic template. Here is how you can run Codeflash with the different Python package managers: + +1. Poetry + +```yaml + - name: Install Project Dependencies + run: | + python -m pip install --upgrade pip + pip install poetry + poetry install --with dev + - name: Run Codeflash to optimize code + id: optimize_code + run: | + poetry env use python + poetry run codeflash +``` +This assumes that you install poetry with pip and have Codeflash dependency in the `dev` section of your `pyproject.toml` file. + +2. uv + +```yaml + - uses: astral-sh/setup-uv@v4 + with: + enable-cache: true + - run: uv sync --group=dev + - name: Run Codeflash to optimize code + run: uv run codeflash +``` + +#### Add your API key to your repository secrets + +Go to your GitHub repository, click **Settings**, and click on **Secrets and +Variables** -> **Actions** on the left sidebar. + +Add the following secret: + +- `CODEFLASH_API_KEY`: The API key you got from https://app.codeflash.ai/app/apikeys + diff --git a/docs/docs/getting-started/local-installation.md b/docs/docs/getting-started/local-installation.md new file mode 100644 index 000000000..8cf333268 --- /dev/null +++ b/docs/docs/getting-started/local-installation.md @@ -0,0 +1,66 @@ +--- +sidebar_position: 1 +--- + +# Local Installation + +Codeflash is installed and configured on a per-project basis. + +You can install Codeflash locally for a project by running the following command in the project's virtual environment: + +```bash +pip install codeflash +``` + +:::tip[Codeflash is a Development Dependency] +We recommend installing Codeflash as a development dependency. +It doesn't need to be installed as part of your package requirements. +Codeflash is intended to be used locally and as part of development workflows such as CI. +::: + +## Generate a Codeflash API Key + +Since Codeflash uses advanced Large Language Models (LLMs) that are hosted in the cloud, you will need to generate an API key to use Codeflash. + +To generate an API key, visit the [Codeflash Web App](https://app.codeflash.ai/) and sign up for an account with GitHub login. + +Once you have signed up, you will be able to generate an API key from the [API Key](https://app.codeflash.ai/app/apikeys) page. +You will need the API key in the next step. + +## Automatic Configuration + +To configure Codeflash for a project, in the root directory of your project where your `pyproject.toml` file is located, run the following command : + +```bash +codeflash init +``` + +If you don't have a pyproject.toml file yet, the codeflash init command will ask you to create one + +:::tip[What's pyproject.toml?] +`pyproject.toml` is a configuration file that is used to specify build tool settings for Python projects. +pyproject.toml is the modern replacement for setup.py and requirements.txt files. +It's the new standard for Python package metadata. +::: + +When running `codeflash init`, you will see the following prompts: + +```text +1. Enter your Codeflash API key: +2. Which Python module do you want me to optimize going forward? (e.g. my_module) +3. Where are your tests located? (e.g. tests/) +4. Which test framework do you use? (pytest/unittest) +``` + +After you have answered these questions, Codeflash will be configured for your project. +The configuration will be saved in the `pyproject.toml` file in the root directory of your project. +To understand the configuration options, and set more advanced options, see the [Configuration](/configuration) page. + +## Install the Codeflash GitHub App + +Finally, if you have not done so already, Codeflash will ask you to install the Github App in your repository. The Codeflash GitHub App allows access to your repository to the codeflash-ai bot to open PRs, review code, and provide optimization suggestions. + +Please [install the Codeflash GitHub +app](https://github.com/apps/codeflash-ai/installations/select_target) by choosing the repository you want to install +Codeflash on. +## diff --git a/docs/docs/getting-the-best-out-of-codeflash.md b/docs/docs/getting-the-best-out-of-codeflash.md new file mode 100644 index 000000000..6ea20dfbc --- /dev/null +++ b/docs/docs/getting-the-best-out-of-codeflash.md @@ -0,0 +1,25 @@ +--- +sidebar_position: 5 +--- + +# Getting the best out of Codeflash + +Codeflash is a powerful tool; here are our recommendations, tips and tricks on getting the best out of it. We do these ourselves, so we hope you will too! + +### Install the Github App and actions workflow + +After you install Codeflash on an actively developed project, [installing the GitHub App](getting-started/codeflash-github-actions) and setting up the +GitHub Actions workflow will automatically optimize your code whenever new pull requests are opened. This ensures you get the best version of any changes you make to your code without any extra effort. We find that PRs are also the best time to review these changes, because the code is fresh in your mind. + +### Find optimizations on your whole codebase with `codeflash --all` + +If you have a lot of existing code, run [`codeflash --all`](optimizing-with-codeflash/codeflash-all) to discover and fix any +slow code in your project. Codeflash will open new pull requests for any optimizations it finds, and you can review and merge them at your own pace. + +### Find and optimize bottlenecks with the Codeflash Tracer + +Find the best results by running [Codeflash Tracer](optimizing-with-codeflash/trace-and-optimize) on the entry point of your script before optimizing it. The Codeflash Tracer will generate a trace file and a Replay Test file that will help Codeflash understand the behavior & inputs of your functions and generate the highest quality optimizations. + +### Review the PRs Codeflash opens + +We're constantly improving Codeflash and the underlying AI models it uses. The state of the art changes weekly, and you can be confident the optimizer will always use the best performing LLMs to find optimizations for your code. That said, because Codeflash uses generative AI, it's still possible that the optimized code may actually have different behavior than the original code under certain conditions. Please review all the PRs that Codeflash opens to ensure that the optimized code is correct, just as you would review any other PR opened by a team member. And don't forget to send us feedback on how we can improve Codeflash - we're always listening! \ No newline at end of file diff --git a/docs/docs/how-codeflash-works.md b/docs/docs/how-codeflash-works.md new file mode 100644 index 000000000..5c31bb1f6 --- /dev/null +++ b/docs/docs/how-codeflash-works.md @@ -0,0 +1,63 @@ +--- +sidebar_position: 4 +--- +# How Codeflash Works + +Codeflash follows a "generate and verify" approach to optimize code. It uses LLMs to generate optimizations, then it rigorously verifies if those optimizations are indeed +faster and if they have the same behavior. The basic unit of optimization is a function—Codeflash tries to speed up the function, and tries to ensure that it still behaves the same way. This way if you merge the optimized code, it simply runs faster without breaking any functionality. + +## Analysis of your code + +Codeflash scans your codebase to identify all available functions. It locates existing unit tests in your projects and maps which functions they test. When optimizing a function, Codeflash runs these discovered tests to verify nothing has broken. + +#### What kind of functions can Codeflash optimize? + +Codeflash works best with self-contained functions that have minimal side effects (like communicating with external systems or sending network requests). Codeflash optimizes a group of functions - consisting of an entry point function and any other functions it directly calls. +Currently, Codeflash cannot optimize async functions. + +#### Test Discovery + +Codeflash currently only runs tests that directly call the target function in their test body. To discover tests that indirectly call the function, you can use the Codeflash Tracer. The Tracer analyzes your test suite and identifies all tests that eventually call a function. + +## Optimization Generation + +To optimize code, Codeflash first gathers all necessary context from the codebase. It then calls our backend to generate several candidate optimizations. These are called "candidates" because their speed and correctness haven't been verified yet. Both properties will be verified in later steps. + +## Verification of correctness + +![Verification](/img/verification.svg) + +The goal of correctness verification is to ensure that when the original code is replaced by the new code, there are no behavioral changes in the code and the rest of the system. This means the replacement should be completely safe. + +To verify correctness, Codeflash calls the function with numerous inputs, confirming that the new function behaves identically to the original. + +Codeflash verifies these specific behaviors to be correct - + +- function return values match exactly +- inputs to function have been mutated exactly the same way as before +- exception types remain consistent + +Additionally, Codeflash checks for sufficient line coverage of the optimized code, increasing confidence in the testing process. + +Codeflash also evaluates that there is sufficient line coverage of the code under optimization. This provides more confidence with testing. + +We recommend manually reviewing the optimized code, since there might be important input cases that we haven’t verified where the behavior could differ. + +#### Test Generation + +Codeflash generates two types of tests: + +- LLM Generated tests - Codeflash uses LLMs to create several regression test cases that cover typical function usage, edge cases, and large-scale inputs to verify both correctness and performance. +- Concolic coverage tests - Codeflash uses state-of-the-art concolic testing with an SMT Solver (a theorem prover) to explore execution paths and generate function arguments. This aims to maximize code coverage for the function being optimized. Codeflash runs the resulting test file to verify correctness. Currently, this feature only supports pytest. + +## Code Execution + +Codeflash runs tests for the target function using either pytest or unittest frameworks. The tests execute on your machine, ensuring access to the Python environment and any other dependencies associated to let Codeflash run your code properly. Running on your machine also ensures accurate performance measurements since runtime varies by system. + +#### Performance benchmarking + +Codeflash implements several techniques to measure code performance accurately. In particular, it runs multiple iterations of the code in a loop to determine the best performance with the minimum runtime. Codeflash compares performance of the original code against the optimization, requiring at least a 10% speed improvement before considering it faster. This approach eliminates most runtime measurement variability, even on noisy CI systems and virtual machines. The final runtime Codeflash reports is the minimum total time it took to run all the test cases. + +## Creating Pull Requests + +Once an optimization passes all checks, Codeflash creates a pull request through the Codeflash GitHub app directly in your repository. The pull request includes the new code, the speedup percentage, an explanation of the optimization, test statistics including coverage, and the test content itself. You can review and merge the new code if it meets your standards. Feel free to modify the code as needed—we welcome your improvements! \ No newline at end of file diff --git a/docs/docs/intro.md b/docs/docs/intro.md new file mode 100644 index 000000000..31f2061f0 --- /dev/null +++ b/docs/docs/intro.md @@ -0,0 +1,48 @@ +--- +sidebar_position: 1 +slug: / +--- +# Introduction +Welcome to the Codeflash documentation! + +## What is Codeflash? + +Welcome! Codeflash is an AI performance optimizer for Python code. +Codeflash speeds up Python code by figuring out the best way to rewrite a particular function, while verifying the behavior of the code is unchanged. + +The optimizations Codeflash finds are generally better algorithms, opportunities to remove wasteful compute, better logic, and utilization of more efficient library methods. + +### How does Codeflash verify correctness? + +Codeflash verifies the correctness of the optimizations it finds by generating and running new regression tests, as well as any existing tests you may already have. +This offers additional confidence that the behavior of your code remains unchanged. + +### Continuous Optimization + +Because Codeflash is an automated process, you can install it as a GitHub action and have it run on every pull request made to your codebase. +When Codeflash finds an optimization, it will ask you to review it. It will write a detailed explanation of the changes it made, and include all relevant info like % speed increase and proofs of correctness. + +Having Codeflash installed on your Github repository gives you the peace of mind that your code is always written optimally. We call it *Continuous Optimization*. + +### Features + + + +| Feature | Description | +|-----------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| [Optimize a single function](optimizing-with-codeflash/one-function) | Basic unit of optimization by asking Codeflash to optimize a particular function | +| [Optimize all code in a repo](optimizing-with-codeflash/codeflash-all) | Codeflash discovers all functions in a repo and optimizes all of them! | +| [Optimize every new pull request](optimizing-with-codeflash/optimize-prs) | Codeflash runs as a GitHub action and GitHub app and reviews all new code for Optimizations | +| [Optimize a whole workflow by Tracing it](optimizing-with-codeflash/trace-and-optimize) | End to end optimization for all the functions called in a workflow, by tracing to collect real inputs seen during execution and ensuring correctness and performance optimization with those inputs | +| Correctness Verification | The way Codeflash gains high confidence that the newly generated optimization has the same behavior as the originally written function. | +| Performance Measurement | Measuring execution times on a set of inputs to estimate runtime performance. | + + +## How to use these docs + +On the left side of the screen you'll find the docs navigation bar. +Start by installing Codeflash, then explore the different ways of using it to optimize your code. + +## Questions or Feedback? + +We love feedback! If you have any questions or feedback, use the Intercom button in the lower right, or drop us a note at [founders@codeflash.ai](mailto:founders@codeflash.ai) - we read every message! diff --git a/docs/docs/optimizing-with-codeflash/_category_.json b/docs/docs/optimizing-with-codeflash/_category_.json new file mode 100644 index 000000000..587a0a774 --- /dev/null +++ b/docs/docs/optimizing-with-codeflash/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Using Codeflash", + "position": 3, + "collapsed": false +} diff --git a/docs/docs/optimizing-with-codeflash/codeflash-all.md b/docs/docs/optimizing-with-codeflash/codeflash-all.md new file mode 100644 index 000000000..359316203 --- /dev/null +++ b/docs/docs/optimizing-with-codeflash/codeflash-all.md @@ -0,0 +1,20 @@ +--- +sidebar_position: 2 +--- + +# Optimize your entire codebase + +Codeflash can optimize your entire codebase by analyzing all the functions in your project and generating optimized versions of them. +It iterates through all the functions in your codebase and optimizes them one by one. + +To optimize your entire codebase, run the following command in your project directory: + +```bash +codeflash --all +``` + +This requires the Codeflash GitHub App to be installed in your repository. + +This is a powerful feature that can help you optimize your entire codebase in one go. +Since it runs on all the functions in your codebase, it can take some time to complete, please be patient. +As this runs you will see Codeflash opening pull requests for each function it successfully optimizes. \ No newline at end of file diff --git a/docs/docs/optimizing-with-codeflash/one-function.md b/docs/docs/optimizing-with-codeflash/one-function.md new file mode 100644 index 000000000..2dec7723a --- /dev/null +++ b/docs/docs/optimizing-with-codeflash/one-function.md @@ -0,0 +1,36 @@ +--- +sidebar_position: 1 +--- +# Optimize a function + +Codeflash is essentially a function optimizer. When asked to optimize a function, Codeflash will analyze the function, +any helper functions it calls, and the imports it uses. It will then generate multiple new versions of the function and its helper functions, that are +optimized for efficiency and performance while being functionally equivalent to the original function. + +Codeflash tests if a function is optimized by running the function and comparing the output of the new function to +the original function. If the outputs match and the runtime of the new function is smaller, then the function is considered optimized. +Codeflash works best on pure functions that don't have side effects. It can also optimize functions with side effects, but +your mileage may vary. + +## How to optimize a function + +To optimize a function, you can run the following command in your project: + +```bash +codeflash --file path/to/your/file.py --function function_name +``` + +If you have installed the GitHub App to your repository, the above command will open a pull request with the optimized function. +If you want to optimize a function locally, you can add a `--no-pr` argument as follows: + +```bash +codeflash --file path/to/your/file.py --function function_name --no-pr +``` + +### Optimizing class methods + +To optimize a method `method_name` in a class `ClassName`, you can run the following command: + +```bash +codeflash --file path/to/your/file.py --function ClassName.method_name +``` diff --git a/docs/docs/optimizing-with-codeflash/optimize-prs.md b/docs/docs/optimizing-with-codeflash/optimize-prs.md new file mode 100644 index 000000000..5f5b55252 --- /dev/null +++ b/docs/docs/optimizing-with-codeflash/optimize-prs.md @@ -0,0 +1,30 @@ +--- +sidebar_position: 3 +--- + +# Optimize Pull Requests + +Codeflash can optimize your pull requests by analyzing the changes in the pull request +and generating optimized versions of the functions that have changed. + +## How to optimize a pull request +After following the setup steps in the [Automate Code Optimization with GitHub Actions](/getting-started/codeflash-github-actions) guide, +Codeflash will automatically optimize your pull requests when they are opened. + +If Codeflash finds any successful optimizations, it will comment on the pull request asking you to review the changes. + +![Codeflash PR Comment](/img/review-comment.png) + +Codeflash can ask you to review the changes in two ways: +### Opening a dependent pull request +Codeflash will open a new pull request with the optimized code. +You can review the changes in this pull request, make changes if you want, and merge it if you are satisfied with the optimizations. +The changes will be merged back into the original pull request as a new commit. + +![Codeflash PR Review](/img/dependent-pr.png) +### Reviewing the changes in the original pull request +If the suggested changes are small and only affect the modified lines, Codeflash will suggest the changes in the original pull request itself. +You can choose to accept or reject the changes directly in the original pull request. +The changes can be added to a batch of changes in the original pull request as a new commit. + +![Codeflash PR Review](/img/code-suggestion.png) diff --git a/docs/docs/optimizing-with-codeflash/trace-and-optimize.md b/docs/docs/optimizing-with-codeflash/trace-and-optimize.md new file mode 100644 index 000000000..c8fbee8f6 --- /dev/null +++ b/docs/docs/optimizing-with-codeflash/trace-and-optimize.md @@ -0,0 +1,84 @@ +--- +sidebar_position: 4 +--- +# Optimize Workflows End-to-End + +Codeflash supports optimizing an entire Python script end to end by tracing the execution of the script and generating Replay Tests. These Replay Tests can be used to optimize all the functions called in the script. + +## Motivation for Tracing a workflow + +One of the hard problems with optimizing new code is verifying correctness and performance gains. +The way Codeflash verifies correctness and performance gains is by running the function under optimization against a set of test cases. +These test cases can be part of your existing unit test suite or generated by Codeflash. However, it's tedious to write test cases for every function you want to optimize, plus it's hard to come up with test cases for complex inputs and inputs that cover all edge cases. +Additionally, running the function with these test cases is not a great way to verify performance gains as the test cases might not be representative of the real-world usage of the function. + +Codeflash Tracer solves these issues. + +## What is Codeflash Tracer? +Codeflash Tracer is a tool that traces the execution of your workflow and generates a set of test cases that are derived from how your code is actually run. +Codeflash Tracer works by recording the inputs of your functions as they are called in your codebase. These inputs are then used to generate test cases that are representative of the real-world usage of your functions. +We call these generated test cases "Replay Tests" because they replay the inputs that were recorded during the tracing phase. + +Then, Codeflash Optimizer can use these replay tests to verify correctness and calculate accurate performance gains for the optimized functions. +Using Replay Tests, Codeflash can verify that the optimized function produces the same output as the original function and also measure the performance gains of the optimized function on the real-world inputs. +This way you can be _sure_ that the optimized function causes no changes of behavior for the traced workflow and also, that it is faster than the original function. + +## Using Codeflash Tracer + +Codeflash Tracer can be used in two ways: + +1. **As a command line module -** + + You can use Codeflash Tracer as a module when you run Python. + If you run a Python script as follows - + ```bash + python path/to/your/file.py --your_options + ``` + You can trace the execution of the script by running - + ```bash + python -m codeflash.tracer -o codeflash.trace path/to/your/file.py --your_options + ``` + + So adding a `-m codeflash.tracer -o codeflash.trace` before your script will trace the execution of the script and save the trace to a file called `codeflash.trace`. + If your script itself runs as a module, you can run it as follows - + ```bash + python -m codeflash.tracer -o codeflash.trace -m path.to.your.module --your_options + ``` + More Options: + - `--max-function-count`: The maximum number of times to trace a single function. More calls to a function will not be traced. Default is 100. + - `--tracer-timeout`: The maximum time in seconds to trace the entire workflow. Default is indefinite. This is useful while tracing really long workflows. +2. **As a Context Manager -** + + You can also use Codeflash Tracer as a context manager in your codebase. + You can wrap the code you want to trace in a `with` statement as follows - + ```python + from codeflash.tracer import Tracer + + with Tracer(output="codeflash.trace"): + # Your code here + ``` + This is useful to only trace and optimize a part of your executable, not the entire script. + Sometimes, if using the tracer as a module fails, then the Context Manager can also be used to trace the code sections. + + More Options: + - `disable`: If set to `True`, the tracer will not trace the code. Default is `False`. + - `max_function_count`: The maximum number of times to trace a single function. More calls to a function will not be traced. Default is 100. + - `timeout`: The maximum time in seconds to trace the entire workflow. Default is indefinite. This is useful while tracing really long workflows, to not wait indefinitely. + - `output`: The file to save the trace to. Default is `codeflash.trace`. + - `config_file_path`: The path to the `pyproject.toml` file which stores the Codeflash config. This is auto-discovered by default. + You can also disable the tracer in the code by setting the `disable=True` option in the `Tracer` constructor. + +## Optimizing with Replay Tests +After the tracing phase is complete, the tracer will generate a trace file as well as a Replay Test file. +The path of the generated replay test is printed on the console after the tracing is complete. It will be located in your tests directory and have a name like `test_file_getting_traced__replay_test_0.py`. +The Replay Test file is a Python test file that when run will call the traced functions with the recorded inputs, i.e. replay them. +Now Codeflash Optimizer can use these Replay Tests to verify correctness and calculate performance gains of the optimized functions. + +To optimize all the functions traced, you can run the following command - +```bash +codeflash --replay-test tests/test_file_getting_traced__replay_test_0.py +``` +Codeflash will auto-discover all the functions that were traced, and use the replay tests, plus will discover existing unit tests and generate more tests to get the best optimizations. +Codeflash will open pull requests with the optimized functions as it finds them, which should speed up your end to end workflow! + + diff --git a/docs/docusaurus.config.ts b/docs/docusaurus.config.ts new file mode 100644 index 000000000..877869aff --- /dev/null +++ b/docs/docusaurus.config.ts @@ -0,0 +1,171 @@ +import { themes as prismThemes } from "prism-react-renderer" +import type { Config } from "@docusaurus/types" +import type * as Preset from "@docusaurus/preset-classic" + +const config: Config = { + title: "Codeflash Docs", + tagline: "Code optimization is cool", + favicon: "img/favicon.ico", + + // Set the production url of your site here + url: "https://docs.codeflash.ai", + // Set the // pathname under which your site is served + // For GitHub pages deployment, it is often '//' + baseUrl: "/", + + // GitHub pages deployment config. + // If you aren't using GitHub pages, you don't need these. + // organizationName: 'facebook', // Usually your GitHub org/user name. + // projectName: 'docusaurus', // Usually your repo name. + + onBrokenLinks: "throw", + onBrokenMarkdownLinks: "warn", + + // Even if you don't use internationalization, you can use this field to set + // useful metadata like html lang. For example, if your site is Chinese, you + // may want to replace "en" with "zh-Hans". + i18n: { + defaultLocale: "en", + locales: ["en"], + }, + + scripts: [ + { + src: "https://widget.intercom.io/widget/ljxo1nzr", + async: true, + onLoad: `window.Intercom('boot', { + app_id: "ljxo1nzr" + });`, + }, + { + src: "https://app.posthog.com/static/array.js", + strategy: "afterInteractive", + onLoad: `window.posthog = window.posthog || []; + window.posthog.init("phc_aUO790jHd7z1SXwsYCz8dRApxueplZlZWeDSpKc5hol", { + api_host: "https://us.i.posthog.com", + });`, + }, + ], + presets: [ + [ + "classic", + { + docs: { + sidebarPath: "./sidebars.ts", + routeBasePath: "/", + // Please change this to your repo. + }, + blog: false, + theme: { + customCss: "./src/css/custom.css", + }, + } satisfies Preset.Options, + ], + ], + + themeConfig: { + // Replace with your project's social card + colorMode: { + defaultMode: "dark", + disableSwitch: false, + respectPrefersColorScheme: false, + }, + image: "img/codeflash_social_card.jpg", + navbar: { + // title: 'My Site', + logo: { + href: "https://codeflash.ai/", + alt: "Codeflash Logo", + src: "img/codeflash_light.svg", + srcDark: "img/codeflash_darkmode.svg", + }, + items: [ + { + type: "docSidebar", + sidebarId: "tutorialSidebar", + position: "left", + label: "Docs", + }, + // {to: '/blog', label: 'Blog', position: 'left'}, + { + href: "https://app.codeflash.ai/", + label: "Get Started", + position: "right", + }, + ], + }, + docs : { + sidebar: { + autoCollapseCategories: false, + hideable: false, + } + }, + footer: { + style: "dark", + links: [ + { + title: "Navigation", + items: [ + { + label: "Home Page", + to: "https://codeflash.ai/", + }, + { + label: "PyPI", + to: "https://pypi.org/project/codeflash/", + }, + { + label: "Get Started", + to: "https://app.codeflash.ai/", + }, + ], + }, + { + title: "Get in Touch", + items: [ + { + label: "Careers", + to: "mailto:careers@codeflash.ai", + }, + { + label: "contact@codeflash.ai", + href: "mailto:contact@codeflash.ai", + }, + ], + }, + ], + copyright: `©2024 CodeFlash Inc.`, + }, + prism: { + theme: prismThemes.github, + darkTheme: prismThemes.dracula, + additionalLanguages: ["bash", "toml"], + }, + algolia: { + // The application ID provided by Algolia + appId: 'Y1C10T0Z7E', + + // Public API key: it is safe to commit it + apiKey: '4d1d294b58eb97edec121c9c1c079c23', + + indexName: 'codeflash', + + // Optional: see doc section below + contextualSearch: true, + + // Optional: Algolia search parameters + searchParameters: {}, + + // Optional: path for search page that enabled by default (`false` to disable it) + searchPagePath: 'search', + + // Optional: whether the insights feature is enabled or not on Docsearch (`false` by default) + insights: true, + + //... other Algolia params + }, + + } satisfies Preset.ThemeConfig, +} + +export default config diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 000000000..aa0200d56 --- /dev/null +++ b/docs/package.json @@ -0,0 +1,47 @@ +{ + "name": "cf-docs", + "version": "0.0.0", + "private": true, + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "^3.6.3", + "@docusaurus/preset-classic": "^3.6.3", + "@mdx-js/react": "^3.0.0", + "clsx": "^2.0.0", + "prism-react-renderer": "^2.3.0", + "react": "^18.0.0", + "react-dom": "^18.0.0" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "^3.6.3", + "@docusaurus/tsconfig": "^3.6.3", + "@docusaurus/types": "^3.6.3", + "typescript": "~5.2.2" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 3 chrome version", + "last 3 firefox version", + "last 5 safari version" + ] + }, + "engines": { + "node": ">=18.0" + } +} diff --git a/docs/sidebars.ts b/docs/sidebars.ts new file mode 100644 index 000000000..acc7685ac --- /dev/null +++ b/docs/sidebars.ts @@ -0,0 +1,31 @@ +import type {SidebarsConfig} from '@docusaurus/plugin-content-docs'; + +/** + * Creating a sidebar enables you to: + - create an ordered group of docs + - render a sidebar for each doc of that group + - provide next/previous navigation + + The sidebars can be generated from the filesystem, or explicitly defined here. + + Create as many sidebars as you want. + */ +const sidebars: SidebarsConfig = { + // By default, Docusaurus generates a sidebar from the docs folder structure + tutorialSidebar: [{type: 'autogenerated', dirName: '.'}], + + // But you can create a sidebar manually + /* + tutorialSidebar: [ + 'intro', + 'hello', + { + type: 'category', + label: 'Tutorial', + items: ['tutorial-basics/create-a-document'], + }, + ], + */ +}; + +export default sidebars; diff --git a/docs/src/components/HomepageFeatures/index.tsx b/docs/src/components/HomepageFeatures/index.tsx new file mode 100644 index 000000000..50a9e6f4c --- /dev/null +++ b/docs/src/components/HomepageFeatures/index.tsx @@ -0,0 +1,70 @@ +import clsx from 'clsx'; +import Heading from '@theme/Heading'; +import styles from './styles.module.css'; + +type FeatureItem = { + title: string; + Svg: React.ComponentType>; + description: JSX.Element; +}; + +const FeatureList: FeatureItem[] = [ + { + title: 'Easy to Use', + Svg: require('@site/static/img/undraw_docusaurus_mountain.svg').default, + description: ( + <> + Docusaurus was designed from the ground up to be easily installed and + used to get your website up and running quickly. + + ), + }, + { + title: 'Focus on What Matters', + Svg: require('@site/static/img/undraw_docusaurus_tree.svg').default, + description: ( + <> + Docusaurus lets you focus on your docs, and we'll do the chores. Go + ahead and move your docs into the docs directory. + + ), + }, + { + title: 'Powered by React', + Svg: require('@site/static/img/undraw_docusaurus_react.svg').default, + description: ( + <> + Extend or customize your website layout by reusing React. Docusaurus can + be extended while reusing the same header and footer. + + ), + }, +]; + +function Feature({title, Svg, description}: FeatureItem) { + return ( +
+
+ +
+
+ {title} +

{description}

+
+
+ ); +} + +export default function HomepageFeatures(): JSX.Element { + return ( +
+
+
+ {FeatureList.map((props, idx) => ( + + ))} +
+
+
+ ); +} diff --git a/docs/src/components/HomepageFeatures/styles.module.css b/docs/src/components/HomepageFeatures/styles.module.css new file mode 100644 index 000000000..b248eb2e5 --- /dev/null +++ b/docs/src/components/HomepageFeatures/styles.module.css @@ -0,0 +1,11 @@ +.features { + display: flex; + align-items: center; + padding: 2rem 0; + width: 100%; +} + +.featureSvg { + height: 200px; + width: 200px; +} diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css new file mode 100644 index 000000000..9cca851d4 --- /dev/null +++ b/docs/src/css/custom.css @@ -0,0 +1,30 @@ +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-color-primary: #d08e0d; /* Codeflash yellow */ + --ifm-color-primary-dark: #FFA000; + --ifm-color-primary-darker: #FF8F00; + --ifm-color-primary-darkest: #FF6F00; + --ifm-color-primary-light: #FFD54F; + --ifm-color-primary-lighter: #FFE082; + --ifm-color-primary-lightest: #FFECB3; + --ifm-code-font-size: 95%; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); +} + +/* For readability concerns, you should choose a lighter palette in dark mode. */ +[data-theme='dark'] { + --ifm-color-primary: #FFD227; /* Codeflash yellow */ + --ifm-color-primary-dark: #FFA000; + --ifm-color-primary-darker: #FF8F00; + --ifm-color-primary-darkest: #FF6F00; + --ifm-color-primary-light: #FFD54F; + --ifm-color-primary-lighter: #FFE082; + --ifm-color-primary-lightest: #FFECB3; + --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); +} diff --git a/docs/src/pages/index.module.css b/docs/src/pages/index.module.css new file mode 100644 index 000000000..9f71a5da7 --- /dev/null +++ b/docs/src/pages/index.module.css @@ -0,0 +1,23 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} diff --git a/docs/src/pages/markdown-page.md b/docs/src/pages/markdown-page.md new file mode 100644 index 000000000..9756c5b66 --- /dev/null +++ b/docs/src/pages/markdown-page.md @@ -0,0 +1,7 @@ +--- +title: Markdown page example +--- + +# Markdown page example + +You don't need React to write simple standalone pages. diff --git a/docs/static/.nojekyll b/docs/static/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/docs/static/img/code-suggestion.png b/docs/static/img/code-suggestion.png new file mode 100644 index 000000000..56459e9f4 Binary files /dev/null and b/docs/static/img/code-suggestion.png differ diff --git a/docs/static/img/codeflash_darkmode.svg b/docs/static/img/codeflash_darkmode.svg new file mode 100644 index 000000000..90aac6725 --- /dev/null +++ b/docs/static/img/codeflash_darkmode.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/static/img/codeflash_github_app_bot.png b/docs/static/img/codeflash_github_app_bot.png new file mode 100644 index 000000000..900868d29 Binary files /dev/null and b/docs/static/img/codeflash_github_app_bot.png differ diff --git a/docs/static/img/codeflash_light.svg b/docs/static/img/codeflash_light.svg new file mode 100644 index 000000000..af3ccbef1 --- /dev/null +++ b/docs/static/img/codeflash_light.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/docs/static/img/codeflash_social_card.png b/docs/static/img/codeflash_social_card.png new file mode 100644 index 000000000..ee6139be2 Binary files /dev/null and b/docs/static/img/codeflash_social_card.png differ diff --git a/docs/static/img/dependent-pr.png b/docs/static/img/dependent-pr.png new file mode 100644 index 000000000..2bd69d0bb Binary files /dev/null and b/docs/static/img/dependent-pr.png differ diff --git a/docs/static/img/docusaurus.png b/docs/static/img/docusaurus.png new file mode 100644 index 000000000..f458149e3 Binary files /dev/null and b/docs/static/img/docusaurus.png differ diff --git a/docs/static/img/favicon.ico b/docs/static/img/favicon.ico new file mode 100644 index 000000000..c385c2a4d Binary files /dev/null and b/docs/static/img/favicon.ico differ diff --git a/docs/static/img/logo.svg b/docs/static/img/logo.svg new file mode 100644 index 000000000..9db6d0d06 --- /dev/null +++ b/docs/static/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/review-comment.png b/docs/static/img/review-comment.png new file mode 100644 index 000000000..75a5e443c Binary files /dev/null and b/docs/static/img/review-comment.png differ diff --git a/docs/static/img/undraw_docusaurus_mountain.svg b/docs/static/img/undraw_docusaurus_mountain.svg new file mode 100644 index 000000000..af961c49a --- /dev/null +++ b/docs/static/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/img/undraw_docusaurus_react.svg b/docs/static/img/undraw_docusaurus_react.svg new file mode 100644 index 000000000..94b5cf08f --- /dev/null +++ b/docs/static/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/img/undraw_docusaurus_tree.svg b/docs/static/img/undraw_docusaurus_tree.svg new file mode 100644 index 000000000..d9161d339 --- /dev/null +++ b/docs/static/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/img/verification.svg b/docs/static/img/verification.svg new file mode 100644 index 000000000..e0bf3f424 --- /dev/null +++ b/docs/static/img/verification.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 000000000..314eab8a4 --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,7 @@ +{ + // This file is not used in compilation. It is here just for a nice editor experience. + "extends": "@docusaurus/tsconfig", + "compilerOptions": { + "baseUrl": "." + } +}