Skip to content

Conversation

@QiJune
Copy link
Member

@QiJune QiJune commented Jul 4, 2017

Paddle can dynamic load cudnn, curand and cublas libraries. This pr is just copy the implementation from paddle/util and paddle/cuda directories to paddle/platform directory.

@QiJune QiJune requested a review from gangliao July 4, 2017 03:06
#include <cublas_v2.h>
#include "paddle/platform/dynamic_loader.h"

namespace paddle {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

- paddle
-- platform
--- dyload

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

See the License for the specific language governing permissions and
limitations under the License. */

#ifndef DYNAMIC_LOAD_H_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#pragma once

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

#ifndef DYNAMIC_LOAD_H_
#define DYNAMIC_LOAD_H_

#include <dlfcn.h>
Copy link
Contributor

@gangliao gangliao Jul 4, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move headerfiles into .cc
remove unnecessary header files

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@gangliao
Copy link
Contributor

gangliao commented Jul 4, 2017

It's better to use dynload.

Shall we need to mkdir platform/dynload and dump all of them into that folder

@QiJune
Copy link
Member Author

QiJune commented Jul 4, 2017

@gangliao Sounds reasonable! Since dynload is an independent namespace, it's better to move them into padde/platform/dyload directory

Copy link
Contributor

@gangliao gangliao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@QiJune QiJune merged commit 6fd41f7 into PaddlePaddle:develop Jul 4, 2017

int GetCurrentDeviceId(void) {
int device_id;
throw_on_error(cudaGetDevice(&device_id), "cudaGetDevice failed");
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we only use PADDLE_ENFORCE and not throw thrust::system_error?

But it seems that we need to move enforce to platform if we want to use PADDLE_ENFORCE in platform

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#define PADDLE_ENFORCE(condition, ...) \
  do {                                 \
    if (UNLIKELY(!(condition))) {      \
      PADDLE_THROW(__VA_ARGS__);       \
    }                                  \
  } while (0)

UNLIKELY can not handle the following situation since different libs have a different return struct.

#pragma once

#include <sstream>
#include <stdexcept>
#include <string>

#ifndef PADDLE_ONLY_CPU

#include <cublas_v2.h>
#include <cudnn.h>
#include <curand.h>
#include <thrust/system/cuda/error.h>
#include <thrust/system_error.h>

#endif  // PADDLE_ONLY_CPU

namespace paddle {
namespace platform {

#ifndef PADDLE_ONLY_CPU

inline void throw_on_error(cudaError_t e, const char* message) {
  if (e) {
    throw thrust::system_error(e, thrust::cuda_category(), message);
  }
}

inline void throw_on_error(curandStatus_t stat, const char* message) {
  if (stat != CURAND_STATUS_SUCCESS) {
    throw thrust::system_error(cudaErrorLaunchFailure, thrust::cuda_category(),
                               message);
  }
}

inline void throw_on_error(cudnnStatus_t stat, const char* message) {
  std::stringstream ss;
  if (stat == CUDNN_STATUS_SUCCESS) {
    return;
  } else {
    ss << cudnnGetErrorString(stat);
    ss << ", " << message;
    throw std::runtime_error(ss.str());
  }
}

inline void throw_on_error(cublasStatus_t stat, const char* message) {
  std::stringstream ss;
  if (stat == CUBLAS_STATUS_SUCCESS) {
    return;
  } else if (stat == CUBLAS_STATUS_NOT_INITIALIZED) {
    ss << "CUBLAS: not initialized";
  } else if (stat == CUBLAS_STATUS_ALLOC_FAILED) {
    ss << "CUBLAS: alloc failed";
  } else if (stat == CUBLAS_STATUS_INVALID_VALUE) {
    ss << "CUBLAS: invalid value";
  } else if (stat == CUBLAS_STATUS_ARCH_MISMATCH) {
    ss << "CUBLAS: arch mismatch";
  } else if (stat == CUBLAS_STATUS_MAPPING_ERROR) {
    ss << "CUBLAS: mapping error";
  } else if (stat == CUBLAS_STATUS_EXECUTION_FAILED) {
    ss << "CUBLAS: execution failed";
  } else if (stat == CUBLAS_STATUS_INTERNAL_ERROR) {
    ss << "CUBLAS: internal error";
  } else if (stat == CUBLAS_STATUS_NOT_SUPPORTED) {
    ss << "CUBLAS: not supported";
  } else if (stat == CUBLAS_STATUS_LICENSE_ERROR) {
    ss << "CUBLAS: license error";
  }
  ss << ", " << message;
  throw std::runtime_error(ss.str());
}

inline void throw_on_error(cublasStatus_t stat) {
  const char* message = "";
  throw_on_error(stat, message);
}

#endif  // PADDLE_ONLY_CPU

inline void throw_on_error(int stat, const char* message) {
  if (stat) {
    throw std::runtime_error(message + (", stat = " + std::to_string(stat)));
  }
}

}  // namespace platform
}  // namespace paddle

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.

3 participants