CUDA,不能为数组指定新的初始值设定项
CUDA, a new initializer may not be specified for an array
所以我目前有这段代码,但在编译时遇到了一个错误,即"可能没有为数组指定新的初始值设定项",但我在代码中没有声明新数组的位置。所以我不确定这个问题是在哪里以及如何发生的。这是我认为问题所在的代码部分…
struct indvPasswords
{
int blockId;
int threadId;
list<char[1024]> passwords;
};
//22,500 individual blocks
int gridSize = 150;
//1024 threads contained within each block
int blockSize = 32;
int totalNumThreads = (gridSize*gridSize)*(blockSize*blockSize);
indvPasswords* pointerToPass = new indvPasswords[totalNumThreads];
这是所有的源代码。它目前使用cuda查找字典密码。。。
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <iostream>
#include <fstream>
#include <string>
#include <list>
using namespace std;
//////////////////////////////
// Constants //
//////////////////////////////
string password = "C:\Users\james\Desktop\password.txt";
string passwordListFile = "C:\Users\james\Desktop\10millionpasswordlist.txt";
struct indvPasswords
{
int blockId;
int threadId;
list<char[1024]> passwords;
};
//22,500 individual blocks
int gridSize = 150;
//1024 threads contained within each block
int blockSize = 32;
int totalNumThreads = (gridSize*gridSize)*(blockSize*blockSize);
indvPasswords* pointerToPass = new indvPasswords[totalNumThreads];
//Some serial setup first
string passwordFile()
{
string pwd = "";
ifstream fileStream(password);
if (fileStream.is_open()) {
getline(fileStream, pwd);
if (pwd != "") {
//Found a password
fileStream.close();
}
else {
cout << "No password found in file" << 'n';
}
}
else {
cout << "Cannot open password file" << 'n';
}
return pwd;
}
list<string> readPasswordList()
{
//open password list
string line = "";
ifstream fileStream(passwordListFile);
list<string> passwordList;
if (fileStream.is_open()) {
while (getline(fileStream, line)) {
passwordList.push_back(line);
}
}
else {
cout << "Cannot open password file" << 'n';
}
return passwordList;
}
void indexing()
{
list<string> passwords = readPasswordList();
int sizeOfList = passwords.size();
int modulus = sizeOfList%gridSize;
int runFlag = 0;
if (modulus != 0) {
//not evenly divided, pass overflow to first block
//Take the modulus off the size of password list, i.e.
//take a number of passwords from the top of the list.
//Temporarily store the passwords removed and give them
//as additional work to the first block.
list<string> temp;
for (int i = 0; i < modulus; i++) {
temp.push_back(passwords.front());
passwords.pop_front();
}
//Now evenly divide up the passwords amoungst the blocks
int numEach = passwords.size();
//The first for loop, iterates through each BLOCK within the GRID
for (int i = 0; i < (gridSize*gridSize); i++) {
//Set flag, for single run of first block list
if (i == 0) {
runFlag = 1;
}
//The second loop, iterates through each THREAD within the current BLOCK
for (int j = 0; j < (blockSize*blockSize); j++){
//setup the indexes
pointerToPass[i].blockId = i;
pointerToPass[i].threadId = j;
//The third loop, copies over a collection of passwords for each THREAD
//within the current BLOCK
for (int l = 0; l < numEach; l++) {
//Add the temporary passwords to the first block
if (runFlag == 1) {
for (int x = 0; x < temp.size(); x++){
//Convert
string tmp = temp.front();
char charTmp[1024];
strcpy(charTmp, tmp.c_str());
pointerToPass[i].passwords.push_back(charTmp);
temp.pop_front();
}
//Now never block run again
runFlag = 0;
}
//convert the passwords from string to char[] before adding
string tmp = passwords.front();
char charTmp[1024];
strcpy(charTmp, tmp.c_str());
pointerToPass[i].passwords.push_back(charTmp);
//now delete the item from passwords that has just been transfered
//over to the other list
passwords.pop_front();
}
}
}
}
else {
//Start to transfer passwords
//First calculate how many passwords each thread will be given to check
int numEach = sizeOfList / totalNumThreads;
//The first for loop, iterates through each BLOCK within the GRID
for (int i = 0; i < (gridSize*gridSize); i++) {
//The second loop, iterates through each THREAD within the current BLOCK
for (int j = 0; j < (blockSize*blockSize); j++){
//setup the indexes
pointerToPass[i].blockId = i;
pointerToPass[i].threadId = j;
//The third loop, copies over a collection of passwords for each THREAD
//within the current BLOCK
for (int l = 0; l < numEach; l++) {
//convert the passwords from string to char[] before adding
string tmp = passwords.front();
char charTmp[1024];
strcpy(charTmp, tmp.c_str());
pointerToPass[i].passwords.push_back(charTmp);
//now delete the item from passwords that has just been transfered
//over to the other list
passwords.pop_front();
}
}
}
}
}
//Now onto the parallel
__device__ bool comparison(indvPasswords *collection, char *password, int *totalThreads)
{
//return value
bool val = false;
//first calculate the block ID
int currentBlockId = blockIdx.y * gridDim.x + blockIdx.x;
//calculate the thread ID
int currentThreadId = currentBlockId * blockDim.y * blockDim.x + threadIdx.y * blockDim.x + threadIdx.x;
//Now go and find the data required for this thread
//Get the block
for (int i = 0; i < (int)totalThreads; i++) {
if (collection[i].blockId == currentBlockId) {
//Now check the thread id
if (collection[i].threadId == currentThreadId) {
//Now begin comparison
for (int j = 0; j < collection[i].passwords.size(); j++)
{
if (password == collection[i].passwords.front()) {
//password found!
val = true;
break;
}
//delete the recently compared password
collection[i].passwords.pop_front();
}
}
}
}
return val;
}
__global__ void kernelComp(indvPasswords *collection, char *password, int *totalThreads)
{
comparison(collection, password, totalThreads);
}
int main()
{
int size = totalNumThreads;
//grid and block sizes
dim3 gridDim(gridSize, gridSize, 1);
dim3 blockDim(blockSize, blockSize, 1);
//Get the password
string tmp = passwordFile();
//convert
char pwd[1024];
strcpy(pwd, tmp.c_str());
indexing();
//device memory pointers
indvPasswords* array_d;
char *pwd_d;
int *threadSize_d;
int *threads = &totalNumThreads;
//allocate host memory
pwd_d = (char*)malloc(1024);
//allocate memory
cudaMalloc((void**)&array_d, size);
cudaMalloc((void**)&pwd_d, 1024);
cudaMalloc((void**)&threadSize_d, sizeof(int));
//copy the data to the device
cudaMemcpy(array_d, pointerToPass, size, cudaMemcpyHostToDevice);
cudaMemcpy(pwd_d, pwd, 1024, cudaMemcpyHostToDevice);
cudaMemcpy(threadSize_d, threads, sizeof(int), cudaMemcpyHostToDevice);
//call the kernel
kernelComp << <gridDim, blockDim>> >(array_d,pwd_d,threadSize_d);
//copy results over
return 0;
}
-
当我使用
nvcc
的-std=c+=11
编译器开关在linux上编译您的代码时,我会收到以下警告:for (int i = 0; i < (int)totalThreads; i++) {
在您的
comparison
函数中。假定totalThreads
是传递给函数的指针:__device__ bool comparison(indvPasswords *collection, char *password, int *totalThreads)
几乎可以肯定,这种用法已经被打破了。我很确定这个警告不应该被忽视,你真正想要的是:
for (int i = 0; i < *totalThreads; i++) {
-
我得到的唯一错误是在这条线上:
pointerToPass[i].passwords.push_back(charTmp);
但这似乎并不是你报告的错误:
$ nvcc -std=c++11 -o t1016 t1016.cu /usr/include/c++/4.8.3/bits/stl_list.h(114): error: a value of type "const char *" cannot be used to initialize an entity of type "char [1024]" detected during: instantiation of "std::_List_node<_Tp>::_List_node(_Args &&...) [with _Tp=char [1024], _Args=<const std::list<char [1024], std::allocator<char [1024]>>::value_type &>]" /usr/include/c++/4.8.3/ext/new_allocator.h(120): here instantiation of "void __gnu_cxx::new_allocator<_Tp>::construct(_Up *, _Args &&...) [with _Tp=std::_List_node<char [1024]>, _Up=std::_List_node<char [1024]>, _Args=<const std::list<char [1024], std::allocator<char [1024]>>::value_type &>]" (506): here instantiation of "std::list<_Tp, _Alloc>::_Node *std::list<_Tp, _Alloc>::_M_create_node(_Args &&...) [with _Tp=char [1024], _Alloc=std::allocator<char [1024]>, _Args=<const std::list<char [1024], std::allocator<char [1024]>>::value_type &>]" (1561): here instantiation of "void std::list<_Tp, _Alloc>::_M_insert(std::list<_Tp, _Alloc>::iterator, _Args &&...) [with _Tp=char [1024], _Alloc=std::allocator<char [1024]>, _Args=<const std::list<char [1024], std::allocator<char [1024]>>::value_type &>]" (1016): here instantiation of "void std::list<_Tp, _Alloc>::push_back(const std::list<_Tp, _Alloc>::value_type &) [with _Tp=char [1024], _Alloc=std::allocator<char [1024]>]" t1016.cu(108): here 1 error detected in the compilation of "/tmp/tmpxft_0000182c_00000000-8_t1016.cpp1.ii".
这个问题的解决方案可能是不使用数组作为列表元素类型,正如@ManosNikolaidis已经建议的那样。
-
然而,我在您的代码中看到的一个更大的问题是,您试图在
__device__
函数中使用c++标准库中的项,但这不起作用:struct indvPasswords { int blockId; int threadId; list<char[1024]> passwords; // using std::list }; ... __global__ void kernelComp(indvPasswords *collection, char *password, int *totalThreads) ^^^^^^^^^^^^^ // can't use std::list in device code
您应该重写设备使用的数据结构,使其仅依赖于内置类型或从这些内置类型派生的类型。
这一行有一个问题:
list<char[1024]> passwords;
数组不能在STL容器中使用,因为它要求类型是可复制构造的和可赋值的。更多详细信息请点击此处。尝试对每个密码使用std::string
。甚至是array<char, 1024>
。
您实际上是在使用new
在这里创建一个数组
indvPasswords* pointerToPass = new indvPasswords[totalNumThreads];
但我认为没有任何问题
相关文章:
- 如何计算数组中元素的位数?(不是数组的长度),并计算其数字的总和
- 如何使用C++初始化向量;脚本化值不是数组、指针或矢量错误
- 如何对不在数组中的变量进行排序?
- 从用户那里获得无限量的输入,而不是打印最大的3个,而不使用数组
- (C++)我的函数不返回数组
- 用c++排序,不带数组
- Sizeof返回的是指针大小,而不是数组大小.有其他方法可以找到尺寸吗
- 在 c++ 中比较不相等数组或字符串的方法
- 为什么会出现一些垃圾而不是数组值?
- 是否可以在不使用数组的情况下将不同数量的相同类型的参数传递给函数?
- 使用指针交换而不引用数组C++
- 使用 auto 时不检查数组边界
- 我想返回数组索引,而不是数组值
- 我不明白数组名称是如何指向数组的指针
- 如何将值分配给递增变量(如数组),但不使用数组
- 我试图释放数据的某些部分,并用特定的整数值标记其休息,以表明它不是有效的指针.(不是数组)
- 当循环崩溃时,不向数组添加单词
- C++用户定义的不使用数组的序列整数
- C++如果我不知道数组大小并且需要接收数组怎么办
- Subscripted Value不是数组