-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Fix PR #15489 (Dynamic Library Loading Support) #15760
Changes from all commits
f116f10
42fda42
bb12267
cb40a02
8feb07d
ca608ff
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| # Licensed to the Apache Software Foundation (ASF) under one | ||
| # or more contributor license agreements. See the NOTICE file | ||
| # distributed with this work for additional information | ||
| # regarding copyright ownership. The ASF licenses this file | ||
| # to you under the Apache License, Version 2.0 (the | ||
| # "License"); you may not use this file except in compliance | ||
| # with the License. You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, | ||
| # software distributed under the License is distributed on an | ||
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| # KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations | ||
| # under the License. | ||
|
|
||
| all: | ||
| g++ -shared -fPIC mylib.cc -o mylib.so -I ../../include/mxnet | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If CI doesn't pass, I suggest to use
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @larroy this isnt building in the CI. this is just an example. See changes in the other Makefile or CMakeLists.txt for changes to build the library in the CI
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I understand, but still this is a PITA if a Makefile doesn't respect the compiler from the environment. That's why I said is not worth another CI round. If you make other changes I would change it. Or is there a reason not to?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How does that work for windows? will it automatically have CXX be "cl" ? |
||
|
|
||
| test: | ||
| g++ -std=c++11 -O3 -o libtest libtest.cc -ldl -I ../../include/mxnet | ||
|
|
||
| windows: | ||
| cl /LD mylib.cc | ||
|
|
||
| win_test: | ||
| cl libtest.cc | ||
|
|
||
| clean: | ||
| rm -rf mylib.so libtest | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,78 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
|
|
||
| /*! | ||
| * Copyright (c) 2015 by Contributors | ||
| * \file libtest.cc | ||
| * \brief This test checks if the library is implemented correctly | ||
| * and does not involve dynamic loading of library into MXNet | ||
| * This test is supposed to be run before test.py | ||
| */ | ||
|
|
||
| #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) | ||
| #include <windows.h> | ||
| #else | ||
| #include <dlfcn.h> | ||
| #endif | ||
|
|
||
| #include <iostream> | ||
| #include "lib_api.h" | ||
|
|
||
| #define MXNET_VERSION 10500 | ||
|
|
||
| int main(void) { | ||
| // Get a handle to the library. | ||
| #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) | ||
| HINSTANCE handle; | ||
| handle = LoadLibrary(TEXT("mylib.dll")); | ||
| #else | ||
| void *handle; | ||
| handle = dlopen("mylib.so", RTLD_LAZY); | ||
| #endif | ||
|
|
||
| if (!handle) { | ||
| std::cerr << "Unable to load library" << std::endl; | ||
| return 1; | ||
| } | ||
|
|
||
| // get initialize function address from the library | ||
| initialize_t init_lib; | ||
| #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) | ||
| init_lib = (initialize_t) GetProcAddress(handle, MXLIB_INITIALIZE_STR); | ||
| #else | ||
| init_lib = (initialize_t) dlsym(handle, MXLIB_INITIALIZE_STR); | ||
| #endif | ||
|
|
||
| if (!init_lib) { | ||
| std::cerr << "Unable to get function 'intialize' from library" << std::endl; | ||
| return 1; | ||
| } | ||
|
|
||
| // Call the function. | ||
| (init_lib)(MXNET_VERSION); | ||
|
|
||
| // Deallocate memory. | ||
| #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) | ||
| FreeLibrary(handle); | ||
| #else | ||
| dlclose(handle); | ||
| #endif | ||
|
|
||
| return 0; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,37 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
|
|
||
| /*! | ||
| * Copyright (c) 2015 by Contributors | ||
| * \file mylib.cc | ||
| * \brief Sample library file | ||
| */ | ||
|
|
||
| #include <iostream> | ||
| #include "lib_api.h" | ||
|
|
||
| int initialize(int version) { | ||
| if (version >= 10400) { | ||
| std::cout << "MXNet version " << version << " supported" << std::endl; | ||
| return 1; | ||
| } else { | ||
| std::cout << "MXNet version " << version << " not supported" << std::endl; | ||
| return 0; | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| #!/usr/bin/env python3 | ||
|
|
||
| # Licensed to the Apache Software Foundation (ASF) under one | ||
| # or more contributor license agreements. See the NOTICE file | ||
| # distributed with this work for additional information | ||
| # regarding copyright ownership. The ASF licenses this file | ||
| # to you under the Apache License, Version 2.0 (the | ||
| # "License"); you may not use this file except in compliance | ||
| # with the License. You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, | ||
| # software distributed under the License is distributed on an | ||
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| # KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations | ||
| # under the License. | ||
|
|
||
| # coding: utf-8 | ||
| # pylint: disable=arguments-differ | ||
|
|
||
| # This test checks if dynamic loading of library into MXNet is successful | ||
|
|
||
| import mxnet as mx | ||
| import os | ||
|
|
||
| if (os.name=='posix'): | ||
| mx.library.load('mylib.so') | ||
| elif (os.name=='nt'): | ||
| mx.library.load('mylib.dll') |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /* | ||
| * Licensed to the Apache Software Foundation (ASF) under one | ||
| * or more contributor license agreements. See the NOTICE file | ||
| * distributed with this work for additional information | ||
| * regarding copyright ownership. The ASF licenses this file | ||
| * to you under the Apache License, Version 2.0 (the | ||
| * "License"); you may not use this file except in compliance | ||
| * with the License. You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, | ||
| * software distributed under the License is distributed on an | ||
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| * KIND, either express or implied. See the License for the | ||
| * specific language governing permissions and limitations | ||
| * under the License. | ||
| */ | ||
|
|
||
| /*! | ||
| * Copyright (c) 2015 by Contributors | ||
| * \file lib_api.h | ||
| * \brief APIs to interact with libraries | ||
| */ | ||
| #ifndef MXNET_LIB_API_H_ | ||
| #define MXNET_LIB_API_H_ | ||
|
|
||
| /*! | ||
| * \brief Following are the APIs implemented in the external library | ||
| * Each API has a #define string that is used to lookup the function in the library | ||
| * Followed by the function declaration | ||
| */ | ||
| #define MXLIB_INITIALIZE_STR "initialize" | ||
| typedef int (*initialize_t)(int); | ||
|
|
||
| extern "C" { | ||
| /*! | ||
| * \brief Checks if the MXNet version is supported by the library. | ||
| * If supported, initializes the library. | ||
| * \param version MXNet version number passed to library and defined as: | ||
| * MXNET_VERSION = (MXNET_MAJOR*10000 + MXNET_MINOR*100 + MXNET_PATCH) | ||
| * \return Non-zero value on error i.e. library incompatible with passed MXNet version | ||
| */ | ||
| #if defined(_WIN32) || defined(_WIN64) || defined(__WINDOWS__) | ||
| __declspec(dllexport) int __cdecl initialize(int); | ||
| #else | ||
| int initialize(int); | ||
| #endif | ||
| } | ||
| #endif // MXNET_LIB_API_H_ |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # Licensed to the Apache Software Foundation (ASF) under one | ||
| # or more contributor license agreements. See the NOTICE file | ||
| # distributed with this work for additional information | ||
| # regarding copyright ownership. The ASF licenses this file | ||
| # to you under the Apache License, Version 2.0 (the | ||
| # "License"); you may not use this file except in compliance | ||
| # with the License. You may obtain a copy of the License at | ||
| # | ||
| # http://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, | ||
| # software distributed under the License is distributed on an | ||
| # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | ||
| # KIND, either express or implied. See the License for the | ||
| # specific language governing permissions and limitations | ||
| # under the License. | ||
|
|
||
| # coding: utf-8 | ||
| """Library management API of mxnet.""" | ||
| from __future__ import absolute_import | ||
| import ctypes | ||
| import os | ||
| from .base import _LIB, check_call, MXNetError | ||
|
|
||
| def load(path): | ||
| """Loads library dynamically. | ||
|
|
||
| Parameters | ||
| --------- | ||
| path : Path to library .so/.dll file | ||
|
|
||
| Returns | ||
| --------- | ||
| void | ||
| """ | ||
| #check if path exists | ||
| if not os.path.exists(path): | ||
| raise MXNetError("load path %s does NOT exist" % path) | ||
| #check if path is an absolute path | ||
| if not os.path.isabs(path): | ||
| raise MXNetError("load path %s is not an absolute path" % path) | ||
| #check if path is to a library file | ||
| _, file_ext = os.path.splitext(path) | ||
| if not file_ext in ['.so', '.dll']: | ||
| raise MXNetError("load path %s is NOT a library file" % path) | ||
|
|
||
| byt_obj = path.encode('utf-8') | ||
| chararr = ctypes.c_char_p(byt_obj) | ||
| check_call(_LIB.MXLoadLib(chararr)) |
Uh oh!
There was an error while loading. Please reload this page.