Попытка вызвать функцию устройства из глобальной функции другого файлаC++

Программы на C++. Форум разработчиков
Ответить
Anonymous
 Попытка вызвать функцию устройства из глобальной функции другого файла

Сообщение Anonymous »

Я пытался создать небольшой проект с использованием CMake и CUDA, будучи новичком в программировании на графическом процессоре (а также вроде CMake), и столкнулся с проблемой, поэтому хочу знать, как сделать следующее:< /p>
Хорошо, допустим, у меня есть два отдельных файла (каждый из них на самом деле представляет собой файл .cuh и .cu, но я просто собираюсь сослаться на им как одному, поскольку они скомпилированы вместе) У меня есть файл A и файл B.
По сути, я хочу этого:
Файл A вызывает __global__, расположенная в отдельном файле, эта глобальная функция затем вызывает функцию __device__ из файла B.
Я хочу иметь возможность скомпилировать файл B как библиотеку так что, если другие файлы по какой-либо причине захотят ссылаться на эту функцию __device__, и я хочу, чтобы файл A скомпилировался как исполняемый файл.
Как мне это сделать? ? Является ли единственным вариантом сохранить их в одном файле?
РЕДАКТИРОВАТЬ:
Я пробовал добавить -dc и -rdc= true, но есть и другие файлы, которые не имеют функций CUDA (нет глобальных функций устройства или хоста), которые компилируются в библиотеки и связываются с файлом A.
EDIT2:< /p>
Я понял, что загрузил ошибку из предыдущего тестирования, но у меня есть небольшая версия того, что я делаю, я старался быть кратким, но вот структура файла

main.cu

main.cuh

CMakeLists.txt

Maths/

AMaths.cu

AMaths.cuh

GMaths.cu

GMaths.cuh

CMakeLists.txt


CMakeLists.txt
cmake_minimum_required (VERSION 3.8)

project (Engine LANGUAGES CUDA CXX)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CUDA_STANDARD 17)
set(CMAKE_CUDA_FLAGS "${CMAKE_CUDA_FLAGS} -rdc=true -lcudadevrt -lcublas_device -dc")

include_directories(Maths)

add_executable(Main Main.cu Main.cuh)

add_subdirectory(Maths)

target_link_libraries(Main
PRIVATE
GMaths
AMaths)

Main.cu
#include "Main.cuh"

__global__ void caller(float* vec1, float* vec2, float* out) {
int i = threadIdx.x + blockDim.x * blockIdx.x;
GMaths::Add(vec1, vec2, out);
}

int main() {
float* vec1;
float* vec2;
float* out;
cudaMalloc(&vec1, sizeof(float) * 3);
cudaMalloc(&vec2, sizeof(float) * 3);
cudaMallocManaged(&out, sizeof(float) * 3);
float* temp = new float[3] {1, 2, 3};
cudaMemcpy(temp, &vec1, sizeof(float) * 3, cudaMemcpyHostToDevice);
cudaMemcpy(temp, &vec2, sizeof(float) * 3, cudaMemcpyHostToDevice);
caller > (vec1, vec2, out);
return 0;
}

Main.cuh
#ifndef MAIN_CUH
#define MAIN_CUH

#include "GMaths.cuh"
#include "AMaths.cuh"

__global__ void caller(float* vec1, float* vec2, float* out);
int main();

#endif

Maths\AMaths.cu
#include "AMaths.cuh"

