Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

.L Metacommand does not work on the device Compiler #8

Open
SimeonEhrig opened this issue Jul 29, 2019 · 0 comments
Open

.L Metacommand does not work on the device Compiler #8

SimeonEhrig opened this issue Jul 29, 2019 · 0 comments
Labels
bug Something isn't working

Comments

@SimeonEhrig
Copy link
Owner

Problem

If the metacommand .L is used to load source code from a file, the device compiler returns an error. But the host works fine.

$ cat getCudaVersion.cpp 
int getCudaVersion(){
  int version = 0;
  cudaRuntimeGetVersion(&version);
  return version;
}

$ cling -xcuda

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ .L getCudaVersion.cpp
[cling]$ getCudaVersion()
input_line_3:2:2: error: use of undeclared identifier 'getCudaVersion'
 getCudaVersion()
 ^
IncrementalCUDADeviceCompiler::process()
failed at compile ptx code
(int) 8000
[cling]$

Reason

The coupling of the device clang::interpreter within the host clang::interpreter has some "gaps". Some functions, e.g. loadFile(), have no handling for the device cling::interpreter.

First solution

Modify following code lib/Interpreter/Interpreter.cpp :

Interpreter::loadFile(const std::string& filename,
                         bool allowSharedLib /*=true*/,
                         Transaction** T /*= 0*/) {
     if (allowSharedLib) {
       CompilationResult result = loadLibrary(filename, true);
       if (result!=kMoreInputExpected)
...

to

Interpreter::loadFile(const std::string& filename,
                         bool allowSharedLib /*=true*/,
                         Transaction** T /*= 0*/) {
     if (m_Opts.CompilerOpts.CUDAHost)
       m_CUDACompiler->getPTXInterpreter()->loadFile(filename, allowSharedLib);
     if (allowSharedLib) {
       CompilationResult result = loadLibrary(filename, true);
       if (result!=kMoreInputExpected)
...

The fix works well with the example getCudaVersion(). But the following example doesn't work.

$ cat gKernel.cu 
__global__ void g1(){
	int i = 3;
}
$ cling -xcuda

****************** CLING ******************
* Type C++ code and press enter to run it *
*             Type .q to exit             *
*******************************************
[cling]$ .L gKernel.cu
[cling]$ g1<<<1,1>>>();
[cling]$ cudaGetLastError()
(cudaError_t) (cudaError::cudaErrorInvalidDeviceFunction) : (unsigned int) 8

The new problem is that cling::Interpreter::loadFile() calls cling::Interpreter::loadHeader(), that calls cling::Interpreter::DeclareInternal(), that calls cling::IncrementalParser::Compile(). But the device cling::Interpreter does not have a working backend. The backend is provided by the IncrementalCUDADdeviceCompiler class. Currently, the IncrementalCUDADeviceCompiler class reimplements parts of the cling::Interpreter API to couple the cling::Interpreter frontend to the nvptx backend. Therefore, this function must be called instead of the functions of the device cling::Interpreter. The function declareInternal() is currently missing.

Possible solution

add declareInternal() to IncrementalCUDADeviceCompiler

It's a quick solution, but it requires an ugly if statement in cling::Interpreter::declareInternal() which checks whether the current interpreter instance is the host or the device. Another problem is that declareInternal() is not the only function that has this kind of problem. Many functions will follow.

Integrate the nvptx backend in the cling::Interpreter class

Avoid some ungly code. Is a more stable and generic solution. Needs more time for implementation. Probably needs to modify the transaction system. But the modification is also necessary for some other features.
-> Better solution -> will be implemented

Test case for clang-test

kernel.cpp

__global__ void g1(int * out){
  *out = 42;
}

CUDALoadFile.C

//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

// The test checks whether setting a new include path at runtime also works for
// the PTX compiler.
// RUN: cat %s | %cling -DTEST_PATH="\"%/p/\"" -x cuda -Xclang -verify 2>&1 | FileCheck %s
// REQUIRES: cuda-runtime

#include <iostream>

// Check if cuda driver is available
int version;
cudaDriverGetVersion(&version)
// CHECK: (cudaError_t) (cudaError::cudaSuccess) : (unsigned int) 0

// Check if a CUDA compatible device (GPU) is available.
int device_count = 0;
cudaGetDeviceCount(&device_count)
// CHECK: (cudaError_t) (cudaError::cudaSuccess) : (unsigned int) 0
device_count > 0
// CHECK: (bool) true

// load kernel from file
.L include/kernel.cpp

int host = -1;
int *device;

// allocate memory on device
cudaMalloc((void**)&device, sizeof(int))
// CHECK: (cudaError_t) (cudaError::cudaSuccess) : (unsigned int) 0

// run kernel and check execution result
g1<<<1,1>>>(device);
cudaGetLastError()
// CHECK: (cudaError_t) (cudaError::cudaSuccess) : (unsigned int) 0

// copy result to host and check it
cudaMemcpy(&host, device, sizeof(int), cudaMemcpyDeviceToHost)
// CHECK: (cudaError_t) (cudaError::cudaSuccess) : (unsigned int) 0
host
// CHECK: (int) 42

// expected-no-diagnostics
.q
@SimeonEhrig SimeonEhrig added the bug Something isn't working label Jul 30, 2019
SimeonEhrig pushed a commit that referenced this issue May 4, 2022
Before, MetaParser might have pointed to a StringRef whose storage
was gone, see asan failure in roottest/cling/other/runfileClose.C below.

This was caused by recursive uses of MetaParser; see stack trace below:
the inner recursion returned, but as the same MetaParser object was used
by both frames, the objects cursor now pointed to freed memory.

Instead, create a MetaParser (and MetaLexer) object per input. That way,
their lifetime corresponds to the lifetime of their input.

=================================================================
==529104==ERROR: AddressSanitizer: stack-use-after-return on address 0x7ffff3afd82a at pc 0x7fffea18df6d bp 0x7fffffff8170 sp 0x7fffffff8168
READ of size 1 at 0x7ffff3afd82a thread T0
[Detaching after fork from child process 529183]
    #0 0x7fffea18df6c in cling::MetaLexer::Lex(cling::Token&) src/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp:58:11
    #1 0x7fffea190d7c in cling::MetaParser::lookAhead(unsigned int) src/interpreter/cling/lib/MetaProcessor/MetaParser.cpp:89:15
    #2 0x7fffea190bd5 in cling::MetaParser::consumeToken() src/interpreter/cling/lib/MetaProcessor/MetaParser.cpp:49:5
    #3 0x7fffea191d4d in cling::MetaParser::isLCommand(cling::MetaSema::ActionResult&) src/interpreter/cling/lib/MetaProcessor/MetaParser.cpp:147:9
    #4 0x7fffea1914dd in cling::MetaParser::isCommand(cling::MetaSema::ActionResult&, cling::Value*) src/interpreter/cling/lib/MetaProcessor/MetaParser.cpp:123:12
    #5 0x7fffea191216 in cling::MetaParser::isMetaCommand(cling::MetaSema::ActionResult&, cling::Value*) src/interpreter/cling/lib/MetaProcessor/MetaParser.cpp:101:33
    #6 0x7fffea14e5aa in cling::MetaProcessor::process(llvm::StringRef, cling::Interpreter::CompilationResult&, cling::Value*, bool) src/interpreter/cling/lib/MetaProcessor/MetaProcessor.cpp:317:24
    #7 0x7fffe99b67b7 in HandleInterpreterException(cling::MetaProcessor*, char const*, cling::Interpreter::CompilationResult&, cling::Value*) src/core/metacling/src/TCling.cxx:2431:29
    #8 0x7fffe99bde30 in TCling::Load(char const*, bool) src/core/metacling/src/TCling.cxx:3454:10
    #9 0x7ffff7865f11 in TSystem::Load(char const*, char const*, bool) src/core/base/src/TSystem.cxx:1941:27
    #10 0x7ffff7b8a0e3 in TUnixSystem::Load(char const*, char const*, bool) src/core/unix/src/TUnixSystem.cxx:2789:20
    #11 0x7fffd78dd08b  (<unknown module>)
    root-project#12 0x7fffe9f8a5d9 in cling::IncrementalExecutor::executeWrapper(llvm::StringRef, cling::Value*) const src/interpreter/cling/lib/Interpreter/IncrementalExecutor.cpp:376:3
    root-project#13 0x7fffe9d73dc2 in cling::Interpreter::RunFunction(clang::FunctionDecl const*, cling::Value*) src/interpreter/cling/lib/Interpreter/Interpreter.cpp:1141:20
    root-project#14 0x7fffe9d6e317 in cling::Interpreter::EvaluateInternal(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::CompilationOptions, cling::Value*, cling::Transaction**, unsigned long) src/interpreter/cling/lib/Interpreter/Interpreter.cpp:1391:29
    root-project#15 0x7fffe9d6c1fe in cling::Interpreter::process(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, cling::Value*, cling::Transaction**, bool) src/interpreter/cling/lib/Interpreter/Interpreter.cpp:819:9
    root-project#16 0x7fffea151826 in cling::MetaProcessor::readInputFromFile(llvm::StringRef, cling::Value*, unsigned long, bool) src/interpreter/cling/lib/MetaProcessor/MetaProcessor.cpp:507:22
    root-project#17 0x7fffe99b585b in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) src/core/metacling/src/TCling.cxx:2570:39
    root-project#18 0x7fffe99bbfee in TCling::ProcessLineSynch(char const*, TInterpreter::EErrorCode*) src/core/metacling/src/TCling.cxx:3496:17
    root-project#19 0x7ffff77203d3 in TApplication::ExecuteFile(char const*, int*, bool) src/core/base/src/TApplication.cxx:1608:30
    root-project#20 0x7ffff771ebdf in TApplication::ProcessFile(char const*, int*, bool) src/core/base/src/TApplication.cxx:1480:11
    root-project#21 0x7ffff771e385 in TApplication::ProcessLine(char const*, bool, int*) src/core/base/src/TApplication.cxx:1453:14
    root-project#22 0x7ffff7f8157a in TRint::ProcessLineNr(char const*, char const*, int*) src/core/rint/src/TRint.cxx:766:11
    root-project#23 0x7ffff7f802f0 in TRint::Run(bool) src/core/rint/src/TRint.cxx:424:22
    root-project#24 0x4ff96d in main src/main/src/rmain.cxx:30:12
    root-project#25 0x7ffff6e040b2 in __libc_start_main /build/glibc-YbNSs7/glibc-2.31/csu/../csu/libc-start.c:308:16
    root-project#26 0x41f35d in _start (asan/bin/root.exe+0x41f35d)

Address 0x7ffff3afd82a is located in stack of thread T0 at offset 42 in frame
    #0 0x7fffe99b3d8f in TCling::ProcessLine(char const*, TInterpreter::EErrorCode*) src/core/metacling/src/TCling.cxx:2456

  This frame has 21 object(s):
    [32, 56) 'sLine' (line 2462) <== Memory access at offset 42 is inside this variable
    [96, 104) 'R__guard2471' (line 2471)
    [128, 136) 'R__guard2488' (line 2488)
    [160, 176) 'interpreterFlagsRAII' (line 2491)
    [192, 240) 'result' (line 2511)
    [272, 276) 'compRes' (line 2512)
    [288, 312) 'mod_line' (line 2517)
    [352, 376) 'aclicMode' (line 2518)
    [416, 440) 'arguments' (line 2519)
    [480, 504) 'io' (line 2520)
    [544, 568) 'fname' (line 2521)
    [608, 632) 'ref.tmp' (line 2547)
    [672, 696) 'ref.tmp145' (line 2547)
    [736, 768) 'code' (line 2555)
    [800, 832) 'codeline' (line 2556)
    [864, 1384) 'in' (line 2559)
    [1520, 1552) 'ref.tmp176' (line 2562)
    [1584, 1600) 'agg.tmp'
    [1616, 1624) 'ref.tmp198' (line 2568)
    [1648, 1664) 'agg.tmp207'
    [1680, 1696) 'autoParseRaii' (line 2588)
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
      (longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-use-after-return src/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp:58:11 in cling::MetaLexer::Lex(cling::Token&)
Shadow bytes around the buggy address:
  0x10007e757ab0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757ac0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757ad0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757ae0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757af0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
=>0x10007e757b00: f5 f5 f5 f5 f5[f5]f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757b10: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757b20: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757b30: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757b40: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
  0x10007e757b50: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==529104==ABORTING

    at src/interpreter/cling/lib/MetaProcessor/MetaLexer.cpp:49
    at src/interpreter/cling/lib/MetaProcessor/MetaParser.cpp:41
    compRes=@0x7ffff3afd910: cling::Interpreter::kSuccess, result=0x7ffff3afd8c0, disableValuePrinting=false)
    at src/interpreter/cling/lib/MetaProcessor/MetaProcessor.cpp:314
    input_line=0x7ffff3afd829 "#define XYZ 21", compRes=@0x7ffff3afd910: cling::Interpreter::kSuccess,
    result=0x7ffff3afd8c0) at src/core/metacling/src/TCling.cxx:2431
    error=0x7fffd78cb0f4 <x>) at src/core/metacling/src/TCling.cxx:2591
    sync=false, err=0x7fffd78cb0f4 <x>) at src/core/base/src/TApplication.cxx:1472
    line=0x7fffd78c9000 "#define XYZ 21", error=0x7fffd78cb0f4 <x>)
    at src/core/base/src/TROOT.cxx:2328
   from asan/roottest/cling/other/fileClose_C.so
    filename=0x6070000f0fd0 "asan/roottest/cling/other/fileClose_C.so", flag=257)
    at /home/axel/build/llvm/llvm-project/compiler-rt/lib/asan/../sanitizer_common/sanitizer_common_interceptors.inc:6270
    at src/interpreter/cling/lib/Utils/PlatformPosix.cpp:118
    permanent=false, resolved=true)
    at src/interpreter/cling/lib/Interpreter/DynamicLibraryManager.cpp:184
    at src/interpreter/cling/lib/Interpreter/Interpreter.cpp:1444
    T=0x0) at src/interpreter/cling/lib/Interpreter/Interpreter.cpp:1560
    at src/interpreter/cling/lib/MetaProcessor/MetaSema.cpp:57
    actionResult=@0x7ffff39532b0: cling::MetaSema::AR_Success)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

1 participant