CUDA version for 1.25

Aug 8, 2013 at 1:16 PM
Edited Aug 8, 2013 at 3:35 PM
Hi,

Which CUDA version is required for CUDAfy 1.25? I've installed CUDA 5.5 and when trying to compile some code, a "CUDA directory not found" exception is raised. Now I have CUDA 5.0 and 5.5 installed in my machine and, previously, with CUDAfy 1.22 and CUDA 5.0, everything was working just fine.

The environment variables are all set, VC++ bin directory is there in PATH, CUDA_PATH is also ok, but for some reason CUDAfy cannot find the CUDA dir anywhere.

Thanks,
Daniel
Aug 9, 2013 at 3:37 AM
Edited Aug 9, 2013 at 10:05 AM
I've managed to get it working with my previous CUDA 5.0 installation by using CompilerOptions. Didn't get any compilation work done with 5.5, though.
Dim cp As New Cudafy.CompileProperties()
With cp
    .Architecture = eArchitecture.sm_13
    .CompileMode = eCudafyCompileMode.Default
    .Platform = ePlatform.x86
    .WorkingDirectory = My.Computer.FileSystem.SpecialDirectories.Temp
    .CompilerPath = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\bin\nvcc.exe"
    .IncludeDirectoryPath = "C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\include"
End With
Aug 14, 2013 at 12:24 AM
Edited Aug 14, 2013 at 12:25 AM
I'm facing the same problem. cudafy-setup.exe also can not find CUDA.

However, I have uninstalled CUDA 5.0...

what should i do now? uninstall CUDA 5.5 and reinstall CUDA 5.0?
Coordinator
Aug 14, 2013 at 8:19 AM
Edited Aug 14, 2013 at 8:20 AM
CUDAfy searches for the latest CUDA SDK. It does this by finding Program Files or Program Files (x86) when running a 32-bit .NET app on a 64-bit machine. If you are on 64-bit and are compiling for 32-bit app then you will need 32-bit CUDA SDK installed. That's all I can think of at this stage.

You can also try building CUDAfy from source code and looking in TranslationProperties.cs in the Cudafy project. You will see a method called GetCudaVersion.
Aug 14, 2013 at 11:54 AM
Edited Aug 14, 2013 at 12:39 PM
Nick,

That's exactly the problem. I have Windows 7 64-bit and installed CUDA SDK 5.5 64-bit. The 32-bit version cannot be installed on 64-bit OS, That's because the 64-bit version already includes the relevant 32-bit DLLs.

My software is being compiled as 32-bit. The strange thing is that the whole ecosystem was working just fine with CUDAfy 1.22 and CUDA 5.0 64-bit....

Thanks,
Daniel
Aug 14, 2013 at 1:35 PM
NickKopp wrote:
CUDAfy searches for the latest CUDA SDK. It does this by finding Program Files or Program Files (x86) when running a 32-bit .NET app on a 64-bit machine. If you are on 64-bit and are compiling for 32-bit app then you will need 32-bit CUDA SDK installed. That's all I can think of at this stage.

You can also try building CUDAfy from source code and looking in TranslationProperties.cs in the Cudafy project. You will see a method called GetCudaVersion.
well, besides the type of the OS, I installed CUDA 5.5 to a self-defined directory, for example in driver D, because my driver C does not have so much space, and i don't want to install stuffs in it....
Aug 14, 2013 at 1:38 PM
sizheng wrote:
NickKopp wrote:
CUDAfy searches for the latest CUDA SDK. It does this by finding Program Files or Program Files (x86) when running a 32-bit .NET app on a 64-bit machine. If you are on 64-bit and are compiling for 32-bit app then you will need 32-bit CUDA SDK installed. That's all I can think of at this stage.