namespace AMaths {
void VecAdd(float* vec1, float* vec2, int vecsize, float* out) {
for (int i = 0; i < vecsize; i++) {
out = vec1 + vec2;
}
}
float V2Dot(Vector2 v1, Vector2 v2) {
return v1.x * v2.x + v1.y * v2.y;
}
float V3Dot(Vector3 v1, Vector3 v2) {
return v1.x * v2.x + v1.y * v2.y + v1.z *v2.z;
}
Quaternion EulerToQuaternion(Euler angles) {
Quaternion result(std::cos(angles.roll / 2) * std::cos(angles.pitch / 2) * std::cos(angles.yaw / 2) + std::sin(angles.roll / 2) * std::sin(angles.pitch / 2) * std::sin(angles.yaw / 2),
std::sin(angles.roll / 2) * std::cos(angles.pitch / 2) * std::cos(angles.yaw / 2) - std::cos(angles.roll / 2) * std::sin(angles.pitch / 2) * std::sin(angles.yaw / 2),
std::cos(angles.roll / 2) * std::sin(angles.pitch / 2) * std::cos(angles.yaw / 2) + std::sin(angles.roll / 2) * std::cos(angles.pitch / 2) * std::sin(angles.yaw / 2),
std::cos(angles.roll / 2) * std::cos(angles.pitch / 2) * std::sin(angles.yaw / 2) - std::sin(angles.roll / 2) * std::sin(angles.pitch / 2) * std::cos(angles.yaw / 2));
return result;
}
Euler QuaternionToEuler(Quaternion angles) {
float sinr_cosangles = 2 * (angles.w * angles.i + angles.j * angles.k);
float cosr_cosangles = 1 - 2 * (angles.i * angles.i + angles.j * angles.j);

float sinangles = std::sqrt(1 + 2 * (angles.w * angles.j - angles.i * angles.k));
float cosangles = std::sqrt(1 - 2 * (angles.w * angles.j - angles.i * angles.k));

float siny_cosangles = 2 * (angles.w * angles.k + angles.i * angles.j);
float cosy_cosangles = 1 - 2 * (angles.j * angles.j + angles.k * angles.k);

Euler result(std::atan2(siny_cosangles, cosy_cosangles),
2 * std::atan2(sinangles, cosangles) - PI / 2,
std::atan2(sinr_cosangles, cosr_cosangles));
return result;
}
void Vector3ToQuaternion(Vector3 vector, Quaternion &out) {
out.w = 0;
out.i = vector.x;
out.j = vector.y;
out.k = vector.z;
}
void QuaternionToVector3(Quaternion quat, Vector3 &out) {
out.x = quat.i;
out.y = quat.j;
out.z = quat.k;
}
void QuaternionMultiplication(Quaternion Q1, Quaternion Q2, Quaternion &out) {
out.w = Q1.w * Q2.w - Q1.i * Q2.i - Q1.j * Q2.j - Q1.k * Q2.k;
out.i = Q1.w * Q2.i + Q1.i * Q2.w + Q1.j * Q2.k - Q1.k * Q2.j;
out.j = Q1.w * Q2.j - Q1.i * Q2.k + Q1.j * Q2.w + Q1.k * Q2.i;
out.k = Q1.w * Q2.k + Q1.i * Q2.j - Q1.j * Q2.i + Q1.k * Q2.w;
}
void InverseQuaternion(Quaternion Q, Quaternion &out) {
out.w = Q.w;
out.i = -Q.i;
out.j = -Q.w;
out.k = -Q.k;
}
void QuaternionToRotationMatrix(Quaternion Q, RotationMatrix &out) {
float v01 = Q.w * Q.i;
float v02 = Q.w * Q.j;
float v03 = Q.w * Q.k;
float v12 = Q.i * Q.j;
float v13 = Q.i * Q.k;
float v23 = Q.j * Q.k;
float q02 = Q.w * Q.w;
out.x1 = 2 * (q02 + Q.i * Q.i) - 1;
out.y2 = 2 * (q02 + Q.j * Q.j) - 1;
out.z3 = 2 * (q02 + Q.k * Q.k) - 1;
out.y1 = 2 * (v12 - v03);
out.z1 = 2 * (v13 + v02);
out.x2 = 2 * (v12 + v03);
out.z2 = 2 * (v23 - v01);
out.x3 = 2 * (v13 - v02);
out.y3 = 2 * (v23 + v01);
}
}

Maths\AMaths.cuh
#ifndef AMATHS_H
#define AMATHS_H
#include
#include

namespace AMaths {
#define PI 3.14159265359
}

