Debugging Python code on Docker container using VSCode

This solution requires a Docker host (Machine A) with VSCode installed. Using the instructions will establish a connection:

[Machine A + Docker + VSCode] <---> [Docker container running on Machine A + VSCode]

Set up VSCode instance on the host machine

  1. Install VSCode (
  2. Install Docker extension on the host (
  3. Find your Docker container
  4. Right-click "Attach Visual Studio Code"

Now, a new VSCode instance will be launched on the Docker container.

Set up VSCode instance on Docker container

  1. Open the folder
  2. Install Python extension (
  3. Go to "Run and Debug" view
  4. Create launch.json
  5. Select Python
  6. You will see the following code generated by VSCode. The code allows you to run Python script of the current file "${file}.

    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit:
    "version": "0.2.0",
    "configurations": &#91;
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": true

7. If you want to run a specific file with parameters

    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit:
    "version": "0.2.0",
    "configurations": &#91;
            "name": "German",
            "type": "python",
            "request": "launch",
            "program": "",
            "args":  &#91;
                "--config-name", "german",
            "console": "integratedTerminal",
            "justMyCode": true
            "name": "Python: Current File",
            "type": "python",
            "request": "launch",
            "program": "${file}",
            "console": "integratedTerminal",
            "justMyCode": true

8. Multiple versions of Python interpreters could be installed in the container.

9. To find out the default Python interpreter. Open terminal. Type

which python

10. Let's say the path is "/usr/bin/python". In VSCode, select the appropriate interpreter through the Command Palette -> "> Python: select interpreter" -> "/usr/bin/python"

11. Now breakpoints can be set to debug the scripts. Go to "Run and Debug" view. And run "German" launch config.

Launch from a local VSCode instance from your desktop or notebook

Because a local VSCode instance can start a remote VSCode instance using SSH ( You can establish the following connection:

[Local machine + VSCode] <---> [Remote machine A + Docker + VSCode] <---> [Docker container running on remote machine A + VSCode]




Resolving error: pathspec 'XXX' did not match any file(s) known to git

$repo/submodule1 ‹f117578*›$ git checkout my_new_branch_in_submodule
error: pathspec 'my_new_branch_in_submodule' did not match any file(s) known to git

$repo/submodule1 ‹f117578*›$ git remote -v
origin (fetch)
origin (push)

$repo/submodule1 ‹f117578*›$ git remote remove origin
git remote add origin

$repo/submodule1 ‹f117578*›$ git checkout my_new_branch_in_submodule
error: pathspec 'my_new_branch_in_submodule' did not match any file(s) known to git
$repo/submodule1 ‹f117578*›$ git pull
remote: Enumerating objects: 1115, done.
remote: Counting objects: 100% (1112/1112), done.
remote: Compressing objects: 100% (492/492), done.
remote: Total 1057 (delta 420), reused 1031 (delta 398), pack-reused 0
Receiving objects: 100% (1057/1057), 554.66 MiB | 4.40 MiB/s, done.
Resolving deltas: 100% (420/420), completed with 20 local objects.
 * &#91;new branch]      my_new_branch_in_submodule -> origin/my_new_branch_in_submodule
 * &#91;new branch]      my_new_branch_2_in_submodule -> origin/my_new_branch_in_submodule2
$repo/submodule1 ‹f117578*›$ git checkout my_new_branch_in_submodule

Xcode 12 Build Errors

Error Message: building for iOS Simulator, but linking in XXX built for iOS, architecture arm64

If you are not using Apple Silicon processor, the reason is that Xcode 12 does not allow build arm64 architecture for Simulator. We should set x86_64 for Simulator building by excluding arm64 via Build Settings -> Excluded Architectures:

Recompile the project again.

If you are using Apple Silicon processor, EXCLUDED_ARCHS for arm64 on the simulator means that people with Apple Silicon macs won't be able to use your framework. Therefore, don't do that. Check the warning messages for your target to identify other conflicts.

Cannot find VALID_ARCHS?

Forget about it. The Build Settings editor no longer includes the Valid Architectures build setting (VALID_ARCHS), and its use is discouraged. Instead, there is a new Excluded Architectures build setting (EXCLUDED_ARCHS). If a project includes VALID_ARCHS, the setting is displayed in the User-Defined section of the Build Settings editor.

Two libraries have the same architectures and in the same fat output file?

fatal error: lipo: /Users/pacowong/Library/Developer/Xcode/DerivedData/Demo-iOS-gxavdlvyqcmylawrmtuqoebcsva/Build/Products/Debug-iphoneos/libSVGKit-iOS.2.1.0.a and /Users/pacowong/Library/Developer/Xcode/DerivedData/Demo-iOS-gxavdlgvyqcmylawrmtuqoebcsva/Build/Products/Debug-iphonesimulator/libSVGKit-iOS.2.1.0.a have the same architectures (arm64) and can't be in the same fat output file

To resolve the conflict in Xcode, go to Build Settings -> Excluded Architectures, set set the following:

If you only have a .a or .framework file, you need to use lipo remove to remove the library that uses arm64 architecture. This can be done using the following command:

$ lipo XXX.a -remove arm64 -output XXX.a

Still does not work?

You need to set it for ALL targets. You can find the targets in Issue Navigator (but not in Project navigator, which is quite weird). You need to modify excluded architectures accordingly.






GitLab: Feature Branch Workflow

Make Your Feature Branch

  1. Clone project:
    • git clone
  2. Create a new branch with your feature:
    • git checkout -b new-feature-branch
  3. Create a file:
    • touch
  4. Update the index using the current content found in the working tree, to prepare the content staged for the next commit:
    • git add
  5. Record changes to the repository:
    • git commit -m "Make some updates on"
  6. Push the branch to GitLab as explained in [2]:
    • git push -u origin new-feature-branch
  7. Find the merge request URL in the prompt:
    • remote: http://gitlab-server/your-username/your-repo-name/merge_requests/...
  8. Open the merge request URL using a web browser

What can you do on the merge request page?

Two useful features for beginners:



Some Abbreviations

a.k.a.: also known as

a.s.a.p: as soon as possible

ca.: about

cf.: compare

et. al.: and others

f.: and the following page

ff.: and the following pages

ibid.: in the same place

i.e.: that is

loc. cit.: in the place cited

N.B.: take notice

p.s.: post script

pro tem: temporarily

viz: namely; as follows

vs.: versus; as against

de novo: from the beginning

ad hoc: a solution designed for a specific problem or task

in situ: locally; on site; on the premises

per se: through itself


Unity: Awake and Start

Adopt from


Both Awake() and Start() will be called once in the lifetime of a script on a GameObject even when you disable and re-enable the script.

The sequence of the function calls is difference. Awake() is invoked before Start().

Awake() is called when the script is loaded so it is a good place to set up the references between scripts and initialization. Start() will then be immediately called once the script component is enabled. Therefore, you can delay any part of initialization when it is really needed.

How to: Debug in Mixed Mode

Adopted from:




A mixed-mode application is any application that combines native code (C++) with managed code (such as Visual Basic, Visual C#, or C++ that runs on the common language runtime) [2]. Debugging mixed-mode applications is largely transparent in Visual Studio; it is not too different from debugging a single-mode application [2].

Why do you debug in mixed mode?[1]

Debugging in both managed and native code is also known as mixed-mode debugging. There are two scenarios for doing so, depending on whether the DLL or the application is written in native code:

  1. The calling application that calls your DLL is written in native code. In this case your DLL is managed, and both managed and native debuggers must be enabled to debug both. You can check this in the <Project> Property Pages dialog box. How you do this depends on whether you start debugging from the DLL project or the calling application project.
  2. The calling application that calls your DLL is written in managed code and your DLL is written in native code.

How to enable mixed-mode debugging?[1]

  1. In Solution Explorer, select the project.
  2. On the View menu, click Property Pages.
  3. In the <Project> Property Pages dialog box, expand the Configuration Properties node, and then select Debugging.
  4. Set Debugger Type to Mixed.

Linking a C++ DLL of a Solution in Visual Studio 2012








If you use Visual Studio to include your own dynamic library for the first time, most of you will encounter this lengthy error:

Error 12 error LNK2019: unresolved external symbol "public: ..."

When you search "visual studio c++ LNK2019: unresolved external symbol" in StackOverflow, the system returns nearly 1000 questions. As you can see, some of them are even marked as duplicated. In fact, existing answers in the previous posts do contain the procedure to solve this error if you are quite familar with C++ development. But it is too implicit for many newcomers to understand. This post will give you a step-by-step guide to solve this problem.

Problem Settings

ProjectDll (say in MySolution\ProjectDll) which implements the library functions

ProjectApp (say in MySolution\ProjectApp) which contains the functions that use the library

And compile with errors LNK2019.

Step 1: Verify the ProjectDll as a DLL project

In Solution Explorer,

1a. Right click ProjectDll –> Properties

1b. Configuration Properties –> General –> Configuration Type –> Dynamic Library (.dll)


Step 2: Mark and export the functions/classes/data to the library

2a. Create a header file, say CommonHeader.h in ProjectDll project


#define _PROJDLL_API __declspec(dllexport)
#define _PROJDLL_API __declspec(dllimport)

The reason using __declspec(dllexport) and __declspec(dllimport) can be found in [4] and [5].

2b. Mark all the required functions/classes/data which have to be exposed

And don't forget to #include "CommonHeader.h" only in the corresponding header(*.h) files.

For example,

In MySystem.h in ProjectDll

class MySystem{..}  ------> class _PROJDLL_API MySystem{..}

extern double GlobalVarA; ------> extern _PROJDLL_API double GlobalVarA;

2c. We need to define the symbol _PROJDLL_EXPORTS to activate __declspec(dllexport) only for this project. However, as the CommonHeader.h will be shared with ProjectApp, we cannot add #define _PROJDLL_EXPORTS in the header files used by another project. One way is to do this in compilation option

Configuration Properties –> C/C++ –> Preprocessor –> Preprocessor Definitions –> Add _PROJDLL_EXPORTS


Step 3: Build the libary

3a. Right click ProjectDll –> Build

Notice a .dll file and a .lib file in In the same window, MySolution\Debug\ directory.


Step 4: Set the Dependencies

4a. In Solution Explorer, right click ProjectDll and open Project Dependencies with the following settings:

Projects: ProjectDll

Depends on: ProjectApp

After this, modifications on ProjectDll will lead to recompilation of ProjectApp.


Step 5: Include necessary files when compiling ProjectApp

5a. Right click ProjectApp –> Common Properties –> Add New Reference… –> Add the ProjectDll project

5b. In the same window, Configuration Properties –> C/C++ –> General –> Additional Include Directories –> [Directory of the header files of ProjectDll in MySolution\ProjectDll]

5c. In the same window, Configuration Properties –> Linker –> Input –> Additional Dependencies –>  [.lib file of ProjectDll in MySolution\Debug$$


Step 6: Compile ProjectApp

Right click ProjectApp –> Build


Right click ProjectApp –> Set as StartUp Project

Press Build in the Toolbar


You need to repeat the above steps for Release mode, probably with a different directory of *.lib file. Of course you can use All Configurations next time when making these settings. Readers should also find the reasons behind these settings from online documents and forums.

Thread Divergence

Adopted from

[1] Programming Massively Parallel Processors: A Hands-on Approach by David B. Kirk and Wen-mei W. Hwu


In Single Instruction Multiple Data (SIMD) architecture, all threads in the same wrap execute the same instruction. However, these threads may in different control flow when working their data. The SIMD hardware needs to execute the same instruction for multiple passes to cope with these divergent paths by keeping the threads independently executed. For example, an if-then-else construct can produce two different paths for the threads. Extra cost will also be incurred in other constructs, such as for-loop or decision conditions on threadIdx values.

An Example of a Thread Divergence Problem: Reduction Algorithm

A reduction algorithm computes a single value from an array of values. You will encounter this kind of algorithm when performing a summary, such as averaging and summing up the given values, or tournament selection. Although sequential algorithm works efficiently in linear time to the number of elements introduced, parallel execution is still favourable due to a large number of elements.

Consider the following kernel function (wasting at least half of the threads in a block) on sum reduction.

Algorithm 1

__shared__ float partialSum[]

unsigned int t = threadIdx.x;

for (unsigned int stride=1; stride<blockDim.x; stride *=2){


    if (t % (2*stride) ==0)

        partialSum[t] += partialSum[t+stride]; //Absorb the neighbour of the right



Iter stride 0 1 2 3 4 5 6 7 8 9 10 11
0   1 4 2 2 4 2 5 2 3 1 4 6
1 1 5   4   6   7   4   10  
2 2 9       13       14      
3 4 22               14      
4 8 36                      

Given N elements, time complexity is N/2+N/4+N/8+…+1=N-1=O(N)

There is an issue of thread divergence in the above algorithm. The first iteration of the loop, some threads will execute a different path due to the condition on threadIdx.x. In the worst case, two passes will be needed for each iteration for the threads in the same wrap.


Algorithm 2

__shared__ float partialSum[]

unsigned int t = threadIdx.x;

for (unsigned int stride=blockDim.x/2; stride>1; stride /=2){


    if (t < stride)

        partialSum[t] += partialSum[t+stride]; //Absorb the neighbour of the right


Iter stride 0 1 2 3 4 5 6 7 8 9 10 11
0   1 4 2 2 4 2 5 2 3 1 4 6
1 8 4 5 6 8 4 2 5 2    
2 4 8 7 11 10            
3 2 19 17                  
4 1 36                      

A if-then statement still remains in the loop but we claimed there is a performance difference between Algorithm 1 and Algorithm 2. The hint is the positions of threads between those executing in different control paths.

Suppose the size of a warp 4 (32 in reality), all the threads in warps 0-1 (corresponding to thread 0-7) executes the same control path, there is no thread divergence in iteration 1 in these wraps. Similarly, this happens in iteration 2. However, when the number of threads is less than the size of warp, thread divergence occurs again in iteration 3 and iteration 4. But when the problem is large, the number iterations with thread divergence accounts for a small constant number of iteration, i.e. log2(size of a warp) (at least after log2(blockDim.x)-log2(size of a warp) iterations for thread divergence to occur ideally).


In this article, we studied how the thread divergence affects the design of algorithm running on GPGPU. Design of algorithm needs to match with the underlying hardware architecture in order to fully utilize the computational resources.