Ophelie-Renaud
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # FxCorr vs. GCorr vs. Ewen tutorial This tutorial provides the key elements for comparing manual and automated versions of the DiFX-based correlator deployment on target CPU-GPU architectures. The aim is replicability. ## Introduction The manual version of the correlator can be found here: `git clone git@github.com:XhrisPhillips/gcorr.git` The principle of the core of DiFX is the following : 1. Data Alignment: Since the telescopes are separated by large distances, the signals they record may experience delays due to the varying lengths of the paths the signals travel. The correlator aligns these signals in time to ensure that they correspond to the same moment in the observation. 1. Correlation: Once the data are aligned, the correlator compares the signals received by each telescope. It performs a mathematical operation known as correlation, which involves multiplying the signals received by pairs of telescopes and summing them up over a specific time interval. 1. Image Formation: The correlated data contain information about the brightness and structure of the observed astronomical object. FxCorr and Gcorr are two implementation of the DiFX correlator, the fisrt one targetting CPU architecture the second one targetting GPU architecture. Hereafter a simplified dataflow representation: ![difx](https://hackmd.io/_uploads/HkBd2cbGR.png) > **Data Acquisition**: Telescope data is read from disk. This data is assumed to be binary and contains no headers. (The data format ar detail in [FxCorr Design](https://github.com/XhrisPhillips/gcorr/tree/master/doc) in Section *Packed Data*). The binary files (xx.bin) are read and packed into a 2D array (Data per Antenna), there are as many binary files as the number of antenna. Subsequently, the delay between telescope is computed as a polynomial from the configuration file (xx.conf). > **Floating point conversion** : Raw data (encoded as integers) is converted to floating point numbers. At this stage, a conversion creates a complex number with an imaginary zero value (phase 0). The data is divided into independent channels at this stage and store in a 3D array (Data per polarization per Antenna). An "offset" correction is also applied at this stage to correct for the geometric effects of signals received by the telescopes at different times. > **Fringe rotation**: Each sample is 'fringe-rotated' to take account of the different speeds of the telescopes relative to each other (Doppler shift). This is achieved by applying a time-varying phase shift to each sample (more detail in [wiki: Doppler effect](https://en.wikipedia.org/wiki/Doppler_effect)). > **FFT** of the samples: "N" samples in time are transformed into "channelled" data. This is repeated for each "N" samples in time. Changing time-domain to frequency-domain make it easier to extract the information afterwards. > **X** Cross-correlation: For each FFT block, the individual frequency channels of each telescope are multiplied and then accumulated to form "visibilities". For N antennas, there are N(N-1)/2 combinations of unique baselines.Each combination must be formed. The data from a series of FFTs is accumulated to form a 'sub-integration'.Typically, this will take between 10 and 100 milliseconds.The sub-integrations are finally averaged for approximately one second to form the final visibility integration. > **Accumulation**: The cross-correlation values for each FFT block are added to the previous iteration in the "visibilities" table.These are the final visibility products required. > At the end phase and amplitude for each frequency channel and each baseline are stored in a vis.out file. ## Input file As stated above, before doing anything you need to generate the input files, i.e. the binary file for each antenna and the telescope configuration file. ### Binary generation ``` cd generator make #This will generate a Test.vdf file containing spectrum data. ./generateSpectrum <args> Usage: generateSpectrum [options] -w/-bandwidth <BANDWIDTH> Channel bandwidth in MHz (64) -b/-nbits <N> Number of bits/sample (default 2) -C/-channels <N> Number of IF channels (default 1) -c/-complex Generate complex data -f/-float Save data as floats -l/-duration <DURATION> Length of output, in seconds -T/-tone <TONE> Frequency of tone (MHz) -2/-tone2 <TONE> Frequency of second tone (MHz) -a/-amp <amp> Amplitude of tone -A/-amp2 <amp2>d Amplitude of second tone -n/-noise Include (correlated) noise -ntap <TAPS> Number of taps for FIR filter to create band shape ./generateSpectrum -w 16 -bits 2 -channels 2 -duration 10 -tone2 5 -noise -amp2 0.01 aa.bin → aa.bin ./generateSpectrum -w 16 -bits 8 -complex -channels 2 -duration 10 -tone2 5 -noise -amp2 0.01 aaa.bin → aaa.bin #This will generate binary files from the generated configuration file Usage: autoSpec [options] -C/-chan <n> Channel to correlate (can specify multiple times) -n/-npoint <n> # spectral channels -N/-init <val> Number of ffts to average per integration -device <pgdev> Pgplot device to plot to -s/-skip <n> Skip this many bytes at start of file -h/-help This list ./autoSpec -w 16 -b 2 -n 512 -C 2 -d /xs aa.bin → aa.Spec ``` ![testeA](https://hackmd.io/_uploads/Byi_2gffA.png) > autoSpec output Two plots represents 2 channels where a tone has been set on 5MHz (2 bits for real) ``` ./autoSpec -w 16 -b 8 -complex -n 512 -C 2 -d /xs aaa.bin → aaa.Spec ``` ![testeB](https://hackmd.io/_uploads/r1M02lzfC.png) > autoSpec output Two plots represent 2 channels where a tone has been set on 5MHz (8 bits for complex) <div style="background-color:#e6f7ff; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:gray;">Tips:</em></strong><br> <em style="color:gray;"> If you are setting up a 6 station test (for example), run generateSpectrum 6 times using a different file name each time. <br><br> You can also fake your binary: <br> touch aa.bin <br> echo 01 > aa.bin <br> touch Test-8bit-complex.bin <br> echo 01 > Test-8bit-complex.bin <br> </em> </div> ### Configuration file In order to run on GPU kernel make sure that your configuration file aka test.conf respect this (default NTHREADS = 256): ``` NBIT 8 (=2 + real or =8 + complex) NPOL 2 (no matter, it's forced at 2) COMPLEX 1 NCHAN 256 (<=NTHREADS or divisible ([256; 1024] otherwise on voit que dalle)) LO 1650000000 (no matter) BANDWIDTH 16000000 (>0) NUMFFTS 256 (<=NTHREADS or divisible and div(8)) NANT 4 (as many as "aa" binary file) Aa aa.bin 0 0 0 0 0 Bb bb.bin 0 0 0 0 0 Cc cc.bin 0 0 0 0 0 Dd dd.bin 0 0 0 0 0 ``` <div style="background-color:#e6f7ff; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:gray;">Tips:</em></strong><br> <em style="color:gray;"> If numFFT increases, then parallelism increases, memory requirements increase and data transfers increase. GPUs being more limited in memory than CPUs and having weaknesses in data transfer may no longer be the optimal solution. <br> </em> </div> ## Running FxCorr First install and configure the stuff: ``` cd fxkernel/ #install ipp [Intel Integrated Performance Primitives for Linux ,2021.11.0,19 MB,Online,Mar. 27, 2024] chmod +x l_ipp_oneapi_p_2021.11.0.532.sh ./l_ipp_oneapi_p_2021.11.0.532.sh #set env var: nano ~/.bashrc #at the end export INTELROOT=~/intel export IPPROOT=~/intel/ipp export CPATH=path/to/ipp/include →ctrl + o, enter, ctrl+x source ~/.bashrc #in genipppc add l.122 "or major==2021" python3 genipppc ~/intel/oneapi 2021.11 #copy past ipp.pc in the right place sudo cp ~/DiFX/gcorr/fxkernel/ipp.pc /lib/pkgconfig/ autoreconf --install ./configure make ``` IPP install [here](https://www.intel.com/content/www/us/en/developer/articles/tool/oneapi-standalone-components.html#ipp) Then run: ``` cd src ./bench_fxkernel test.conf ``` <div style="background-color:#300A24; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:white;">Prompt:</em></strong><br> <em style="color:gray;"> → Got COMPLEX 0<br> Got NBIT 2<br> Got NPOL 2<br> Got NCHAN 1024<br> Got LO 1.65e+09<br> Got BANDWIDTH 3.2e+07<br> Got NUMFFTS 3200<br> Got NANT 4<br> Subint time is 102.4 msec<br> Processing 1.024 sec <br> Allocating 3 MB per antenna per subint<br> 12 MB total<br> Initialising data to random values<br> Launching Threads<br> Go<br> Run time was 1334 milliseconds<br> 785.819 Mbps<br> </em> </div> ``` ./testfxkernel test.conf ``` <div style="background-color:#300A24; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:white;">Prompt:</em></strong><br> <em style="color:gray;"> → Got COMPLEX 0<br> Got NBIT 2<br> Got NPOL 2<br> Got NCHAN 1024<br> Got LO 1.65e+09<br> Got BANDWIDTH 3.2e+07<br> Got NUMFFTS 3200<br> Got NANT 4<br> Aa:aa.bin<br> Bb:bb.bin<br> Cc:cc.bin<br> Dd:dd.bin<br> Allocating 3 MB per antenna per subint<br> 12 MB total<br> </em> </div> Or: ``` cd bench ./runall.sh ``` ![CPU Benchmark](https://hackmd.io/_uploads/B1-bhcOb0.png) ## Running GCorr ### Running on your laptop ``` #GPU check (Should be NVIDIA) lspci | grep -i nvidia → 3D controller: NVIDIA Corporation GA107M [GeForce RTX 2050] (rev a1) ``` Install NVIDIA CUDA Drivers & CUDA Toolkit for your system, see NVIDIA's [tutorial](https://docs.nvidia.com/cuda/cuda-installation-guide-linux/ ) ``` #Check CUDA compiler & CUDA install with nvcc -V → nvcc: NVIDIA (R) Cuda compiler driver → Copyright (c) 2005-2024 NVIDIA Corporation → Built on Thu_Mar_28_02:18:24_PDT_2024 → Cuda compilation tools, release 12.4, V12.4.131 → Build cuda_12.4.r12.4/compiler.34097967_0 #check your GPU architecture nvidia-smi ``` <div style="background-color:#300A24; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:white;">Prompt:</em></strong><br> <em style="color:gray;"> → =========================================+======================+======================|<br> | 0 Tesla P100-PCIE-16GB On | 00000000:04:00.0 Off | 0 |<br> ...<br> +-----------------------------------------+----------------------+----------------------+<br> | 1 Tesla P100-PCIE-16GB On | 00000000:82:00.0 Off | <br> ...<br> </em> </div> > e.g.: Tesla P100-PCIE-16GB => Pascal architecture, NVIDIA GeForce RTX 2080 Ti => Turing, Quadro RTX 6000 => Turing , ... (ask chatGPT for that...) | Fermi† | Kepler† | Maxwell‡ | Pascal | Volta | Turing | Ampere | Ada | Hopper | Blackwell | | ------ | ------- | -------- | ------ | ----- | ------ | ------ | --- | ------ | --------- | | sm_20 | sm_30 | sm_50 | sm_60 | sm_70 | sm_75 | sm_80 | sm_89 | sm_90 | ??? | | | sm_35 | sm_52 | sm_61 | sm_72 | | sm_86 | | sm_90a | | | | sm_37 | sm_53 | sm_62 | | | sm_87 | | | | > †: deprecated from CUDA 9 and 11 onwards, ‡: deprecated from CUDA 11.6 onwards And then build & make GCorr ``` cd gcorr/ aclocal autoconf autoheader automake --add-missing ./configure make ``` > Makefile is created in src/ adapt this line: `NVCC = nvcc -O3 -arch=sm_86 -lineinfo -maxrregcount 64` with your architecture: `NVCC = nvcc -O3 -arch=sm_86 -arch=sm_60 -lineinfo -maxrregcount 64` otherwise you will have "no kernel image is available for execution on the device" error at the time of correlation. To run the tests : ``` cd gcorr/bench ./runall.sh ``` ![Capture d’écran du 2024-04-26 11-03-01](https://hackmd.io/_uploads/rkp5MiOZ0.png) ### Running on grid5000 Nvidia GPU Open an account [grid5000 account](https://www.grid5000.fr/w/Grid5000:Get_an_account). *The example here are for rennes.* Choose the node you need based on its characteristics (number of GPUs, memory ...) presented in [Rennes:Hardware - grid5000](https://www.grid5000.fr/w/Rennes:Hardware). Check the availability of your `chosen` node on [Rennes:node](https://intranet.grid5000.fr/oar/Rennes/drawgantt-svg/) or [Rennes:node(production)](https://intranet.grid5000.fr/oar/Rennes/drawgantt-svg-prod/) (more status [here](https://www.grid5000.fr/w/Status)) ``` # ssh connect ssh orenaud@access.grid5000.fr ssh rennes #connect 1 abacus node (they host NVIDIA GPU) oarsub -q production -p abacus1 -I #copy the folder scp -r ~/path/gcorr orenaud@access.grid5000.fr:rennes #Check CUDA compiler & CUDA install with nvcc -V cd gcorr/gcorr aclocal autoconf autoheader automake --add-missing ./configure make ``` ``` ./benchmark_gxkernel test.conf ``` <div style="background-color:#300A24; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:white;">Prompt:</em></strong><br> <em style="color:gray;"> → fftsamples = 4096 , numffts is 2048<br> BENCHMARK PROGRAM STARTS<br> Each unpacking test will run with 512 threads, 8 x 2048 blocks<br> nsamples = 8388608<br> nantennas = 6<br> ==== TIMER: calculateDelaysAndPhases ====<br> Iterations | Average time | Min time | Max time | Data time | Speed up |<br> 100 | 0.017 ms | 0.014 ms | 0.041 ms | 0.066 s | 3793.364 |<br> ...<br> </em> </div> ``` ./testgpukernel test.conf ``` <div style="background-color:#300A24; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:white;">Prompt:</em></strong><br> <em style="color:gray;"> → reading configuration file <br> test.conf <br> running 10 loops<br> will output text data<br> Subintsamples= 131072<br> Subint = 2.048 msec<br> Allocate Memory<br> Allocating host data<br> Allocating 0 MB per antenna per subint<br> 0 MB total<br> Allocating GPU data<br> Alloc 65536 complex output values per baseline<br> Allocated 50.891 Mb on GPU<br> Reading data </em> </div> ``` # Compare GPU correlation engine to CPU version ./validate_xcorr test.conf ``` <div style="background-color:#300A24; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:white;">Prompt:</em></strong><br> <em style="color:gray;"> → ***CPU***<br> 1 1: (-1.7135,2.39079) ...<br> ***CrossCorr***<br> Maximum difference = 1106.0758 (147587.14%)<br> Average difference = 150.8477 (2130.07%)<br> ***CrossCorrAccumHoriz***<br> Maximum difference = 0.0000 (0.00%)<br> Average difference = 0.0000 (0.00%)<br> ***CCAH2***<br> Maximum difference = 0.0000 (0.00%)<br> Average difference = 0.0000 (0.00%)<br> **CCAH3**<br> Maximum difference = 0.0000 (0.00%)<br> Average difference = 0.0000 (0.00%)<br> </em> </div> > ``` #run cd gcorr/bench ./runall.sh ``` <div style="background-color:#300A24; padding:10px; border-radius: 5px;font-size: 12px"> <strong><em style="color:white;">Prompt:</em></strong><br> <em style="color:gray;"> → ***CHANNELS***<br> NCHAN= 64 <br>***ANTENNA***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 <br>***ANTENNA 16384***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 <br>***CHANNELS 8bit***<br> NCHAN= 64 <br>***ANTENNA 8bit***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 <br> ***ANTENNA 16384***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 <br> *****************<br> ******HALF*******<br> *****************<br> ***CHANNELS***<br> NCHAN= 64 <br>***ANTENNA***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 <br>***ANTENNA 16384***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 <br> ***CHANNELS 8bit***<br> NCHAN= 64 ***ANTENNA 8bit***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 <br> ***ANTENNA 16384***<br> NANT= 4 NANT= 6 NANT= 8 NANT= 10 NANT= 12 NANT= 16 </em> </div> ## Output file You can visualize your data with the notebook available [here](https://colab.research.google.com/drive/1wEkoTKZVg0fBC_8KcRdCKvL0_GrnKbjb#scrollTo=JAQfFu9OwXy2). Import your vis.out file and run the code. ![vis](https://hackmd.io/_uploads/ryQBDKrGR.png) > Display of the 4 average caracheristics by baselines (detailed in the notebook). >TODO: changer le lien vers github ## References [[1] E. Michel, O. Renaud, A. Deller, K. Desnos, C. Phillips, J.-F. Nezan, Static Dataflow Synthesis for Heterogeneous CPU-GPU systems, IETR, , Swinburne, CSIRO, 202_](https://fr.overleaf.com/project/660670ce5cf576bdb096dcd4). >TODO: change the link to pdf version once published [[2] A.T. Deller, S.J. Tingay, M. Bailes, & C. West, DiFX: A software correlator for very long baseline interferometry using multi-processor computing environments, Swinburne, 2007](https://arxiv.org/abs/astro-ph/0702141). [[3] A.T. Deller, W.F. Brisken, C.J. Phillips, J. Morgan, W. Alef, R. Cappallo, E.Middelberg, J. Romney, H. Rottmann, S.J. Tingay, R. Wayth DiFX2: A more flexible, efficient, robust and powerful software correlator,Swinburne, 2011](https://arxiv.org/abs/1101.0885). [![gcorr](https://img.shields.io/github/stars/XhrisPhillips/gcorr?style=social&label=XhrisPhillips/gcorr)](https://github.com/XhrisPhillips/gcorr) [![preesm-apps](https://img.shields.io/github/stars/preesm/preesm-apps?style=social&label=preesm/preesm-apps&logo=data:image/svg%2bxml;base64,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)](https://github.com/preesm/preesm-apps) ## Acknowledgement *This project has received funding from the European Union’s Horizon 2020 research and innovation program under the Marie Skłodowska-Curie grant agreement No 873120.* ####

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully