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.

References:

[1] https://stackoverflow.com/questions/63993084/problems-after-upgrading-to-xcode-12ld-building-for-ios-simulator-but-linking

[2] https://stackoverflow.com/questions/64123206/xcode-12-problems-build-input-file-cannot-be-found-building-for-release-on

[3] https://stackoverflow.com/questions/63259053/xcode-12-beta-valid-architectures-missing-in-build-settings

[4] https://blog.csdn.net/huawt520/article/details/109305833

GitLab: Feature Branch Workflow

Make Your Feature Branch

  1. Clone project:
    • git clone git@example.com:your-project.git
  2. Create a new branch with your feature:
    • git checkout -b new-feature-branch
  3. Create a file:
    • touch test.py
  4. Update the index using the current content found in the working tree, to prepare the content staged for the next commit:
    • git add test.py
  5. Record changes to the repository:
    • git commit -m "Make some updates on test.py"
  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?

https://docs.gitlab.com/ee/user/project/merge_requests/getting_started.html

Two useful features for beginners:

References

[1] https://docs.gitlab.com/ee/gitlab-basics/feature_branch_workflow.html
[2] https://stackoverflow.com/questions/17096311/why-do-i-need-to-explicitly-push-a-new-branch/17096880#17096880

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

 

https://en.wikipedia.org/wiki/List_of_Latin_phrases

 

Unity: Awake and Start

Adopt from

[1] http://unity3d.com/learn/tutorials/modules/beginner/scripting/awake-and-start

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:

[1] http://msdn.microsoft.com/en-us/library/kbaht4dh.aspx

[2] http://msdn.microsoft.com/en-us/library/fz5w87ad.aspx

Introduction

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

References

[1] http://stackoverflow.com/questions/12573816/what-is-an-undefined-reference-unresolved-external-symbol-error-and-how-do-i-fix

[2] http://stackoverflow.com/questions/17350521/error-lnk2019-unresolved-external-symbol-in-visual-studio

[3] http://stackoverflow.com/questions/8735918/c-lnk2019-unresolved-external-symbol

[4] http://stackoverflow.com/questions/4489441/why-when-is-declspec-dllimport-not-needed

[5] http://msdn.microsoft.com/en-us/library/a90k134d.aspx

Introduction

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

//CommonHeader.h

#ifdef _PROJDLL_EXPORTS
#define _PROJDLL_API __declspec(dllexport)
#else
#define _PROJDLL_API __declspec(dllimport)
#endif

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

OR

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

Background

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){

    __syncthreads();

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

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

}

 

    Threads
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.

Solution

Algorithm 2

__shared__ float partialSum[]

unsigned int t = threadIdx.x;

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

    __syncthreads();

    if (t < stride)

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

}

    Threads
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).

Conclusion

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.

Eclipse Launch Configuration

Sometimes, the application has to be invoked with some arguments for other execution options to suit different purposes. For example, Internet Explorer supported the following options

(adopt from http://msdn.microsoft.com/en-us/library/ee330728(v=VS.85).aspx)

iexplore.exe [ [ -embedding ] [ -extoff ] [ -framemerging ] [ -k ] [ -noframemerging ] [ -nohangrecovery ] [ -private ] ] [ URL ]

If you are going to develop your program in Eclipse and want to test your application with different options, you may follow the instructions below.

  1. Open your project in Eclipse.
  2. In Project Explorer, find your project.
  3. Right-click and select Properties and then Properties Windows appears.
  4. In the menu on the left, click Run/Debug Settings.
  5. On the right, select a Launch configuration (by default there is at least one)
  6. Press Edit to change the configuration

As you can see, there are a number of configurations but we only focus on the settings in the Arguments tab.

  1. In the Arguments tab, input your arguments for the program. Each line is for one argument.
  2. If you do not want to use the default Working directory, unchecked Use default. This is useful if you want to open a file that is in the same directory as the executable. Suppose the executable named MyApp1. To specify the directory,
    1. For C++ project, very often, we change it from ${workspace_loc:MyApp1} to ${workspace_loc:MyApp1/Debug}
    2. For Java project, very often,  we change it from ${workspace_loc:MyApp1} to ${workspace_loc:MyApp1/bin}

Python: Install pip on Windows

References

[1] http://www.pip-installer.org/en/latest/

[2] http://pypi.python.org/pypi/pip#downloads

[3] http://pypi.python.org/pypi/setuptools#downloads

[4] http://stackoverflow.com/questions/4750806/how-to-install-pip-on-windows


Python allows developers to install packages. pip is a tool for installing and managing Python packages. To install pip, you can follow the steps below:

Install setuptools

  1. Download setuptools [http://pypi.python.org/pypi/setuptools#downloads]
  2. Open the installer to install setuptools

Install pip

  1. Download pip-1.2.x.tar.gz (e.g. pip-1.2.1.tar.gz)[http://pypi.python.org/pypi/pip#downloads]
  2. Upzip the pip-1.2.x.tar.gz to a folder, e.g. C:\Downloads\pip-1.2.x
  3. Assume the folder is at C:\Downloads\pip-1.2.x
    cd "C:\Downloads\pip-1.2.x"
  4. Install pip
    C:\Python27\python.exe setup.py install

Update environment variable

Refer to http://www.helpwithwindows.com/WindowsXP/howto-04.html

  1. Add path C:\Python27
  2. Add path C:\Python27\Scripts
  3. Reopen the command prompt

Use pip

For example, we want to install the networkx package [http://networkx.lanl.gov/]

pip install networkx