You can also try building CUDAfy from source code and looking in TranslationProperties.cs in the Cudafy project. You will see a method called GetCudaVersion.
well, besides the type of the OS, I installed CUDA 5.5 to a self-defined directory, for example in driver D, because my driver C does not have so much space, and i don't want to install stuffs in it....
why does not it find CUDA by PATH?
Aug 14, 2013 at 1:52 PM
sizheng wrote:
why does not it find CUDA by PATH?
I have the same question. After installing CUDA 5.5, besides CUDA_PATH which points directly to the most up-to-date CUDA version installed, there are environment variables for every CUDA version, i.e. CUDA_PATH_V4_0, CUDA_PATH_V5_0, CUDA_PATH_V5_5...
Aug 14, 2013 at 2:18 PM
DanWBR wrote:
sizheng wrote:
why does not it find CUDA by PATH?
I have the same question. After installing CUDA 5.5, besides CUDA_PATH which points directly to the most up-to-date CUDA version installed, there are environment variables for every CUDA version, i.e. CUDA_PATH_V4_0, CUDA_PATH_V5_0, CUDA_PATH_V5_5...
yes.

I'm recompling it...
Aug 14, 2013 at 2:24 PM
DanWBR wrote:
sizheng wrote:
why does not it find CUDA by PATH?
I have the same question. After installing CUDA 5.5, besides CUDA_PATH which points directly to the most up-to-date CUDA version installed, there are environment variables for every CUDA version, i.e. CUDA_PATH_V4_0, CUDA_PATH_V5_0, CUDA_PATH_V5_5...
Hi Dan,

have you recompiled it by yourself?

I recompiled it from the source code, but it generates several separate dll files, but not one single cudafy.net.dll like released.

do you know how to do that?
Aug 14, 2013 at 2:29 PM
sizheng wrote:
DanWBR wrote:
sizheng wrote:
why does not it find CUDA by PATH?
I have the same question. After installing CUDA 5.5, besides CUDA_PATH which points directly to the most up-to-date CUDA version installed, there are environment variables for every CUDA version, i.e. CUDA_PATH_V4_0, CUDA_PATH_V5_0, CUDA_PATH_V5_5...
Hi Dan,

have you recompiled it by yourself?

I recompiled it from the source code, but it generates several separate dll files, but not one single cudafy.net.dll like released.

do you know how to do that?
oh, it seems that i should use ILMerge
Aug 14, 2013 at 2:30 PM
sizheng wrote:
Hi Dan,

have you recompiled it by yourself?

I recompiled it from the source code, but it generates several separate dll files, but not one single cudafy.net.dll like released.

do you know how to do that?
Hi sizheng,

I've tried to recompile CUDAfy but it generates lots of separate DLLs, as you saw by yourself. Then I've managed to get CUDAfy 1.25 working with CUDA 5.0 using CompileOptions, as I wrote in my second post.

With CUDA 5.5, the nvcc compiler was giving me an error message about an unsupported Visual Studio version (I have VC++ 2010 Express Edition installed). Probably it is something related to the 32/64-bit thing, but since it worked with 5.0, I just let it "there" because of these annoying incompatiblity problems.

Daniel
Aug 14, 2013 at 2:32 PM
sizheng wrote:
oh, it seems that i should use ILMerge
Exactly.
Aug 14, 2013 at 2:34 PM
DanWBR wrote:
sizheng wrote:
Hi Dan,

have you recompiled it by yourself?

I recompiled it from the source code, but it generates several separate dll files, but not one single cudafy.net.dll like released.

do you know how to do that?
Hi sizheng,

I've tried to recompile CUDAfy but it generates lots of separate DLLs, as you saw by yourself. Then I've managed to get CUDAfy 1.25 working with CUDA 5.0 using CompileOptions, as I wrote in my second post.

With CUDA 5.5, the nvcc compiler was giving me an error message about an unsupported Visual Studio version (I have VC++ 2010 Express Edition installed). Probably it is something related to the 32/64-bit thing, but since it worked with 5.0, I just let it "there" because of these annoying incompatiblity problems.

Daniel
Thanks Dan.

I will try more. If i can't get it work, I will turn to CUDA 5.0 or C++AMP...
Aug 14, 2013 at 3:59 PM
finally, I get it work.

I found a environment variable named as NVSDKCOMPUTE_ROOT, which points to the directory to CUDA, so I let TranslationProperties.cs read it.

but I don't think it's a general sulution, because i'm not sure that environment variable exists for everyone.

