SCons - 为 CUDA、CORBA 等集成自定义构建器

Posted

技术标签:

【中文标题】SCons - 为 CUDA、CORBA 等集成自定义构建器【英文标题】:SCons - integrating custom builders for CUDA, CORBA etc 【发布时间】:2015-11-28 18:18:05 【问题描述】:

对于一个异构(C、C++14、Fortran95、python3)项目,我目前正在评估 CMake SCons 将为我们提供哪些优势,以集成 CUDA (7.5)、CORBA 的平台编译器和编译器包装器(omniorb-4.2.1)、MPI2(MPICH)等

首先,我创建了一个项目根目录(附加的 SConstruct 脚本中的“data/projects/sn-ps”)和一个子目录“model”in which the 'echo.idl' of the omniorb4 Documentation

interface Echo  
    string echoString(in string mesg); 
;

驻留(带有int main()int main() 将由与-Wbexample 开关一起使用的omniidl 生成)和一个子目录树'include/cuda_samples_inc',它是'common/ inc' 的 CUDA Toolkit Samples 分支,并复制了 CUDA Toolkit Samples

2_Graphics/simpleGL/simpleGL.cu 

进入项目根目录。

我的自定义 SConstruct

import os

CORBA_PASS = False
CUDA_PASS = True

CUDA_FAIL = not CUDA_PASS
CORBA_FAIL = not CORBA_PASS

EXE_SUFFIX = None
if os.name != 'posix':
    raise NotImplementedError('Only on POSIX platforms yet')


PROJECT_ROOT = '/data/projects/snippets'  # your mileage will likely vary

INCLUDE_DIR = os.path.join(PROJECT_ROOT, 'include')
LIB_DIR = os.path.join(PROJECT_ROOT, 'lib')

SYS_LIBS = ['dl', 'pthread']
GL_LIBS = ['glut', 'GLEW', 'GL', 'GLU', 'X11']
CORBA_LIBS = ['omniORB4', 'omnithread']


class CUDAEnvironment(Environment):
    CUDA_ROOT = '/usr/local/cuda-7.5'
    CUDA_BIN_DIR = os.path.join(CUDA_ROOT, 'bin')
    CUDA_INCLUDE_DIRS = os.path.join(INCLUDE_DIR, 'cuda_samples_inc')
    GENC = "-gencode arch=compute_%d,code=sm_%d "
    GEN_RANGE = [20, 30, 35, 37, 50, 52]
    GENT = "-gencode arch=compute_52,code=compute_52"
    GENS = " ".join([GENC % (n, n) for n in GEN_RANGE]) + GENT

    COMPILE = """\
        %s/nvcc -ccbin g++ -I %s -m64 %s -o $TARGET -c $SOURCE \
    """ % (CUDA_BIN_DIR, CUDA_INCLUDE_DIRS, GENS)

    LINK = """\
        %s/nvcc -ccbin g++ -I %s -m64 %s -o $TARGET $SOURCE \
        -L%s, %s\
    """ % (CUDA_BIN_DIR, CUDA_INCLUDE_DIRS, GENS, LIB_DIR,
           ''.join([' -l%s' % (s,) for s in GL_LIBS]))

    def __init__(self):
        super(Environment, self).__init__()
        C = CUDAEnvironment  # class alias

        self.Append(PATH=":".join([os.environ['PATH'],
                                    C.CUDA_BIN_DIR]))

        cu2o = Builder(action=C.COMPILE, suffix='.o', src_suffix='.cu')
        o2exe = Builder(action=C.LINK, suffix=EXE_SUFFIX, src_suffix='.o')

        self.Append(BUILDERS='CU2O': cu2o, 'O2EXE': o2exe)


if (CUDA_PASS):
    CUDA = CUDAEnvironment()
    CUDA.CU2O(['simpleGL.cu'])
    CUDA.O2EXE(['simpleGL.o'])

if (CUDA_FAIL):
    CUDA = CUDAEnvironment()
    o = CUDA.Object(['simpleGL.cu']) # line 63
    CUDA.Program(o)


class CORBAEnvironment(Environment):
    IDL2CC = """
        omniidl -bcxx -Wbexample $SOURCE
        cp `basename $SOURCE .idl`SK.cc `basename $SOURCE .idl`.cc
     """        
    COMPILE = """\
        g++ -std=c++14 -I. -Wall -pedantic %s $SOURCES -o $TARGET
    """ % (''.join([' -l%s' % (s,) for s in CORBA_LIBS + SYS_LIBS]))

    def __init__(self):
        super(Environment, self).__init__()
        C = CORBAEnvironment  # class alias

        idl2cc = Builder(
            action=C.IDL2CC, suffix='.cc', src_suffix='.idl'
        )

        cc2exe = Builder(
            action=C.COMPILE, suffix=EXE_SUFFIX, src_suffix='.cc'
        )

        self.Append(BUILDERS='IDL2CC': idl2cc, 'CC2EXE': cc2exe)


if (CORBA_PASS):
    CORBA = CORBAEnvironment()
    CORBA.IDL2CC('echo.cc', os.path.join('model', 'echo.idl'))
    CORBA.CC2EXE('echo', ['echo.cc', 'echo_i.cc'])