namespace Literals {
constexpr long double operator"" _mm(long double x) { return x / 1000; };
constexpr long double operator"" _cm(long double x) { return x / 100; };
constexpr long double operator"" _m(long double x) { return x; };
constexpr long double operator"" _deg(long double x) { return x * (PI / 180); };
constexpr long double operator"" _rad(long double x) { return x; };
}

namespace AMaths {
#define HALFPI 1.57079632679
#define QUATERPI 0.785398163397
#define ONEOVERPI 0.318309886184
#define A 0.0776509570923569
#define B -0.287434475393028
#define C (QUATERPI - A - B)
#define S1 0.166666666667
#define S2 0.00833333333333
#define S3 0.000198412698413
struct Vector2 {
float x, y;
};
struct Vector3 {
float x, y, z;
Vector3() {
this->x = 0;
this->y = 0;
this->z = 0;
}
Vector3(float x, float y, float z) {
this->x = x;
this->y = y;
this->z = z;
}
};
struct Euler {
float yaw, pitch, roll;
Euler() {
this->yaw = 0;
this->pitch = 0;
this->roll = 0;
}
Euler(float yaw, float pitch, float roll) {
this->yaw = yaw;
this->pitch = pitch;
this->roll = roll;
}
};
struct Quaternion {
float w, i, j, k;
Quaternion() {
this->w = 0;
this->i = 0;
this->j = 0;
this->k = 0;
}
Quaternion(float w, float i, float j, float k) {
this->w = w;
this->i = i;
this->j = j;
this->k = k;
}
};
struct RotationMatrix {
float x1, y1, z1;
float x2, y2, z2;
float x3, y3, z3;
};
void VecAdd(float* vec1, float* vec2, int vecsize, float* out);
float V2Dot(Vector2 v1, Vector2 v2);
float V3Dot(Vector3 v1, Vector3 v2);
Quaternion EulerToQuaternion(Euler);
Euler QuaternionToEuler(Quaternion);
void Vector3ToQuaternion(Vector3 vector, Quaternion &out);
void QuaternionToVector3(Quaternion quat, Vector3 &out);
void QuaternionMultiplication(Quaternion Q1, Quaternion Q2, Quaternion &out);
void InverseQuaternion(Quaternion Q, Quaternion &out);
void QuaternionToRotationMatrix(Quaternion Q, RotationMatrix &out);
}
#endif

Maths\GMaths.cu
#include "GMaths.cuh"
namespace GMaths {
__device__ void Add(float val1, float val2, float &out) {
out = val1 + val2;
}

__global__ void VecAdd(float* vec1, float* vec2, float* out) {
int i = threadIdx.x + blockDim.x * blockIdx.x;
out = vec1 + vec2;
}
__global__ void MatMulVec4(float* matrix[16], float* vector[4], float* out[4]) {
int temp = threadIdx.x + blockDim.x * blockIdx.x;
int i = temp % 4;
int s = (int)(temp / (4));
out = matrix[i] * vector[0] + matrix[i+4] * vector[1] + matrix[i+8] * vector[2] + matrix[i+12] * vector[3];
}
}

Maths\GMaths.cuh
#ifndef GMATHS_CUH
#define GMATHS_CUH
namespace GMaths {
__device__ void Add(float val1, float val2, float &out);
__global__ void VecAdd(float* vec1, float* vec2, float* out);
__global__ void MatMulVec4(float* matrix[16], float* vector[4], float* out[4]);
}
#endif

Maths\CMakeLists.txt
add_library(AMaths AMaths.cuh AMaths.cu)
add_library(GMaths GMaths.cuh GMaths.cu)
target_compile_features(AMaths PUBLIC cxx_std_11)
target_compile_features(GMaths PUBLIC cxx_std_11)
set_target_properties(AMaths PROPERTIES CUDA_SEPARABLE_COMPILATION ON)
set_target_properties(GMaths PROPERTIES CUDA_SEPARABLE_COMPILATION ON)


Подробнее здесь: https://stackoverflow.com/questions/784 ... l-function
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C++»