Unresolved extern when compiling OpenCL to PTX using Clang? - clang

I'm following the instructions on this SO answer but when I try to run the resulting PTX file I get the follow error in clBuild
ptxas fatal : Unresolved extern function 'get_group_id'
In the PTX file I have the following for every OpenCL function call I use
.func (.param .b64 func_retval0) get_group_id
(
.param .b32 get_group_id_param_0
)
;
The above isn't present in the PTX files created by the OpenCL runtime when I provide it with a CL file. Instead it has the proper special register.
Following these instructions (links against a different libclc library) gives me a segmentation fault during the LLVM IR to PTX compilation with the following error:
fatal error: error in backend: Cannot cast between two non-generic address spaces
Are those instructions still valid? Is there something else I should be doing?
I'm using the latest version of libclc, Clang 3.7, and Nvidia driver 352.39

The problem is that llvm does not provide an OpenCL device code library. llvm however provides the intrinsics for getting the IDs of a GPU thread. Now you have to write your own implantations of get_global_id etc. using clang's builtins and compile it to llvm bitcode with the nvptx target. Before you lower your IR to PTX you use llvm-link to link your device library with your compiled OpenCL module and that's it.
A example how you would write such a function:
#define __ptx_mad(a,b,c) ((a)*(b)+(c))
__attribute__((always_inline)) unsigned int get_global_id(unsigned int dimindx) {
switch (dimindx) {
case 0: return __ptx_mad(__nvvm_read_ptx_sreg_ntid_x(), __nvvm_read_ptx_sreg_ctaid_x(), __nvvm_read_ptx_sreg_tid_x());
case 1: return __ptx_mad(__nvvm_read_ptx_sreg_ntid_y(), __nvvm_read_ptx_sreg_ctaid_y(), __nvvm_read_ptx_sreg_tid_y());
case 2: return __ptx_mad(__nvvm_read_ptx_sreg_ntid_z(), __nvvm_read_ptx_sreg_ctaid_z(), __nvvm_read_ptx_sreg_tid_z());
default: return 0;
}
}

Related

Trouble getting started with Metal shader compilation

I'm having trouble getting started with Metal's shader compilation.
How to make a MTLLibrary that can link to a MTLDynamicLibrary (or MTLLinkedFunctions), in particular a library that declares extern functions that are to be resolved at runtime when providing preloadedLibraries (or linkedFunctions) in the compute pipeline descriptor? For example, I can compile the following to air using xcrun metal (with option -c), but then invoking xcrun metallib (even with option --split-module-without-linking) gives the error LLVM ERROR: Undefined symbol: _Z3addjj. In other words, how do I make a 'partially bound' metal library?
// shader.h
extern uint add(uint a, uint b);
/// shader.metal
#include "shader.h"
kernel void kernel_func(uint gid [[ thread_position_in_grid ]]) { add(gid,2); }
WWDC2021 mentions this extern technique, but the Dynamic Library Code Sample from the previous year doesn't use extern (or the installName), so I don't make sense of it.
When creating an executable library that uses a dynamic library, there are two points where you must include the dynamic library (I thought there was only one).
The process is different depending on whether the executable source is compiled at build or runtime. I'll describe for the case of runtime, because I haven't yet figured out the case for the executable library created from a metallib file.
The first point is when you compile the executable, where you must include the dynamic library in the libraries field of the CompileOptions. The library is there at this point just as a dummy, to check that you have a dynamic library that defines the declarations allowing for proper linkage, though that linkage doesn't occur at this stage, just the checking.
The second point is when you create the pipeline state, where you must include the dynamic library in the preloadedLibraries field of the pipeline descriptor. This time, the dynamic library is not a dummy but the real library you plan to use, as it will be linked with the executable during pipeline creation.

QtCreator annotation compiler does not find stdbool.h

I'm using QtCreator 4.11.2 , installed via MSYS2, with ClangCodeModel enabled.
Here is my program (this is the result of creating a New Non-QT Plain C Application):
#include <stdio.h>
#include <stdbool.h>
_Bool a;
bool b;
int main()
{
printf("Hello World!\n");
return 0;
}
The .pro file is unchanged from the default:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
SOURCES += \
main.c
The annotation compiler highlights an error saying stdbool.h cannot be found.
But it does not give an error for _Bool a; , so it is clearly running in C99 mode but has some problem with include paths. The "Follow symbol under cursor" option works, opening stdbool.h.
My question is: How do I configure include paths for the annotation compiler or otherwise fix this problem?
I have been unable to figure out how to set options for the annotation compiler or even which compiler binary it is using . Under Tools > Options > C++ > Code Model > Diagnostic Configuration it lets me add -W flags but does not let me add -I flags, a red message pops up saying the option is invalid.
Under Tools > Options > C++ Code Model inspector, there are no diagnostic messages, and the Code Model Inspecting Log shows stdbool.h being correctly found and parsed, as msys64/mingw64/lib/gcc/x86_64-w64-mingw32/9.3.0/include/stdbool.h.
If I disable the ClangCodeModel plugin then there are no errors , but I would like to use the clang version if it can be made to work as in general it has good diagnostics.
The result of clang --version in a shell prompt is:
clang version 10.0.0 (https://github.com/msys2/MINGW-packages.git 3f880aaba91a3d9cdfb222dc270274731a2119a9)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: F:\Prog\msys64\mingw64\bin
and if I compile this same source code using clang outside of QtCreator, it compiles and runs correctly with no diagnostics. So the annotation compiler is clearly not the same as the commandline clang?
The Kit I have selected in QtCreator is the autodetected Desktop Qt MinGW-w64 64bit (MSYS2)
The exact same symptoms occur if I make a Plain C++ project and try to include stdbool.h (which is required to exist by the C++ Standard, although deprecated), although interestingly it does accept <cstdbool>.
I have found a workaround of sorts: including in the .pro file the line:
INCLUDEPATH += F:/Prog/msys64/mingw64/lib/gcc/x86_64-w64-mingw32/9.3.0/include/
causes the annotation compiler to work correctly, however this is undesirable as I'd have to keep changing it whenever I switch Kits because it also passes this to the actual build compiler, not just the annotation compiler.
Create file stdbool.h in C:\msys64\mingw64\x86_64-w64-mingw32\include and copy paste this code:
/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
/*
* ISO C Standard: 7.16 Boolean type and values <stdbool.h>
*/
#ifndef _STDBOOL_H
#define _STDBOOL_H
#ifndef __cplusplus
#define bool _Bool
#define true 1
#define false 0
#else /* __cplusplus */
/* Supporting _Bool in C++ is a GCC extension. */
#define _Bool bool
#if __cplusplus < 201103L
/* Defining these macros in C++98 is a GCC extension. */
#define bool bool
#define false false
#define true true
#endif
#endif /* __cplusplus */
/* Signal that all the definitions are present. */
#define __bool_true_false_are_defined 1
#endif /* stdbool.h */
Note
Creating a manual file stdbool.h works for me but its a sketchy and a temporary solution for now. Don't use this if you feel its too sketcy. I would rather use a alternative solution than this hack if it exist. This solution might not be good but it still works for me.

Undefined behavior sanitizer suppression file: failed to parse suppressions

After compiling an application with clang 3.6 using -fsanitize=undefined,
I'm trying to start the instrumented program while using a suppression file to ignore some of the errors:
UBSAN_OPTIONS="suppressions=ubsan.supp" ./app.exe
The suppression file ubsan.supp contains:
signed-integer-overflow:example.c
This leads to an error message:
UndefinedBehaviorSanitizer: failed to parse suppressions
The same occurs with a gcc 4.9 build.
The only documentation I can find is http://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html, which is for clang 3.9, while I use 3.6 (which doesn't have documentation for ubsan included).
Can anyone provide working examples for ubsan suppression files, that work in clang 3.6?
Edit: By browsing the source code of ubsan, I found that the only valid suppression type might be "vptr_check" - dunno which version I was looking at though.
Can anyone confirm that in clang 3.9 more suppression types are available?
I didn't spend the time to find out exactly which suppressions were available in clang-3.6, but it appears that in clang-3.7 only vptr_check is available as a suppression. Starting in clang-3.8, the suppressions list is defined to be the list of checks, plus vptr_check.
In clang-3.9 the checks available are:
"undefined"
"null"
"misaligned-pointer-use"
"alignment"
"object-size"
"signed-integer-overflow"
"unsigned-integer-overflow"
"integer-divide-by-zero"
"float-divide-by-zero"
"shift-base"
"shift-exponent"
"bounds"
"unreachable"
"return"
"vla-bound"
"float-cast-overflow"
"bool"
"enum"
"function"
"returns-nonnull-attribute"
"nonnull-attribute"
"vptr"
"cfi"
"vptr_check"
I'd tried it by creating three files, compile.sh, main.cpp and suppressions.supp as shown below. The unsigned-integer-overflow is not a part of undefined that's why it needs to be included specifically. This works on my machine with clang-3.9.
So, I'd guess more suppression types are valid in clang-3.9.
# compile.sh
set -x
UBSAN_OPTIONS=suppressions=suppressions.supp:print_stacktrace=1 #:help=1
export UBSAN_OPTIONS
clang++-3.9 -g -std=c++11 -fsanitize=undefined -fno-omit-frame-pointer -fsanitize=unsigned-integer-overflow main.cpp
./a.out
// main.cpp
#include <bits/stdc++.h>
#include <bits/stl_tree.h>
using namespace std;
int main(int argc, char **argv) {
unsigned int k = UINT_MAX;
k += 1;
return 0;
}
# suppressions.supp
unsigned-integer-overflow:main.cpp

How to compile my c program which uses opencv

I have started learning OpenCV.
I am working on linux.
From their documentation page I was able to compile this
http://docs.opencv.org/doc/tutorials/introduction/linux_gcc_cmake/linux_gcc_cmake.html#linux-gcc-usage
However after that I got lost in trying to declare a new mat and it's constructors.
SO I decided to go with this book http://www.amazon.com/Learning-OpenCV-Computer-Vision-Library/dp/0596516134
However I am not able to compile the very first program from this book.
The program is here :
#include "highgui.h"
int main(int argc, char** argv)
{
IplImage* img = cvLoadImage (argv[1]);
cvNamedWindow("Example1", CV_WINODW_AUTOSIZE);
cvShowImage("Example1",img);
cvWaitKey(0);
cvReleaseImage(&img);
cvDestroyWindow("Example1");
}
I saved this in a file named load.c
Then I created a CMakeLists.txt file and put this in it :
project( load )
find_package( OpenCV REQUIRED )
add_executable( load load )
target_link_libraries( load ${OpenCV_LIBS} )
when running "cmake ." from terminal it is succesful. But when I am running "make" it gives me this error :
Scanning dependencies of target load
[100%] Building C object CMakeFiles/load.dir/load.o
/home/ishan/load/load.c: In function ‘main’:
/home/ishan/load/load.c:4:2: error: too few arguments to function ‘cvLoadImage’
/usr/local/include/opencv2/highgui/highgui_c.h:212:18: note: declared here
/home/ishan/load/load.c:5:28: error: ‘CV_WINODW_AUTOSIZE’ undeclared (first use in this function)
/home/ishan/load/load.c:5:28: note: each undeclared identifier is reported only once for each function it appears in
make[2]: *** [CMakeFiles/load.dir/load.o] Error 1
make[1]: *** [CMakeFiles/load.dir/all] Error 2
make: *** [all] Error 2
I think it is because this example in the book is for OpenCV 1.x while I am currently running 2.4.3, however I believe there must be a way to run this program and the subsequent program that are in the book.
I think the problem lies with linking the header files properly.
I would like to first read from the book and using reference from documentation and then switch to documentation fully. But for now I wish to learn from the book as learning from the book is far easier to me than documentation. Plus I bought this book for approx 3000 INR and got it just today, I don't want to see it go to waste. I want to learn from it.
Please help me out.
CV_WINODW_AUTOSIZE is mispelled. The correct constant is CV_WINDOW_AUTOSIZE
cvLoadImage (argv[1]); should be cvLoadImage (argv[1], 1); (for loading a color image) because the C standard does not support default arguments.
By the way, if you're using OpenCV 2.0+, I recommend learning the C++ API. It's a lot less convoluted than the C API and performance is comparable.

Cannot link a minimal Lua program

I have the following trivial Lua program which I copied from the book Programming In Lua
#include <stdio.h>
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
int main (void)
{
char buff[256];
int error;
lua_State *L = luaL_newstate(); /* opens Lua */
luaL_openlibs(L); /* opens the standard libraries */
while (fgets(buff, sizeof(buff), stdin) != NULL)
{
error = luaL_loadbuffer(L, buff, strlen(buff), "line") ||
lua_pcall(L, 0, 0, 0);
if (error)
{
fprintf(stderr, "%s", lua_tostring(L, -1));
lua_pop(L, 1); /* pop error message from the stack */
}
}
lua_close(L);
return 0;
}
my environment is cywin
my make file looks like this:
CC=gcc
INCLUDE='-I/home/xyz/c_drive/Program Files/Lua/5.1/include'
LINKFLAGS='-L/home/xyz/c_drive/Program Files/Lua/5.1/lib' -llua51
li.o:li.c
$(CC) $(INCLUDE) -c li.c
main:li.o
$(CC) -o main $(LINKFLAGS) li.o
clean:
rm *.o
rm main
My /home/xyz/c_drive/Program Files/Lua/5.1/lib directory contains lua5.1.dll lua5.1.lib lua51.dll and lua51.lib
Trying to build my main target I am getting the following errors:
li.o:li.c:(.text+0x35): undefined reference to `_luaL_newstate'
li.o:li.c:(.text+0x49): undefined reference to `_luaL_openlibs'
li.o:li.c:(.text+0xaf): undefined reference to `_luaL_loadbuffer'
li.o:li.c:(.text+0xd9): undefined reference to `_lua_pcall'
li.o:li.c:(.text+0x120): undefined reference to `_lua_tolstring'
li.o:li.c:(.text+0x154): undefined reference to `_lua_settop'
li.o:li.c:(.text+0x167): undefined reference to `_lua_close'
Any ideas about what I might be doing wrong here?
The problem is that you have named the libraries on the link command line before the object files that require them. The linker loads modules from left to right on the command line. At the point on the line where you name -llua51, no undefined symbols that could be satisfied by that library are known. Then you name li.o, which does have unknown symbols.
Some Unix-like environments don't treat this as an error because part of the link process is deferred to the program load when reference to .so files are satisfied. But Cygwin, MinGW, and Windows in general must treat this as an error because DLLs work quite differently from .so files.
The solution is to put -llua51 after all the .o files on your link line.
Edit: Incidentally, it appears you are linking against the Lua for Windows distribution, but building with GCC under Cygwin. You will want to use Dependency Walker to make sure that your program does not depend on the Cygwin runtime, and that it does depend on the same C runtime as the lua51.dll from Lua for Windows. IIRC, that will be the runtime for the previous version of Visual Studio. It is possible to make GCC link against that, but you will need to be using the MinGW port (which you can use from Cygwin), and link against a couple of specific libraries to get that version. I'm away from my usual PC, or I'd quote an exact link line. (I believe you need -lmoldname -lmsvcr80 or something like that, as the last items on the link line.)
It will cause mysterious and very hard to diagnose problems if more than one C runtime library is in use. The easy answer is to use the same one as your preferred Lua DLL. Another alternative is that the Lua Binaries project has pre-compiled Lua DLLs for a wide array of C toolchains on Windows. If you need a Lua application that understands the Cygwin environment, you will want one that is built by GCC for Cygwin and not the Lua for Windows flavor. Lua Binaries will be your friend, or you can build Lua your self from source.
The names in the Lua API do not have those leading underscores. Try compiling with -fno-leading-underscore.

Resources