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

[headers] remove many installed files which should remain private, add more fixes for downstream projects #2952

Merged
merged 22 commits into from
Jun 5, 2019

Conversation

cenit
Copy link
Collaborator

@cenit cenit commented Apr 17, 2019

as per title.
Discussing about publishing the tool and live in peace with other libraries, I was informed that we export some header files that have the same name as other libraries. The best solution is to wrap them inside a darknet folder. Thanks to common usage of the tool which does not involve installing darknet system-wide, and thanks also to the power of CMake that can make this change invisible to the end user, this change should not impact anyone. In the meantime I also implemented some minor fixes for downstream projects using darknet through CMake

CMakeLists.txt Outdated Show resolved Hide resolved
@cenit
Copy link
Collaborator Author

cenit commented Apr 18, 2019

due to #2956 discussion, I just understood that it is not necessary to install all header files like it is done now. Since we want to reduce API exposure also with the CMake toolchain, we can just install darknet.h and yolo_v2_class.hpp, solving all our problems without even having to move headers to a separate folders.

@AlexeyAB
Copy link
Owner

Does this PR fixes some cases with OSx, build.sh, cuDNN, or something else?

@cenit
Copy link
Collaborator Author

cenit commented Apr 18, 2019

yes some very minor changes. But let me prepare another commit to undo changes in header path location before considering merge

@cenit cenit changed the title [headers] move .h files to our own subfolder when installed to avoid clashes with other libraries [headers] remove many installed files which should remain private, add more fixes for downstream projects Apr 18, 2019
@cenit
Copy link
Collaborator Author

cenit commented Apr 18, 2019

vcpkg CI integration on Linux is not really working. I have to debug what’s going on

@cenit
Copy link
Collaborator Author

cenit commented Apr 18, 2019

Then it will be ready for merging considerations

@AlexeyAB
Copy link
Owner

Ok, just say when I can merge it.

Also is it known issue with CUDA 10.1? #2971

@AlexeyAB
Copy link
Owner

@cenit Hi,
Can we somehow add support for multiple CUDA Compute Capabilities?
Or at least always_CC3.0 + selected_CC? #3014

@cenit
Copy link
Collaborator Author

cenit commented Apr 23, 2019

@cenit Hi,
Can we somehow add support for multiple CUDA Compute Capabilities?
Or at least always_CC3.0 + selected_CC? #3014

hi! Yes this should be my next priority, before even working on the setup script.
Let me just push another commit here so that we can consider this complete and then it will be my next stage

@cenit
Copy link
Collaborator Author

cenit commented Apr 23, 2019