if (CORBA_FAIL):
    CORBA = CORBAEnvironment()
    skel = CORBA.Object(os.path.join('model', 'echo.idl'))  # line 98
    impl = CORBA.Object('echo_i.cc')
    CORBA.Program([skel, impl])

在启用开关CUDA_PASSCORBA_PASS 时效果很好,但对于

CUDA = CUDAEnvironment()
o = CUDA.Object(['simpleGL.cu']) # line 63
CUDA.Program(o)

回复

CORBA = CORBAEnvironment()
skel = CORBA.Object(os.path.join('model', 'echo.idl'))  # line 98
impl = CORBA.Object('echo_i.cc')
CORBA.Program([skel, impl])

blocks,scons 因为我害怕的那种错误而放弃了:

scons: *** While building `['simpleGL.o']' from `['simpleGL.cu']'
Don't know how to build from a source file with suffix `.cu'.  
Expected a suffix in this list: ['.c', '.m', '.cpp', '.cc', '.cxx', 
'.c++', '.C++', '.mm', '.C', '.f', '.for', '.ftn', '.fpp', '.FPP',
'.F', '.FOR', '.FTN', '.f77', '.F77', '.f90', '.F90', '.f95', '.F95',
'.f03', '.F03', '.s', '.asm', '.ASM', '.spp', '.SPP', '.sx', '.S'].
File "/data/projects/snippets/SConstruct", line 63, in <module>

分别:

scons: *** While building `['model/echo.o']' from `['model/echo.idl']':
Don't know how to build from a source file with suffix `.idl'
[same as above]
File "/data/projects/snippets/SConstruct", line 98, in <module>.

很遗憾,

如何从后缀为&lt;suffix&gt;的源文件构建

这正是我试图用我的自定义环境和构建器告诉 scons 的。

所以我的问题是:

如何集成自定义环境和构建器,以便使用 SCons Object()Program() 构建器外观?

Scons Builder() doc,尤其是。 18.2. Attaching a Builder to a Construction Environment 似乎只是解释了我的 PASS 块中使用的语法以及传递的 Program() 调用,但不是如何制作例如'Object()' 知道自定义构建器。

不用说,python 本身几乎可以用于手动编码所有类型的行为或附加组件,但我希望尽可能地留在 SCons 工具集的范围内。

版本:

SCons 2.3.1(但这并不是一成不变的,如果更新到 2.4.1 会有所帮助,我会这样做)与python 2.7.9 一起运行

【问题讨论】:

这个问题和CUDA编程有什么关系?为什么它带有 CUDA 标签?不是纯粹的scons 配置问题吗? 【参考方案1】:

SCons 有src_builder 的概念。它是一个关键字(通常添加到 Builder 类的构造函数中),它通知系统如何通过首先运行额外的构建器来创建实际的 C/CPP 源文件。 在 ll 中查看工具 engine/SCons/Tool/qt.py。 315 上面写着:

# register the builders 
env['BUILDERS']['Uic'] = uicBld
env['BUILDERS']['Moc'] = mocBld
static_obj, shared_obj = SCons.Tool.createObjBuilders(env)
static_obj.add_src_builder('Uic')
shared_obj.add_src_builder('Uic')

。通过调用add_src_builder,Uic 构建器将分别注册到静态和共享对象构建器。然后,如果将*.uic 文件直接提供给Object,SCons 会检查其定义的源构建器列表,将*.uic 转换为其对应的*.cc 文件,然后将后者传递给对象构建器。

【讨论】:

非常感谢!这绝对是向前迈出的一大步,至少对 CORBA 的 Object() 调用(在对我的代码进行了一些琐碎的修改之后)与 .idl 一起工作。问题是,CU2O 工具已经生成了一个.o,如果我尝试将我的CU2O 添加为src_builder,scons 理所当然地抱怨Multiple ways to build the same target [...] simpleGL.o。此外,我现在正在寻找相关Tool.createProgBuilder(env) 的一些用途,以便在Program() 调用下插入我的exe 构建器。当我有实质性进展时,我会更新我的代码,如果可以的话,我想给你写信。 一旦您成功掌握了对象文件的创建,您应该让 Program 的默认处理程序处理链接步骤。不要提供专门的构建器来将每个对象链接到最终的可执行文件中。相反,为每个需要不同路径和/或设置的构建任务初始化一个单独的环境。您还需要使用 CPPPATH 之类的特殊变量来包含目录,而不是将“-I”标志硬编码到命令调用中,因为前者让您也可以在 Windows 上构建。 由于您从 SCons 开始,并查看您当前的构建规范,我还建议您订阅我们的用户邮件列表(scons-users@scons.org,另请参阅 @987654321 @ ) 并开始在那里提出您的进一步问题。您将在那里接触到更广泛的 SCons 专家...而且响应时间通常很短。 我一定会订阅该列表;提示。 这里的错误消息有几个重复项。在检查其他已经存在的答案对您没有帮助之后,最好打开一个新问题。

以上是关于SCons - 为 CUDA、CORBA 等集成自定义构建器的主要内容,如果未能解决你的问题,请参考以下文章

CORBA 和 MOM 集成

使用 SCons 着色编译器诊断

自定义python模块路径

Corba python 与 web 服务 java 的集成

利用scons构建project

在 Scons 中将“-W1,-rpath=\$ORIGIN”替换为“-W1,-rpath,\$ORIGIN”