[Risolto][OpenCL] Array dinamici nel Kernel

Linguaggi di programmazione: php, perl, python, C, bash e tutti gli altri.
Scrivi risposta
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

[Risolto][OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

Ciao a tutti,
per un progetto universitario sto lavorando con OpenCL e, per iniziare, sto facendo un po' di test per verificare quante cose effettivamente si possano fare. Nel fare questi test mi sono imbattuto in un problema abbastanza grande, il non poter passare array di puntatori al kernel. Ho pensato quindi di passare come parametro un array di strutture, ognuna delle quali contiene un array di caratteri ed un intero che ne determina la lunghezza effettiva. Mi trovo però nella situazione di dover lavorare sulle "stringhe" effettive, quindi creare internamente al kernel un array di caratteri che copra soltanto i primi n caratteri dell'array (dove n è la lunghezza). Però a quanto pare OpenCL vuole che la dimensione del nuovo array sia costante. Per cercare di essere più chiaro vi scrivo il breve codice :

Kernel:

Codice: Seleziona tutto

typedef struct word{
	char word[100];
	int len;
}word_t;
__kernel void prova(__global word_t *data,  __global res_t *result)
{
	size_t id=get_global_id(0);
	int size=0;
	int i=0;
	size=data[id].len;
   char word[size];
   //lavoro con la word che ho costruito

}
Ovviamente la dimensione 100 è una esagerazione per tenere conto di eventuali lunghissime parole (estremamente improbabili). Purtroppo però le varie parole con cui dovrei lavorare le prendo da un file, e sono potenzialmente tutte di dimensioni diverse, dunque non posso calibrare pienamente l'array per contenere una certa lunghezza esatta.
La mia domanda è : c'è un metodo che finora non ho trovato per ovviare a questo problema? Oppure, in alternativa, avete qualche suggerimento alternativo su come passare eventualmente un lungo array di char e poi splittarlo?
Spero di essere stato sufficientemente chiaro, se poi dovessi aver tralasciato qualche informazione chiedete pure.
Grazie :)
Ultima modifica di John_Marco il martedì 28 ottobre 2014, 9:42, modificato 1 volta in totale.
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

Scusate, mi permetto un UP sperando che qualcuno sappia aiutarmi! :)
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da SuperStep »

ciao, premetto che non lavoro con il kernel,

puo' essere che hai sbagliato a passare la struttura ?

magari dovresti provare a passare un puntatore di puntatori alla funzione,

lo crei dinamicamente di dimensione pari al numero di righe +1, nell'ultima riga metti il valore NULL, e continui ad esaminare le righe fino a NULL.

se il problema invece risiede nel fatto che i puntatori creati dinamicamente (nella swap) non sono visibili in __kernel,

puoi provare a passare il nome del file alla funzione, ed aprire il file direttamente da li con open.
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

Ciao, ti ringrazio per la risposta. Per quanto riguarda il kernel OpenCl non gli piace nulla che sia puntatore di puntatore. Puoi passargli solamente array di quello che vuoi (anche struct, appunto, ma che non contengano puntatori) già dimensionati. Il passare il nome del file e quindi tentare di elaborare i dati internamente al kernel potrebbe funzionare (dovrei provare perchè in realtà comunque ci sarebbero problemi sulla dimensione variabile di quello che carico), ma non so fino a che punto convenga visto che implicherebbe una sequenza di operazioni sequenziali (perdona il gioco di parole) che andrebbero a rallentare l'obiettivo generale di tutto, ovvero lo sfruttare il parallelismo della GPU :)
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da SuperStep »

e se provassi a creare un file per la stringa?

mi spiego meglio:

1) Apri due file, uno della sorgente, l'altro dove scrivi la stringa

2) Leggi la prima stringa dal file, sul secondo file ti sposti a SEEK_START?(come era l'inizio?) e scrivi la stringa letta con \0 alla fine

3) sposti il seek del secondo file di nuovo all'inizio

4) passi il fd alla funzione che legge fino a \0

5) restituisci il valore voluto

tutto questo mentre non finisci di leggere il file.

La lettura su file e' estremamente piu' lenta di quella di memoria...
in questo modo pero' eviti di dover apire e chiudere il file ogni volta.

I Buffer esistono proprio per velocizzare queste operazioni, ma le loro grandezze sono definite staticamente.

Quindi la mia risposta non e' velocissima, pero' ti permette di passare una stringa di dimensione variabile senza dover aprire e chiudere file ogni volta, ma solo di leggere e scrivere su file.
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

Potrebbe essere una soluzione, ma anche in questo caso non sfrutterei il parallelismo. L'idea era quella di passare, ad esempio, 10 parole e avere 10 processi paralleli che ci lavorano su. In questo modo lavorerebbe un solo processo per volta e potrebbe essere terribilmente inefficiente avendo file con migliaia di parole..
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da SuperStep »

allora devi per forza creare buffer di dimensione statica, e passare il riferimento a questi buffer, non vedo altra soluzione.

p.s. dichiarerei i buffer piu' grandi di 100, almeno il triplo. (300 * 4 byte (char) sono 0,0012 megabyte). (che memorie hai a disposizione?).

non mi preoccuperei a questo punto dell'uso di memoria.
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

In realtà non è tanto la memoria che mi preoccupa, quanto il fatto che i caratteri non utilizzati nella parola vengono comunque computati. Per ora ho deciso di lasciar perdere questo punto e focalizzarmi su un aspetto più semplice da questo punto di vista, ovvero il bruteforce. Sarà computazionalmente più complicato ma almeno posso gestire staticamente le dimensioni delle varie parole :)
Avatar utente
SuperStep
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 2037
Iscrizione: lunedì 19 dicembre 2011, 16:26
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS x86_64
Sesso: Maschile
Località: Somma Vesuviana (NA)

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da SuperStep »

Basta aggiungere il tappo a fine stringa /0 e scrivere l'algoritmo in modo che legga fino a tappo. Esistono delle funzioni apposta in string.h, mi pare sia strcpy... Non mi ricordo, non ho il PC sotto mano, scrivo dal tablet, ma sono sicuro che ci sono.
ubuntu 16.04 LTS 64-bit - Memoria: 31,3 Gib - Processore: Intel Core i7-5960X CPU @ 3.00 GHz × 16 - Grafica: AMD Radeon HD 7800 Series - Disco: SSD 256 GB x 4 (RAID 01)
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

Credo di aver già tentato le funzioni di string.h senza successo, ma riproverò! Grazie per gli spunti, appena avrò modo di lavorarci su vedrò di ottenere qualche risultato :)
Avatar utente
erPicci
Prode Principiante
Messaggi: 156
Iscrizione: martedì 26 aprile 2011, 12:07

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da erPicci »

Premetto che ho lavorato molto di più con CUDA che non con OpenCL, ma il ragionamento dovrebbe essere analogo:
non poter passare array di puntatori al kernel
Non è un "problema", piuttosto un'architettura diversa. Assumi per assurdo di poter passare un vettore di puntatori ad un kernel su una GPU...
Il vettore viene copiato sulla memoria della GPU. Innanzitutto... la copia è una shallow copy o una deep copy? Già il fatto di non avere determinismo nella scelta dell'implementazione è indice che qualcosa non va...
Nel caso in cui sia una shallow copy, il vettore viene copiato così com'è, con all'interno i puntatori alla memoria dello host. Quindi ogni volta che un worker item vuole deferenziare l'i-esimo elemento del vettore cosa accade? Deve inviare una richiesta al gestore della memoria dello host? Anche sperando in un minimo di coalescenza, le transazioni di memoria diventano troppe e "frammentate". È *quasi* come cercare di passare un puntatore tramite socket (<== nota: paragone molto informale!!!)
L'alternativa è la deep copy, che copia ricorsivamente ogni puntatore che incontra... naturalmente nel caso in cui la struttura passata sia circolare, la deep copy non termina, per questo in genere non viene usata.
Il passare il nome del file e quindi tentare di elaborare i dati internamente [...] non so fino a che punto convenga visto che implicherebbe una sequenza di operazioni sequenziali (perdona il gioco di parole) che andrebbero a rallentare l'obiettivo generale di tutto, ovvero lo sfruttare il parallelismo della GPU
Esatto, senza contare che non hai un bus diretto tra GPU e disco, quindi tutto dovrebbe passare per la CPU. A questo punto conviere far leggere il file alla CPU e convertirlo in una struttura più adatta alla GPU. Strategia comunemente seguita nella programmazione su GPU.
non è tanto la memoria che mi preoccupa, quanto il fatto che i caratteri non utilizzati nella parola vengono comunque computati
È normale quando programmi su GPU: molto più efficiente calcolare un dato e scartarlo, piuttosto che discriminare tra cosa calcolare e cosa no (introducendo divergenza). In alcuni casi limite si riesce a fare questa discriminazione senza introdurre divergenza, ma dipende molto da cosa devi fare.
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