in addition, it seems it does not work stably. there would be some errors for the examples, which may say some variable has not been defined in the .cu code. and also, the error may be different for every time.
Coordinator
Aug 15, 2013 at 7:38 AM
Okay, thanks guys for the useful pointers. This is also the reason why open source exists so please stick with it and contribute!
  1. It is true that CUDAfy expects CUDA to be in Program Files. Can you show the code you used for accessing the environment variables?
  2. For merging into Cudafy.NET.dll we use .NET Reactor which is a commercial piece of software. Have not tried using ILMerge. If you try ILMerge please let me know how it works out.
  3. CUDAfy V1.25 uses a new translate/compile model that should be more flexible when using the new Cudafy overloads. It is also possible that it has broken some of the existing Cudafy overloads. @DanWBR - Can you try using CudafyOld(...) and see if this resolves your issues?
  4. @sizheng - what is not stable?
Aug 15, 2013 at 2:04 PM
well, this is the code after I modified in the "if" section of "public static CompileProperties Create":
                // Get ProgramFiles directory and CUDA directories
                // Get architecture
                //string progFiles = null;
                //switch (platform)
                //{
                //    case ePlatform.x64:
                //        progFiles = Utility.ProgramFilesx64();
                //        break;
                //    case ePlatform.x86:
                //        progFiles = Utility.ProgramFilesx86();
                //        break;
                //    default:
                //        progFiles = Utility.CUDA_PATH();
                //        if (platform == ePlatform.Auto)
                //            platform = IntPtr.Size == 4 ? ePlatform.x86 : ePlatform.x64;
                //        break;
                //}
                //string toolkitbasedir = progFiles + Path.DirectorySeparatorChar + csGPUTOOLKIT;
                string toolkitbasedir = Utility.CUDA_PATH();
                Version selVer;
                string cvStr = GetCudaVersion(toolkitbasedir, out selVer);
                if (string.IsNullOrEmpty(cvStr))
                {
                    throw new CudafyCompileException(CudafyCompileException.csCUDA_DIR_NOT_FOUND);
                    //Exception ex = new Exception(toolkitbasedir);
                    //throw ex;
                }
                string gpuToolKit = toolkitbasedir + cvStr;
                tp.CompilerPath = gpuToolKit + Path.DirectorySeparatorChar + @"bin" + Path.DirectorySeparatorChar + csNVCC;
                tp.IncludeDirectoryPath = gpuToolKit + Path.DirectorySeparatorChar + @"include";
                tp.Architecture = (arch == eArchitecture.Unknown) ? eArchitecture.sm_13 : arch;
                bool binary = ((mode & eCudafyCompileMode.Binary) == eCudafyCompileMode.Binary);
                string tempFileName = "CUDAFYSOURCETEMP.tmp";
                string cuFileName = tempFileName.Replace(".tmp", ".cu");
                string outputFileName = tempFileName.Replace(".tmp", binary ? ".cubin" : ".ptx");
                tp.InputFile = cuFileName;
                tp.OutputFile = outputFileName;
                if ((mode & eCudafyCompileMode.DynamicParallelism) == eCudafyCompileMode.DynamicParallelism)
                {
                    tp.AdditionalInputArgs = "cudadevrt.lib  cublas_device.lib  -dlink";                    
                }
and in Utilities.cs, I just added the method "CUDA_PATH()":
        public static string CUDA_PATH()
        {
            return Environment.GetEnvironmentVariable("NVSDKCOMPUTE_ROOT");
        }
the value of NVSDKCOMPUTE_ROOT on my computer is D:\NVIDIA Corporation\NVIDIA GPU Computing Toolkit\CUDA\

in fact, the value of NVSDKCOMPUTE_ROOT was D:\NVIDIA Corporation\NVIDIA GPU Computing Toolkit\CUDA\v5.5\, but I modified it to match the code. Because I'm not sure I have seen it for previous version of CUDA, so I assume that it is not used by other program...

