所以我目前有这个代码,但是我在编译时遇到错误,“可能没有为数组指定新的初始化程序”,但在我的代码中没有声明新数组。所以我不确定这个问题发生在哪里以及如何发生。这是我觉得问题的代码部分....
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;
}
答案 0 :(得分:1)
这一行存在问题:
list<char[1024]> passwords;
数组不能在STL容器中使用,因为它要求类型是可复制构造和可分配的。更多细节here。尝试为每个密码使用std::string
。甚至是array<char, 1024>
。
您实际上是使用new
在此处创建数组
indvPasswords* pointerToPass = new indvPasswords[totalNumThreads];
但是我没有看到任何错误
答案 1 :(得分:1)
当我使用-std=c+=11
nvcc
编译器开关在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".
该问题的解决方案可能是not use an array as the list element type,正如@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
您应该重新编写设备使用的数据结构,以仅依赖于内置类型或从这些内置类型派生的类型。