Ciao e grazie per la risposta :) Ti spiego brevemente quel che dovrei fare, anche se purtroppo guardando in giro e vedendo anche le risposte che ho ricevuto da altre parti mi sa che non ci sia una soluzione immediata. Per un progettino all'università devo realizzare una sorta di password cracker che sfrutti la GPU. Dovrei almeno implementare le due modalità più semplici e diffuse, ovvero il brute-force ed il dizionario. Quello che tentavo di fare è appunto il dizionario. Ho implementato un MD5 che verrà richiamato dal Kernel e avevo pensato di far lavorare ogni work unit su X parole del dizionario (ipotizzando un solo hash MD5 da trovare). Il problema è che passando un array di caratteri a dimensione fissa l'algoritmo considera anche tutti i caratteri in eccesso (nonostante io abbia tentato di aggiungere alla fine il terminatore, ed anche di riempire tutto lo spazio in eccesso con terminatori). E' qui che nasce il problema per cui ho aperto il topic.
Avatar utente
erPicci
Prode Principiante
Messaggi: 156
Iscrizione: martedì 26 aprile 2011, 12:07

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da erPicci »

Quindi, se ho capito bene, hai un file contentente parole (il dizionario) e una stringa hash, e vuoi capire quale parola del dizionario produce quella stringa?

Hai qualche informazione "statistica" sulle lunghezze delle parole su cui lavori? Se la lunghezza massima non è eccessiva e la varianza è poca, puoi usare una matrice vettorizzata in cui ogni riga contiene una parola e la cui leading dimension è la lunghezza massima. La bassa varianza ti assicura di avere poco spreco di memoria.
esempio:

Codice: Seleziona tutto

dizionario = {
  'p' 'a' 'r' 'o' 'l' 'a' '1' '\0' '\0' '\0'
  'p' 'a' 'r' 'o' 'l' 'a' '2' '2'   '2'  '2'
  'p' 'a' 'r' 'o' 'l' 'a' '3' '3'   '\0' '\0'
}
Ogni work unit lavora su una riga della matrice vettorizzata, ovvero su una parola. Il work unit i-esimo sa che troverà la sua parola tra dizionario + (i * leading_dim) e dizionario * ((i+1) * leading_dim) - 1. In questo modo non hai necessità di controllare la presenza del terminatore di stringa (che potrebbe anche non esserci, se preferisci).
Naturalmente il tuo algoritmo di hash deve trattare allo stesso modo "parola\0" e "parola\0\0\0"...
Se la lunghezza massima è troppa o la varianza è alta funziona lo stesso, ma con un po' di spreco di memoria.

Nella scelta della leading dimension potresti ottenere delle performance migliori se questa è multipla di 16 o 32... per questioni legate a coalescenza e allineamento in memoria. Ma di questo non sono per nulla sicuro, quindi prendilo un po' con le pinze. In ogni caso sarebbe solo un discorso di ottimizzazione.
John_Marco
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 311
Iscrizione: martedì 5 maggio 2009, 19:55
Desktop: Unity
Distribuzione: Ubuntu 16.04 LTS X86_64
Sesso: Maschile
Località: Potenza - Roma

Re: [OpenCL] Array dinamici nel Kernel

Messaggio da John_Marco »

Scusa il ritardo. Grazie della risposta, mi ha dato interessanti spunti per lavorare. Faccio un po' di prove :) Grazie ancora
Scrivi risposta

Ritorna a “Programmazione”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 5 ospiti