you can see that I even don't check the version of OS, because I just want my program run:)
Aug 15, 2013 at 2:13 PM
NickKopp wrote:
Okay, thanks guys for the useful pointers. This is also the reason why open source exists so please stick with it and contribute!
  1. It is true that CUDAfy expects CUDA to be in Program Files. Can you show the code you used for accessing the environment variables?
  2. For merging into Cudafy.NET.dll we use .NET Reactor which is a commercial piece of software. Have not tried using ILMerge. If you try ILMerge please let me know how it works out.
  3. CUDAfy V1.25 uses a new translate/compile model that should be more flexible when using the new Cudafy overloads. It is also possible that it has broken some of the existing Cudafy overloads. @DanWBR - Can you try using CudafyOld(...) and see if this resolves your issues?
  4. @sizheng - what is not stable?
  1. the code is as posted
  2. I failed to use ILMerge, so I gave up. I just use the separate .dll files.
  3. I've got this error:
    Image
Aug 15, 2013 at 2:16 PM
Hey sizheng,

Can you try using CUDA_PATH instead of NVSDKCOMPUTE_ROOT? It seems that it contains the path to the latest CUDA version installed in your machine.

Nick,

I'll try to compile using CudafyOld(...) tonight and let you know about the result.

Regards,
Daniel
Aug 15, 2013 at 3:22 PM
Edited Aug 15, 2013 at 3:23 PM
yes, i know CUDA_PATH. but it includes the version subdirectory "v5.5".
that conflicts to the code, because the code will test all possible version subdirectory under toolkitbasedir.
That's why I modified NVSDKCOMPUTE_ROOT from D:\NVIDIA Corporation\NVIDIA GPU Computing Toolkit\CUDA\v5.5\ to D:\NVIDIA Corporation\NVIDIA GPU Computing Toolkit\CUDA\ and then use it.
I'm afraid of making some other program unavailable if i modify CUDA_PATH.
Aug 15, 2013 at 10:47 PM
Nick,

If I use CudafyOld like this
CudafyTranslator.CudafyOld(ePlatform.x86, eArchitecture.sm_13, New Version(5, 0), True, ...)
it gets compiled just fine. But if I try to use CUDA 5.5,
CudafyTranslator.CudafyOld(ePlatform.x86, eArchitecture.sm_13, New Version(5, 5), True, ...)
nvcc throws this error:
nvcc : fatal error : nvcc cannot find a supported version of Microsoft Visual Studio. Only the versions 2008, 2010, and 2012 are supported
Why does my VC++ 2010 Express Edition works with v5.0 but not with v5.5? What's the difference?
Coordinator
Aug 16, 2013 at 2:02 PM
Okay we're getting somewhere! This shows the error is more than likely nothing to do with CUDAfy but how nvcc works. I have also in the past managed to use Express edition however this strongly hints that this has been broken - may need to google for how to work around this with CUDA 5.5. Keep us posted if you resolve this...
Aug 23, 2013 at 6:59 AM
Hi,
With CUDA 5.5 CUDAfy 1.22 works well.
If I switch to CUDAfy 1.25 nvcc error shows (CudafyCompileExeption: Compilation Error: nvcc : fatal error : nvcc cannot find a supported version of Microsoft Visual Studio. Only the versions 2008, 2010, and 2012 are supported
...
at chapter 03/simple_kernel.cs line 20
in program.cs line 42).

What have been changed - I mean, referencing nvcc - in 1.25?

I have the following softwares:
64 bit CUDA 5.5, 64 bit Windows Server 2012, Visual Studio 2012, CUDAfy 1.22 and 1.25.
Br,
Peter
Coordinator
Aug 23, 2013 at 7:28 AM
Edited Aug 23, 2013 at 7:29 AM
Are you compiling for x64 or Any? x86 will fail to work correctly on x64 OS. Can you look through the debug information to see what the nvcc command line was? You can also print the CompilerArguments and CompilerOutput properties of the CudafyModule object in your catch block.
You can also try CudafyOld(...)
Aug 23, 2013 at 9:12 AM
Hello,
I compiled for Any and X64. The same error occures.
The copy of Exception:
Cudafy.CudafyCompileException was caught
HResult=-2146233088
Message=Compilation error: .
Source=Cudafy.NET
StackTrace:
   at Cudafy.CudafyModule.Compile(CompileProperties[] props)
   at Cudafy.Translator.CudafyTranslator.Cudafy(IEnumerable`1 props, Type[] types)
   at Cudafy.Translator.CudafyTranslator.Cudafy(CompileProperties prop, Type[] types)
   at Cudafy.Translator.CudafyTranslator.Cudafy(ePlatform platform, eArchitecture arch, Version cudaVersion, Boolean compile, Type[] types)
   at Cudafy.Translator.CudafyTranslator.Cudafy(ePlatform platform, eArchitecture arch, Type[] types)
   at Cudafy.Translator.CudafyTranslator.Cudafy()
   at CudafyByExample.simple_kernel.Execute() in c:\Users\csernap.SCOMSRV\Documents\CUDAfy.NET SDK\CudafyV1.25\CudafyByExample\chapter03\simple_kernel.cs:line 20
   at CudafyByExample.Program.Main(String[] args) in c:\Users\csernap.SCOMSRV\Documents\CUDAfy.NET SDK\CudafyV1.25\CudafyByExample\Program.cs:line 42
InnerException:
I hope, I cut the desired section (if not, please sepcify, bacuse I am not a deep expert):
https://skydrive.live.com/redir?resid=2A7286880B87A539!20738&authkey=!ADGwCVpBZ6RD_X0&v=3

Br,
Peter
Coordinator
Aug 23, 2013 at 9:30 AM
No I mean the object returned by the CudafyTranslator.Cudafy(...) method.
Aug 23, 2013 at 3:06 PM
Edited Aug 23, 2013 at 8:03 PM
It dies at the invocation of CudafyModule km = CudafyTranslator.Cudafy() row.
km has not got any object.

The correct 1.22 version's CompilerArguments and CompilerOutput properties are empty.
Br,
Peter

Ps.
I've just attached the 22231 source...
Aug 23, 2013 at 8:01 PM
Edited Aug 25, 2013 at 3:11 PM
My CompilerArguments:

-I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -m64 -arch=sm_13 -ptx "C:\Users\csernap.SCOMSRV\Documents\CUDAfy.NET SDK\CudafyV1.25\CudafyByExample\bin\Debug\CUDAFYSOURCETEMP.cu" -o "C:\Users\csernap.SCOMSRV\Documents\CUDAfy.NET SDK\CudafyV1.25\CudafyByExample\bin\Debug\CUDAFYSOURCETEMP.ptx"

My CompilerOutput:
nvcc : fatal error : nvcc cannot find a supported version of Microsoft Visual Studio. Only the versions 2008, 2010, and 2012 are supported

My p.CompilerPath:
C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc

Br,
Peter
Aug 27, 2013 at 4:49 PM
Hi Nick,
Can I provide further information on calling the process?
Br,
Peter
Coordinator
Aug 27, 2013 at 6:30 PM
Struggling to understand what is happening. You can try to compare the compiler arguments of the V1.22 and V1.25 versions? Did you try calling CudafyOld(...) ?
Aug 27, 2013 at 8:32 PM
Edited Aug 27, 2013 at 8:42 PM
Hi,
I wanted to use old version of the trunk, but several files are missing from the solution - so its hard to rebuild the 20436 trunk:
Cloo.VS2010.csproj : error : The project file could not be loaded. Could not find a part of the path... (the whole project is missing)
OptionalStrings.cs is missing from Cudafy.Translator
OpenCLDevice.cs from Cudafy.Host
IntegerIntrinsics.cs from Cudafy/Extension

I could not use files from later trunks...
I have the same problem with 20746.

Br,
Peter
Coordinator
Aug 28, 2013 at 6:17 AM
Just use the latest version and compare with older revisions.
Aug 28, 2013 at 7:03 AM
Ok, I started, but give me some time. I have to deal with other things during daylight :-(
Aug 29, 2013 at 7:12 PM
Edited Aug 29, 2013 at 7:14 PM
Hi,
In 20436 (1.22) OpenCL not calls the kernelmodule.Compile function but 22231 (1.25) does where the process is stopped.
If I switch to Cuda mode the version of 20436 exites because cudart64_50_35.dll is missing (could you give me a clue how can override in Cuda 5.5, please?).
The 22231 shows the above mentioned exeptions.

Maybe it is not the question, but there is a slightly difference between the Cuda sourcecodes of the two versions:
20436
'#if defined(cl_khr_fp64)
'#pragma OPENCL EXTENSION cl_khr_fp64: enable
'#elif defined(cl_amd_fp64)
'#pragma OPENCL EXTENSION cl_amd_fp64: enable
'#endif

// CudafyByExample.simple_kernel
__kernel void thekernel();

// CudafyByExample.simple_kernel
__kernel void thekernel()
{
}

22231
// CudafyByExample.simple_kernel
extern "C" global void thekernel();

// CudafyByExample.simple_kernel
extern "C" global void thekernel()
{
}
Coordinator
Aug 30, 2013 at 7:55 AM
1) cudart dll is typically only used by CUDAfy to retrieve some device properties. CUDAfy V1.25 requires CUDA 5.5. Please let me know which method throws the dll not found.

2) One source code you show is OpenCL the other is CUDA!
Aug 30, 2013 at 2:03 PM
1, In 1.22 the gpu.GetDeviceProperties().Name throws the missing dll exeption.

2, I had an eArchitecture.sm_30 attribute in Cudafy and the specified architecture overrides the eLanguage.OpenCL.

If I switch everything to OpenCL the 1.25 version WORKS!
If I switch to CUDA (with the specified architecture), the same nvcc : fatal error... message appears.

Running CUDA:
My CompilerArguments:
-I"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\include" -m64 -arch=sm_30 -ptx "C:\Users\csernap.SCOMSRV\Documents\CUDAfy.NET SDK\CUDAfy22231source\Cudafy\CudafyByExample\bin\x64\Debug\CUDAFYSOURCETEMP.cu" -o "C:\Users\csernap.SCOMSRV\Documents\CUDAfy.NET SDK\CUDAfy22231source\Cudafy\CudafyByExample\bin\x64\Debug\CUDAFYSOURCETEMP.ptx"

Process.StartInfo.Filename:
"C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.5\bin\nvcc"
Coordinator
Aug 31, 2013 at 6:58 AM
  1. Yes because this overload of GetDeviceProperties attempts to use cudart64_50_35.dll. You can change the source code in the CUDARuntime64 class in CUDA.NET project.
  2. Indeed the same nvcc error has not been resolved.
Aug 31, 2013 at 8:27 PM
Hi, just a thought: I have seen in CUDA sample project that the same kind of problem exists if you have not upgrade toolset to v110.
Sep 1, 2013 at 5:54 AM
I switched the dll to cudart64_55 in 1.22 and the same nvcc error occured.
Coordinator
Sep 1, 2013 at 7:59 AM
Did you resolve the dll not found error? I do not believe this is related to the nvcc error.
Sep 1, 2013 at 8:16 AM
Yes, I switched cudart64_50_35 to cudart64_55, which resolved the missing dll issue, but not the nvcc error.

I dig the nvcc compiler and I found that there went something wrong.

I deleted the prevoiusly installed 2010 Express C editors, removed the CUDA toolkit, and repaired the VS 2012.
After the repair I reinstalled CUDA 5.5.

Next I run in command line: "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\vcvarsall.bat" amd64

I checked if the cl.exe works well from command line (and it did!)

After all the CudafyByExample project works!

Thank you for your help Nick!
Br,
Peter
Sep 30, 2013 at 1:27 AM
I'm having similar problems.

I have had this working on this machine before, and am re-installing.

my setup:
windows 8 64-bit
visual C# 2010 express
I've installed both Cuda 5.0 64bit and Cuda 5.5 64bit.
I'm building both 32 and 64 bit applications.
Cudafy v1.26

This has worked previously - the 32bit Cuda SDK is not required for 32bit applications (as mentioned by someone above, the 64bit SDK must contain the 32bit dlls as well).

When I run with Cuda5.5 I get the "nvcc cannot find a supported version of Microsoft Visual Studio". I've tried amending the nvcc.profile with no luck.

If I switch to Cuda5.0 it works fine.

I've googled Cuda5.5 wrt the express editions but not found anything relevant.


It's not obvious from the long posts above which step fixed this specific problem. For now I'll still to Cuda5.0, but if there's any further testing I can do to help resolve the problem let me know.
Oct 1, 2013 at 2:58 PM
Hi mcmillab,

I think that a fix is yet to be found. In the meantime I'm using CUDA 5.0 since I have a Geforce GTX 550 Ti and have no need to use features specific to 5.5.

Regards,
Daniel