ok only one question remain unsolved for this PR (apart from the API expansion, which I strongly support but I'd prefer if you did it), please let me know your opinion so that I can apply it:
for downstream projects, do you prefer

#include <darknet.h>

or

#include <darknet/darknet.h>

?

The first looks shorter and easier, but if we want to expand headers from the two as of now (darknet.h and yolo_v2_class.hpp) to others, it is better if we already start to "namespace" our files inside "our folder". In this way, we can use also generic names without risking to overlap with files already installed on the system (think about darknet installed by vcpkg or a package manager, not when darknet lives in his own folder cloned through git, in this case there is no problem)

@AlexeyAB
Copy link
Owner

We can use the second way #include <darknet/darknet.h>. As it is used in OpenCV #include <opencv2/opencv.hpp> or Boost-library #include <boost/asio.hpp> in common way.
Will you do this in your PR?


it is better if we already start to "namespace" our files inside "our folder".

It is easy to do for C++ yolo_v2_class.hpp (also I should rename it to yolo_api.hpp or darknet_api.hpp) since we should only add 2 lines

namespace dark {
...
}

But it is much more difficult to do for C darknet.h since we should rename all API functions for adding prefix dark_ or dn_, so we should rename all these functions and their calls in the all c-files in Darknet. The main thing is not to spoil anything, so it can be a long process.

Also it affects on Python scripts, that are use C API.


Also we should think about C# API https://github.com/AlexeyAB/darknet/blob/099b71d1de6b992ce8f9d7ff585c84efd0d4bf94/build/darknet/YoloWrapper.cs
that is C-API

extern "C" LIB_API int init(const char *configurationFilename, const char *weightsFilename, int gpu);
extern "C" LIB_API int detect_image(const char *filename, bbox_t_container &container);
extern "C" LIB_API int detect_mat(const uint8_t* data, const size_t data_length, bbox_t_container &container);
extern "C" LIB_API int dispose();
extern "C" LIB_API int get_device_count();
extern "C" LIB_API int get_device_name(int gpu, char* deviceName);
extern "C" LIB_API void send_json_custom(char const* send_buf, int port, int timeout);

which uses C++-API
//static Detector* detector = NULL;
static std::unique_ptr<Detector> detector;
int init(const char *configurationFilename, const char *weightsFilename, int gpu)
{
detector.reset(new Detector(configurationFilename, weightsFilename, gpu));
return 1;
}
int detect_image(const char *filename, bbox_t_container &container)
{
std::vector<bbox_t> detection = detector->detect(filename);
for (size_t i = 0; i < detection.size() && i < C_SHARP_MAX_OBJECTS; ++i)
container.candidates[i] = detection[i];
return detection.size();
}
int detect_mat(const uint8_t* data, const size_t data_length, bbox_t_container &container) {
#ifdef OPENCV
std::vector<char> vdata(data, data + data_length);
cv::Mat image = imdecode(cv::Mat(vdata), 1);
std::vector<bbox_t> detection = detector->detect(image);
for (size_t i = 0; i < detection.size() && i < C_SHARP_MAX_OBJECTS; ++i)
container.candidates[i] = detection[i];
return detection.size();
#else
return -1;
#endif // OPENCV
}
int dispose() {
//if (detector != NULL) delete detector;
//detector = NULL;
detector.reset();
return 1;
}
int get_device_count() {
#ifdef GPU
int count = 0;
cudaGetDeviceCount(&count);
return count;
#else
return -1;
#endif // GPU
}
int get_device_name(int gpu, char* deviceName) {
#ifdef GPU
cudaDeviceProp prop;
cudaGetDeviceProperties(&prop, gpu);
std::string result = prop.name;
std::copy(result.begin(), result.end(), deviceName);
return 1;
#else
return -1;
#endif // GPU
}
#ifdef GPU
void check_cuda(cudaError_t status) {
if (status != cudaSuccess) {
const char *s = cudaGetErrorString(status);
printf("CUDA Error Prev: %s\n", s);
}
}
#endif
struct detector_gpu_t {
network net;
image images[NFRAMES];
float *avg;
float* predictions[NFRAMES];
int demo_index;
unsigned int *track_id;
};

@cenit
Copy link
Collaborator Author

cenit commented Apr 23, 2019

What I meant with namespacing under quotes was just the darknet/ folder. I will do it in this PR, in the next commit.

But I also understand your point, about real namespacing, which is maybe necessary only for the C++ header. Because as you said it’s more difficult and for C it impacts also python. It deserves another PR for sure. When discussing the API surface expansion we can discuss the rework of the namespace and a revision of C/C++/C#

@cenit
Copy link
Collaborator Author

cenit commented May 4, 2019

I still have some improvements to apply for downstream users of darknet library. Sorry for the delay, I had some problems

@AlexeyAB
Copy link
Owner

AlexeyAB commented May 7, 2019

@cenit Hi,

Is this PR ready and I can merge it?

I created several projects: https://github.com/AlexeyAB/darknet/projects
And added tasks which you do: https://github.com/AlexeyAB/darknet/projects/3

@cenit
Copy link
Collaborator Author

cenit commented May 7, 2019

Hi no sorry still not finished. I am very sorry, I am too much busy these days. Tomorrow I will finish it!

edit: wonderful projects! Just had the time to read them, wow! Yes, that's exactly what I meant. In this way we can see better our way forwards!

@cenit
Copy link
Collaborator Author

cenit commented May 13, 2019

waiting for microsoft/vcpkg#6417 to be merged since it fixes vcpkg on macOS. Some tests also on my part, then it should be ready to merge

@AlexeyAB
Copy link
Owner

Nice work! Will wait.

@cenit
Copy link
Collaborator Author

cenit commented May 14, 2019

microsoft/vcpkg#6417 is merged. And PR should be almost ready. I'd like to do some other tests, but I don't know if I have time today

edit: I will read CI logs and check for regression later when it will be finished, since I changed some logics inside CMake

@cenit
Copy link
Collaborator Author

cenit commented May 16, 2019

I think it should be ready to let users test it. In case of problems I will help debug.
Two things are important: best cuda compute capability is detected automatically and now we can use multiple CUDA compute capabilities in CMake easily. It was an easy win with this refactor!

@AlexeyAB
Copy link
Owner

Thanks a lot! Does it use by default two CCs: CC 3.0 + CC 7.0/7.5 selected based on CUDA-version?

@cenit
Copy link
Collaborator Author

cenit commented May 16, 2019

for now it just choose the best CC based on your gpu and your cuda version. On CI, where the detection fails because there's no GPU, it builds for ALL CCs 😄 it seems to work well!
Manually from the cmake interface (command line or gui) you can tell the script to do it automatically (best CC) or to build for some specific CCs

@AlexeyAB
Copy link
Owner

Can we add CUDA CC selection to the Cmake-gui, or can we use by default two CCs: CC 3.0 + CC 7.0/7.5 selected based on CUDA-version?


I just can't find where can I set CUDA CC in the Cmake-gui:
image


Can we do it in the same way as it is done in OpenCV?

image

@cenit
Copy link
Collaborator Author

cenit commented May 19, 2019

Sure, I will improve user interface in the next commit :)

@cenit
Copy link
Collaborator Author

cenit commented May 20, 2019

now there's a CUDA_ARCHITECTURES variable with some pre-set values:

  • "Auto" detects local machine GPU compute arch automatically and builds for it
  • "Common" cover common architectures
  • "All" builds for all architectures known by the CUDA SDK found
  • "Names" is a list of architectures to enable by name, an example is given
  • "Numbers" is a list of compute capabilities (version number) to enable (an example 3.0 + 7.5 is given)

@AlexeyAB Please let me know if you like this version more

@AlexeyAB
Copy link
Owner

AlexeyAB commented Jun 4, 2019

@cenit Hi, Thanks for multiple CCs! )

I think we can enable CUDNN_HALF even for CC >= 6.0: https://github.com/AlexeyAB/darknet/pull/2952/files#diff-af3b638bc2a3e6c650974192a53c7291R58


"Auto" detects local machine GPU compute arch automatically and builds for it

Does it detect CC based on GPU-card or on CUDA-version?
What behavior will be if there are several different GPUs?

May be it is better to use minimal CC3.0 + Auto(CC7.5) by default? It will solve issue for multiple different GPUs.

I got for RTX 2070 and CUDA 10.0:

  • Auto: compute_75,sm_75

  • Common: compute_30,sm_30;compute_35,sm_35;compute_50,sm_50;compute_52,sm_52;compute_60,sm_60;compute_61,sm_61;compute_70,sm_70;compute_75,sm_75;compute_70,compute_70;compute_75,compute_75

  • All: compute_20,sm_20;compute_20,sm_21;compute_30,sm_30;compute_35,sm_35;compute_50,sm_50;compute_52,sm_52;compute_32,sm_32;compute_37,sm_37;compute_53,sm_53;compute_60,sm_60;compute_61,sm_61;compute_70,sm_70;compute_75,sm_75

  • Kepler Maxwell Kepler+Tegra Maxwell+Tegra Pascal: compute_30,sm_30;compute_35,sm_35;compute_50,sm_50;compute_52,sm_52;compute_32,sm_32;compute_53,sm_53;compute_60,sm_60;compute_61,sm_61

  • compute_30,sm_30;compute_75,sm_75: compute_30,sm_30;compute_75,sm_75

@cenit
Copy link
Collaborator Author

cenit commented Jun 4, 2019

@AlexeyAB hi! ok for CC>6.0 to enable CUDNN_HALF.

About the CC, it is completely delegated to CMake. In the new frameworks that we are exploiting CMake has this wonderful capability, which is getting better every version more. I'd leave Auto by default, not CC3.0+CC7.5, because that one is just one click away and I see it as a "more expert setting" than a plain automatic selection... but of course changing the default is very easy, just let me know. IMHO it is also less future-proof. Auto will work even in 5 years, 3.0+7.5 it will be "old"... so less mainteinance for you ;)

@AlexeyAB
Copy link
Owner

AlexeyAB commented Jun 4, 2019

Do you mean that if I have Tesla V100 CC6.0 and CUDA 10.0 that supports CC7.5, then CMake will use CC6.0 automatically by using Auto?

@cenit
Copy link
Collaborator Author

cenit commented Jun 5, 2019

Yes. It should, at least...

@AlexeyAB AlexeyAB merged commit 2347913 into AlexeyAB:master Jun 5, 2019
@AlexeyAB
Copy link
Owner

AlexeyAB commented Jun 5, 2019

Thanks for PR, I merged it!
Can you show what line im CmakeList do CC-autodetection?

@cenit
Copy link
Collaborator Author

cenit commented Jun 5, 2019

Hi!
Sure, it's this one:

cuda_select_nvcc_arch_flags(CUDA_ARCH_FLAGS ${CUDA_ARCHITECTURES})

you give it a parameter (CUDA_ARCHITECTURES) which is created as a drop-down list with some options but can always overridden by user and it returns a variable (CUDA_ARCH_FLAGS) which contains the list of the options to pass to the compilers to have all the CCs requested

@cenit cenit deleted the dev/cenit/include branch June 5, 2019 15:22
TomHeaven pushed a commit to TomHeaven/darknet that referenced this pull request Aug 13, 2020
 [headers] remove many installed files which should remain private, add more fixes for downstream projects
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants